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]
