[gnome-color-manager] Add optional exif2 support so we can get properties of RAW files too



commit 926ecf7a8f086dd0f2f2c63b1ba0b9f3700d8cdc
Author: Richard Hughes <richard hughsie com>
Date:   Mon May 24 13:44:19 2010 +0100

    Add optional exif2 support so we can get properties of RAW files too
    
    Note: This is implimented as a seporate executable that is used
    to avoid either compiling GCM with g++ and to avoid weird linker
    errors on random platforms

 configure.ac                        |   13 +++++
 contrib/gnome-color-manager.spec.in |    2 +
 data/tests/Makefile.am              |    1 +
 data/tests/test.kdc                 |  Bin 0 -> 92675 bytes
 src/.gitignore                      |    1 +
 src/Makefile.am                     |    8 +++
 src/gcm-exif.c                      |   83 +++++++++++++++++++++++++++++++++
 src/gcm-helper-exiv.cpp             |   87 +++++++++++++++++++++++++++++++++++
 src/gcm-self-test.c                 |   13 +++++
 9 files changed, 208 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4cbdaa7..1812054 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,7 @@ AC_CONFIG_MACRO_DIR([m4])
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 
 AC_PROG_CC
+AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_RANLIB
 LT_INIT
@@ -145,6 +146,17 @@ if test x$enable_sane = xyes; then
 	AC_DEFINE(GCM_USE_SANE,1,[Use SANE support for detecting scanners])
 fi
 
+AC_ARG_ENABLE(exiv, AS_HELP_STRING([--enable-exiv],[Enable EXIV support for RAW support]), enable_exiv=$enableval,
+				   enable_exiv=yes)
+dnl **** Check for EXIV ****
+if test x$enable_exiv != xno; then
+	PKG_CHECK_MODULES(EXIV, exiv2)
+fi
+AM_CONDITIONAL(GCM_USE_EXIV, test x$enable_exiv = xyes)
+if test x$enable_exiv = xyes; then
+	AC_DEFINE(GCM_USE_EXIV,1,[Use EXIV support for detecting scanners])
+fi
+
 PKG_CHECK_MODULES(CANBERRA, libcanberra-gtk >= $CANBERRA_REQUIRED)
 
 PKG_CHECK_MODULES(EXIF, libexif)
@@ -269,6 +281,7 @@ echo "
         cppflags:                  ${CPPFLAGS}
         PackageKit integration:    ${enable_packagekit}
         SANE support:              ${enable_sane}
+        RAW support:               ${enable_exiv}
         building unit tests:       ${enable_tests}
 "
 
diff --git a/contrib/gnome-color-manager.spec.in b/contrib/gnome-color-manager.spec.in
index a79decd..08f3786 100644
--- a/contrib/gnome-color-manager.spec.in
+++ b/contrib/gnome-color-manager.spec.in
@@ -40,6 +40,7 @@ BuildRequires: cups-devel
 BuildRequires: sane-backends-devel
 BuildRequires: libtiff-devel
 BuildRequires: libexif-devel
+BuildRequires: exiv2-devel
 BuildRequires: libcanberra-devel
 BuildRequires: libnotify-devel
 BuildRequires: glib2-devel >= 2.25.1
