mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-02 14:20:06 +00:00
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:
parent
e4e3b44e04
commit
93df7379e4
4 changed files with 82 additions and 7 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue