mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
WebP/Lossless: Set alpha to 0xff if is_alpha_used is false in header
simple-vp8l-alpha-used-false.webp is a copy of simple-vp8l.webp,
with the byte at offset 0x18 changed from 0x10 to 0x00 -- that
is, the bit in the VP8L header that stores `is_alpha_used` is cleared.
We would already allocated a BGRx8888 instead of a BGRA8888 bitmap,
but keep actual alpha data in the `x` channel.
That lead to at least `image` still writing a PNG with an alpha channel.
So explicitly set the alpha channel to 0xff when is_alpha_used is false,
to make sure all consumers of decoded lossless webp data have behavior
consistent with other webp readers.
In practice, webp encoders usually don't write files that have
`is_alpha_used` set to false and then write actual alpha data to their
output. So this is rarely observable. However, for example for
lossy+ALPH webp files, the lossless webp used to store the ALPH channel
has `is_alpha_used` set to false and all channels but green are 0
(since the lossless green channel stores the alpha channel of a
lossy+ALPH webp). So if we dump such a bitmap to a standalone webp
file (e.g. with the temporary debugging code in fc3249a1ca
),
then without this commit here, `image` would convert that webp to
a fully transparent webp, while other webp software would correctly
display the green image with opaque alpha.
This commit is contained in:
parent
5e5493e334
commit
e19892a099
Notes:
sideshowbarker
2024-07-17 05:03:11 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/e19892a099 Pull-request: https://github.com/SerenityOS/serenity/pull/19464
3 changed files with 26 additions and 0 deletions
|
@ -342,10 +342,33 @@ TEST_CASE(test_webp_simple_lossless)
|
|||
auto frame = MUST(plugin_decoder->frame(0));
|
||||
EXPECT_EQ(frame.image->size(), Gfx::IntSize(386, 395));
|
||||
|
||||
EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color(0, 0, 0, 0));
|
||||
|
||||
// This pixel tests all predictor modes except 5, 7, 8, 9, and 13.
|
||||
EXPECT_EQ(frame.image->get_pixel(289, 332), Gfx::Color(0xf2, 0xee, 0xd3, 255));
|
||||
}
|
||||
|
||||
TEST_CASE(test_webp_simple_lossless_alpha_used_false)
|
||||
{
|
||||
// This file is identical to simple-vp8l.webp, but the `is_alpha_used` used bit is false.
|
||||
// The file still contains alpha data. This tests that the decoder replaces the stored alpha data with 0xff if `is_alpha_used` is false.
|
||||
auto file = MUST(Core::MappedFile::map(TEST_INPUT("simple-vp8l-alpha-used-false.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(386, 395));
|
||||
|
||||
auto frame = MUST(plugin_decoder->frame(0));
|
||||
EXPECT_EQ(frame.image->size(), Gfx::IntSize(386, 395));
|
||||
|
||||
EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color(0, 0, 0, 0xff));
|
||||
}
|
||||
|
||||
TEST_CASE(test_webp_extended_lossy)
|
||||
{
|
||||
// This extended lossy image has an ALPH chunk for (losslessly compressed) alpha data.
|
||||
|
|
BIN
Tests/LibGfx/test-inputs/simple-vp8l-alpha-used-false.webp
Normal file
BIN
Tests/LibGfx/test-inputs/simple-vp8l-alpha-used-false.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -1000,6 +1000,9 @@ ErrorOr<NonnullRefPtr<Bitmap>> decode_webp_chunk_VP8L_contents(VP8LHeader const&
|
|||
for (auto const& transform : transforms.in_reverse())
|
||||
bitmap = TRY(transform->transform(bitmap));
|
||||
|
||||
if (!vp8l_header.is_alpha_used)
|
||||
bitmap->strip_alpha_channel();
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue