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 |