@@ -92,6 +93,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &> /dev/null || :
 %doc AUTHORS COPYING NEWS README
 /lib/udev/rules.d/*.rules
 %{_bindir}/gcm-*
+%{_libexecdir}/*
 %dir %{_datadir}/gnome-color-manager
 %{_datadir}/gnome-color-manager/gcm-*.ui
 %dir %{_datadir}/gnome-color-manager/targets
diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index a745113..451b0ab 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -2,6 +2,7 @@ TEST_FILES =						\
 	test.tif					\
 	test.png					\
 	test.jpg					\
+	test.kdc					\
 	cie-widget.png					\
 	gamma-widget.png				\
 	ibm-t61.icc					\
diff --git a/data/tests/test.kdc b/data/tests/test.kdc
new file mode 100644
index 0000000..3235462
Binary files /dev/null and b/data/tests/test.kdc differ
diff --git a/src/.gitignore b/src/.gitignore
index 55d7092..ef822fc 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -13,5 +13,6 @@ gcm-dump-profile
 gcm-fix-profile
 gcm-self-test
 gcm-install-system-wide
+gcm-helper-exiv
 org.gnome.ColorManager.h
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 684b583..61e0173 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ INCLUDES =						\
 	$(SANE_CFLAGS)					\
 	$(TIFF_CFLAGS)					\
 	$(EXIF_CFLAGS)					\
+	$(EXIV_CFLAGS)					\
 	$(NOTIFY_CFLAGS)				\
 	$(CANBERRA_CFLAGS)				\
 	$(DBUS_GLIB_CFLAGS)				\
@@ -18,6 +19,7 @@ INCLUDES =						\
 	-DGNOME_DESKTOP_USE_UNSTABLE_API		\
 	$(GUDEV_CFLAGS)					\
 	-DBINDIR=\"$(bindir)\"				\
+	-DLIBEXECDIR=\"$(libexecdir)\"			\
 	-DSBINDIR=\"$(sbindir)\"			\
 	-DDATADIR=\"$(datadir)\"			\
 	-DSYSCONFDIR=\""$(sysconfdir)"\"		\
@@ -112,6 +114,12 @@ bin_PROGRAMS =						\
 	gcm-picker					\
 	gcm-import
 
+if GCM_USE_EXIV
+libexec_PROGRAMS = gcm-helper-exiv
+gcm_helper_exiv_SOURCES = gcm-helper-exiv.cpp
+gcm_helper_exiv_LDADD = $(EXIV_LIBS)
+endif
+
 gcm_install_system_wide_SOURCES =			\
 	gcm-install-system-wide.c
 
diff --git a/src/gcm-exif.c b/src/gcm-exif.c
index a985383..532084f 100644
--- a/src/gcm-exif.c
+++ b/src/gcm-exif.c
@@ -199,6 +199,70 @@ out:
 	return ret;
 }
 
+#ifdef GCM_USE_EXIV
+/**
+ * gcm_exif_parse_exiv:
+ **/
+static gboolean
+gcm_exif_parse_exiv (GcmExif *exif, const gchar *filename, GError **error)
+{
+	gboolean ret;
+	gchar *command_line;
+	gint exit_status = 0;
+	gchar *standard_output = NULL;
+	gchar **split = NULL;
+	GcmExifPrivate *priv = exif->priv;
+
+	command_line = g_strdup_printf (LIBEXECDIR "/gcm-helper-exiv %s", filename);
+	ret = g_spawn_command_line_sync (command_line, &standard_output, NULL, &exit_status, error);
+	if (!ret)
+		goto out;
+
+	/* failed to sniff */
+	if (exit_status != 0) {
+		ret = FALSE;
+		g_set_error (error, GCM_EXIF_ERROR, GCM_EXIF_ERROR_NO_SUPPORT,
+			     "Failed to run: %s", standard_output);
+		goto out;
+	}
+
+	/* get data */
+	split = g_strsplit (standard_output, "\n", -1);
+	if (g_strv_length (split) != 4) {
+		ret = FALSE;
+		g_set_error (error, GCM_EXIF_ERROR, GCM_EXIF_ERROR_NO_SUPPORT,
+			     "Unexpected output: %s", standard_output);
+		goto out;
+	}
+
+	/* free old versions */
+	g_free (priv->manufacturer);
+	g_free (priv->model);
+	g_free (priv->serial);
+
+	/* create copies for ourselves */
+	if (split[0][0] != '\0')
+		priv->manufacturer = g_strdup (split[0]);
+	else
+		priv->manufacturer = NULL;
+	if (split[1][0] != '\0')
+		priv->model = g_strdup (split[1]);
+	else
+		priv->model = NULL;
+	if (split[2][0] != '\0')
+		priv->serial = g_strdup (split[2]);
+	else
+		priv->serial = NULL;
+	priv->device_kind = GCM_DEVICE_KIND_CAMERA;
+
+out:
+	g_free (standard_output);
+	g_free (command_line);
+	g_strfreev (split);
+	return ret;
+}
+#endif
+
 /**
  * gcm_exif_parse:
  **/
@@ -232,6 +296,25 @@ gcm_exif_parse (GcmExif *exif, GFile *file, GError **error)
 		goto out;
 	}
 
