FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/jpegxl_parser.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 445 930 47.8%
Functions: 21 27 77.8%
Branches: 249 682 36.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 #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 int skip;
159 int copied;
160 int collected_size;
161 int codestream_length;
162 int skipped_icc;
163 int 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 14 }
1078
1079 static int skip_icc_profile(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1080 {
1081 int64_t ret;
1082 uint32_t last = 0, last2 = 0;
1083 JXLEntropyDecoder dec = { 0 };
1084 uint64_t enc_size = jxl_u64(gb);
1085 uint64_t output_size = 0;
1086 int out_size_shift = 0;
1087
1088 if (!enc_size || enc_size > (1 << 22))
1089 return AVERROR_INVALIDDATA;
1090
1091 ret = entropy_decoder_init(avctx, gb, &dec, 41);
1092 if (ret < 0)
1093 goto end;
1094
1095 if (get_bits_left(gb) < 0) {
1096 ret = AVERROR_BUFFER_TOO_SMALL;
1097 goto end;
1098 }
1099
1100 for (uint64_t read = 0; read < enc_size; read++) {
1101 ret = entropy_decoder_read_symbol(gb, &dec, icc_context(read, last, last2));
1102 if (ret < 0)
1103 goto end;
1104 if (ret > 255) {
1105 ret = AVERROR_INVALIDDATA;
1106 goto end;
1107 }
1108 if (get_bits_left(gb) < 0) {
1109 ret = AVERROR_BUFFER_TOO_SMALL;
1110 goto end;
1111 }
1112 last2 = last;
1113 last = ret;
1114 if (out_size_shift < 63) {
1115 output_size += (ret & UINT64_C(0x7F)) << out_size_shift;
1116 if (!(ret & 0x80)) {
1117 out_size_shift = 63;
1118 } else {
1119 out_size_shift += 7;
1120 if (out_size_shift > 56) {
1121 ret = AVERROR_INVALIDDATA;
1122 goto end;
1123 }
1124 }
1125 } else if (output_size < 132) {
1126 ret = AVERROR_INVALIDDATA;
1127 goto end;
1128 }
1129 }
1130
1131 ret = 0;
1132
1133 end:
1134 entropy_decoder_close(&dec);
1135
1136 return ret;
1137 }
1138
1139 337 static int skip_extensions(GetBitContext *gb)
1140 {
1141 337 uint64_t extensions = jxl_u64(gb), extensions_len = 0;
1142
1143
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 337 times.
337 if (get_bits_left(gb) < 0)
1144 return AVERROR_BUFFER_TOO_SMALL;
1145
1146
1/2
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
337 if (!extensions)
1147 337 return 0;
1148
1149 for (int i = 0; i < 64; i++) {
1150 if (extensions & (UINT64_C(1) << i))
1151 extensions_len += jxl_u64(gb);
1152 if (get_bits_left(gb) < 0)
1153 return AVERROR_BUFFER_TOO_SMALL;
1154 }
1155
1156 if (extensions_len > INT_MAX || get_bits_left(gb) < extensions_len)
1157 return AVERROR_BUFFER_TOO_SMALL;
1158
1159 skip_bits_long(gb, extensions_len);
1160
1161 return 0;
1162 }
1163
1164 193 static int parse_frame_header(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1165 {
1166 193 int all_default, do_yCbCr = 0, num_passes = 1, ret;
1167 193 int group_size_shift = 1, lf_level = 0, save_as_ref = 0;
1168 193 int have_crop = 0, full_frame = 1, resets_canvas = 1, upsampling = 1;
1169 193 JXLFrame *frame = &ctx->codestream.frame;
1170 193 const FFJXLMetadata *meta = &ctx->codestream.meta;
1171 193 int32_t x0 = 0, y0 = 0;
1172 193 uint32_t duration = 0, width = meta->coded_width, height = meta->coded_height;
1173 uint32_t name_len, num_groups, num_lf_groups, group_dim, lf_group_dim, toc_count;
1174 193 uint64_t flags = 0;
1175 193 int start_len = get_bits_count(gb);
1176
1177 193 memset(frame, 0, sizeof(*frame));
1178 193 frame->is_last = 1;
1179
1180 193 all_default = get_bits1(gb);
1181
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1182 193 frame->type = get_bits(gb, 2);
1183 193 frame->encoding = get_bits1(gb);
1184 193 flags = jxl_u64(gb);
1185
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (!meta->xyb_encoded)
1186 1 do_yCbCr = get_bits1(gb);
1187
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!(flags & JXL_FLAG_USE_LF_FRAME)) {
1188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (do_yCbCr)
1189 skip_bits(gb, 6); // jpeg upsampling
1190 193 upsampling = jxl_u32(gb, 1, 2, 4, 8, 0, 0, 0, 0);
1191 193 skip_bits_long(gb, 2 * meta->num_extra_channels);
1192
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1193 return AVERROR_BUFFER_TOO_SMALL;
1194 }
1195
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (frame->encoding == JPEGXL_ENC_MODULAR)
1196 1 group_size_shift = get_bits(gb, 2);
1197
1/2
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
192 else if (meta->xyb_encoded)
1198 192 skip_bits(gb, 6); // xqm and bqm scales
1199
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1200 193 num_passes = jxl_u32(gb, 1, 2, 3, 4, 0, 0, 0, 3);
1201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (num_passes != 1) {
1202 int num_ds = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 1);
1203 skip_bits(gb, 2 * (num_passes - 1)); // shift
1204 skip_bits(gb, 2 * num_ds); // downsample
1205 for (int i = 0; i < num_ds; i++)
1206 jxl_u32(gb, 0, 1, 2, 0, 0, 0, 0, 3);
1207 }
1208 }
1209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (frame->type == JPEGXL_FRAME_LF)
1210 lf_level = 1 + get_bits(gb, 2);
1211 else
1212 193 have_crop = get_bits1(gb);
1213
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 3 times.
193 if (have_crop) {
1214
1/2
✓ Branch 0 taken 190 times.
✗ Branch 1 not taken.
190 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1215 190 uint32_t ux0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1216 190 uint32_t uy0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 x0 = unpack_signed(ux0);
1218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 y0 = unpack_signed(uy0);
1219 }
1220 190 width = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1221 190 height = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1222
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
1223
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;
1224 }
1225
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1226 return AVERROR_BUFFER_TOO_SMALL;
1227
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) {
1228
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 193 times.
435 for (int i = 0; i <= meta->num_extra_channels; i++) {
1229 242 int mode = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1230
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))
1231 jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1232
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
1233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 || mode == JPEGXL_BM_MUL))
1234 skip_bits1(gb);
1235
2/2
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 49 times.
242 if (!i)
1236
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;
1237
2/2
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 4 times.
242 if (!resets_canvas)
1238 238 skip_bits(gb, 2);
1239
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
242 if (get_bits_left(gb) < 0)
1240 return AVERROR_BUFFER_TOO_SMALL;
1241 }
1242
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 144 times.
193 if (meta->animation_offset)
1243 49 duration = jxl_u32(gb, 0, 1, 0, 0, 0, 0, 8, 32);
1244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (meta->have_timecodes)
1245 skip_bits_long(gb, 32);
1246 193 frame->is_last = get_bits1(gb);
1247 } else {
1248 frame->is_last = 0;
1249 }
1250
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)
1251 185 save_as_ref = get_bits(gb, 2);
1252
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 ||
1253
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)
1254 && frame->type != JPEGXL_FRAME_LF))
1255 skip_bits1(gb); // save before color transform
1256 193 name_len = 8 * jxl_u32(gb, 0, 0, 16, 48, 0, 4, 5, 10);
1257
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < name_len)
1258 return AVERROR_BUFFER_TOO_SMALL;
1259 193 skip_bits_long(gb, name_len);
1260 }
1261
1262
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1263 193 int restd = get_bits1(gb), gab = 1;
1264
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd)
1265 144 gab = get_bits1(gb);
1266
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))
1267 // gab custom
1268 skip_bits_long(gb, 16 * 6);
1269
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1270 return AVERROR_BUFFER_TOO_SMALL;
1271
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd) {
1272 144 int epf = get_bits(gb, 2);
1273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (epf) {
1274 if (frame->encoding == JPEGXL_ENC_VARDCT && get_bits1(gb)) {
1275 skip_bits_long(gb, 16 * 8); // custom epf sharpness
1276 if (get_bits_left(gb) < 0)
1277 return AVERROR_BUFFER_TOO_SMALL;
1278 }
1279 if (get_bits1(gb)) {
1280 skip_bits_long(gb, 3 * 16 + 32); // custom epf weight
1281 if (get_bits_left(gb) < 0)
1282 return AVERROR_BUFFER_TOO_SMALL;
1283 }
1284 if (get_bits1(gb)) { // custom epf sigma
1285 if (frame->encoding == JPEGXL_ENC_VARDCT)
1286 skip_bits(gb, 16);
1287 skip_bits_long(gb, 16 * 3);
1288 if (get_bits_left(gb) < 0)
1289 return AVERROR_BUFFER_TOO_SMALL;
1290 }
1291 if (frame->encoding == JPEGXL_ENC_MODULAR)
1292 skip_bits(gb, 16);
1293 }
1294 144 ret = skip_extensions(gb);
1295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (ret < 0)
1296 return ret;
1297 }
1298 193 ret = skip_extensions(gb);
1299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1300 return ret;
1301 }
1302
1303 193 width = div_ceil(div_ceil(width, upsampling), 1 << (3 * lf_level));
1304 193 height = div_ceil(div_ceil(height, upsampling), 1 << (3 * lf_level));
1305 193 group_dim = 128 << group_size_shift;
1306 193 lf_group_dim = group_dim << 3;
1307 193 num_groups = div_ceil(width, group_dim) * div_ceil(height, group_dim);
1308 193 num_lf_groups = div_ceil(width, lf_group_dim) * div_ceil(height, lf_group_dim);
1309
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)
1310 150 toc_count = 1;
1311 else
1312 43 toc_count = 2 + num_lf_groups + num_groups * num_passes;
1313
1314 // permuted toc
1315
2/2
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 50 times.
193 if (get_bits1(gb)) {
1316 JXLEntropyDecoder dec;
1317 143 int64_t end, lehmer = 0;
1318 143 ret = entropy_decoder_init(avctx, gb, &dec, 8);
1319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
1320 return ret;
1321
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0) {
1322 entropy_decoder_close(&dec);
1323 return AVERROR_BUFFER_TOO_SMALL;
1324 }
1325 143 end = entropy_decoder_read_symbol(gb, &dec, toc_context(toc_count));
1326
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) {
1327 entropy_decoder_close(&dec);
1328 return AVERROR_INVALIDDATA;
1329 }
1330
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 143 times.
875 for (uint32_t i = 0; i < end; i++) {
1331 732 lehmer = entropy_decoder_read_symbol(gb, &dec, toc_context(lehmer));
1332
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) {
1333 entropy_decoder_close(&dec);
1334 return AVERROR_BUFFER_TOO_SMALL;
1335 }
1336 }
1337 143 entropy_decoder_close(&dec);
1338 }
1339 193 align_get_bits(gb);
1340
1341
2/2
✓ Branch 0 taken 782 times.
✓ Branch 1 taken 193 times.
975 for (uint32_t i = 0; i < toc_count; i++) {
1342 782 frame->body_length += 8 * jxl_u32(gb, 0, 1024, 17408, 4211712, 10, 14, 22, 30);
1343
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 782 times.
782 if (get_bits_left(gb) < 0)
1344 return AVERROR_BUFFER_TOO_SMALL;
1345 }
1346 193 align_get_bits(gb);
1347
1348 193 frame->total_length = frame->body_length + get_bits_count(gb) - start_len;
1349
1350 193 return 0;
1351 }
1352
1353 10 static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size)
1354 {
1355 GetByteContext gb;
1356
1357
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 if (ctx->skip > buf_size)
1358 3 return AVERROR_BUFFER_TOO_SMALL;
1359
1360 7 buf += ctx->skip;
1361 7 buf_size -= ctx->skip;
1362 7 bytestream2_init(&gb, buf, buf_size);
1363
1364 while (1) {
1365 uint64_t size;
1366 7 int head_size = 8;
1367
1368
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
1369 break;
1370
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
7 if (bytestream2_peek_le64(&gb) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
1371 3 break;
1372
1373
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (bytestream2_get_bytes_left(&gb) < 8)
1374 3 return AVERROR_BUFFER_TOO_SMALL;
1375
1376 1 size = bytestream2_get_be32(&gb);
1377 1 bytestream2_skip(&gb, 4); // tag
1378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size == 1) {
1379 if (bytestream2_get_bytes_left(&gb) < 8)
1380 return AVERROR_BUFFER_TOO_SMALL;
1381 size = bytestream2_get_be64(&gb);
1382 head_size = 16;
1383 }
1384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
1385 return AVERROR_INVALIDDATA;
1386 /* invalid ISOBMFF size */
1387
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)
1388 return AVERROR_INVALIDDATA;
1389
1390 1 ctx->skip += size;
1391 1 bytestream2_skip(&gb, size - head_size);
1392
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (bytestream2_get_bytes_left(&gb) <= 0)
1393 1 return AVERROR_BUFFER_TOO_SMALL;
1394 }
1395
1396 3 return 0;
1397 }
1398
1399 92 static int try_parse(AVCodecParserContext *s, AVCodecContext *avctx, JXLParseContext *ctx,
1400 const uint8_t *buf, int buf_size)
1401 {
1402 int ret, cs_buflen, header_skip;
1403 const uint8_t *cs_buffer;
1404 GetBitContext gb;
1405
1406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (ctx->skip > buf_size)
1407 return AVERROR_BUFFER_TOO_SMALL;
1408
1409 92 buf += ctx->skip;
1410 92 buf_size -= ctx->skip;
1411
1412
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) {
1413 6 ctx->container = 1;
1414 6 ret = ff_jpegxl_collect_codestream_header(buf, buf_size, ctx->cs_buffer,
1415 sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, &ctx->copied);
1416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1417 return ret;
1418 6 ctx->collected_size = ret;
1419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctx->copied) {
1420 ctx->skip += ret;
1421 return AVERROR_BUFFER_TOO_SMALL;
1422 }
1423 6 cs_buffer = ctx->cs_buffer;
1424
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);
1425 } else {
1426 86 cs_buffer = buf;
1427 86 cs_buflen = buf_size;
1428 }
1429
1430
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 72 times.
92 if (!ctx->codestream_length) {
1431 20 header_skip = ff_jpegxl_parse_codestream_header(cs_buffer, cs_buflen, &ctx->codestream.meta, 0);
1432
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14 times.
20 if (header_skip < 0)
1433 6 return header_skip;
1434 14 ctx->codestream_length = header_skip;
1435 14 populate_fields(s, avctx, &ctx->codestream.meta);
1436 }
1437
1438
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 80 times.
86 if (ctx->container)
1439 6 return ctx->collected_size;
1440
1441 80 ret = init_get_bits8(&gb, cs_buffer, cs_buflen);
1442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (ret < 0)
1443 return ret;
1444
1445 80 skip_bits_long(&gb, ctx->codestream_length);
1446
1447
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) {
1448 ret = skip_icc_profile(avctx, ctx, &gb);
1449 if (ret < 0)
1450 return ret;
1451 ctx->skipped_icc = 1;
1452 align_get_bits(&gb);
1453 ctx->codestream_length = get_bits_count(&gb);
1454 }
1455
1456
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 5 times.
80 if (get_bits_left(&gb) <= 0)
1457 5 return AVERROR_BUFFER_TOO_SMALL;
1458
1459 while (1) {
1460 193 ret = parse_frame_header(avctx, ctx, &gb);
1461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1462 return ret;
1463 193 ctx->codestream_length += ctx->codestream.frame.total_length;
1464
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 185 times.
193 if (ctx->codestream.frame.is_last)
1465 8 return ctx->codestream_length / 8;
1466
2/2
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 118 times.
185 if (get_bits_left(&gb) <= ctx->codestream.frame.body_length)
1467 67 return AVERROR_BUFFER_TOO_SMALL;
1468 118 skip_bits_long(&gb, ctx->codestream.frame.body_length);
1469 }
1470 }
1471
1472 97 static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx,
1473 const uint8_t **poutbuf, int *poutbuf_size,
1474 const uint8_t *buf, int buf_size)
1475 {
1476 97 JXLParseContext *ctx = s->priv_data;
1477 97 int next = END_NOT_FOUND, ret;
1478 97 const uint8_t *pbuf = ctx->pc.buffer;
1479 97 int pindex = ctx->pc.index;
1480
1481 97 *poutbuf_size = 0;
1482 97 *poutbuf = NULL;
1483
1484
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 77 times.
97 if (!ctx->pc.index) {
1485
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
20 if (ctx->pc.overread)
1486 1 goto flush;
1487 19 pbuf = buf;
1488 19 pindex = buf_size;
1489 }
1490
1491
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) {
1492 92 ret = try_parse(s, avctx, ctx, pbuf, pindex);
1493
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 14 times.
92 if (ret < 0)
1494 78 goto flush;
1495 14 ctx->next = ret;
1496
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (ctx->container)
1497 6 ctx->skip += ctx->next;
1498 }
1499
1500
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) {
1501 10 ret = skip_boxes(ctx, pbuf, pindex);
1502
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3 times.
10 if (ret < 0) {
1503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret == AVERROR_INVALIDDATA)
1504 ctx->next = -1;
1505 7 goto flush;
1506 }
1507 3 ctx->next = ret + ctx->skip;
1508 }
1509
1510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ctx->next >= 0)
1511 11 next = ctx->next - ctx->pc.index;
1512
1513 flush:
1514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (next > buf_size)
1515 next = END_NOT_FOUND;
1516
1517 97 ret = ff_combine_frame(&ctx->pc, next, &buf, &buf_size);
1518
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 20 times.
97 if (ret < 0)
1519 77 return buf_size;
1520
1521 20 *poutbuf = buf;
1522 20 *poutbuf_size = buf_size;
1523
1524 20 ctx->codestream_length = 0;
1525 20 ctx->collected_size = 0;
1526 20 ctx->container = 0;
1527 20 ctx->copied = 0;
1528 20 ctx->skip = 0;
1529 20 ctx->skipped_icc = 0;
1530 20 ctx->next = 0;
1531 20 memset(&ctx->codestream, 0, sizeof(ctx->codestream));
1532
1533 20 return next;
1534 }
1535
1536 const AVCodecParser ff_jpegxl_parser = {
1537 .codec_ids = { AV_CODEC_ID_JPEGXL },
1538 .priv_data_size = sizeof(JXLParseContext),
1539 .parser_parse = jpegxl_parse,
1540 .parser_close = ff_parse_close,
1541 };
1542