From f096d6406e9b5e00fa21390224c2bfcc3be8f135 Mon Sep 17 00:00:00 2001
From: Stefan Kost <ensonic@users.sf.net>
Date: Wed, 10 Jun 2009 11:15:01 +0300
Subject: metadata: fix conversion of geo coordinates

Coordinate conversion has been verified with exiv2 and some webpages.
Minutes wher totally off and seconds were not used at all.
---
 ext/metadata/metadataexif.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

(limited to 'ext/metadata')

diff --git a/ext/metadata/metadataexif.c b/ext/metadata/metadataexif.c
index 58d83e2d..0769dab4 100644
--- a/ext/metadata/metadataexif.c
+++ b/ext/metadata/metadataexif.c
@@ -694,16 +694,16 @@ metadataparse_exif_content_foreach_entry_func (ExifEntry * entry,
 
           /* DDD - degrees */
           value = (gdouble) rt->numerator / (gdouble) rt->denominator;
+          GST_DEBUG ("deg: %lu / %lu", rt->numerator, rt->denominator);
           rt++;
 
           /* MM - minutes and SS - seconds */
-          if (rt->numerator % rt->denominator) {
-            value += (gdouble) rt->numerator / (gdouble) rt->denominator;
-          } else {
-            value += rt->numerator / rt->denominator;
-            rt++;
-            value += rt->numerator / rt->denominator;
-          }
+          GST_DEBUG ("min: %lu / %lu", rt->numerator, rt->denominator);
+          value += (gdouble) rt->numerator / ((gdouble) rt->denominator * 60.0);
+          rt++;
+          GST_DEBUG ("sec: %lu / %lu", rt->numerator, rt->denominator);
+          value +=
+              (gdouble) rt->numerator / ((gdouble) rt->denominator * 3600.0);
 
           /* apply sign */
           if (entry->tag == EXIF_TAG_GPS_LATITUDE) {
@@ -1049,17 +1049,24 @@ metadatamux_exif_for_each_tag_in_list (const GstTagList * list,
           const ExifTag ref_tag = entry->tag == EXIF_TAG_GPS_LATITUDE ?
               EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF;
 
+          /* DDD - degrees */
           rt->numerator = (gulong) v;
           rt->denominator = 1;
+          GST_DEBUG ("deg: %lf : %lu / %lu", v, rt->numerator, rt->denominator);
           v -= rt->numerator;
           rt++;
 
-          rt->numerator = (gulong) (0.5 + v * 100.0);
-          rt->denominator = 100;
+          /* MM - minutes */
+          rt->numerator = (gulong) (v * 60.0);
+          rt->denominator = 1;
+          GST_DEBUG ("min: %lf : %lu / %lu", v, rt->numerator, rt->denominator);
+          v -= ((gdouble) rt->numerator / 60.0);
           rt++;
 
-          rt->numerator = 0;
+          /* SS - seconds */
+          rt->numerator = (gulong) (0.5 + v * 3600.0);
           rt->denominator = 1;
+          GST_DEBUG ("sec: %lf : %lu / %lu", v, rt->numerator, rt->denominator);
 
           if (entry->tag == EXIF_TAG_GPS_LONGITUDE) {
             GST_DEBUG ("longitude : %lf", value);
-- 
cgit v1.2.1


From d5b302ffc4b83a93c726f3b69cd1593adb232944 Mon Sep 17 00:00:00 2001
From: Stefan Kost <ensonic@users.sf.net>
Date: Mon, 22 Jun 2009 18:35:21 +0300
Subject: metadata: map more tags and fix reading of xmp tags

Register xmp schemas for photoshop and iptc. Map a few location tags there.
Add more dc tags. Fix reading xmp tag by iteration over known schemas. Add
some more debug logging.
---
 ext/metadata/metadatatags.c | 12 +++++++++
 ext/metadata/metadatatags.h |  4 +++
 ext/metadata/metadataxmp.c  | 64 ++++++++++++++++++++++++++++++++++-----------
 3 files changed, 65 insertions(+), 15 deletions(-)

(limited to 'ext/metadata')

diff --git a/ext/metadata/metadatatags.c b/ext/metadata/metadatatags.c
index 82e6c381..4beee172 100644
--- a/ext/metadata/metadatatags.c
+++ b/ext/metadata/metadatatags.c
@@ -446,5 +446,17 @@ metadata_tags_iptc_register (void)
 static void
 metadata_tags_xmp_register (void)
 {
+  gst_tag_register (GST_TAG_XMP_GEO_LOCATION_COUNTRY, GST_TAG_FLAG_META,
+      G_TYPE_STRING, GST_TAG_XMP_GEO_LOCATION_COUNTRY,
+      "human readable english country name of where the media has been recorded or produced",
+      NULL);
+  gst_tag_register (GST_TAG_XMP_GEO_LOCATION_CITY, GST_TAG_FLAG_META,
+      G_TYPE_STRING, GST_TAG_XMP_GEO_LOCATION_CITY,
+      "human readable english city name of where the media has been recorded or produced",
+      NULL);
+  gst_tag_register (GST_TAG_XMP_GEO_LOCATION_SUBLOCATION, GST_TAG_FLAG_META,
+      G_TYPE_STRING, GST_TAG_XMP_GEO_LOCATION_SUBLOCATION,
+      "human readable location detail of where the media has been recorded or produced",
+      NULL);
 
 }
diff --git a/ext/metadata/metadatatags.h b/ext/metadata/metadatatags.h
index 8500f15a..4d718738 100644
--- a/ext/metadata/metadatatags.h
+++ b/ext/metadata/metadatatags.h
@@ -126,6 +126,10 @@ typedef enum {
 #define GST_TAG_GPS_SPEED                  "" 
 #define GST_TAG_GPS_TRACK                  ""
 
+#define GST_TAG_XMP_GEO_LOCATION_COUNTRY   "geo-location-country"
+#define GST_TAG_XMP_GEO_LOCATION_CITY      "geo-location-city"
+#define GST_TAG_XMP_GEO_LOCATION_SUBLOCATION  "geo-location-sublocation"
+
 /* *INDENT-ON* */
 
 /*
diff --git a/ext/metadata/metadataxmp.c b/ext/metadata/metadataxmp.c
index 4da279df..5d5bdefa 100644
--- a/ext/metadata/metadataxmp.c
+++ b/ext/metadata/metadataxmp.c
@@ -155,13 +155,26 @@ typedef struct _tag_SchemaMap
 #define XMP_SCHEMA_NODE 0x80000000UL
 
 /* *INDENT-OFF* */
-/* When changing this table, update 'metadata_mapping.htm' file too. */
+/* When changing these tables, update 'metadata_mapping.htm' file too. */
 static const SchemaTagMap schema_map_dublin_tags_map[] = {
+  {"creator",     GST_TAG_ARTIST      },
   {"description", GST_TAG_DESCRIPTION },
-  {"title",       GST_TAG_TITLE       },
+  {"format",      GST_TAG_VIDEO_CODEC },
   {"rights",      GST_TAG_COPYRIGHT   },
+  {"subject",     GST_TAG_KEYWORDS    },
+  {"title",       GST_TAG_TITLE       },
   {"type",        GST_TAG_CODEC       },
-  {"format",      GST_TAG_VIDEO_CODEC },
+  {NULL, NULL}
+};
+
+static const SchemaTagMap schema_map_photoshop_tags_map[] = {
+  {"country",     GST_TAG_XMP_GEO_LOCATION_COUNTRY },
+  {"city",        GST_TAG_XMP_GEO_LOCATION_CITY   },
+  {NULL, NULL}
+};
+
+static const SchemaTagMap schema_map_iptc4xmpcore_tags_map[] = {
+  {"location",    GST_TAG_XMP_GEO_LOCATION_SUBLOCATION },
   {NULL, NULL}
 };
 /* *INDENT-ON* */
@@ -173,9 +186,26 @@ static const SchemaMap schema_map_dublin = {
   schema_map_dublin_tags_map
 };
 
-/* When changing this table, update 'metadata_mapping.htm' file too. */
+/* http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf */
+static const SchemaMap schema_map_photoshop = {
+  "http://ns.adobe.com/photoshop/1.0/",
+  "photoshop:",
+  10,
+  schema_map_photoshop_tags_map
+};
+
+/* http://www.iptc.org/std/Iptc4xmpCore/1.0/specification/Iptc4xmpCore_1.0-spec-XMPSchema_8.pdf */
+static const SchemaMap schema_map_iptc4xmpcore = {
+  "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/",
+  "Iptc4xmpCore:",
+  13,
+  schema_map_iptc4xmpcore_tags_map
+};
+
 static const SchemaMap *schemas_map[] = {
   &schema_map_dublin,
+  &schema_map_photoshop,
+  &schema_map_iptc4xmpcore,
   NULL
 };
 
@@ -474,7 +504,6 @@ metadatamux_xmp_get_tagsmap_from_gsttag (const SchemaMap * schema_map,
   if (NULL == schema_map)
     goto done;
 
-
   for (i = 0; schema_map->tags_map[i].gst_tag; i++) {
     if (0 == strcmp (schema_map->tags_map[i].gst_tag, tag)) {
       tags_map = (SchemaTagMap *) & schema_map->tags_map[i];
@@ -567,10 +596,14 @@ void
 metadataparse_xmp_iter_node_schema (GstTagList * taglist, GstTagMergeMode mode,
     XmpPtr xmp, const char *schema, const char *path)
 {
-  SchemaMap *schema_map = NULL;
+  const SchemaMap *schema_map = NULL;
+  gint i;
 
-  if (0 == strcmp (schema, "http://purl.org/dc/elements/1.1/")) {
-    schema_map = (SchemaMap *) & schema_map_dublin;
+  for (i = 0; schemas_map[i]; i++) {
+    if (0 == strcmp (schema, schemas_map[i]->schema)) {
+      schema_map = schemas_map[i];
+      break;
+    }
   }
 
   metadataparse_xmp_iter_array (taglist, mode, xmp, schema, path, schema_map);
@@ -805,6 +838,8 @@ metadatamux_xmp_for_each_tag_in_list (const GstTagList * list,
   XmpPtr xmp = (XmpPtr) user_data;
   int i;
 
+  GST_DEBUG ("trying to map tag '%s' to xmp", tag);
+
   for (i = 0; schemas_map[i]; i++) {
 
     /* FIXME: should try to get all of values (index) for the tag */
@@ -814,9 +849,7 @@ metadatamux_xmp_for_each_tag_in_list (const GstTagList * list,
         metadatamux_xmp_get_tagsmap_from_gsttag (smap, tag);
 
     if (stagmap) {
-
       gchar *value = NULL;
-
       GType type = gst_tag_get_type (tag);
 
       switch (type) {
@@ -827,8 +860,10 @@ metadatamux_xmp_for_each_tag_in_list (const GstTagList * list,
           break;
       }
 
-      if (value) {
+      GST_DEBUG ("found mapping for tag '%s' in schema %s", tag,
+          schemas_map[i]->prefix);
 
+      if (value) {
         uint32_t options = 0;
 
 #ifdef XMP_1_99_5
@@ -857,13 +892,12 @@ metadatamux_xmp_for_each_tag_in_list (const GstTagList * list,
         }
 
         g_free (value);
-
       }
-
+    } else {
+      GST_DEBUG ("no xmp mapping for tag '%s' in schema %s found", tag,
+          schemas_map[i]->prefix);
     }
-
   }
-
 }
 
 #endif /* else (ifndef HAVE_XMP) */
-- 
cgit v1.2.1