diff options
author | Leo Izen <[email protected]> | 2025-03-25 12:14:32 -0400 |
---|---|---|
committer | Leo Izen <[email protected]> | 2025-08-19 11:26:47 -0400 |
commit | d3190a64c366a79091fe47fddf93c09a7d988802 (patch) | |
tree | 879f67932ded381496db96ec8636d0d75d17382a | |
parent | 44af3829796427b89c4b76b56652cc5932ada616 (diff) |
avcodec/pngenc: support writing EXIF profiles
Add support to write EXIF profiles using the new EXIF framework, namely
ff_exif_get_buffer, and writing them into eXIf chunks.
Signed-off-by: Leo Izen <[email protected]>
-rw-r--r-- | libavcodec/exif.c | 7 | ||||
-rw-r--r-- | libavcodec/pngenc.c | 16 | ||||
-rw-r--r-- | tests/ref/fate/cover-art-mp3-id3v2-remux | 6 | ||||
-rw-r--r-- | tests/ref/fate/mov-cover-image | 6 |
4 files changed, 29 insertions, 6 deletions
diff --git a/libavcodec/exif.c b/libavcodec/exif.c index c48eb5daa6..fa46202874 100644 --- a/libavcodec/exif.c +++ b/libavcodec/exif.c @@ -1350,6 +1350,13 @@ int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ } if (!pw && w && w < 0xFFFFu || !ph && h && h < 0xFFFFu) { rewrite = 1; + exif = NULL; + for (size_t i = 0; i < ifd.count; i++) { + if (ifd.entries[i].id == EXIFIFD_TAG && ifd.entries[i].type == AV_TIFF_IFD) { + exif = &ifd.entries[i].value.ifd; + break; + } + } if (!exif) { AVExifMetadata exif_new = { 0 }; ret = av_exif_set_entry(logctx, &ifd, EXIFIFD_TAG, AV_TIFF_IFD, 1, NULL, 0, &exif_new); diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 9bbb8267cf..635c89e87e 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -22,6 +22,7 @@ #include "avcodec.h" #include "codec_internal.h" #include "encode.h" +#include "exif_internal.h" #include "bytestream.h" #include "lossless_videoencdsp.h" #include "png.h" @@ -29,6 +30,7 @@ #include "zlib_wrapper.h" #include "libavutil/avassert.h" +#include "libavutil/buffer.h" #include "libavutil/crc.h" #include "libavutil/csp.h" #include "libavutil/libm.h" @@ -373,6 +375,7 @@ static int encode_headers(AVCodecContext *avctx, const AVFrame *pict) { AVFrameSideData *side_data; PNGEncContext *s = avctx->priv_data; + AVBufferRef *exif_data = NULL; int ret; /* write png header */ @@ -414,6 +417,19 @@ static int encode_headers(AVCodecContext *avctx, const AVFrame *pict) } } + ret = ff_exif_get_buffer(avctx, pict, &exif_data, AV_EXIF_TIFF_HEADER); + if (exif_data) { + // png_write_chunk accepts an int, not a size_t, so we have to check overflow + if (exif_data->size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + // that's a very big exif chunk, probably a bug + av_log(avctx, AV_LOG_ERROR, "extremely large EXIF buffer detected, not writing\n"); + else + png_write_chunk(&s->bytestream, MKTAG('e','X','I','f'), exif_data->data, exif_data->size); + av_buffer_unref(&exif_data); + } else if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF metadata: %s\n", av_err2str(ret)); + } + side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_ICC_PROFILE); if ((ret = png_write_iccp(s, side_data))) return ret; diff --git a/tests/ref/fate/cover-art-mp3-id3v2-remux b/tests/ref/fate/cover-art-mp3-id3v2-remux index 011c123a70..42fe704470 100644 --- a/tests/ref/fate/cover-art-mp3-id3v2-remux +++ b/tests/ref/fate/cover-art-mp3-id3v2-remux @@ -1,5 +1,5 @@ -a8dc078d174d5c4ae9769090b8404bae *tests/data/fate/cover-art-mp3-id3v2-remux.mp3 -346394 tests/data/fate/cover-art-mp3-id3v2-remux.mp3 +070ed1d95dc1bd365d68ae795966589f *tests/data/fate/cover-art-mp3-id3v2-remux.mp3 +346509 tests/data/fate/cover-art-mp3-id3v2-remux.mp3 #tb 0: 1/14112000 #media_type 0: audio #codec_id 0: mp3 @@ -23,7 +23,7 @@ a8dc078d174d5c4ae9769090b8404bae *tests/data/fate/cover-art-mp3-id3v2-remux.mp3 0, -353590, -353590, 368640, 417, 0x15848290, S=1, Skip Samples, 10, 0x034e0055 1, 0, 0, 0, 208350, 0x291b44d1 2, 0, 0, 0, 15760, 0x71d5c418 -3, 0, 0, 0, 112719, 0x117b6853 +3, 0, 0, 0, 112834, 0x7da17554 0, 15050, 15050, 368640, 418, 0x46f684a4 0, 383690, 383690, 368640, 418, 0x46f684a4 0, 752330, 752330, 368640, 418, 0x46f684a4 diff --git a/tests/ref/fate/mov-cover-image b/tests/ref/fate/mov-cover-image index 0607d56a0c..305a851d98 100644 --- a/tests/ref/fate/mov-cover-image +++ b/tests/ref/fate/mov-cover-image @@ -1,5 +1,5 @@ -9a5143f063aedb39fb1f080444cc19a0 *tests/data/fate/mov-cover-image.mp4 -1023905 tests/data/fate/mov-cover-image.mp4 +ea8251f5922d663b174855af325d689f *tests/data/fate/mov-cover-image.mp4 +1024065 tests/data/fate/mov-cover-image.mp4 #extradata 0: 2, 0x00340022 #tb 0: 1/44100 #media_type 0: audio @@ -20,7 +20,7 @@ 0, -1088, -1088, 1024, 6, 0x027e00e8, F=0x5 0, -64, -64, 1024, 6, 0x027e00e8 1, 0, 0, 0, 25441, 0xe82503b0 -2, 0, 0, 0, 44643, 0xdb75ffb5 +2, 0, 0, 0, 44803, 0x1e4a0e8f 0, 960, 960, 1024, 6, 0x027e00e8 0, 1984, 1984, 1024, 6, 0x027e00e8 0, 3008, 3008, 1024, 6, 0x027e00e8 |