Browse code

avcodec/mjpegdec: Read EXIF metadata in JPEG input.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Thilo Borgmann authored on 2013/08/13 02:36:08
Showing 4 changed files
... ...
@@ -14,6 +14,7 @@ version <next>
14 14
 - ffmpeg -t option can now be used for inputs, to limit the duration of
15 15
   data read from an input file
16 16
 - incomplete Voxware MetaSound decoder
17
+- read EXIF metadata from JPEG
17 18
 
18 19
 
19 20
 version 2.0:
... ...
@@ -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
 
... ...
@@ -119,6 +119,7 @@ typedef struct MJpegDecodeContext {
119 119
     unsigned int ljpeg_buffer_size;
120 120
 
121 121
     int extern_huff;
122
+    AVDictionary *exif_metadata;
122 123
 } MJpegDecodeContext;
123 124
 
124 125
 int ff_mjpeg_decode_init(AVCodecContext *avctx);