The branch, master has been updated
       via  dc39a576ad8c489bf229c4acdf5c347b1dd264b2 (commit)
      from  51d3c4b4b62691736172120c5d728e6c400d69c9 (commit)


- Log -----------------------------------------------------------------
commit dc39a576ad8c489bf229c4acdf5c347b1dd264b2
Author:     Leo Izen <[email protected]>
AuthorDate: Wed Sep 17 08:48:02 2025 -0400
Commit:     Leo Izen <[email protected]>
CommitDate: Sun Oct 19 09:17:38 2025 -0400

    avcodec/pngenc: include EXIF buffer in max_packet_size
    
    When calculating the max size of an output PNG packet, we should
    include the size of a possible eXIf chunk that we may write.
    
    This fixes a regression since d3190a64c366a79091fe47fddf93c09a7d988802
    as well as a bug that existed prior in the apng encoder since commit
    4a580975d4b978894d20dd443163cc8b6a2dbf2a.
    
    Signed-off-by: Leo Izen <[email protected]>

diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 8e4f42125e..07f5452157 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -646,6 +646,34 @@ static int add_icc_profile_size(AVCodecContext *avctx, 
const AVFrame *pict,
     return 0;
 }
 
+static int add_exif_profile_size(AVCodecContext *avctx, const AVFrame *pict,
+                                 uint64_t *max_packet_size)
+{
+    const AVFrameSideData *sd;
+    uint64_t new_pkt_size;
+    /* includes orientation tag */
+    const int base_exif_size = 92;
+    uint64_t estimated_exif_size;
+
+    sd = av_frame_get_side_data(pict, AV_FRAME_DATA_EXIF);
+    estimated_exif_size = sd ? sd->size : 0;
+    sd = av_frame_get_side_data(pict, AV_FRAME_DATA_DISPLAYMATRIX);
+    if (sd)
+        estimated_exif_size += base_exif_size;
+
+    if (!estimated_exif_size)
+        return 0;
+
+    /* 12 is the png chunk header size */
+    new_pkt_size = *max_packet_size + estimated_exif_size + 12;
+    if (new_pkt_size < *max_packet_size)
+        return AVERROR_INVALIDDATA;
+
+    *max_packet_size = new_pkt_size;
+
+    return 0;
+}
+
 static int encode_png(AVCodecContext *avctx, AVPacket *pkt,
                       const AVFrame *pict, int *got_packet)
 {
@@ -664,6 +692,10 @@ static int encode_png(AVCodecContext *avctx, AVPacket *pkt,
         );
     if ((ret = add_icc_profile_size(avctx, pict, &max_packet_size)))
         return ret;
+    ret = add_exif_profile_size(avctx, pict, &max_packet_size);
+    if (ret < 0)
+        return ret;
+
     ret = ff_alloc_packet(avctx, pkt, max_packet_size);
     if (ret < 0)
         return ret;
@@ -996,16 +1028,23 @@ static int encode_apng(AVCodecContext *avctx, AVPacket 
*pkt,
             enc_row_size +
             (4 + 12) * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) 
// fdAT * ceil(enc_row_size / IOBUF_SIZE)
         );
-    if ((ret = add_icc_profile_size(avctx, pict, &max_packet_size)))
-        return ret;
     if (max_packet_size > INT_MAX)
         return AVERROR(ENOMEM);
 
     if (avctx->frame_num == 0) {
         if (!pict)
             return AVERROR(EINVAL);
-
-        s->bytestream = s->extra_data = av_malloc(FF_INPUT_BUFFER_MIN_SIZE);
+        uint64_t extradata_size = FF_INPUT_BUFFER_MIN_SIZE;
+        ret = add_icc_profile_size(avctx, pict, &extradata_size);
+        if (ret < 0)
+            return ret;
+        ret = add_exif_profile_size(avctx, pict, &extradata_size);
+        if (ret < 0)
+            return ret;
+        /* the compiler will optimize this out if UINT64_MAX == SIZE_MAX */
+        if (extradata_size > SIZE_MAX)
+            return AVERROR(ENOMEM);
+        s->bytestream = s->extra_data = av_malloc(extradata_size);
         if (!s->extra_data)
             return AVERROR(ENOMEM);
 

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/pngenc.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)


hooks/post-receive
-- 

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to