FFmpeg coverage


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