PR #25772 opened by Forgejo_Fairy
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25772
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25772.patch

When `LUT_1D_SIZE` precedes `LUT_3D_SIZE`, the Cube parser skips the shaper 
declaration and consumes its rows as the first cube entries. An identity shaper 
plus an identity cube consequently maps RGB `128 128 128` to `128 0 128` while 
exiting successfully.

Reject the unsupported declaration before reading cube data, including 
declarations with leading whitespace, and emit an explicit diagnostic. 
Declarations after the 3D header are already rejected by the numeric-row 
parser. Document the limitation and add a generated-input FATE test checking 
both failure and the diagnostic. This implements the explicit-error outcome 
requested in #25698; shaper evaluation remains unsupported.

Validation: `fate-filter-lut3d-shaper` passes with the patch and fails against 
unpatched master baa68e68b34e. Manual checks cover the supplied example, 
leading whitespace, reversed headers, standalone 1D files, and plain identity 
cubes with comments, titles, and identity domain directives. The valid controls 
preserve both reported input colours byte-for-byte. `git diff --check` passes.

Fixes #25698.


>From 8c0735b17a1001512e5fa6d323ca87e54ed2f3e6 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Thu, 5 Nov 2026 01:45:51 +0000
Subject: [PATCH] avfilter/lut3d: reject cube files containing a 1D shaper

The Iridas cube parser skips unrecognized lines before LUT_3D_SIZE.
When LUT_1D_SIZE precedes it, the 1D shaper rows are consequently read
as the first 3D entries, silently producing incorrect colors.

Reject the unsupported declaration, including leading whitespace,
before consuming any cube data. A declaration after LUT_3D_SIZE is
already rejected by the numeric row parser. Document the limitation
and add a generated-input FATE test checking rejection and its diagnostic.

Fixes #25698.

Assisted-by: Fairy
---
 doc/filters.texi            |  2 +-
 libavfilter/vf_lut3d.c      |  9 +++++++++
 tests/fate/filter-video.mak | 13 +++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index b860e64a1d3..50d6612ac79 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -18241,7 +18241,7 @@ Currently supported formats:
 @item 3dl
 AfterEffects
 @item cube
-Iridas
+Iridas (3D LUT only; files containing a 1D shaper are not supported)
 @item dat
 DaVinci
 @item m3d
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 2c78507b7e4..1b45730cdd6 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -680,6 +680,15 @@ static int parse_cube(AVFilterContext *ctx, FILE *f)
     float max[3] = {1.0, 1.0, 1.0};
 
     while (fgets(line, sizeof(line), f)) {
+        const char *p = line;
+
+        while (av_isspace(*p))
+            p++;
+        if (!strncmp(p, "LUT_1D_SIZE", 11)) {
+            av_log(ctx, AV_LOG_ERROR, "Cube files with a 1D LUT are not 
supported\n");
+            return AVERROR_PATCHWELCOME;
+        }
+
         if (!strncmp(line, "LUT_3D_SIZE", 11)) {
             int ret, i, j, k, size2;
             const int size = strtol(line + 12, NULL, 0);
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 95254ff3fcf..9658b379877 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -622,6 +622,19 @@ fate-filter-noformat-chroma: CMD = framecrc -flags 
bitexact -lavfi testsrc2=s=64
 FATE_FILTER-$(call FILTERFRAMECRC, TESTSRC2 FORMAT SETPARAMS ZSCALE SCALE, 
LAVFI_INDEV WRAPPED_AVFRAME_DECODER) += fate-filter-zscale-chroma-input-override
 fate-filter-zscale-chroma-input-override: CMD = framecrc -flags bitexact -f 
lavfi -i testsrc2=s=64x64:r=2:d=2,setparams=chroma_location=left -vf 
zscale=chromalin=center,format=chroma_locations=center,scale=flags=accurate_rnd+bitexact
 -frames:v 4
 
+tests/data/filter-lut3d-shaper.cube: TAG = GEN
+tests/data/filter-lut3d-shaper.cube: | tests/data
+       $(M)printf '%s\n' 'LUT_1D_SIZE 2' 'LUT_3D_SIZE 2' '0 0 0' '1 1 1' \
+           '0 0 0' '1 0 0' '0 1 0' '1 1 0' '0 0 1' '1 0 1' '0 1 1' '1 1 1' > $@
+
+FATE_FILTER-$(call ALLYES, LUT3D_FILTER COLOR_FILTER FORMAT_FILTER LAVFI_INDEV 
\
+                           WRAPPED_AVFRAME_DECODER WRAPPED_AVFRAME_ENCODER \
+                           NULL_MUXER) += fate-filter-lut3d-shaper
+fate-filter-lut3d-shaper: tests/data/filter-lut3d-shaper.cube
+fate-filter-lut3d-shaper: CMD = ! run $(FFMPEG) -nostdin -hide_banner -f lavfi 
-i 
"color=s=16x16:d=0.04,format=rgb24,lut3d=file=$(TARGET_PATH)/tests/data/filter-lut3d-shaper.cube"
 -f null -
+fate-filter-lut3d-shaper: CMP = grep
+fate-filter-lut3d-shaper: REF = Cube files with a 1D LUT are not supported
+
 FATE_FILTER-$(call ALLYES, SCALE_FILTER TESTSRC2_FILTER LAVFI_INDEV \
                            WRAPPED_AVFRAME_DECODER WRAPPED_AVFRAME_ENCODER \
                            NULL_MUXER) += fate-filter-scale-print-info \
-- 
2.54.0

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

Reply via email to