aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorThilo Borgmann <thilo.borgmann@googlemail.com>2013-08-12 19:36:08 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-08-13 00:30:34 +0200
commitbb4e1b4cf910af0de2bc884c75544603c40010cc (patch)
treef9b0a43dade39cee5d7cba468083df737d387120 /libavcodec
parentad0f7574effe25afaa32684291adfe6943d67836 (diff)
downloadffmpeg-bb4e1b4cf910af0de2bc884c75544603c40010cc.tar.gz
avcodec/mjpegdec: Read EXIF metadata in JPEG input.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/Makefile2
-rw-r--r--libavcodec/mjpegdec.c46
-rw-r--r--libavcodec/mjpegdec.h1
3 files changed, 48 insertions, 1 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 5ba8a1ab9e..e9ba2fa239 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -267,7 +267,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 c92738f727..76a4a31caf 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,
@@ -1493,6 +1496,43 @@ 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;
+ const uint8_t *aligned;
+
+ skip_bits(&s->gb, 16); // skip padding
+ len -= 2;
+
+ // init byte wise reading
+ aligned = align_get_bits(&s->gb);
+ bytestream2_init(&gbytes, aligned, len);
+
+ // 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 0th IFD and store the metadata
+ // (return values > 0 indicate the presence of subimage metadata)
+ ret = ff_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n");
+ return ret;
+ }
+
+ 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);
@@ -1688,6 +1728,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
int i, index;
int ret = 0;
+ av_dict_free(&s->exif_metadata);
+
buf_ptr = buf;
buf_end = buf + buf_size;
while (buf_ptr < buf_end) {
@@ -1916,6 +1958,9 @@ the_end:
}
}
+ av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
+ av_dict_free(&s->exif_metadata);
+
av_log(avctx, AV_LOG_DEBUG, "decode frame unused %td bytes\n",
buf_end - buf_ptr);
// return buf_end - buf_ptr;
@@ -1942,6 +1987,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
av_freep(&s->blocks[i]);
av_freep(&s->last_nnz[i]);
}
+ av_dict_free(&s->exif_metadata);
return 0;
}
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 0cb26f1c81..fa69d50389 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -119,6 +119,7 @@ typedef struct MJpegDecodeContext {
unsigned int ljpeg_buffer_size;
int extern_huff;
+ AVDictionary *exif_metadata;
} MJpegDecodeContext;
int ff_mjpeg_decode_init(AVCodecContext *avctx);