[tracker-miners/wip/rishi/libraw] tracker-extract: Add LibRaw based extractor for RAW files



commit d6e7eb7321a224cfd0ec0d7d45e220be30c604c5
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Sep 12 17:13:57 2017 +0200

    tracker-extract: Add LibRaw based extractor for RAW files
    
    https://bugzilla.gnome.org/show_bug.cgi?id=787589

 configure.ac                              |   36 ++
 meson.build                               |    2 +
 src/tracker-extract/10-raw.rule           |    4 +
 src/tracker-extract/Makefile.am           |   18 +
 src/tracker-extract/meson.build           |    4 +
 src/tracker-extract/tracker-extract-raw.c |  566 +++++++++++++++++++++++++++++
 6 files changed, 630 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8b33336..73f3826 100644
--- a/configure.ac
+++ b/configure.ac
@@ -217,6 +217,7 @@ CAIRO_REQUIRED=1.0
 LIBICU_REQUIRED=4.8.1.1
 LIBJPEG_REQUIRED="any version"
 LIBGIF_REQUIRED="any version"
+LIBRAW_REQUIRED="any version"
 LIBTIFF_REQUIRED="any version"
 LIBVORBIS_REQUIRED=0.22
 LIBFLAC_REQUIRED=1.2.1
@@ -1460,6 +1461,40 @@ LDFLAGS="$OLD_LDFLAGS"
 LIBS="$OLD_LIBS"
 
 ##################################################################
+# Check for tracker-extract: libraw
+##################################################################
+
+AC_ARG_ENABLE(libraw,
+              AS_HELP_STRING([--enable-libraw],
+                             [enable extractor for RAW metadata [[default=auto]]]),
+              [enable_libraw=$enableval],
+              [enable_libraw=auto])
+
+if test "x$enable_libraw" != "xno" ; then
+   PKG_CHECK_MODULES(LIBRAW,
+                     [libraw],
+                    [have_libraw=yes],
+                    [have_libraw=no])
+
+   AC_SUBST(LIBRAW_CFLAGS)
+   AC_SUBST(LIBRAW_LIBS)
+
+   if test "x$have_libraw" = "xyes"; then
+      AC_DEFINE(HAVE_LIBRAW, [], [Define if we have libraw])
+   fi
+else
+   have_libraw="no  (disabled)"
+fi
+
+if test "x$enable_libraw" = "xyes"; then
+   if test "x$have_libraw" != "xyes"; then
+      AC_MSG_ERROR([Could not find libraw.])
+   fi
+fi
+
+AM_CONDITIONAL(HAVE_LIBRAW, test "x$have_libraw" = "xyes")
+
+##################################################################
 # Check for tracker-extract: vorbis
 ##################################################################
 
@@ -1859,6 +1894,7 @@ Metadata Extractors:
        Support XPS:                            $have_libgxps
        Support GIF:                            $have_libgif (xmp: $have_exempi)
        Support JPEG:                           $have_libjpeg (xmp: $have_exempi, exif: $have_libexif, iptc: 
$have_libiptcdata)
+       Support RAW:                            $have_libraw
        Support TIFF:                           $have_libtiff (xmp: $have_exempi, exif: yes, iptc: 
$have_libiptcdata)
        Support Vorbis (ogg/etc):               $have_libvorbis
        Support Flac:                           $have_libflac
diff --git a/meson.build b/meson.build
index b8a8ade..1b0eee1 100644
--- a/meson.build
+++ b/meson.build
@@ -38,6 +38,7 @@ libgxps = dependency('libgxps', required: false)
 libiptcdata = dependency('libiptcdata', required: false)
 libosinfo = dependency('libosinfo', version: '> 0.2.9', required: false)
 libpng = dependency('libpng', version: '> 0.89', required: false)
+libraw = dependency('libraw', required: false)
 libtiff = dependency('libtiff-4', required: false)
 libxml2 = dependency('libxml-2.0', version: '> 2.6')
 libvorbis = dependency('vorbisfile', version: '> 0.22')
