[tracker] Fixed the TIFF extractor for the new image ontology
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker] Fixed the TIFF extractor for the new image ontology
- Date: Thu, 16 Apr 2009 11:36:12 -0400 (EDT)
commit 0e48339c88fe619e7020b827047f9af2a006eaf4
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Apr 16 16:08:01 2009 +0200
Fixed the TIFF extractor for the new image ontology
---
src/tracker-extract/tracker-extract-jpeg.c | 1 -
src/tracker-extract/tracker-extract-tiff.c | 318 ++++++++++++++++++++++++----
2 files changed, 280 insertions(+), 39 deletions(-)
diff --git a/src/tracker-extract/tracker-extract-jpeg.c b/src/tracker-extract/tracker-extract-jpeg.c
index e0062cb..89f0e16 100644
--- a/src/tracker-extract/tracker-extract-jpeg.c
+++ b/src/tracker-extract/tracker-extract-jpeg.c
@@ -35,7 +35,6 @@
#include <string.h>
#include <fcntl.h>
-#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/src/tracker-extract/tracker-extract-tiff.c b/src/tracker-extract/tracker-extract-tiff.c
index 821cd22..cf1fc4b 100644
--- a/src/tracker-extract/tracker-extract-tiff.c
+++ b/src/tracker-extract/tracker-extract-tiff.c
@@ -21,6 +21,16 @@
#include "config.h"
+#include <stdio.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* strcasestr() */
+#endif
+
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+
#include <glib.h>
#include <glib/gstdio.h>
@@ -31,6 +41,7 @@
#include <libtracker-common/tracker-type-utils.h>
#include <libtracker-common/tracker-statement-list.h>
#include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-utils.h>
#include "tracker-main.h"
#include "tracker-xmp.h"
@@ -47,7 +58,7 @@
#define RDF_PREFIX TRACKER_RDF_PREFIX
#define RDF_TYPE RDF_PREFIX "type"
-typedef gchar * (*PostProcessor) (gchar *);
+typedef gchar * (*PostProcessor) (const gchar *, gboolean *);
typedef enum {
TIFF_TAGTYPE_UNDEFINED = 0,
@@ -63,56 +74,270 @@ typedef struct {
const gchar *name;
TagType type;
PostProcessor post;
+ const gchar *rdf_class;
+ const gchar *rdf_property;
+ const gchar *urn_prefix;
} TiffTag;
static void extract_tiff (const gchar *filename,
GPtrArray *metadata);
-static gchar *date_to_iso8601 (gchar *date);
+
+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 TrackerExtractData extract_data[] = {
{ "image/tiff", extract_tiff },
{ NULL, NULL }
};
+
+
/* FIXME: We are missing some */
static TiffTag tags[] = {
- { TIFFTAG_ARTIST, NCO_PREFIX "creator", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_COPYRIGHT, NIE_PREFIX "copyright", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_DATETIME, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_DOCUMENTNAME, NIE_PREFIX "title", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_IMAGEDESCRIPTION, NIE_PREFIX "comment", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_IMAGEWIDTH, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL },
- { TIFFTAG_IMAGELENGTH, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL },
- { TIFFTAG_MAKE, "Image:CameraMake", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_MODEL, "Image:CameraModel", TIFF_TAGTYPE_STRING, NULL },
- { TIFFTAG_ORIENTATION, "Image:Orientation", TIFF_TAGTYPE_UINT16, NULL },
- { TIFFTAG_SOFTWARE, "Image:Software", TIFF_TAGTYPE_STRING, NULL },
- { -1, NULL, TIFF_TAGTYPE_UNDEFINED, NULL }
+ { TIFFTAG_ARTIST, NCO_PREFIX "creator", TIFF_TAGTYPE_STRING, NULL, NCO_PREFIX "Contact", NCO_PREFIX "fullname" , ":"},
+ { TIFFTAG_COPYRIGHT, NIE_PREFIX "copyright", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_DATETIME, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_DOCUMENTNAME, NIE_PREFIX "title", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_IMAGEDESCRIPTION, NIE_PREFIX "comment", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_IMAGEWIDTH, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL, NULL, NULL, NULL },
+ { TIFFTAG_IMAGELENGTH, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL, NULL, NULL, NULL },
+ { TIFFTAG_MAKE, NMM_PREFIX "camera", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_MODEL, NMM_PREFIX "camera", TIFF_TAGTYPE_STRING, NULL, NULL, NULL, NULL },
+ { TIFFTAG_ORIENTATION, NFO_PREFIX "orientation", TIFF_TAGTYPE_UINT16, fix_orientation, NULL, NULL, NULL },
+ /* { TIFFTAG_SOFTWARE, "Image:Software", TIFF_TAGTYPE_STRING, NULL }, */
+ { -1, NULL, TIFF_TAGTYPE_UNDEFINED, NULL, NULL, NULL, NULL }
};
static TiffTag exiftags[] = {
- { EXIFTAG_EXPOSURETIME, "Image:ExposureTime", TIFF_TAGTYPE_DOUBLE, NULL},
- { EXIFTAG_FNUMBER, "Image:FNumber", TIFF_TAGTYPE_DOUBLE, NULL},
- { EXIFTAG_EXPOSUREPROGRAM, "Image:ExposureProgram", TIFF_TAGTYPE_UINT16, NULL },
- { EXIFTAG_ISOSPEEDRATINGS, "Image:ISOSpeed", TIFF_TAGTYPE_C16_UINT16, NULL},
- { EXIFTAG_DATETIMEORIGINAL, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, date_to_iso8601 },
- { EXIFTAG_METERINGMODE, "Image:MeteringMode", TIFF_TAGTYPE_UINT16, NULL},
- { EXIFTAG_FLASH, "Image:Flash", TIFF_TAGTYPE_UINT16, NULL},
- { EXIFTAG_FOCALLENGTH, "Image:FocalLength", TIFF_TAGTYPE_DOUBLE, NULL},
- { EXIFTAG_PIXELXDIMENSION, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL},
- { EXIFTAG_PIXELYDIMENSION, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL},
- { EXIFTAG_WHITEBALANCE, "Image:WhiteBalance", TIFF_TAGTYPE_UINT16, NULL},
- { -1, NULL, TIFF_TAGTYPE_UNDEFINED, NULL }
+ { EXIFTAG_EXPOSURETIME, NMM_PREFIX "exposureTime", TIFF_TAGTYPE_DOUBLE, fix_exposure_time, NULL, NULL, NULL},
+ { EXIFTAG_FNUMBER, NMM_PREFIX "fnumber", TIFF_TAGTYPE_DOUBLE, fix_fnumber, NULL, NULL, NULL},
+ /* { EXIFTAG_EXPOSUREPROGRAM, "Image:ExposureProgram", TIFF_TAGTYPE_UINT16, NULL, NULL, NULL, NULL }, */
+ { EXIFTAG_ISOSPEEDRATINGS, NMM_PREFIX "isoSpeed", TIFF_TAGTYPE_C16_UINT16, NULL, NULL, NULL, NULL},
+ { EXIFTAG_DATETIMEORIGINAL, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, date_to_iso8601, NULL, NULL, NULL },
+ { EXIFTAG_METERINGMODE, NMM_PREFIX "meteringMode", TIFF_TAGTYPE_UINT16, fix_metering_mode, NULL, NULL, NULL },
+ { EXIFTAG_FLASH, NMM_PREFIX "flash", TIFF_TAGTYPE_UINT16, fix_flash, NULL, NULL, NULL },
+ { EXIFTAG_FOCALLENGTH, NMM_PREFIX "focalLength", TIFF_TAGTYPE_DOUBLE, fix_focal_length, NULL, NULL, NULL},
+ { EXIFTAG_PIXELXDIMENSION, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL, NULL, NULL, NULL},
+ { EXIFTAG_PIXELYDIMENSION, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL, NULL, NULL, NULL},
+ { EXIFTAG_WHITEBALANCE, NMM_PREFIX "whiteBalance", TIFF_TAGTYPE_UINT16, fix_white_balance, NULL, NULL, NULL },
+ { -1, NULL, TIFF_TAGTYPE_UNDEFINED, NULL, NULL, 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 */
+
static gchar *
-date_to_iso8601 (gchar *date)
+date_to_iso8601 (const gchar *exif_date, gboolean *free_it)
{
/* 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, EXIF_DATE_FORMAT);
+ *free_it = TRUE;
+ return tracker_date_format_to_iso8601 (exif_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)
+{
+ /* Found in the field: Auto, Did not fire, Red-eye reduction */
+
+ *free_it = FALSE;
+
+ if (strcasestr (flash, "not fire")) {
+ return (gchar *) "nmm:flash-off";
+ } else {
+ return (gchar *) "nmm:flash-on";
+ }
+}
+
+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) {
+ default:
+ case 0:
+ return (gchar *) "nfo:orientation-top";
+ case 1:
+ return (gchar *) "nfo:orientation-top-mirror"; // not sure
+ case 2:
+ return (gchar *) "nfo:orientation-bottom-mirror"; // not sure
+ case 3:
+ return (gchar *) "nfo:orientation-bottom";
+ 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";
+ }
+ }
+ }
+
+ return (gchar *) "nfo:orientation-top";
+}
+
+
+static gchar *
+fix_metering_mode (const gchar *metering_mode, gboolean *free_it)
+{
+ /* Found in the field: Multi-segment. These will yield as other */
+
+ *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
@@ -221,13 +446,17 @@ extract_tiff (const gchar *uri,
}
if (tag->post) {
+ gboolean free_it = FALSE;
+ gchar *value = (*tag->post) (buffer, &free_it);
tracker_statement_list_insert (metadata, uri,
- tag->name,
- (*tag->post) (buffer));
+ tag->name,
+ value);
+ if (free_it)
+ g_free (value);
} else {
tracker_statement_list_insert (metadata, uri,
- tag->name,
- buffer);
+ tag->name,
+ buffer);
}
}
}
@@ -236,6 +465,7 @@ extract_tiff (const gchar *uri,
/* We want to give native tags priority over XMP/Exif */
for (tag = tags; tag->name; ++tag) {
gchar *what_i_need;
+ gboolean free_it = FALSE;
switch (tag->type) {
case TIFF_TAGTYPE_STRING:
@@ -272,20 +502,32 @@ extract_tiff (const gchar *uri,
}
if (tag->post) {
- what_i_need = (*tag->post) (buffer);
+ what_i_need = (*tag->post) (buffer, &free_it);
} else {
what_i_need = buffer;
}
- if (tag->tag == TIFFTAG_ARTIST) {
- tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
- tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", what_i_need);
- tracker_statement_list_insert (metadata, uri, tag->name, ":");
+
+ if (tag->urn_prefix) {
+ gchar *canonical_uri;
+
+ if (tag->urn_prefix[0] == ':')
+ canonical_uri = tracker_uri_printf_escaped (tag->urn_prefix, what_i_need);
+ else
+ canonical_uri = (gchar *) tag->urn_prefix;
+
+ tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, tag->rdf_class);
+ tracker_statement_list_insert (metadata, canonical_uri, tag->rdf_property, what_i_need);
+ tracker_statement_list_insert (metadata, uri, tag->name, canonical_uri);
+
+ if (tag->urn_prefix[0] != ':')
+ g_free (canonical_uri);
} else {
tracker_statement_list_insert (metadata, uri, tag->name, what_i_need);
}
- if (tag->post)
+
+ if (free_it)
g_free (what_i_need);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]