Commit dc70496d4f for ffmpeg

commit dc70496d4fba4375ce9606972561e65ee5726d23
Author: Joss Gray <joss@jossgray.net>
Date:   Fri Jul 24 16:06:00 2026 -0400

    avcodec/notchlc: harden chroma ramp against descending endpoints

    The chroma ramps had the same signed-division flaw as the alpha ramp: with
    u0 + ((u1 - u0) * selector + 2) / 3 the dividend goes negative for u1 < u0,
    and truncation toward zero inverts the round-up convention, so selector 3
    reconstructs u1 + 1 instead of u1.

    Use the same non-negative weighted sum, which reconstructs both endpoints
    exactly for all 65536 endpoint pairs and is bit-identical for u0 <= u1.
    udif/vdif become unused and are dropped.

diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c
index 3d23c4e743..016d39d129 100644
--- a/libavcodec/notchlc.c
+++ b/libavcodec/notchlc.c
@@ -364,7 +364,7 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
         for (int x = 0; x < avctx->width; x += 16) {
             unsigned offset = bytestream2_get_le32(&rgb) * 4;
             int u[16][16] = { 0 }, v[16][16] = { 0 };
-            int u0, v0, u1, v1, udif, vdif;
+            int u0, v0, u1, v1;
             unsigned escape, is8x8, loc;

             bytestream2_seek(&dgb, s->uv_data_offset + offset, SEEK_SET);
@@ -382,15 +382,15 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                 v0 = (v0 << 4) | (v0 & 0xF);
                 u1 = (u1 << 4) | (u1 & 0xF);
                 v1 = (v1 << 4) | (v1 & 0xF);
-                udif = u1 - u0;
-                vdif = v1 - v0;

                 for (int i = 0; i < 16; i += 4) {
                     for (int j = 0; j < 16; j += 4) {
+                        const int selector = loc & 3;
+
                         for (int ii = 0; ii < 4; ii++) {
                             for (int jj = 0; jj < 4; jj++) {
-                                u[i + ii][j + jj] = u0 + ((udif * (int)(loc & 3) + 2) / 3);
-                                v[i + ii][j + jj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3);
+                                u[i + ii][j + jj] = (u0 * (3 - selector) + u1 * selector + 2) / 3;
+                                v[i + ii][j + jj] = (v0 * (3 - selector) + v1 * selector + 2) / 3;
                             }
                         }

@@ -410,15 +410,15 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                             v0 = (v0 << 4) | (v0 & 0xF);
                             u1 = (u1 << 4) | (u1 & 0xF);
                             v1 = (v1 << 4) | (v1 & 0xF);
-                            udif = u1 - u0;
-                            vdif = v1 - v0;

                             for (int ii = 0; ii < 8; ii += 2) {
                                 for (int jj = 0; jj < 8; jj += 2) {
+                                    const int selector = loc & 3;
+
                                     for (int iii = 0; iii < 2; iii++) {
                                         for (int jjj = 0; jjj < 2; jjj++) {
-                                            u[i + ii + iii][j + jj + jjj] = u0 + ((udif * (int)(loc & 3) + 2) / 3);
-                                            v[i + ii + iii][j + jj + jjj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3);
+                                            u[i + ii + iii][j + jj + jjj] = (u0 * (3 - selector) + u1 * selector + 2) / 3;
+                                            v[i + ii + iii][j + jj + jjj] = (v0 * (3 - selector) + v1 * selector + 2) / 3;
                                         }
                                     }

@@ -437,13 +437,13 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                                     v0 = (v0 << 4) | (v0 & 0xF);
                                     u1 = (u1 << 4) | (u1 & 0xF);
                                     v1 = (v1 << 4) | (v1 & 0xF);
-                                    udif = u1 - u0;
-                                    vdif = v1 - v0;

                                     for (int iii = 0; iii < 4; iii++) {
                                         for (int jjj = 0; jjj < 4; jjj++) {
-                                            u[i + ii + iii][j + jj + jjj] = u0 + ((udif * (int)(loc & 3) + 2) / 3);
-                                            v[i + ii + iii][j + jj + jjj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3);
+                                            const int selector = loc & 3;
+
+                                            u[i + ii + iii][j + jj + jjj] = (u0 * (3 - selector) + u1 * selector + 2) / 3;
+                                            v[i + ii + iii][j + jj + jjj] = (v0 * (3 - selector) + v1 * selector + 2) / 3;

                                             loc >>= 2;
                                         }