@@ -390,6 +391,7 @@ if have_tracker_extract
     '    Support GIF:                            @0@ (xmp: @1@)'.format(libgif.found().to_string(), 
exempi.found().to_string()),
     '    Support JPEG:                           @0@ (xmp: @1@, exif: @2@, iptc: @3@)'.format(
         libjpeg.found().to_string(), exempi.found().to_string(), libexif.found().to_string(), 
libiptcdata.found().to_string()),
+    '    Support RAW:                            ' + libraw.found().to_string(),
     '    Support TIFF:                           @0@ (xmp: @1@, exif: @2@, iptc: @3@)'.format(
         libtiff.found().to_string(), exempi.found().to_string(), libexif.found().to_string(), 
libiptcdata.found().to_string()),
     '    Support Vorbis (ogg/etc):               ' + libvorbis.found().to_string(),
diff --git a/src/tracker-extract/10-raw.rule b/src/tracker-extract/10-raw.rule
new file mode 100644
index 0000000..c395b38
--- /dev/null
+++ b/src/tracker-extract/10-raw.rule
@@ -0,0 +1,4 @@
+[ExtractorRule]
+ModulePath=libextract-raw.so
+MimeTypes=image/x-canon-cr2;image/x-canon-crw;image/x-epson-erf;image/x-fuji-raf;image/x-minolta-mrw;image/x-nikon-nef;image/x-olympus-orf;image/x-pentax-pef;image/x-sony-arw;
+FallbackRdfTypes=nfo:Image;nmm:Photo;
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index cad85ba..77721ff 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -33,6 +33,7 @@ rules_files = \
        10-pdf.rule \
        10-png.rule \
        10-ps.rule \
+       10-raw.rule \
        10-svg.rule \
        10-tiff.rule \
        10-vorbis.rule \
@@ -143,6 +144,11 @@ extractmodules_LTLIBRARIES += libextract-png.la
 rules_DATA += 10-png.rule
 endif
 
+if HAVE_LIBRAW
+extractmodules_LTLIBRARIES += libextract-raw.la
+rules_DATA += 10-raw.rule
+endif
+
 if HAVE_ABIWORD
 extractmodules_LTLIBRARIES += libextract-abw.la
 rules_DATA += 10-abw.rule
@@ -267,6 +273,18 @@ libextract_png_la_LIBADD = \
        $(TRACKER_EXTRACT_MODULES_LIBS) \
        $(LIBPNG_LIBS)
 
+# RAW
+libextract_raw_la_SOURCES = tracker-extract-raw.c
+libextract_raw_la_CFLAGS = \
+       $(TRACKER_EXTRACT_MODULES_CFLAGS) \
+       $(LIBRAW_CFLAGS)
+libextract_raw_la_LDFLAGS = $(module_flags)
+libextract_raw_la_LIBADD = \
+       $(top_builddir)/src/libtracker-extract/libtracker-extract.la \
+       $(top_builddir)/src/libtracker-common/libtracker-common.la \
+       $(BUILD_LIBS) \
+       $(TRACKER_EXTRACT_MODULES_LIBS) \
+       $(LIBRAW_LIBS)
 
 # PS
 libextract_ps_la_SOURCES = tracker-extract-ps.c
diff --git a/src/tracker-extract/meson.build b/src/tracker-extract/meson.build
index 2f429e2..aa02c19 100644
--- a/src/tracker-extract/meson.build
+++ b/src/tracker-extract/meson.build
@@ -85,6 +85,10 @@ if libpng.found()
   modules += [['extract-png', 'tracker-extract-png.c', '10-png.rule', [libpng, tracker_common_dep]]]
 endif
 
+if libraw.found()
+  modules += [['extract-raw', 'tracker-extract-raw.c', '10-raw.rule', [libraw, tracker_common_dep]]]
+endif
+
 if get_option('ps')
   modules += [['extract-ps', 'tracker-extract-ps.c', '10-ps.rule', [tracker_common_dep]]]
 endif
