mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-27 11:32:51 +00:00
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.
This commit is contained in:
parent
631b6a1766
commit
63490f4b48
4 changed files with 385 additions and 86 deletions
|
@ -1,3 +1,10 @@
|
|||
2008-01-17 Edgard Lima <edgard.lima@indt.org.br>
|
||||
|
||||
* ext/metadata/TODO:
|
||||
* ext/metadata/metadataexif.c:
|
||||
* ext/metadata/metadataxmp.c:
|
||||
Fixed adding EXIF tags to correct IFD. Mapped some XMP tags.
|
||||
|
||||
2008-01-16 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* gst/h264parse/gsth264parse.c: (gst_nal_list_new),
|
||||
|
|
|
@ -3,12 +3,11 @@ This file contains a list of things to be done as well some open issues (questio
|
|||
|
||||
INFO:
|
||||
|
||||
1- I (Edgard Lima - alima - edgard.lima@indt.org.br) will be on vacation until 05-Jan-2008. After that I will be back on it.
|
||||
2- to see what tags are mapped so far run 'grep -n GST_TAG *.[ch]' into this folder.
|
||||
1- to see what tags are mapped so far run 'grep -n GST_TAG *.[ch]' into this folder.
|
||||
|
||||
TODO:
|
||||
|
||||
1- Add individual XMP tags (and more for EXIF and IPTC)
|
||||
1- Add more individual tags to XMP, EXIF and IPTC
|
||||
2- Get properties like 'width' and 'height' from caps
|
||||
3- Review the code (in order to move to gst-plugins-good)
|
||||
4- Document how the plugin works (atchitecture and interaction beteween modules)
|
||||
|
@ -19,10 +18,10 @@ OPEN ISSUES:
|
|||
2- How to change metadata when the orignal image was modified.
|
||||
ex: file.jpeg has XMP, then we do filesrc ! metadataparse ! jpegdec ! pngenc ! metadatamux ! files
|
||||
is the metadata still valid? which fields are no valid anymore?
|
||||
3- Add GST_TYPE_FRACTION support for GStreamer TAGS
|
||||
4- currently, in JPEG files, if there is a Photoshop segment, everything inside it but IPTC will be lost. From the point of view of implementation it is easy, but I still don't now how to solve from the point of view of "designing". Anyway I think it is not so important.
|
||||
3- In EXIF, how to make sure we are compliant with the specification when adding some tag? For example, we are not considerinb what are mandatory (or optional) IFDs for tags.
|
||||
4- Add GST_TYPE_FRACTION support for GStreamer TAGS
|
||||
5- currently, in JPEG files, if there is a Photoshop segment, everything inside it but IPTC will be lost. From the point of view of implementation it is easy, but I still don't now how to solve from the point of view of "designing". Anyway I think it is not so important.
|
||||
6- language is not considered in XMP (How to do it with GStreamer?)
|
||||
|
||||
KNOWN BUGS
|
||||
|
||||
1- exposure-time, exposure-program and fnumber can't be read from a file saved from scratch (whithout WHOLE_CHUNK from previous file)
|
||||
I believe it is a bug in libexif
|
||||
|
|
|
@ -88,6 +88,7 @@ typedef struct _tag_MEUserData
|
|||
typedef struct _tag_MapIntStr
|
||||
{
|
||||
ExifTag exif;
|
||||
ExifIfd ifd;
|
||||
const gchar *str;
|
||||
} MapIntStr;
|
||||
|
||||
|
@ -98,21 +99,35 @@ static void exif_content_foreach_entry_func (ExifEntry * entry, void *);
|
|||
|
||||
/* *INDENT-OFF* */
|
||||
static MapIntStr mappedTags[] = {
|
||||
{EXIF_TAG_MAKE, /*ASCII,*/ GST_TAG_DEVICE_MAKE, /*STRING*/},
|
||||
{EXIF_TAG_MODEL, /*ASCII,*/ GST_TAG_DEVICE_MODEL, /*STRING*/},
|
||||
{EXIF_TAG_SOFTWARE, /*ASCII,*/ GST_TAG_CREATOR_TOOL, /*STRING*/},
|
||||
{EXIF_TAG_X_RESOLUTION, /*RATIONAL,*/ GST_TAG_IMAGE_XRESOLUTION, /*FRACTION*/}, /* inches */
|
||||
{EXIF_TAG_Y_RESOLUTION, /*RATIONAL,*/ GST_TAG_IMAGE_YRESOLUTION, /*FRACTION*/}, /* inches */
|
||||
{EXIF_TAG_EXPOSURE_TIME, /*RATIONAL,*/ GST_TAG_CAPTURE_EXPOSURE_TIME, /*FRACTION*/},
|
||||
{EXIF_TAG_FNUMBER, /*RATIONAL,*/ GST_TAG_CAPTURE_FNUMBER, /*FRACTION*/},
|
||||
{EXIF_TAG_EXPOSURE_PROGRAM, /*SHORT,*/ GST_TAG_CAPTURE_EXPOSURE_PROGRAM, /*UINT*/},
|
||||
{EXIF_TAG_BRIGHTNESS_VALUE, /*SRATIONAL,*/ GST_TAG_CAPTURE_BRIGHTNESS, /*FRACTION*/},
|
||||
{EXIF_TAG_WHITE_BALANCE, /*SHORT,*/ GST_TAG_CAPTURE_WHITE_BALANCE, /*UINT*/},
|
||||
{EXIF_TAG_DIGITAL_ZOOM_RATIO, /*RATIONAL,*/ GST_TAG_CAPTURE_DIGITAL_ZOOM, /*FRACTION*/},
|
||||
{EXIF_TAG_GAIN_CONTROL, /*SHORT,*/ GST_TAG_CAPTURE_GAIN, /*UINT*/},
|
||||
{EXIF_TAG_CONTRAST, /*SHORT,*/ GST_TAG_CAPTURE_CONTRAST, /*INT*/},
|
||||
{EXIF_TAG_SATURATION, /*SHORT,*/ GST_TAG_CAPTURE_SATURATION, /*INT*/},
|
||||
{0, NULL}
|
||||
{EXIF_TAG_MAKE, /*ASCII,*/ EXIF_IFD_0,
|
||||
GST_TAG_DEVICE_MAKE, /*STRING*/},
|
||||
{EXIF_TAG_MODEL, /*ASCII,*/ EXIF_IFD_0,
|
||||
GST_TAG_DEVICE_MODEL, /*STRING*/},
|
||||
{EXIF_TAG_SOFTWARE, /*ASCII,*/ EXIF_IFD_0,
|
||||
GST_TAG_CREATOR_TOOL, /*STRING*/},
|
||||
{EXIF_TAG_X_RESOLUTION, /*RATIONAL,*/ EXIF_IFD_0,
|
||||
GST_TAG_IMAGE_XRESOLUTION, /*FRACTION*/}, /* inches */
|
||||
{EXIF_TAG_Y_RESOLUTION, /*RATIONAL,*/ EXIF_IFD_0,
|
||||
GST_TAG_IMAGE_YRESOLUTION, /*FRACTION*/}, /* inches */
|
||||
{EXIF_TAG_EXPOSURE_TIME, /*RATIONAL,*/ EXIF_IFD_EXIF,
|
||||
GST_TAG_CAPTURE_EXPOSURE_TIME, /*FRACTION*/},
|
||||
{EXIF_TAG_FNUMBER, /*RATIONAL,*/ EXIF_IFD_EXIF,
|
||||
GST_TAG_CAPTURE_FNUMBER, /*FRACTION*/},
|
||||
{EXIF_TAG_EXPOSURE_PROGRAM, /*SHORT,*/ EXIF_IFD_EXIF,
|
||||
GST_TAG_CAPTURE_EXPOSURE_PROGRAM, /*UINT*/},
|
||||
{EXIF_TAG_BRIGHTNESS_VALUE, /*SRATIONAL,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_BRIGHTNESS, /*FRACTION*/},
|
||||
{EXIF_TAG_WHITE_BALANCE, /*SHORT,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_WHITE_BALANCE, /*UINT*/},
|
||||
{EXIF_TAG_DIGITAL_ZOOM_RATIO, /*RATIONAL,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_DIGITAL_ZOOM, /*FRACTION*/},
|
||||
{EXIF_TAG_GAIN_CONTROL, /*SHORT,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_GAIN, /*UINT*/},
|
||||
{EXIF_TAG_CONTRAST, /*SHORT,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_CONTRAST, /*INT*/},
|
||||
{EXIF_TAG_SATURATION, /*SHORT,*/ EXIF_IFD_0,
|
||||
GST_TAG_CAPTURE_SATURATION, /*INT*/},
|
||||
{0, EXIF_IFD_COUNT, NULL}
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -134,13 +149,15 @@ metadataparse_exif_get_tag_from_exif (ExifTag exif, GType * type)
|
|||
}
|
||||
|
||||
static ExifTag
|
||||
metadataparse_exif_get_exif_from_tag (const gchar * tag, GType * type)
|
||||
metadataparse_exif_get_exif_from_tag (const gchar * tag, GType * type,
|
||||
ExifIfd * ifd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (mappedTags[i].exif) {
|
||||
if (0 == strcmp (mappedTags[i].str, tag)) {
|
||||
*type = gst_tag_get_type (tag);
|
||||
*ifd = mappedTags[i].ifd;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
|
@ -361,13 +378,12 @@ done:
|
|||
" Title: %s\n"
|
||||
" Description: %s\n",
|
||||
entry,
|
||||
exif_tag_get_name_in_ifd (entry->tag, EXIF_IFD_0),
|
||||
exif_tag_get_name (entry->tag),
|
||||
exif_format_get_name (entry->format),
|
||||
entry->size,
|
||||
(int) (entry->components),
|
||||
exif_entry_get_value (entry, buf, sizeof (buf)),
|
||||
exif_tag_get_title_in_ifd (entry->tag, EXIF_IFD_0),
|
||||
exif_tag_get_description_in_ifd (entry->tag, EXIF_IFD_0));
|
||||
exif_tag_get_title (entry->tag), exif_tag_get_description (entry->tag));
|
||||
|
||||
return;
|
||||
|
||||
|
@ -449,9 +465,10 @@ metadataexif_for_each_tag_in_list (const GstTagList * list, const gchar * tag,
|
|||
ExifTag exif_tag;
|
||||
GType type;
|
||||
ExifEntry *entry = NULL;
|
||||
ExifIfd ifd;
|
||||
const ExifByteOrder byte_order = exif_data_get_byte_order (ed);
|
||||
|
||||
exif_tag = metadataparse_exif_get_exif_from_tag (tag, &type);
|
||||
exif_tag = metadataparse_exif_get_exif_from_tag (tag, &type, &ifd);
|
||||
|
||||
if (!exif_tag)
|
||||
goto done;
|
||||
|
@ -462,7 +479,7 @@ metadataexif_for_each_tag_in_list (const GstTagList * list, const gchar * tag,
|
|||
exif_entry_ref (entry);
|
||||
else {
|
||||
entry = exif_entry_new ();
|
||||
exif_content_add_entry (ed->ifd[EXIF_IFD_0], entry);
|
||||
exif_content_add_entry (ed->ifd[ifd], entry);
|
||||
exif_entry_initialize (entry, exif_tag);
|
||||
}
|
||||
|
||||
|
|
|
@ -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_simple (const char *schema, const char *path,
|
||||
const char *value);
|
||||
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 (XmpPtr xmp, XmpIteratorPtr iter);
|
||||
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 (GstTagList * taglist, GstTagMergeMode mode,
|
||||
const char *schema, const char *path, const char *value,
|
||||
const SchemaMap * schema_map);
|
||||
|
||||
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,19 +184,10 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
if (!xmp)
|
||||
goto done;
|
||||
|
||||
xmp_iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_JUSTCHILDREN);
|
||||
|
||||
if (!xmp_iter)
|
||||
goto done;
|
||||
|
||||
metadataparse_xmp_iter (xmp, xmp_iter);
|
||||
metadataparse_xmp_iter (taglist, mode, xmp);
|
||||
|
||||
done:
|
||||
|
||||
if (xmp_iter) {
|
||||
xmp_iterator_free (xmp_iter);
|
||||
}
|
||||
|
||||
if (xmp) {
|
||||
xmp_free (xmp);
|
||||
}
|
||||
|
@ -156,95 +196,309 @@ done:
|
|||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while (xmp_iterator_next (iter, xstr_schema, xstr_path, xstr_prop, &opt)) {
|
||||
xmp_iter = xmp_iterator_new (xmp, schema, path, 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (xstr_prop) {
|
||||
done:
|
||||
|
||||
if (xmp_iter)
|
||||
xmp_iterator_free (xmp_iter);
|
||||
|
||||
if (xstr_prop)
|
||||
xmp_string_free (xstr_prop);
|
||||
}
|
||||
if (xstr_path) {
|
||||
|
||||
if (xstr_path)
|
||||
xmp_string_free (xstr_path);
|
||||
}
|
||||
if (xstr_schema) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue