From 816674de365ee4ce460d94201346aea46c7dd9e7 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 8 Jun 2023 17:28:59 -0400 Subject: [PATCH] WebP: Add test for horizontal ALPH chunk filtering_method --- Tests/LibGfx/TestImageDecoder.cpp | 25 +++++++++++++++++++ .../LibGfx/ImageFormats/WebPLoader.cpp | 1 - 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index 1ccca42af0..092d7c3fa7 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -348,6 +348,7 @@ TEST_CASE(test_webp_simple_lossless) TEST_CASE(test_webp_extended_lossy) { + // This extended lossy image has an ALPH chunk for (losslessly compressed) alpha data. auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossy.webp"sv))); EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes())); auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes())); @@ -379,6 +380,30 @@ TEST_CASE(test_webp_extended_lossy) EXPECT_EQ(frame.image->get_pixel(341, 75), Gfx::Color(0, 0, 0, 128)); } +TEST_CASE(test_webp_extended_lossy_alpha_horizontal_filter) +{ + // Also lossy rgb + lossless alpha, but with a horizontal alpha filtering method. + // The image should look like smolkling.webp, but with a horizontal alpha gradient. + auto file = MUST(Core::MappedFile::map(TEST_INPUT("smolkling-horizontal-alpha.webp"sv))); + EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes())); + auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes())); + MUST(plugin_decoder->initialize()); + + EXPECT_EQ(plugin_decoder->frame_count(), 1u); + EXPECT(!plugin_decoder->is_animated()); + EXPECT(!plugin_decoder->loop_count()); + + EXPECT_EQ(plugin_decoder->size(), Gfx::IntSize(264, 264)); + + auto frame = MUST(plugin_decoder->frame(0)); + EXPECT_EQ(frame.image->size(), Gfx::IntSize(264, 264)); + + // While VP8 YUV contents are defined bit-exact, the YUV->RGB conversion isn't. + // So pixels changing by 1 or so below is fine if you change code. + // The important component in this test is alpha, and that shouldn't change even by 1 as it's losslessly compressed and doesn't use YUV. + EXPECT_EQ(frame.image->get_pixel(131, 131), Gfx::Color(0x8f, 0x51, 0x2f, 0x4b)); +} + TEST_CASE(test_webp_extended_lossy_uncompressed_alpha) { auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossy-uncompressed-alpha.webp"sv))); diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp index 56b9c3854c..5e2417c1b4 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp @@ -276,7 +276,6 @@ static ErrorOr decode_webp_chunk_ALPH(Chunk const& alph_chunk, Bitmap& bit // "Method 1: predictor = A" // "The top-left value at location (0, 0) uses 0 as predictor value. Otherwise, // For horizontal or gradient filtering methods, the left-most pixels at location (0, y) are predicted using the location (0, y-1) just above." - // FIXME: This branch is untested. for (int y = 1; y < bitmap.height(); ++y) alpha[y * bitmap.width()] += alpha[(y - 1) * bitmap.width()]; for (int y = 0; y < bitmap.height(); ++y) {