[tracker/roi-png-fix] Fix the Imagemagick png raw profile magic.



commit 373147928efe09921cb23f649272c7486645687f
Author: Mikael Ottela <mikael ottela ixonos com>
Date:   Thu Sep 8 15:21:27 2011 +0300

    Fix the Imagemagick png raw profile magic.

 src/tracker-extract/tracker-extract-png.c |  154 +++++++++++++++++++++++++++--
 1 files changed, 146 insertions(+), 8 deletions(-)
---
diff --git a/src/tracker-extract/tracker-extract-png.c b/src/tracker-extract/tracker-extract-png.c
index a001071..4091166 100644
--- a/src/tracker-extract/tracker-extract-png.c
+++ b/src/tracker-extract/tracker-extract-png.c
@@ -79,6 +79,112 @@ rfc1123_to_iso8601_date (const gchar *date)
 	return tracker_date_format_to_iso8601 (date, RFC1123_DATE_FORMAT);
 }
 
+#if defined(HAVE_EXEMPI) && defined(PNG_iTXt_SUPPORTED)
+
+/* Handle raw profiles by Imagemagick (at least). Hex encoded with
+ * line-changes and other (undocumented/unofficial) twists.
+ */
+static gchar *
+raw_profile_new (const gchar *input,
+                 const guint  input_length,
+                 guint       *output_length)
+{
+	static const gchar* const lut = "0123456789abcdef";
+	gchar *output;
+	const gchar *ptr;
+	const gchar *length_ptr;
+	gsize size;
+	gchar *length_str;
+	guint length;
+
+	size_t len;
+	size_t i;
+	size_t o;
+	char *p;
+	char *q;
+
+	ptr = input;
+
+	if (*ptr != '\n') {
+		return NULL;
+	}
+
+	ptr++;
+
+	if (!g_ascii_isalpha (*ptr)) {
+		return NULL;
+	}
+
+	/* Skip the type string */
+	do {
+		ptr++;
+	} while (g_ascii_isalpha (*ptr));
+
+	if (*ptr != '\n') {
+		return NULL;
+	}
+
+	/* Hop over whitespaces */
+	do {
+		ptr++;
+	} while (*ptr == ' ');
+
+	if (!g_ascii_isdigit (*ptr)) {
+		return NULL;
+	}
+
+	/* Get the length string */
+	length_ptr = ptr;
+	size = 1;
+
+	do {
+		ptr++;
+		size++;
+	} while (g_ascii_isdigit (*ptr));
+
+	length_str = g_strndup (length_ptr, size - 1);
+
+	if (*ptr != '\n') {
+		return NULL;
+	}
+
+	ptr++;
+
+	length = atoi (length_str);
+	g_free (length_str);
+
+	len = length;
+	i = 0;
+	o = 0;
+
+	output = malloc (length + 1); /* A bit less with non-valid */
+
+	o = 0;
+	while (o < len) {
+		do {
+			gchar a = ptr[i];
+			p = strchr (lut, a);
+			i++;
+		} while (p == 0);
+
+		do {
+			gchar b = ptr[i];
+			q = strchr (lut, b);
+			i++;
+		} while (q == 0);
+
+		output[o] = (((p - lut) << 4) | (q - lut));
+		o++;
+	}
+
+	output[o] = '\0';
+	*output_length = o;
+
+	return output;
+}
+
+#endif /* HAVE_EXEMPI && PNG_iTXt_SUPPORTED */
+
 static void
 read_metadata (TrackerSparqlBuilder *preupdate,
                TrackerSparqlBuilder *metadata,
@@ -115,21 +221,48 @@ read_metadata (TrackerSparqlBuilder *preupdate,
 				continue;
 			}
 
-	#if defined(HAVE_EXEMPI) && defined(PNG_iTXt_SUPPORTED)
+#if defined(HAVE_EXEMPI) && defined(PNG_iTXt_SUPPORTED)
 			if (g_strcmp0 ("XML:com.adobe.xmp", text_ptr[i].key) == 0) {
 				/* ATM tracker_extract_xmp_read supports setting xd
 				 * multiple times, keep it that way as here it's
 				 * theoretically possible that the function gets
-				 * called multiple times 
+				 * called multiple times
 				 */
 				xd = tracker_xmp_new (text_ptr[i].text,
-					              text_ptr[i].itxt_length,
-					              uri);
+				                      text_ptr[i].itxt_length,
+				                      uri);
+
+				continue;
+			}
+
+			if (g_strcmp0 ("Raw profile type xmp", text_ptr[i].key) == 0) {
+				gchar *xmp_buffer;
+				guint xmp_buffer_length = 0;
+				guint input_len;
+
+				if (text_ptr[i].text_length) {
+					input_len = text_ptr[i].text_length;
+				} else {
+					input_len = text_ptr[i].itxt_length;
+				}
+
+				xmp_buffer = raw_profile_new (text_ptr[i].text,
+				                              input_len,
+				                              &xmp_buffer_length);
+
+				if (xmp_buffer) {
+					xd = tracker_xmp_new (xmp_buffer,
+					                      xmp_buffer_length,
+					                      uri);
+				}
+
+				g_free (xmp_buffer);
+
 				continue;
 			}
-	#endif
+#endif
 
-	#if defined(HAVE_LIBEXIF) && defined(PNG_iTXt_SUPPORTED)
+#if defined(HAVE_LIBEXIF) && defined(PNG_iTXt_SUPPORTED)
 			/* I'm not certain this is the key for EXIF. Using key according to
 			 * this document about exiftool:
 			 * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData 
@@ -140,7 +273,7 @@ read_metadata (TrackerSparqlBuilder *preupdate,
 					               uri);
 				continue;
 			}
-	#endif /* HAVE_LIBEXIF */
+#endif /* HAVE_LIBEXIF */
 
 			if (g_strcmp0 (text_ptr[i].key, "Author") == 0) {
 				pd.author = text_ptr[i].text;
@@ -457,11 +590,12 @@ read_metadata (TrackerSparqlBuilder *preupdate,
 
 		if (xd->address || xd->state || xd->country || xd->city)  {
 			gchar *addruri;
+
 			addruri = tracker_sparql_get_uuid_urn ();
 
 			tracker_sparql_builder_predicate (metadata, "slo:postalAddress");
 			tracker_sparql_builder_object_iri (metadata, addruri);
-			
+
 			tracker_sparql_builder_insert_open (preupdate, NULL);
 			if (graph) {
 				tracker_sparql_builder_graph_open (preupdate, graph);
@@ -539,6 +673,10 @@ read_metadata (TrackerSparqlBuilder *preupdate,
 		tracker_sparql_builder_object_double (metadata, value);
 	}
 
+	if (xd->regions) {
+		tracker_xmp_apply_regions (preupdate, metadata, graph, xd);
+	}
+
 	for (i = 0; i < keywords->len; i++) {
 		gchar *p, *escaped, *var;
 



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