changeset 1060:1e2de04c6fc4

added option to use exif thumbnails - it requires exiv2 0.18 or the current svn - it is disabled by default because the exif thumbnails may be outdated if the image was edited
author nadvornik
date Sat, 11 Oct 2008 20:19:48 +0000
parents 008dfb7b1e42
children 156a58224c85
files src/exif.c src/exif.h src/exiv2.cc src/image-load.c src/options.c src/options.h src/preferences.c src/rcfile.c src/thumb.c
diffstat 9 files changed, 49 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/exif.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/exif.c	Sat Oct 11 20:19:48 2008 +0000
@@ -1605,7 +1605,7 @@
 
 static GList *exif_unmap_list = 0;
 
-guchar *exif_get_preview(ExifData *exif, guint *data_len)
+guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height)
 {
 	int success;
 	guint offset;
--- a/src/exif.h	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/exif.h	Sat Oct 11 20:19:48 2008 +0000
@@ -158,7 +158,7 @@
 gint exif_jpeg_parse_color(ExifData *exif, guchar *data, guint size);
 
 /*raw support */
-guchar *exif_get_preview(ExifData *exif, guint *data_len);
+guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height);
 void exif_free_preview(guchar *buf);
 
 
--- a/src/exiv2.cc	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/exiv2.cc	Sat Oct 11 20:19:48 2008 +0000
@@ -608,13 +608,15 @@
 
 #if EXIV2_TEST_VERSION(0,17,90)
 
-guchar *exif_get_preview(ExifData *exif, guint *data_len)
+guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height)
 {
 	if (!exif) return NULL;
 
 	const char* path = exif->image->io().path().c_str();
 	/* given image pathname, first do simple (and fast) file extension test */
-	if (!filter_file_class(path, FORMAT_CLASS_RAWIMAGE)) return NULL;
+	gboolean is_raw = filter_file_class(path, FORMAT_CLASS_RAWIMAGE);
+	
+	if (!is_raw && requested_width == 0) return NULL;
 
 	try {
 
@@ -624,7 +626,29 @@
 
 		if (!list.empty())
 			{
-			Exiv2::PreviewPropertiesList::iterator pos = --list.end();
+			Exiv2::PreviewPropertiesList::iterator pos;
+			Exiv2::PreviewPropertiesList::iterator last = --list.end();
+			
+			if (requested_width == 0)
+				{
+				pos = last; // the largest
+				}
+			else
+				{
+				pos = list.begin();
+				while (pos != last)
+					{
+					if (pos->width_ >= (uint32_t)requested_width &&
+					    pos->height_ >= (uint32_t)requested_height) break;
+					++pos;
+					}
+				
+				// we are not interested in smaller thumbnails in normal image formats - we can use full image instead
+				if (!is_raw) 
+					{
+					if (pos->width_ < (uint32_t)requested_width || pos->height_ < (uint32_t)requested_height) return NULL; 
+					}
+				}
 
 			Exiv2::PreviewImage image = loader.getPreviewImage(*pos);
 
@@ -683,7 +707,7 @@
 
 static GList *exif_unmap_list = 0;
 
-extern "C" guchar *exif_get_preview(ExifData *exif, guint *data_len)
+extern "C" guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height)
 {
 	unsigned long offset;
 
--- a/src/image-load.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/image-load.c	Sat Oct 11 20:19:48 2008 +0000
@@ -607,12 +607,15 @@
 		{
 		ExifData *exif = exif_read_fd(il->fd);
 
-		il->mapped_file = exif_get_preview(exif, &il->bytes_total);
-		
+		if (options->thumbnails.use_exif)
+			il->mapped_file = exif_get_preview(exif, &il->bytes_total, il->requested_width, il->requested_height);
+		else
+			il->mapped_file = exif_get_preview(exif, &il->bytes_total, 0, 0); /* get the largest available preview image or NULL for normal images*/
+
 		if (il->mapped_file)
 			{
 			il->preview = TRUE;
-			DEBUG_1("Raw file %s contains embedded image", il->fd->path);
+			DEBUG_1("Usable reduced size (preview) image loaded from file %s", il->fd->path);
 			}
 		exif_free_fd(il->fd, exif);
 		}
--- a/src/options.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/options.c	Sat Oct 11 20:19:48 2008 +0000
@@ -158,6 +158,7 @@
 	options->thumbnails.quality = GDK_INTERP_TILES;
 	options->thumbnails.spec_standard = TRUE;
 	options->thumbnails.use_xvpics = TRUE;
+	options->thumbnails.use_exif = FALSE;
 
 	options->tree_descend_subdirs = FALSE;
 	options->update_on_time_change = TRUE;
--- a/src/options.h	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/options.h	Sat Oct 11 20:19:48 2008 +0000
@@ -94,6 +94,7 @@
 		gboolean use_xvpics;
 		gboolean spec_standard;
 		guint quality;
+		gboolean use_exif;
 	} thumbnails;
 
 	/* file filtering */
--- a/src/preferences.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/preferences.c	Sat Oct 11 20:19:48 2008 +0000
@@ -255,6 +255,7 @@
 	options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
 	options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
 	options->thumbnails.fast = c_options->thumbnails.fast;
+	options->thumbnails.use_exif = c_options->thumbnails.use_exif;
 #if 0
 	options->thumbnails.use_xvpics = c_options->thumbnails.use_xvpics;
 #endif
@@ -978,6 +979,9 @@
 	pref_checkbox_new_int(group, _("Faster jpeg thumbnailing (may reduce quality)"),
 			      options->thumbnails.fast, &c_options->thumbnails.fast);
 
+	pref_checkbox_new_int(group, _("Use EXIF thumbnails when available"),
+			      options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
+
 	group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
 
 	c_options->slideshow.delay = options->slideshow.delay;
--- a/src/rcfile.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/rcfile.c	Sat Oct 11 20:19:48 2008 +0000
@@ -403,6 +403,7 @@
 	WRITE_BOOL(thumbnails.use_xvpics);
 	WRITE_BOOL(thumbnails.spec_standard);
 	WRITE_UINT(thumbnails.quality);
+	WRITE_BOOL(thumbnails.use_exif);
 
 
 	WRITE_SUBTITLE("File sorting Options");
@@ -776,6 +777,7 @@
 		READ_BOOL(thumbnails.use_xvpics);
 		READ_BOOL(thumbnails.spec_standard);
 		READ_UINT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
+		READ_BOOL(thumbnails.use_exif);
 
 		/* file sorting options */
 		READ_UINT(file_sort.method);
--- a/src/thumb.c	Tue Oct 07 19:34:11 2008 +0000
+++ b/src/thumb.c	Sat Oct 11 20:19:48 2008 +0000
@@ -471,7 +471,11 @@
 {
 	ThumbLoader *tl;
 
-	if (options->thumbnails.spec_standard)
+	/* non-std thumb loader is more effective for configurations with disabled caching
+	   because it loads the thumbnails at the required size. loader_std loads
+	   the thumbnails at the sizes appropriate for standard cache (typically 256x256 pixels)
+	   and then performs one additional scaling */
+	if (options->thumbnails.spec_standard && options->thumbnails.enable_caching)
 		{
 		return (ThumbLoader *)thumb_loader_std_new(width, height);
 		}