summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Izen <[email protected]>2025-03-25 12:14:32 -0400
committerLeo Izen <[email protected]>2025-08-19 11:26:47 -0400
commitd3190a64c366a79091fe47fddf93c09a7d988802 (patch)
tree879f67932ded381496db96ec8636d0d75d17382a
parent44af3829796427b89c4b76b56652cc5932ada616 (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.c7
-rw-r--r--libavcodec/pngenc.c16
-rw-r--r--tests/ref/fate/cover-art-mp3-id3v2-remux6
-rw-r--r--tests/ref/fate/mov-cover-image6
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