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 <leo.izen@gmail.com>
This commit is contained in:
Leo Izen
2025-03-25 12:14:32 -04:00
parent 44af382979
commit d3190a64c3
4 changed files with 29 additions and 6 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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