diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp index 5d01b459197..b57ba6a97ca 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp @@ -67,15 +67,6 @@ static ErrorOr write_VP8L_header(Stream& stream, unsigned width, unsigned return {}; } -static bool are_all_pixels_opaque(Bitmap const& bitmap) -{ - for (ARGB32 pixel : bitmap) { - if ((pixel >> 24) != 0xff) - return false; - } - return true; -} - // FIXME: Consider using LibRIFF for RIFF writing details. (It currently has no writing support.) static ErrorOr align_to_two(Stream& stream, size_t number_of_bytes_written) { @@ -190,11 +181,11 @@ static ErrorOr align_to_two(AllocatingMemoryStream& stream) ErrorOr WebPWriter::encode(Stream& stream, Bitmap const& bitmap, Options const& options) { - bool alpha_is_used_hint = !are_all_pixels_opaque(bitmap); - dbgln_if(WEBP_DEBUG, "Writing WebP of size {} with alpha hint: {}", bitmap.size(), alpha_is_used_hint); - // The chunk headers need to know their size, so we either need a SeekableStream or need to buffer the data. We're doing the latter. - auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap)); + bool is_fully_opaque; + auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap, is_fully_opaque)); + bool alpha_is_used_hint = !is_fully_opaque; + dbgln_if(WEBP_DEBUG, "Writing WebP of size {} with alpha hint: {}", bitmap.size(), alpha_is_used_hint); ByteBuffer vp8x_chunk_bytes; ByteBuffer iccp_chunk_bytes; @@ -315,7 +306,8 @@ ErrorOr WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In // Since we have a SeekableStream, we could write both the VP8L chunk header and the ANMF chunk header with a placeholder size, // compress the frame data directly to the stream, and then go back and update the two sizes. // That's pretty messy though, and the compressed image data is smaller than the uncompressed bitmap passed in. So we'll buffer it. - auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap)); + bool is_fully_opaque; + auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap, is_fully_opaque)); ANMFChunkHeader chunk; chunk.frame_x = static_cast(at.x()); @@ -331,7 +323,7 @@ ErrorOr WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In TRY(update_size_in_header()); - if (!(m_vp8x_flags & 0x10) && !are_all_pixels_opaque(bitmap)) + if (!(m_vp8x_flags & 0x10) && !is_fully_opaque) TRY(set_alpha_bit_in_header()); return {}; diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.cpp index cb1813969bf..3ad7a74cc7a 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.cpp @@ -213,7 +213,7 @@ static ErrorOr write_normal_code_lengths(LittleEndianOutputBitStr return CanonicalCode::from_bytes(bit_lengths.span().trim(code_count)); } -static ErrorOr write_VP8L_image_data(Stream& stream, Bitmap const& bitmap) +static ErrorOr write_VP8L_image_data(Stream& stream, Bitmap const& bitmap, bool& is_fully_opaque) { LittleEndianOutputBitStream bit_stream { MaybeOwned(stream) }; @@ -291,6 +291,9 @@ static ErrorOr write_VP8L_image_data(Stream& stream, Bitmap const& bitmap) prefix_code_group[i] = TRY(write_simple_code_lengths(bit_stream, { symbols, non_zero_symbol_count })); else prefix_code_group[i] = TRY(write_normal_code_lengths(bit_stream, code_lengths[i], alphabet_sizes[i])); + + if (i == 3) + is_fully_opaque = non_zero_symbol_count == 1 && symbols[0] == 0xff; } // For code #5, use a simple empty code, since we don't use this yet. @@ -306,10 +309,10 @@ static ErrorOr write_VP8L_image_data(Stream& stream, Bitmap const& bitmap) return {}; } -ErrorOr compress_VP8L_image_data(Bitmap const& bitmap) +ErrorOr compress_VP8L_image_data(Bitmap const& bitmap, bool& is_fully_opaque) { AllocatingMemoryStream vp8l_data_stream; - TRY(write_VP8L_image_data(vp8l_data_stream, bitmap)); + TRY(write_VP8L_image_data(vp8l_data_stream, bitmap, is_fully_opaque)); return vp8l_data_stream.read_until_eof(); } diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.h b/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.h index 4041c4b6752..bba42f9046e 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.h +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPWriterLossless.h @@ -11,6 +11,6 @@ namespace Gfx { -ErrorOr compress_VP8L_image_data(Bitmap const&); +ErrorOr compress_VP8L_image_data(Bitmap const&, bool& is_fully_opaque); }