summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2003-10-14 16:00:32 +0000
committerAlexander Larsson <alexl@src.gnome.org>2003-10-14 16:00:32 +0000
commitf950720caa6d1ff3b805ab23a1267d0dcfd60282 (patch)
tree9cc2907667c53f86a1afb277509c010a191d97a9 /components
parentb5fd55155ac4dea22949c5fd71525055166f4720 (diff)
downloadnautilus-f950720caa6d1ff3b805ab23a1267d0dcfd60282.tar.gz
Support for exif info.
2003-10-14 Alexander Larsson <alexl@redhat.com> * acconfig.h: * components/image_properties/Makefile.am: * components/image_properties/nautilus-image-properties-view.c: * configure.in: Support for exif info.
Diffstat (limited to 'components')
-rw-r--r--components/image_properties/Makefile.am6
-rw-r--r--components/image_properties/nautilus-image-properties-view.c229
2 files changed, 206 insertions, 29 deletions
diff --git a/components/image_properties/Makefile.am b/components/image_properties/Makefile.am
index dd96e54b5..073497c55 100644
--- a/components/image_properties/Makefile.am
+++ b/components/image_properties/Makefile.am
@@ -11,7 +11,8 @@ INCLUDES = \
-I$(top_srcdir) \
-I$(top_builddir) \
$(DISABLE_DEPRECATED_CFLAGS) \
- $(COMPONENT_CFLAGS)
+ $(COMPONENT_CFLAGS) \
+ $(EXIF_CFLAGS)
bonobodir = $(libdir)/bonobo
bonobo_LTLIBRARIES = libnautilus-image-properties-view.la
@@ -23,7 +24,8 @@ libnautilus_image_properties_view_la_SOURCES = \
libnautilus_image_properties_view_la_LIBADD = \
$(top_builddir)/libnautilus/libnautilus.la \
- $(COMPONENT_LIBS)
+ $(COMPONENT_LIBS) \
+ $(EXIF_LIBS)
libnautilus_image_properties_view_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/components/image_properties/nautilus-image-properties-view.c b/components/image_properties/nautilus-image-properties-view.c
index 92bdaea7b..21024ca37 100644
--- a/components/image_properties/nautilus-image-properties-view.c
+++ b/components/image_properties/nautilus-image-properties-view.c
@@ -32,6 +32,18 @@
#include <eel/eel-gnome-extensions.h>
#include <string.h>
+#ifdef HAVE_EXIF
+ #include <libexif/exif-data.h>
+ #include <libexif/exif-ifd.h>
+ #include <libexif/exif-loader.h>
+ #include <gtk/gtkliststore.h>
+ #include <gtk/gtktreestore.h>
+ #include <gtk/gtktreeview.h>
+ #include <gtk/gtkscrolledwindow.h>
+ #include <gtk/gtkcellrenderertext.h>
+ #include <eel/eel-vfs-extensions.h>
+#endif
+
#define LOAD_BUFFER_SIZE 8192
struct NautilusImagePropertiesViewDetails {
@@ -41,8 +53,22 @@ struct NautilusImagePropertiesViewDetails {
GnomeVFSAsyncHandle *vfs_handle;
GdkPixbufLoader *loader;
gboolean got_size;
+ gboolean pixbuf_still_loading;
char buffer[LOAD_BUFFER_SIZE];
+ int width;
+ int height;
+#ifdef HAVE_EXIF
+ ExifLoader *exifldr;
+#endif /*HAVE_EXIF*/
+};
+
+#ifdef HAVE_EXIF
+struct ExifAttribute {
+ ExifTag tag;
+ char *value;
+ gboolean found;
};
+#endif /*HAVE_EXIF*/
enum {
PROP_URI,
@@ -57,8 +83,9 @@ nautilus_image_properties_view_finalize (GObject *object)
view = NAUTILUS_IMAGE_PROPERTIES_VIEW (object);
- if (view->details->vfs_handle != NULL)
+ if (view->details->vfs_handle != NULL) {
gnome_vfs_async_cancel (view->details->vfs_handle);
+ }
view->details->vfs_handle = NULL;
g_free (view->details->location);
@@ -75,23 +102,162 @@ file_closed_callback (GnomeVFSAsyncHandle *handle,
{
}
+#ifdef HAVE_EXIF
+static char *
+exif_string_to_utf8 (const char *exif_str)
+{
+ char *utf8_str;
+
+ if (g_utf8_validate (exif_str, -1, NULL)) {
+ return g_strdup (exif_str);
+ }
+
+ utf8_str = g_locale_to_utf8 (exif_str, -1, NULL, NULL, NULL);
+ if (utf8_str != NULL) {
+ return utf8_str;
+ }
+
+ return eel_make_valid_utf8 (exif_str);
+}
+
+static void
+exif_content_callback (ExifContent *content, gpointer data)
+{
+ struct ExifAttribute *attribute;
+
+ attribute = (struct ExifAttribute *)data;
+ if (attribute->found) {
+ return;
+ }
+
+ attribute->value = g_strdup (exif_content_get_value (content, attribute->tag));
+ if (attribute->value != NULL) {
+ attribute->found = TRUE;
+ }
+}
+
+static char *
+exifdata_get_tag_name_utf8 (ExifTag tag)
+{
+ return exif_string_to_utf8 (exif_tag_get_name (tag));
+}
+
+static char *
+exifdata_get_tag_value_utf8 (ExifData *data, ExifTag tag)
+{
+ struct ExifAttribute attribute;
+ char *utf8_value;
+
+ attribute.tag = tag;
+ attribute.value = NULL;
+ attribute.found = FALSE;
+
+ exif_data_foreach_content (data, exif_content_callback, &attribute);
+
+ if (attribute.found) {
+ utf8_value = exif_string_to_utf8 (attribute.value);
+ g_free (attribute.value);
+ } else {
+ utf8_value = NULL;
+ }
+
+ return utf8_value;
+}
+
+static void
+append_tag_value_pair (GString *string, ExifData *data, ExifTag tag, gchar *description)
+{
+ char *utf_attribute;
+ char *utf_value;
+
+ utf_attribute = exifdata_get_tag_name_utf8 (tag);
+ utf_value = exifdata_get_tag_value_utf8 (data, tag);
+
+ if ((utf_attribute == NULL) || (utf_value == NULL)) {
+ g_free (utf_attribute);
+ g_free (utf_value);
+ return;
+ }
+
+ g_string_append_printf (string, "<b>%s:</b> %s\n", (description != NULL) ? description : utf_attribute, utf_value);
+
+ g_free (utf_attribute);
+ g_free (utf_value);
+}
+
+static void
+append_exifdata_string (ExifData *exifdata, GString *string)
+{
+ gchar *camera_make, *camera_model;
+
+ if (exifdata->ifd[0] && exifdata->ifd[0]->count) {
+ camera_make = exifdata_get_tag_value_utf8 (exifdata, EXIF_TAG_MAKE);
+ camera_model = exifdata_get_tag_value_utf8 (exifdata, EXIF_TAG_MODEL);
+ if (camera_make != NULL) {
+ g_string_append_printf (string, "<b>%s:</b> %s %s\n",
+ _("Camera"),
+ camera_make,
+ camera_model);
+ }
+ append_tag_value_pair (string, exifdata, EXIF_TAG_DATE_TIME, _("Date Taken"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_EXPOSURE_TIME, _("Exposure Time"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_EXPOSURE_PROGRAM, _("Exposure Program"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_APERTURE_VALUE, _("Aperture Value"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_METERING_MODE, _("Metering Mode"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_FLASH,_("Flash Fired"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_FOCAL_LENGTH,_("Focal Lenght"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_SHUTTER_SPEED_VALUE, _("Shutter Speed"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_ISO_SPEED_RATINGS, _("ISO Speed Rating"));
+ append_tag_value_pair (string, exifdata, EXIF_TAG_SOFTWARE, _("Software"));
+
+ }
+}
+#endif /*HAVE_EXIF*/
+
static void
load_finished (NautilusImagePropertiesView *view)
{
+ GdkPixbufFormat *format;
+ char *name, *desc;
+ GString *str;
+
+ if (view->details->got_size) {
+ str = g_string_new (NULL);
+ format = gdk_pixbuf_loader_get_format (view->details->loader);
+
+ name = gdk_pixbuf_format_get_name (format);
+ desc = gdk_pixbuf_format_get_description (format);
+ g_string_append_printf (str, _("<b>Image Type:</b> %s (%s)\n<b>Resolution:</b> %dx%d pixels\n"),
+ name, desc, view->details->width, view->details->height);
+ g_free (name);
+ g_free (desc);
+
+#ifdef HAVE_EXIF
+ append_exifdata_string (exif_loader_get_data (view->details->exifldr), str);
+#endif /*HAVE_EXIF*/
+
+ gtk_label_set_markup (GTK_LABEL (view->details->resolution), str->str);
+ g_string_free (str, TRUE);
+ } else {
+ gtk_label_set_text (GTK_LABEL (view->details->resolution), _("Failed to load image information"));
+ }
+
if (view->details->loader != NULL) {
gdk_pixbuf_loader_close (view->details->loader, NULL);
g_object_unref (view->details->loader);
view->details->loader = NULL;
}
+#ifdef HAVE_EXIF
+ if (view->details->exifldr != NULL) {
+ exif_loader_unref (view->details->exifldr);
+ view->details->exifldr = NULL;
+ }
+#endif /*HAVE_EXIF*/
if (view->details->vfs_handle != NULL) {
gnome_vfs_async_close (view->details->vfs_handle, file_closed_callback, NULL);
view->details->vfs_handle = NULL;
}
-
- if (!view->details->got_size) {
- gtk_label_set_text (GTK_LABEL (view->details->resolution), _("Failed to load image information"));
- }
}
static void
@@ -103,16 +269,31 @@ file_read_callback (GnomeVFSAsyncHandle *vfs_handle,
gpointer callback_data)
{
NautilusImagePropertiesView *view;
+#ifdef HAVE_EXIF
+ int exif_still_loading;
+#endif
view = NAUTILUS_IMAGE_PROPERTIES_VIEW (callback_data);
if (result == GNOME_VFS_OK && bytes_read != 0) {
- if (!gdk_pixbuf_loader_write (view->details->loader,
- buffer,
- bytes_read,
- NULL)) {
- result = GNOME_VFS_ERROR_WRONG_FORMAT;
- } else if (!view->details->got_size) {
+#ifdef HAVE_EXIF
+ exif_still_loading = exif_loader_write (view->details->exifldr,
+ buffer,
+ bytes_read);
+#endif
+ if (view->details->pixbuf_still_loading) {
+ if (!gdk_pixbuf_loader_write (view->details->loader,
+ buffer,
+ bytes_read,
+ NULL)) {
+ view->details->pixbuf_still_loading = FALSE;
+ }
+ }
+ if (view->details->pixbuf_still_loading
+#ifdef HAVE_EXIF
+ && (exif_still_loading == 1)
+#endif
+ ) {
gnome_vfs_async_read (view->details->vfs_handle,
view->details->buffer,
sizeof (view->details->buffer),
@@ -121,7 +302,6 @@ file_read_callback (GnomeVFSAsyncHandle *vfs_handle,
return;
}
}
-
load_finished (view);
}
@@ -132,24 +312,13 @@ size_prepared_callback (GdkPixbufLoader *loader,
gpointer callback_data)
{
NautilusImagePropertiesView *view;
- GdkPixbufFormat *format;
- char *str;
- char *name, *desc;
view = NAUTILUS_IMAGE_PROPERTIES_VIEW (callback_data);
-
- format = gdk_pixbuf_loader_get_format (loader);
-
- name = gdk_pixbuf_format_get_name (format);
- desc = gdk_pixbuf_format_get_description (format);
- str = g_strdup_printf (_("<b>Image Type:</b> %s (%s)\n<b>Resolution:</b> %dx%d pixels\n"),
- name, desc, width, height);
- gtk_label_set_markup (GTK_LABEL (view->details->resolution), str);
- g_free (str);
- g_free (name);
- g_free (desc);
+ view->details->height = height;
+ view->details->width = width;
view->details->got_size = TRUE;
+ view->details->pixbuf_still_loading = FALSE;
}
static void
@@ -167,6 +336,12 @@ file_opened_callback (GnomeVFSAsyncHandle *vfs_handle,
}
view->details->loader = gdk_pixbuf_loader_new ();
+ view->details->pixbuf_still_loading = TRUE;
+ view->details->width = 0;
+ view->details->height = 0;
+#ifdef HAVE_EXIF
+ view->details->exifldr = exif_loader_new ();
+#endif /*HAVE_EXIF*/
g_signal_connect (view->details->loader, "size_prepared",
G_CALLBACK (size_prepared_callback), view);
@@ -257,7 +432,7 @@ nautilus_image_properties_view_init (NautilusImagePropertiesView *view)
gtk_box_pack_start (GTK_BOX (view->details->vbox),
view->details->resolution,
FALSE, TRUE, 2);
-
+
gtk_widget_show_all (view->details->vbox);
bonobo_control_construct (BONOBO_CONTROL (view), view->details->vbox);