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;
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);
#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 {
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);
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;
{
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);
}
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;
gboolean use_xvpics;
gboolean spec_standard;
guint quality;
+ gboolean use_exif;
} thumbnails;
/* file filtering */
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
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;
WRITE_BOOL(thumbnails.use_xvpics);
WRITE_BOOL(thumbnails.spec_standard);
WRITE_UINT(thumbnails.quality);
+ WRITE_BOOL(thumbnails.use_exif);
WRITE_SUBTITLE("File sorting Options");
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);
{
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);
}