summaryrefslogtreecommitdiffstats
path: root/ext/metadata/metadataxmp.c
diff options
context:
space:
mode:
authorEdgard Lima <edgard.lima@indt.org.br>2008-01-17 16:10:48 +0000
committerEdgard Lima <edgard.lima@indt.org.br>2008-01-17 16:10:48 +0000
commit63490f4b482eb00fbd354a0aa90056ca80f6fe3c (patch)
treee061709c84b927be107d4045bdbc4d18639fcbd9 /ext/metadata/metadataxmp.c
parent631b6a1766f76ed7075e03d5a94683f6a9c10fc2 (diff)
downloadgst-plugins-bad-63490f4b482eb00fbd354a0aa90056ca80f6fe3c.tar.gz
gst-plugins-bad-63490f4b482eb00fbd354a0aa90056ca80f6fe3c.tar.bz2
gst-plugins-bad-63490f4b482eb00fbd354a0aa90056ca80f6fe3c.zip
Fixed adding EXIF tags to correct IFD. Mapped some XMP tags.
Original commit message from CVS: Fixed adding EXIF tags to correct IFD. Mapped some XMP tags.
Diffstat (limited to 'ext/metadata/metadataxmp.c')
-rw-r--r--ext/metadata/metadataxmp.c382
1 files changed, 329 insertions, 53 deletions
diff --git a/ext/metadata/metadataxmp.c b/ext/metadata/metadataxmp.c
index 56c3ad87..cc8172ce 100644
--- a/ext/metadata/metadataxmp.c
+++ b/ext/metadata/metadataxmp.c
@@ -88,14 +88,64 @@ metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 * size,
#define XMP_SCHEMA_NODE 0x80000000UL
-void
-metadataparse_xmp_iter_array (XmpPtr xmp, const char *schema, const char *path);
+typedef struct _tag_SchemaTagMap
+{
+ const gchar *xmp_tag;
+ const gchar *gst_tag;
+} SchemaTagMap;
+
+typedef struct _tag_SchemaMap
+{
+ const gchar *schema;
+ const gchar *prefix;
+ const guint8 prefix_len;
+ const SchemaTagMap *tags_map;
+} SchemaMap;
+
+static const SchemaTagMap schema_map_dublin_tags_map[] = {
+ {"description", GST_TAG_DESCRIPTION},
+ {"title", GST_TAG_TITLE},
+ {"rights", GST_TAG_COPYRIGHT},
+ {NULL, NULL}
+};
+
+static const SchemaMap schema_map_dublin = { "http://purl.org/dc/elements/1.1/",
+ "dc:",
+ 3,
+ schema_map_dublin_tags_map
+};
+
+static const SchemaMap *schemas_map[] = {
+ &schema_map_dublin,
+ NULL
+};
+
+static void
+metadataparse_xmp_iter_add_to_tag_list (GstTagList * taglist,
+ GstTagMergeMode mode, const char *path, const char *value,
+ const SchemaMap * schema_map, const uint32_t opt);
+
+static void
+metadataparse_xmp_iter_array (GstTagList * taglist, GstTagMergeMode mode,
+ XmpPtr xmp, const char *schema, const char *path,
+ const SchemaMap * schema_map);
+
+static void
+metadataparse_xmp_iter_node_schema (GstTagList * taglist, GstTagMergeMode mode,
+ XmpPtr xmp, const char *schema, const char *path);
static void
-metadataparse_xmp_iter_simple (const char *schema, const char *path,
- const char *value);
+metadataparse_xmp_iter_simple (GstTagList * taglist, GstTagMergeMode mode,
+ const char *schema, const char *path, const char *value,
+ const SchemaMap * schema_map);
-static void metadataparse_xmp_iter (XmpPtr xmp, XmpIteratorPtr iter);
+static void
+metadataparse_xmp_iter_simple_qual (GstTagList * taglist, GstTagMergeMode mode,
+ const char *schema, const char *path, const char *value,
+ const SchemaMap * schema_map);
+
+static void
+metadataparse_xmp_iter (GstTagList * taglist, GstTagMergeMode mode, XmpPtr xmp);
gboolean
metadataparse_xmp_init (void)
@@ -116,7 +166,6 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
const guint8 *buf;
guint32 size;
XmpPtr xmp = NULL;
- XmpIteratorPtr xmp_iter = NULL;
if (adapter == NULL || (size = gst_adapter_available (adapter)) == 0) {
goto done;
@@ -135,116 +184,321 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
if (!xmp)
goto done;
- xmp_iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_JUSTCHILDREN);
+ metadataparse_xmp_iter (taglist, mode, xmp);
+
+done:
+
+ if (xmp) {
+ xmp_free (xmp);
+ }
+
+ return;
+
+}
- if (!xmp_iter)
+static const SchemaTagMap *
+metadataparse_get_tagsmap_from_gsttag (const SchemaMap * schema_map,
+ const gchar * tag)
+{
+ SchemaTagMap *tags_map = NULL;
+ int i;
+
+ if (NULL == schema_map)
goto done;
- metadataparse_xmp_iter (xmp, xmp_iter);
+
+ 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];
+ break;
+ }
+ }
done:
- if (xmp_iter) {
- xmp_iterator_free (xmp_iter);
+ return tags_map;
+
+}
+
+static const SchemaTagMap *
+metadataparse_get_tagsmap_from_path (const SchemaMap * schema_map,
+ const gchar * path, uint32_t opt)
+{
+
+ GString *string = NULL;
+ gchar *ch;
+ SchemaTagMap *tags_map = NULL;
+
+ if (NULL == schema_map)
+ goto done;
+
+ tags_map = (SchemaTagMap *) schema_map->tags_map;
+
+ if (XMP_HAS_PROP_QUALIFIERS (opt) || XMP_IS_ARRAY_ALTTEXT (opt)) {
+
+ string = g_string_new (path);
+
+ /* remove the language qualifier */
+ ch = string->str + string->len - 3;
+ while (ch != string->str + schema_map->prefix_len) {
+ if (*ch == '[') {
+ *ch = '\0';
+ }
+ --ch;
+ }
+
+ } else {
+ ch = (gchar *) path + schema_map->prefix_len;
}
- if (xmp) {
- xmp_free (xmp);
+ while (tags_map->xmp_tag) {
+ if (0 == strcmp (tags_map->xmp_tag, ch))
+ break;
+ tags_map++;
}
+done:
+
+ if (string)
+ g_string_free (string, TRUE);
+
+ return tags_map;
+
+}
+
+static void
+metadataparse_xmp_iter_add_to_tag_list (GstTagList * taglist,
+ GstTagMergeMode mode, const char *path, const char *value,
+ const SchemaMap * schema_map, const uint32_t opt)
+{
+
+ const SchemaTagMap *smaptag =
+ metadataparse_get_tagsmap_from_path (schema_map, path, opt);
+
+ if (NULL == smaptag)
+ goto done;
+
+ if (NULL == smaptag->gst_tag)
+ goto done;
+
+ GType type = gst_tag_get_type (smaptag->gst_tag);
+
+ switch (type) {
+ case G_TYPE_STRING:
+ gst_tag_list_add (taglist, mode, smaptag->gst_tag, value, NULL);
+ break;
+ default:
+ break;
+ }
+
+done:
+
return;
}
void
-metadataparse_xmp_iter_simple_qual (const char *schema, const char *path,
- const char *value)
+metadataparse_xmp_iter_simple_qual (GstTagList * taglist, GstTagMergeMode mode,
+ const char *schema, const char *path, const char *value,
+ const SchemaMap * schema_map)
{
GString *string = g_string_new (path);
gchar *ch;
+ /* remove the language qualifier */
ch = string->str + string->len - 3;
- while (ch != string->str) {
+ while (ch != string->str + schema_map->prefix_len) {
if (*ch == '[') {
*ch = '\0';
}
--ch;
}
- GST_LOG (" %s = %s\n", string->str, value);
+ GST_LOG (" %s = %s", string->str, value);
+
+ metadataparse_xmp_iter_add_to_tag_list (taglist, mode, path, value,
+ schema_map, XMP_PROP_HAS_QUALIFIERS);
+
g_string_free (string, TRUE);
}
-void
-metadataparse_xmp_iter_simple (const char *schema, const char *path,
- const char *value)
-{
- GST_LOG (" %s = %s\n", path, value);
-}
void
-metadataparse_xmp_iter_array (XmpPtr xmp, const char *schema, const char *path)
+metadataparse_xmp_iter_simple (GstTagList * taglist, GstTagMergeMode mode,
+ const char *schema, const char *path, const char *value,
+ const SchemaMap * schema_map)
{
+ GST_LOG (" %s = %s", path, value);
- XmpIteratorPtr xmp_iter = NULL;
-
- xmp_iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
-
- if (xmp_iter) {
- metadataparse_xmp_iter (xmp, xmp_iter);
-
- xmp_iterator_free (xmp_iter);
- }
+ metadataparse_xmp_iter_add_to_tag_list (taglist, mode, path, value,
+ schema_map, 0);
}
void
-metadataparse_xmp_iter (XmpPtr xmp, XmpIteratorPtr iter)
+metadataparse_xmp_iter_array (GstTagList * taglist, GstTagMergeMode mode,
+ XmpPtr xmp, const char *schema, const char *path,
+ const SchemaMap * schema_map)
{
XmpStringPtr xstr_schema = xmp_string_new ();
XmpStringPtr xstr_path = xmp_string_new ();
XmpStringPtr xstr_prop = xmp_string_new ();
uint32_t opt = 0;
+ XmpIteratorPtr xmp_iter = NULL;
+
+ xmp_iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
+
+ if (NULL == xmp_iter)
+ goto done;
- while (xmp_iterator_next (iter, xstr_schema, xstr_path, xstr_prop, &opt)) {
+ while (xmp_iterator_next (xmp_iter, xstr_schema, xstr_path, xstr_prop, &opt)) {
const char *schema = xmp_string_cstr (xstr_schema);
const char *path = xmp_string_cstr (xstr_path);
const char *value = xmp_string_cstr (xstr_prop);
if (XMP_IS_NODE_SCHEMA (opt)) {
- GST_LOG ("%s\n", schema);
- metadataparse_xmp_iter_array (xmp, schema, path);
+ GST_LOG ("Unexpected iteraction");
} else if (XMP_IS_PROP_SIMPLE (opt)) {
if (strcmp (path, "") != 0) {
if (XMP_HAS_PROP_QUALIFIERS (opt)) {
- metadataparse_xmp_iter_simple_qual (schema, path, value);
+ /* ignore language qualifier, just get the first */
+ metadataparse_xmp_iter_simple_qual (taglist, mode, schema, path,
+ value, schema_map);
} else {
- metadataparse_xmp_iter_simple (schema, path, value);
+ metadataparse_xmp_iter_simple (taglist, mode, schema, path, value,
+ schema_map);
}
}
} else if (XMP_IS_PROP_ARRAY (opt)) {
+ /* FIXME: array with merge mode */
+ GstTagMergeMode new_mode = mode;
+
+#if 0
+ //const gchar *tag = ;
+ if (mode == GST_TAG_MERGE_REPLACE) {
+ //gst_tag_list_remove_tag(taglist, );
+ }
+#endif
if (XMP_IS_ARRAY_ALTTEXT (opt)) {
- metadataparse_xmp_iter_array (xmp, schema, path);
- xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
+ metadataparse_xmp_iter_array (taglist, new_mode, xmp, schema, path,
+ schema_map);
+ xmp_iterator_skip (xmp_iter, XMP_ITER_SKIPSUBTREE);
} else {
- metadataparse_xmp_iter_array (xmp, schema, path);
- xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
+ metadataparse_xmp_iter_array (taglist, new_mode, xmp, schema, path,
+ schema_map);
+ xmp_iterator_skip (xmp_iter, XMP_ITER_SKIPSUBTREE);
}
}
+ }
+done:
- }
+ if (xmp_iter)
+ xmp_iterator_free (xmp_iter);
- if (xstr_prop) {
+ if (xstr_prop)
xmp_string_free (xstr_prop);
- }
- if (xstr_path) {
+
+ if (xstr_path)
xmp_string_free (xstr_path);
+
+ if (xstr_schema)
+ xmp_string_free (xstr_schema);
+
+}
+
+void
+metadataparse_xmp_iter_node_schema (GstTagList * taglist, GstTagMergeMode mode,
+ XmpPtr xmp, const char *schema, const char *path)
+{
+ SchemaMap *schema_map = NULL;
+
+ if (0 == strcmp (schema, "http://purl.org/dc/elements/1.1/")) {
+ schema_map = (SchemaMap *) & schema_map_dublin;
}
- if (xstr_schema) {
+
+ metadataparse_xmp_iter_array (taglist, mode, xmp, schema, path, schema_map);
+}
+
+void
+metadataparse_xmp_iter (GstTagList * taglist, GstTagMergeMode mode, XmpPtr xmp)
+{
+ XmpStringPtr xstr_schema = xmp_string_new ();
+ XmpStringPtr xstr_path = xmp_string_new ();
+ XmpStringPtr xstr_prop = xmp_string_new ();
+ uint32_t opt = 0;
+ XmpIteratorPtr xmp_iter = NULL;
+
+ xmp_iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_JUSTCHILDREN);
+
+ if (NULL == xmp_iter)
+ goto done;
+
+ while (xmp_iterator_next (xmp_iter, xstr_schema, xstr_path, xstr_prop, &opt)) {
+ const char *schema = xmp_string_cstr (xstr_schema);
+ const char *path = xmp_string_cstr (xstr_path);
+
+ if (XMP_IS_NODE_SCHEMA (opt)) {
+ GST_LOG ("%s", schema);
+ metadataparse_xmp_iter_node_schema (taglist, mode, xmp, schema, path);
+ } else {
+ GST_LOG ("Unexpected iteraction");
+ }
+ }
+
+done:
+
+ if (xmp_iter)
+ xmp_iterator_free (xmp_iter);
+
+ if (xstr_prop)
+ xmp_string_free (xstr_prop);
+
+ if (xstr_path)
+ xmp_string_free (xstr_path);
+
+ if (xstr_schema)
xmp_string_free (xstr_schema);
+}
+
+
+static void
+metadataxmp_for_each_tag_in_list (const GstTagList * list, const gchar * tag,
+ gpointer user_data)
+{
+ XmpPtr xmp = (XmpPtr) user_data;
+ int i;
+
+ for (i = 0; schemas_map[i]; i++) {
+
+ const SchemaMap *smap = schemas_map[i];
+ const SchemaTagMap *stagmap =
+ metadataparse_get_tagsmap_from_gsttag (smap, tag);
+
+ if (stagmap) {
+
+ gchar *value = NULL;
+
+ GType type = gst_tag_get_type (tag);
+
+ switch (type) {
+ case G_TYPE_STRING:
+ gst_tag_list_get_string (list, tag, &value);
+ break;
+ default:
+ break;
+ }
+
+ if (value) {
+ xmp_set_property (xmp, smap->schema, stagmap->xmp_tag, value);
+ g_free (value);
+ }
+
+ }
+
}
+
}
void
@@ -253,6 +507,8 @@ metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 * size,
{
GstBuffer *xmp_chunk = NULL;
const GValue *val = NULL;
+ XmpPtr xmp = NULL;
+ XmpStringPtr xmp_str_buf = xmp_string_new ();
if (!(buf && size))
goto done;
@@ -265,15 +521,35 @@ metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 * size,
val = gst_tag_list_get_value_index (taglist, GST_TAG_XMP, 0);
if (val) {
xmp_chunk = gst_value_get_buffer (val);
- if (xmp_chunk) {
- *size = GST_BUFFER_SIZE (xmp_chunk);
- *buf = g_new (guint8, *size);
- memcpy (*buf, GST_BUFFER_DATA (xmp_chunk), *size);
- }
+ if (xmp_chunk)
+ xmp = xmp_new (GST_BUFFER_DATA (xmp_chunk), GST_BUFFER_SIZE (xmp_chunk));
+ }
+
+ if (NULL == xmp)
+ xmp = xmp_new_empty ();
+
+ gst_tag_list_foreach (taglist, metadataxmp_for_each_tag_in_list, xmp);
+
+ if (!xmp_serialize (xmp, xmp_str_buf, 0, 2)) {
+ GST_ERROR ("failed to serialize xmp into chunk\n");
+ } else if (xmp_str_buf) {
+ unsigned int len = strlen (xmp_string_cstr (xmp_str_buf));
+
+ *size = len + 1;
+ *buf = malloc (*size);
+ memcpy (*buf, xmp_string_cstr (xmp_str_buf), *size);
+ } else {
+ GST_ERROR ("failed to serialize xmp into chunk\n");
}
done:
+ if (xmp_str_buf)
+ xmp_string_free (xmp_str_buf);
+
+ if (xmp)
+ xmp_free (xmp);
+
return;
}