Patch to make progressive loading optional

Jon Colverson <[email protected]> Thu, 23 Dec 2004 05:29:31 +0000
Newsgroups gmane.comp.gnome.apps.gqview.devel
Message-ID <[email protected]>
Hello. I've attached a patch to gqview (1.5.4) that adds an option to 
enable or disable progressive loading. I wanted this because I don't 
like the visual results during decoding of progressive JPEGs and it 
seems that non-progressive decoding is faster (I haven't made any 
measurements to back that up).

The patch adds a gboolean parameter to image_loader_start() to specify 
whether the image should be loaded progressively or not. If not, it just 
uses gdk_pixbuf_new_from_file() to load the image, and then signals that 
it completed if there was no error. This obviously makes the interface 
unresponsive during loading.

Non-progressive loading is only used for loading the current image (not 
for preloading, or thumbnails etc.) If the user selects an image that is 
already partly pre-loaded, the pre-loading is cancelled and the image is 
reloaded non-progressively.

The diff is a bit hard to read for the part in image_read_ahead_check(), 
but it looks more complicated than it is.

Are you interested in including this patch in GQview? If so, I'll write 
the documentation for it.

Thanks.

-- 
Jon
progressive_option.diff (text/x-patch, 10.5 KB)
diff -ru gqview-1.5.4.orig/src/dupe.c gqview-1.5.4/src/dupe.c
--- gqview-1.5.4.orig/src/dupe.c	2004-11-08 23:28:15.000000000 +0000
+++ gqview-1.5.4/src/dupe.c	2004-12-21 04:15:04.000000000 +0000
@@ -1473,7 +1473,7 @@
 					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))
+					if (!image_loader_start(dw->img_loader, dupe_loader_done_cb, dw, TRUE))
 						{
 						image_sim_free(di->simd);
 						di->simd = image_sim_new();
diff -ru gqview-1.5.4.orig/src/globals.c gqview-1.5.4/src/globals.c
--- gqview-1.5.4.orig/src/globals.c	2004-10-22 18:31:42.000000000 +0100
+++ gqview-1.5.4/src/globals.c	2004-12-23 03:33:00.000000000 +0000
@@ -102,6 +102,8 @@
 
 gint dupe_custom_threshold = 99;
 
+gint progressive_image_loading = TRUE;
+
 gint debug = FALSE;
 
 /* logo & misc images */
diff -ru gqview-1.5.4.orig/src/gqview.h gqview-1.5.4/src/gqview.h
--- gqview-1.5.4.orig/src/gqview.h	2004-09-14 23:59:57.000000000 +0100
+++ gqview-1.5.4/src/gqview.h	2004-12-21 06:23:47.000000000 +0000
@@ -158,6 +158,8 @@
 
 extern gint dupe_custom_threshold;
 
+extern gint progressive_image_loading;
+
 extern gint debug;
 
 extern gint recent_list_max;
diff -ru gqview-1.5.4.orig/src/image.c gqview-1.5.4/src/image.c
--- gqview-1.5.4.orig/src/image.c	2004-11-01 21:06:22.000000000 +0000
+++ gqview-1.5.4/src/image.c	2004-12-21 07:50:08.000000000 +0000
@@ -1612,7 +1612,7 @@
 	imd->read_ahead_il = image_loader_new(imd->read_ahead_path);
 
 	image_loader_set_error_func(imd->read_ahead_il, image_read_ahead_error_cb, imd);
-	if (!image_loader_start(imd->read_ahead_il, image_read_ahead_done_cb, imd))
+	if (!image_loader_start(imd->read_ahead_il, image_read_ahead_done_cb, imd, TRUE))
 		{
 		image_read_ahead_cancel(imd);
 		image_complete_util(imd, TRUE);
@@ -1800,30 +1800,39 @@
 
 	if (imd->read_ahead_il)
 		{
-		imd->il = imd->read_ahead_il;
-		imd->read_ahead_il = NULL;
+		if (progressive_image_loading)
+			{
+			imd->il = imd->read_ahead_il;
+			imd->read_ahead_il = NULL;
 
-		/* override the old signals */
-		image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd);
-		image_loader_set_error_func(imd->il, image_load_error_cb, imd);
-		image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT);
+			/* override the old signals */
+			image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd);
+			image_loader_set_error_func(imd->il, image_load_error_cb, imd);
+			image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT);
 
 #ifdef IMAGE_THROTTLE_LARGER_IMAGES
-		image_load_buffer_throttle(imd->il);
+			image_load_buffer_throttle(imd->il);
 #endif
 
-		/* do this one directly (probably should add a set func) */
-		imd->il->func_done = image_load_done_cb;
+			/* do this one directly (probably should add a set func) */
+			imd->il->func_done = image_load_done_cb;
+
+			if (!imd->delay_flip)
+				{
+				if (imd->pixbuf) g_object_unref(imd->pixbuf);
+				imd->pixbuf = image_loader_get_pixbuf(imd->il);
+				if (imd->pixbuf) g_object_ref(imd->pixbuf);
+				}
 
