diff options
author | Leo Izen <leo.izen@gmail.com> | 2025-03-12 09:54:09 -0400 |
---|---|---|
committer | Leo Izen <leo.izen@gmail.com> | 2025-08-19 11:26:47 -0400 |
commit | 52dba25661305e3c4a6209d46aea43cd327c960e (patch) | |
tree | 3fc3bb637cb87f243f57dce3c1588a5ba89a043f | |
parent | bfb17d26306592c85cf0c4e909099c621177b062 (diff) | |
download | ffmpeg-52dba25661305e3c4a6209d46aea43cd327c960e.tar.gz |
avcodec/mjpegdec: use new EXIF parse API
Switch over to the new API to parse EXIF metadata.
Signed-off-by: Leo Izen <leo.izen@gmail.com>
-rw-r--r-- | libavcodec/mjpegdec.c | 89 | ||||
-rw-r--r-- | libavcodec/mjpegdec.h | 3 | ||||
-rw-r--r-- | tests/ref/fate/exif-image-embedded | 3 | ||||
-rw-r--r-- | tests/ref/fate/exif-image-jpg | 3 |
4 files changed, 22 insertions, 76 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 983a30cb59..46ec3eb938 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -55,7 +55,6 @@ #include "put_bits.h" #include "exif_internal.h" #include "bytestream.h" -#include "tiff_common.h" static int init_default_huffman_tables(MJpegDecodeContext *s) @@ -2043,8 +2042,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) /* EXIF metadata */ if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) { - GetByteContext gbytes; - int ret, le, ifd_offset, bytes_read; + int ret; const uint8_t *aligned; skip_bits(&s->gb, 16); // skip padding @@ -2052,26 +2050,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) // 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"); - } else { - 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"); - } + ret = av_exif_parse_buffer(s->avctx, aligned, len, &s->exif_metadata, AV_EXIF_TIFF_HEADER); + if (ret < 0) { + av_log(s->avctx, AV_LOG_WARNING, "unable to parse EXIF buffer\n"); + goto out; } - bytes_read = bytestream2_tell(&gbytes); - skip_bits(&s->gb, bytes_read << 3); - len -= bytes_read; + skip_bits(&s->gb, ret << 3); + len -= ret; goto out; } @@ -2384,13 +2371,12 @@ int ff_mjpeg_decode_frame_from_buf(AVCodecContext *avctx, AVFrame *frame, int index; int ret = 0; int is16bit; - AVDictionaryEntry *e = NULL; s->force_pal8 = 0; s->buf_size = buf_size; - av_dict_free(&s->exif_metadata); + av_exif_free(&s->exif_metadata); av_freep(&s->stereo3d); s->adobe_transform = -1; @@ -2868,60 +2854,13 @@ the_end: } } - if (e = av_dict_get(s->exif_metadata, "Orientation", e, AV_DICT_IGNORE_SUFFIX)) { - char *value = e->value + strspn(e->value, " \n\t\r"), *endptr; - int orientation = strtol(value, &endptr, 0); - - if (!*endptr) { - AVFrameSideData *sd = NULL; - - if (orientation >= 2 && orientation <= 8) { - int32_t *matrix; - - sd = av_frame_new_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); - if (!sd) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); - return AVERROR(ENOMEM); - } - - matrix = (int32_t *)sd->data; - - switch (orientation) { - case 2: - av_display_rotation_set(matrix, 0.0); - av_display_matrix_flip(matrix, 1, 0); - break; - case 3: - av_display_rotation_set(matrix, 180.0); - break; - case 4: - av_display_rotation_set(matrix, 180.0); - av_display_matrix_flip(matrix, 1, 0); - break; - case 5: - av_display_rotation_set(matrix, 90.0); - av_display_matrix_flip(matrix, 1, 0); - break; - case 6: - av_display_rotation_set(matrix, 90.0); - break; - case 7: - av_display_rotation_set(matrix, -90.0); - av_display_matrix_flip(matrix, 1, 0); - break; - case 8: - av_display_rotation_set(matrix, -90.0); - break; - default: - av_assert0(0); - } - } - } + if (s->exif_metadata.entries) { + ret = ff_exif_attach_ifd(avctx, frame, &s->exif_metadata); + av_exif_free(&s->exif_metadata); + if (ret < 0) + av_log(avctx, AV_LOG_WARNING, "couldn't attach EXIF metadata\n"); } - av_dict_copy(&frame->metadata, s->exif_metadata, 0); - av_dict_free(&s->exif_metadata); - if (avctx->codec_id != AV_CODEC_ID_SMVJPEG && (avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || avctx->codec_tag == MKTAG('A', 'V', 'D', 'J')) && @@ -2973,7 +2912,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); + av_exif_free(&s->exif_metadata); reset_icc_profile(s); diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 13c524d597..8b9ed67856 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -36,6 +36,7 @@ #include "avcodec.h" #include "blockdsp.h" +#include "exif.h" #include "get_bits.h" #include "hpeldsp.h" #include "idctdsp.h" @@ -138,7 +139,7 @@ typedef struct MJpegDecodeContext { unsigned int ljpeg_buffer_size; int extern_huff; - AVDictionary *exif_metadata; + AVExifMetadata exif_metadata; AVStereo3D *stereo3d; ///!< stereoscopic information (cached, since it is read before frame allocation) diff --git a/tests/ref/fate/exif-image-embedded b/tests/ref/fate/exif-image-embedded index 574a3af848..a6617bd89f 100644 --- a/tests/ref/fate/exif-image-embedded +++ b/tests/ref/fate/exif-image-embedded @@ -32,6 +32,9 @@ color_transfer=unknown chroma_location=center TAG:ExifIFD/UserComment=AppleMark +[SIDE_DATA] +side_data_type=EXIF metadata +[/SIDE_DATA] [/FRAME] [FRAME] media_type=audio diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg index 5a8cd10063..5135ae32f8 100644 --- a/tests/ref/fate/exif-image-jpg +++ b/tests/ref/fate/exif-image-jpg @@ -197,4 +197,7 @@ TAG:ExifIFD/ExposureMode= 0 TAG:ExifIFD/WhiteBalance= 0 TAG:ExifIFD/DigitalZoomRatio= 4000:4000 TAG:ExifIFD/SceneCaptureType= 0 +[SIDE_DATA] +side_data_type=EXIF metadata +[/SIDE_DATA] [/FRAME] |