summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2010-08-17 15:05:32 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2010-08-24 22:20:48 -0300
commit57013ae63e681057d7525d6e09532995177127ce (patch)
tree32e03aa46d5de309af9c6c0661d558267e8935d9
parent421e1e05ffaa2ef8787c7ef831e4e60e0aec33ad (diff)
tag: exif: Adds mapping for GST_TAG_APPLICATION_DATA
Adds mapping for GST_TAG_APPLICATION_DATA to the exif 'maker-note' tag.
-rw-r--r--gst-libs/gst/tag/gstexiftag.c100
-rw-r--r--tests/check/libs/tag.c12
2 files changed, 112 insertions, 0 deletions
diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c
index 3e75b53b7..a443ba722 100644
--- a/gst-libs/gst/tag/gstexiftag.c
+++ b/gst-libs/gst/tag/gstexiftag.c
@@ -181,6 +181,7 @@ static const GstExifTagMatch tag_map_ifd0[] = {
static const GstExifTagMatch tag_map_exif[] = {
{NULL, EXIF_VERSION_TAG, EXIF_TYPE_UNDEFINED, 0, NULL, NULL},
{GST_TAG_DATE_TIME, 0x9003, EXIF_TYPE_ASCII, 0, NULL, NULL},
+ {GST_TAG_APPLICATION_DATA, 0x927C, EXIF_TYPE_UNDEFINED, 0, NULL, NULL},
{NULL, 0, 0, 0, NULL, NULL}
};
@@ -493,6 +494,47 @@ write_exif_ascii_tag_from_taglist (GstExifWriter * writer,
}
static void
+write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
+ const GstTagList * taglist, const GstExifTagMatch * exiftag)
+{
+ const GValue *value;
+ const guint8 *data = NULL;
+ gint size = 0;
+ gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);
+
+ if (tag_size != 1) {
+ GST_WARNING ("Only the first item in the taglist will be serialized");
+ return;
+ }
+
+ value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);
+
+ /* do some conversion if needed */
+ switch (G_VALUE_TYPE (value)) {
+ case G_TYPE_STRING:
+ data = (guint8 *) g_value_get_string (value);
+ size = strlen ((gchar *) data); /* no need to +1, undefined doesn't require it */
+ break;
+ default:
+ if (G_VALUE_TYPE (value) == GST_TYPE_BUFFER) {
+ GstBuffer *buf = gst_value_get_buffer (value);
+
+ data = GST_BUFFER_DATA (buf);
+ size = GST_BUFFER_SIZE (buf);
+ } else {
+ GST_WARNING ("Conversion from %s to raw data not supported",
+ G_VALUE_TYPE_NAME (value));
+ }
+ break;
+ }
+
+ if (size == 0)
+ return;
+
+ write_exif_undefined_tag (writer, exiftag->exif_tag, data, size);
+}
+
+static void
write_exif_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist,
const GstExifTagMatch * exiftag)
{
@@ -508,6 +550,9 @@ write_exif_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist,
case EXIF_TYPE_ASCII:
write_exif_ascii_tag_from_taglist (writer, taglist, exiftag);
break;
+ case EXIF_TYPE_UNDEFINED:
+ write_exif_undefined_tag_from_taglist (writer, taglist, exiftag);
+ break;
default:
GST_WARNING ("Unhandled tag type %d", exiftag->exif_type);
}
@@ -689,6 +734,58 @@ parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag,
}
static void
+parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag,
+ guint32 count, guint32 offset, const guint8 * offset_as_data)
+{
+ GType tagtype;
+ guint8 *data;
+ guint32 real_offset;
+
+ if (count > 4) {
+ if (offset < reader->base_offset) {
+ GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
+ reader->base_offset);
+ return;
+ }
+
+ real_offset = offset - reader->base_offset;
+ if (real_offset >= GST_BUFFER_SIZE (reader->buffer)) {
+ GST_WARNING ("Invalid offset %u for buffer of size %u, not adding tag %s",
+ real_offset, GST_BUFFER_SIZE (reader->buffer), tag->gst_tag);
+ return;
+ }
+
+ /* +1 because it could be a string without the \0 */
+ data = malloc (sizeof (guint8) * count + 1);
+ memcpy (data, GST_BUFFER_DATA (reader->buffer) + real_offset, count);
+ data[count] = 0;
+ } else {
+ data = malloc (sizeof (guint8) * count + 1);
+ memcpy (data, (guint8 *) offset_as_data, count);
+ data[count] = 0;
+ }
+
+ tagtype = gst_tag_get_type (tag->gst_tag);
+ if (tagtype == GST_TYPE_BUFFER) {
+ GstBuffer *buf = gst_buffer_new ();
+ gst_buffer_set_data (buf, data, count);
+ data = NULL;
+
+ gst_tag_list_add (reader->taglist, GST_TAG_MERGE_APPEND, tag->gst_tag,
+ buf, NULL);
+
+ gst_buffer_unref (buf);
+ } else if (tagtype == G_TYPE_STRING) {
+ gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
+ data, NULL);
+ } else {
+ GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
+ tag->gst_tag);
+ }
+ g_free (data);
+}
+
+static void
parse_exif_rational_tag (GstExifReader * exif_reader,
const gchar * gst_tag, guint32 count, guint32 offset, gdouble multiplier)
{
@@ -946,6 +1043,9 @@ parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset,
parse_exif_rational_tag (exif_reader, tag_map[map_index].gst_tag,
tagdata.count, tagdata.offset, 1);
break;
+ case EXIF_TYPE_UNDEFINED:
+ parse_exif_undefined_tag (exif_reader, &tag_map[map_index],
+ tagdata.count, tagdata.offset, tagdata.offset_as_data);
default:
GST_WARNING ("Unhandled tag type: %u", tagdata.tag_type);
break;
diff --git a/tests/check/libs/tag.c b/tests/check/libs/tag.c
index e561dce47..94c5978ad 100644
--- a/tests/check/libs/tag.c
+++ b/tests/check/libs/tag.c
@@ -1243,6 +1243,8 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
{
GValue value = { 0 };
GstDateTime *datetime = NULL;
+ GstBuffer *buf = NULL;
+ gint i;
g_value_init (&value, G_TYPE_STRING);
g_value_set_static_string (&value, "my string");
@@ -1334,6 +1336,16 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
gst_date_time_unref (datetime);
do_simple_exif_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
g_value_unset (&value);
+
+ g_value_init (&value, GST_TYPE_BUFFER);
+ buf = gst_buffer_new_and_alloc (1024);
+ for (i = 0; i < 1024; i++)
+ GST_BUFFER_DATA (buf)[i] = i % 255;
+ gst_value_set_buffer (&value, buf);
+ gst_buffer_unref (buf);
+ do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_DATA,
+ &value);
+ g_value_unset (&value);
}
GST_END_TEST;