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