Coverage Report

Created: 2025-08-28 06:26

/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
}