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

📄 thumb_standard.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (thumb_loader_std_setup(tl, tl->source_path)) return TRUE;		}	thumb_loader_std_save(tl, NULL);	return FALSE;}static void thumb_loader_std_done_cb(ImageLoader *il, gpointer data){	ThumbLoaderStd *tl = data;	GdkPixbuf *pixbuf;	if (debug)		{		printf("thumb image done: %s\n", tl->source_path);		printf("            from: %s\n", tl->il->path);		}	pixbuf = image_loader_get_pixbuf(tl->il);	if (!pixbuf)		{		if (debug) printf("...but no pixbuf\n");		thumb_loader_std_error_cb(il, data);		return;		}	if (tl->thumb_path && !thumb_loader_std_validate(tl, pixbuf))		{		if (thumb_loader_std_next_source(tl, TRUE)) return;		if (tl->func_error) tl->func_error(tl, tl->data);		return;		}	tl->cache_hit = (tl->thumb_path != NULL);	tl->pixbuf = thumb_loader_std_finish(tl, pixbuf, il->shrunk);	if (tl->func_done) tl->func_done(tl, tl->data);}static void thumb_loader_std_error_cb(ImageLoader *il, gpointer data){	ThumbLoaderStd *tl = data;	/* if at least some of the image is available, go to done */	if (image_loader_get_pixbuf(tl->il) != NULL)		{		thumb_loader_std_done_cb(il, data);		return;		}	if (debug)		{		printf("thumb image error: %s\n", tl->source_path);		printf("             from: %s\n", tl->il->path);		}	if (thumb_loader_std_next_source(tl, TRUE)) return;	if (tl->func_error) tl->func_error(tl, tl->data);}static void thumb_loader_std_progress_cb(ImageLoader *il, gdouble percent, gpointer data){	ThumbLoaderStd *tl = data;	tl->progress = (gdouble)percent;	if (tl->func_progress) tl->func_progress(tl, tl->data);}static gint thumb_loader_std_setup(ThumbLoaderStd *tl, const gchar *path){	tl->il = image_loader_new(path);	if (thumbnail_fast)		{		/* this will speed up jpegs by up to 3x in some cases */		if (tl->requested_width <= THUMB_SIZE_NORMAL &&		    tl->requested_height <= THUMB_SIZE_NORMAL)			{			image_loader_set_requested_size(tl->il, THUMB_SIZE_NORMAL, THUMB_SIZE_NORMAL);			}		else			{			image_loader_set_requested_size(tl->il, THUMB_SIZE_LARGE, THUMB_SIZE_LARGE);			}		}	image_loader_set_error_func(tl->il, thumb_loader_std_error_cb, tl);	if (tl->func_progress)		{		image_loader_set_percent_func(tl->il, thumb_loader_std_progress_cb, tl);		}	if (image_loader_start(tl->il, thumb_loader_std_done_cb, tl))		{		return TRUE;		}	image_loader_free(tl->il);	tl->il = NULL;	return FALSE;}/* * Note: Currently local_cache only specifies where to save a _new_ thumb, if *       a valid existing thumb is found anywhere the local thumb will not be created. */void thumb_loader_std_set_cache(ThumbLoaderStd *tl, gint enable_cache, gint local, gint retry_failed){	if (!tl) return;	tl->cache_enable = enable_cache;	tl->cache_local = local;	tl->cache_retry = retry_failed;}gint thumb_loader_std_start(ThumbLoaderStd *tl, const gchar *path){	static gchar *thumb_cache = NULL;	struct stat st;	if (!tl || !path) return FALSE;	thumb_loader_std_reset(tl);	if (!stat_utf8(path, &st)) return FALSE;	tl->source_path = g_strdup(path);	tl->source_mtime = st.st_mtime;	tl->source_size = st.st_size;	tl->source_mode = st.st_mode;	if (!thumb_cache) thumb_cache = g_strconcat(homedir(), "/", THUMB_FOLDER, NULL);	if (strncmp(tl->source_path, thumb_cache, strlen(thumb_cache)) != 0)		{		gchar *pathl;		pathl = path_from_utf8(path);		tl->thumb_uri = g_filename_to_uri(pathl, NULL, NULL);		tl->local_uri = filename_from_path(tl->thumb_uri);		g_free(pathl);		}	if (tl->cache_enable)		{		gint found;		tl->thumb_path = thumb_loader_std_cache_path(tl, FALSE, NULL, FALSE);		tl->thumb_path_local = FALSE;		found = isfile(tl->thumb_path);		if (found && thumb_loader_std_setup(tl, tl->thumb_path)) return TRUE;		if (thumb_loader_std_fail_check(tl)) return FALSE;		return thumb_loader_std_next_source(tl, found);		}	if (!thumb_loader_std_setup(tl, tl->source_path))		{		thumb_loader_std_save(tl, NULL);		return FALSE;		}	return TRUE;}void thumb_loader_std_free(ThumbLoaderStd *tl){	if (!tl) return;	thumb_loader_std_reset(tl);	g_free(tl);}GdkPixbuf *thumb_loader_std_get_pixbuf(ThumbLoaderStd *tl, gint with_fallback){	GdkPixbuf *pixbuf;	if (tl && tl->pixbuf)		{		pixbuf = tl->pixbuf;		g_object_ref(pixbuf);		}	else if (with_fallback)		{		gint w, h;		pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);		w = gdk_pixbuf_get_width(pixbuf);		h = gdk_pixbuf_get_height(pixbuf);		if (w > tl->requested_width || h > tl->requested_height)			{			gint nw, nh;			if (thumb_loader_std_scale_aspect(tl->requested_width, tl->requested_height,							  w, h, &nw, &nh))				{				GdkPixbuf *tmp;				tmp = pixbuf;				pixbuf = gdk_pixbuf_scale_simple(tmp, nw, nh, GDK_INTERP_TILES);				g_object_unref(G_OBJECT(tmp));				}			}		}	else		{		pixbuf = NULL;		}	return pixbuf;}typedef struct _ThumbValidate ThumbValidate;struct _ThumbValidate{	ThumbLoaderStd *tl;	gchar *path;	gint days;	void (*func_valid)(const gchar *path, gint valid, gpointer data);	gpointer data;	gint idle_id;};static void thumb_loader_std_thumb_file_validate_free(ThumbValidate *tv){	thumb_loader_std_free(tv->tl);	g_free(tv->path);	g_free(tv);}void thumb_loader_std_thumb_file_validate_cancel(ThumbLoaderStd *tl){	ThumbValidate *tv;	if (!tl) return;	tv = tl->data;	if (tv->idle_id != -1) g_source_remove(tv->idle_id);	tv->idle_id = -1;	thumb_loader_std_thumb_file_validate_free(tv);}static void thumb_loader_std_thumb_file_validate_finish(ThumbValidate *tv, gint valid){	if (tv->func_valid) tv->func_valid(tv->path, valid, tv->data);	thumb_loader_std_thumb_file_validate_free(tv);}static void thumb_loader_std_thumb_file_validate_done_cb(ThumbLoaderStd *tl, gpointer data){	ThumbValidate *tv = data;	GdkPixbuf *pixbuf;	gint valid = FALSE;	pixbuf = thumb_loader_std_get_pixbuf(tv->tl, FALSE);	if (pixbuf)		{		const gchar *uri;		const gchar *mtime_str;		uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);		mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);		if (uri && mtime_str)			{			if (strncmp(uri, "file:", strlen("file:")) == 0)				{				struct stat st;				gchar *target;				target = g_filename_from_uri(uri, NULL, NULL);				if (stat(target, &st) == 0 &&				    st.st_mtime == strtol(mtime_str, NULL, 10))					{					valid = TRUE;					}				g_free(target);				}			else				{				struct stat st;				if (debug) printf("thumb uri foreign, doing day check: %s\n", uri);				if (stat_utf8(tv->path, &st))					{					time_t now;					now = time(NULL);					if (st.st_atime >= now - (time_t)tv->days * 24 * 60 * 60)						{						valid = TRUE;						}					}				}			}		g_object_unref(pixbuf);		}	thumb_loader_std_thumb_file_validate_finish(tv, valid);}static void thumb_loader_std_thumb_file_validate_error_cb(ThumbLoaderStd *tl, gpointer data){	ThumbValidate *tv = data;	thumb_loader_std_thumb_file_validate_finish(tv, FALSE);}static gint thumb_loader_std_thumb_file_validate_idle_cb(gpointer data){	ThumbValidate *tv = data;	tv->idle_id = -1;	thumb_loader_std_thumb_file_validate_finish(tv, FALSE);	return FALSE;}ThumbLoaderStd *thumb_loader_std_thumb_file_validate(const gchar *thumb_path, gint allowed_days,						     void (*func_valid)(const gchar *path, gint valid, gpointer data),						     gpointer data){	ThumbValidate *tv;	tv = g_new0(ThumbValidate, 1);	tv->tl = thumb_loader_std_new(THUMB_SIZE_LARGE, THUMB_SIZE_LARGE);	thumb_loader_std_set_callbacks(tv->tl,				       thumb_loader_std_thumb_file_validate_done_cb,				       thumb_loader_std_thumb_file_validate_error_cb,				       NULL,				       tv);	thumb_loader_std_reset(tv->tl);	tv->path = g_strdup(thumb_path);	tv->days = allowed_days;	tv->func_valid = func_valid;	tv->data = data;	if (!thumb_loader_std_setup(tv->tl, thumb_path))		{		tv->idle_id = g_idle_add(thumb_loader_std_thumb_file_validate_idle_cb, tv);		}	else		{		tv->idle_id = -1;		}	return tv->tl;}static void thumb_std_maint_remove_one(const gchar *source, const gchar *uri, gint local,				       const gchar *subfolder){	gchar *thumb_path;	thumb_path = thumb_std_cache_path(source,					  (local) ? filename_from_path(uri) : uri,					  local, subfolder);	if (isfile(thumb_path))		{		if (debug) printf("thumb removing: %s\n", thumb_path);		unlink_file(thumb_path);		}	g_free(thumb_path);}/* this also removes local thumbnails (the source is gone so it makes sense) */void thumb_std_maint_removed(const gchar *source){	gchar *uri;	gchar *sourcel;	sourcel = path_from_utf8(source);	uri = g_filename_to_uri(sourcel, NULL, NULL);	g_free(sourcel);	/* all this to remove a thumbnail? */	thumb_std_maint_remove_one(source, uri, FALSE, THUMB_FOLDER_NORMAL);	thumb_std_maint_remove_one(source, uri, FALSE, THUMB_FOLDER_LARGE);	thumb_std_maint_remove_one(source, uri, FALSE, THUMB_FOLDER_FAIL);	thumb_std_maint_remove_one(source, uri, TRUE, THUMB_FOLDER_NORMAL);	thumb_std_maint_remove_one(source, uri, TRUE, THUMB_FOLDER_LARGE);	g_free(uri);}typedef struct _TMaintMove TMaintMove;struct _TMaintMove{	gchar *source;	gchar *dest;	ThumbLoaderStd *tl;	gchar *source_uri;	gchar *thumb_path;	gint pass;};static GList *thumb_std_maint_move_list = NULL;static GList *thumb_std_maint_move_tail = NULL;static void thumb_std_maint_move_step(TMaintMove *tm);static gint thumb_std_maint_move_idle(gpointer data);static void thumb_std_maint_move_validate_cb(const gchar *path, gint valid, gpointer data){	TMaintMove *tm = data;	GdkPixbuf *pixbuf;	pixbuf = thumb_loader_std_get_pixbuf(tm->tl, FALSE);	if (pixbuf)		{		const gchar *uri;		const gchar *mtime_str;		uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);		mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);		if (uri && mtime_str && strcmp(uri, tm->source_uri) == 0)			{			gchar *pathl;			/* The validation utility abuses ThumbLoader, and we			 * abuse the utility just to load the thumbnail,			 * but the loader needs to look sane for the save to complete.			 */			tm->tl->cache_enable = TRUE;			tm->tl->cache_hit = FALSE;			tm->tl->cache_local = FALSE;			g_free(tm->tl->source_path);			tm->tl->source_path = g_strdup(tm->dest);			tm->tl->source_mtime = strtol(mtime_str, NULL, 10);			pathl = path_from_utf8(tm->tl->source_path);			g_free(tm->tl->thumb_uri);			tm->tl->thumb_uri = g_filename_to_uri(pathl, NULL, NULL);			tm->tl->local_uri = filename_from_path(tm->tl->thumb_uri);			g_free(pathl);			g_free(tm->tl->thumb_path);			tm->tl->thumb_path = NULL;			tm->tl->thumb_path_local = FALSE;			if (debug) printf("thumb move attempting save:\n");			thumb_loader_std_save(tm->tl, pixbuf);			}		if (debug) printf("thumb move unlink: %s\n", tm->thumb_path);		unlink_file(tm->thumb_path);		}	thumb_std_maint_move_step(tm);}static void thumb_std_maint_move_step(TMaintMove *tm){	const gchar *folder;	tm->pass++;	if (tm->pass > 2)		{		g_free(tm->source);		g_free(tm->dest);		g_free(tm->source_uri);		g_free(tm->thumb_path);		g_free(tm);		if (thumb_std_maint_move_list)			{			g_idle_add_full(G_PRIORITY_LOW, thumb_std_maint_move_idle, NULL, NULL);			}		return;		}	folder = (tm->pass == 1) ? THUMB_FOLDER_NORMAL : THUMB_FOLDER_LARGE;		g_free(tm->thumb_path);	tm->thumb_path = thumb_std_cache_path(tm->source, tm->source_uri, FALSE, folder);	tm->tl = thumb_loader_std_thumb_file_validate(tm->thumb_path, 0,						      thumb_std_maint_move_validate_cb, tm);}static gint thumb_std_maint_move_idle(gpointer data){	TMaintMove *tm;	gchar *pathl;	if (!thumb_std_maint_move_list) return FALSE;	tm = thumb_std_maint_move_list->data;	thumb_std_maint_move_list = g_list_remove(thumb_std_maint_move_list, tm);	if (!thumb_std_maint_move_list) thumb_std_maint_move_tail = NULL;	pathl = path_from_utf8(tm->source);	tm->source_uri = g_filename_to_uri(pathl, NULL, NULL);	g_free(pathl);	tm->pass = 0;	thumb_std_maint_move_step(tm);	return FALSE;}/* This will schedule a move of the thumbnail for source image to dest when idle. * We do this so that file renaming or moving speed is not sacrificed by * moving the thumbnails at the same time because: * * This cache design requires the tedious task of loading the png thumbnails and saving them. * * The thumbnails are processed when the app is idle. If the app * exits early well too bad - they can simply be regenerated from scratch. * * This does not manage local thumbnails (fixme ?) */void thumb_std_maint_moved(const gchar *source, const gchar *dest){	TMaintMove *tm;	tm = g_new0(TMaintMove, 1);	tm->source = g_strdup(source);	tm->dest = g_strdup(dest);	if (!thumb_std_maint_move_list)		{		g_idle_add_full(G_PRIORITY_LOW, thumb_std_maint_move_idle, NULL, NULL);		}	if (thumb_std_maint_move_tail)		{		g_list_append(thumb_std_maint_move_tail, tm);		thumb_std_maint_move_tail = thumb_std_maint_move_tail->next;		}	else		{		thumb_std_maint_move_list = g_list_append(thumb_std_maint_move_list, tm);		thumb_std_maint_move_tail = thumb_std_maint_move_list;		}}

⌨️ 快捷键说明

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