[FFmpeg-devel] [Read EXIF metadata 3/5] Read EXIF metadata in JPEG input.
Thilo Borgmann
thilo.borgmann at googlemail.com
Fri Aug 9 16:42:08 CEST 2013
3/3 rev 3
-Thilo
-------------- next part --------------
>From 790f986b8efa229d0545ee3c2c3f3c90a16837ca Mon Sep 17 00:00:00 2001
From: Thilo Borgmann <thilo.borgmann at googlemail.com>
Date: Fri, 9 Aug 2013 16:34:26 +0200
Subject: [PATCH 3/3] Read EXIF metadata in JPEG input.
---
Changelog | 1 +
libavcodec/Makefile | 2 +-
libavcodec/mjpegdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/Changelog b/Changelog
index f1d7fa6..4a6c60c 100644
--- a/Changelog
+++ b/Changelog
@@ -14,6 +14,7 @@ version <next>
- ffmpeg -t option can now be used for inputs, to limit the duration of
data read from an input file
- incomplete Voxware MetaSound decoder
+- read EXIF metadata from JPEG
version 2.0:
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 487153c..6c800e0 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -265,7 +265,7 @@ OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \
twinvq.o
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o
-OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o
+OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o exif.o tiff_common.o
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o
OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index c92738f..932be65 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -39,6 +39,9 @@
#include "mjpeg.h"
#include "mjpegdec.h"
#include "jpeglsdec.h"
+#include "tiff.h"
+#include "exif.h"
+#include "bytestream.h"
static int build_vlc(VLC *vlc, const uint8_t *bits_table,
@@ -215,6 +218,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
int len, nb_components, i, width, height, pix_fmt_id;
int h_count[MAX_COMPONENTS];
int v_count[MAX_COMPONENTS];
+ AVDictionary **metadata = avpriv_frame_get_metadatap(s->picture_ptr);
+ AVDictionary *tmp;
s->cur_scan = 0;
s->upscale_h = s->upscale_v = 0;
@@ -459,6 +464,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
}
+ // keep metadata alive by hiding AVDictioniary behind *tmp
+ tmp = *metadata;
+ *metadata = NULL;
+
av_frame_unref(s->picture_ptr);
if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0)
return -1;
@@ -466,6 +475,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->picture_ptr->key_frame = 1;
s->got_picture = 1;
+ // restore metadata in current buffer
+ *avpriv_frame_get_metadatap(s->picture_ptr) = tmp;
+
for (i = 0; i < 3; i++)
s->linesize[i] = s->picture_ptr->linesize[i] << s->interlaced;
@@ -1493,6 +1505,42 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
goto out;
}
+ /* EXIF metadata */
+ if (s->start_code == APP1 && id == AV_RB32("Exif")) {
+ GetByteContext gbytes;
+ int ret, le, ifd_offset, bytes_read, ifds_read;
+
+ skip_bits(&s->gb, 16); // skip padding
+
+ // init byte wise reading
+ bytestream2_init(&gbytes, align_get_bits(&s->gb), get_bits_left(&s->gb) >> 3);
+
+ // read TIFF header
+ ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
+ if (ret) {
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n");
+ return ret;
+ }
+
+ bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
+
+ // read all IFDs and store the metadata
+ ifds_read = 0;
+ while ((ifd_offset = ff_exif_decode_ifd(s->avctx, &gbytes, le, avpriv_frame_get_metadatap(s->picture_ptr))) > 0) {
+ if (++ifds_read > FF_ARRAY_ELEMS(ifd_tags)) {
+ av_log(s->avctx, AV_LOG_INFO, "mjpeg: found more IFD's in EXIF data than expected. Skipping.\n");
+ break;
+ }
+ bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
+ }
+
+ bytes_read = bytestream2_tell(&gbytes);
+ skip_bits(&s->gb, bytes_read << 3);
+ len -= bytes_read;
+
+ goto out;
+ }
+
/* Apple MJPEG-A */
if ((s->start_code == APP1) && (len > (0x28 - 8))) {
id = get_bits_long(&s->gb, 32);
--
1.7.4.3
More information about the ffmpeg-devel
mailing list