[gthumb] Use exiv2 to extract thumbnails
- From: Michael J. Chudobiak <mjc src gnome org>
- To: svn-commits-list gnome org
- Subject: [gthumb] Use exiv2 to extract thumbnails
- Date: Fri, 26 Jun 2009 16:32:39 +0000 (UTC)
commit 7cf9e991ae0273173c8e265da71a5276b0bbe0b4
Author: Michael J. Chudobiak <mjc avtechpulse com>
Date: Fri Jun 26 12:32:16 2009 -0400
Use exiv2 to extract thumbnails
libgthumb/file-utils.c | 58 +++++++++++++++++++++++++++++++++++++++++
libgthumb/file-utils.h | 4 ++-
libgthumb/gth-exiv2-utils.cpp | 24 +++++++++++++++++
libgthumb/gth-exiv2-utils.hpp | 4 +++
src/dlg-photo-importer.c | 35 +++++++++++++++----------
5 files changed, 110 insertions(+), 15 deletions(-)
---
diff --git a/add-include-prefix b/add-include-prefix
old mode 100755
new mode 100644
diff --git a/autogen.sh b/autogen.sh
old mode 100755
new mode 100644
diff --git a/libgthumb/file-utils.c b/libgthumb/file-utils.c
index 7112a27..0a085b3 100644
--- a/libgthumb/file-utils.c
+++ b/libgthumb/file-utils.c
@@ -2174,6 +2174,59 @@ free_cache (void)
}
+const char * get_embedded_thumb (const char *local_path, const char *tmp_thumb);
+
+GdkPixbuf*
+gth_extract_embedded_thumbnail (GFile *gfile, int size)
+{
+ GdkPixbuf *pixbuf = NULL;
+ char *local_path = g_file_get_path (gfile);
+
+ if (local_path) {
+ char *tmp_dir = get_temp_dir_name ();
+ char *filename = g_strconcat (tmp_dir, "/thumb", NULL);
+
+ const char *ext = get_embedded_thumb (local_path, filename);
+
+ if (ext && ext[0] != 0) {
+ char *full_filename = g_strconcat (filename, ext, NULL);
+ if (path_is_file (full_filename)) {
+ if (size > 0)
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (full_filename, size, size, TRUE, NULL);
+ else
+ pixbuf = gdk_pixbuf_new_from_file (full_filename, NULL);
+ }
+ dir_remove_recursive (tmp_dir);
+ }
+
+ /* size sanity check */
+ if (pixbuf) {
+ int real_w = 0;
+ int real_h = 0;
+ int w, h;
+
+ w = gdk_pixbuf_get_width (pixbuf);
+ h = gdk_pixbuf_get_height (pixbuf);
+
+ gdk_pixbuf_get_file_info (local_path, &real_w, &real_h);
+
+ if ((w>0) && (h>0) && (real_w>0) && (real_h>0)) {
+ if (((real_w > real_h) && (h > w)) ||
+ ((real_w < real_h) && (w > h))) {
+ /* reject thumbnails where the orientation is
+ obviously wrong */
+ g_object_unref (pixbuf);
+ pixbuf = NULL;
+ }
+ }
+ }
+ }
+
+ g_free (local_path);
+ return pixbuf;
+}
+
+
static GdkPixbuf*
get_pixbuf_using_external_converter (FileData *file,
int requested_width,
@@ -2391,6 +2444,11 @@ gth_pixbuf_new_from_file (FileData *file,
return NULL;
}
+ /* use exiv2 to extract embedded thumbnails, if possible */
+ if ((pixbuf == NULL)
+ && (requested_width > 0))
+ pixbuf = gth_extract_embedded_thumbnail (file->gfile, requested_width);
+
#ifdef HAVE_LIBOPENRAW
/* Raw thumbnails - using libopenraw is much faster than using dcraw for
thumbnails. Use libopenraw for full raw images too, once it matures. */
diff --git a/libgthumb/file-utils.h b/libgthumb/file-utils.h
index d5cc44a..89c642d 100644
--- a/libgthumb/file-utils.h
+++ b/libgthumb/file-utils.h
@@ -218,8 +218,10 @@ gboolean is_local_file (const char *filename);
void free_cache (void);
GHashTable * read_dot_hidden_file (const char *uri);
-/* Pixbuf + VFS */
+/* Pixbuf */
+GdkPixbuf* gth_extract_embedded_thumbnail (GFile *gfile,
+ int size);
GdkPixbuf* gth_pixbuf_new_from_file (FileData *file,
GError **error,
int requested_width,
diff --git a/libgthumb/gth-exiv2-utils.cpp b/libgthumb/gth-exiv2-utils.cpp
index a0909ce..03b4e5e 100644
--- a/libgthumb/gth-exiv2-utils.cpp
+++ b/libgthumb/gth-exiv2-utils.cpp
@@ -573,6 +573,30 @@ mandatory_string (Exiv2::ExifData &checkdata,
checkdata[tag] = value;
}
+
+extern "C"
+const char *
+get_embedded_thumb (const char *local_file, const char *tmp_thumb)
+{
+ try {
+ Exiv2::Image::AutoPtr image1 = Exiv2::ImageFactory::open (local_file);
+ g_assert (image1.get() != 0);
+
+ image1->readMetadata();
+ Exiv2::ExifData &ed = image1->exifData();
+ Exiv2::ExifThumbC et(ed);
+
+ et.writeFile(tmp_thumb);
+ return et.extension();
+ }
+ catch (const Exiv2::AnyError& error) {
+ std::cerr << error << "\n";
+ return NULL;
+ }
+
+}
+
+
extern "C"
void
write_metadata (const char *from_file,
diff --git a/libgthumb/gth-exiv2-utils.hpp b/libgthumb/gth-exiv2-utils.hpp
index 6dd9374..9d961db 100644
--- a/libgthumb/gth-exiv2-utils.hpp
+++ b/libgthumb/gth-exiv2-utils.hpp
@@ -33,6 +33,10 @@ extern "C" GList *
read_exiv2_sidecar (const char *uri,
GList *metadata);
+extern "C" const char *
+get_embedded_thumb (const char *local_file,
+ const char *tmp_thumb);
+
extern "C" void
write_metadata (const char *from_file,
const char *to_file,
diff --git a/src/dlg-photo-importer.c b/src/dlg-photo-importer.c
index c40c3bc..7c0245c 100644
--- a/src/dlg-photo-importer.c
+++ b/src/dlg-photo-importer.c
@@ -50,6 +50,7 @@
#include "rotation-utils.h"
#include "main.h"
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnomeui/gnome-desktop-thumbnail.h>
@@ -779,7 +780,6 @@ gfile_get_preview (DialogData *data,
GIcon *gicon;
GtkIconTheme *theme;
GFileInfo *info;
- char *uri;
const char *mime_type;
mime_type = gfile_get_mime_type (gfile, FALSE);
@@ -795,11 +795,18 @@ gfile_get_preview (DialogData *data,
return NULL;
if (data->generate_previews && is_relevant_mime_type (gfile, TRUE, FALSE)) {
- uri = g_file_get_uri (gfile);
+
+ pixbuf = gth_extract_embedded_thumbnail (gfile, size);
+ if (pixbuf) {
+ gfile_debug (DEBUG_INFO, "using embedded thumbnail for", gfile);
+ return pixbuf;
+ }
+
+ char *uri = g_file_get_uri (gfile);
pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (data->factory, uri, mime_type);
g_free (uri);
-
if (pixbuf) {
+ gfile_debug (DEBUG_INFO, "using generated thumbnail for", gfile);
int w = gdk_pixbuf_get_width (pixbuf);
int h = gdk_pixbuf_get_height (pixbuf);
if (scale_keeping_ratio (&w, &h, size, size, FALSE)) {
@@ -807,20 +814,20 @@ gfile_get_preview (DialogData *data,
pixbuf = gdk_pixbuf_scale_simple (tmp, w, h, GDK_INTERP_BILINEAR);
g_object_unref (tmp);
}
+ return pixbuf;
}
- if (pixbuf) {
- gfile_debug (DEBUG_INFO, "using thumbnail for", gfile);
- } else {
- char *local_path = g_file_get_path (gfile);
+ char *local_path = g_file_get_path (gfile);
+ if (local_path)
pixbuf = gdk_pixbuf_new_from_file_at_scale (local_path, size, size, TRUE, NULL);
- g_free (local_path);
- if (pixbuf) {
- gfile_debug (DEBUG_INFO, "using gdk pixbuf loader for", gfile);
- GdkPixbuf *tmp = pixbuf;
- pixbuf = gdk_pixbuf_apply_embedded_orientation (tmp);
- g_object_unref (tmp);
- }
+ g_free (local_path);
+
+ if (pixbuf) {
+ gfile_debug (DEBUG_INFO, "using gdk pixbuf loader for", gfile);
+ GdkPixbuf *tmp = pixbuf;
+ pixbuf = gdk_pixbuf_apply_embedded_orientation (tmp);
+ g_object_unref (tmp);
+ return pixbuf;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]