[tracker/coalesce] Change structure of the JPEG extractor
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/coalesce] Change structure of the JPEG extractor
- Date: Wed, 2 Sep 2009 15:35:39 +0000 (UTC)
commit fd1912d1cf7ee542c76323040e567b06c2292290
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Sep 2 17:31:51 2009 +0200
Change structure of the JPEG extractor
- This breaks the TIFF, XMP, PDF and GStreamer extractor
- This is a work in progress
- Currently this doesn't add any of the tags of JPEG to the
SPARQL update query (they just all get freed atm)
- This cleans up the shared XMP, Exif and IPTC code
This commit is going to be squashed together with a few other
commits. This means that you should not rely your work on this
branch on Philip not going to git-rebase it. He will.
Guaranteed.
src/tracker-extract/Makefile.am | 9 +-
src/tracker-extract/tracker-exif.c | 452 ++++++++++++++++++++++++++
src/tracker-extract/tracker-exif.h | 40 +++
src/tracker-extract/tracker-extract-jpeg.c | 480 ++++++++--------------------
src/tracker-extract/tracker-iptc.c | 116 +++----
src/tracker-extract/tracker-iptc.h | 31 ++-
src/tracker-extract/tracker-xmp.c | 262 +++++-----------
src/tracker-extract/tracker-xmp.h | 23 ++-
8 files changed, 819 insertions(+), 594 deletions(-)
---
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index 8c68c3c..5e6f457 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -100,6 +100,11 @@ xmp_sources = \
tracker-xmp.c \
tracker-xmp.h
+# Common exif Sources
+exif_sources = \
+ tracker-exif.c \
+ tracker-exif.h
+
# Common iptc Sources
iptc_sources = \
tracker-iptc.c \
@@ -202,7 +207,7 @@ libextract_xine_la_LIBADD = $(GLIB2_LIBS) $(XINE_LIBS) $(GCOV_LIBS) \
$(top_builddir)/src/libtracker-common/libtracker-common.la
# JPEG
-libextract_jpeg_la_SOURCES = tracker-extract-jpeg.c $(xmp_sources) $(iptc_sources)
+libextract_jpeg_la_SOURCES = tracker-extract-jpeg.c $(xmp_sources) $(iptc_sources) $(exif_sources)
libextract_jpeg_la_LDFLAGS = $(module_flags)
libextract_jpeg_la_LIBADD = $(GLIB2_LIBS) $(LIBJPEG_LIBS) $(LIBEXIF_LIBS) $(LIBIPTCDATA_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS) \
$(top_builddir)/src/libtracker-common/libtracker-common.la
@@ -286,4 +291,4 @@ BUILT_SOURCES = \
CLEANFILES = $(BUILT_SOURCES)
-EXTRA_DIST = tracker-marshal.list
\ No newline at end of file
+EXTRA_DIST = tracker-marshal.list
diff --git a/src/tracker-extract/tracker-exif.c b/src/tracker-extract/tracker-exif.c
new file mode 100644
index 0000000..a7ba24f
--- /dev/null
+++ b/src/tracker-extract/tracker-exif.c
@@ -0,0 +1,452 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Tracker Exif - Exif helper functions
+ * Copyright (C) 2008, Nokia
+ *
+ * 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 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.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#include "config.h"
+
+#include <locale.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+
+#include "tracker-main.h"
+#include "tracker-exif.h"
+
+#include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-utils.h>
+
+
+#ifdef HAVE_LIBEXIF
+
+#include <libexif/exif-data.h>
+
+#define EXIF_DATE_FORMAT "%Y:%m:%d %H:%M:%S"
+
+#ifndef HAVE_STRCASESTR
+static gchar *
+strcasestr (const gchar *haystack,
+ const gchar *needle)
+{
+ gchar *p;
+ gchar *startn = NULL;
+ gchar *np = NULL;
+
+ for (p = (gchar *) haystack; *p; p++) {
+ if (np) {
+ if (toupper (*p) == toupper (*np)) {
+ if (!*++np) {
+ return startn;
+ }
+ } else {
+ np = 0;
+ }
+ } else if (toupper (*p) == toupper (*needle)) {
+ np = (gchar *) needle + 1;
+ startn = p;
+ }
+ }
+
+ return NULL;
+}
+#endif /* HAVE_STRCASESTR */
+
+static gchar *
+get_date (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+
+ exif_entry_get_value (entry, buf, 1024);
+ /* From: ex; date "2007:04:15 15:35:58"
+ * To : ex. "2007-04-15T17:35:58+0200 where +0200 is localtime */
+ return tracker_date_format_to_iso8601 (buf, EXIF_DATE_FORMAT);
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_focal_length(ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+ exif_entry_get_value (entry, buf, 1024);
+ return g_strndup (buf, strstr (buf, " mm") - buf);
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_flash (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ if (strcasestr (buf, "flash fired")) {
+ return g_strdup ("nmm:flash-on");
+ }
+
+ return g_strdup ("nmm:flash-off");
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_fnumber (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+ gchar *new_fn;
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ if (strlen (buf) <= 0) {
+ return NULL;
+ }
+
+ new_fn = g_strdup (buf);
+
+ if (new_fn[0] == 'F') {
+ new_fn[0] = ' ';
+ } else if (buf[0] == 'f' && new_fn[1] == '/') {
+ new_fn[0] = new_fn[1] = ' ';
+ }
+
+ return g_strstrip (new_fn);
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_exposure_time (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+ gchar *sep;
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ sep = strchr (buf, '/');
+
+ if (sep) {
+ gdouble fraction;
+
+ fraction = g_ascii_strtod (sep + 1, NULL);
+
+ if (fraction > 0.0) {
+ gdouble val;
+ gchar bufr[G_ASCII_DTOSTR_BUF_SIZE];
+
+ val = 1.0f / fraction;
+ g_ascii_dtostr (bufr, sizeof(bufr), val);
+
+ return g_strdup (bufr);
+ }
+ }
+
+ return g_strdup (buf);
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_orientation (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+ guint i;
+
+ if (entry) {
+ gchar buf[1024];
+ static const gchar *ostr[8] = {
+ /* 0 */ "top - left",
+ /* 1 */ "top - right",
+ /* 2 */ "bottom - right",
+ /* 3 */ "bottom - left",
+ /* 4 */ "left - top",
+ /* 5 */ "right - top",
+ /* 6 */ "right - bottom",
+ /* 7 */ "left - bottom"
+ };
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ for (i=0; i < 8; i++) {
+ if (g_strcmp0 (buf, ostr[i]) == 0) {
+ switch (i) {
+ case 0:
+ return g_strdup ("nfo:orientation-top");
+ case 1:
+ return g_strdup ("nfo:orientation-top-mirror");
+ case 2:
+ return g_strdup ("nfo:orientation-bottom");
+ case 3:
+ return g_strdup ("nfo:orientation-bottom-mirror");
+ case 4:
+ return g_strdup ("nfo:orientation-left-mirror");
+ case 5:
+ return g_strdup ("nfo:orientation-right");
+ case 6:
+ return g_strdup ("nfo:orientation-right-mirror");
+ case 7:
+ return g_strdup ("nfo:orientation-left");
+ default:
+ break;
+ }
+ }
+ }
+
+ return g_strdup ("nfo:orientation-top");
+
+ }
+
+ return NULL;
+}
+
+
+static gchar *
+get_metering_mode (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ if (strcasestr (buf, "center")) {
+ return g_strdup ("nmm:meteringMode-center-weighted-average");
+ }
+
+ if (strcasestr (buf, "average")) {
+ return g_strdup ("nmm:meteringMode-average");
+ }
+
+ if (strcasestr (buf, "spot")) {
+ return g_strdup ("nmm:meteringMode-spot");
+ }
+
+ if (strcasestr (buf, "multispot")) {
+ return g_strdup ("nmm:meteringMode-multispot");
+ }
+
+ if (strcasestr (buf, "pattern")) {
+ return g_strdup ("nmm:meteringMode-pattern");
+ }
+
+ if (strcasestr (buf, "partial")) {
+ return g_strdup ("nmm:meteringMode-partial");
+ }
+
+ return g_strdup ("nmm:meteringMode-other");
+ }
+
+ return NULL;
+}
+
+
+static gchar *
+get_white_balance (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+ exif_entry_get_value (entry, buf, 1024);
+
+ if (strcasestr (buf, "auto")) {
+ return g_strdup ("nmm:whiteBalance-auto");
+ }
+
+ /* Found in the field: sunny, fluorescent, incandescent, cloudy.
+ * These will this way also yield as manual. */
+
+ return g_strdup ("nmm:whiteBalance-manual");
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_value (ExifData *exif, ExifTag tag)
+{
+ ExifEntry *entry = exif_data_get_entry (exif, tag);
+
+ if (entry) {
+ gchar buf[1024];
+
+ exif_entry_get_value (entry, buf, 1024);
+
+ return g_strdup (buf);
+ }
+
+ return NULL;
+}
+
+#endif /* HAVE_LIBEXIF */
+
+void
+tracker_read_exif (const unsigned char *buffer,
+ size_t len,
+ const gchar *uri,
+ TrackerExifData *data)
+{
+#ifdef HAVE_LIBEXIF
+ guint i;
+ ExifData *exif;
+ ExifTag p[20] = { EXIF_TAG_PIXEL_Y_DIMENSION,
+ /* 01 */ EXIF_TAG_PIXEL_X_DIMENSION,
+ /* 02 */ EXIF_TAG_RELATED_IMAGE_WIDTH,
+ /* 03 */ EXIF_TAG_DOCUMENT_NAME,
+ /* 04 */ EXIF_TAG_DATE_TIME,
+ /* 05 */ EXIF_TAG_DATE_TIME_ORIGINAL,
+ /* 06 */ EXIF_TAG_ARTIST,
+ /* 07 */ EXIF_TAG_USER_COMMENT,
+ /* 08 */ EXIF_TAG_IMAGE_DESCRIPTION,
+ /* 09 */ EXIF_TAG_MAKE,
+ /* 10 */ EXIF_TAG_ORIENTATION,
+ /* 11 */ EXIF_TAG_EXPOSURE_TIME,
+ /* 12 */ EXIF_TAG_FNUMBER,
+ /* 13 */ EXIF_TAG_FLASH,
+ /* 14 */ EXIF_TAG_FOCAL_LENGTH,
+ /* 15 */ EXIF_TAG_ISO_SPEED_RATINGS,
+ /* 16 */ EXIF_TAG_METERING_MODE,
+ /* 17 */ EXIF_TAG_WHITE_BALANCE,
+ /* 18 */ EXIF_TAG_COPYRIGHT,
+ /* 19 */ EXIF_TAG_MODEL };
+
+ exif = exif_data_new();
+
+ exif_data_set_option (exif, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
+ exif_data_unset_option (exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+ exif_data_set_option (exif, EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE);
+
+ exif_data_load_data (exif, (unsigned char *) buffer, len);
+
+ for (i = 0 ; i < 20; i++) {
+ switch (p[i]) {
+ case EXIF_TAG_PIXEL_Y_DIMENSION:
+ if (!data->y_dimention)
+ data->y_dimention = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_PIXEL_X_DIMENSION:
+ if (!data->x_dimention)
+ data->x_dimention = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_RELATED_IMAGE_WIDTH:
+ if (!data->image_width)
+ data->image_width = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_DOCUMENT_NAME:
+ if (!data->document_name)
+ data->document_name = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_DATE_TIME:
+ if (!data->time) {
+ data->time = get_date (exif, p[1]);
+ }
+ break;
+ case EXIF_TAG_DATE_TIME_ORIGINAL:
+ if (!data->time_original)
+ data->time_original = get_date (exif, p[i]);
+ break;
+ case EXIF_TAG_ARTIST:
+ if (!data->artist)
+ data->artist = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_USER_COMMENT:
+ if (!data->user_comment)
+ data->user_comment = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_IMAGE_DESCRIPTION:
+ if (!data->description)
+ data->description = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_MAKE:
+ if (!data->make)
+ data->make = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_MODEL:
+ if (!data->model)
+ data->model = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_ORIENTATION:
+ if (!data->orientation)
+ data->orientation = get_orientation (exif, p[i]);
+ break;
+ case EXIF_TAG_EXPOSURE_TIME:
+ if (!data->exposure_time)
+ data->exposure_time = get_exposure_time (exif, p[i]);
+ break;
+ case EXIF_TAG_FNUMBER:
+ if (!data->fnumber)
+ data->fnumber = get_fnumber (exif, p[i]);
+ break;
+ case EXIF_TAG_FLASH:
+ if (!data->flash)
+ data->flash = get_flash (exif, p[i]);
+ break;
+ case EXIF_TAG_FOCAL_LENGTH:
+ if (!data->focal_length)
+ data->focal_length = get_focal_length (exif, p[i]);
+ break;
+ case EXIF_TAG_ISO_SPEED_RATINGS:
+ if (!data->iso_speed_ratings)
+ data->iso_speed_ratings = get_value (exif, p[i]);
+ break;
+ case EXIF_TAG_METERING_MODE:
+ if (!data->metering_mode)
+ data->metering_mode = get_metering_mode (exif, p[i]);
+ break;
+ case EXIF_TAG_WHITE_BALANCE:
+ if (!data->white_balance)
+ data->white_balance = get_white_balance (exif, p[i]);
+ break;
+ case EXIF_TAG_COPYRIGHT:
+ if (!data->copyright)
+ data->copyright = get_value (exif, p[i]);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ exif_data_free (exif);
+
+#endif /* HAVE_LIBEXIF */
+}
+
diff --git a/src/tracker-extract/tracker-exif.h b/src/tracker-extract/tracker-exif.h
new file mode 100644
index 0000000..ccedc31
--- /dev/null
+++ b/src/tracker-extract/tracker-exif.h
@@ -0,0 +1,40 @@
+/* Tracker Xmp - Xmp helper functions
+ * Copyright (C) 2008, Nokia
+ *
+ * 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.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef _TRACKER_EXIF_H_
+#define _TRACKER_EXIF_H_
+
+#include <glib.h>
+
+typedef struct {
+ gchar *y_dimention, *x_dimention, *image_width, *document_name, *time, *time_original,
+ *artist, *user_comment, *description, *make, *model, *orientation,
+ *exposure_time, *fnumber, *flash, *focal_length, *iso_speed_ratings,
+ *metering_mode, *white_balance, *copyright;
+} TrackerExifData;
+
+void tracker_read_exif (const unsigned char *buffer,
+ size_t len,
+ const gchar *uri,
+ TrackerExifData *data);
+
+#endif /* _TRACKER_EXIF_H_ */
+
diff --git a/src/tracker-extract/tracker-extract-jpeg.c b/src/tracker-extract/tracker-extract-jpeg.c
index 725abaa..6dcb63c 100644
--- a/src/tracker-extract/tracker-extract-jpeg.c
+++ b/src/tracker-extract/tracker-extract-jpeg.c
@@ -54,32 +54,38 @@
#include "tracker-main.h"
#include "tracker-xmp.h"
#include "tracker-iptc.h"
+#include "tracker-exif.h"
+#define RDF_PREFIX TRACKER_RDF_PREFIX
#define NMM_PREFIX TRACKER_NMM_PREFIX
#define NFO_PREFIX TRACKER_NFO_PREFIX
#define NIE_PREFIX TRACKER_NIE_PREFIX
#define DC_PREFIX TRACKER_DC_PREFIX
#define NCO_PREFIX TRACKER_NCO_PREFIX
-#define RDF_PREFIX TRACKER_RDF_PREFIX
-#define RDF_TYPE RDF_PREFIX "type"
+#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
+#define XMP_NAMESPACE "http://ns.adobe.com/xap/1.0/\x00"
+#define XMP_NAMESPACE_LENGTH 29
#endif /* HAVE_EXEMPI */
-#ifdef HAVE_LIBEXIF
-#include <libexif/exif-data.h>
-#define EXIF_DATE_FORMAT "%Y:%m:%d %H:%M:%S"
-#endif /* HAVE_LIBEXIF */
-
#ifdef HAVE_LIBIPTCDATA
-#define PS3_NAMESPACE "Photoshop 3.0\0"
-#define PS3_NAMESPACE_LENGTH 14
+#define PS3_NAMESPACE "Photoshop 3.0\0"
+#define PS3_NAMESPACE_LENGTH 14
#include <libiptcdata/iptc-jpeg.h>
#endif /* HAVE_LIBIPTCDATA */
+typedef struct {
+ gchar *camera, *title, *orientation, *copyright, *white_balance,
+ *fnumber, *flash, *focal_length, *time_original, *artist,
+ *exposure_time, *iso_speed_ratings, *date, *description,
+ *metering_mode;
+} JpegNeedsMergeData;
+
static void extract_jpeg (const gchar *filename,
TrackerSparqlBuilder *metadata);
@@ -88,37 +94,6 @@ static TrackerExtractData data[] = {
{ NULL, NULL }
};
-
-#ifndef HAVE_STRCASESTR
-
-static gchar *
-strcasestr (const gchar *haystack,
- const gchar *needle)
-{
- gchar *p;
- gchar *startn = NULL;
- gchar *np = NULL;
-
- for (p = (gchar *) haystack; *p; p++) {
- if (np) {
- if (toupper (*p) == toupper (*np)) {
- if (!*++np) {
- return startn;
- }
- } else {
- np = 0;
- }
- } else if (toupper (*p) == toupper (*needle)) {
- np = (gchar *) needle + 1;
- startn = p;
- }
- }
-
- return NULL;
-}
-
-#endif /* HAVE_STRCASESTR */
-
struct tej_error_mgr
{
struct jpeg_error_mgr jpeg;
@@ -132,289 +107,6 @@ static void tracker_extract_jpeg_error_exit (j_common_ptr cinfo)
longjmp(h->setjmp_buffer, 1);
}
-#ifdef HAVE_LIBEXIF
-
-typedef gchar * (*PostProcessor) (const gchar*, gboolean *free_it);
-
-typedef struct {
- ExifTag tag;
- const gchar *name;
- PostProcessor post;
- const gchar *rdf_class;
- const gchar *rdf_property;
- const gchar *urn_prefix;
-} TagType;
-
-static gchar *date_to_iso8601 (const gchar *exif_date, gboolean *free_it);
-static gchar *fix_focal_length (const gchar *fl, gboolean *free_it);
-static gchar *fix_flash (const gchar *flash, gboolean *free_it);
-static gchar *fix_fnumber (const gchar *fn, gboolean *free_it);
-static gchar *fix_exposure_time (const gchar *et, gboolean *free_it);
-static gchar *fix_orientation (const gchar *orientation, gboolean *free_it);
-static gchar *fix_metering_mode (const gchar *metering_mode, gboolean *free_it);
-static gchar *fix_white_balance (const gchar *white_balance, gboolean *free_it);
-
-static TagType tags[] = {
- { EXIF_TAG_PIXEL_Y_DIMENSION, NFO_PREFIX "height", NULL, NULL, NULL, NULL },
- { EXIF_TAG_PIXEL_X_DIMENSION, NFO_PREFIX "width", NULL, NULL, NULL, NULL },
- { EXIF_TAG_RELATED_IMAGE_WIDTH, NFO_PREFIX "width", NULL, NULL, NULL, NULL },
- { EXIF_TAG_DOCUMENT_NAME, NIE_PREFIX "title", NULL, NULL, NULL, NULL },
- /* { -1, "Image:Album", NULL }, */
- { EXIF_TAG_DATE_TIME, NIE_PREFIX "contentCreated", date_to_iso8601, NULL, NULL, NULL },
- { EXIF_TAG_DATE_TIME_ORIGINAL, NIE_PREFIX "contentCreated", date_to_iso8601, NULL, NULL, NULL },
- /* { -1, "Image:Keywords", NULL }, */
- { EXIF_TAG_ARTIST, NCO_PREFIX "creator", NULL, NCO_PREFIX "Contact", NCO_PREFIX "fullname", "urn:artist:%s"},
- { EXIF_TAG_USER_COMMENT, NIE_PREFIX "comment", NULL, NULL, NULL, NULL },
- { EXIF_TAG_IMAGE_DESCRIPTION, NIE_PREFIX "description", NULL, NULL, NULL, NULL },
- /* { EXIF_TAG_SOFTWARE, "Image:Software", NULL }, */
- { EXIF_TAG_MAKE, NMM_PREFIX "camera", NULL, NULL, NULL, NULL },
- { EXIF_TAG_MODEL, NMM_PREFIX "camera", NULL, NULL, NULL, NULL },
- { EXIF_TAG_ORIENTATION, NFO_PREFIX "orientation", fix_orientation, NULL, NULL, NULL },
- /* { EXIF_TAG_EXPOSURE_PROGRAM, "Image:ExposureProgram", NULL }, */
- { EXIF_TAG_EXPOSURE_TIME, NMM_PREFIX "exposureTime", fix_exposure_time, NULL, NULL, NULL },
- { EXIF_TAG_FNUMBER, NMM_PREFIX "fnumber", fix_fnumber, NULL, NULL, NULL },
- { EXIF_TAG_FLASH, NMM_PREFIX "flash", fix_flash, NULL, NULL, NULL },
- { EXIF_TAG_FOCAL_LENGTH, NMM_PREFIX "focalLength", fix_focal_length, NULL, NULL, NULL },
- { EXIF_TAG_ISO_SPEED_RATINGS, NMM_PREFIX "isoSpeed", NULL, NULL, NULL, NULL },
- { EXIF_TAG_METERING_MODE, NMM_PREFIX "meteringMode", fix_metering_mode, NULL, NULL, NULL },
- { EXIF_TAG_WHITE_BALANCE, NMM_PREFIX "whiteBalance", fix_white_balance, NULL, NULL, NULL },
- { EXIF_TAG_COPYRIGHT, NIE_PREFIX "copyright", NULL, NULL, NULL, NULL },
- { -1, NULL, NULL }
-};
-
-#endif /* HAVE_EXIF */
-
-#ifdef HAVE_LIBEXIF
-
-static gchar *
-date_to_iso8601 (const gchar *date, gboolean *free_it)
-{
- /* From: ex; date "2007:04:15 15:35:58"
- * To : ex. "2007-04-15T17:35:58+0200 where +0200 is localtime */
- *free_it = TRUE;
- return tracker_date_format_to_iso8601 (date, EXIF_DATE_FORMAT);
-}
-
-static gchar *
-fix_focal_length (const gchar *fl, gboolean *free_it)
-{
- *free_it = TRUE;
- return g_strndup (fl, strstr (fl, " mm") - fl);
-}
-
-static gchar *
-fix_flash (const gchar *flash, gboolean *free_it)
-{
- *free_it = FALSE;
-
- if (strcasestr (flash, "flash fired")) {
- return (gchar *) "nmm:flash-on";
- } else {
- return (gchar *) "nmm:flash-off";
- }
-}
-
-static gchar *
-fix_fnumber (const gchar *fn, gboolean *free_it)
-{
- gchar *new_fn;
-
- if (!fn) {
- *free_it = FALSE;
- return NULL;
- }
-
- new_fn = g_strdup (fn);
-
- if (new_fn[0] == 'F') {
- new_fn[0] = ' ';
- } else if (fn[0] == 'f' && new_fn[1] == '/') {
- new_fn[0] = new_fn[1] = ' ';
- }
-
- *free_it = TRUE;
- return g_strstrip (new_fn);
-}
-
-static gchar *
-fix_exposure_time (const gchar *et, gboolean *free_it)
-{
- gchar *sep;
-
- sep = strchr (et, '/');
-
- *free_it = TRUE;
-
- if (sep) {
- gdouble fraction;
-
- fraction = g_ascii_strtod (sep + 1, NULL);
-
- if (fraction > 0.0) {
- gdouble val;
- gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
-
- val = 1.0f / fraction;
- g_ascii_dtostr (buf, sizeof(buf), val);
-
- return g_strdup (buf);
- }
- }
-
- return g_strdup (et);
-}
-
-static gchar *
-fix_orientation (const gchar *orientation, gboolean *free_it)
-{
- guint i;
- static const gchar *ostr[8] = {
- /* 0 */ "top - left",
- /* 1 */ "top - right",
- /* 2 */ "bottom - right",
- /* 3 */ "bottom - left",
- /* 4 */ "left - top",
- /* 5 */ "right - top",
- /* 6 */ "right - bottom",
- /* 7 */ "left - bottom"
- };
-
- *free_it = FALSE;
-
- for (i=0; i < 8; i++) {
- if (g_strcmp0 (orientation,ostr[i]) == 0) {
- switch (i) {
- case 0:
- return (gchar *) "nfo:orientation-top";
- case 1:
- return (gchar *) "nfo:orientation-top-mirror";
- case 2:
- return (gchar *) "nfo:orientation-bottom";
- case 3:
- return (gchar *) "nfo:orientation-bottom-mirror";
- case 4:
- return (gchar *) "nfo:orientation-left-mirror";
- case 5:
- return (gchar *) "nfo:orientation-right";
- case 6:
- return (gchar *) "nfo:orientation-right-mirror";
- case 7:
- return (gchar *) "nfo:orientation-left";
- default:
- break;
- }
- }
- }
-
- return (gchar *) "nfo:orientation-top";
-}
-
-
-static gchar *
-fix_metering_mode (const gchar *metering_mode, gboolean *free_it)
-{
- *free_it = FALSE;
-
- if (strcasestr (metering_mode, "center")) {
- return (gchar *) "nmm:meteringMode-center-weighted-average";
- }
-
- if (strcasestr (metering_mode, "average")) {
- return (gchar *) "nmm:meteringMode-average";
- }
-
- if (strcasestr (metering_mode, "spot")) {
- return (gchar *) "nmm:meteringMode-spot";
- }
-
- if (strcasestr (metering_mode, "multispot")) {
- return (gchar *) "nmm:meteringMode-multispot";
- }
-
- if (strcasestr (metering_mode, "pattern")) {
- return (gchar *) "nmm:meteringMode-pattern";
- }
-
- if (strcasestr (metering_mode, "partial")) {
- return (gchar *) "nmm:meteringMode-partial";
- }
-
- return (gchar *) "nmm:meteringMode-other";
-}
-
-
-static gchar *
-fix_white_balance (const gchar *white_balance, gboolean *free_it)
-{
- *free_it = FALSE;
-
- if (strcasestr (white_balance, "auto")) {
- return (gchar *) "nmm:whiteBalance-auto";
- }
-
- /* Found in the field: sunny, fluorescent, incandescent, cloudy. These
- * will this way also yield as manual. */
-
- return (gchar *) "nmm:whiteBalance-manual";
-}
-
-static void
-read_exif (const unsigned char *buffer,
- size_t len,
- const gchar *uri,
- TrackerSparqlBuilder *metadata)
-{
- ExifData *exif;
- TagType *p;
-
- tracker_statement_list_insert (metadata, uri,
- RDF_TYPE,
- NMM_PREFIX "Photo");
-
- exif = exif_data_new();
- exif_data_set_option (exif, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
- exif_data_unset_option (exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
- exif_data_set_option (exif, EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE);
-
- exif_data_load_data (exif, (unsigned char *) buffer, len);
-
- for (p = tags; p->name; ++p) {
- ExifEntry *entry = exif_data_get_entry (exif, p->tag);
-
- if (entry) {
- gchar buffer_[1024];
- gchar *what_i_need;
- gboolean free_it = FALSE;
-
- exif_entry_get_value (entry, buffer_, 1024);
-
- if (p->post) {
- what_i_need = (*p->post) (buffer_, &free_it);
- } else {
- what_i_need = buffer_;
- }
-
- if (p->urn_prefix) {
- gchar *canonical_uri = tracker_uri_printf_escaped (p->urn_prefix, what_i_need);
- tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, p->rdf_class);
- tracker_statement_list_insert (metadata, canonical_uri, p->rdf_property, what_i_need);
- tracker_statement_list_insert (metadata, uri, p->name, canonical_uri);
- g_free (canonical_uri);
- } else {
- tracker_statement_list_insert (metadata, uri, p->name, what_i_need);
- }
-
- if (free_it)
- g_free (what_i_need);
- }
- }
-
- exif_data_free (exif);
-}
-
-#endif /* HAVE_LIBEXIF */
-
-
static void
extract_jpeg (const gchar *uri,
TrackerSparqlBuilder *metadata)
@@ -437,6 +129,10 @@ extract_jpeg (const gchar *uri,
f = tracker_file_open (filename, "rb", FALSE);
if (f) {
+ TrackerXmpData xmp_data = { 0 };
+ TrackerExifData exif_data = { 0 };
+ TrackerIptcData iptc_data = { 0 };
+ JpegNeedsMergeData merge_data = { 0 };
gchar *str;
gsize len;
#ifdef HAVE_LIBIPTCDATA
@@ -445,8 +141,12 @@ extract_jpeg (const gchar *uri,
#endif /* HAVE_LIBIPTCDATA */
tracker_statement_list_insert (metadata, uri,
- RDF_TYPE,
- NFO_PREFIX "Image");
+ RDF_PREFIX "type",
+ NFO_PREFIX "Image");
+
+ tracker_statement_list_insert (metadata, uri,
+ RDF_PREFIX "type",
+ NMM_PREFIX "Photo");
cinfo.err = jpeg_std_error (&tejerr.jpeg);
tejerr.jpeg.error_exit = tracker_extract_jpeg_error_exit;
@@ -482,32 +182,39 @@ extract_jpeg (const gchar *uri,
str = g_strndup ((gchar*) marker->data, len);
tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "comment",
- str);
+ NIE_PREFIX "comment",
+ str);
+
g_free (str);
+
break;
-
+
case JPEG_APP0+1:
str = (gchar*) marker->data;
len = marker->data_length;
#ifdef HAVE_LIBEXIF
- if (strncmp ("Exif", (gchar*) (marker->data), 5) == 0) {
- read_exif ((unsigned char*) marker->data,
- marker->data_length, uri,
- metadata);
+ if (strncmp (EXIF_NAMESPACE, (gchar*) (marker->data), EXIF_NAMESPACE_LENGTH) == 0) {
+
+ tracker_read_exif ((unsigned char*) marker->data,
+ marker->data_length,
+ uri, &exif_data);
}
#endif /* HAVE_LIBEXIF */
#ifdef HAVE_EXEMPI
-
if (strncmp (XMP_NAMESPACE, str, XMP_NAMESPACE_LENGTH) == 0) {
+ TrackerXmpData xmp_data = { 0 };
+
tracker_read_xmp (str + XMP_NAMESPACE_LENGTH,
len - XMP_NAMESPACE_LENGTH,
- uri, metadata);
+ uri, &xmp_data);
+
}
#endif /* HAVE_EXEMPI */
+
break;
+
case JPEG_APP0+13:
str = (gchar*) marker->data;
len = marker->data_length;
@@ -516,12 +223,14 @@ extract_jpeg (const gchar *uri,
offset = iptc_jpeg_ps3_find_iptc (str, len, &sublen);
if (offset>0) {
tracker_read_iptc (str + offset,
- sublen,
- uri, metadata);
+ sublen,
+ uri, &iptc_data);
}
}
#endif /* HAVE_LIBIPTCDATA */
+
break;
+
default:
marker = marker->next;
continue;
@@ -530,7 +239,63 @@ extract_jpeg (const gchar *uri,
marker = marker->next;
}
- /* We want native size to have priority over EXIF, XMP etc */
+ merge_data.camera = tracker_coalesce (2, xmp_data.Model,
+ xmp_data.Make,
+ exif_data.model,
+ exif_data.make);
+
+ merge_data.title = tracker_coalesce (2, xmp_data.title,
+ exif_data.document_name);
+
+ merge_data.orientation = tracker_coalesce (3, exif_data.orientation,
+ xmp_data.Orientation,
+ iptc_data.image_orientation);
+
+ merge_data.copyright = tracker_coalesce (3, exif_data.copyright,
+ xmp_data.rights,
+ iptc_data.copyright_notice);
+
+ merge_data.white_balance = tracker_coalesce (2, exif_data.white_balance,
+ xmp_data.WhiteBalance);
+
+
+ merge_data.fnumber = tracker_coalesce (2, exif_data.fnumber,
+ xmp_data.FNumber);
+
+ merge_data.flash = tracker_coalesce (2, exif_data.flash,
+ xmp_data.Flash);
+
+ merge_data.focal_length = tracker_coalesce (2, exif_data.focal_length,
+ xmp_data.FocalLength);
+
+ merge_data.time_original = tracker_coalesce (2, exif_data.time_original,
+ xmp_data.DateTimeOriginal);
+
+ merge_data.artist = tracker_coalesce (2, exif_data.artist,
+ xmp_data.Artist,
+ xmp_data.contributor);
+
+ merge_data.exposure_time = tracker_coalesce (2, exif_data.exposure_time,
+ xmp_data.ExposureTime);
+
+ merge_data.iso_speed_ratings = tracker_coalesce (2, exif_data.iso_speed_ratings,
+ xmp_data.ISOSpeedRatings);
+
+ merge_data.date = tracker_coalesce (3, exif_data.time,
+ xmp_data.date,
+ iptc_data.date_created);
+
+ merge_data.description = tracker_coalesce (2, exif_data.description,
+ xmp_data.description);
+
+
+
+ merge_data.metering_mode = tracker_coalesce (2, exif_data.metering_mode,
+ xmp_data.MeteringMode);
+
+
+ g_free (exif_data.user_comment);
+
tracker_statement_list_insert_with_int (metadata, uri,
NFO_PREFIX "width",
cinfo.image_width);
@@ -538,6 +303,43 @@ extract_jpeg (const gchar *uri,
NFO_PREFIX "height",
cinfo.image_height);
+ g_free (exif_data.y_dimention);
+ g_free (exif_data.x_dimention);
+
+ g_free (xmp_data.creator);
+ g_free (xmp_data.keywords);
+ g_free (xmp_data.subject);
+ g_free (xmp_data.publisher);
+ g_free (xmp_data.type);
+ g_free (xmp_data.format);
+ g_free (xmp_data.identifier);
+ g_free (xmp_data.source);
+ g_free (xmp_data.language);
+ g_free (xmp_data.relation);
+ g_free (xmp_data.coverage);
+ g_free (xmp_data.license);
+
+ g_free (iptc_data.keywords);
+ g_free (iptc_data.byline);
+ g_free (iptc_data.credit);
+
+ g_free (merge_data.camera);
+ g_free (merge_data.title);
+ g_free (merge_data.orientation);
+ g_free (merge_data.copyright);
+ g_free (merge_data.white_balance);
+ g_free (merge_data.fnumber);
+ g_free (merge_data.flash);
+ g_free (merge_data.focal_length);
+ g_free (merge_data.time_original);
+ g_free (merge_data.artist);
+ g_free (merge_data.exposure_time);
+ g_free (merge_data.iso_speed_ratings);
+ g_free (merge_data.date);
+ g_free (merge_data.description);
+ g_free (merge_data.metering_mode);
+
+
jpeg_destroy_decompress (&cinfo);
fail:
tracker_file_close (f, FALSE);
diff --git a/src/tracker-extract/tracker-iptc.c b/src/tracker-extract/tracker-iptc.c
index 575b9d2..00de234 100644
--- a/src/tracker-extract/tracker-iptc.c
+++ b/src/tracker-extract/tracker-iptc.c
@@ -20,23 +20,13 @@
#include "config.h"
-#include <libtracker-common/tracker-ontology.h>
-#include <libtracker-common/tracker-statement-list.h>
-
#include "tracker-iptc.h"
#include "tracker-main.h"
-#define RDF_PREFIX TRACKER_RDF_PREFIX
-#define RDF_TYPE RDF_PREFIX "type"
-#define NIE_PREFIX TRACKER_NIE_PREFIX
-#define NCO_PREFIX TRACKER_NCO_PREFIX
-#define NFO_PREFIX TRACKER_NFO_PREFIX
-
#include <glib.h>
#include <string.h>
#include <libtracker-common/tracker-type-utils.h>
-#include <libtracker-common/tracker-file-utils.h>
#ifdef HAVE_LIBIPTCDATA
@@ -45,44 +35,6 @@
#define IPTC_DATE_FORMAT "%Y %m %d"
-typedef const gchar * (*IptcPostProcessor) (const gchar*);
-
-typedef struct {
- IptcRecord record;
- IptcTag tag;
- const gchar *name;
- IptcPostProcessor post;
- const gchar *urn;
- const gchar *rdf_type;
- const gchar *predicate;
-} IptcTagType;
-
-static const gchar *fix_iptc_orientation (const gchar *orientation);
-
-static gchar *
-date_to_iso8601 (const gchar *date)
-{
- /* From: ex; date "2007:04:15 15:35:58"
- * To : ex. "2007-04-15T17:35:58+0200 where +0200 is localtime
- */
- return tracker_date_format_to_iso8601 (date, IPTC_DATE_FORMAT);
-}
-
-static IptcTagType iptctags[] = {
- { 2, IPTC_TAG_KEYWORDS, NIE_PREFIX "keyword", NULL, NULL, NULL, NULL }, /* We might have to strtok_r this one? */
- /* { 2, IPTC_TAG_CONTENT_LOC_NAME, "Image:Location", NULL, NULL, NULL, NULL }, */
- /*{ 2, IPTC_TAG_SUBLOCATION, "Image:Location", NULL, NULL, NULL, NULL },*/
- { 2, IPTC_TAG_DATE_CREATED, NIE_PREFIX "contentCreated", date_to_iso8601, NULL, NULL, NULL },
- /*{ 2, IPTC_TAG_ORIGINATING_PROGRAM, "Image:Software", NULL, NULL, NULL, NULL },*/
- { 2, IPTC_TAG_BYLINE, NCO_PREFIX "creator", NULL, ":", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
- /*{ 2, IPTC_TAG_CITY, "Image:City", NULL, NULL, NULL, NULL },*/
- /*{ 2, IPTC_TAG_COUNTRY_NAME, "Image:Country", NULL, NULL, NULL, NULL },*/
- { 2, IPTC_TAG_CREDIT, NCO_PREFIX "creator", NULL, ":", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
- { 2, IPTC_TAG_COPYRIGHT_NOTICE, NIE_PREFIX "copyright", NULL, NULL, NULL, NULL },
- { 2, IPTC_TAG_IMAGE_ORIENTATION, NFO_PREFIX "orientation", fix_iptc_orientation, NULL, NULL, NULL },
- { -1, -1, NULL, NULL, NULL, NULL, NULL }
-};
-
static const gchar *
fix_iptc_orientation (const gchar *orientation)
{
@@ -100,45 +52,73 @@ void
tracker_read_iptc (const unsigned char *buffer,
size_t len,
const gchar *uri,
- TrackerSparqlBuilder *metadata)
+ TrackerIptcData *data)
{
#ifdef HAVE_LIBIPTCDATA
- IptcData *iptc = NULL;
- IptcTagType *p = NULL;
+ guint i;
+ IptcData *iptc = NULL;
+ IptcTag p[6] = { IPTC_TAG_KEYWORDS,
+ /* 01 */ IPTC_TAG_DATE_CREATED,
+ /* 02 */ IPTC_TAG_BYLINE,
+ /* 03 */ IPTC_TAG_CREDIT,
+ /* 04 */ IPTC_TAG_COPYRIGHT_NOTICE,
+ /* 05 */ IPTC_TAG_IMAGE_ORIENTATION};
+
+ /* FIXME According to valgrind this is leaking (together with the unref).
+ * Problem in libiptc */
- /* FIXME According to valgrind this is leaking (together with the unref). Problem in libiptc */
iptc = iptc_data_new ();
- if (!iptc)
+
+ if (!iptc)
return;
+
if (iptc_data_load (iptc, buffer, len) < 0) {
iptc_data_unref (iptc);
return;
}
- for (p = iptctags; p->name; ++p) {
+ for (i = 0; i < 6; i++) {
IptcDataSet *dataset = NULL;
- while ( (dataset = iptc_data_get_next_dataset (iptc, dataset, p->record, p->tag) ) ) {
+ while ((dataset = iptc_data_get_next_dataset (iptc, dataset, 2, p[i]))) {
gchar mbuffer[1024];
- const gchar *what_i_need;
iptc_dataset_get_as_str (dataset, mbuffer, 1024);
-
- if (p->post) {
- what_i_need = (*p->post) (mbuffer);
- } else {
- what_i_need = mbuffer;
- }
- if (p->urn) {
- tracker_statement_list_insert (metadata, p->urn, RDF_TYPE, p->rdf_type);
- tracker_statement_list_insert (metadata, p->urn, p->predicate, what_i_need);
- tracker_statement_list_insert (metadata, uri, p->name, p->urn);
- } else {
- tracker_statement_list_insert (metadata, uri, p->name, what_i_need);
+ switch (p[i]) {
+ case IPTC_TAG_KEYWORDS:
+ if (!data->keywords)
+ data->keywords = g_strdup (mbuffer);
+ break;
+ case IPTC_TAG_DATE_CREATED:
+ if (!data->date_created) {
+ /* From: ex; date "2007:04:15 15:35:58"
+ * To : ex. "2007-04-15T17:35:58+0200 where +0200 is localtime */
+ data->date_created = tracker_date_format_to_iso8601 (mbuffer, IPTC_DATE_FORMAT);
+ }
+ break;
+ case IPTC_TAG_BYLINE:
+ if (!data->byline)
+ data->byline = g_strdup (mbuffer);
+ break;
+ case IPTC_TAG_CREDIT:
+ if (!data->credit)
+ data->credit = g_strdup (mbuffer);
+ break;
+ case IPTC_TAG_COPYRIGHT_NOTICE:
+ if (!data->copyright_notice)
+ data->copyright_notice = g_strdup (mbuffer);
+ break;
+ case IPTC_TAG_IMAGE_ORIENTATION:
+ if (!data->image_orientation)
+ data->image_orientation = g_strdup (fix_iptc_orientation (mbuffer));
+ break;
+ default:
+ break;
}
}
}
+
iptc_data_unref (iptc);
#endif
diff --git a/src/tracker-extract/tracker-iptc.h b/src/tracker-extract/tracker-iptc.h
index c688844..ac6a817 100644
--- a/src/tracker-extract/tracker-iptc.h
+++ b/src/tracker-extract/tracker-iptc.h
@@ -1,12 +1,37 @@
+/* Tracker IPTC - Iptc helper functions
+ * Copyright (C) 2008, Nokia
+ *
+ * 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.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
#ifndef _TRACKER_IPTC_H_
#define _TRACKER_IPTC_H_
#include <glib.h>
+typedef struct {
+ gchar *keywords, *date_created, *byline, *credit, *copyright_notice,
+ *image_orientation;
+} TrackerIptcData;
+
void tracker_read_iptc (const unsigned char *buffer,
- size_t len,
- const gchar *uri,
- TrackerSparqlBuilder *metadata);
+ size_t len,
+ const gchar *uri,
+ TrackerIptcData *data);
#endif
diff --git a/src/tracker-extract/tracker-xmp.c b/src/tracker-extract/tracker-xmp.c
index 60c2cf6..ebfaa28 100644
--- a/src/tracker-extract/tracker-xmp.c
+++ b/src/tracker-extract/tracker-xmp.c
@@ -25,20 +25,10 @@
#include <glib.h>
-#include <libtracker-common/tracker-ontology.h>
-#include <libtracker-common/tracker-statement-list.h>
-
#include "tracker-main.h"
#include "tracker-xmp.h"
-#define RDF_PREFIX TRACKER_RDF_PREFIX
-#define RDF_TYPE RDF_PREFIX "type"
-#define NIE_PREFIX TRACKER_NIE_PREFIX
-#define NFO_PREFIX TRACKER_NFO_PREFIX
-#define NCO_PREFIX TRACKER_NCO_PREFIX
-#define NMM_PREFIX TRACKER_NMM_PREFIX
-#define DC_PREFIX TRACKER_DC_PREFIX
-
+#include <libtracker-common/tracker-type-utils.h>
#include <libtracker-common/tracker-utils.h>
#ifdef HAVE_EXEMPI
@@ -49,10 +39,10 @@
static void tracker_xmp_iter (XmpPtr xmp,
XmpIteratorPtr iter,
const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
gboolean append);
static void tracker_xmp_iter_simple (const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
const gchar *schema,
const gchar *path,
const gchar *value,
@@ -117,14 +107,14 @@ fix_white_balance (const gchar *wb)
static void
tracker_xmp_iter_array (XmpPtr xmp,
const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
const gchar *schema,
const gchar *path)
{
XmpIteratorPtr iter;
iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
- tracker_xmp_iter (xmp, iter, uri, metadata, TRUE);
+ tracker_xmp_iter (xmp, iter, uri, data, TRUE);
xmp_iterator_free (iter);
}
@@ -133,14 +123,14 @@ tracker_xmp_iter_array (XmpPtr xmp,
static void
tracker_xmp_iter_alt_text (XmpPtr xmp,
const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
const gchar *schema,
const gchar *path)
{
XmpIteratorPtr iter;
iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
- tracker_xmp_iter (xmp, iter, uri, metadata, FALSE);
+ tracker_xmp_iter (xmp, iter, uri, data, FALSE);
xmp_iterator_free (iter);
}
@@ -148,7 +138,7 @@ tracker_xmp_iter_alt_text (XmpPtr xmp,
static void
tracker_xmp_iter_simple_qual (XmpPtr xmp,
const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
const gchar *schema,
const gchar *path,
const gchar *value,
@@ -194,7 +184,7 @@ tracker_xmp_iter_simple_qual (XmpPtr xmp,
}
if (!ignore_element) {
- tracker_xmp_iter_simple (uri, metadata, schema, path, value, append);
+ tracker_xmp_iter_simple (uri, data, schema, path, value, append);
}
xmp_string_free (the_prop);
@@ -247,12 +237,12 @@ fix_orientation (const gchar *orientation)
}
-/* We have a simple element. Add any metadata we know about to the
+/* We have a simple element. Add any data we know about to the
* hash table.
*/
static void
tracker_xmp_iter_simple (const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
const gchar *schema,
const gchar *path,
const gchar *value,
@@ -270,203 +260,113 @@ tracker_xmp_iter_simple (const gchar *uri,
/* Dublin Core */
if (strcmp (schema, NS_DC) == 0) {
- if (strcmp (name, "title") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "title", value);
+ if (strcmp (name, "title") == 0 && !data->title) {
+ data->title = g_strdup (value);
}
- else if (strcmp (name, "rights") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "copyright", value);
+ else if (strcmp (name, "rights") == 0 && !data->rights) {
+ data->rights = g_strdup (value);
}
- else if (strcmp (name, "creator") == 0) {
-
- tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
- tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
- tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", ":");
-
+ else if (strcmp (name, "creator") == 0 && !data->creator) {
+ data->creator = g_strdup (value);
}
- else if (strcmp (name, "description") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "description", value);
+ else if (strcmp (name, "description") == 0 && !data->description) {
+ data->description = g_strdup (value);
}
- else if (strcmp (name, "date") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "contentCreated", value);
- }
- else if (strcmp (name, "keywords") == 0) {
- gchar *keywords = g_strdup (value);
- char *lasts, *keyw;
- size_t len;
-
- keyw = keywords;
- keywords = strchr (keywords, '"');
- if (keywords)
- keywords++;
- else
- keywords = keyw;
-
- len = strlen (keywords);
- if (keywords[len - 1] == '"')
- keywords[len - 1] = '\0';
-
- for (keyw = strtok_r (keywords, ",; ", &lasts); keyw;
- keyw = strtok_r (NULL, ",; ", &lasts)) {
- tracker_statement_list_insert (metadata,
- uri, NIE_PREFIX "keyword",
- (const gchar*) keyw);
- }
-
- g_free (keyw);
+ else if (strcmp (name, "date") == 0 && !data->date) {
+ data->date = g_strdup (value);
}
- else if (strcmp (name, "subject") == 0) {
- gchar *keywords = g_strdup (value);
- char *lasts, *keyw;
- size_t len;
-
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "subject", value);
-
- /* The subject field may contain keywords as well */
-
- keyw = keywords;
- keywords = strchr (keywords, '"');
- if (keywords)
- keywords++;
- else
- keywords = keyw;
-
- len = strlen (keywords);
- if (keywords[len - 1] == '"')
- keywords[len - 1] = '\0';
-
- for (keyw = strtok_r (keywords, ",; ", &lasts); keyw;
- keyw = strtok_r (NULL, ",; ", &lasts)) {
- tracker_statement_list_insert (metadata,
- uri, NIE_PREFIX "keyword",
- (const gchar*) keyw);
- }
-
- g_free (keyw);
-
+ else if (strcmp (name, "keywords") == 0 && !data->keywords) {
+ data->keywords = g_strdup (value);
}
- else if (strcmp (name, "publisher") == 0) {
- tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
- tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
- tracker_statement_list_insert (metadata, uri, NCO_PREFIX "publisher", ":");
+ else if (strcmp (name, "subject") == 0 && !data->subject) {
+ data->subject = g_strdup (value);
}
- else if (strcmp (name, "contributor") == 0) {
- tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
- tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
- tracker_statement_list_insert (metadata, uri, NCO_PREFIX "contributor", ":");
+ else if (strcmp (name, "publisher") == 0 && !data->publisher) {
+ data->publisher = g_strdup (value);
}
- else if (strcmp (name, "type") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "type", value);
+ else if (strcmp (name, "contributor") == 0 && !data->contributor) {
+ data->contributor = g_strdup (value);
}
- else if (strcmp (name, "format") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "format", value);
+ else if (strcmp (name, "type") == 0 && !data->type) {
+ data->type = g_strdup (value);
}
- else if (strcmp (name, "identifier") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "identifier", value);
+ else if (strcmp (name, "format") == 0 && !data->format) {
+ data->format = g_strdup (value);
}
- else if (strcmp (name, "source") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "source", value);
+ else if (strcmp (name, "identifier") == 0 && !data->identifier) {
+ data->identifier = g_strdup (value);
}
- else if (strcmp (name, "language") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "language", value);
+ else if (strcmp (name, "source") == 0 && !data->source) {
+ data->source = g_strdup (value);
}
- else if (strcmp (name, "relation") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "relation", value);
+ else if (strcmp (name, "language") == 0 && !data->language) {
+ data->language = g_strdup (value);
}
- else if (strcmp (name, "coverage") == 0) {
- tracker_statement_list_insert (metadata, uri,
- DC_PREFIX "coverage", value);
+ else if (strcmp (name, "relation") == 0 && !data->relation) {
+ data->relation = g_strdup (value);
+ }
+ else if (strcmp (name, "coverage") == 0 && !data->coverage) {
+ data->coverage = g_strdup (value);
}
}
/* Creative Commons */
else if (strcmp (schema, NS_CC) == 0) {
- if (strcmp (name, "license") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "license", value);
+ if (strcmp (name, "license") == 0 && !data->license) {
+ data->license = g_strdup (value);
}
}
/* Exif basic scheme */
else if (strcmp (schema, NS_EXIF) == 0) {
- if (strcmp (name, "Title") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NFO_PREFIX "title", value);
+ if (strcmp (name, "Title") == 0 && !data->Title) {
+ data->Title = g_strdup (value);
}
- else if (strcmp (name, "DateTimeOriginal") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "contentCreated", value);
+ else if (strcmp (name, "DateTimeOriginal") == 0 && !data->DateTimeOriginal) {
+ data->DateTimeOriginal = g_strdup (value);
}
- else if (strcmp (name, "Artist") == 0) {
- tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
- tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
- /* contributor is OK here? */
- tracker_statement_list_insert (metadata, uri, NCO_PREFIX "contributor", ":");
+ else if (strcmp (name, "Artist") == 0 && !data->Artist) {
+ data->Artist = g_strdup (value);
}
/* else if (strcmp (name, "Software") == 0) {
tracker_statement_list_insert (metadata, uri,
"Image:Software", value);
}*/
- else if (strcmp (name, "Make") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "camera", value);
+ else if (strcmp (name, "Make") == 0 && !data->Make) {
+ data->Make = g_strdup (value);
}
- else if (strcmp (name, "Model") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "camera", value);
+ else if (strcmp (name, "Model") == 0 && !data->Model) {
+ data->Model = g_strdup (value);
}
- else if (strcmp (name, "Orientation") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NFO_PREFIX "orientation",
- fix_orientation (value));
+ else if (strcmp (name, "Orientation") == 0 && !data->Orientation) {
+ data->Orientation = g_strdup (fix_orientation (value));
}
- else if (strcmp (name, "Flash") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "flash",
- fix_flash (value));
+ else if (strcmp (name, "Flash") == 0 && !data->Flash) {
+ data->Flash = g_strdup (fix_flash (value));
}
- else if (strcmp (name, "MeteringMode") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "meteringMode",
- fix_metering_mode (value));
+ else if (strcmp (name, "MeteringMode") == 0 && !data->MeteringMode) {
+ data->MeteringMode = g_strdup (fix_metering_mode (value));
}
/*else if (strcmp (name, "ExposureProgram") == 0) {
tracker_statement_list_insert (metadata, uri,
"Image:ExposureProgram", value);
}*/
- else if (strcmp (name, "ExposureTime") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "exposureTime", value);
+ else if (strcmp (name, "ExposureTime") == 0 && !data->ExposureTime) {
+ data->ExposureTime = g_strdup (value);
}
- else if (strcmp (name, "FNumber") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "fnumber", value);
+ else if (strcmp (name, "FNumber") == 0 && !data->FNumber) {
+ data->FNumber = g_strdup (value);
}
- else if (strcmp (name, "FocalLength") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "focalLength", value);
+ else if (strcmp (name, "FocalLength") == 0 && !data->FocalLength) {
+ data->FocalLength = g_strdup (value);
}
- else if (strcmp (name, "ISOSpeedRatings") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "isoSpeed", value);
+ else if (strcmp (name, "ISOSpeedRatings") == 0 && !data->ISOSpeedRatings) {
+ data->ISOSpeedRatings = g_strdup (value);
}
- else if (strcmp (name, "WhiteBalance") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NMM_PREFIX "whiteBalance",
- fix_white_balance (value));
+ else if (strcmp (name, "WhiteBalance") == 0 && !data->WhiteBalance) {
+ data->WhiteBalance = g_strdup (fix_white_balance (value));
}
- else if (strcmp (name, "Copyright") == 0) {
- tracker_statement_list_insert (metadata, uri,
- NIE_PREFIX "copyright", value);
+ else if (strcmp (name, "Copyright") == 0 && !data->Copyright) {
+ data->Copyright = g_strdup (value);
}
}
/* XAP (XMP)scheme */
@@ -534,7 +434,7 @@ void
tracker_xmp_iter (XmpPtr xmp,
XmpIteratorPtr iter,
const gchar *uri,
- TrackerSparqlBuilder *metadata,
+ TrackerXmpData *data,
gboolean append)
{
XmpStringPtr the_schema = xmp_string_new ();
@@ -550,18 +450,18 @@ tracker_xmp_iter (XmpPtr xmp,
if (XMP_IS_PROP_SIMPLE (opt)) {
if (!tracker_is_empty_string (path)) {
if (XMP_HAS_PROP_QUALIFIERS (opt)) {
- tracker_xmp_iter_simple_qual (xmp, uri, metadata, schema, path, value, append);
+ tracker_xmp_iter_simple_qual (xmp, uri, data, schema, path, value, append);
} else {
- tracker_xmp_iter_simple (uri, metadata, schema, path, value, append);
+ tracker_xmp_iter_simple (uri, data, schema, path, value, append);
}
}
}
else if (XMP_IS_PROP_ARRAY (opt)) {
if (XMP_IS_ARRAY_ALTTEXT (opt)) {
- tracker_xmp_iter_alt_text (xmp, uri, metadata, schema, path);
+ tracker_xmp_iter_alt_text (xmp, uri, data, schema, path);
xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
} else {
- tracker_xmp_iter_array (xmp, uri, metadata, schema, path);
+ tracker_xmp_iter_array (xmp, uri, data, schema, path);
xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
}
}
@@ -578,7 +478,7 @@ void
tracker_read_xmp (const gchar *buffer,
size_t len,
const gchar *uri,
- TrackerSparqlBuilder *metadata)
+ TrackerXmpData *data)
{
#ifdef HAVE_EXEMPI
XmpPtr xmp;
@@ -592,7 +492,7 @@ tracker_read_xmp (const gchar *buffer,
XmpIteratorPtr iter;
iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_PROPERTIES);
- tracker_xmp_iter (xmp, iter, uri, metadata, FALSE);
+ tracker_xmp_iter (xmp, iter, uri, data, FALSE);
xmp_iterator_free (iter);
xmp_free (xmp);
}
diff --git a/src/tracker-extract/tracker-xmp.h b/src/tracker-extract/tracker-xmp.h
index fd4d7c6..f14b2c3 100644
--- a/src/tracker-extract/tracker-xmp.h
+++ b/src/tracker-extract/tracker-xmp.h
@@ -22,9 +22,30 @@
#include <glib.h>
+typedef struct {
+ /* NS_DC */
+ gchar *title, *rights, *creator, *description, *date, *keywords, *subject,
+ *publisher, *contributor, *type, *format, *identifier, *source,
+ *language, *relation, *coverage;
+
+ /* NS_CC */
+ gchar *license;
+
+ /* NS_EXIF */
+ gchar *Title, *DateTimeOriginal, *Artist, *Make, *Model, *Orientation,
+ *Flash, *MeteringMode, *ExposureTime, *FNumber, *FocalLength,
+ *ISOSpeedRatings, *WhiteBalance, *Copyright;
+
+ /* TODO NS_XAP*/
+ /* TODO NS_IPTC4XMP */
+ /* TODO NS_PHOTOSHOP */
+
+} TrackerXmpData;
+
+
void tracker_read_xmp (const gchar *buffer,
size_t len,
const gchar *uri,
- TrackerSparqlBuilder *metadata);
+ TrackerXmpData *data);
#endif /* _TRACKER_XMP_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]