FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/jpegxl_parser.c
Date: 2024-04-20 14:10:07
Exec Total Coverage
Lines: 445 927 48.0%
Functions: 21 27 77.8%
Branches: 247 676 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 ret = read_hybrid_uint(gb, &bundle->lz_len_conf, token - bundle->lz77_min_symbol, &dec->num_to_copy);
356 if (ret < 0)
357 return ret;
358 dec->num_to_copy += bundle->lz77_min_length;
359 if (bundle->use_prefix_code)
360 token = read_prefix_symbol(gb, lz77dist);
361 else
362 token = read_ans_symbol(gb, dec, lz77dist);
363 ret = read_hybrid_uint(gb, &lz77dist->config, token, &distance);
364 if (ret < 0)
365 return ret;
366 distance++;
367 distance = FFMIN3(distance, dec->num_decoded, 1 << 20);
368 dec->copy_pos = dec->num_decoded - distance;
369 return decode_hybrid_varlen_uint(gb, dec, bundle, context, hybrid_uint);
370 }
371 875 ret = read_hybrid_uint(gb, &dist->config, token, hybrid_uint);
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (ret < 0)
373 return ret;
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (bundle->lz77_enabled)
375 dec->window[dec->num_decoded++ & 0xFFFFF] = *hybrid_uint;
376
377 875 return 0;
378 }
379
380 static int populate_distribution(GetBitContext *gb, JXLSymbolDistribution *dist, int log_alphabet_size)
381 {
382 int len = 0, shift, omit_log = -1, omit_pos = -1;
383 int prev = 0, num_same = 0;
384 uint32_t total_count = 0;
385 uint8_t logcounts[258] = { 0 };
386 uint8_t same[258] = { 0 };
387 const int table_size = 1 << log_alphabet_size;
388 dist->uniq_pos = -1;
389
390 if (get_bits1(gb)) {
391 /* simple code */
392 if (get_bits1(gb)) {
393 uint8_t v1 = jxl_u8(gb);
394 uint8_t v2 = jxl_u8(gb);
395 if (v1 == v2)
396 return AVERROR_INVALIDDATA;
397 dist->freq[v1] = get_bits(gb, 12);
398 dist->freq[v2] = (1 << 12) - dist->freq[v1];
399 if (!dist->freq[v1])
400 dist->uniq_pos = v2;
401 dist->alphabet_size = 1 + FFMAX(v1, v2);
402 } else {
403 uint8_t x = jxl_u8(gb);
404 dist->freq[x] = 1 << 12;
405 dist->uniq_pos = x;
406 dist->alphabet_size = 1 + x;
407 }
408 if (dist->alphabet_size > table_size)
409 return AVERROR_INVALIDDATA;
410
411 return 0;
412 }
413
414 if (get_bits1(gb)) {
415 /* flat code */
416 dist->alphabet_size = jxl_u8(gb) + 1;
417 if (dist->alphabet_size > table_size)
418 return AVERROR_INVALIDDATA;
419 for (int i = 0; i < dist->alphabet_size; i++)
420 dist->freq[i] = (1 << 12) / dist->alphabet_size;
421 for (int i = 0; i < (1 << 12) % dist->alphabet_size; i++)
422 dist->freq[i]++;
423 return 0;
424 }
425
426 do {
427 if (!get_bits1(gb))
428 break;
429 } while (++len < 3);
430
431 shift = (get_bitsz(gb, len) | (1 << len)) - 1;
432 if (shift > 13)
433 return AVERROR_INVALIDDATA;
434
435 dist->alphabet_size = jxl_u8(gb) + 3;
436 if (dist->alphabet_size > table_size)
437 return AVERROR_INVALIDDATA;
438
439 for (int i = 0; i < dist->alphabet_size; i++) {
440 logcounts[i] = get_vlc2(gb, dist_prefix_table, 7, 1);
441 if (logcounts[i] == 13) {
442 int rle = jxl_u8(gb);
443 same[i] = rle + 5;
444 i += rle + 3;
445 continue;
446 }
447 if (logcounts[i] > omit_log) {
448 omit_log = logcounts[i];
449 omit_pos = i;
450 }
451 }
452 if (omit_pos < 0 || omit_pos + 1 < dist->alphabet_size && logcounts[omit_pos + 1] == 13)
453 return AVERROR_INVALIDDATA;
454
455 for (int i = 0; i < dist->alphabet_size; i++) {
456 if (same[i]) {
457 num_same = same[i] - 1;
458 prev = i > 0 ? dist->freq[i - 1] : 0;
459 }
460 if (num_same) {
461 dist->freq[i] = prev;
462 num_same--;
463 } else {
464 if (i == omit_pos || !logcounts[i])
465 continue;
466 if (logcounts[i] == 1) {
467 dist->freq[i] = 1;
468 } else {
469 int bitcount = FFMIN(FFMAX(0, shift - ((12 - logcounts[i] + 1) >> 1)), logcounts[i] - 1);
470 dist->freq[i] = (1 << (logcounts[i] - 1)) + (get_bitsz(gb, bitcount) << (logcounts[i] - 1 - bitcount));
471 }
472 }
473 total_count += dist->freq[i];
474 }
475 dist->freq[omit_pos] = (1 << 12) - total_count;
476
477 return 0;
478 }
479
480 143 static void dist_bundle_close(JXLDistributionBundle *bundle)
481 {
482
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)
483
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++)
484 143 ff_vlc_free(&bundle->dists[i].vlc);
485 143 av_freep(&bundle->dists);
486 143 av_freep(&bundle->cluster_map);
487 143 }
488
489
490 static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
491 JXLDistributionBundle *bundle, int num_dist, int disallow_lz77);
492
493 143 static int read_dist_clustering(GetBitContext *gb, JXLEntropyDecoder *dec, JXLDistributionBundle *bundle)
494 {
495 int ret;
496
497 143 bundle->cluster_map = av_malloc(bundle->num_dist);
498
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!bundle->cluster_map)
499 return AVERROR(ENOMEM);
500
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->num_dist == 1) {
502 bundle->cluster_map[0] = 0;
503 bundle->num_clusters = 1;
504 return 0;
505 }
506
507
1/2
✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
143 if (get_bits1(gb)) {
508 /* simple clustering */
509 143 uint32_t nbits = get_bits(gb, 2);
510
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 143 times.
1287 for (int i = 0; i < bundle->num_dist; i++)
511 1144 bundle->cluster_map[i] = get_bitsz(gb, nbits);
512 } else {
513 /* complex clustering */
514 int use_mtf = get_bits1(gb);
515 JXLDistributionBundle nested = { 0 };
516 /* num_dist == 1 prevents this from recursing again */
517 ret = read_distribution_bundle(gb, dec, &nested, 1, bundle->num_dist <= 2);
518 if (ret < 0) {
519 dist_bundle_close(&nested);
520 return ret;
521 }
522 for (int i = 0; i < bundle->num_dist; i++) {
523 uint32_t clust;
524 ret = decode_hybrid_varlen_uint(gb, dec, &nested, 0, &clust);
525 if (ret < 0) {
526 dist_bundle_close(&nested);
527 return ret;
528 }
529 bundle->cluster_map[i] = clust;
530 }
531 dec->state = -1;
532 /* it's not going to necessarily be zero after reading */
533 dec->num_to_copy = 0;
534 dist_bundle_close(&nested);
535 if (use_mtf) {
536 uint8_t mtf[256];
537 for (int i = 0; i < 256; i++)
538 mtf[i] = i;
539 for (int i = 0; i < bundle->num_dist; i++) {
540 int index = bundle->cluster_map[i];
541 bundle->cluster_map[i] = mtf[index];
542 if (index) {
543 int value = mtf[index];
544 for (int j = index; j > 0; j--)
545 mtf[j] = mtf[j - 1];
546 mtf[0] = value;
547 }
548 }
549 }
550 }
551
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 143 times.
1287 for (int i = 0; i < bundle->num_dist; i++) {
552
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 1001 times.
1144 if (bundle->cluster_map[i] >= bundle->num_clusters)
553 143 bundle->num_clusters = bundle->cluster_map[i] + 1;
554 }
555
556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->num_clusters > bundle->num_dist)
557 return AVERROR_INVALIDDATA;
558
559 143 return 0;
560 }
561
562 static int gen_alias_map(JXLEntropyDecoder *dec, JXLSymbolDistribution *dist, int log_alphabet_size)
563 {
564 uint32_t bucket_size, table_size;
565 uint8_t overfull[256], underfull[256];
566 int overfull_pos = 0, underfull_pos = 0;
567 dist->log_bucket_size = 12 - log_alphabet_size;
568 bucket_size = 1 << dist->log_bucket_size;
569 table_size = 1 << log_alphabet_size;
570
571 if (dist->uniq_pos >= 0) {
572 for (int i = 0; i < table_size; i++) {
573 dist->symbols[i] = dist->uniq_pos;
574 dist->offsets[i] = bucket_size * i;
575 dist->cutoffs[i] = 0;
576 }
577 return 0;
578 }
579
580 for (int i = 0; i < dist->alphabet_size; i++) {
581 dist->cutoffs[i] = dist->freq[i];
582 dist->symbols[i] = i;
583 if (dist->cutoffs[i] > bucket_size)
584 overfull[overfull_pos++] = i;
585 else if (dist->cutoffs[i] < bucket_size)
586 underfull[underfull_pos++] = i;
587 }
588
589 for (int i = dist->alphabet_size; i < table_size; i++) {
590 dist->cutoffs[i] = 0;
591 underfull[underfull_pos++] = i;
592 }
593
594 while (overfull_pos) {
595 int o, u, by;
596 /* this should be impossible */
597 if (!underfull_pos)
598 return AVERROR_INVALIDDATA;
599 u = underfull[--underfull_pos];
600 o = overfull[--overfull_pos];
601 by = bucket_size - dist->cutoffs[u];
602 dist->cutoffs[o] -= by;
603 dist->symbols[u] = o;
604 dist->offsets[u] = dist->cutoffs[o];
605 if (dist->cutoffs[o] < bucket_size)
606 underfull[underfull_pos++] = o;
607 else if (dist->cutoffs[o] > bucket_size)
608 overfull[overfull_pos++] = o;
609 }
610
611 for (int i = 0; i < table_size; i++) {
612 if (dist->cutoffs[i] == bucket_size) {
613 dist->symbols[i] = i;
614 dist->offsets[i] = 0;
615 dist->cutoffs[i] = 0;
616 } else {
617 dist->offsets[i] -= dist->cutoffs[i];
618 }
619 }
620
621 return 0;
622 }
623
624 142 static int read_simple_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
625 {
626 int nsym, tree_select, bits;
627
628 int8_t lens[4];
629 int16_t symbols[4];
630
631 142 nsym = 1 + get_bits(gb, 2);
632
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 142 times.
468 for (int i = 0; i < nsym; i++)
633 326 symbols[i] = get_bitsz(gb, dist->log_alphabet_size);
634
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if (nsym == 4)
635 tree_select = get_bits1(gb);
636
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) {
637 case 1:
638 dist->vlc.bits = 0;
639 dist->default_symbol = symbols[0];
640 return 0;
641 100 case 2:
642 100 bits = 1;
643 100 lens[0] = 1, lens[1] = 1, lens[2] = 0, lens[3] = 0;
644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (symbols[1] < symbols[0])
645 FFSWAP(int16_t, symbols[0], symbols[1]);
646 100 break;
647 42 case 3:
648 42 bits = 2;
649 42 lens[0] = 1, lens[1] = 2, lens[2] = 2, lens[3] = 0;
650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (symbols[2] < symbols[1])
651 FFSWAP(int16_t, symbols[1], symbols[2]);
652 42 break;
653 case 4:
654 if (tree_select) {
655 bits = 3;
656 lens[0] = 1, lens[1] = 2, lens[2] = 3, lens[3] = 3;
657 if (symbols[3] < symbols[2])
658 FFSWAP(int16_t, symbols[2], symbols[3]);
659 } else {
660 bits = 2;
661 lens[0] = 2, lens[1] = 2, lens[2] = 2, lens[3] = 2;
662 while (1) {
663 if (symbols[1] < symbols[0])
664 FFSWAP(int16_t, symbols[0], symbols[1]);
665 if (symbols[3] < symbols[2])
666 FFSWAP(int16_t, symbols[2], symbols[3]);
667 if (symbols[1] <= symbols[2])
668 break;
669 FFSWAP(int16_t, symbols[1], symbols[2]);
670 }
671 }
672 break;
673 default:
674 // Challenge Complete! How did we get here?
675 return AVERROR_BUG;
676 }
677
678 142 return ff_vlc_init_from_lengths(&dist->vlc, bits, nsym, lens, 1, symbols,
679 2, 2, 0, VLC_INIT_LE, dec->logctx);
680 }
681
682 143 static int read_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
683 {
684 143 int8_t level1_lens[18] = { 0 };
685 143 int8_t level1_lens_s[18] = { 0 };
686 143 int16_t level1_syms[18] = { 0 };
687 143 uint32_t level1_codecounts[19] = { 0 };
688 143 uint8_t *buf = NULL;
689 int8_t *level2_lens, *level2_lens_s;
690 int16_t *level2_syms;
691 uint32_t *level2_codecounts;
692
693 143 int repeat_count_prev = 0, repeat_count_zero = 0, prev = 8;
694 143 int total_code = 0, len, hskip, num_codes = 0, ret;
695
696 143 VLC level1_vlc = { 0 };
697
698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (dist->alphabet_size == 1) {
699 dist->vlc.bits = 0;
700 dist->default_symbol = 0;
701 return 0;
702 }
703
704 143 hskip = get_bits(gb, 2);
705
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 1 times.
143 if (hskip == 1)
706 142 return read_simple_vlc_prefix(gb, dec, dist);
707
708 1 level1_codecounts[0] = hskip;
709
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (int i = hskip; i < 18; i++) {
710 8 len = level1_lens[prefix_codelen_map[i]] = get_vlc2(gb, level0_table, 4, 1);
711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (len < 0) {
712 ret = AVERROR_INVALIDDATA;
713 goto end;
714 }
715 8 level1_codecounts[len]++;
716
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (len) {
717 7 total_code += (32 >> len);
718 7 num_codes++;
719 }
720
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (total_code >= 32) {
721 1 level1_codecounts[0] += 18 - i - 1;
722 1 break;
723 }
724 }
725
726
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) {
727 ret = AVERROR_INVALIDDATA;
728 goto end;
729 }
730
731
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 for (int i = 1; i < 19; i++)
732 18 level1_codecounts[i] += level1_codecounts[i - 1];
733
734
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 for (int i = 17; i >= 0; i--) {
735 18 int idx = --level1_codecounts[level1_lens[i]];
736 18 level1_lens_s[idx] = level1_lens[i];
737 18 level1_syms[idx] = i;
738 }
739
740 1 ret = ff_vlc_init_from_lengths(&level1_vlc, 5, 18, level1_lens_s, 1, level1_syms, 2, 2,
741 0, VLC_INIT_LE, dec->logctx);
742
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
743 goto end;
744
745 1 buf = av_mallocz(MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t) + sizeof(uint32_t))
746 + sizeof(uint32_t));
747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!buf) {
748 ret = AVERROR(ENOMEM);
749 goto end;
750 }
751
752 1 level2_lens = (int8_t *)buf;
753 1 level2_lens_s = (int8_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * sizeof(int8_t));
754 1 level2_syms = (int16_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t)));
755 1 level2_codecounts = (uint32_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t)));
756
757 1 total_code = 0;
758
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 for (int i = 0; i < dist->alphabet_size; i++) {
759 16 len = get_vlc2(gb, level1_vlc.table, 5, 1);
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (len < 0) {
761 ret = AVERROR_INVALIDDATA;
762 goto end;
763 }
764
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
16 if (get_bits_left(gb) < 0) {
765 ret = AVERROR_BUFFER_TOO_SMALL;
766 goto end;
767 }
768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (len == 16) {
769 int extra = 3 + get_bits(gb, 2);
770 if (repeat_count_prev)
771 extra += 4 * (repeat_count_prev - 2) - repeat_count_prev;
772 extra = FFMIN(extra, dist->alphabet_size - i);
773 for (int j = 0; j < extra; j++)
774 level2_lens[i + j] = prev;
775 total_code += (32768 >> prev) * extra;
776 i += extra - 1;
777 repeat_count_prev += extra;
778 repeat_count_zero = 0;
779 level2_codecounts[prev] += extra;
780
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 } else if (len == 17) {
781 2 int extra = 3 + get_bits(gb, 3);
782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (repeat_count_zero > 0)
783 extra += 8 * (repeat_count_zero - 2) - repeat_count_zero;
784 2 extra = FFMIN(extra, dist->alphabet_size - i);
785 2 i += extra - 1;
786 2 repeat_count_prev = 0;
787 2 repeat_count_zero += extra;
788 2 level2_codecounts[0] += extra;
789 } else {
790 14 level2_lens[i] = len;
791 14 repeat_count_prev = repeat_count_zero = 0;
792
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5 times.
14 if (len) {
793 9 total_code += (32768 >> len);
794 9 prev = len;
795 }
796 14 level2_codecounts[len]++;
797 }
798
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (total_code >= 32768) {
799 1 level2_codecounts[0] += dist->alphabet_size - i - 1;
800 1 break;
801 }
802 }
803
804
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) {
805 ret = AVERROR_INVALIDDATA;
806 goto end;
807 }
808
809
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
29 for (int i = 1; i < dist->alphabet_size + 1; i++)
810 28 level2_codecounts[i] += level2_codecounts[i - 1];
811
812
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
29 for (int i = dist->alphabet_size - 1; i >= 0; i--) {
813 28 int idx = --level2_codecounts[level2_lens[i]];
814 28 level2_lens_s[idx] = level2_lens[i];
815 28 level2_syms[idx] = i;
816 }
817
818 1 ret = ff_vlc_init_from_lengths(&dist->vlc, 15, dist->alphabet_size, level2_lens_s,
819 1, level2_syms, 2, 2, 0, VLC_INIT_LE, dec->logctx);
820
821 1 end:
822 1 av_freep(&buf);
823 1 ff_vlc_free(&level1_vlc);
824
825 1 return ret;
826 }
827
828 143 static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
829 JXLDistributionBundle *bundle, int num_dist, int disallow_lz77)
830 {
831 int ret;
832
833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (num_dist <= 0)
834 return AVERROR(EINVAL);
835
836 143 bundle->num_dist = num_dist;
837 143 bundle->lz77_enabled = get_bits1(gb);
838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (bundle->lz77_enabled) {
839 if (disallow_lz77)
840 return AVERROR_INVALIDDATA;
841 bundle->lz77_min_symbol = jxl_u32(gb, 224, 512, 4096, 8, 0, 0, 0, 15);
842 bundle->lz77_min_length = jxl_u32(gb, 3, 4, 5, 9, 0, 0, 2, 8);
843 bundle->num_dist++;
844 ret = read_hybrid_uint_conf(gb, &bundle->lz_len_conf, 8);
845 if (ret < 0)
846 return ret;
847 }
848
849
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) {
850 dec->window = av_malloc_array(1 << 20, sizeof(uint32_t));
851 if (!dec->window)
852 return AVERROR(ENOMEM);
853 }
854
855 143 ret = read_dist_clustering(gb, dec, bundle);
856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
857 return ret;
858
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
859 return AVERROR_BUFFER_TOO_SMALL;
860
861 143 bundle->dists = av_calloc(bundle->num_clusters, sizeof(JXLSymbolDistribution));
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!bundle->dists)
863 return AVERROR(ENOMEM);
864
865 143 bundle->use_prefix_code = get_bits1(gb);
866
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);
867
868
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
869 143 ret = read_hybrid_uint_conf(gb, &bundle->dists[i].config, bundle->log_alphabet_size);
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
871 return ret;
872
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
873 return AVERROR_BUFFER_TOO_SMALL;
874 }
875
876
1/2
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
143 if (bundle->use_prefix_code) {
877
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
878 143 JXLSymbolDistribution *dist = &bundle->dists[i];
879
1/2
✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
143 if (get_bits1(gb)) {
880 143 int n = get_bits(gb, 4);
881 143 dist->alphabet_size = 1 + (1 << n) + get_bitsz(gb, n);
882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (dist->alphabet_size > MAX_PREFIX_ALPHABET_SIZE)
883 return AVERROR_INVALIDDATA;
884 } else {
885 dist->alphabet_size = 1;
886 }
887 143 dist->log_alphabet_size = clog1p(dist->alphabet_size - 1);
888 }
889
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 143 times.
286 for (int i = 0; i < bundle->num_clusters; i++) {
890 143 ret = read_vlc_prefix(gb, dec, &bundle->dists[i]);
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
892 return ret;
893
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0)
894 return AVERROR_BUFFER_TOO_SMALL;
895 }
896 } else {
897 for (int i = 0; i < bundle->num_clusters; i++) {
898 ret = populate_distribution(gb, &bundle->dists[i], bundle->log_alphabet_size);
899 if (ret < 0)
900 return ret;
901 if (get_bits_left(gb) < 0)
902 return AVERROR_BUFFER_TOO_SMALL;
903 }
904 for (int i = 0; i < bundle->num_clusters; i++) {
905 ret = gen_alias_map(dec, &bundle->dists[i], bundle->log_alphabet_size);
906 if (ret < 0)
907 return ret;
908 }
909 }
910
911 143 return 0;
912 }
913
914 143 static void entropy_decoder_close(JXLEntropyDecoder *dec)
915 {
916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (!dec)
917 return;
918 143 av_freep(&dec->window);
919 143 dist_bundle_close(&dec->bundle);
920 }
921
922 143 static int entropy_decoder_init(void *avctx, GetBitContext *gb, JXLEntropyDecoder *dec, int num_dist)
923 {
924 int ret;
925
926 143 memset(dec, 0, sizeof(*dec));
927 143 dec->logctx = avctx;
928 143 dec->state = -1;
929
930 143 ret = read_distribution_bundle(gb, dec, &dec->bundle, num_dist, 0);
931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0) {
932 entropy_decoder_close(dec);
933 return ret;
934 }
935
936 143 return 0;
937 }
938
939 875 static int64_t entropy_decoder_read_symbol(GetBitContext *gb, JXLEntropyDecoder *dec, uint32_t context)
940 {
941 int ret;
942 uint32_t hybrid_uint;
943
944 875 ret = decode_hybrid_varlen_uint(gb, dec, &dec->bundle, context, &hybrid_uint);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 875 times.
875 if (ret < 0)
946 return ret;
947
948 875 return hybrid_uint;
949 }
950
951 static inline uint32_t icc_context(uint64_t i, uint32_t b1, uint32_t b2)
952 {
953 uint32_t p1, p2;
954 if (i <= 128)
955 return 0;
956 if (b1 >= 'a' && b1 <= 'z' || b1 >= 'A' && b1 <= 'Z')
957 p1 = 0;
958 else if (b1 >= '0' && b1 <= '9' || b1 == '.' || b1 == ',')
959 p1 = 1;
960 else if (b1 <= 1)
961 p1 = b1 + 2;
962 else if (b1 > 1 && b1 < 16)
963 p1 = 4;
964 else if (b1 > 240 && b1 < 255)
965 p1 = 5;
966 else if (b1 == 255)
967 p1 = 6;
968 else
969 p1 = 7;
970
971 if (b2 >= 'a' && b2 <= 'z' || b2 >= 'A' && b2 <= 'Z')
972 p2 = 0;
973 else if (b2 >= '0' && b2 <= '9' || b2 == '.' || b2 == ',')
974 p2 = 1;
975 else if (b2 < 16)
976 p2 = 2;
977 else if (b2 > 240)
978 p2 = 3;
979 else
980 p2 = 4;
981
982 return 1 + p1 + p2 * 8;
983 }
984
985 875 static inline uint32_t toc_context(uint32_t x)
986 {
987 875 return FFMIN(7, clog1p(x));
988 }
989
990 14 static void populate_fields(AVCodecParserContext *s, AVCodecContext *avctx, const FFJXLMetadata *meta)
991 {
992 14 s->width = meta->width;
993 14 s->height = meta->height;
994
995
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 switch (meta->csp) {
996 14 case JPEGXL_CS_RGB:
997 case JPEGXL_CS_XYB:
998 14 avctx->colorspace = AVCOL_SPC_RGB;
999 14 break;
1000 default:
1001 avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
1002 }
1003
1004
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (meta->wp == JPEGXL_WP_D65) {
1005
1/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 switch (meta->primaries) {
1006 14 case JPEGXL_PR_SRGB:
1007 14 avctx->color_primaries = AVCOL_PRI_BT709;
1008 14 break;
1009 case JPEGXL_PR_P3:
1010 avctx->color_primaries = AVCOL_PRI_SMPTE432;
1011 break;
1012 case JPEGXL_PR_2100:
1013 avctx->color_primaries = AVCOL_PRI_BT2020;
1014 break;
1015 default:
1016 avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
1017 }
1018 } else if (meta->wp == JPEGXL_WP_DCI && meta->primaries == JPEGXL_PR_P3) {
1019 avctx->color_primaries = AVCOL_PRI_SMPTE431;
1020 } else {
1021 avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
1022 }
1023
1024
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (meta->trc > JPEGXL_TR_GAMMA) {
1025 14 FFJXLTransferCharacteristic trc = meta->trc - JPEGXL_TR_GAMMA;
1026
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) {
1027 case JPEGXL_TR_BT709:
1028 avctx->color_trc = AVCOL_TRC_BT709;
1029 break;
1030 case JPEGXL_TR_LINEAR:
1031 avctx->color_trc = AVCOL_TRC_LINEAR;
1032 break;
1033 14 case JPEGXL_TR_SRGB:
1034 14 avctx->color_trc = AVCOL_TRC_IEC61966_2_1;
1035 14 break;
1036 case JPEGXL_TR_PQ:
1037 avctx->color_trc = AVCOL_TRC_SMPTEST2084;
1038 break;
1039 case JPEGXL_TR_DCI:
1040 avctx->color_trc = AVCOL_TRC_SMPTE428;
1041 break;
1042 case JPEGXL_TR_HLG:
1043 avctx->color_trc = AVCOL_TRC_ARIB_STD_B67;
1044 break;
1045 default:
1046 avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1047 }
1048 } else if (meta->trc > 0) {
1049 if (meta->trc > 45355 && meta->trc < 45555)
1050 avctx->color_trc = AVCOL_TRC_GAMMA22;
1051 else if (meta->trc > 35614 && meta->trc < 35814)
1052 avctx->color_trc = AVCOL_TRC_GAMMA28;
1053 else
1054 avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1055 } else {
1056 avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
1057 }
1058
1059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (meta->csp == JPEGXL_CS_GRAY) {
1060 if (meta->bit_depth <= 8)
1061 s->format = meta->have_alpha ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
1062 else if (meta->bit_depth <= 16)
1063 s->format = meta->have_alpha ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
1064 else
1065 s->format = meta->have_alpha ? AV_PIX_FMT_NONE : AV_PIX_FMT_GRAYF32;
1066 } else {
1067
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (meta->bit_depth <= 8)
1068
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;
1069 else if (meta->bit_depth <= 16)
1070 s->format = meta->have_alpha ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
1071 else
1072 s->format = meta->have_alpha ? AV_PIX_FMT_RGBAF32 : AV_PIX_FMT_RGBF32;
1073 }
1074 14 }
1075
1076 static int skip_icc_profile(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1077 {
1078 int64_t ret;
1079 uint32_t last = 0, last2 = 0;
1080 JXLEntropyDecoder dec = { 0 };
1081 uint64_t enc_size = jxl_u64(gb);
1082 uint64_t output_size = 0;
1083 int out_size_shift = 0;
1084
1085 if (!enc_size || enc_size > (1 << 22))
1086 return AVERROR_INVALIDDATA;
1087
1088 ret = entropy_decoder_init(avctx, gb, &dec, 41);
1089 if (ret < 0)
1090 goto end;
1091
1092 if (get_bits_left(gb) < 0) {
1093 ret = AVERROR_BUFFER_TOO_SMALL;
1094 goto end;
1095 }
1096
1097 for (uint64_t read = 0; read < enc_size; read++) {
1098 ret = entropy_decoder_read_symbol(gb, &dec, icc_context(read, last, last2));
1099 if (ret < 0)
1100 goto end;
1101 if (ret > 255) {
1102 ret = AVERROR_INVALIDDATA;
1103 goto end;
1104 }
1105 if (get_bits_left(gb) < 0) {
1106 ret = AVERROR_BUFFER_TOO_SMALL;
1107 goto end;
1108 }
1109 last2 = last;
1110 last = ret;
1111 if (out_size_shift < 63) {
1112 output_size += (ret & UINT64_C(0x7F)) << out_size_shift;
1113 if (!(ret & 0x80)) {
1114 out_size_shift = 63;
1115 } else {
1116 out_size_shift += 7;
1117 if (out_size_shift > 56) {
1118 ret = AVERROR_INVALIDDATA;
1119 goto end;
1120 }
1121 }
1122 } else if (output_size < 132) {
1123 ret = AVERROR_INVALIDDATA;
1124 goto end;
1125 }
1126 }
1127
1128 ret = 0;
1129
1130 end:
1131 entropy_decoder_close(&dec);
1132
1133 return ret;
1134 }
1135
1136 337 static int skip_extensions(GetBitContext *gb)
1137 {
1138 337 uint64_t extensions = jxl_u64(gb), extensions_len = 0;
1139
1140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 337 times.
337 if (get_bits_left(gb) < 0)
1141 return AVERROR_BUFFER_TOO_SMALL;
1142
1143
1/2
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
337 if (!extensions)
1144 337 return 0;
1145
1146 for (int i = 0; i < 64; i++) {
1147 if (extensions & (UINT64_C(1) << i))
1148 extensions_len += jxl_u64(gb);
1149 if (get_bits_left(gb) < 0)
1150 return AVERROR_BUFFER_TOO_SMALL;
1151 }
1152
1153 if (extensions_len > INT_MAX || get_bits_left(gb) < extensions_len)
1154 return AVERROR_BUFFER_TOO_SMALL;
1155
1156 skip_bits_long(gb, extensions_len);
1157
1158 return 0;
1159 }
1160
1161 193 static int parse_frame_header(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
1162 {
1163 193 int all_default, do_yCbCr = 0, num_passes = 1, ret;
1164 193 int group_size_shift = 1, lf_level = 0, save_as_ref = 0;
1165 193 int have_crop = 0, full_frame = 1, resets_canvas = 1, upsampling = 1;
1166 193 JXLFrame *frame = &ctx->codestream.frame;
1167 193 const FFJXLMetadata *meta = &ctx->codestream.meta;
1168 193 int32_t x0 = 0, y0 = 0;
1169 193 uint32_t duration = 0, width = meta->coded_width, height = meta->coded_height;
1170 uint32_t name_len, num_groups, num_lf_groups, group_dim, lf_group_dim, toc_count;
1171 193 uint64_t flags = 0;
1172 193 int start_len = get_bits_count(gb);
1173
1174 193 memset(frame, 0, sizeof(*frame));
1175 193 frame->is_last = 1;
1176
1177 193 all_default = get_bits1(gb);
1178
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1179 193 frame->type = get_bits(gb, 2);
1180 193 frame->encoding = get_bits1(gb);
1181 193 flags = jxl_u64(gb);
1182
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (!meta->xyb_encoded)
1183 1 do_yCbCr = get_bits1(gb);
1184
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!(flags & JXL_FLAG_USE_LF_FRAME)) {
1185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (do_yCbCr)
1186 skip_bits(gb, 6); // jpeg upsampling
1187 193 upsampling = jxl_u32(gb, 1, 2, 4, 8, 0, 0, 0, 0);
1188 193 skip_bits_long(gb, 2 * meta->num_extra_channels);
1189
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1190 return AVERROR_BUFFER_TOO_SMALL;
1191 }
1192
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 192 times.
193 if (frame->encoding == JPEGXL_ENC_MODULAR)
1193 1 group_size_shift = get_bits(gb, 2);
1194
1/2
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
192 else if (meta->xyb_encoded)
1195 192 skip_bits(gb, 6); // xqm and bqm scales
1196
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1197 193 num_passes = jxl_u32(gb, 1, 2, 3, 4, 0, 0, 0, 3);
1198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (num_passes != 1) {
1199 int num_ds = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 1);
1200 skip_bits(gb, 2 * (num_passes - 1)); // shift
1201 skip_bits(gb, 2 * num_ds); // downsample
1202 for (int i = 0; i < num_ds; i++)
1203 jxl_u32(gb, 0, 1, 2, 0, 0, 0, 0, 3);
1204 }
1205 }
1206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (frame->type == JPEGXL_FRAME_LF)
1207 lf_level = 1 + get_bits(gb, 2);
1208 else
1209 193 have_crop = get_bits1(gb);
1210
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 3 times.
193 if (have_crop) {
1211
1/2
✓ Branch 0 taken 190 times.
✗ Branch 1 not taken.
190 if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
1212 190 uint32_t ux0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1213 190 uint32_t uy0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 x0 = unpack_signed(ux0);
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
190 y0 = unpack_signed(uy0);
1216 }
1217 190 width = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1218 190 height = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
1219
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
1220
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;
1221 }
1222
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1223 return AVERROR_BUFFER_TOO_SMALL;
1224
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) {
1225
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 193 times.
435 for (int i = 0; i <= meta->num_extra_channels; i++) {
1226 242 int mode = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1227
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))
1228 jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
1229
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
1230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 || mode == JPEGXL_BM_MUL))
1231 skip_bits1(gb);
1232
2/2
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 49 times.
242 if (!i)
1233
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;
1234
2/2
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 4 times.
242 if (!resets_canvas)
1235 238 skip_bits(gb, 2);
1236
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
242 if (get_bits_left(gb) < 0)
1237 return AVERROR_BUFFER_TOO_SMALL;
1238 }
1239
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 144 times.
193 if (meta->animation_offset)
1240 49 duration = jxl_u32(gb, 0, 1, 0, 0, 0, 0, 8, 32);
1241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (meta->have_timecodes)
1242 skip_bits_long(gb, 32);
1243 193 frame->is_last = get_bits1(gb);
1244 } else {
1245 frame->is_last = 0;
1246 }
1247
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)
1248 185 save_as_ref = get_bits(gb, 2);
1249
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 ||
1250
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)
1251 && frame->type != JPEGXL_FRAME_LF))
1252 skip_bits1(gb); // save before color transform
1253 193 name_len = 8 * jxl_u32(gb, 0, 0, 16, 48, 0, 4, 5, 10);
1254
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < name_len)
1255 return AVERROR_BUFFER_TOO_SMALL;
1256 193 skip_bits_long(gb, name_len);
1257 }
1258
1259
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (!all_default) {
1260 193 int restd = get_bits1(gb), gab = 1;
1261
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd)
1262 144 gab = get_bits1(gb);
1263
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))
1264 // gab custom
1265 skip_bits_long(gb, 16 * 6);
1266
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
193 if (get_bits_left(gb) < 0)
1267 return AVERROR_BUFFER_TOO_SMALL;
1268
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 49 times.
193 if (!restd) {
1269 144 int epf = get_bits(gb, 2);
1270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (epf) {
1271 if (frame->encoding == JPEGXL_ENC_VARDCT && get_bits1(gb)) {
1272 skip_bits_long(gb, 16 * 8); // custom epf sharpness
1273 if (get_bits_left(gb) < 0)
1274 return AVERROR_BUFFER_TOO_SMALL;
1275 }
1276 if (get_bits1(gb)) {
1277 skip_bits_long(gb, 3 * 16 + 32); // custom epf weight
1278 if (get_bits_left(gb) < 0)
1279 return AVERROR_BUFFER_TOO_SMALL;
1280 }
1281 if (get_bits1(gb)) { // custom epf sigma
1282 if (frame->encoding == JPEGXL_ENC_VARDCT)
1283 skip_bits(gb, 16);
1284 skip_bits_long(gb, 16 * 3);
1285 if (get_bits_left(gb) < 0)
1286 return AVERROR_BUFFER_TOO_SMALL;
1287 }
1288 if (frame->encoding == JPEGXL_ENC_MODULAR)
1289 skip_bits(gb, 16);
1290 }
1291 144 ret = skip_extensions(gb);
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (ret < 0)
1293 return ret;
1294 }
1295 193 ret = skip_extensions(gb);
1296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1297 return ret;
1298 }
1299
1300 193 width = div_ceil(div_ceil(width, upsampling), 1 << (3 * lf_level));
1301 193 height = div_ceil(div_ceil(height, upsampling), 1 << (3 * lf_level));
1302 193 group_dim = 128 << group_size_shift;
1303 193 lf_group_dim = group_dim << 3;
1304 193 num_groups = div_ceil(width, group_dim) * div_ceil(height, group_dim);
1305 193 num_lf_groups = div_ceil(width, lf_group_dim) * div_ceil(height, lf_group_dim);
1306
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)
1307 150 toc_count = 1;
1308 else
1309 43 toc_count = 2 + num_lf_groups + num_groups * num_passes;
1310
1311 // permuted toc
1312
2/2
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 50 times.
193 if (get_bits1(gb)) {
1313 JXLEntropyDecoder dec;
1314 143 uint32_t end, lehmer = 0;
1315 143 ret = entropy_decoder_init(avctx, gb, &dec, 8);
1316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (ret < 0)
1317 return ret;
1318
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143 times.
143 if (get_bits_left(gb) < 0) {
1319 entropy_decoder_close(&dec);
1320 return AVERROR_BUFFER_TOO_SMALL;
1321 }
1322 143 end = entropy_decoder_read_symbol(gb, &dec, toc_context(toc_count));
1323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (end > toc_count) {
1324 entropy_decoder_close(&dec);
1325 return AVERROR_INVALIDDATA;
1326 }
1327
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 143 times.
875 for (uint32_t i = 0; i < end; i++) {
1328 732 lehmer = entropy_decoder_read_symbol(gb, &dec, toc_context(lehmer));
1329
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 732 times.
732 if (get_bits_left(gb) < 0) {
1330 entropy_decoder_close(&dec);
1331 return AVERROR_BUFFER_TOO_SMALL;
1332 }
1333 }
1334 143 entropy_decoder_close(&dec);
1335 }
1336 193 align_get_bits(gb);
1337
1338
2/2
✓ Branch 0 taken 782 times.
✓ Branch 1 taken 193 times.
975 for (uint32_t i = 0; i < toc_count; i++) {
1339 782 frame->body_length += 8 * jxl_u32(gb, 0, 1024, 17408, 4211712, 10, 14, 22, 30);
1340
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 782 times.
782 if (get_bits_left(gb) < 0)
1341 return AVERROR_BUFFER_TOO_SMALL;
1342 }
1343 193 align_get_bits(gb);
1344
1345 193 frame->total_length = frame->body_length + get_bits_count(gb) - start_len;
1346
1347 193 return 0;
1348 }
1349
1350 10 static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size)
1351 {
1352 GetByteContext gb;
1353
1354
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 if (ctx->skip > buf_size)
1355 3 return AVERROR_BUFFER_TOO_SMALL;
1356
1357 7 buf += ctx->skip;
1358 7 buf_size -= ctx->skip;
1359 7 bytestream2_init(&gb, buf, buf_size);
1360
1361 while (1) {
1362 uint64_t size;
1363 7 int head_size = 8;
1364
1365
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
1366 break;
1367
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
7 if (bytestream2_peek_le64(&gb) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
1368 3 break;
1369
1370
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (bytestream2_get_bytes_left(&gb) < 8)
1371 3 return AVERROR_BUFFER_TOO_SMALL;
1372
1373 1 size = bytestream2_get_be32(&gb);
1374 1 bytestream2_skip(&gb, 4); // tag
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size == 1) {
1376 if (bytestream2_get_bytes_left(&gb) < 8)
1377 return AVERROR_BUFFER_TOO_SMALL;
1378 size = bytestream2_get_be64(&gb);
1379 head_size = 16;
1380 }
1381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
1382 return AVERROR_INVALIDDATA;
1383 /* invalid ISOBMFF size */
1384
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)
1385 return AVERROR_INVALIDDATA;
1386
1387 1 ctx->skip += size;
1388 1 bytestream2_skip(&gb, size - head_size);
1389
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (bytestream2_get_bytes_left(&gb) <= 0)
1390 1 return AVERROR_BUFFER_TOO_SMALL;
1391 }
1392
1393 3 return 0;
1394 }
1395
1396 92 static int try_parse(AVCodecParserContext *s, AVCodecContext *avctx, JXLParseContext *ctx,
1397 const uint8_t *buf, int buf_size)
1398 {
1399 int ret, cs_buflen, header_skip;
1400 const uint8_t *cs_buffer;
1401 GetBitContext gb;
1402
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (ctx->skip > buf_size)
1404 return AVERROR_BUFFER_TOO_SMALL;
1405
1406 92 buf += ctx->skip;
1407 92 buf_size -= ctx->skip;
1408
1409
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) {
1410 6 ctx->container = 1;
1411 6 ret = ff_jpegxl_collect_codestream_header(buf, buf_size, ctx->cs_buffer,
1412 sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, &ctx->copied);
1413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1414 return ret;
1415 6 ctx->collected_size = ret;
1416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctx->copied) {
1417 ctx->skip += ret;
1418 return AVERROR_BUFFER_TOO_SMALL;
1419 }
1420 6 cs_buffer = ctx->cs_buffer;
1421
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);
1422 } else {
1423 86 cs_buffer = buf;
1424 86 cs_buflen = buf_size;
1425 }
1426
1427
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 72 times.
92 if (!ctx->codestream_length) {
1428 20 header_skip = ff_jpegxl_parse_codestream_header(cs_buffer, cs_buflen, &ctx->codestream.meta, 0);
1429
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14 times.
20 if (header_skip < 0)
1430 6 return header_skip;
1431 14 ctx->codestream_length = header_skip;
1432 14 populate_fields(s, avctx, &ctx->codestream.meta);
1433 }
1434
1435
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 80 times.
86 if (ctx->container)
1436 6 return ctx->collected_size;
1437
1438 80 ret = init_get_bits8(&gb, cs_buffer, cs_buflen);
1439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (ret < 0)
1440 return ret;
1441
1442 80 skip_bits_long(&gb, ctx->codestream_length);
1443
1444
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) {
1445 ret = skip_icc_profile(avctx, ctx, &gb);
1446 if (ret < 0)
1447 return ret;
1448 ctx->skipped_icc = 1;
1449 align_get_bits(&gb);
1450 ctx->codestream_length = get_bits_count(&gb);
1451 }
1452
1453
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 5 times.
80 if (get_bits_left(&gb) <= 0)
1454 5 return AVERROR_BUFFER_TOO_SMALL;
1455
1456 while (1) {
1457 193 ret = parse_frame_header(avctx, ctx, &gb);
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (ret < 0)
1459 return ret;
1460 193 ctx->codestream_length += ctx->codestream.frame.total_length;
1461
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 185 times.
193 if (ctx->codestream.frame.is_last)
1462 8 return ctx->codestream_length / 8;
1463
2/2
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 118 times.
185 if (get_bits_left(&gb) <= ctx->codestream.frame.body_length)
1464 67 return AVERROR_BUFFER_TOO_SMALL;
1465 118 skip_bits_long(&gb, ctx->codestream.frame.body_length);
1466 }
1467 }
1468
1469 97 static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx,
1470 const uint8_t **poutbuf, int *poutbuf_size,
1471 const uint8_t *buf, int buf_size)
1472 {
1473 97 JXLParseContext *ctx = s->priv_data;
1474 97 int next = END_NOT_FOUND, ret;
1475 97 const uint8_t *pbuf = ctx->pc.buffer;
1476 97 int pindex = ctx->pc.index;
1477
1478 97 *poutbuf_size = 0;
1479 97 *poutbuf = NULL;
1480
1481
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 77 times.
97 if (!ctx->pc.index) {
1482
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
20 if (ctx->pc.overread)
1483 1 goto flush;
1484 19 pbuf = buf;
1485 19 pindex = buf_size;
1486 }
1487
1488
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) {
1489 92 ret = try_parse(s, avctx, ctx, pbuf, pindex);
1490
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 14 times.
92 if (ret < 0)
1491 78 goto flush;
1492 14 ctx->next = ret;
1493
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (ctx->container)
1494 6 ctx->skip += ctx->next;
1495 }
1496
1497
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) {
1498 10 ret = skip_boxes(ctx, pbuf, pindex);
1499
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3 times.
10 if (ret < 0) {
1500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret == AVERROR_INVALIDDATA)
1501 ctx->next = -1;
1502 7 goto flush;
1503 }
1504 3 ctx->next = ret + ctx->skip;
1505 }
1506
1507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ctx->next >= 0)
1508 11 next = ctx->next - ctx->pc.index;
1509
1510 flush:
1511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (next > buf_size)
1512 next = END_NOT_FOUND;
1513
1514 97 ret = ff_combine_frame(&ctx->pc, next, &buf, &buf_size);
1515
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 20 times.
97 if (ret < 0)
1516 77 return buf_size;
1517
1518 20 *poutbuf = buf;
1519 20 *poutbuf_size = buf_size;
1520
1521 20 ctx->codestream_length = 0;
1522 20 ctx->collected_size = 0;
1523 20 ctx->container = 0;
1524 20 ctx->copied = 0;
1525 20 ctx->skip = 0;
1526 20 ctx->skipped_icc = 0;
1527 20 ctx->next = 0;
1528 20 memset(&ctx->codestream, 0, sizeof(ctx->codestream));
1529
1530 20 return next;
1531 }
1532
1533 const AVCodecParser ff_jpegxl_parser = {
1534 .codec_ids = { AV_CODEC_ID_JPEGXL },
1535 .priv_data_size = sizeof(JXLParseContext),
1536 .parser_parse = jpegxl_parse,
1537 .parser_close = ff_parse_close,
1538 };
1539