FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/jpegxl_parser.c
Date: 2026-11-01 12:52:33
Exec Total Coverage
Lines: 456 943 48.4%
Functions: 21 27 77.8%
Branches: 260 694 37.5%

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 17 static void populate_fields(AVCodecParserContext *s, AVCodecContext *avctx, const FFJXLMetadata *meta)
995 {
996 17 s->width = meta->width;
997 17 s->height = meta->height;
998
999
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 switch (meta->csp) {
1000 17 case JPEGXL_CS_RGB:
1001 case JPEGXL_CS_XYB:
1002 17 avctx->colorspace = AVCOL_SPC_RGB;
1003 17 break;
1004 ✗ default:
1005 ✗ avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
1006 }
1007
1008
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (meta->wp == JPEGXL_WP_D65) {
1009
1/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 switch (meta->primaries) {
1010 17 case JPEGXL_PR_SRGB:
1011 17 avctx->color_primaries = AVCOL_PRI_BT709;
1012 17 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 17 times.
✗ Branch 1 not taken.
17 if (meta->trc > JPEGXL_TR_GAMMA) {
1029 17 FFJXLTransferCharacteristic trc = meta->trc - JPEGXL_TR_GAMMA;
1030
1/7
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
17 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 17 case JPEGXL_TR_SRGB:
1038 17 avctx->color_trc = AVCOL_TRC_IEC61966_2_1;
1039 17 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 17 times.
17 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 17 times.
✗ Branch 1 not taken.
17 if (meta->bit_depth <= 8)
1072
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 15 times.
17 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 15 times.
17 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 17 }
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 15 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 10 times.
15 if (ctx->skip > buf_size)
1371 5 return AVERROR_BUFFER_TOO_SMALL;
1372
1373 10 buf += ctx->skip;
1374 10 buf_size -= ctx->skip;
1375 10 bytestream2_init(&gb, buf, buf_size);
1376
1377 1 while (1) {
1378 uint64_t size;
1379 11 int head_size = 8;
1380
1381
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
1382 ✗ break;
1383
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
11 if (bytestream2_peek_le64(&gb) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
1384 4 break;
1385
1386
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
7 if (bytestream2_get_bytes_left(&gb) < 8)
1387 4 return AVERROR_BUFFER_TOO_SMALL;
1388
1389 3 size = bytestream2_get_be32(&gb);
1390 3 bytestream2_skip(&gb, 4); // tag
1391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 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
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 } else if (!size) {
1397 /* the box extends to the end of the file */
1398 1 return END_NOT_FOUND;
1399 }
1400 /* invalid ISOBMFF size */
1401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (size < head_size)
1402 ✗ return AVERROR_INVALIDDATA;
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (size > INT_MAX - ctx->skip)
1404 ✗ return END_NOT_FOUND;
1405
1406 2 ctx->skip += size;
1407 2 bytestream2_skip(&gb, size - head_size);
1408
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (bytestream2_get_bytes_left(&gb) <= 0)
1409 1 return AVERROR_BUFFER_TOO_SMALL;
1410 }
1411
1412 4 return 0;
1413 }
1414
1415 97 static int64_t try_parse(AVCodecParserContext *s, AVCodecContext *avctx, JXLParseContext *ctx,
1416 const uint8_t *buf, int buf_size)
1417 {
1418 int ret, cs_buflen, header_skip;
1419 const uint8_t *cs_buffer;
1420 GetBitContext gb;
1421
1422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (ctx->skip > buf_size)
1423 ✗ return AVERROR_BUFFER_TOO_SMALL;
1424
1425 97 buf += ctx->skip;
1426 97 buf_size -= ctx->skip;
1427
1428
3/4
✓ Branch 0 taken 97 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 88 times.
97 if (ctx->container || AV_RL64(buf) == FF_JPEGXL_CONTAINER_SIGNATURE_LE) {
1429 9 ctx->container = 1;
1430 9 ret = ff_jpegxl_collect_codestream_header(buf, buf_size, ctx->cs_buffer,
1431 sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, &ctx->copied);
1432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ret < 0)
1433 ✗ return ret;
1434 9 ctx->collected_size = ret;
1435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!ctx->copied) {
1436 ✗ ctx->skip += ret;
1437 ✗ return AVERROR_BUFFER_TOO_SMALL;
1438 }
1439 9 cs_buffer = ctx->cs_buffer;
1440
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 cs_buflen = FFMIN(sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, ctx->copied);
1441 } else {
1442 88 cs_buffer = buf;
1443 88 cs_buflen = buf_size;
1444 }
1445
1446
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 72 times.
97 if (!ctx->codestream_length) {
1447 25 header_skip = ff_jpegxl_parse_codestream_header(cs_buffer, cs_buflen, &ctx->codestream.meta, 0);
1448
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 17 times.
25 if (header_skip < 0)
1449 8 return header_skip;
1450 17 ctx->codestream_length = header_skip;
1451 17 populate_fields(s, avctx, &ctx->codestream.meta);
1452 }
1453
1454
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 80 times.
89 if (ctx->container)
1455 9 return ctx->collected_size;
1456
1457 80 ret = init_get_bits8(&gb, cs_buffer, cs_buflen);
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (ret < 0)
1459 ✗ return ret;
1460
1461 80 skip_bits_long(&gb, ctx->codestream_length);
1462
1463
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) {
1464 ✗ ret = skip_icc_profile(avctx, ctx, &gb);
1465 ✗ if (ret < 0)
1466 ✗ return ret;
1467 ✗ ctx->skipped_icc = 1;
1468 ✗ align_get_bits(&gb);
1469 ✗ ctx->codestream_length = get_bits_count(&gb);
1470 }
1471
1472
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 5 times.
80 if (get_bits_left(&gb) <= 0)
1473 5 return AVERROR_BUFFER_TOO_SMALL;
1474
1475 while (1) {
1476 193 ret = parse_frame_header(avctx, ctx, &gb);
1477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1478 ✗ return ret;
1479 193 ctx->codestream_length += ctx->codestream.frame.total_length;
1480
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 185 times.
193 if (ctx->codestream.frame.is_last)
1481 8 return ctx->codestream_length / 8;
1482
2/2
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 118 times.
185 if (get_bits_left(&gb) <= ctx->codestream.frame.body_length)
1483 67 return AVERROR_BUFFER_TOO_SMALL;
1484 118 skip_bits_long(&gb, ctx->codestream.frame.body_length);
1485 }
1486 }
1487
1488 105 static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx,
1489 const uint8_t **poutbuf, int *poutbuf_size,
1490 const uint8_t *buf, int buf_size)
1491 {
1492 105 JXLParseContext *ctx = s->priv_data;
1493 105 int next = END_NOT_FOUND, ret;
1494 105 const uint8_t *pbuf = ctx->pc.buffer;
1495 105 int pindex = ctx->pc.index;
1496
1497 105 *poutbuf_size = 0;
1498 105 *poutbuf = NULL;
1499
1500
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 80 times.
105 if (!ctx->pc.index) {
1501
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
25 if (ctx->pc.overread)
1502 1 goto flush;
1503 24 pbuf = buf;
1504 24 pindex = buf_size;
1505 }
1506
1507
4/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 97 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 97 times.
✗ Branch 5 not taken.
104 if ((!ctx->container || !ctx->codestream_length) && !ctx->next) {
1508 97 int64_t ret64 = try_parse(s, avctx, ctx, pbuf, pindex);
1509
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 17 times.
97 if (ret64 < 0)
1510 80 goto flush;
1511 17 ctx->next = ret64;
1512
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
17 if (ctx->container)
1513 9 ctx->skip += ctx->next;
1514 }
1515
1516
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1 times.
24 if (ctx->container && ctx->next >= 0) {
1517 15 ret = skip_boxes(ctx, pbuf, pindex);
1518
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
15 if (ret == END_NOT_FOUND) {
1519 /* the rest of the stream belongs to this image */
1520 1 ctx->next = -1;
1521 1 goto flush;
1522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 } else if (ret == AVERROR_INVALIDDATA) {
1523 /* end the image at the invalid box */
1524 ✗ av_log(avctx, AV_LOG_ERROR, "Invalid ISOBMFF box size\n");
1525 ✗ ctx->next = ctx->skip;
1526
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
14 } else if (ret < 0) {
1527 10 goto flush;
1528 } else {
1529 4 ctx->next = ret + ctx->skip;
1530 }
1531 }
1532
1533
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (ctx->next >= 0)
1534 12 next = ctx->next - ctx->pc.index;
1535
1536 1 flush:
1537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
105 if (next > buf_size)
1538 ✗ next = END_NOT_FOUND;
1539
1540 105 ret = ff_combine_frame(&ctx->pc, next, &buf, &buf_size);
1541
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 25 times.
105 if (ret < 0)
1542 80 return buf_size;
1543
1544 25 *poutbuf = buf;
1545 25 *poutbuf_size = buf_size;
1546
1547 25 ctx->codestream_length = 0;
1548 25 ctx->collected_size = 0;
1549 25 ctx->container = 0;
1550 25 ctx->copied = 0;
1551 25 ctx->skip = 0;
1552 25 ctx->skipped_icc = 0;
1553 25 ctx->next = 0;
1554 25 memset(&ctx->codestream, 0, sizeof(ctx->codestream));
1555
1556 25 return next;
1557 }
1558
1559 const FFCodecParser ff_jpegxl_parser = {
1560 PARSER_CODEC_LIST(AV_CODEC_ID_JPEGXL, AV_CODEC_ID_JPEGXL_ANIM),
1561 .priv_data_size = sizeof(JXLParseContext),
1562 .parse = jpegxl_parse,
1563 .close = ff_parse_close,
1564 };
1565