Explorar o código

LibGfx/JPEGXL: Fix property 8

The first implementation of this property was just plain wrong. Looks
like this property isn't used a lot as I found the issue by reviewing
the code and not because of a specific image.

The test image is a 32x32 mosaic of alternating black and yellow pixels,
it was generated using this code:

Bitdepth 8
RCT 1
Width 32
Height 32

if W-WW-NW+NWW > -300
 - Set -1000
 - Set 900
Lucas CHOLLET hai 1 ano
pai
achega
00240cb0b3

+ 20 - 0
Tests/LibGfx/TestImageDecoder.cpp

@@ -574,3 +574,23 @@ TEST_CASE(test_jxl_modular_simple_tree_upsample2_10bits)
     auto frame = MUST(plugin_decoder->frame(0));
     EXPECT_EQ(frame.image->get_pixel(42, 57), Gfx::Color::from_string("#4c0072"sv));
 }
+
+TEST_CASE(test_jxl_modular_property_8)
+{
+    auto file = MUST(Core::MappedFile::map(TEST_INPUT("jxl/modular_property_8.jxl"sv)));
+    EXPECT(Gfx::JPEGXLImageDecoderPlugin::sniff(file->bytes()));
+    auto plugin_decoder = MUST(Gfx::JPEGXLImageDecoderPlugin::create(file->bytes()));
+
+    expect_single_frame_of_size(*plugin_decoder, { 32, 32 });
+
+    auto frame = MUST(plugin_decoder->frame(0));
+    for (u8 i = 0; i < 32; ++i) {
+        for (u8 j = 0; j < 32; ++j) {
+            auto const color = frame.image->get_pixel(i, j);
+            if ((i + j) % 2 == 0)
+                EXPECT_EQ(color, Gfx::Color::Black);
+            else
+                EXPECT_EQ(color, Gfx::Color::Yellow);
+        }
+    }
+}

BIN=BIN
Tests/LibGfx/test-inputs/jxl/modular_property_8.jxl


+ 9 - 6
Userland/Libraries/LibGfx/ImageFormats/JPEGXLLoader.cpp

@@ -1303,12 +1303,15 @@ static ErrorOr<Vector<i32>> get_properties(Vector<Channel> const& channels, u16
     TRY(properties.try_append(W));
 
     // x > 0 ? W - /* (the value of property 9 at position (x - 1, y)) */ : W
-    i32 x_1 = x - 1;
-    i32 const W_x_1 = x_1 > 0 ? channels[i].get(x_1 - 1, y) : (x_1 >= 0 && y > 0 ? channels[i].get(x_1, y - 1) : 0);
-    i32 const N_x_1 = x_1 >= 0 && y > 0 ? channels[i].get(x_1, y - 1) : W_x_1;
-    i32 const NW_x_1 = x_1 > 0 && y > 0 ? channels[i].get(x_1 - 1, y - 1) : W_x_1;
-
-    TRY(properties.try_append(W_x_1 + N_x_1 - NW_x_1));
+    if (x > 0) {
+        auto const x_1 = x - 1;
+        i32 const W_x_1 = x_1 > 0 ? channels[i].get(x_1 - 1, y) : (y > 0 ? channels[i].get(x_1, y - 1) : 0);
+        i32 const N_x_1 = y > 0 ? channels[i].get(x_1, y - 1) : W_x_1;
+        i32 const NW_x_1 = x_1 > 0 && y > 0 ? channels[i].get(x_1 - 1, y - 1) : W_x_1;
+        TRY(properties.try_append(W - (W_x_1 + N_x_1 - NW_x_1)));
+    } else {
+        TRY(properties.try_append(W));
+    }
 
     TRY(properties.try_append(W + N - NW));
     TRY(properties.try_append(W - NW));