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