-		if (!imd->delay_flip)
+			image_read_ahead_cancel(imd);
+			return TRUE;
+			}
+		else
 			{
-			if (imd->pixbuf) g_object_unref(imd->pixbuf);
-			imd->pixbuf = image_loader_get_pixbuf(imd->il);
-			if (imd->pixbuf) g_object_ref(imd->pixbuf);
+			if (debug) printf("dumping a partially preloaded image %s\n", imd->read_ahead_path);
+			image_read_ahead_cancel(imd);
+			return FALSE;
 			}
-
-		image_read_ahead_cancel(imd);
-		return TRUE;
 		}
 	else if (imd->read_ahead_pixbuf)
 		{
@@ -1877,7 +1886,7 @@
 	image_loader_set_error_func(imd->il, image_load_error_cb, imd);
 	image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT);
 
-	if (!image_loader_start(imd->il, image_load_done_cb, imd))
+	if (!image_loader_start(imd->il, image_load_done_cb, imd, progressive_image_loading))
 		{
 		if (debug) printf("image start error\n");
 
diff -ru gqview-1.5.4.orig/src/image-load.c gqview-1.5.4/src/image-load.c
--- gqview-1.5.4.orig/src/image-load.c	2004-09-28 16:45:39.000000000 +0100
+++ gqview-1.5.4/src/image-load.c	2004-12-21 06:35:44.000000000 +0000
@@ -365,7 +365,10 @@
 	il->idle_priority = priority;
 }
 
-gint image_loader_start(ImageLoader *il, void (*func_done)(ImageLoader *, gpointer), gpointer data_done)
+gint image_loader_start(ImageLoader *il,
+			void (*func_done)(ImageLoader *, gpointer),
+			gpointer data_done,
+			gboolean progressive)
 {
 	if (!il) return FALSE;
 
@@ -374,7 +377,29 @@
 	il->func_done = func_done;
 	il->data_done = data_done;
 
-	return image_loader_setup(il);
+	if (progressive)
+		{
+		if (debug) printf("progressive load for %s\n", il->path);
+		return image_loader_setup(il);
+		}
+	else
+		{
+		if (debug) printf("non-progressive load for %s\n", il->path);
+		if ((il->pixbuf = gdk_pixbuf_new_from_file(il->path, NULL)) != NULL)
+			{
+			image_loader_area_cb(NULL,
+					     0, 0,
+					     gdk_pixbuf_get_width(il->pixbuf),
+					     gdk_pixbuf_get_height(il->pixbuf),
+					     il);
+			image_loader_done(il);
+			return TRUE;
+			}
+		else
+			{
+			return FALSE;
+			}
+		}
 }
 
 gfloat image_loader_get_percent(ImageLoader *il)
@@ -398,7 +423,7 @@
 
 	il = image_loader_new(path);
 