+#ifdef GCM_USE_EXIV
+	if (g_strcmp0 (content_type, "image/x-adobe-dng") == 0 ||
+	    g_strcmp0 (content_type, "image/x-canon-crw") == 0 ||
+	    g_strcmp0 (content_type, "image/x-fuji-raf") == 0 ||
+	    g_strcmp0 (content_type, "image/x-kde-raw") == 0 ||
+	    g_strcmp0 (content_type, "image/x-kodak-kdc") == 0 ||
+	    g_strcmp0 (content_type, "image/x-minolta-mrw") == 0 ||
+	    g_strcmp0 (content_type, "image/x-nikon-nef") == 0 ||
+	    g_strcmp0 (content_type, "image/x-olympus-orf") == 0 ||
+	    g_strcmp0 (content_type, "image/x-panasonic-raw") == 0 ||
+	    g_strcmp0 (content_type, "image/x-pentax-pef") == 0 ||
+	    g_strcmp0 (content_type, "image/x-sigma-x3f") == 0 ||
+	    g_strcmp0 (content_type, "image/x-sony-arw") == 0) {
+		filename = g_file_get_path (file);
+		ret = gcm_exif_parse_exiv (exif, filename, error);
+		goto out;
+	}
+#endif
+
 	/* no support */
 	g_set_error (error,
 		     GCM_EXIF_ERROR,
diff --git a/src/gcm-helper-exiv.cpp b/src/gcm-helper-exiv.cpp
new file mode 100644
index 0000000..6385d5b
--- /dev/null
+++ b/src/gcm-helper-exiv.cpp
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <exiv2/image.hpp>
+#include <exiv2/exif.hpp>
+#include <iostream>
+#include <iomanip>
+
+int
+main (int argc, char* const argv[])
+{
+	Exiv2::Image::AutoPtr image;
+	Exiv2::ExifData exifData;
+	std::string filename;
+	std::string make;
+	std::string model;
+	std::string serial;
+	int i;
+	int retval = 0;
+	const char *temp[] = {
+		"Exif.Canon.SerialNumber",
+		"Exif.Fujifilm.SerialNumber",
+		"Exif.Nikon3.SerialNO",
+		"Exif.Nikon3.SerialNumber",
+		"Exif.OlympusEq.InternalSerialNumber",
+		"Exif.OlympusEq.SerialNumber",
+		"Exif.Olympus.SerialNumber",
+		"Exif.Olympus.SerialNumber2",
+		"Exif.Sigma.SerialNumber",
+		NULL };
+
+	try {
+		/* open file */
+		if (argc == 2)
+			filename = argv[1];
+		if (filename.empty())
+			throw Exiv2::Error(1, "No filename specified");
+		image = Exiv2::ImageFactory::open(filename);
+		image->readMetadata();
+
+		/* get exif data */
+		exifData = image->exifData();
+		if (exifData.empty()) {
+			std::string error(argv[1]);
+			error += ": No Exif data found in the file";
+			throw Exiv2::Error(1, error);
+		}
+
+		/* try to find make, model and serial number */
+		make = exifData["Exif.Image.Make"].toString();
+		model = exifData["Exif.Image.Model"].toString();
+		for (i=0; temp[i] != NULL; i++) {
+			if (exifData[temp[i]].idx())
+				serial = exifData[temp[i]].toString();
+			if (!serial.empty())
+				break;
+		}
+		std::cout << model << "\n";
+		std::cout << make << "\n";
+		std::cout << serial << "\n";
+	} catch (Exiv2::AnyError& e) {
+		std::cout << "Failed to load: " << e << "\n";
+		retval = -1;
+	}
+out:
+	return retval;
+}
+
+
diff --git a/src/gcm-self-test.c b/src/gcm-self-test.c
index 8077a4a..587be3e 100644
--- a/src/gcm-self-test.c
+++ b/src/gcm-self-test.c
@@ -587,6 +587,19 @@ gcm_test_exif_func (void)
 	g_assert_cmpstr (gcm_exif_get_serial (exif), ==, NULL);
 	g_assert_cmpint (gcm_exif_get_device_kind (exif), ==, GCM_DEVICE_KIND_CAMERA);
 
+	/* RAW */
+	filename = gcm_test_get_data_file ("test.kdc");
+	file = g_file_new_for_path (filename);
+	ret = gcm_exif_parse (exif, file, &error);
+	g_free (filename);
+	g_object_unref (file);
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (gcm_exif_get_model (exif), ==, "Eastman Kodak Company");
+	g_assert_cmpstr (gcm_exif_get_manufacturer (exif), ==, "Kodak Digital Science DC50 Zoom Camera");
+	g_assert_cmpstr (gcm_exif_get_serial (exif), ==, NULL);
+	g_assert_cmpint (gcm_exif_get_device_kind (exif), ==, GCM_DEVICE_KIND_CAMERA);
+
 	/* PNG */
 	filename = gcm_test_get_data_file ("test.png");
 	file = g_file_new_for_path (filename);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]