This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 235b81cb9a393e67137cb16d8b55c1bbae0d6514
Author:     Wu Jianhua <[email protected]>
AuthorDate: Thu Aug 27 03:09:39 2026 +0800
Commit:     jianhuaw <[email protected]>
CommitDate: Fri Aug 28 18:50:16 2026 +0000

    avcodec/tiffenc: support writing ICC profiles
    
    Write ICC profiles as TIFF UNDEFINED data and align all out-of-line IFD 
values to a word boundary. Account for non-empty ICC side data while allocating 
the packet and calculate the image size in checked 64-bit arithmetic.
    
    Signed-off-by: Wu Jianhua <[email protected]>
---
 libavcodec/tiffenc.c | 44 +++++++++++++++++++++++++++++++++++---------
 tests/ref/lavf/tiff  |  4 ++--
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index f4556d5f65..c498e04fa4 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -130,6 +130,7 @@ static int add_entry(TiffEncoderContext *s, enum TiffTags 
tag,
                      enum AVTiffDataType type, int count, const void *ptr_val)
 {
     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
+    int64_t data_size = count * (int64_t)type_sizes2[type];
 
     av_assert0(s->num_entries < TIFF_MAX_ENTRY);
 
@@ -140,9 +141,13 @@ static int add_entry(TiffEncoderContext *s, enum TiffTags 
tag,
     if (type_sizes[type] * (int64_t)count <= 4) {
         tnput(&entries_ptr, count, ptr_val, type, 0);
     } else {
-        bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
-        if (check_size(s, count * (int64_t)type_sizes2[type]))
+        int padding = (*s->buf - s->buf_start) & 1;
+
+        if (check_size(s, data_size + padding))
             return AVERROR_INVALIDDATA;
+        if (padding)
+            bytestream_put_byte(s->buf, 0);
+        bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
         tnput(s->buf, count, ptr_val, type, 0);
     }
 
@@ -251,17 +256,19 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     TiffEncoderContext *s = avctx->priv_data;
     const AVFrame *const p = pict;
+    const AVFrameSideData *icc_profile;
     int i;
     uint8_t *ptr;
     uint8_t *offset;
     uint32_t strips;
-    int bytes_per_row;
+    int64_t bytes_per_row;
     uint32_t res[2] = { s->dpi, 1 };    // image resolution (72/1)
     uint16_t bpp_tab[4];
     int ret = 0;
     int is_yuv = 0, alpha = 0;
     int shift_h, shift_v;
-    int packet_size;
+    int64_t packet_size;
+    int icc_size = 0;
 
     s->width          = avctx->width;
     s->height         = avctx->height;
@@ -322,6 +329,15 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
     for (i = 0; i < s->bpp_tab_size; i++)
         bpp_tab[i] = desc->comp[i].depth;
 
+    icc_profile = av_frame_get_side_data(pict, AV_FRAME_DATA_ICC_PROFILE);
+    if (icc_profile && icc_profile->size) {
+        if (icc_profile->size > INT_MAX) {
+            av_log(avctx, AV_LOG_ERROR, "ICC profile is too large\n");
+            return AVERROR_INVALIDDATA;
+        }
+        icc_size = icc_profile->size;
+    }
+
     if (s->compr == TIFF_DEFLATE       ||
         s->compr == TIFF_ADOBE_DEFLATE ||
         s->compr == TIFF_LZW)
@@ -329,16 +345,21 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
         s->rps = s->height;
     else
         // suggest size of strip
-        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);
+        s->rps = FFMAX(8192 / ((((int64_t)s->width * s->bpp) >> 3) + 1), 1);
     // round rps up
     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1];
 
     strips = (s->height - 1) / s->rps + 1;
 
-    bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
-                     s->subsampling[0] * s->subsampling[1] + 7) >> 3;
-    packet_size = avctx->height * bytes_per_row * 2 +
-                  avctx->height * 4 + FF_INPUT_BUFFER_MIN_SIZE;
+    bytes_per_row = ((((int64_t)s->width - 1) / s->subsampling[0] + 1) *
+                     s->bpp * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
+    if (bytes_per_row > INT_MAX)
+        return AVERROR(EINVAL);
+    if (avctx->height > (INT64_MAX - FF_INPUT_BUFFER_MIN_SIZE - icc_size -
+                         !!icc_size) / (2 * bytes_per_row + 4))
+        return AVERROR(EINVAL);
+    packet_size = avctx->height * (2 * bytes_per_row + 4) +
+                  FF_INPUT_BUFFER_MIN_SIZE + icc_size + !!icc_size;
 
     if ((ret = ff_alloc_packet(avctx, pkt, packet_size)) < 0)
         return ret;
@@ -515,6 +536,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
             ADD_ENTRY1(s, TIFF_YCBCR_POSITIONING, AV_TIFF_SHORT, 2);
         ADD_ENTRY(s, TIFF_REFERENCE_BW,      AV_TIFF_RATIONAL, 6, refbw);
     }
+
+    if (icc_size)
+        ADD_ENTRY(s, TIFF_ICC_PROFILE, AV_TIFF_UNDEFINED, icc_size, 
icc_profile->data);
+
     // write offset to dir
     bytestream_put_le32(&offset, ptr - pkt->data);
 
@@ -587,6 +612,7 @@ const FFCodec ff_tiff_encoder = {
     .p.id           = AV_CODEC_ID_TIFF,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
                       AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+    .caps_internal  = FF_CODEC_CAP_ICC_PROFILES,
     .priv_data_size = sizeof(TiffEncoderContext),
     .init           = encode_init,
     .close          = encode_close,
diff --git a/tests/ref/lavf/tiff b/tests/ref/lavf/tiff
index 35655b10a7..2c367c491b 100644
--- a/tests/ref/lavf/tiff
+++ b/tests/ref/lavf/tiff
@@ -1,3 +1,3 @@
-b3299346a8959553a437e486d8f3bf76 *tests/data/images/tiff/02.tiff
-307131 tests/data/images/tiff/02.tiff
+362a9ddc023705de16ea26e58f6f639b *tests/data/images/tiff/02.tiff
+307132 tests/data/images/tiff/02.tiff
 tests/data/images/tiff/%02d.tiff CRC=0x6da01946

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to