-	success = image_loader_start(il, NULL, NULL);
+	success = image_loader_start(il, NULL, NULL, TRUE);
 
 	if (success && il->pixbuf)
 		{
diff -ru gqview-1.5.4.orig/src/image-load.h gqview-1.5.4/src/image-load.h
--- gqview-1.5.4.orig/src/image-load.h	2004-09-28 16:07:54.000000000 +0100
+++ gqview-1.5.4/src/image-load.h	2004-12-21 04:13:41.000000000 +0000
@@ -34,7 +34,10 @@
  */
 void image_loader_set_priority(ImageLoader *il, gint priority);
 
-gint image_loader_start(ImageLoader *il, void (*func_done)(ImageLoader *, gpointer), gpointer data_done);
+gint image_loader_start(ImageLoader *il,
+			void (*func_done)(ImageLoader *, gpointer),
+			gpointer data_done,
+			gboolean progressive);
 
 
 GdkPixbuf *image_loader_get_pixbuf(ImageLoader *il);
diff -ru gqview-1.5.4.orig/src/preferences.c gqview-1.5.4/src/preferences.c
--- gqview-1.5.4.orig/src/preferences.c	2004-11-08 23:04:32.000000000 +0000
+++ gqview-1.5.4/src/preferences.c	2004-12-21 07:04:57.000000000 +0000
@@ -109,6 +109,8 @@
 
 static gint enable_read_ahead_c;
 
+static gint progressive_image_loading_c;
+
 #if 0
 static gint place_dialogs_under_mouse_c;
 #endif
@@ -283,6 +285,8 @@
 
 	enable_read_ahead = enable_read_ahead_c;
 
+	progressive_image_loading = progressive_image_loading_c;
+
 #if 0
 	place_dialogs_under_mouse = place_dialogs_under_mouse_c;
 #endif
@@ -997,6 +1001,9 @@
 	add_check_button(enable_read_ahead, &enable_read_ahead_c,
 			 _("Preload next image"), vbox);
 
+	add_check_button(progressive_image_loading, &progressive_image_loading_c,
+			 _("Load images progressively"), vbox);
+
 	/* image tab */
 
 	vbox = gtk_vbox_new(FALSE, 0);
diff -ru gqview-1.5.4.orig/src/print.c gqview-1.5.4/src/print.c
--- gqview-1.5.4.orig/src/print.c	2004-11-08 23:57:38.000000000 +0000
+++ gqview-1.5.4/src/print.c	2004-12-21 04:18:00.000000000 +0000
@@ -1985,7 +1985,7 @@
 	if (!path) return FALSE;
 
 	pw->job_loader = image_loader_new(path);
-	if (!image_loader_start(pw->job_loader, print_job_render_image_loader_done, pw))
+	if (!image_loader_start(pw->job_loader, print_job_render_image_loader_done, pw, TRUE))
 		{
 		image_loader_free(pw->job_loader);
 		pw->job_loader= NULL;
@@ -2106,7 +2106,7 @@
 
 	image_loader_free(pw->job_loader);
 	pw->job_loader = image_loader_new(path);
-	if (!image_loader_start(pw->job_loader, print_job_render_proof_loader_done, pw))
+	if (!image_loader_start(pw->job_loader, print_job_render_proof_loader_done, pw, TRUE))
 		{
 		image_loader_free(pw->job_loader);
 		pw->job_loader = NULL;
diff -ru gqview-1.5.4.orig/src/rcfile.c gqview-1.5.4/src/rcfile.c
--- gqview-1.5.4.orig/src/rcfile.c	2004-09-13 22:22:11.000000000 +0100
+++ gqview-1.5.4/src/rcfile.c	2004-12-21 06:48:56.000000000 +0000
@@ -283,6 +283,8 @@
 
 	write_int_option(f, "custom_similarity_threshold", dupe_custom_threshold);
 
+	write_bool_option(f, "progressive_image_loading", progressive_image_loading);
+
 	fprintf(f,"\n##### Slideshow Options #####\n\n");
 
 	write_int_unit_option(f, "slideshow_delay", slideshow_delay, SLIDESHOW_SUBSECOND_PRECISION);
@@ -516,6 +518,9 @@
 		dupe_custom_threshold = read_int_option(f, option,
 			"custom_similarity_threshold", value, dupe_custom_threshold);
 
+		progressive_image_loading = read_bool_option(f, option,
+			"progressive_image_loading", value, progressive_image_loading);
+
 		/* slideshow options */
 
 		slideshow_delay = read_int_unit_option(f, option,
diff -ru gqview-1.5.4.orig/src/search.c gqview-1.5.4/src/search.c
--- gqview-1.5.4.orig/src/search.c	2004-11-08 23:59:56.000000000 +0000
+++ gqview-1.5.4/src/search.c	2004-12-21 04:18:38.000000000 +0000
@@ -1528,7 +1528,7 @@
 			{
 			sd->img_loader = image_loader_new(fd->path);
 			image_loader_set_error_func(sd->img_loader, search_file_load_done_cb, sd);
-			if (image_loader_start(sd->img_loader, search_file_load_done_cb, sd))
+			if (image_loader_start(sd->img_loader, search_file_load_done_cb, sd, TRUE))
 				{
 				return TRUE;
 				}
@@ -2004,7 +2004,7 @@
 
 			sd->img_loader = image_loader_new(sd->search_similarity_path);
 			image_loader_set_error_func(sd->img_loader, search_similarity_load_done_cb, sd);
-			if (image_loader_start(sd->img_loader, search_similarity_load_done_cb, sd))
+			if (image_loader_start(sd->img_loader, search_similarity_load_done_cb, sd, TRUE))
 				{
 				return;
 				}
diff -ru gqview-1.5.4.orig/src/thumb.c gqview-1.5.4/src/thumb.c
--- gqview-1.5.4.orig/src/thumb.c	2004-10-23 05:07:21.000000000 +0100
+++ gqview-1.5.4/src/thumb.c	2004-12-21 04:19:24.000000000 +0000
@@ -163,7 +163,7 @@
 
 		thumb_loader_setup(tl, tl->path);
 
-		if (!image_loader_start(tl->il, thumb_loader_done_cb, tl))
+		if (!image_loader_start(tl->il, thumb_loader_done_cb, tl, TRUE))
 			{
 			image_loader_free(tl->il);
 			tl->il = NULL;
@@ -333,7 +333,7 @@
 		thumb_loader_setup(tl, tl->path);
 		}
 
-	if (!image_loader_start(tl->il, thumb_loader_done_cb, tl))
+	if (!image_loader_start(tl->il, thumb_loader_done_cb, tl, TRUE))
 		{
 		/* try from original if cache attempt */
 		if (tl->from_cache)
@@ -342,7 +342,7 @@
 			print_term(_("Thumbnail image in cache failed to load, trying to recreate.\n"));
 
 			thumb_loader_setup(tl, tl->path);
-			if (image_loader_start(tl->il, thumb_loader_done_cb, tl)) return TRUE;
+			if (image_loader_start(tl->il, thumb_loader_done_cb, tl, TRUE)) return TRUE;
 			}
 		/* mark failed thumbnail in cache with 0 byte file */
 		if (enable_thumb_caching)