diff --git a/src/tracker-extract/tracker-extract-raw.c b/src/tracker-extract/tracker-extract-raw.c
new file mode 100644
index 0000000..16408a4
--- /dev/null
+++ b/src/tracker-extract/tracker-extract-raw.c
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <libraw.h>
+
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-extract/tracker-extract.h>
+#include <libtracker-sparql/tracker-sparql.h>
+
+#include "tracker-main.h"
+
+#define CM_TO_INCH              0.393700787
+
+#ifdef HAVE_LIBEXIF
+#define EXIF_NAMESPACE          "Exif"
+#define EXIF_NAMESPACE_LENGTH   4
+#endif /* HAVE_LIBEXIF */
+
+#ifdef HAVE_EXEMPI
+#define XMP_NAMESPACE           "http://ns.adobe.com/xap/1.0/\x00";
+#define XMP_NAMESPACE_LENGTH    29
+#endif /* HAVE_EXEMPI */
+
+#ifdef HAVE_LIBIPTCDATA
+#define PS3_NAMESPACE           "Photoshop 3.0\0"
+#define PS3_NAMESPACE_LENGTH    14
+#include <libiptcdata/iptc-jpeg.h>
+#endif /* HAVE_LIBIPTCDATA */
+
+typedef struct {
+       const gchar *make;
+       const gchar *model;
+       const gchar *title;
+       const gchar *orientation;
+       const gchar *copyright;
+       const gchar *white_balance;
+       const gchar *fnumber;
+       const gchar *flash;
+       const gchar *focal_length;
+       const gchar *artist;
+       const gchar *exposure_time;
+       const gchar *iso_speed_ratings;
+       const gchar *date;
+       const gchar *description;
+       const gchar *metering_mode;
+       const gchar *creator;
+       const gchar *comment;
+       const gchar *city;
+       const gchar *state;
+       const gchar *address;
+       const gchar *country;
+       const gchar *gps_altitude;
+       const gchar *gps_latitude;
+       const gchar *gps_longitude;
+       const gchar *gps_direction;
+} MergeData;
+
+static gboolean
+guess_dlna_profile (gint          width,
+                    gint          height,
+                    const gchar **dlna_profile,
+                    const gchar **dlna_mimetype)
+{
+       const gchar *profile = NULL;
+
+       if (dlna_profile) {
+               *dlna_profile = NULL;
+       }
+
+       if (dlna_mimetype) {
+               *dlna_mimetype = NULL;
+       }
+
+       if (width <= 640 && height <= 480) {
+               profile = "JPEG_SM";
+       } else if (width <= 1024 && height <= 768) {
+               profile = "JPEG_MED";
+       } else if (width <= 4096 && height <= 4096) {
+               profile = "JPEG_LRG";
+       }
+
+       if (profile) {
+               if (dlna_profile) {
+                       *dlna_profile = profile;
+               }
+
+               if (dlna_mimetype) {
+                       *dlna_mimetype = "image/jpeg";
+               }
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+G_MODULE_EXPORT gboolean
+tracker_extract_get_metadata (TrackerExtractInfo *info)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct tej_error_mgr tejerr;
+       struct jpeg_marker_struct *marker;
+       TrackerResource *metadata;
+       TrackerXmpData *xd = NULL;
+       TrackerExifData *ed = NULL;
+       TrackerIptcData *id = NULL;
+       MergeData md = { 0 };
+       GFile *file;
+       FILE *f;
+       goffset size;
+       gchar *filename, *uri;
+       gchar *comment = NULL;
+       const gchar *dlna_profile, *dlna_mimetype;
+       GPtrArray *keywords;
+       gboolean success = TRUE;
+       guint i;
+
+       file = tracker_extract_info_get_file (info);
+       filename = g_file_get_path (file);
+
+       size = tracker_file_get_size (filename);
+
+       if (size < 18) {
+               g_free (filename);
+               return FALSE;
+       }
+
+       f = tracker_file_open (filename);
+       g_free (filename);
+
+       if (!f) {
+               return FALSE;
+       }
+
+       uri = g_file_get_uri (file);
+
+       cinfo.err = jpeg_std_error (&tejerr.jpeg);
+       tejerr.jpeg.error_exit = extract_jpeg_error_exit;
+       if (setjmp (tejerr.setjmp_buffer)) {
+               success = FALSE;
+               goto fail;
+       }
+
+       metadata = tracker_resource_new (NULL);
+       tracker_resource_add_uri (metadata, "rdf:type", "nfo:Image");
+       tracker_resource_add_uri (metadata, "rdf:type", "nmm:Photo");
+
+       jpeg_create_decompress (&cinfo);
+
+       jpeg_save_markers (&cinfo, JPEG_COM, 0xFFFF);
+       jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xFFFF);
+       jpeg_save_markers (&cinfo, JPEG_APP0 + 13, 0xFFFF);
+
+       jpeg_stdio_src (&cinfo, f);
+
+       jpeg_read_header (&cinfo, TRUE);
+
+       /* FIXME? It is possible that there are markers after SOS,
+        * but there shouldn't be. Should we decompress the whole file?
+        *
+        * jpeg_start_decompress(&cinfo);
+        * jpeg_finish_decompress(&cinfo);
+        *
+        * jpeg_calc_output_dimensions(&cinfo);
+        */
+
+       marker = (struct jpeg_marker_struct *) &cinfo.marker_list;
+
+       while (marker) {
+               gchar *str;
+               gsize len;
+#ifdef HAVE_LIBIPTCDATA
+               gsize offset;
+               guint sublen;
+#endif /* HAVE_LIBIPTCDATA */
+
+               switch (marker->marker) {
+               case JPEG_COM:
+                       g_free (comment);
+                       comment = g_strndup ((gchar*) marker->data, marker->data_length);
+                       break;
+
+               case JPEG_APP0 + 1:
+                       str = (gchar*) marker->data;
+                       len = marker->data_length;
+
+#ifdef HAVE_LIBEXIF
+                       if (strncmp (EXIF_NAMESPACE, str, EXIF_NAMESPACE_LENGTH) == 0) {
+                               ed = tracker_exif_new ((guchar *) marker->data, len, uri);
+                       }
+#endif /* HAVE_LIBEXIF */
+
+#ifdef HAVE_EXEMPI
+                       if (strncmp (XMP_NAMESPACE, str, XMP_NAMESPACE_LENGTH) == 0) {
+                               xd = tracker_xmp_new (str + XMP_NAMESPACE_LENGTH,
+                                                     len - XMP_NAMESPACE_LENGTH,
+                                                     uri);
+                       }
+#endif /* HAVE_EXEMPI */
+
+                       break;
+
+               case JPEG_APP0 + 13:
+                       str = (gchar*) marker->data;
+                       len = marker->data_length;
+#ifdef HAVE_LIBIPTCDATA
+                       if (len > 0 && strncmp (PS3_NAMESPACE, str, PS3_NAMESPACE_LENGTH) == 0) {
+                               offset = iptc_jpeg_ps3_find_iptc (str, len, &sublen);
+                               if (offset > 0 && sublen > 0) {
+                                       id = tracker_iptc_new (str + offset, sublen, uri);
+                               }
+                       }
+#endif /* HAVE_LIBIPTCDATA */
+
+                       break;
+
+               default:
+                       marker = marker->next;
+                       continue;
+               }
+
+               marker = marker->next;
+       }
+
+       if (!ed) {
+               ed = g_new0 (TrackerExifData, 1);
+       }
+
+       if (!xd) {
+               xd = g_new0 (TrackerXmpData, 1);
+       }
+
+       if (!id) {
+               id = g_new0 (TrackerIptcData, 1);
+       }
+
+       md.title = tracker_coalesce_strip (4, xd->title, ed->document_name, xd->title2, xd->pdf_title);
+       md.orientation = tracker_coalesce_strip (3, xd->orientation, ed->orientation, id->image_orientation);
+       md.copyright = tracker_coalesce_strip (4, xd->copyright, xd->rights, ed->copyright, 
id->copyright_notice);
+       md.white_balance = tracker_coalesce_strip (2, xd->white_balance, ed->white_balance);
+       md.fnumber = tracker_coalesce_strip (2, xd->fnumber, ed->fnumber);
+       md.flash = tracker_coalesce_strip (2, xd->flash, ed->flash);
+       md.focal_length =  tracker_coalesce_strip (2, xd->focal_length, ed->focal_length);
+       md.artist = tracker_coalesce_strip (3, xd->artist, ed->artist, xd->contributor);
+       md.exposure_time = tracker_coalesce_strip (2, xd->exposure_time, ed->exposure_time);
+       md.iso_speed_ratings = tracker_coalesce_strip (2, xd->iso_speed_ratings, ed->iso_speed_ratings);
+       md.date = tracker_coalesce_strip (5, xd->date, xd->time_original, ed->time, id->date_created, 
ed->time_original);
+       md.description = tracker_coalesce_strip (2, xd->description, ed->description);
+       md.metering_mode = tracker_coalesce_strip (2, xd->metering_mode, ed->metering_mode);
+       md.city = tracker_coalesce_strip (2, xd->city, id->city);
+       md.state = tracker_coalesce_strip (2, xd->state, id->state);
+       md.address = tracker_coalesce_strip (2, xd->address, id->sublocation);
+       md.country = tracker_coalesce_strip (2, xd->country, id->country_name);
+
+       /* FIXME We are not handling the altitude ref here for xmp */
+       md.gps_altitude = tracker_coalesce_strip (2, xd->gps_altitude, ed->gps_altitude);
+       md.gps_latitude = tracker_coalesce_strip (2, xd->gps_latitude, ed->gps_latitude);
+       md.gps_longitude = tracker_coalesce_strip (2, xd->gps_longitude, ed->gps_longitude);
+       md.gps_direction = tracker_coalesce_strip (2, xd->gps_direction, ed->gps_direction);
+       md.creator = tracker_coalesce_strip (3, xd->creator, id->byline, id->credit);
+       md.comment = tracker_coalesce_strip (2, comment, ed->user_comment);
+       md.make = tracker_coalesce_strip (2, xd->make, ed->make);
+       md.model = tracker_coalesce_strip (2, xd->model, ed->model);
+
+       /* Prioritize on native dimention in all cases */
+       tracker_resource_set_int64 (metadata, "nfo:width", cinfo.image_width);
+       tracker_resource_set_int64 (metadata, "nfo:height", cinfo.image_height);
+
+       if (guess_dlna_profile (cinfo.image_width, cinfo.image_height, &dlna_profile, &dlna_mimetype)) {
+               tracker_resource_set_string (metadata, "nmm:dlnaProfile", dlna_profile);
+               tracker_resource_set_string (metadata, "nmm:dlnaMime", dlna_mimetype);
+       }
+
+       if (id->contact) {
+               TrackerResource *contact = tracker_extract_new_contact (id->contact);
+               tracker_resource_add_relation (metadata, "nco:contributor", contact);
+               g_object_unref (contact);
+       }
+
+       keywords = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
+
+       if (xd->keywords) {
+               tracker_keywords_parse (keywords, xd->keywords);
+       }
+
+       if (xd->pdf_keywords) {
+               tracker_keywords_parse (keywords, xd->pdf_keywords);
+       }
+
+       if (xd->subject) {
+               tracker_keywords_parse (keywords, xd->subject);
+       }
+
+       if (xd->publisher) {
+               TrackerResource *publisher = tracker_extract_new_contact (xd->publisher);
+               tracker_resource_add_relation (metadata, "nco:publisher", publisher);
+               g_object_unref (publisher);
+       }
+
+       if (xd->type) {
+               tracker_resource_set_string (metadata, "dc:type", xd->type);
+       }
+
+       if (xd->rating) {
+               tracker_resource_set_string (metadata, "nao:numericRating", xd->rating);
+       }
+
+       if (xd->format) {
+               tracker_resource_set_string (metadata, "dc:format", xd->format);
+       }
+
+       if (xd->identifier) {
+               tracker_resource_set_string (metadata, "dc:identifier", xd->identifier);
+       }
+
+       if (xd->source) {
+               tracker_resource_set_string (metadata, "dc:source", xd->source);
+       }
+
+       if (xd->language) {
+               tracker_resource_set_string (metadata, "dc:language", xd->language);
+       }
+
+       if (xd->relation) {
+               tracker_resource_set_string (metadata, "dc:relation", xd->relation);
+       }
+
+       if (xd->coverage) {
+               tracker_resource_set_string (metadata, "dc:coverage", xd->coverage);
+       }
+
+       if (xd->license) {
+               tracker_resource_set_string (metadata, "nie:license", xd->license);
+       }
+
+       if (xd->regions) {
+               tracker_xmp_apply_regions_to_resource (metadata, xd);
+       }
+
+       if (id->keywords) {
+               tracker_keywords_parse (keywords, id->keywords);
+       }
+
+       for (i = 0; i < keywords->len; i++) {
+               TrackerResource *tag;
+               const gchar *p;
+
+               p = g_ptr_array_index (keywords, i);
+               tag = tracker_extract_new_tag (p);
+
+               tracker_resource_add_relation (metadata, "nao:hasTag", tag);
+
+               g_object_unref (tag);
+       }
+       g_ptr_array_free (keywords, TRUE);
+
+       if (md.make || md.model) {
+               TrackerResource *equipment = tracker_extract_new_equipment (md.make, md.model);
+               tracker_resource_add_relation (metadata, "nfo:equipment", equipment);
+               g_object_unref (equipment);
+       }
+
+       tracker_guarantee_resource_title_from_file (metadata,
+                                                   "nie:title",
+                                                   md.title,
+                                                   uri,
+                                                   NULL);
+
+       if (md.orientation) {
+               TrackerResource *orientation;
+
+               orientation = tracker_resource_new (md.orientation);
+               tracker_resource_set_relation (metadata, "nfo:orientation", orientation);
+               g_object_unref (orientation);
+       }
+
+       if (md.copyright) {
+               tracker_resource_set_string (metadata, "nie:copyright", md.copyright);
+       }
+
+       if (md.white_balance) {
+               TrackerResource *white_balance;
+
+               white_balance = tracker_resource_new (md.white_balance);
+               tracker_resource_set_relation (metadata, "nmm:meteringMode", white_balance);
+               g_object_unref (white_balance);
+       }
+
+       if (md.fnumber) {
+               gdouble value;
+
+               value = g_strtod (md.fnumber, NULL);
+               tracker_resource_set_double (metadata, "nmm:fnumber", value);
+       }
+
+       if (md.flash) {
+               TrackerResource *flash;
+
+               flash = tracker_resource_new (md.flash);
+               tracker_resource_set_relation (metadata, "nmm:flash", flash);
+               g_object_unref (flash);
+       }
+
+       if (md.focal_length) {
+               gdouble value;
+
+               value = g_strtod (md.focal_length, NULL);
+               tracker_resource_set_double (metadata, "nmm:focalLength", value);
+       }
+
+       if (md.artist) {
+               TrackerResource *artist = tracker_extract_new_contact (md.artist);
+               tracker_resource_add_relation (metadata, "nco:contributor", artist);
+               g_object_unref (artist);
+       }
+
+       if (md.exposure_time) {
+               gdouble value;
+
+               value = g_strtod (md.exposure_time, NULL);
+               tracker_resource_set_double (metadata, "nmm:exposureTime", value);
+       }
+
+       if (md.iso_speed_ratings) {
+               gdouble value;
+
+               value = g_strtod (md.iso_speed_ratings, NULL);
+               tracker_resource_set_double (metadata, "nmm:isoSpeed", value);
+       }
+
+       tracker_guarantee_resource_date_from_file_mtime (metadata,
+                                                        "nie:contentCreated",
+                                                        md.date,
+                                                        uri);
+
+       if (md.description) {
+               tracker_resource_set_string(metadata, "nie:description", md.description);
+       }
+
+       if (md.metering_mode) {
+               TrackerResource *metering;
+
+               metering = tracker_resource_new (md.metering_mode);
+               tracker_resource_set_relation (metadata, "nmm:meteringMode", metering);
+               g_object_unref (metering);
+       }
+
+       if (md.creator) {
+               TrackerResource *creator = tracker_extract_new_contact (md.creator);
+               tracker_resource_add_relation (metadata, "nco:creator", creator);
+               g_object_unref (creator);
+
+               /* NOTE: We only have affiliation with
+                * nco:PersonContact and we are using
+                * nco:Contact here.
+                */
+
+               /* if (id->byline_title) { */
+               /*      tracker_sparql_builder_insert_open (preupdate, NULL); */
+
+               /*      tracker_sparql_builder_subject (preupdate, "_:affiliation_by_line"); */
+               /*      tracker_sparql_builder_predicate (preupdate, "a"); */
+               /*      tracker_sparql_builder_object (preupdate, "nco:Affiliation"); */
+
+               /*      tracker_sparql_builder_predicate (preupdate, "nco:title"); */
+               /*      tracker_sparql_builder_object_unvalidated (preupdate, id->byline_title); */
+
+               /*      tracker_sparql_builder_insert_close (preupdate); */
+
+               /*      tracker_sparql_builder_predicate (preupdate, "a"); */
+               /*      tracker_sparql_builder_object (preupdate, "nco:Contact"); */
+               /*      tracker_sparql_builder_predicate (preupdate, "nco:hasAffiliation"); */
+               /*      tracker_sparql_builder_object (preupdate, "_:affiliation_by_line"); */
+               /* } */
+       }
+
+       if (md.comment) {
+               tracker_guarantee_resource_utf8_string (metadata, "nie:comment", md.comment);
+       }
+
+       if (md.address || md.state || md.country || md.city ||
+           md.gps_altitude || md.gps_latitude || md.gps_longitude) {
+
+               TrackerResource *location = tracker_extract_new_location (md.address,
+                       md.state, md.city, md.country, md.gps_altitude,
+                       md.gps_latitude, md.gps_longitude);
+
+               tracker_resource_add_relation (metadata, "slo:location", location);
+
+               g_object_unref (location);
+       }
+
+       if (md.gps_direction) {
+               tracker_resource_set_string (metadata, "nfo:heading", md.gps_direction);
+       }
+
+       if (cinfo.density_unit != 0 || ed->x_resolution) {
+               gdouble value;
+
+               if (cinfo.density_unit == 0) {
+                       if (ed->resolution_unit != 3)
+                               value = g_strtod (ed->x_resolution, NULL);
+                       else
+                               value = g_strtod (ed->x_resolution, NULL) * CM_TO_INCH;
+               } else {
+                       if (cinfo.density_unit == 1)
+                               value = cinfo.X_density;
+                       else
+                               value = cinfo.X_density * CM_TO_INCH;
+               }
+
+               tracker_resource_set_double (metadata, "nfo:horizontalResolution", value);
+       }
+
+       if (cinfo.density_unit != 0 || ed->y_resolution) {
+               gdouble value;
+
+               if (cinfo.density_unit == 0) {
+                       if (ed->resolution_unit != 3)
+                               value = g_strtod (ed->y_resolution, NULL);
+                       else
+                               value = g_strtod (ed->y_resolution, NULL) * CM_TO_INCH;
+               } else {
+                       if (cinfo.density_unit == 1)
+                               value = cinfo.Y_density;
+                       else
+                               value = cinfo.Y_density * CM_TO_INCH;
+               }
+
+               tracker_resource_set_double (metadata, "nfo:verticalResolution", value);
+       }
+
+       jpeg_destroy_decompress (&cinfo);
+
+       tracker_exif_free (ed);
+       tracker_xmp_free (xd);
+       tracker_iptc_free (id);
+       g_free (comment);
+
+       tracker_extract_info_set_resource (info, metadata);
+       g_object_unref (metadata);
+
+fail:
+       tracker_file_close (f, FALSE);
+       g_free (uri);
+
+       return success;
+}


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