mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 13:55:41 +00:00
jpegformat: Add exif support
Adds exif writing support to jifmux. Adds parsing support to jpegparse. Fixes #614872
This commit is contained in:
parent
eebe58a163
commit
00897e21a9
2 changed files with 83 additions and 12 deletions
|
@ -338,7 +338,8 @@ static gboolean
|
|||
gst_jif_mux_mangle_markers (GstJifMux * self)
|
||||
{
|
||||
gboolean modified = FALSE;
|
||||
const GstTagList *tags;
|
||||
GstTagList *tags = NULL;
|
||||
gboolean cleanup_tags;
|
||||
GstJifMuxMarker *m;
|
||||
GList *node, *file_hdr = NULL, *frame_hdr = NULL, *scan_hdr = NULL;
|
||||
GList *app0_jfif = NULL, *app1_exif = NULL, *app1_xmp = NULL, *com = NULL;
|
||||
|
@ -367,7 +368,8 @@ gst_jif_mux_mangle_markers (GstJifMux * self)
|
|||
}
|
||||
break;
|
||||
case APP1:
|
||||
if (m->size > 6 && !memcmp (m->data, "EXIF\0\0", 6)) {
|
||||
if (m->size > 6 && (!memcmp (m->data, "EXIF\0\0", 6) ||
|
||||
!memcmp (m->data, "Exif\0\0", 6))) {
|
||||
GST_DEBUG_OBJECT (self, "found APP1 EXIF");
|
||||
if (!app1_exif)
|
||||
app1_exif = node;
|
||||
|
@ -435,25 +437,66 @@ gst_jif_mux_mangle_markers (GstJifMux * self)
|
|||
/* else */
|
||||
/* remove JFIF if exists */
|
||||
|
||||
/* if we want combined or EXIF */
|
||||
/* check if we don't have EXIF APP1 */
|
||||
if (!app1_exif) {
|
||||
/* exif_data = gst_tag_list_to_exif_buffer (tags); */
|
||||
/* insert into self->markers list */
|
||||
/* Existing exif tags will be removed and our own will be added */
|
||||
if (!tags) {
|
||||
tags = (GstTagList *) gst_tag_setter_get_tag_list (GST_TAG_SETTER (self));
|
||||
cleanup_tags = FALSE;
|
||||
}
|
||||
/* else */
|
||||
/* remove EXIF if exists */
|
||||
|
||||
tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (self));
|
||||
if (!tags) {
|
||||
tags = gst_tag_list_new ();
|
||||
}
|
||||
|
||||
/* FIXME: not happy with those
|
||||
* - else where we would use VIDEO_CODEC = "Jpeg"
|
||||
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_VIDEO_CODEC, "image/jpeg", NULL);
|
||||
*/
|
||||
|
||||
/* Add EXIF */
|
||||
{
|
||||
GstBuffer *exif_data;
|
||||
guint8 *data;
|
||||
GstJifMuxMarker *m;
|
||||
GList *pos;
|
||||
|
||||
/* insert into self->markers list */
|
||||
exif_data = gst_tag_list_to_exif_buffer_with_tiff_header (tags);
|
||||
if (exif_data &&
|
||||
GST_BUFFER_SIZE (exif_data) + 8 >= G_GUINT64_CONSTANT (65536)) {
|
||||
GST_WARNING_OBJECT (self, "Exif tags data size exceed maximum size");
|
||||
gst_buffer_unref (exif_data);
|
||||
exif_data = NULL;
|
||||
}
|
||||
if (exif_data) {
|
||||
data = g_malloc0 (GST_BUFFER_SIZE (exif_data) + 6);
|
||||
memcpy (data, "Exif", 4);
|
||||
memcpy (data + 6, GST_BUFFER_DATA (exif_data),
|
||||
GST_BUFFER_SIZE (exif_data));
|
||||
m = gst_jif_mux_new_marker (APP1, GST_BUFFER_SIZE (exif_data) + 6, data,
|
||||
TRUE);
|
||||
gst_buffer_unref (exif_data);
|
||||
|
||||
if (app1_exif) {
|
||||
gst_jif_mux_marker_free ((GstJifMuxMarker *) app1_exif->data);
|
||||
app1_exif->data = m;
|
||||
} else {
|
||||
pos = file_hdr;
|
||||
if (app0_jfif)
|
||||
pos = app0_jfif;
|
||||
pos = g_list_next (pos);
|
||||
|
||||
self->priv->markers =
|
||||
g_list_insert_before (self->priv->markers, pos, m);
|
||||
if (pos) {
|
||||
app1_exif = g_list_previous (pos);
|
||||
} else {
|
||||
app1_exif = g_list_last (self->priv->markers);
|
||||
}
|
||||
}
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* add xmp */
|
||||
xmp_data = gst_tag_list_to_xmp_buffer (tags, FALSE);
|
||||
if (xmp_data) {
|
||||
|
@ -506,6 +549,9 @@ gst_jif_mux_mangle_markers (GstJifMux * self)
|
|||
|
||||
modified = TRUE;
|
||||
}
|
||||
|
||||
if (tags && cleanup_tags)
|
||||
gst_tag_list_free (tags);
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
|
|
@ -578,7 +578,32 @@ gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
|
|||
if (!gst_byte_reader_get_string_utf8 (&reader, &id_str))
|
||||
goto error;
|
||||
|
||||
if (!strcmp (id_str, "http://ns.adobe.com/xap/1.0/")) {
|
||||
if (!strcmp (id_str, "Exif")) {
|
||||
const guint8 *exif_data = NULL;
|
||||
guint exif_size = size - 2;
|
||||
GstTagList *tags;
|
||||
GstBuffer *buf;
|
||||
|
||||
/* skip padding */
|
||||
gst_byte_reader_skip (&reader, 1);
|
||||
|
||||
/* handle exif metadata */
|
||||
if (!gst_byte_reader_get_data (&reader, exif_size, &exif_data))
|
||||
goto error;
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
GST_BUFFER_DATA (buf) = (guint8 *) exif_data;
|
||||
GST_BUFFER_SIZE (buf) = exif_size;
|
||||
tags = gst_tag_list_from_exif_buffer_with_tiff_header (buf);
|
||||
gst_buffer_unref (buf);
|
||||
if (tags) {
|
||||
GST_INFO_OBJECT (parse, "post exif metadata");
|
||||
gst_element_found_tags_for_pad (GST_ELEMENT_CAST (parse),
|
||||
parse->priv->srcpad, tags);
|
||||
}
|
||||
GST_LOG_OBJECT (parse, "parsed marker %x: '%s' %u bytes",
|
||||
marker, id_str, size - 2);
|
||||
} else if (!strcmp (id_str, "http://ns.adobe.com/xap/1.0/")) {
|
||||
const guint8 *xmp_data = NULL;
|
||||
guint xmp_size = size - 2 - 29;
|
||||
GstTagList *tags;
|
||||
|
|
Loading…
Reference in a new issue