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.
This commit is contained in:
Stefan Kost 2009-01-23 14:43:00 +02:00
parent e4e3b44e04
commit 93df7379e4
4 changed files with 82 additions and 7 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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__ */