From dfa23662e18f00ca3185ad24208b45c77bc69400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 23 Dec 2011 22:24:44 +0000 Subject: [PATCH] tag: fix writing of Exif tag payloads <= 4 bytes When the payload for an Exif tag is less than or equal to 4 bytes, the data is simply put into the offset field. Fix writing these kinds of payloads on big endian systems (and possibly also on little endian systems). The caller will have already formatted the bytes in memory according to the writer's endianness, so just write out the bytes as they are in this case. Fixes tags unit test on big endian systems. --- gst-libs/gst/tag/gstexiftag.c | 36 +++++++++++++++++++---------------- tests/check/libs/tag.c | 2 ++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c index 4ad3a13e35..5902e2b5c1 100644 --- a/gst-libs/gst/tag/gstexiftag.c +++ b/gst-libs/gst/tag/gstexiftag.c @@ -612,7 +612,7 @@ gst_tag_list_has_ifd_tags (const GstTagList * taglist, static void gst_exif_writer_write_tag_header (GstExifWriter * writer, guint16 exif_tag, guint16 exif_type, guint32 count, guint32 offset, - gboolean is_data) + const guint32 * offset_data) { GST_DEBUG ("Writing tag entry: id %x, type %u, count %u, offset %u", exif_tag, exif_type, count, offset); @@ -621,13 +621,17 @@ gst_exif_writer_write_tag_header (GstExifWriter * writer, gst_byte_writer_put_uint16_le (&writer->tagwriter, exif_tag); gst_byte_writer_put_uint16_le (&writer->tagwriter, exif_type); gst_byte_writer_put_uint32_le (&writer->tagwriter, count); - gst_byte_writer_put_uint32_le (&writer->tagwriter, offset); + if (offset_data != NULL) { + gst_byte_writer_put_data (&writer->tagwriter, (guint8 *) offset_data, 4); + } else { + gst_byte_writer_put_uint32_le (&writer->tagwriter, offset); + } } else if (writer->byte_order == G_BIG_ENDIAN) { gst_byte_writer_put_uint16_be (&writer->tagwriter, exif_tag); gst_byte_writer_put_uint16_be (&writer->tagwriter, exif_type); gst_byte_writer_put_uint32_be (&writer->tagwriter, count); - if (is_data) { - gst_byte_writer_put_uint32_le (&writer->tagwriter, offset); + if (offset_data != NULL) { + gst_byte_writer_put_data (&writer->tagwriter, (guint8 *) offset_data, 4); } else { gst_byte_writer_put_uint32_be (&writer->tagwriter, offset); } @@ -671,7 +675,7 @@ gst_exif_writer_write_rational_tag (GstExifWriter * writer, guint32 offset = gst_byte_writer_get_size (&writer->datawriter); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_RATIONAL, - 1, offset, FALSE); + 1, offset, NULL); gst_exif_writer_write_rational_data (writer, frac_n, frac_d); } @@ -683,7 +687,7 @@ gst_exif_writer_write_signed_rational_tag (GstExifWriter * writer, guint32 offset = gst_byte_writer_get_size (&writer->datawriter); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_SRATIONAL, - 1, offset, FALSE); + 1, offset, NULL); gst_exif_writer_write_signed_rational_data (writer, frac_n, frac_d); } @@ -720,7 +724,7 @@ gst_exif_writer_write_byte_tag (GstExifWriter * writer, guint16 tag, GST_WRITE_UINT8 ((guint8 *) & offset, value); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_BYTE, - 1, offset, TRUE); + 1, offset, &offset); } static void @@ -736,7 +740,7 @@ gst_exif_writer_write_short_tag (GstExifWriter * writer, guint16 tag, } gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_SHORT, - 1, offset, TRUE); + 1, offset, &offset); } static void @@ -751,7 +755,7 @@ gst_exif_writer_write_long_tag (GstExifWriter * writer, guint16 tag, } gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_LONG, - 1, offset, TRUE); + 1, offset, &offset); } @@ -766,13 +770,13 @@ write_exif_undefined_tag (GstExifWriter * writer, guint16 tag, * resulting tag headers offset and the base offset */ offset = gst_byte_writer_get_size (&writer->datawriter); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_UNDEFINED, - size, offset, FALSE); + size, offset, NULL); gst_byte_writer_put_data (&writer->datawriter, data, size); } else { /* small enough to go in the offset */ memcpy ((guint8 *) & offset, data, size); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_UNDEFINED, - size, offset, TRUE); + size, offset, &offset); } } @@ -802,13 +806,13 @@ write_exif_ascii_tag (GstExifWriter * writer, guint16 tag, const gchar * str) * resulting tag headers offset and the base offset */ offset = gst_byte_writer_get_size (&writer->datawriter); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_ASCII, - ascii_size, offset, FALSE); + ascii_size, offset, NULL); gst_byte_writer_put_string (&writer->datawriter, ascii_str); } else { /* small enough to go in the offset */ memcpy ((guint8 *) & offset, ascii_str, ascii_size); gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_ASCII, - ascii_size, offset, TRUE); + ascii_size, offset, &offset); } g_free (ascii_str); @@ -1435,7 +1439,7 @@ parse_exif_rational_tag (GstExifReader * exif_reader, } static GstBuffer * -write_exif_ifd (const GstTagList * taglist, gboolean byte_order, +write_exif_ifd (const GstTagList * taglist, guint byte_order, guint32 base_offset, const GstExifTagMatch * tag_map) { GstExifWriter writer; @@ -1492,7 +1496,7 @@ write_exif_ifd (const GstTagList * taglist, gboolean byte_order, GST_DEBUG ("Adding inner ifd: %x", tag_map[i].exif_tag); gst_exif_writer_write_tag_header (&writer, tag_map[i].exif_tag, EXIF_TYPE_LONG, 1, - gst_byte_writer_get_size (&writer.datawriter), FALSE); + gst_byte_writer_get_size (&writer.datawriter), NULL); gst_byte_writer_put_data (&writer.datawriter, GST_BUFFER_DATA (inner_ifd), GST_BUFFER_SIZE (inner_ifd)); gst_buffer_unref (inner_ifd); @@ -1939,7 +1943,7 @@ serialize_geo_coordinate (GstExifWriter * writer, const GstTagList * taglist, offset = gst_byte_writer_get_size (&writer->datawriter); gst_exif_writer_write_tag_header (writer, exiftag->exif_tag, - EXIF_TYPE_RATIONAL, 3, offset, FALSE); + EXIF_TYPE_RATIONAL, 3, offset, NULL); gst_exif_writer_write_rational_data (writer, degrees, 1); gst_exif_writer_write_rational_data (writer, minutes, 1); gst_exif_writer_write_rational_data (writer, seconds, 1); diff --git a/tests/check/libs/tag.c b/tests/check/libs/tag.c index db5932360a..634cc3fe43 100644 --- a/tests/check/libs/tag.c +++ b/tests/check/libs/tag.c @@ -1392,6 +1392,7 @@ do_exif_tag_serialization_deserialization (GstTagList * taglist) /* LE */ buf = gst_tag_list_to_exif_buffer (taglist, G_LITTLE_ENDIAN, 0); + GST_MEMDUMP ("Exif tag", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); taglist2 = gst_tag_list_from_exif_buffer (buf, G_LITTLE_ENDIAN, 0); gst_buffer_unref (buf); @@ -1400,6 +1401,7 @@ do_exif_tag_serialization_deserialization (GstTagList * taglist) /* BE */ buf = gst_tag_list_to_exif_buffer (taglist, G_BIG_ENDIAN, 0); + GST_MEMDUMP ("Exif tag", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); taglist2 = gst_tag_list_from_exif_buffer (buf, G_BIG_ENDIAN, 0); gst_buffer_unref (buf);