From 93df7379e47144261787378fa195cad676b855ad Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Fri, 23 Jan 2009 14:43:00 +0200 Subject: [PATCH] Configure byte order for EXIF. Fixes #568704 Exif blocks can be in differnt byte orders. Add an element property to select wich one should be written. --- ext/metadata/gstmetadatamux.c | 30 ++++++++++++++++++++++++++---- ext/metadata/gstmetadatamux.h | 3 +++ ext/metadata/metadataexif.c | 33 +++++++++++++++++++++++++++++++-- ext/metadata/metadataexif.h | 23 ++++++++++++++++++++++- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/ext/metadata/gstmetadatamux.c b/ext/metadata/gstmetadatamux.c index 657774d6c3..e6a66fa3aa 100644 --- a/ext/metadata/gstmetadatamux.c +++ b/ext/metadata/gstmetadatamux.c @@ -84,8 +84,6 @@ #include "gstmetadatamux.h" -#include "metadataexif.h" - #include "metadataiptc.h" #include "metadataxmp.h" @@ -104,6 +102,7 @@ enum enum { ARG_0, + ARG_EXIF_BYTE_ORDER, }; @@ -121,6 +120,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_metadata_mux_debug); #define GOTO_DONE_IF_NULL_AND_FAIL(ptr, ret) \ do { if ( NULL == (ptr) ) { (ret) = FALSE; goto done; } } while(FALSE) +#define DEFAULT_EXIF_BYTE_ORDER GST_META_EXIF_BYTE_ORDER_MOTOROLA + static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, @@ -292,6 +293,18 @@ gst_metadata_mux_class_init (GstMetadataMuxClass * klass) gstbasemetadata_class->sink_event = GST_DEBUG_FUNCPTR (gst_metadata_mux_sink_event); + /** + * GstMetadataMux:exif-byte-order: + * + * Set byte-order for exif metadata writing. + * + * Since: 0.10.11 + */ + g_object_class_install_property (gobject_class, ARG_EXIF_BYTE_ORDER, + g_param_spec_enum ("exif-byte-order", "Exif byte-order", + "Byte-order for exif metadata writing", GST_TYPE_META_EXIF_BYTE_ORDER, + DEFAULT_EXIF_BYTE_ORDER, G_PARAM_READWRITE)); + } static void @@ -299,14 +312,18 @@ gst_metadata_mux_init (GstMetadataMux * filter, GstMetadataMuxClass * gclass) { gst_base_metadata_set_option_flag (GST_BASE_METADATA (filter), META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP | META_OPT_MUX); - + filter->exif_options.byteorder = DEFAULT_EXIF_BYTE_ORDER; } static void gst_metadata_mux_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { + GstMetadataMux *filter = GST_METADATA_MUX (object); switch (prop_id) { + case ARG_EXIF_BYTE_ORDER: + filter->exif_options.byteorder = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -317,7 +334,11 @@ static void gst_metadata_mux_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { + GstMetadataMux *filter = GST_METADATA_MUX (object); switch (prop_id) { + case ARG_EXIF_BYTE_ORDER: + g_value_set_enum (value, filter->exif_options.byteorder); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -400,7 +421,8 @@ gst_metadata_mux_create_chunks_from_tags (GstBaseMetadata * base) if (taglist) { if (gst_base_metadata_get_option_flag (base) & META_OPT_EXIF) { - metadatamux_exif_create_chunk_from_tag_list (&buf, &size, taglist); + metadatamux_exif_create_chunk_from_tag_list (&buf, &size, taglist, + &filter->exif_options); gst_base_metadata_update_inject_segment_with_new_data (base, &buf, &size, MD_CHUNK_EXIF); } diff --git a/ext/metadata/gstmetadatamux.h b/ext/metadata/gstmetadatamux.h index bcdeaf1b98..a24b3ff018 100644 --- a/ext/metadata/gstmetadatamux.h +++ b/ext/metadata/gstmetadatamux.h @@ -48,6 +48,8 @@ #include "gstbasemetadata.h" +#include "metadataexif.h" + G_BEGIN_DECLS /* *INDENT-OFF* */ @@ -75,6 +77,7 @@ typedef struct _GstMetadataMuxClass GstMetadataMuxClass; struct _GstMetadataMux { GstBaseMetadata metadata; + MetaExifWriteOptions exif_options; }; struct _GstMetadataMuxClass diff --git a/ext/metadata/metadataexif.c b/ext/metadata/metadataexif.c index 6924511d8d..73cb275b81 100644 --- a/ext/metadata/metadataexif.c +++ b/ext/metadata/metadataexif.c @@ -69,6 +69,23 @@ GST_DEBUG_CATEGORY (gst_metadata_exif_debug); #define GST_CAT_DEFAULT gst_metadata_exif_debug +GType +gst_meta_exif_byte_order_get_type (void) +{ + static GType meta_exif_byte_order_type = 0; + static const GEnumValue meta_exif_byte_order[] = { + {GST_META_EXIF_BYTE_ORDER_MOTOROLA, "Motorola byte-order", "Motorola"}, + {GST_META_EXIF_BYTE_ORDER_INTEL, "Intel byte-order", "Intel"}, + {0, NULL, NULL}, + }; + + if (!meta_exif_byte_order_type) { + meta_exif_byte_order_type = + g_enum_register_static ("MetaExifByteOrder", meta_exif_byte_order); + } + return meta_exif_byte_order_type; +} + /* * Implementation when libexif isn't available at compilation time */ @@ -95,7 +112,7 @@ metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, void metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) + const GstTagList * taglist, const MetaExifWriteOptions * opts) { /* do nothing */ } @@ -353,6 +370,7 @@ done: * @buf: buffer that will have the created EXIF chunk * @size: size of the buffer that will be created * @taglist: list of tags to be added to EXIF chunk + * @opts: write options for exif metadata * * Get tags from @taglist, create a EXIF chunk based on it and save to @buf. * Note: The EXIF chunk is NOT wrapped by any bytes specific to any file format @@ -362,7 +380,7 @@ done: void metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) + const GstTagList * taglist, const MetaExifWriteOptions * opts) { ExifData *ed = NULL; GstBuffer *exif_chunk = NULL; @@ -387,6 +405,17 @@ metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, if (!ed) { ed = exif_data_new (); + GST_DEBUG ("setting byteorder %d", opts->byteorder); + switch (opts->byteorder) { + case GST_META_EXIF_BYTE_ORDER_MOTOROLA: + exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_MOTOROLA); + break; + case GST_META_EXIF_BYTE_ORDER_INTEL: + exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_INTEL); + break; + default: + break; + } exif_data_set_data_type (ed, EXIF_DATA_TYPE_COMPRESSED); exif_data_fix (ed); } diff --git a/ext/metadata/metadataexif.h b/ext/metadata/metadataexif.h index 8f1d8a21fc..4b77531434 100644 --- a/ext/metadata/metadataexif.h +++ b/ext/metadata/metadataexif.h @@ -50,6 +50,27 @@ G_BEGIN_DECLS +typedef enum { + GST_META_EXIF_BYTE_ORDER_MOTOROLA, + GST_META_EXIF_BYTE_ORDER_INTEL +} MetaExifByteOrder; + +typedef struct _MetaExifWriteOptions MetaExifWriteOptions; + +/** + * MetaExifWriteOptions: + * @byteorder: byte-ordering for exif chunk + * + * Options for Exif metadata writing + */ +struct _MetaExifWriteOptions +{ + MetaExifByteOrder byteorder; +}; + +#define GST_TYPE_META_EXIF_BYTE_ORDER (gst_meta_exif_byte_order_get_type()) +GType gst_meta_exif_byte_order_get_type (void); + /* * external function prototypes */ @@ -60,7 +81,7 @@ metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, extern void metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 *size, - const GstTagList * taglist); + const GstTagList * taglist, const MetaExifWriteOptions *opts); G_END_DECLS #endif /* __GST_METADATAPARSE_EXIF_H__ */