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

Git pushed a commit to branch master
in repository ffmpeg.

commit 283197ce1107afe182be91cff0fb4b4e00bfb106
Author:     Joss Gray <[email protected]>
AuthorDate: Sun Jul 12 14:49:49 2026 -0400
Commit:     dev-joss <[email protected]>
CommitDate: Sat Nov 7 21:59:44 2026 +0000

    avcodec/notchlc: fix alpha block decoding
    
    Alpha ramp blocks read their endpoint pair and selector word once per
    16x16 macroblock and then consumed only three selector bits per 4x4 block,
    so every pixel of a block shared one selector and fifteen of the sixteen
    blocks decoded from the wrong data. Read the 64-bit alpha word inside the
    ramp case, once per 4x4 block, and advance the selector after every
    sample.
    
    The ramp mapping also dropped its divisor: alpha0 + (alpha1 - alpha0) *
    selector scales the endpoint difference by up to seven instead of
    interpolating between the endpoints. Divide by seven, rounding up, as the
    chroma ramps already do.
    
    Write the interpolation as the non-negative weighted sum
    (alpha0 * (7 - selector) + alpha1 * selector + 6) / 7 rather than the
    equivalent difference form. The difference form has a negative dividend
    when alpha1 < alpha0, and C truncation toward zero then inverts the
    round-up convention, so selector 7 reconstructs alpha1 + 1 instead of
    alpha1. The weighted sum rounds up regardless of endpoint ordering and
    reconstructs both endpoints exactly. Both forms are bit-identical for
    alpha0 <= alpha1; the NotchLC Adobe CC plugin was not observed to emit
    descending pairs, so this only affects streams with descending endpoints.
---
 libavcodec/notchlc.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c
index 396089254e..3d23c4e743 100644
--- a/libavcodec/notchlc.c
+++ b/libavcodec/notchlc.c
@@ -298,7 +298,7 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
             for (int x = 0; x < avctx->width; x += 16) {
                 unsigned m = bytestream2_get_le32(gb);
                 unsigned offset = bytestream2_get_le32(gb);
-                unsigned alpha0, alpha1;
+                int alpha0, alpha1;
                 uint64_t control;
 
                 if (offset >= UINT_MAX / 4)
@@ -308,10 +308,6 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                     return AVERROR_INVALIDDATA;
 
                 bytestream2_seek(&dgb, offset, SEEK_SET);
-                control = bytestream2_get_le64(&dgb);
-                alpha0 = control & 0xFF;
-                alpha1 = (control >> 8) & 0xFF;
-                control = control >> 16;
 
                 for (int by = 0; by < 4; by++) {
                     for (int bx = 0; bx < 4; bx++) {
@@ -331,9 +327,16 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                             }
                             break;
                         case 2:
+                            control = bytestream2_get_le64(&dgb);
+                            alpha0 = control & 0xFF;
+                            alpha1 = (control >> 8) & 0xFF;
+                            control >>= 16;
                             for (int i = 0; i < 4; i++) {
                                 for (int j = 0; j < 4; j++) {
-                                    dsta[x + (i + by * 4) * alinesize + bx * 4 
+ j] = (alpha0 + (alpha1 - alpha0) * (control & 7)) << 4;
+                                    const int selector = control & 7;
+
+                                    dsta[x + (i + by * 4) * alinesize + bx * 4 
+ j] = ((alpha0 * (7 - selector) + alpha1 * selector + 6) / 7) << 4;
+                                    control >>= 3;
                                 }
                             }
                             break;
@@ -341,7 +344,6 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                             return AVERROR_INVALIDDATA;
                         }
 
-                        control >>= 3;
                         m >>= 2;
                     }
                 }

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