Coverage Report

Created: 2026-02-14 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibGfx/ImageFormats/JPEGWriterTables.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Vector.h>
10
11
namespace Gfx {
12
13
struct QuantizationTable {
14
    Array<u8, 64> table {};
15
    u8 id {};
16
};
17
18
// K.1 - Quantization tables for luminance and chrominance components
19
20
// clang-format off
21
constexpr static QuantizationTable s_default_luminance_quantization_table {
22
    .table = {
23
        16, 11, 10, 16, 124, 140, 151, 161,
24
        12, 12, 14, 19, 126, 158, 160, 155,
25
        14, 13, 16, 24, 140, 157, 169, 156,
26
        14, 17, 22, 29, 151, 187, 180, 162,
27
        18, 22, 37, 56, 168, 109, 103, 177,
28
        24, 35, 55, 64, 181, 104, 113, 192,
29
        49, 64, 78, 87, 103, 121, 120, 101,
30
        72, 92, 95, 98, 112, 100, 103, 199,
31
    },
32
    .id = 0,
33
};
34
35
constexpr static QuantizationTable s_default_chrominance_quantization_table {
36
    .table = {
37
        17, 18, 24, 47, 99, 99, 99, 99,
38
        18, 21, 26, 66, 99, 99, 99, 99,
39
        24, 26, 56, 99, 99, 99, 99, 99,
40
        47, 66, 99, 99, 99, 99, 99, 99,
41
        99, 99, 99, 99, 99, 99, 99, 99,
42
        99, 99, 99, 99, 99, 99, 99, 99,
43
        99, 99, 99, 99, 99, 99, 99, 99,
44
        99, 99, 99, 99, 99, 99, 99, 99,
45
    },
46
    .id = 1,
47
};
48
49
constexpr static QuantizationTable s_dummy_quantization_table {
50
    .table = {
51
        1, 1, 1, 1, 1, 1, 1, 1,
52
        1, 1, 1, 1, 1, 1, 1, 1,
53
        1, 1, 1, 1, 1, 1, 1, 1,
54
        1, 1, 1, 1, 1, 1, 1, 1,
55
        1, 1, 1, 1, 1, 1, 1, 1,
56
        1, 1, 1, 1, 1, 1, 1, 1,
57
        1, 1, 1, 1, 1, 1, 1, 1,
58
        1, 1, 1, 1, 1, 1, 1, 1,
59
    },
60
    .id = 1,
61
};
62
63
// clang-format on
64
65
struct OutputHuffmanTable {
66
    struct Symbol {
67
        u8 input_byte {};
68
        u8 code_length {};
69
        u16 word {};
70
    };
71
72
    Symbol from_input_byte(u8 input_byte) const
73
0
    {
74
0
        for (auto symbol : table) {
75
0
            if (symbol.input_byte == input_byte)
76
0
                return symbol;
77
0
        }
78
0
        VERIFY_NOT_REACHED();
79
0
    }
80
81
    Vector<Symbol, 16> table {};
82
    u8 id {};
83
};
84
85
static OutputHuffmanTable s_default_dc_luminance_huffman_table {
86
    .table = {
87
        { 0, 2, 0b00 },
88
        { 1, 3, 0b010 },
89
        { 2, 3, 0b011 },
90
        { 3, 3, 0b100 },
91
        { 4, 3, 0b101 },
92
        { 5, 3, 0b110 },
93
        { 6, 4, 0b1110 },
94
        { 7, 5, 0b11110 },
95
        { 8, 6, 0b111110 },
96
        { 9, 7, 0b1111110 },
97
        { 10, 8, 0b11111110 },
98
        { 11, 9, 0b111111110 },
99
    },
100
    .id = (0 << 4) | 0,
101
};
102
103
static OutputHuffmanTable s_default_dc_chrominance_huffman_table {
104
    .table = {
105
        { 0, 2, 0b00 },
106
        { 1, 2, 0b01 },
107
        { 2, 2, 0b10 },
108
        { 3, 3, 0b110 },
109
        { 4, 4, 0b1110 },
110
        { 5, 5, 0b11110 },
111
        { 6, 6, 0b111110 },
112
        { 7, 7, 0b1111110 },
113
        { 8, 8, 0b11111110 },
114
        { 9, 9, 0b111111110 },
115
        { 10, 10, 0b1111111110 },
116
        { 11, 11, 0b11111111110 },
117
    },
118
    .id = (0 << 4) | 1,
119
};
120
121
static OutputHuffmanTable s_default_ac_luminance_huffman_table {
122
    .table = {
123
        { 0x01, 2, 0b00 },
124
        { 0x02, 2, 0b01 },
125
        { 0x03, 3, 0b100 },
126
        { 0x00, 4, 0b1010 },
127
        { 0x04, 4, 0b1011 },
128
        { 0x11, 4, 0b1100 },
129
        { 0x05, 5, 0b11010 },
130
        { 0x12, 5, 0b11011 },
131
        { 0x21, 5, 0b11100 },
132
        { 0x31, 6, 0b111010 },
133
        { 0x41, 6, 0b111011 },
134
        { 0x06, 7, 0b1111000 },
135
        { 0x13, 7, 0b1111001 },
136
        { 0x51, 7, 0b1111010 },
137
        { 0x61, 7, 0b1111011 },
138
        { 0x07, 8, 0b11111000 },
139
        { 0x22, 8, 0b11111001 },
140
        { 0x71, 8, 0b11111010 },
141
        { 0x14, 9, 0b111110110 },
142
        { 0x32, 9, 0b111110111 },
143
        { 0x81, 9, 0b111111000 },
144
        { 0x91, 9, 0b111111001 },
145
        { 0xA1, 9, 0b111111010 },
146
        { 0x08, 10, 0b1111110110 },
147
        { 0x23, 10, 0b1111110111 },
148
        { 0x42, 10, 0b1111111000 },
149
        { 0xB1, 10, 0b1111111001 },
150
        { 0xC1, 10, 0b1111111010 },
151
        { 0x15, 11, 0b11111110110 },
152
        { 0x52, 11, 0b11111110111 },
153
        { 0xD1, 11, 0b11111111000 },
154
        { 0xF0, 11, 0b11111111001 },
155
        { 0x24, 12, 0b111111110100 },
156
        { 0x33, 12, 0b111111110101 },
157
        { 0x62, 12, 0b111111110110 },
158
        { 0x72, 12, 0b111111110111 },
159
        { 0x82, 15, 0b111111111000000 },
160
        { 0x09, 16, 0b1111111110000010 },
161
        { 0x0A, 16, 0b1111111110000011 },
162
        { 0x16, 16, 0b1111111110000100 },
163
        { 0x17, 16, 0b1111111110000101 },
164
        { 0x18, 16, 0b1111111110000110 },
165
        { 0x19, 16, 0b1111111110000111 },
166
        { 0x1A, 16, 0b1111111110001000 },
167
        { 0x25, 16, 0b1111111110001001 },
168
        { 0x26, 16, 0b1111111110001010 },
169
        { 0x27, 16, 0b1111111110001011 },
170
        { 0x28, 16, 0b1111111110001100 },
171
        { 0x29, 16, 0b1111111110001101 },
172
        { 0x2A, 16, 0b1111111110001110 },
173
        { 0x34, 16, 0b1111111110001111 },
174
        { 0x35, 16, 0b1111111110010000 },
175
        { 0x36, 16, 0b1111111110010001 },
176
        { 0x37, 16, 0b1111111110010010 },
177
        { 0x38, 16, 0b1111111110010011 },
178
        { 0x39, 16, 0b1111111110010100 },
179
        { 0x3A, 16, 0b1111111110010101 },
180
        { 0x43, 16, 0b1111111110010110 },
181
        { 0x44, 16, 0b1111111110010111 },
182
        { 0x45, 16, 0b1111111110011000 },
183
        { 0x46, 16, 0b1111111110011001 },
184
        { 0x47, 16, 0b1111111110011010 },
185
        { 0x48, 16, 0b1111111110011011 },
186
        { 0x49, 16, 0b1111111110011100 },
187
        { 0x4A, 16, 0b1111111110011101 },
188
        { 0x53, 16, 0b1111111110011110 },
189
        { 0x54, 16, 0b1111111110011111 },
190
        { 0x55, 16, 0b1111111110100000 },
191
        { 0x56, 16, 0b1111111110100001 },
192
        { 0x57, 16, 0b1111111110100010 },
193
        { 0x58, 16, 0b1111111110100011 },
194
        { 0x59, 16, 0b1111111110100100 },
195
        { 0x5A, 16, 0b1111111110100101 },
196
        { 0x63, 16, 0b1111111110100110 },
197
        { 0x64, 16, 0b1111111110100111 },
198
        { 0x65, 16, 0b1111111110101000 },
199
        { 0x66, 16, 0b1111111110101001 },
200
        { 0x67, 16, 0b1111111110101010 },
201
        { 0x68, 16, 0b1111111110101011 },
202
        { 0x69, 16, 0b1111111110101100 },
203
        { 0x6A, 16, 0b1111111110101101 },
204
        { 0x73, 16, 0b1111111110101110 },
205
        { 0x74, 16, 0b1111111110101111 },
206
        { 0x75, 16, 0b1111111110110000 },
207
        { 0x76, 16, 0b1111111110110001 },
208
        { 0x77, 16, 0b1111111110110010 },
209
        { 0x78, 16, 0b1111111110110011 },
210
        { 0x79, 16, 0b1111111110110100 },
211
        { 0x7A, 16, 0b1111111110110101 },
212
        { 0x83, 16, 0b1111111110110110 },
213
        { 0x84, 16, 0b1111111110110111 },
214
        { 0x85, 16, 0b1111111110111000 },
215
        { 0x86, 16, 0b1111111110111001 },
216
        { 0x87, 16, 0b1111111110111010 },
217
        { 0x88, 16, 0b1111111110111011 },
218
        { 0x89, 16, 0b1111111110111100 },
219
        { 0x8A, 16, 0b1111111110111101 },
220
        { 0x92, 16, 0b1111111110111110 },
221
        { 0x93, 16, 0b1111111110111111 },
222
        { 0x94, 16, 0b1111111111000000 },
223
        { 0x95, 16, 0b1111111111000001 },
224
        { 0x96, 16, 0b1111111111000010 },
225
        { 0x97, 16, 0b1111111111000011 },
226
        { 0x98, 16, 0b1111111111000100 },
227
        { 0x99, 16, 0b1111111111000101 },
228
        { 0x9A, 16, 0b1111111111000110 },
229
        { 0xA2, 16, 0b1111111111000111 },
230
        { 0xA3, 16, 0b1111111111001000 },
231
        { 0xA4, 16, 0b1111111111001001 },
232
        { 0xA5, 16, 0b1111111111001010 },
233
        { 0xA6, 16, 0b1111111111001011 },
234
        { 0xA7, 16, 0b1111111111001100 },
235
        { 0xA8, 16, 0b1111111111001101 },
236
        { 0xA9, 16, 0b1111111111001110 },
237
        { 0xAA, 16, 0b1111111111001111 },
238
        { 0xB2, 16, 0b1111111111010000 },
239
        { 0xB3, 16, 0b1111111111010001 },
240
        { 0xB4, 16, 0b1111111111010010 },
241
        { 0xB5, 16, 0b1111111111010011 },
242
        { 0xB6, 16, 0b1111111111010100 },
243
        { 0xB7, 16, 0b1111111111010101 },
244
        { 0xB8, 16, 0b1111111111010110 },
245
        { 0xB9, 16, 0b1111111111010111 },
246
        { 0xBA, 16, 0b1111111111011000 },
247
        { 0xC2, 16, 0b1111111111011001 },
248
        { 0xC3, 16, 0b1111111111011010 },
249
        { 0xC4, 16, 0b1111111111011011 },
250
        { 0xC5, 16, 0b1111111111011100 },
251
        { 0xC6, 16, 0b1111111111011101 },
252
        { 0xC7, 16, 0b1111111111011110 },
253
        { 0xC8, 16, 0b1111111111011111 },
254
        { 0xC9, 16, 0b1111111111100000 },
255
        { 0xCA, 16, 0b1111111111100001 },
256
        { 0xD2, 16, 0b1111111111100010 },
257
        { 0xD3, 16, 0b1111111111100011 },
258
        { 0xD4, 16, 0b1111111111100100 },
259
        { 0xD5, 16, 0b1111111111100101 },
260
        { 0xD6, 16, 0b1111111111100110 },
261
        { 0xD7, 16, 0b1111111111100111 },
262
        { 0xD8, 16, 0b1111111111101000 },
263
        { 0xD9, 16, 0b1111111111101001 },
264
        { 0xDA, 16, 0b1111111111101010 },
265
        { 0xE1, 16, 0b1111111111101011 },
266
        { 0xE2, 16, 0b1111111111101100 },
267
        { 0xE3, 16, 0b1111111111101101 },
268
        { 0xE4, 16, 0b1111111111101110 },
269
        { 0xE5, 16, 0b1111111111101111 },
270
        { 0xE6, 16, 0b1111111111110000 },
271
        { 0xE7, 16, 0b1111111111110001 },
272
        { 0xE8, 16, 0b1111111111110010 },
273
        { 0xE9, 16, 0b1111111111110011 },
274
        { 0xEA, 16, 0b1111111111110100 },
275
        { 0xF1, 16, 0b1111111111110101 },
276
        { 0xF2, 16, 0b1111111111110110 },
277
        { 0xF3, 16, 0b1111111111110111 },
278
        { 0xF4, 16, 0b1111111111111000 },
279
        { 0xF5, 16, 0b1111111111111001 },
280
        { 0xF6, 16, 0b1111111111111010 },
281
        { 0xF7, 16, 0b1111111111111011 },
282
        { 0xF8, 16, 0b1111111111111100 },
283
        { 0xF9, 16, 0b1111111111111101 },
284
        { 0xFA, 16, 0b1111111111111110 },
285
    },
286
    .id = (1 << 4) | 0,
287
};
288
289
static OutputHuffmanTable s_default_ac_chrominance_huffman_table {
290
    .table = {
291
        { 0x00, 2, 0b00 },
292
        { 0x01, 2, 0b01 },
293
        { 0x02, 3, 0b100 },
294
        { 0x03, 4, 0b1010 },
295
        { 0x11, 4, 0b1011 },
296
        { 0x04, 5, 0b11000 },
297
        { 0x05, 5, 0b11001 },
298
        { 0x21, 5, 0b11010 },
299
        { 0x31, 5, 0b11011 },
300
        { 0x06, 6, 0b111000 },
301
        { 0x12, 6, 0b111001 },
302
        { 0x41, 6, 0b111010 },
303
        { 0x51, 6, 0b111011 },
304
        { 0x07, 7, 0b1111000 },
305
        { 0x61, 7, 0b1111001 },
306
        { 0x71, 7, 0b1111010 },
307
        { 0x13, 8, 0b11110110 },
308
        { 0x22, 8, 0b11110111 },
309
        { 0x32, 8, 0b11111000 },
310
        { 0x81, 8, 0b11111001 },
311
        { 0x08, 9, 0b111110100 },
312
        { 0x14, 9, 0b111110101 },
313
        { 0x42, 9, 0b111110110 },
314
        { 0x91, 9, 0b111110111 },
315
        { 0xA1, 9, 0b111111000 },
316
        { 0xB1, 9, 0b111111001 },
317
        { 0xC1, 9, 0b111111010 },
318
        { 0x09, 10, 0b1111110110 },
319
        { 0x23, 10, 0b1111110111 },
320
        { 0x33, 10, 0b1111111000 },
321
        { 0x52, 10, 0b1111111001 },
322
        { 0xF0, 10, 0b1111111010 },
323
        { 0x15, 11, 0b11111110110 },
324
        { 0x62, 11, 0b11111110111 },
325
        { 0x72, 11, 0b11111111000 },
326
        { 0xD1, 11, 0b11111111001 },
327
        { 0x0A, 12, 0b111111110100 },
328
        { 0x16, 12, 0b111111110101 },
329
        { 0x24, 12, 0b111111110110 },
330
        { 0x34, 12, 0b111111110111 },
331
        { 0xE1, 14, 0b11111111100000 },
332
        { 0x25, 15, 0b111111111000010 },
333
        { 0xF1, 15, 0b111111111000011 },
334
        { 0x17, 16, 0b1111111110001000 },
335
        { 0x18, 16, 0b1111111110001001 },
336
        { 0x19, 16, 0b1111111110001010 },
337
        { 0x1A, 16, 0b1111111110001011 },
338
        { 0x26, 16, 0b1111111110001100 },
339
        { 0x27, 16, 0b1111111110001101 },
340
        { 0x28, 16, 0b1111111110001110 },
341
        { 0x29, 16, 0b1111111110001111 },
342
        { 0x2A, 16, 0b1111111110010000 },
343
        { 0x35, 16, 0b1111111110010001 },
344
        { 0x36, 16, 0b1111111110010010 },
345
        { 0x37, 16, 0b1111111110010011 },
346
        { 0x38, 16, 0b1111111110010100 },
347
        { 0x39, 16, 0b1111111110010101 },
348
        { 0x3A, 16, 0b1111111110010110 },
349
        { 0x43, 16, 0b1111111110010111 },
350
        { 0x44, 16, 0b1111111110011000 },
351
        { 0x45, 16, 0b1111111110011001 },
352
        { 0x46, 16, 0b1111111110011010 },
353
        { 0x47, 16, 0b1111111110011011 },
354
        { 0x48, 16, 0b1111111110011100 },
355
        { 0x49, 16, 0b1111111110011101 },
356
        { 0x4A, 16, 0b1111111110011110 },
357
        { 0x53, 16, 0b1111111110011111 },
358
        { 0x54, 16, 0b1111111110100000 },
359
        { 0x55, 16, 0b1111111110100001 },
360
        { 0x56, 16, 0b1111111110100010 },
361
        { 0x57, 16, 0b1111111110100011 },
362
        { 0x58, 16, 0b1111111110100100 },
363
        { 0x59, 16, 0b1111111110100101 },
364
        { 0x5A, 16, 0b1111111110100110 },
365
        { 0x63, 16, 0b1111111110100111 },
366
        { 0x64, 16, 0b1111111110101000 },
367
        { 0x65, 16, 0b1111111110101001 },
368
        { 0x66, 16, 0b1111111110101010 },
369
        { 0x67, 16, 0b1111111110101011 },
370
        { 0x68, 16, 0b1111111110101100 },
371
        { 0x69, 16, 0b1111111110101101 },
372
        { 0x6A, 16, 0b1111111110101110 },
373
        { 0x73, 16, 0b1111111110101111 },
374
        { 0x74, 16, 0b1111111110110000 },
375
        { 0x75, 16, 0b1111111110110001 },
376
        { 0x76, 16, 0b1111111110110010 },
377
        { 0x77, 16, 0b1111111110110011 },
378
        { 0x78, 16, 0b1111111110110100 },
379
        { 0x79, 16, 0b1111111110110101 },
380
        { 0x7A, 16, 0b1111111110110110 },
381
        { 0x82, 16, 0b1111111110110111 },
382
        { 0x83, 16, 0b1111111110111000 },
383
        { 0x84, 16, 0b1111111110111001 },
384
        { 0x85, 16, 0b1111111110111010 },
385
        { 0x86, 16, 0b1111111110111011 },
386
        { 0x87, 16, 0b1111111110111100 },
387
        { 0x88, 16, 0b1111111110111101 },
388
        { 0x89, 16, 0b1111111110111110 },
389
        { 0x8A, 16, 0b1111111110111111 },
390
        { 0x92, 16, 0b1111111111000000 },
391
        { 0x93, 16, 0b1111111111000001 },
392
        { 0x94, 16, 0b1111111111000010 },
393
        { 0x95, 16, 0b1111111111000011 },
394
        { 0x96, 16, 0b1111111111000100 },
395
        { 0x97, 16, 0b1111111111000101 },
396
        { 0x98, 16, 0b1111111111000110 },
397
        { 0x99, 16, 0b1111111111000111 },
398
        { 0x9A, 16, 0b1111111111001000 },
399
        { 0xA2, 16, 0b1111111111001001 },
400
        { 0xA3, 16, 0b1111111111001010 },
401
        { 0xA4, 16, 0b1111111111001011 },
402
        { 0xA5, 16, 0b1111111111001100 },
403
        { 0xA6, 16, 0b1111111111001101 },
404
        { 0xA7, 16, 0b1111111111001110 },
405
        { 0xA8, 16, 0b1111111111001111 },
406
        { 0xA9, 16, 0b1111111111010000 },
407
        { 0xAA, 16, 0b1111111111010001 },
408
        { 0xB2, 16, 0b1111111111010010 },
409
        { 0xB3, 16, 0b1111111111010011 },
410
        { 0xB4, 16, 0b1111111111010100 },
411
        { 0xB5, 16, 0b1111111111010101 },
412
        { 0xB6, 16, 0b1111111111010110 },
413
        { 0xB7, 16, 0b1111111111010111 },
414
        { 0xB8, 16, 0b1111111111011000 },
415
        { 0xB9, 16, 0b1111111111011001 },
416
        { 0xBA, 16, 0b1111111111011010 },
417
        { 0xC2, 16, 0b1111111111011011 },
418
        { 0xC3, 16, 0b1111111111011100 },
419
        { 0xC4, 16, 0b1111111111011101 },
420
        { 0xC5, 16, 0b1111111111011110 },
421
        { 0xC6, 16, 0b1111111111011111 },
422
        { 0xC7, 16, 0b1111111111100000 },
423
        { 0xC8, 16, 0b1111111111100001 },
424
        { 0xC9, 16, 0b1111111111100010 },
425
        { 0xCA, 16, 0b1111111111100011 },
426
        { 0xD2, 16, 0b1111111111100100 },
427
        { 0xD3, 16, 0b1111111111100101 },
428
        { 0xD4, 16, 0b1111111111100110 },
429
        { 0xD5, 16, 0b1111111111100111 },
430
        { 0xD6, 16, 0b1111111111101000 },
431
        { 0xD7, 16, 0b1111111111101001 },
432
        { 0xD8, 16, 0b1111111111101010 },
433
        { 0xD9, 16, 0b1111111111101011 },
434
        { 0xDA, 16, 0b1111111111101100 },
435
        { 0xE2, 16, 0b1111111111101101 },
436
        { 0xE3, 16, 0b1111111111101110 },
437
        { 0xE4, 16, 0b1111111111101111 },
438
        { 0xE5, 16, 0b1111111111110000 },
439
        { 0xE6, 16, 0b1111111111110001 },
440
        { 0xE7, 16, 0b1111111111110010 },
441
        { 0xE8, 16, 0b1111111111110011 },
442
        { 0xE9, 16, 0b1111111111110100 },
443
        { 0xEA, 16, 0b1111111111110101 },
444
        { 0xF2, 16, 0b1111111111110110 },
445
        { 0xF3, 16, 0b1111111111110111 },
446
        { 0xF4, 16, 0b1111111111111000 },
447
        { 0xF5, 16, 0b1111111111111001 },
448
        { 0xF6, 16, 0b1111111111111010 },
449
        { 0xF7, 16, 0b1111111111111011 },
450
        { 0xF8, 16, 0b1111111111111100 },
451
        { 0xF9, 16, 0b1111111111111101 },
452
        { 0xFA, 16, 0b1111111111111110 },
453
    },
454
    .id = (1 << 4) | 1,
455
};
456
457
}