summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp')
-rw-r--r--Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp82
1 files changed, 1 insertions, 81 deletions
diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp
index b5cc00e55b..e5b9715d47 100644
--- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp
+++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp
@@ -11,11 +11,11 @@
#include <AK/Vector.h>
#include <LibGfx/ImageFormats/WebPLoader.h>
#include <LibGfx/ImageFormats/WebPLoaderLossless.h>
+#include <LibGfx/ImageFormats/WebPLoaderLossy.h>
#include <LibGfx/Painter.h>
// Overview: https://developers.google.com/speed/webp/docs/compression
// Container: https://developers.google.com/speed/webp/docs/riff_container
-// Lossy format: https://datatracker.ietf.org/doc/html/rfc6386
namespace Gfx {
@@ -55,17 +55,6 @@ struct Chunk {
ReadonlyBytes data;
};
-struct VP8Header {
- u8 version;
- bool show_frame;
- u32 size_of_first_partition;
- u32 width;
- u8 horizontal_scale;
- u32 height;
- u8 vertical_scale;
- ReadonlyBytes lossy_data;
-};
-
struct VP8XHeader {
bool has_icc;
bool has_alpha;
@@ -228,75 +217,6 @@ static ErrorOr<Chunk> decode_webp_advance_chunk(ReadonlyBytes& chunks)
return chunk;
}
-// 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(ReadonlyBytes vp8_data)
-{
- if (vp8_data.size() < 10)
- return Error::from_string_literal("WebPImageDecoderPlugin: 'VP8 ' chunk too small");
-
- // FIXME: Eventually, this should probably call into LibVideo/VP8,
- // and image decoders should move into LibImageDecoders which depends on both LibGfx and LibVideo.
- // (LibVideo depends on LibGfx, so LibGfx can't depend on LibVideo itself.)
-
- // https://datatracker.ietf.org/doc/html/rfc6386#section-4 "Overview of Compressed Data Format"
- // "The decoder is simply presented with a sequence of compressed frames [...]
- // 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_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);
- bool is_key_frame = (frame_tag & 1) == 0; // https://www.rfc-editor.org/errata/eid5534
- u8 version = (frame_tag & 0xe) >> 1;
- bool show_frame = (frame_tag & 0x10) != 0;
- u32 size_of_first_partition = frame_tag >> 5;
-
- if (!is_key_frame)
- return Error::from_string_literal("WebPImageDecoderPlugin: 'VP8 ' chunk not a key frame");
-
- // FIXME: !show_frame does not make sense in a webp file either, probably?
-
- u32 start_code = data[3] | (data[4] << 8) | (data[5] << 16);
- if (start_code != 0x2a019d) // https://www.rfc-editor.org/errata/eid7370
- return Error::from_string_literal("WebPImageDecoderPlugin: 'VP8 ' chunk invalid start_code");
-
- // "The scaling specifications for each dimension are encoded as follows.
- // 0 | No upscaling (the most common case).
- // 1 | Upscale by 5/4.
- // 2 | Upscale by 5/3.
- // 3 | Upscale by 2."
- // This is a display-time operation and doesn't affect decoding.
- u16 width_and_horizontal_scale = data[6] | (data[7] << 8);
- u16 width = width_and_horizontal_scale & 0x3fff;
- u8 horizontal_scale = width_and_horizontal_scale >> 14;
-
- u16 heigth_and_vertical_scale = data[8] | (data[9] << 8);
- u16 height = heigth_and_vertical_scale & 0x3fff;
- u8 vertical_scale = heigth_and_vertical_scale >> 14;
-
- 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, vp8_data.slice(10) };
-}
-
-static ErrorOr<NonnullRefPtr<Bitmap>> decode_webp_chunk_VP8_contents(VP8Header const& vp8_header, bool include_alpha_channel)
-{
- 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
- 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
-}
-
// https://developers.google.com/speed/webp/docs/riff_container#alpha
static ErrorOr<void> decode_webp_chunk_ALPH(Chunk const& alph_chunk, Bitmap& bitmap)
{