Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Thilo Borgmann authored on 2013/08/13 02:36:08... | ... |
@@ -267,7 +267,7 @@ OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \ |
267 | 267 |
twinvq.o |
268 | 268 |
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o |
269 | 269 |
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o |
270 |
-OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o |
|
270 |
+OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o exif.o tiff_common.o |
|
271 | 271 |
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o |
272 | 272 |
OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o |
273 | 273 |
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o |
... | ... |
@@ -39,6 +39,9 @@ |
39 | 39 |
#include "mjpeg.h" |
40 | 40 |
#include "mjpegdec.h" |
41 | 41 |
#include "jpeglsdec.h" |
42 |
+#include "tiff.h" |
|
43 |
+#include "exif.h" |
|
44 |
+#include "bytestream.h" |
|
42 | 45 |
|
43 | 46 |
|
44 | 47 |
static int build_vlc(VLC *vlc, const uint8_t *bits_table, |
... | ... |
@@ -1493,6 +1496,43 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) |
1493 | 1493 |
goto out; |
1494 | 1494 |
} |
1495 | 1495 |
|
1496 |
+ /* EXIF metadata */ |
|
1497 |
+ if (s->start_code == APP1 && id == AV_RB32("Exif")) { |
|
1498 |
+ GetByteContext gbytes; |
|
1499 |
+ int ret, le, ifd_offset, bytes_read; |
|
1500 |
+ const uint8_t *aligned; |
|
1501 |
+ |
|
1502 |
+ skip_bits(&s->gb, 16); // skip padding |
|
1503 |
+ len -= 2; |
|
1504 |
+ |
|
1505 |
+ // init byte wise reading |
|
1506 |
+ aligned = align_get_bits(&s->gb); |
|
1507 |
+ bytestream2_init(&gbytes, aligned, len); |
|
1508 |
+ |
|
1509 |
+ // read TIFF header |
|
1510 |
+ ret = ff_tdecode_header(&gbytes, &le, &ifd_offset); |
|
1511 |
+ if (ret) { |
|
1512 |
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n"); |
|
1513 |
+ return ret; |
|
1514 |
+ } |
|
1515 |
+ |
|
1516 |
+ bytestream2_seek(&gbytes, ifd_offset, SEEK_SET); |
|
1517 |
+ |
|
1518 |
+ // read 0th IFD and store the metadata |
|
1519 |
+ // (return values > 0 indicate the presence of subimage metadata) |
|
1520 |
+ ret = ff_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata); |
|
1521 |
+ if (ret < 0) { |
|
1522 |
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n"); |
|
1523 |
+ return ret; |
|
1524 |
+ } |
|
1525 |
+ |
|
1526 |
+ bytes_read = bytestream2_tell(&gbytes); |
|
1527 |
+ skip_bits(&s->gb, bytes_read << 3); |
|
1528 |
+ len -= bytes_read; |
|
1529 |
+ |
|
1530 |
+ goto out; |
|
1531 |
+ } |
|
1532 |
+ |
|
1496 | 1533 |
/* Apple MJPEG-A */ |
1497 | 1534 |
if ((s->start_code == APP1) && (len > (0x28 - 8))) { |
1498 | 1535 |
id = get_bits_long(&s->gb, 32); |
... | ... |
@@ -1688,6 +1728,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
1688 | 1688 |
int i, index; |
1689 | 1689 |
int ret = 0; |
1690 | 1690 |
|
1691 |
+ av_dict_free(&s->exif_metadata); |
|
1692 |
+ |
|
1691 | 1693 |
buf_ptr = buf; |
1692 | 1694 |
buf_end = buf + buf_size; |
1693 | 1695 |
while (buf_ptr < buf_end) { |
... | ... |
@@ -1916,6 +1958,9 @@ the_end: |
1916 | 1916 |
} |
1917 | 1917 |
} |
1918 | 1918 |
|
1919 |
+ av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0); |
|
1920 |
+ av_dict_free(&s->exif_metadata); |
|
1921 |
+ |
|
1919 | 1922 |
av_log(avctx, AV_LOG_DEBUG, "decode frame unused %td bytes\n", |
1920 | 1923 |
buf_end - buf_ptr); |
1921 | 1924 |
// return buf_end - buf_ptr; |
... | ... |
@@ -1942,6 +1987,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) |
1942 | 1942 |
av_freep(&s->blocks[i]); |
1943 | 1943 |
av_freep(&s->last_nnz[i]); |
1944 | 1944 |
} |
1945 |
+ av_dict_free(&s->exif_metadata); |
|
1945 | 1946 |
return 0; |
1946 | 1947 |
} |
1947 | 1948 |
|