Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibCompress/DeflateTables.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Array.h>
10
#include <stdint.h>
11
12
namespace Compress {
13
14
// RFC 1951 - 3.2.5
15
static constexpr struct {
16
    u16 symbol;
17
    u16 base_length;
18
    u16 extra_bits;
19
} packed_length_symbols[29] = {
20
    { 257, 3, 0 },
21
    { 258, 4, 0 },
22
    { 259, 5, 0 },
23
    { 260, 6, 0 },
24
    { 261, 7, 0 },
25
    { 262, 8, 0 },
26
    { 263, 9, 0 },
27
    { 264, 10, 0 },
28
    { 265, 11, 1 },
29
    { 266, 13, 1 },
30
    { 267, 15, 1 },
31
    { 268, 17, 1 },
32
    { 269, 19, 2 },
33
    { 270, 23, 2 },
34
    { 271, 27, 2 },
35
    { 272, 31, 2 },
36
    { 273, 35, 3 },
37
    { 274, 43, 3 },
38
    { 275, 51, 3 },
39
    { 276, 59, 3 },
40
    { 277, 67, 4 },
41
    { 278, 83, 4 },
42
    { 279, 99, 4 },
43
    { 280, 115, 4 },
44
    { 281, 131, 5 },
45
    { 282, 163, 5 },
46
    { 283, 195, 5 },
47
    { 284, 227, 5 },
48
    { 285, 258, 0 }
49
};
50
51
// RFC 1951 - 3.2.5
52
static constexpr struct {
53
    u16 symbol;
54
    u16 base_distance;
55
    u16 extra_bits;
56
} packed_distances[31] = {
57
    { 0, 1, 0 },
58
    { 1, 2, 0 },
59
    { 2, 3, 0 },
60
    { 3, 4, 0 },
61
    { 4, 5, 1 },
62
    { 5, 7, 1 },
63
    { 6, 9, 2 },
64
    { 7, 13, 2 },
65
    { 8, 17, 3 },
66
    { 9, 25, 3 },
67
    { 10, 33, 4 },
68
    { 11, 49, 4 },
69
    { 12, 65, 5 },
70
    { 13, 97, 5 },
71
    { 14, 129, 6 },
72
    { 15, 193, 6 },
73
    { 16, 257, 7 },
74
    { 17, 385, 7 },
75
    { 18, 513, 8 },
76
    { 19, 769, 8 },
77
    { 20, 1025, 9 },
78
    { 21, 1537, 9 },
79
    { 22, 2049, 10 },
80
    { 23, 3073, 10 },
81
    { 24, 4097, 11 },
82
    { 25, 6145, 11 },
83
    { 26, 8193, 12 },
84
    { 27, 12289, 12 },
85
    { 28, 16385, 13 },
86
    { 29, 24577, 13 },
87
    { 30, 32 * KiB + 1, 0 }, // signifies end
88
};
89
90
// RFC 1951 - 3.2.6
91
static constexpr struct {
92
    u16 base_value;
93
    u16 bits;
94
} fixed_literal_bits[5] = {
95
    { 0, 8 },
96
    { 144, 9 },
97
    { 256, 7 },
98
    { 280, 8 },
99
    { 288, 0 } // signifies end
100
};
101
102
// RFC 1951 - 3.2.7
103
static constexpr size_t code_lengths_code_lengths_order[] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
104
105
static consteval Array<u16, 259> generate_length_to_symbol()
106
{
107
    Array<u16, 259> array = { UINT16_MAX, UINT16_MAX, UINT16_MAX }; // there are 256 valid lengths (3-258) + 3 invalid lengths (0-2)
108
    size_t base_length = 0;
109
    for (size_t len = 3; len < 259; len++) {
110
        if (len == packed_length_symbols[base_length + 1].base_length)
111
            base_length++;
112
        array[len] = packed_length_symbols[base_length].symbol;
113
    }
114
    return array;
115
}
116
static constexpr auto length_to_symbol = generate_length_to_symbol();
117
118
static consteval Array<u16, 256> generate_distance_to_base_lo()
119
{
120
    Array<u16, 256> array;
121
    size_t base_distance = 0;
122
    for (size_t dist = 1; dist <= 256; dist++) {
123
        if (dist == packed_distances[base_distance + 1].base_distance)
124
            base_distance++;
125
        array[dist - 1] = packed_distances[base_distance].symbol;
126
    }
127
    return array;
128
}
129
static constexpr auto distance_to_base_lo = generate_distance_to_base_lo();
130
static consteval Array<u16, 256> generate_distance_to_base_hi()
131
{
132
    Array<u16, 256> array = { UINT16_MAX, UINT16_MAX };
133
    size_t base_distance = 16;
134
    for (size_t dist = 257; dist <= 32 * KiB; dist++) {
135
        if (dist == packed_distances[base_distance + 1].base_distance)
136
            base_distance++;
137
        array[(dist - 1) >> 7] = packed_distances[base_distance].symbol;
138
    }
139
    return array;
140
}
141
static constexpr auto distance_to_base_hi = generate_distance_to_base_hi();
142
143
static consteval Array<u8, 288> generate_fixed_literal_bit_lengths()
144
{
145
    Array<u8, 288> array;
146
    for (size_t i = 0; i < 4; i++) {
147
        array.span().slice(fixed_literal_bits[i].base_value, fixed_literal_bits[i + 1].base_value - fixed_literal_bits[i].base_value).fill(fixed_literal_bits[i].bits);
148
    }
149
    return array;
150
}
151
static constexpr auto fixed_literal_bit_lengths = generate_fixed_literal_bit_lengths();
152
153
static consteval Array<u8, 32> generate_fixed_distance_bit_lengths()
154
{
155
    Array<u8, 32> array;
156
    array.fill(5);
157
    return array;
158
}
159
static constexpr auto fixed_distance_bit_lengths = generate_fixed_distance_bit_lengths();
160
161
static consteval u8 reverse8(u8 value)
162
{
163
    u8 result = 0;
164
    for (size_t i = 0; i < 8; i++) {
165
        if (value & (1 << i))
166
            result |= 1 << (7 - i);
167
    }
168
    return result;
169
}
170
static consteval Array<u8, UINT8_MAX + 1> generate_reverse8_lookup_table()
171
{
172
    Array<u8, UINT8_MAX + 1> array;
173
    for (size_t i = 0; i <= UINT8_MAX; i++) {
174
        array[i] = reverse8(i);
175
    }
176
    return array;
177
}
178
static constexpr auto reverse8_lookup_table = generate_reverse8_lookup_table();
179
180
// Lookup-table based bit swap
181
ALWAYS_INLINE static u16 fast_reverse16(u16 value, size_t bits)
182
25.8M
{
183
25.8M
    VERIFY(bits <= 16);
184
185
25.8M
    u16 lo = value & 0xff;
186
25.8M
    u16 hi = value >> 8;
187
188
25.8M
    u16 reversed = (u16)((reverse8_lookup_table[lo] << 8) | reverse8_lookup_table[hi]);
189
190
25.8M
    return reversed >> (16 - bits);
191
25.8M
}
Unexecuted instantiation: WebPLoaderLossless.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: WebPSharedLossless.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Deflate.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Line
Count
Source
182
25.8M
{
183
25.8M
    VERIFY(bits <= 16);
184
185
25.8M
    u16 lo = value & 0xff;
186
25.8M
    u16 hi = value >> 8;
187
188
25.8M
    u16 reversed = (u16)((reverse8_lookup_table[lo] << 8) | reverse8_lookup_table[hi]);
189
190
25.8M
    return reversed >> (16 - bits);
191
25.8M
}
Unexecuted instantiation: Zlib.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: FuzzGzipRoundtrip.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: Gzip.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: Filter.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: FuzzGzipDecompression.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: Zip.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: FuzzDeflateCompression.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
Unexecuted instantiation: FuzzDeflateDecompression.cpp:Compress::fast_reverse16(unsigned short, unsigned long)
192
193
}