/src/serenity/Userland/Libraries/LibGfx/ImageFormats/WebPSharedLossless.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2024, Nico Weber <thakis@chromium.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <LibCompress/Deflate.h> |
10 | | |
11 | | namespace Gfx { |
12 | | |
13 | | constexpr Array kCodeLengthCodeOrder = { 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
14 | | |
15 | | // WebP-lossless's CanonicalCodes are almost identical to deflate's. |
16 | | // One difference is that codes with a single element in webp-lossless consume 0 bits to produce that single element, |
17 | | // while they consume 1 bit in Compress::CanonicalCode. This class wraps Compress::CanonicalCode to handle the case |
18 | | // where the codes contain just a single element, and dispatches to Compress::CanonicalCode else. |
19 | | class CanonicalCode { |
20 | | public: |
21 | 222k | CanonicalCode() = default; |
22 | | |
23 | | static ErrorOr<CanonicalCode> from_bytes(ReadonlyBytes); |
24 | | ErrorOr<u32> read_symbol(LittleEndianInputBitStream&) const; |
25 | | ErrorOr<void> write_symbol(LittleEndianOutputBitStream&, u32) const; |
26 | | |
27 | | private: |
28 | | explicit CanonicalCode(u32 single_symbol) |
29 | 216k | : m_code(single_symbol) |
30 | 216k | { |
31 | 216k | } |
32 | | |
33 | | explicit CanonicalCode(Compress::CanonicalCode code) |
34 | 4.57k | : m_code(move(code)) |
35 | 4.57k | { |
36 | 4.57k | } |
37 | | |
38 | | Variant<u32, Compress::CanonicalCode> m_code { 0 }; |
39 | | }; |
40 | | |
41 | | ALWAYS_INLINE ErrorOr<void> CanonicalCode::write_symbol(LittleEndianOutputBitStream& bit_stream, u32 symbol) const |
42 | 0 | { |
43 | 0 | TRY(m_code.visit( |
44 | 0 | [&](u32 single_code) __attribute__((always_inline))->ErrorOr<void> { VERIFY(symbol == single_code); return {}; }, |
45 | 0 | [&](Compress::CanonicalCode const& code) __attribute__((always_inline)) { return code.write_symbol(bit_stream, symbol); })); |
46 | 0 | return {}; |
47 | 0 | } |
48 | | |
49 | | // https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#61_overview |
50 | | // "From here on, we refer to this set as a prefix code group." |
51 | | class PrefixCodeGroup { |
52 | | public: |
53 | 44.5k | PrefixCodeGroup() = default; |
54 | 315k | PrefixCodeGroup(PrefixCodeGroup&&) = default; |
55 | | PrefixCodeGroup(PrefixCodeGroup const&) = delete; |
56 | | |
57 | 220k | CanonicalCode& operator[](int i) { return m_codes[i]; } |
58 | 4.42G | CanonicalCode const& operator[](int i) const { return m_codes[i]; } |
59 | | |
60 | | private: |
61 | | Array<CanonicalCode, 5> m_codes; |
62 | | }; |
63 | | |
64 | | enum class ImageKind { |
65 | | SpatiallyCoded, |
66 | | EntropyCoded, |
67 | | }; |
68 | | |
69 | | enum TransformType { |
70 | | // predictor-tx = %b00 predictor-image |
71 | | PREDICTOR_TRANSFORM = 0, |
72 | | |
73 | | // color-tx = %b01 color-image |
74 | | COLOR_TRANSFORM = 1, |
75 | | |
76 | | // subtract-green-tx = %b10 |
77 | | SUBTRACT_GREEN_TRANSFORM = 2, |
78 | | |
79 | | // color-indexing-tx = %b11 color-indexing-image |
80 | | COLOR_INDEXING_TRANSFORM = 3, |
81 | | }; |
82 | | |
83 | | } |