FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/jpegxl_parser.c
Date: 2026-09-24 20:08:24
Exec Total Coverage
Lines: 449 937 47.9%
Functions: 21 27 77.8%
Branches: 254 692 36.7%

Line Branch Exec Source
1 /**
2 * JPEG XL parser
3 * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <errno.h>
23 #include <stdint.h>
24 #include <string.h>
25
26 #include "libavutil/attributes.h"
27 #include "libavutil/error.h"
28 #include "libavutil/intmath.h"
29 #include "libavutil/macros.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/pixfmt.h"
32
33 #include "bytestream.h"
34 #include "codec_id.h"
35 #include "parser_internal.h"
36 #define UNCHECKED_BITSTREAM_READER 0
37 #define BITSTREAM_READER_LE
38 #include "get_bits.h"
39 #include "jpegxl.h"
40 #include "jpegxl_parse.h"
41 #include "parser.h"
42 #include "vlc.h"
43
44 #define JXL_FLAG_NOISE 1
45 #define JXL_FLAG_PATCHES 2
46 #define JXL_FLAG_SPLINES 16
47 #define JXL_FLAG_USE_LF_FRAME 32
48 #define JXL_FLAG_SKIP_ADAPTIVE_LF_SMOOTH 128
49
50 #define MAX_PREFIX_ALPHABET_SIZE (1u << 15)
51
52 #define clog1p(x) (ff_log2(x) + !!(x))
53 #define unpack_signed(x) (((x) & 1 ? -(x)-1 : (x))/2)
54 #define div_ceil(x, y) (((x) - 1) / (y) + 1)
55 #define vlm(a,b) {.sym = (a), .len = (b)}
56
57 typedef struct JXLHybridUintConf {
58 int split_exponent;
59 uint32_t msb_in_token;
60 uint32_t lsb_in_token;
61 } JXLHybridUintConf;
62
63 typedef struct JXLSymbolDistribution {
64 JXLHybridUintConf config;
65 int log_bucket_size;
66 /* this is the actual size of the alphabet */
67 int alphabet_size;
68 /* ceil(log(alphabet_size)) */
69 int log_alphabet_size;
70
71 /* for prefix code distributions */
72 VLC vlc;
73 /* in case bits == 0 */
74 uint32_t default_symbol;
75
76 /*
77 * each (1 << log_alphabet_size) length
78 * with log_alphabet_size <= 8
79 */
80 /* frequencies associated with this Distribution */
81 uint32_t freq[258];
82 /* cutoffs for using the symbol table */
83 uint16_t cutoffs[258];
84 /* the symbol table for this distribution */
85 uint16_t symbols[258];
86 /* the offset for symbols */
87 uint16_t offsets[258];
88
89 /* if this distribution contains only one symbol this is its index */
90 int uniq_pos;
91 } JXLSymbolDistribution;
92
93 typedef struct JXLDistributionBundle {
94 /* lz77 flags */
95 int lz77_enabled;
96 uint32_t lz77_min_symbol;
97 uint32_t lz77_min_length;
98 JXLHybridUintConf lz_len_conf;
99
100 /* one entry for each distribution */
101 uint8_t *cluster_map;
102 /* length of cluster_map */
103 int num_dist;
104
105 /* one for each cluster */
106 JXLSymbolDistribution *dists;
107 int num_clusters;
108
109 /* whether to use brotli prefixes or ans */
110 int use_prefix_code;
111 /* bundle log alphabet size, dist ones may be smaller */
112 int log_alphabet_size;
113 } JXLDistributionBundle;
114
115 typedef struct JXLEntropyDecoder {
116
117 /* state is a positive 32-bit integer, or -1 if unset */
118 int64_t state;
119
120 /* lz77 values */
121 uint32_t num_to_copy;
122 uint32_t copy_pos;
123 uint32_t num_decoded;
124
125 /* length is (1 << 20) */
126 /* if lz77 is enabled for this bundle */
127 /* if lz77 is disabled it's NULL */
128 uint32_t *window;
129
130 /* primary bundle associated with this distribution */
131 JXLDistributionBundle bundle;
132
133 /* for av_log */
134 void *logctx;
135 } JXLEntropyDecoder;
136
137 typedef struct JXLFrame {
138 FFJXLFrameType type;
139 FFJXLFrameEncoding encoding;
140
141 int is_last;
142 int full_frame;
143
144 uint32_t total_length;
145 uint32_t body_length;
146 } JXLFrame;
147
148 typedef struct JXLCodestream {
149 FFJXLMetadata meta;
150 JXLFrame frame;
151 } JXLCodestream;
152
153 typedef struct JXLParseContext {
154 ParseContext pc;
155 JXLCodestream codestream;
156
157 /* using ISOBMFF-based container */
158 int container;
159 int64_t skip;
160 int copied;
161 int64_t collected_size;
162 int64_t codestream_length;
163 int skipped_icc;
164 int64_t next;
165
166 uint8_t cs_buffer[4096 + AV_INPUT_BUFFER_PADDING_SIZE];
167 } JXLParseContext;
168
169 /* used for reading brotli prefixes */
170 static const VLCElem level0_table[16] = {
171 vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(2, 3), vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(1, 4),
172 vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(2, 3), vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(5, 4),
173 };
174
175 /* prefix table for populating ANS distribution */
176 static const VLCElem dist_prefix_table[128] = {
177 vlm(10, 3), vlm(12, 7), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
178 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
179 vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
180 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
181 vlm(10, 3), vlm(11, 6), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
182 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
183 vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
184 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
185 vlm(10, 3), vlm(13, 7), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
186 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
187 vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
188 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
189 vlm(10, 3), vlm(11, 6), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
190 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
191 vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
192 vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
193 };
194
195 static const uint8_t prefix_codelen_map[18] = {
196 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
197 };
198
199 /**
200 * Read a variable-length 8-bit integer.
201 * Used when populating the ANS frequency tables.
202 */
203 ✗ static av_always_inline uint8_t jxl_u8(GetBitContext *gb)
204 {
205 int n;
206 ✗ if (!get_bits1(gb))
207 ✗ return 0;
208 ✗ n = get_bits(gb, 3);
209
210 ✗ return get_bitsz(gb, n) | (1 << n);
211 }
212
213 /* read a U32(c_i + u(u_i)) */
214 2412 static av_always_inline uint32_t jxl_u32(GetBitContext *gb,
215 uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3,
216 uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3)
217 {
218 2412 const uint32_t constants[4] = {c0, c1, c2, c3};
219 2412 const uint32_t ubits [4] = {u0, u1, u2, u3};
220 2412 uint32_t ret, choice = get_bits(gb, 2);
221
222 2412 ret = constants[choice];
223
2/2
✓ Branch 0 taken 1590 times.
✓ Branch 1 taken 822 times.
2412 if (ubits[choice])
224 1590 ret += get_bits_long(gb, ubits[choice]);
225
226 2412 return ret;
227 }
228
229 /* read a U64() */
230 530 static uint64_t jxl_u64(GetBitContext *gb)
231 {
232 530 uint64_t shift = 12, ret;
233
234
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 387 times.
530 switch (get_bits(gb, 2)) {
235 ✗ case 1:
236 ✗ ret = 1 + get_bits(gb, 4);
237 ✗ break;
238 143 case 2:
239 143 ret = 17 + get_bits(gb, 8);
240 143 break;
241 ✗ case 3:
242 ✗ ret = get_bits(gb, 12);
243 ✗ while (get_bits1(gb)) {
244 ✗ if (shift < 60) {
245 ✗ ret |= (uint64_t)get_bits(gb, 8) << shift;
246 ✗ shift += 8;
247 } else {
248 ✗ ret |= (uint64_t)get_bits(gb, 4) << shift;
249 ✗ break;
250 }
251 }
252 ✗ break;
253 387 default:
254 387 ret = 0;
255 }
256
257 530 return ret;
258 }
259
260 143 static int read_hybrid_uint_conf(GetBitContext *gb, JXLHybridUintConf *conf, int log_alphabet_size)
261 {
262 143 conf->split_exponent = get_bitsz(gb, clog1p(log_alphabet_size));
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (conf->split_exponent == log_alphabet_size) {
264 ✗ conf->msb_in_token = conf->lsb_in_token = 0;
265 ✗ return 0;
266 }
267
268 143 conf->msb_in_token = get_bitsz(gb, clog1p(conf->split_exponent));
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (conf->msb_in_token > conf->split_exponent)
270 ✗ return AVERROR_INVALIDDATA;
271 143 conf->lsb_in_token = get_bitsz(gb, clog1p(conf->split_exponent - conf->msb_in_token));
272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (conf->msb_in_token + conf->lsb_in_token > conf->split_exponent)
273 ✗ return AVERROR_INVALIDDATA;
274
275 143 return 0;
276 }
277
278 875 static int read_hybrid_uint(GetBitContext *gb, const JXLHybridUintConf *conf, uint32_t token, uint32_t *hybrid_uint)
279 {
280 875 uint32_t n, low, split = 1 << conf->split_exponent;
281
282
2/2
✓ Branch 0 taken 849 times.
✓ Branch 1 taken 26 times.
875 if (token < split) {
283 849 *hybrid_uint = token;
284 849 return 0;
285 }
286
287 26 n = conf->split_exponent - conf->lsb_in_token - conf->msb_in_token +
288 26 ((token - split) >> (conf->msb_in_token + conf->lsb_in_token));
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (n >= 32)
290 ✗ return AVERROR_INVALIDDATA;
291 26 low = token & ((1 << conf->lsb_in_token) - 1);
292 26 token >>= conf->lsb_in_token;
293 26 token &= (1 << conf->msb_in_token) - 1;
294 26 token |= 1 << conf->msb_in_token;
295 26 *hybrid_uint = (((token << n) | get_bits_long(gb, n)) << conf->lsb_in_token ) | low;
296
297 26 return 0;
298 }
299
300 875 static inline uint32_t read_prefix_symbol(GetBitContext *gb, const JXLSymbolDistribution *dist)
301 {
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (!dist->vlc.bits)
303 ✗ return dist->default_symbol;
304
305 875 return get_vlc2(gb, dist->vlc.table, dist->vlc.bits, 1);
306 }
307
308 ✗ static uint32_t read_ans_symbol(GetBitContext *gb, JXLEntropyDecoder *dec, const JXLSymbolDistribution *dist)
309 {
310 uint32_t index, i, pos, symbol, offset;
311
312 ✗ if (dec->state < 0)
313 ✗ dec->state = get_bits_long(gb, 32);
314
315 ✗ index = dec->state & 0xFFF;
316 ✗ i = index >> dist->log_bucket_size;
317 ✗ pos = index & ((1 << dist->log_bucket_size) - 1);
318 ✗ symbol = pos >= dist->cutoffs[i] ? dist->symbols[i] : i;
319 ✗ offset = pos >= dist->cutoffs[i] ? dist->offsets[i] + pos : pos;
320 ✗ dec->state = dist->freq[symbol] * (dec->state >> 12) + offset;
321 ✗ if (dec->state < (1 << 16))
322 ✗ dec->state = (dec->state << 16) | get_bits(gb, 16);
323 ✗ dec->state &= 0xFFFFFFFF;
324
325 ✗ return symbol;
326 }
327
328 875 static int decode_hybrid_varlen_uint(GetBitContext *gb, JXLEntropyDecoder *dec,
329 const JXLDistributionBundle *bundle,
330 uint32_t context, uint32_t *hybrid_uint)
331 {
332 int ret;
333 uint32_t token, distance;
334 const JXLSymbolDistribution *dist;
335
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (dec->num_to_copy > 0) {
337 ✗ *hybrid_uint = dec->window[dec->copy_pos++ & 0xFFFFF];
338 ✗ dec->num_to_copy--;
339 ✗ dec->window[dec->num_decoded++ & 0xFFFFF] = *hybrid_uint;
340 ✗ return 0;
341 }
342
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (context >= bundle->num_dist)
344 ✗ return AVERROR(EINVAL);
345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (bundle->cluster_map[context] >= bundle->num_clusters)
346 ✗ return AVERROR_INVALIDDATA;
347
348 875 dist = &bundle->dists[bundle->cluster_map[context]];
349
1/2
✓ Branch 0 taken 875 times.
✗ Branch 1 not taken.
875 if (bundle->use_prefix_code)
350 875 token = read_prefix_symbol(gb, dist);
351 else
352 ✗ token = read_ans_symbol(gb, dec, dist);
353
354
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
875 if (bundle->lz77_enabled && token >= bundle->lz77_min_symbol) {
355 ✗ const JXLSymbolDistribution *lz77dist = &bundle->dists[bundle->cluster_map[bundle->num_dist - 1]];
356 ✗ if (!dec->num_decoded)
357 ✗ return AVERROR_INVALIDDATA;
358 ✗ ret = read_hybrid_uint(gb, &bundle->lz_len_conf, token - bundle->lz77_min_symbol, &dec->num_to_copy);
359 ✗ if (ret < 0)
360 ✗ return ret;
361 ✗ dec->num_to_copy += bundle->lz77_min_length;
362 ✗ if (bundle->use_prefix_code)
363 ✗ token = read_prefix_symbol(gb, lz77dist);
364 else
365 ✗ token = read_ans_symbol(gb, dec, lz77dist);
366 ✗ ret = read_hybrid_uint(gb, &lz77dist->config, token, &distance);
367 ✗ if (ret < 0)
368 ✗ return ret;
369 ✗ distance++;
370 ✗ distance = FFMIN3(distance, dec->num_decoded, 1 << 20);
371 ✗ dec->copy_pos = dec->num_decoded - distance;
372 ✗ return decode_hybrid_varlen_uint(gb, dec, bundle, context, hybrid_uint);
373 }
374 875 ret = read_hybrid_uint(gb, &dist->config, token, hybrid_uint);
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (ret < 0)
376 ✗ return ret;
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (bundle->lz77_enabled)
378 ✗ dec->window[dec->num_decoded++ & 0xFFFFF] = *hybrid_uint;
379
380 875 return 0;
381 }
382
383 ✗ static int populate_distribution(GetBitContext *gb, JXLSymbolDistribution *dist, int log_alphabet_size)
384 {
385 ✗ int len = 0, shift, omit_log = -1, omit_pos = -1;
386 ✗ int prev = 0, num_same = 0;
387 ✗ uint32_t total_count = 0;
388 ✗ uint8_t logcounts[258] = { 0 };
389 ✗ uint8_t same[258] = { 0 };
390 ✗ const int table_size = 1 << log_alphabet_size;
391 ✗ dist->uniq_pos = -1;
392
393 ✗ if (get_bits1(gb)) {
394 /* simple code */
395 ✗ if (get_bits1(gb)) {
396 ✗ uint8_t v1 = jxl_u8(gb);
397 ✗ uint8_t v2 = jxl_u8(gb);
398 ✗ if (v1 == v2)
399 ✗ return AVERROR_INVALIDDATA;
400 ✗ dist->freq[v1] = get_bits(gb, 12);
401 ✗ dist->freq[v2] = (1 << 12) - dist->freq[v1];
402 ✗ if (!dist->freq[v1])
403 ✗ dist->uniq_pos = v2;
404 ✗ dist->alphabet_size = 1 + FFMAX(v1, v2);
405 } else {
406 ✗ uint8_t x = jxl_u8(gb);
407 ✗ dist->freq[x] = 1 << 12;
408 ✗ dist->uniq_pos = x;
409 ✗ dist->alphabet_size = 1 + x;
410 }
411 ✗ if (dist->alphabet_size > table_size)
412 ✗ return AVERROR_INVALIDDATA;
413
414 ✗ return 0;
415 }
416
417 ✗ if (get_bits1(gb)) {
418 /* flat code */
419 ✗ dist->alphabet_size = jxl_u8(gb) + 1;
420 ✗ if (dist->alphabet_size > table_size)
421 ✗ return AVERROR_INVALIDDATA;
422 ✗ for (int i = 0; i < dist->alphabet_size; i++)
423 ✗ dist->freq[i] = (1 << 12) / dist->alphabet_size;
424 ✗ for (int i = 0; i < (1 << 12) % dist->alphabet_size; i++)
425 ✗ dist->freq[i]++;
426 ✗ return 0;
427 }
428
429 do {
430 ✗ if (!get_bits1(gb))
431 ✗ break;
432 ✗ } while (++len < 3);
433
434 ✗ shift = (get_bitsz(gb, len) | (1 << len)) - 1;
435 ✗ if (shift > 13)
436 ✗ return AVERROR_INVALIDDATA;
437
438 ✗ dist->alphabet_size = jxl_u8(gb) + 3;
439 ✗ if (dist->alphabet_size > table_size)
440 ✗ return AVERROR_INVALIDDATA;
441
442 ✗ for (int i = 0; i < dist->alphabet_size; i++) {
443 ✗ logcounts[i] = get_vlc2(gb, dist_prefix_table, 7, 1);
444 ✗ if (logcounts[i] == 13) {
445 ✗ int rle = jxl_u8(gb);
446 ✗ same[i] = rle + 5;
447 ✗ i += rle + 3;
448 ✗ continue;
449 }
450 ✗ if (logcounts[i] > omit_log) {
451 ✗ omit_log = logcounts[i];
452 ✗ omit_pos = i;
453 }
454 }
455 ✗ if (omit_pos < 0 || omit_pos + 1 < dist->alphabet_size && logcounts[omit_pos + 1] == 13)
456 ✗ return AVERROR_INVALIDDATA;
457
458 ✗ for (int i = 0; i < dist->alphabet_size; i++) {
459 ✗ if (same[i]) {
460 ✗ num_same = same[i] - 1;
461 ✗ prev = i > 0 ? dist->freq[i - 1] : 0;
462 }
463 ✗ if (num_same) {
464 ✗ dist->freq[i] = prev;
465 ✗ num_same--;
466 } else {
467 ✗ if (i == omit_pos || !logcounts[i])
468 ✗ continue;
469 ✗ if (logcounts[i] == 1) {
470 ✗ dist->freq[i] = 1;
471 } else {
472 ✗ int bitcount = FFMIN(FFMAX(0, shift - ((12 - logcounts[i] + 1) >> 1)), logcounts[i] - 1);
473 ✗ dist->freq[i] = (1 << (logcounts[i] - 1)) + (get_bitsz(gb, bitcount) << (logcounts[i] - 1 - bitcount));
474 }
475 }
476 ✗ total_count += dist->freq[i];
477 }
478 ✗ dist->freq[omit_pos] = (1 << 12) - total_count;
479
480 ✗ return 0;
481 }
482
483 143 static void dist_bundle_close(JXLDistributionBundle *bundle)
484 {
485
2/4
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
✗ Branch 3 not taken.
143 if (bundle->use_prefix_code && bundle->dists)
486
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++)
487 143 ff_vlc_free(&bundle->dists[i].vlc);
488 143 av_freep(&bundle->dists);
489 143 av_freep(&bundle->cluster_map);
490 143 }
491
492
493 static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
494 JXLDistributionBundle *bundle, int num_dist, int disallow_lz77);
495
496 143 static int read_dist_clustering(GetBitContext *gb, JXLEntropyDecoder *dec, JXLDistributionBundle *bundle)
497 {
498 int ret;
499
500 143 bundle->cluster_map = av_malloc(bundle->num_dist);
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!bundle->cluster_map)
502 ✗ return AVERROR(ENOMEM);
503
504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->num_dist == 1) {
505 ✗ bundle->cluster_map[0] = 0;
506 ✗ bundle->num_clusters = 1;
507 ✗ return 0;
508 }
509
510
1/2
✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
143 if (get_bits1(gb)) {
511 /* simple clustering */
512 143 uint32_t nbits = get_bits(gb, 2);
513
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 143 times.
1287 for (int i = 0; i < bundle->num_dist; i++)
514 1144 bundle->cluster_map[i] = get_bitsz(gb, nbits);
515 } else {
516 /* complex clustering */
517 ✗ int use_mtf = get_bits1(gb);
518 ✗ JXLDistributionBundle nested = { 0 };
519 /* num_dist == 1 prevents this from recursing again */
520 ✗ ret = read_distribution_bundle(gb, dec, &nested, 1, bundle->num_dist <= 2);
521 ✗ if (ret < 0) {
522 ✗ dist_bundle_close(&nested);
523 ✗ return ret;
524 }
525 ✗ for (int i = 0; i < bundle->num_dist; i++) {
526 uint32_t clust;
527 ✗ ret = decode_hybrid_varlen_uint(gb, dec, &nested, 0, &clust);
528 ✗ if (ret < 0) {
529 ✗ dist_bundle_close(&nested);
530 ✗ return ret;
531 }
532 ✗ bundle->cluster_map[i] = clust;
533 }
534 ✗ dec->state = -1;
535 /* it's not going to necessarily be zero after reading */
536 ✗ dec->num_to_copy = 0;
537 ✗ dec->num_decoded = 0;
538 ✗ dist_bundle_close(&nested);
539 ✗ if (use_mtf) {
540 uint8_t mtf[256];
541 ✗ for (int i = 0; i < 256; i++)
542 ✗ mtf[i] = i;
543 ✗ for (int i = 0; i < bundle->num_dist; i++) {
544 ✗ int index = bundle->cluster_map[i];
545 ✗ bundle->cluster_map[i] = mtf[index];
546 ✗ if (index) {
547 ✗ int value = mtf[index];
548 ✗ for (int j = index; j > 0; j--)
549 ✗ mtf[j] = mtf[j - 1];
550 ✗ mtf[0] = value;
551 }
552 }
553 }
554 }
555
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 143 times.
1287 for (int i = 0; i < bundle->num_dist; i++) {
556
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 1001 times.
1144 if (bundle->cluster_map[i] >= bundle->num_clusters)
557 143 bundle->num_clusters = bundle->cluster_map[i] + 1;
558 }
559
560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->num_clusters > bundle->num_dist)
561 ✗ return AVERROR_INVALIDDATA;
562
563 143 return 0;
564 }
565
566 ✗ static int gen_alias_map(JXLEntropyDecoder *dec, JXLSymbolDistribution *dist, int log_alphabet_size)
567 {
568 uint32_t bucket_size, table_size;
569 uint8_t overfull[256], underfull[256];
570 ✗ int overfull_pos = 0, underfull_pos = 0;
571 ✗ dist->log_bucket_size = 12 - log_alphabet_size;
572 ✗ bucket_size = 1 << dist->log_bucket_size;
573 ✗ table_size = 1 << log_alphabet_size;
574
575 ✗ if (dist->uniq_pos >= 0) {
576 ✗ for (int i = 0; i < table_size; i++) {
577 ✗ dist->symbols[i] = dist->uniq_pos;
578 ✗ dist->offsets[i] = bucket_size * i;
579 ✗ dist->cutoffs[i] = 0;
580 }
581 ✗ return 0;
582 }
583
584 ✗ for (int i = 0; i < dist->alphabet_size; i++) {
585 ✗ dist->cutoffs[i] = dist->freq[i];
586 ✗ dist->symbols[i] = i;
587 ✗ if (dist->cutoffs[i] > bucket_size)
588 ✗ overfull[overfull_pos++] = i;
589 ✗ else if (dist->cutoffs[i] < bucket_size)
590 ✗ underfull[underfull_pos++] = i;
591 }
592
593 ✗ for (int i = dist->alphabet_size; i < table_size; i++) {
594 ✗ dist->cutoffs[i] = 0;
595 ✗ underfull[underfull_pos++] = i;
596 }
597
598 ✗ while (overfull_pos) {
599 int o, u, by;
600 /* this should be impossible */
601 ✗ if (!underfull_pos)
602 ✗ return AVERROR_INVALIDDATA;
603 ✗ u = underfull[--underfull_pos];
604 ✗ o = overfull[--overfull_pos];
605 ✗ by = bucket_size - dist->cutoffs[u];
606 ✗ dist->cutoffs[o] -= by;
607 ✗ dist->symbols[u] = o;
608 ✗ dist->offsets[u] = dist->cutoffs[o];
609 ✗ if (dist->cutoffs[o] < bucket_size)
610 ✗ underfull[underfull_pos++] = o;
611 ✗ else if (dist->cutoffs[o] > bucket_size)
612 ✗ overfull[overfull_pos++] = o;
613 }
614
615 ✗ for (int i = 0; i < table_size; i++) {
616 ✗ if (dist->cutoffs[i] == bucket_size) {
617 ✗ dist->symbols[i] = i;
618 ✗ dist->offsets[i] = 0;
619 ✗ dist->cutoffs[i] = 0;
620 } else {
621 ✗ dist->offsets[i] -= dist->cutoffs[i];
622 }
623 }
624
625 ✗ return 0;
626 }
627
628 142 static int read_simple_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
629 {
630 int nsym, tree_select, bits;
631
632 int8_t lens[4];
633 int16_t symbols[4];
634
635 142 nsym = 1 + get_bits(gb, 2);
636
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 142 times.
468 for (int i = 0; i < nsym; i++)
637 326 symbols[i] = get_bitsz(gb, dist->log_alphabet_size);
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if (nsym == 4)
639 ✗ tree_select = get_bits1(gb);
640
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
142 switch (nsym) {
641 ✗ case 1:
642 ✗ dist->vlc.bits = 0;
643 ✗ dist->default_symbol = symbols[0];
644 ✗ return 0;
645 100 case 2:
646 100 bits = 1;
647 100 lens[0] = 1, lens[1] = 1, lens[2] = 0, lens[3] = 0;
648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (symbols[1] < symbols[0])
649 ✗ FFSWAP(int16_t, symbols[0], symbols[1]);
650 100 break;
651 42 case 3:
652 42 bits = 2;
653 42 lens[0] = 1, lens[1] = 2, lens[2] = 2, lens[3] = 0;
654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (symbols[2] < symbols[1])
655 ✗ FFSWAP(int16_t, symbols[1], symbols[2]);
656 42 break;
657 ✗ case 4:
658 ✗ if (tree_select) {
659 ✗ bits = 3;
660 ✗ lens[0] = 1, lens[1] = 2, lens[2] = 3, lens[3] = 3;
661 ✗ if (symbols[3] < symbols[2])
662 ✗ FFSWAP(int16_t, symbols[2], symbols[3]);
663 } else {
664 ✗ bits = 2;
665 ✗ lens[0] = 2, lens[1] = 2, lens[2] = 2, lens[3] = 2;
666 while (1) {
667 ✗ if (symbols[1] < symbols[0])
668 ✗ FFSWAP(int16_t, symbols[0], symbols[1]);
669 ✗ if (symbols[3] < symbols[2])
670 ✗ FFSWAP(int16_t, symbols[2], symbols[3]);
671 ✗ if (symbols[1] <= symbols[2])
672 ✗ break;
673 ✗ FFSWAP(int16_t, symbols[1], symbols[2]);
674 }
675 }
676 ✗ break;
677 ✗ default:
678 // Challenge Complete! How did we get here?
679 ✗ return AVERROR_BUG;
680 }
681
682 142 return ff_vlc_init_from_lengths(&dist->vlc, bits, nsym, lens, 1, symbols,
683 2, 2, 0, VLC_INIT_LE, dec->logctx);
684 }
685
686 143 static int read_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
687 {
688 143 int8_t level1_lens[18] = { 0 };
689 143 int8_t level1_lens_s[18] = { 0 };
690 143 int16_t level1_syms[18] = { 0 };
691 143 uint32_t level1_codecounts[19] = { 0 };
692 143 uint8_t *buf = NULL;
693 int8_t *level2_lens, *level2_lens_s;
694 int16_t *level2_syms;
695 uint32_t *level2_codecounts;
696
697 143 int repeat_count_prev = 0, repeat_count_zero = 0, prev = 8;
698 143 int total_code = 0, len, hskip, num_codes = 0, ret;
699
700 143 VLC level1_vlc = { 0 };
701
702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (dist->alphabet_size == 1) {
703 ✗ dist->vlc.bits = 0;
704 ✗ dist->default_symbol = 0;
705 ✗ return 0;
706 }
707
708 143 hskip = get_bits(gb, 2);
709
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 1 times.
143 if (hskip == 1)
710 142 return read_simple_vlc_prefix(gb, dec, dist);
711
712 1 level1_codecounts[0] = hskip;
713
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (int i = hskip; i < 18; i++) {
714 8 len = level1_lens[prefix_codelen_map[i]] = get_vlc2(gb, level0_table, 4, 1);
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (len < 0) {
716 ✗ ret = AVERROR_INVALIDDATA;
717 ✗ goto end;
718 }
719 8 level1_codecounts[len]++;
720
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (len) {
721 7 total_code += (32 >> len);
722 7 num_codes++;
723 }
724
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (total_code >= 32) {
725 1 level1_codecounts[0] += 18 - i - 1;
726 1 break;
727 }
728 }
729
730
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 if (total_code != 32 && num_codes >= 2 || num_codes < 1) {
731 ✗ ret = AVERROR_INVALIDDATA;
732 ✗ goto end;
733 }
734
735
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 for (int i = 1; i < 19; i++)
736 18 level1_codecounts[i] += level1_codecounts[i - 1];
737
738
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 for (int i = 17; i >= 0; i--) {
739 18 int idx = --level1_codecounts[level1_lens[i]];
740 18 level1_lens_s[idx] = level1_lens[i];
741 18 level1_syms[idx] = i;
742 }
743
744 1 ret = ff_vlc_init_from_lengths(&level1_vlc, 5, 18, level1_lens_s, 1, level1_syms, 2, 2,
745 0, VLC_INIT_LE, dec->logctx);
746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
747 ✗ goto end;
748
749 1 buf = av_mallocz(MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t) + sizeof(uint32_t))
750 + sizeof(uint32_t));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!buf) {
752 ✗ ret = AVERROR(ENOMEM);
753 ✗ goto end;
754 }
755
756 1 level2_lens = (int8_t *)buf;
757 1 level2_lens_s = (int8_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * sizeof(int8_t));
758 1 level2_syms = (int16_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t)));
759 1 level2_codecounts = (uint32_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t)));
760
761 1 total_code = 0;
762
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 for (int i = 0; i < dist->alphabet_size; i++) {
763 16 len = get_vlc2(gb, level1_vlc.table, 5, 1);
764
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (len < 0) {
765 ✗ ret = AVERROR_INVALIDDATA;
766 ✗ goto end;
767 }
768
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
16 if (get_bits_left(gb) < 0) {
769 ✗ ret = AVERROR_BUFFER_TOO_SMALL;
770 ✗ goto end;
771 }
772
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (len == 16) {
773 ✗ int extra = 3 + get_bits(gb, 2);
774 ✗ if (repeat_count_prev)
775 ✗ extra += 4 * (repeat_count_prev - 2) - repeat_count_prev;
776 ✗ extra = FFMIN(extra, dist->alphabet_size - i);
777 ✗ for (int j = 0; j < extra; j++)
778 ✗ level2_lens[i + j] = prev;
779 ✗ total_code += (32768 >> prev) * extra;
780 ✗ i += extra - 1;
781 ✗ repeat_count_prev += extra;
782 ✗ repeat_count_zero = 0;
783 ✗ level2_codecounts[prev] += extra;
784
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 } else if (len == 17) {
785 2 int extra = 3 + get_bits(gb, 3);
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (repeat_count_zero > 0)
787 ✗ extra += 8 * (repeat_count_zero - 2) - repeat_count_zero;
788 2 extra = FFMIN(extra, dist->alphabet_size - i);
789 2 i += extra - 1;
790 2 repeat_count_prev = 0;
791 2 repeat_count_zero += extra;
792 2 level2_codecounts[0] += extra;
793 } else {
794 14 level2_lens[i] = len;
795 14 repeat_count_prev = repeat_count_zero = 0;
796
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5 times.
14 if (len) {
797 9 total_code += (32768 >> len);
798 9 prev = len;
799 }
800 14 level2_codecounts[len]++;
801 }
802
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (total_code >= 32768) {
803 1 level2_codecounts[0] += dist->alphabet_size - i - 1;
804 1 break;
805 }
806 }
807
808
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (total_code != 32768 && level2_codecounts[0] < dist->alphabet_size - 1) {
809 ✗ ret = AVERROR_INVALIDDATA;
810 ✗ goto end;
811 }
812
813
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
29 for (int i = 1; i < dist->alphabet_size + 1; i++)
814 28 level2_codecounts[i] += level2_codecounts[i - 1];
815
816
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
29 for (int i = dist->alphabet_size - 1; i >= 0; i--) {
817 28 int idx = --level2_codecounts[level2_lens[i]];
818 28 level2_lens_s[idx] = level2_lens[i];
819 28 level2_syms[idx] = i;
820 }
821
822 1 ret = ff_vlc_init_from_lengths(&dist->vlc, 15, dist->alphabet_size, level2_lens_s,
823 1, level2_syms, 2, 2, 0, VLC_INIT_LE, dec->logctx);
824
825 1 end:
826 1 av_freep(&buf);
827 1 ff_vlc_free(&level1_vlc);
828
829 1 return ret;
830 }
831
832 143 static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
833 JXLDistributionBundle *bundle, int num_dist, int disallow_lz77)
834 {
835 int ret;
836
837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (num_dist <= 0)
838 ✗ return AVERROR(EINVAL);
839
840 143 bundle->num_dist = num_dist;
841 143 bundle->lz77_enabled = get_bits1(gb);
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->lz77_enabled) {
843 ✗ if (disallow_lz77)
844 ✗ return AVERROR_INVALIDDATA;
845 ✗ bundle->lz77_min_symbol = jxl_u32(gb, 224, 512, 4096, 8, 0, 0, 0, 15);
846 ✗ bundle->lz77_min_length = jxl_u32(gb, 3, 4, 5, 9, 0, 0, 2, 8);
847 ✗ bundle->num_dist++;
848 ✗ ret = read_hybrid_uint_conf(gb, &bundle->lz_len_conf, 8);
849 ✗ if (ret < 0)
850 ✗ return ret;
851 }
852
853
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
143 if (bundle->lz77_enabled && !dec->window) {
854 ✗ dec->window = av_malloc_array(1 << 20, sizeof(uint32_t));
855 ✗ if (!dec->window)
856 ✗ return AVERROR(ENOMEM);
857 }
858
859 143 ret = read_dist_clustering(gb, dec, bundle);
860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
861 ✗ return ret;
862
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
863 ✗ return AVERROR_BUFFER_TOO_SMALL;
864
865 143 bundle->dists = av_calloc(bundle->num_clusters, sizeof(JXLSymbolDistribution));
866
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!bundle->dists)
867 ✗ return AVERROR(ENOMEM);
868
869 143 bundle->use_prefix_code = get_bits1(gb);
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 bundle->log_alphabet_size = bundle->use_prefix_code ? 15 : 5 + get_bits(gb, 2);
871
872
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
873 143 ret = read_hybrid_uint_conf(gb, &bundle->dists[i].config, bundle->log_alphabet_size);
874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
875 ✗ return ret;
876
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
877 ✗ return AVERROR_BUFFER_TOO_SMALL;
878 }
879
880
1/2
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
143 if (bundle->use_prefix_code) {
881
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
882 143 JXLSymbolDistribution *dist = &bundle->dists[i];
883
1/2
✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
143 if (get_bits1(gb)) {
884 143 int n = get_bits(gb, 4);
885 143 dist->alphabet_size = 1 + (1 << n) + get_bitsz(gb, n);
886
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (dist->alphabet_size > MAX_PREFIX_ALPHABET_SIZE)
887 ✗ return AVERROR_INVALIDDATA;
888 } else {
889 ✗ dist->alphabet_size = 1;
890 }
891 143 dist->log_alphabet_size = clog1p(dist->alphabet_size - 1);
892 }
893
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
894 143 ret = read_vlc_prefix(gb, dec, &bundle->dists[i]);
895
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
896 ✗ return ret;
897
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
898 ✗ return AVERROR_BUFFER_TOO_SMALL;
899 }
900 } else {
901 ✗ for (int i = 0; i < bundle->num_clusters; i++) {
902 ✗ ret = populate_distribution(gb, &bundle->dists[i], bundle->log_alphabet_size);
903 ✗ if (ret < 0)
904 ✗ return ret;
905 ✗ if (get_bits_left(gb) < 0)
906 ✗ return AVERROR_BUFFER_TOO_SMALL;
907 }
908 ✗ for (int i = 0; i < bundle->num_clusters; i++) {
909 ✗ ret = gen_alias_map(dec, &bundle->dists[i], bundle->log_alphabet_size);
910 ✗ if (ret < 0)
911 ✗ return ret;
912 }
913 }
914
915 143 return 0;
916 }
917
918 143 static void entropy_decoder_close(JXLEntropyDecoder *dec)
919 {
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!dec)
921 ✗ return;
922 143 av_freep(&dec->window);
923 143 dist_bundle_close(&dec->bundle);
924 }
925
926 143 static int entropy_decoder_init(void *avctx, GetBitContext *gb, JXLEntropyDecoder *dec, int num_dist)
927 {
928 int ret;
929
930 143 memset(dec, 0, sizeof(*dec));
931 143 dec->logctx = avctx;
932 143 dec->state = -1;
933
934 143 ret = read_distribution_bundle(gb, dec, &dec->bundle, num_dist, 0);
935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0) {
936 ✗ entropy_decoder_close(dec);
937 ✗ return ret;
938 }
939
940 143 return 0;
941 }
942
943 875 static int64_t entropy_decoder_read_symbol(GetBitContext *gb, JXLEntropyDecoder *dec, uint32_t context)
944 {
945 int ret;
946 uint32_t hybrid_uint;
947
948 875 ret = decode_hybrid_varlen_uint(gb, dec, &dec->bundle, context, &hybrid_uint);
949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (ret < 0)
950 ✗ return ret;
951
952 875 return hybrid_uint;
953 }
954
955 ✗ static inline uint32_t icc_context(uint64_t i, uint32_t b1, uint32_t b2)
956 {
957 uint32_t p1, p2;
958 ✗ if (i <= 128)
959 ✗ return 0;
960 ✗ if (b1 >= 'a' && b1 <= 'z' || b1 >= 'A' && b1 <= 'Z')
961 ✗ p1 = 0;
962 ✗ else if (b1 >= '0' && b1 <= '9' || b1 == '.' || b1 == ',')
963 ✗ p1 = 1;
964 ✗ else if (b1 <= 1)
965 ✗ p1 = b1 + 2;
966 ✗ else if (b1 > 1 && b1 < 16)
967 ✗ p1 = 4;
968 ✗ else if (b1 > 240 && b1 < 255)
969 ✗ p1 = 5;
970 ✗ else if (b1 == 255)
971 ✗ p1 = 6;
972 else
973 ✗ p1 = 7;
974
975 ✗ if (b2 >= 'a' && b2 <= 'z' || b2 >= 'A' && b2 <= 'Z')
976 ✗ p2 = 0;
977 ✗ else if (b2 >= '0' && b2 <= '9' || b2 == '.' || b2 == ',')
978 ✗ p2 = 1;
979 ✗ else if (b2 < 16)
980 ✗ p2 = 2;
981 ✗ else if (b2 > 240)
982 ✗ p2 = 3;
983 else
984 ✗ p2 = 4;
985
986 ✗ return 1 + p1 + p2 * 8;
987 }
988
989 875 static inline uint32_t toc_context(uint32_t x)
990 {
991 875 return FFMIN(7, clog1p(x));
992 }
993
994 15 static void populate_fields(AVCodecParserContext *s, AVCodecContext *avctx, const FFJXLMetadata *meta)
995 {
996 15 s->width = meta->width;
997 15 s->height = meta->height;
998
999
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 switch (meta->csp) {
1000 15 case JPEGXL_CS_RGB:
1001 case JPEGXL_CS_XYB:
1002 15 avctx->colorspace = AVCOL_SPC_RGB;
1003 15 break;
1004 ✗ default:
1005 ✗ avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
1006 }
1007
1008
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta->wp == JPEGXL_WP_D65) {
1009
1/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 switch (meta->primaries) {
1010 15 case JPEGXL_PR_SRGB:
1011 15 avctx->color_primaries = AVCOL_PRI_BT709;
1012 15 break;
1013 ✗ case JPEGXL_PR_P3:
1014 ✗ avctx->color_primaries = AVCOL_PRI_SMPTE432;
1015 ✗ break;
1016 ✗ case JPEGXL_PR_2100:
1017 ✗ avctx->color_primaries = AVCOL_PRI_BT2020;
1018 ✗ break;
1019 ✗ default:
1020 ✗ avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
1021 }
1022 ✗ } else if (meta->wp == JPEGXL_WP_DCI && meta->primaries == JPEGXL_PR_P3) {
1023 ✗ avctx->color_primaries = AVCOL_PRI_SMPTE431;
1024 } else {
1025 ✗ avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
1026 }
1027
1028
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta->trc > JPEGXL_TR_GAMMA) {
1029 15 FFJXLTransferCharacteristic trc = meta->trc - JPEGXL_TR_GAMMA;
1030
1/7
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
15 switch (trc) {
1031 ✗ case JPEGXL_TR_BT709:
1032 ✗ avctx->color_trc = AVCOL_TRC_BT709;
1033 ✗ break;
1034 ✗ case JPEGXL_TR_LINEAR:
1035 ✗ avctx->color_trc = AVCOL_TRC_LINEAR;
1036 ✗ break;
1037 15 case JPEGXL_TR_SRGB:
1038 15 avctx->color_trc = AVCOL_TRC_IEC61966_2_1;
1039 15 break;
1040 ✗ case JPEGXL_TR_PQ:
1041 ✗ avctx->color_trc = AVCOL_TRC_SMPTEST2084;
1042 ✗ break;
1043 ✗ case JPEGXL_TR_DCI:
1044 ✗ avctx->color_trc = AVCOL_TRC_SMPTE428;
1045 ✗ break;
1046 ✗ case JPEGXL_TR_HLG:
1047 ✗ avctx->color_trc = AVCOL_TRC_ARIB_STD_B67;
1048 ✗ break;
1049 ✗ default:
1050 ✗ avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1051 }
1052 ✗ } else if (meta->trc > 0) {
1053 ✗ if (meta->trc > 45355 && meta->trc < 45555)
1054 ✗ avctx->color_trc = AVCOL_TRC_GAMMA22;
1055 ✗ else if (meta->trc > 35614 && meta->trc < 35814)
1056 ✗ avctx->color_trc = AVCOL_TRC_GAMMA28;
1057 else
1058 ✗ avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1059 } else {
1060 ✗ avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1061 }
1062
1063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (meta->csp == JPEGXL_CS_GRAY) {
1064 ✗ if (meta->bit_depth <= 8)
1065 ✗ s->format = meta->have_alpha ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
1066 ✗ else if (meta->bit_depth <= 16)
1067 ✗ s->format = meta->have_alpha ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
1068 else
1069 ✗ s->format = meta->have_alpha ? AV_PIX_FMT_NONE : AV_PIX_FMT_GRAYF32;
1070 } else {
1071
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta->bit_depth <= 8)
1072
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
15 s->format = meta->have_alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
1073 ✗ else if (meta->bit_depth <= 16)
1074 ✗ s->format = meta->have_alpha ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
1075 else
1076 ✗ s->format = meta->have_alpha ? AV_PIX_FMT_RGBAF32 : AV_PIX_FMT_RGBF32;
1077 }
1078
1079
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
15 if (meta->have_alpha) {
1080 2 avctx->alpha_mode = meta->alpha_associated ? AVALPHA_MODE_PREMULTIPLIED
1081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 : AVALPHA_MODE_STRAIGHT;
1082 }
1083 15 }
1084
1085 ✗ static int skip_icc_profile(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1086 {
1087 int64_t ret;
1088 ✗ uint32_t last = 0, last2 = 0;
1089 ✗ JXLEntropyDecoder dec = { 0 };
1090 ✗ uint64_t enc_size = jxl_u64(gb);
1091 ✗ uint64_t output_size = 0;
1092 ✗ int out_size_shift = 0;
1093
1094 ✗ if (!enc_size || enc_size > (1 << 22))
1095 ✗ return AVERROR_INVALIDDATA;
1096
1097 ✗ ret = entropy_decoder_init(avctx, gb, &dec, 41);
1098 ✗ if (ret < 0)
1099 ✗ goto end;
1100
1101 ✗ if (get_bits_left(gb) < 0) {
1102 ✗ ret = AVERROR_BUFFER_TOO_SMALL;
1103 ✗ goto end;
1104 }
1105
1106 ✗ for (uint64_t read = 0; read < enc_size; read++) {
1107 ✗ ret = entropy_decoder_read_symbol(gb, &dec, icc_context(read, last, last2));
1108 ✗ if (ret < 0)
1109 ✗ goto end;
1110 ✗ if (ret > 255) {
1111 ✗ ret = AVERROR_INVALIDDATA;
1112 ✗ goto end;
1113 }
1114 ✗ if (get_bits_left(gb) < 0) {
1115 ✗ ret = AVERROR_BUFFER_TOO_SMALL;
1116 ✗ goto end;
1117 }
1118 ✗ last2 = last;
1119 ✗ last = ret;
1120 ✗ if (out_size_shift < 63) {
1121 ✗ output_size += (ret & UINT64_C(0x7F)) << out_size_shift;
1122 ✗ if (!(ret & 0x80)) {
1123 ✗ out_size_shift = 63;
1124 } else {
1125 ✗ out_size_shift += 7;
1126 ✗ if (out_size_shift > 56) {
1127 ✗ ret = AVERROR_INVALIDDATA;
1128 ✗ goto end;
1129 }
1130 }
1131 ✗ } else if (output_size < 132) {
1132 ✗ ret = AVERROR_INVALIDDATA;
1133 ✗ goto end;
1134 }
1135 }
1136
1137 ✗ ret = 0;
1138
1139 ✗ end:
1140 ✗ entropy_decoder_close(&dec);
1141
1142 ✗ return ret;
1143 }
1144
1145 337 static int skip_extensions(GetBitContext *gb)
1146 {
1147 337 uint64_t extensions = jxl_u64(gb), extensions_len = 0;
1148
1149
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 337 times.
337 if (get_bits_left(gb) < 0)
1150 ✗ return AVERROR_BUFFER_TOO_SMALL;
1151
1152
1/2
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
337 if (!extensions)
1153 337 return 0;
1154
1155 ✗ for (int i = 0; i < 64; i++) {
1156 ✗ if (extensions & (UINT64_C(1) << i))
1157 ✗ extensions_len += jxl_u64(gb);
1158 ✗ if (get_bits_left(gb) < 0)
1159 ✗ return AVERROR_BUFFER_TOO_SMALL;
1160 }
1161
1162 ✗ if (extensions_len > INT_MAX || get_bits_left(gb) < extensions_len)
1163 ✗ return AVERROR_BUFFER_TOO_SMALL;
1164
1165 ✗ skip_bits_long(gb, extensions_len);
1166
1167 ✗ return 0;
1168 }
1169
1170 193 static int parse_frame_header(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1171 {
1172 193 int all_default, do_yCbCr = 0, num_passes = 1, ret;
1173 193 int group_size_shift = 1, lf_level = 0, save_as_ref = 0;
1174 193 int have_crop = 0, full_frame = 1, resets_canvas = 1, upsampling = 1;
1175 193 JXLFrame *frame = &ctx->codestream.frame;
1176 193 const FFJXLMetadata *meta = &ctx->codestream.meta;
1177 193 int32_t x0 = 0, y0 = 0;
1178 193 uint32_t duration = 0, width = meta->coded_width, height = meta->coded_height;
1179 uint32_t name_len, num_groups, num_lf_groups, group_dim, lf_group_dim, toc_count;
1180 193 uint64_t flags = 0;
1181 193 int start_len = get_bits_count(gb);
1182
1183 193 memset(frame, 0, sizeof(*frame));
1184 193 frame->is_last = 1;
1185
1186 193 all_default = get_bits1(gb);
1187
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1188 193 frame->type = get_bits(gb, 2);
1189 193 frame->encoding = get_bits1(gb);
1190 193 flags = jxl_u64(gb);
1191
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (!meta->xyb_encoded)
1192 1 do_yCbCr = get_bits1(gb);
1193
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!(flags & JXL_FLAG_USE_LF_FRAME)) {
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (do_yCbCr)
1195 ✗ skip_bits(gb, 6); // jpeg upsampling
1196 193 upsampling = jxl_u32(gb, 1, 2, 4, 8, 0, 0, 0, 0);
1197 193 skip_bits_long(gb, 2 * meta->num_extra_channels);
1198
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1199 ✗ return AVERROR_BUFFER_TOO_SMALL;
1200 }
1201
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (frame->encoding == JPEGXL_ENC_MODULAR)
1202 1 group_size_shift = get_bits(gb, 2);
1203
1/2
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
192 else if (meta->xyb_encoded)
1204 192 skip_bits(gb, 6); // xqm and bqm scales
1205
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1206 193 num_passes = jxl_u32(gb, 1, 2, 3, 4, 0, 0, 0, 3);
1207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (num_passes != 1) {
1208 ✗ int num_ds = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 1);
1209 ✗ skip_bits(gb, 2 * (num_passes - 1)); // shift
1210 ✗ skip_bits(gb, 2 * num_ds); // downsample
1211 ✗ for (int i = 0; i < num_ds; i++)
1212 ✗ jxl_u32(gb, 0, 1, 2, 0, 0, 0, 0, 3);
1213 }
1214 }
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (frame->type == JPEGXL_FRAME_LF)
1216 ✗ lf_level = 1 + get_bits(gb, 2);
1217 else
1218 193 have_crop = get_bits1(gb);
1219
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 3 times.
193 if (have_crop) {
1220
1/2
✓ Branch 0 taken 190 times.
✗ Branch 1 not taken.
190 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1221 190 uint32_t ux0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1222 190 uint32_t uy0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 x0 = unpack_signed(ux0);
1224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 y0 = unpack_signed(uy0);
1225 }
1226 190 width = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1227 190 height = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1228
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
212 full_frame = x0 <= 0 && y0 <= 0 && width + x0 >= meta->coded_width
1229
2/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
212 && height + y0 >= meta->coded_height;
1230 }
1231
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1232 ✗ return AVERROR_BUFFER_TOO_SMALL;
1233
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
193 if (frame->type == JPEGXL_FRAME_REGULAR || frame->type == JPEGXL_FRAME_SKIP_PROGRESSIVE) {
1234
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 193 times.
435 for (int i = 0; i <= meta->num_extra_channels; i++) {
1235 242 int mode = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1236
4/6
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 98 times.
242 if (meta->num_extra_channels && (mode == JPEGXL_BM_BLEND || mode == JPEGXL_BM_MULADD))
1237 ✗ jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1238
4/6
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
242 if (meta->num_extra_channels && (mode == JPEGXL_BM_BLEND || mode == JPEGXL_BM_MULADD
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 || mode == JPEGXL_BM_MUL))
1240 ✗ skip_bits1(gb);
1241
2/2
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 49 times.
242 if (!i)
1242
3/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 190 times.
193 resets_canvas = mode == JPEGXL_BM_REPLACE && full_frame;
1243
2/2
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 4 times.
242 if (!resets_canvas)
1244 238 skip_bits(gb, 2);
1245
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
242 if (get_bits_left(gb) < 0)
1246 ✗ return AVERROR_BUFFER_TOO_SMALL;
1247 }
1248
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 144 times.
193 if (meta->animation_offset)
1249 49 duration = jxl_u32(gb, 0, 1, 0, 0, 0, 0, 8, 32);
1250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (meta->have_timecodes)
1251 ✗ skip_bits_long(gb, 32);
1252 193 frame->is_last = get_bits1(gb);
1253 } else {
1254 ✗ frame->is_last = 0;
1255 }
1256
3/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 185 times.
✓ Branch 3 taken 8 times.
193 if (frame->type != JPEGXL_FRAME_LF && !frame->is_last)
1257 185 save_as_ref = get_bits(gb, 2);
1258
3/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 190 times.
193 if (frame->type == JPEGXL_FRAME_REFERENCE_ONLY ||
1259
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
3 (resets_canvas && !frame->is_last && (!duration || save_as_ref)
1260 ✗ && frame->type != JPEGXL_FRAME_LF))
1261 ✗ skip_bits1(gb); // save before color transform
1262 193 name_len = 8 * jxl_u32(gb, 0, 0, 16, 48, 0, 4, 5, 10);
1263
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < name_len)
1264 ✗ return AVERROR_BUFFER_TOO_SMALL;
1265 193 skip_bits_long(gb, name_len);
1266 }
1267
1268
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1269 193 int restd = get_bits1(gb), gab = 1;
1270
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd)
1271 144 gab = get_bits1(gb);
1272
3/6
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
193 if (gab && !restd && get_bits1(gb))
1273 // gab custom
1274 ✗ skip_bits_long(gb, 16 * 6);
1275
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1276 ✗ return AVERROR_BUFFER_TOO_SMALL;
1277
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd) {
1278 144 int epf = get_bits(gb, 2);
1279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (epf) {
1280 ✗ if (frame->encoding == JPEGXL_ENC_VARDCT && get_bits1(gb)) {
1281 ✗ skip_bits_long(gb, 16 * 8); // custom epf sharpness
1282 ✗ if (get_bits_left(gb) < 0)
1283 ✗ return AVERROR_BUFFER_TOO_SMALL;
1284 }
1285 ✗ if (get_bits1(gb)) {
1286 ✗ skip_bits_long(gb, 3 * 16 + 32); // custom epf weight
1287 ✗ if (get_bits_left(gb) < 0)
1288 ✗ return AVERROR_BUFFER_TOO_SMALL;
1289 }
1290 ✗ if (get_bits1(gb)) { // custom epf sigma
1291 ✗ if (frame->encoding == JPEGXL_ENC_VARDCT)
1292 ✗ skip_bits(gb, 16);
1293 ✗ skip_bits_long(gb, 16 * 3);
1294 ✗ if (get_bits_left(gb) < 0)
1295 ✗ return AVERROR_BUFFER_TOO_SMALL;
1296 }
1297 ✗ if (frame->encoding == JPEGXL_ENC_MODULAR)
1298 ✗ skip_bits(gb, 16);
1299 }
1300 144 ret = skip_extensions(gb);
1301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (ret < 0)
1302 ✗ return ret;
1303 }
1304 193 ret = skip_extensions(gb);
1305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1306 ✗ return ret;
1307 }
1308
1309 193 width = div_ceil(div_ceil(width, upsampling), 1 << (3 * lf_level));
1310 193 height = div_ceil(div_ceil(height, upsampling), 1 << (3 * lf_level));
1311 193 group_dim = 128 << group_size_shift;
1312 193 lf_group_dim = group_dim << 3;
1313 193 num_groups = div_ceil(width, group_dim) * div_ceil(height, group_dim);
1314 193 num_lf_groups = div_ceil(width, lf_group_dim) * div_ceil(height, lf_group_dim);
1315
3/4
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
193 if (num_groups == 1 && num_passes == 1)
1316 150 toc_count = 1;
1317 else
1318 43 toc_count = 2 + num_lf_groups + num_groups * num_passes;
1319
1320 // permuted toc
1321
2/2
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 50 times.
193 if (get_bits1(gb)) {
1322 JXLEntropyDecoder dec;
1323 143 int64_t end, lehmer = 0;
1324 /* parser sanity check to prevent TOC perm from spinning cpu */
1325
2/4
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 143 times.
143 if (width > meta->coded_width * 8 || height > meta->coded_height * 8) {
1326 ✗ av_log(avctx, AV_LOG_WARNING, "frame of size %" PRIu32 "x%" PRIu32
1327 " exceeds max size of %" PRIu32 "x%" PRIu32 ", aborting parser\n",
1328 ✗ width, height, meta->coded_width * 8, meta->coded_height * 8);
1329 ✗ return AVERROR_INVALIDDATA;
1330 }
1331 143 ret = entropy_decoder_init(avctx, gb, &dec, 8);
1332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
1333 ✗ return ret;
1334
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0) {
1335 ✗ entropy_decoder_close(&dec);
1336 ✗ return AVERROR_BUFFER_TOO_SMALL;
1337 }
1338 143 end = entropy_decoder_read_symbol(gb, &dec, toc_context(toc_count));
1339
2/4
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 143 times.
143 if (end < 0 || end > toc_count) {
1340 ✗ entropy_decoder_close(&dec);
1341 ✗ return AVERROR_INVALIDDATA;
1342 }
1343
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 143 times.
875 for (uint32_t i = 0; i < end; i++) {
1344 732 lehmer = entropy_decoder_read_symbol(gb, &dec, toc_context(lehmer));
1345
2/4
✓ Branch 0 taken 732 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 732 times.
732 if (lehmer < 0 || get_bits_left(gb) < 0) {
1346 ✗ entropy_decoder_close(&dec);
1347 ✗ return lehmer < 0 ? lehmer : AVERROR_BUFFER_TOO_SMALL;
1348 }
1349 }
1350 143 entropy_decoder_close(&dec);
1351 }
1352 193 align_get_bits(gb);
1353
1354
2/2
✓ Branch 0 taken 782 times.
✓ Branch 1 taken 193 times.
975 for (uint32_t i = 0; i < toc_count; i++) {
1355 782 frame->body_length += 8 * jxl_u32(gb, 0, 1024, 17408, 4211712, 10, 14, 22, 30);
1356
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 782 times.
782 if (get_bits_left(gb) < 0)
1357 ✗ return AVERROR_BUFFER_TOO_SMALL;
1358 }
1359 193 align_get_bits(gb);
1360
1361 193 frame->total_length = frame->body_length + get_bits_count(gb) - start_len;
1362
1363 193 return 0;
1364 }
1365
1366 13 static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size)
1367 {
1368 GetByteContext gb;
1369
1370
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
13 if (ctx->skip > buf_size)
1371 5 return AVERROR_BUFFER_TOO_SMALL;
1372
1373 8 buf += ctx->skip;
1374 8 buf_size -= ctx->skip;
1375 8 bytestream2_init(&gb, buf, buf_size);
1376
1377 ✗ while (1) {
1378 uint64_t size;
1379 8 int head_size = 8;
1380
1381
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
1382 ✗ break;
1383
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
8 if (bytestream2_peek_le64(&gb) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
1384 3 break;
1385
1386
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
5 if (bytestream2_get_bytes_left(&gb) < 8)
1387 4 return AVERROR_BUFFER_TOO_SMALL;
1388
1389 1 size = bytestream2_get_be32(&gb);
1390 1 bytestream2_skip(&gb, 4); // tag
1391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size == 1) {
1392 ✗ if (bytestream2_get_bytes_left(&gb) < 8)
1393 ✗ return AVERROR_BUFFER_TOO_SMALL;
1394 ✗ size = bytestream2_get_be64(&gb);
1395 ✗ head_size = 16;
1396 }
1397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
1398 ✗ return AVERROR_INVALIDDATA;
1399 /* invalid ISOBMFF size */
1400
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (size <= head_size || size > INT_MAX - ctx->skip)
1401 ✗ return AVERROR_INVALIDDATA;
1402
1403 1 ctx->skip += size;
1404 1 bytestream2_skip(&gb, size - head_size);
1405
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (bytestream2_get_bytes_left(&gb) <= 0)
1406 1 return AVERROR_BUFFER_TOO_SMALL;
1407 }
1408
1409 3 return 0;
1410 }
1411
1412 94 static int64_t try_parse(AVCodecParserContext *s, AVCodecContext *avctx, JXLParseContext *ctx,
1413 const uint8_t *buf, int buf_size)
1414 {
1415 int ret, cs_buflen, header_skip;
1416 const uint8_t *cs_buffer;
1417 GetBitContext gb;
1418
1419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (ctx->skip > buf_size)
1420 ✗ return AVERROR_BUFFER_TOO_SMALL;
1421
1422 94 buf += ctx->skip;
1423 94 buf_size -= ctx->skip;
1424
1425
3/4
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 87 times.
94 if (ctx->container || AV_RL64(buf) == FF_JPEGXL_CONTAINER_SIGNATURE_LE) {
1426 7 ctx->container = 1;
1427 7 ret = ff_jpegxl_collect_codestream_header(buf, buf_size, ctx->cs_buffer,
1428 sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, &ctx->copied);
1429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
1430 ✗ return ret;
1431 7 ctx->collected_size = ret;
1432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!ctx->copied) {
1433 ✗ ctx->skip += ret;
1434 ✗ return AVERROR_BUFFER_TOO_SMALL;
1435 }
1436 7 cs_buffer = ctx->cs_buffer;
1437
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 cs_buflen = FFMIN(sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, ctx->copied);
1438 } else {
1439 87 cs_buffer = buf;
1440 87 cs_buflen = buf_size;
1441 }
1442
1443
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 72 times.
94 if (!ctx->codestream_length) {
1444 22 header_skip = ff_jpegxl_parse_codestream_header(cs_buffer, cs_buflen, &ctx->codestream.meta, 0);
1445
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 15 times.
22 if (header_skip < 0)
1446 7 return header_skip;
1447 15 ctx->codestream_length = header_skip;
1448 15 populate_fields(s, avctx, &ctx->codestream.meta);
1449 }
1450
1451
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 80 times.
87 if (ctx->container)
1452 7 return ctx->collected_size;
1453
1454 80 ret = init_get_bits8(&gb, cs_buffer, cs_buflen);
1455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (ret < 0)
1456 ✗ return ret;
1457
1458 80 skip_bits_long(&gb, ctx->codestream_length);
1459
1460
2/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
80 if (!ctx->skipped_icc && ctx->codestream.meta.have_icc_profile) {
1461 ✗ ret = skip_icc_profile(avctx, ctx, &gb);
1462 ✗ if (ret < 0)
1463 ✗ return ret;
1464 ✗ ctx->skipped_icc = 1;
1465 ✗ align_get_bits(&gb);
1466 ✗ ctx->codestream_length = get_bits_count(&gb);
1467 }
1468
1469
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 5 times.
80 if (get_bits_left(&gb) <= 0)
1470 5 return AVERROR_BUFFER_TOO_SMALL;
1471
1472 while (1) {
1473 193 ret = parse_frame_header(avctx, ctx, &gb);
1474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1475 ✗ return ret;
1476 193 ctx->codestream_length += ctx->codestream.frame.total_length;
1477
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 185 times.
193 if (ctx->codestream.frame.is_last)
1478 8 return ctx->codestream_length / 8;
1479
2/2
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 118 times.
185 if (get_bits_left(&gb) <= ctx->codestream.frame.body_length)
1480 67 return AVERROR_BUFFER_TOO_SMALL;
1481 118 skip_bits_long(&gb, ctx->codestream.frame.body_length);
1482 }
1483 }
1484
1485 101 static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx,
1486 const uint8_t **poutbuf, int *poutbuf_size,
1487 const uint8_t *buf, int buf_size)
1488 {
1489 101 JXLParseContext *ctx = s->priv_data;
1490 101 int next = END_NOT_FOUND, ret;
1491 101 const uint8_t *pbuf = ctx->pc.buffer;
1492 101 int pindex = ctx->pc.index;
1493
1494 101 *poutbuf_size = 0;
1495 101 *poutbuf = NULL;
1496
1497
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 79 times.
101 if (!ctx->pc.index) {
1498
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 21 times.
22 if (ctx->pc.overread)
1499 1 goto flush;
1500 21 pbuf = buf;
1501 21 pindex = buf_size;
1502 }
1503
1504
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
100 if ((!ctx->container || !ctx->codestream_length) && !ctx->next) {
1505 94 int64_t ret64 = try_parse(s, avctx, ctx, pbuf, pindex);
1506
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 15 times.
94 if (ret64 < 0)
1507 79 goto flush;
1508 15 ctx->next = ret64;
1509
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8 times.
15 if (ctx->container)
1510 7 ctx->skip += ctx->next;
1511 }
1512
1513
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
21 if (ctx->container && ctx->next >= 0) {
1514 13 ret = skip_boxes(ctx, pbuf, pindex);
1515
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 if (ret < 0) {
1516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret == AVERROR_INVALIDDATA)
1517 ✗ ctx->next = -1;
1518 10 goto flush;
1519 }
1520 3 ctx->next = ret + ctx->skip;
1521 }
1522
1523
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ctx->next >= 0)
1524 11 next = ctx->next - ctx->pc.index;
1525
1526 ✗ flush:
1527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 101 times.
101 if (next > buf_size)
1528 ✗ next = END_NOT_FOUND;
1529
1530 101 ret = ff_combine_frame(&ctx->pc, next, &buf, &buf_size);
1531
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 22 times.
101 if (ret < 0)
1532 79 return buf_size;
1533
1534 22 *poutbuf = buf;
1535 22 *poutbuf_size = buf_size;
1536
1537 22 ctx->codestream_length = 0;
1538 22 ctx->collected_size = 0;
1539 22 ctx->container = 0;
1540 22 ctx->copied = 0;
1541 22 ctx->skip = 0;
1542 22 ctx->skipped_icc = 0;
1543 22 ctx->next = 0;
1544 22 memset(&ctx->codestream, 0, sizeof(ctx->codestream));
1545
1546 22 return next;
1547 }
1548
1549 const FFCodecParser ff_jpegxl_parser = {
1550 PARSER_CODEC_LIST(AV_CODEC_ID_JPEGXL, AV_CODEC_ID_JPEGXL_ANIM),
1551 .priv_data_size = sizeof(JXLParseContext),
1552 .parse = jpegxl_parse,
1553 .close = ff_parse_close,
1554 };
1555