diff options
author | Nico Weber <thakis@chromium.org> | 2023-05-08 00:40:44 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-09 06:35:56 +0200 |
commit | 83da7ad875d8b0b5e09d8f6661a4ff7d708e07d6 (patch) | |
tree | 2cb17a16af29733bda2454efe535e8338e89397d | |
parent | d15dc28833a9f7344a8b7bdede18c057c5493fbc (diff) | |
download | serenity-83da7ad875d8b0b5e09d8f6661a4ff7d708e07d6.zip |
LibGfx/WebP: Give VP8 decoding functions same interface as VP8L ones
Namely:
* Store compressed data in VP8Header
* Make the functions just take ReadonlyBytes instead of a Chunk
Having a function that takes a header and does decoding of the data
after the header isn't really necessary for VP8. For VP8L, it's needed
because the ALPH chunk stores VP8L data without the VP8L header.
But it's nice to make the functions consistent, and it's kind of a
nice structure.
No behavior change.
-rw-r--r-- | Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp index d3be4e4630..b5cc00e55b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp @@ -63,6 +63,7 @@ struct VP8Header { u8 horizontal_scale; u32 height; u8 vertical_scale; + ReadonlyBytes lossy_data; }; struct VP8XHeader { @@ -229,11 +230,9 @@ static ErrorOr<Chunk> decode_webp_advance_chunk(ReadonlyBytes& chunks) // https://developers.google.com/speed/webp/docs/riff_container#simple_file_format_lossy // https://datatracker.ietf.org/doc/html/rfc6386#section-19 "Annex A: Bitstream Syntax" -static ErrorOr<VP8Header> decode_webp_chunk_VP8_header(Chunk const& vp8_chunk) +static ErrorOr<VP8Header> decode_webp_chunk_VP8_header(ReadonlyBytes vp8_data) { - VERIFY(vp8_chunk.type == FourCC("VP8 ")); - - if (vp8_chunk.data.size() < 10) + if (vp8_data.size() < 10) return Error::from_string_literal("WebPImageDecoderPlugin: 'VP8 ' chunk too small"); // FIXME: Eventually, this should probably call into LibVideo/VP8, @@ -245,7 +244,7 @@ static ErrorOr<VP8Header> decode_webp_chunk_VP8_header(Chunk const& vp8_chunk) // The first frame presented to the decompressor is [...] a key frame. [...] // [E]very compressed frame has three or more pieces. It begins with an uncompressed data chunk comprising 10 bytes in the case of key frames - u8 const* data = vp8_chunk.data.data(); + u8 const* data = vp8_data.data(); // https://datatracker.ietf.org/doc/html/rfc6386#section-9.1 "Uncompressed Data Chunk" u32 frame_tag = data[0] | (data[1] << 8) | (data[2] << 16); @@ -280,20 +279,19 @@ static ErrorOr<VP8Header> decode_webp_chunk_VP8_header(Chunk const& vp8_chunk) dbgln_if(WEBP_DEBUG, "version {}, show_frame {}, size_of_first_partition {}, width {}, horizontal_scale {}, height {}, vertical_scale {}", version, show_frame, size_of_first_partition, width, horizontal_scale, height, vertical_scale); - return VP8Header { version, show_frame, size_of_first_partition, width, horizontal_scale, height, vertical_scale }; + return VP8Header { version, show_frame, size_of_first_partition, width, horizontal_scale, height, vertical_scale, vp8_data.slice(10) }; } -static ErrorOr<NonnullRefPtr<Bitmap>> decode_webp_chunk_VP8(Chunk const& vp8_chunk, bool include_alpha_channel) +static ErrorOr<NonnullRefPtr<Bitmap>> decode_webp_chunk_VP8_contents(VP8Header const& vp8_header, bool include_alpha_channel) { - VERIFY(vp8_chunk.type == FourCC("VP8 ")); auto bitmap_format = include_alpha_channel ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888; // Uncomment this to test ALPH decoding for WebP-lossy-with-alpha images while lossy decoding isn't implemented yet. #if 0 - auto vp8_header = TRY(decode_webp_chunk_VP8_header(vp8_chunk)); return Bitmap::create(bitmap_format, { vp8_header.width, vp8_header.height }); #else // FIXME: Implement webp lossy decoding. + (void)vp8_header; (void)bitmap_format; return Error::from_string_literal("WebPImageDecoderPlugin: decoding lossy webps not yet implemented"); #endif @@ -566,7 +564,7 @@ static ErrorOr<void> decode_webp_first_chunk(WebPLoadingContext& context) TRY(read_webp_first_chunk(context)); if (context.first_chunk->type == FourCC("VP8 ")) { - auto vp8_header = TRY(decode_webp_chunk_VP8_header(context.first_chunk.value())); + auto vp8_header = TRY(decode_webp_chunk_VP8_header(context.first_chunk->data)); context.size = IntSize { vp8_header.width, vp8_header.height }; context.state = WebPLoadingContext::State::FirstChunkDecoded; return {}; @@ -641,7 +639,8 @@ static ErrorOr<NonnullRefPtr<Bitmap>> decode_webp_image_data(ImageData const& im } VERIFY(image_data.image_data_chunk.type == FourCC("VP8 ")); - auto bitmap = TRY(decode_webp_chunk_VP8(image_data.image_data_chunk, image_data.alpha_chunk.has_value())); + auto vp8_header = TRY(decode_webp_chunk_VP8_header(image_data.image_data_chunk.data)); + auto bitmap = TRY(decode_webp_chunk_VP8_contents(vp8_header, image_data.alpha_chunk.has_value())); if (image_data.alpha_chunk.has_value()) TRY(decode_webp_chunk_ALPH(image_data.alpha_chunk.value(), *bitmap)); |