⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dupe.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	if (mask & DUPE_MATCH_SUM)		{		if (!a->md5sum) a->md5sum = md5_text_from_file_utf8(a->path, "");		if (!b->md5sum) b->md5sum = md5_text_from_file_utf8(b->path, "");		if (a->md5sum[0] == '\0' ||		    b->md5sum[0] == '\0' ||		    strcmp(a->md5sum, b->md5sum) != 0) return FALSE;		}	if (mask & DUPE_MATCH_DIM)		{		if (a->width == 0) image_load_dimensions(a->path, &a->width, &a->height);		if (b->width == 0) image_load_dimensions(b->path, &b->width, &b->height);		if (a->width != b->width || a->height != b->height) return FALSE;		}	if (mask & DUPE_MATCH_SIM_HIGH ||	    mask & DUPE_MATCH_SIM_MED ||	    mask & DUPE_MATCH_SIM_LOW ||	    mask & DUPE_MATCH_SIM_CUSTOM)		{		gdouble f;		gdouble m;		if (mask & DUPE_MATCH_SIM_HIGH) m = 0.95;		else if (mask & DUPE_MATCH_SIM_MED) m = 0.90;		else if (mask & DUPE_MATCH_SIM_CUSTOM) m = (gdouble)dupe_custom_threshold / 100.0;		else m = 0.85;		if (fast)			{			f = image_sim_compare_fast(a->simd, b->simd, m);			}		else			{			f = image_sim_compare(a->simd, b->simd);			}		*rank = f * 100.0;		if (f < m) return FALSE;		if (debug > 2) printf("similar: %32s %32s = %f\n", a->name, b->name, f);		}	return TRUE;}static void dupe_list_check_match(DupeWindow *dw, DupeItem *needle, GList *start){	GList *work;	if (dw->second_set)		{		work = dw->second_list;		}	else if (start)		{		work = start;		}	else		{		work = g_list_last(dw->list);		}	while (work)		{		DupeItem *di = work->data;		/* speed opt: forward for second set, back for simple compare */		if (dw->second_set)			work = work->next;		else			work = work->prev;		if (!dupe_match_link_exists(needle, di))			{			gdouble rank;			if (dupe_match(di, needle, dw->match_mask, &rank, TRUE))				{				dupe_match_link(di, needle, rank);				}			}		}}/* * ------------------------------------------------------------------ * Thumbnail handling * ------------------------------------------------------------------ */static void dupe_listview_set_thumb(DupeWindow *dw, DupeItem *di, GtkTreeIter *iter){	GtkListStore *store;	GtkTreeIter iter_n;	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview)));	if (!iter)		{		if (dupe_listview_find_item(store, di, &iter_n) >= 0)			{			iter = &iter_n;			}		}	if (iter) gtk_list_store_set(store, iter, DUPE_COLUMN_THUMB, di->pixbuf, -1);}static void dupe_thumb_do(DupeWindow *dw){	DupeItem *di;	if (!dw->thumb_loader || !dw->thumb_item) return;	di = dw->thumb_item;	if (di->pixbuf) g_object_unref(di->pixbuf);	di->pixbuf = thumb_loader_get_pixbuf(dw->thumb_loader, TRUE);	dupe_listview_set_thumb(dw, di, NULL);}static void dupe_thumb_error_cb(ThumbLoader *tl, gpointer data){	DupeWindow *dw = data;	dupe_thumb_do(dw);	dupe_thumb_step(dw);}static void dupe_thumb_done_cb(ThumbLoader *tl, gpointer data){	DupeWindow *dw = data;	dupe_thumb_do(dw);	dupe_thumb_step(dw);}static void dupe_thumb_step(DupeWindow *dw){	GtkTreeModel *store;	GtkTreeIter iter;	DupeItem *di = NULL;	gint valid;	gint row = 0;	gint length = 0;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview));	valid = gtk_tree_model_get_iter_first(store, &iter);	while (!di && valid)		{		GdkPixbuf *pixbuf;		length++;		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, DUPE_COLUMN_THUMB, &pixbuf, -1);		if (pixbuf || di->pixbuf)			{			if (!pixbuf) gtk_list_store_set(GTK_LIST_STORE(store), &iter, DUPE_COLUMN_THUMB, di->pixbuf, -1);			row++;			di = NULL;			}		valid = gtk_tree_model_iter_next(store, &iter);		}	if (valid)		{		while (gtk_tree_model_iter_next(store, &iter)) length++;		}	if (!di)		{		dw->thumb_item = NULL;		thumb_loader_free(dw->thumb_loader);		dw->thumb_loader = NULL;		dupe_window_update_progress(dw, NULL, 0.0, FALSE);		return;		}	dupe_window_update_progress(dw, _("Loading thumbs..."),				    length == 0 ? 0.0 : (gdouble)(row) / length, FALSE);	dw->thumb_item = di;	thumb_loader_free(dw->thumb_loader);	dw->thumb_loader = thumb_loader_new(thumb_max_width, thumb_max_height);	thumb_loader_set_callbacks(dw->thumb_loader,				   dupe_thumb_done_cb,				   dupe_thumb_error_cb,				   NULL,				   dw);	/* start it */	if (!thumb_loader_start(dw->thumb_loader, di->path))		{		/* error, handle it, do next */		if (debug) printf("error loading thumb for %s\n", di->path);		dupe_thumb_do(dw);		dupe_thumb_step(dw);		}}/* * ------------------------------------------------------------------ * Dupe checking loop * ------------------------------------------------------------------ */static void dupe_check_stop(DupeWindow *dw){	if (dw->idle_id != -1 || dw->img_loader || dw->thumb_loader)		{		g_source_remove(dw->idle_id);		dw->idle_id = -1;		dupe_window_update_progress(dw, NULL, 0.0, FALSE);		widget_set_cursor(dw->listview, -1);		}	thumb_loader_free(dw->thumb_loader);	dw->thumb_loader = NULL;	image_loader_free(dw->img_loader);	dw->img_loader = NULL;}static void dupe_loader_done_cb(ImageLoader *il, gpointer data){	DupeWindow *dw = data;	GdkPixbuf *pixbuf;	pixbuf = image_loader_get_pixbuf(il);	if (dw->setup_point)		{		DupeItem *di = dw->setup_point->data;		if (!di->simd)			{			di->simd = image_sim_new_from_pixbuf(pixbuf);			}		else			{			image_sim_fill_data(di->simd, pixbuf);			}		if (di->width == 0 && di->height == 0)			{			di->width = gdk_pixbuf_get_width(pixbuf);			di->height = gdk_pixbuf_get_height(pixbuf);			}		if (enable_thumb_caching)			{			dupe_item_write_cache(di);			}		image_sim_alternate_processing(di->simd);		}	image_loader_free(dw->img_loader);	dw->img_loader = NULL;	dw->idle_id = g_idle_add(dupe_check_cb, dw);}static void dupe_setup_reset(DupeWindow *dw){	dw->setup_point = NULL;	dw->setup_n = 0;	dw->setup_time = msec_time();	dw->setup_time_count = 0;}static GList *dupe_setup_point_step(DupeWindow *dw, GList *p){	if (!p) return NULL;	if (p->next) return p->next;	if (dw->second_set && g_list_first(p) == dw->list) return dw->second_list;	return NULL;}static gint dupe_check_cb(gpointer data){	DupeWindow *dw = data;	if (dw->idle_id == -1) return FALSE;	if (!dw->setup_done)		{		if ((dw->match_mask & DUPE_MATCH_SUM) &&		    !(dw->setup_mask & DUPE_MATCH_SUM) )			{			if (!dw->setup_point) dw->setup_point = dw->list;			while (dw->setup_point)				{				DupeItem *di = dw->setup_point->data;				dw->setup_point = dupe_setup_point_step(dw, dw->setup_point);				dw->setup_n++;				if (!di->md5sum)					{					dupe_window_update_progress(dw, _("Reading checksums..."),						dw->setup_count == 0 ? 0.0 : (gdouble)(dw->setup_n - 1) / dw->setup_count, FALSE);					if (enable_thumb_caching)						{						dupe_item_read_cache(di);						if (di->md5sum) return TRUE;						}					di->md5sum = md5_text_from_file_utf8(di->path, "");					if (enable_thumb_caching)						{						dupe_item_write_cache(di);						}					return TRUE;					}				}			dw->setup_mask |= DUPE_MATCH_SUM;			dupe_setup_reset(dw);			}		if ((dw->match_mask & DUPE_MATCH_DIM) &&		    !(dw->setup_mask & DUPE_MATCH_DIM) )			{			if (!dw->setup_point) dw->setup_point = dw->list;			while (dw->setup_point)				{				DupeItem *di = dw->setup_point->data;				dw->setup_point = dupe_setup_point_step(dw, dw->setup_point);				dw->setup_n++;				if (di->width == 0 && di->height == 0)					{					dupe_window_update_progress(dw, _("Reading dimensions..."),						dw->setup_count == 0 ? 0.0 : (gdouble)(dw->setup_n - 1) / dw->setup_count, FALSE);					if (enable_thumb_caching)						{						dupe_item_read_cache(di);						if (di->width != 0 || di->height != 0) return TRUE;						}					image_load_dimensions(di->path, &di->width, &di->height);					if (enable_thumb_caching)						{						dupe_item_write_cache(di);						}					return TRUE;					}				}			dw->setup_mask |= DUPE_MATCH_DIM;			dupe_setup_reset(dw);			}		if ((dw->match_mask & DUPE_MATCH_SIM_HIGH ||		     dw->match_mask & DUPE_MATCH_SIM_MED ||		     dw->match_mask & DUPE_MATCH_SIM_LOW ||		     dw->match_mask & DUPE_MATCH_SIM_CUSTOM) &&		    !(dw->setup_mask & DUPE_MATCH_SIM_MED) )			{			if (!dw->setup_point) dw->setup_point = dw->list;			while (dw->setup_point)				{				DupeItem *di = dw->setup_point->data;				if (!di->simd)					{					dupe_window_update_progress(dw, _("Reading similarity data..."),						dw->setup_count == 0 ? 0.0 : (gdouble)dw->setup_n / dw->setup_count, FALSE);					if (enable_thumb_caching)						{						dupe_item_read_cache(di);						if (cache_sim_data_filled(di->simd))							{							image_sim_alternate_processing(di->simd);							return TRUE;							}						}					dw->img_loader = image_loader_new(di->path);					image_loader_set_buffer_size(dw->img_loader, 8);					image_loader_set_error_func(dw->img_loader, dupe_loader_done_cb, dw);					if (!image_loader_start(dw->img_loader, dupe_loader_done_cb, dw))						{						image_sim_free(di->simd);						di->simd = image_sim_new();						image_loader_free(dw->img_loader);						dw->img_loader = NULL;						return TRUE;						}					dw->idle_id = -1;					return FALSE;					}				dw->setup_point = dupe_setup_point_step(dw, dw->setup_point);				dw->setup_n++;				}			dw->setup_mask |= DUPE_MATCH_SIM_MED;			dupe_setup_reset(dw);			}		dupe_window_update_progress(dw, _("Comparing..."), 0.0, FALSE);		dw->setup_done = TRUE;		dupe_setup_reset(dw);		dw->setup_count = g_list_length(dw->list);		}	if (!dw->working)		{		if (dw->setup_count > 0)			{			dw->setup_count = 0;			dupe_window_update_progress(dw, _("Sorting..."), 1.0, TRUE);			return TRUE;			}		dw->idle_id = -1;		dupe_window_update_progress(dw, NULL, 0.0, FALSE);		dupe_match_rank(dw);		dupe_window_update_count(dw, FALSE);		dupe_listview_populate(dw);		/* check thumbs */		if (dw->show_thumbs) dupe_thumb_step(dw);		widget_set_cursor(dw->listview, -1);		return FALSE;		}	dupe_list_check_match(dw, (DupeItem *)dw->working->data, dw->working);	dupe_window_update_progress(dw, _("Comparing..."), dw->setup_count == 0 ? 0.0 : (gdouble) dw->setup_n / dw->setup_count, FALSE);	dw->setup_n++;	dw->working = dw->working->prev;	return TRUE;}static void dupe_check_start(DupeWindow *dw){	dw->setup_done = FALSE;	dw->setup_count = g_list_length(dw->list);	if (dw->second_set) dw->setup_count += g_list_length(dw->second_list);	dw->setup_mask = 0;	dupe_setup_reset(dw);	dw->working = g_list_last(dw->list);	dupe_window_update_count(dw, TRUE);	widget_set_cursor(dw->listview, GDK_WATCH);	if (dw->idle_id != -1) return;	dw->idle_id = g_idle_add(dupe_check_cb, dw);}/* * ------------------------------------------------------------------ * Item addition, removal * ------------------------------------------------------------------ */static void dupe_item_remove(DupeWindow *dw, DupeItem *di){	if (!di) return;	/* handle things that may be in progress... */	if (dw->working && dw->working->data == di)		{		dw->working = dw->working->prev;		}	if (dw->thumb_loader && dw->thumb_item == di)		{		dupe_thumb_step(dw);		}	if (dw->setup_point && dw->setup_point->data == di)		{		dw->setup_point = dupe_setup_point_step(dw, dw->setup_point);		if (dw->img_loader)			{			image_loader_free(dw->img_loader);			dw->img_loader = NULL;			dw->idle_id = g_idle_add(dupe_check_cb, dw);			}		}	if (di->group && dw->dupes)		{		/* is a dupe, must remove from group/reset children if a parent */		DupeItem *parent;		parent = dupe_match_find_parent(dw, di);		if (di == parent)			{			if (g_list_length(parent->group) < 2)				{				DupeItem *child;				child = dupe_match_highest_rank(parent);				dupe_match_link_clear(child, TRUE);				dupe_listview_remove(dw, child);				dupe_match_link_clear(parent, TRUE);				dupe_listview_remove(dw, parent);				dw->dupes = g_list_remove(dw->dupes, parent);				}			else				{				DupeItem *new_parent;				DupeMatch *dm;								dm = parent->group->data;				new_parent = dm->di;				dupe_match_reparent(dw, parent, new_parent);				dupe_listview_remove(dw, parent);				}			}		else			{			if (g_list_length(parent->group) < 2)				{				dupe_match_link_clear(parent, TRUE);				dupe_listview_remove(dw, parent);				dw->dupes = g_list_remove(dw->dupes, parent);				}			dupe_match_link_clear(di, TRUE);			dupe_listview_remove(dw, di);			}		}	else		{		/* not a dupe, or not sorted yet, simply reset */		dupe_match_link_clear(di, TRUE);		}	if (dw->second_list && g_list_find(dw->second_list, di))		{		dupe_second_remove(dw, di);		}	else		{		dw->list = g_list_remove(dw->list, di);		}	dupe_item_free(di);	dupe_window_update_count(dw, FALSE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -