Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / libavcodec / jpegxl_parse.c
1 /*
2  * JPEG XL Header 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 <stdint.h>
23
24 #include "bytestream.h"
25 #define UNCHECKED_BITSTREAM_READER 0
26 #define BITSTREAM_READER_LE
27 #include "get_bits.h"
28 #include "jpegxl.h"
29 #include "jpegxl_parse.h"
30
31 /* read a U32(c_i + u(u_i)) */
32 static av_always_inline uint32_t jxl_u32(GetBitContext *gb,
33                         uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3,
34                         uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3)
35 {
36     const uint32_t constants[4] = {c0, c1, c2, c3};
37     const uint32_t ubits    [4] = {u0, u1, u2, u3};
38     uint32_t ret, choice = get_bits(gb, 2);
39
40     ret = constants[choice];
41     if (ubits[choice])
42         ret += get_bits_long(gb, ubits[choice]);
43
44     return ret;
45 }
46
47 static av_always_inline uint32_t jxl_enum(GetBitContext *gb)
48 {
49     return jxl_u32(gb, 0, 1, 2, 18, 0, 0, 4, 6);
50 }
51
52 /* read a U64() */
53 static uint64_t jxl_u64(GetBitContext *gb)
54 {
55     uint64_t shift = 12, ret;
56
57     switch (get_bits(gb, 2)) {
58     case 1:
59         ret = 1 + get_bits(gb, 4);
60         break;
61     case 2:
62         ret = 17 + get_bits(gb, 8);
63         break;
64     case 3:
65         ret = get_bits(gb, 12);
66         while (get_bits1(gb)) {
67             if (shift < 60) {
68                 ret |= (uint64_t)get_bits(gb, 8) << shift;
69                 shift += 8;
70             } else {
71                 ret |= (uint64_t)get_bits(gb, 4) << shift;
72                 break;
73             }
74         }
75         break;
76     default:
77         ret = 0;
78     }
79
80     return ret;
81 }
82
83 static uint32_t jpegxl_width_from_ratio(uint32_t height, int ratio)
84 {
85     uint64_t height64 = height; /* avoid integer overflow */
86     switch (ratio) {
87     case 1:
88         return height;
89     case 2:
90         return (uint32_t)((height64 * 12) / 10);
91     case 3:
92         return (uint32_t)((height64 * 4) / 3);
93     case 4:
94         return (uint32_t)((height64 * 3) / 2);
95     case 5:
96         return (uint32_t)((height64 * 16) / 9);
97     case 6:
98         return (uint32_t)((height64 * 5) / 4);
99     case 7:
100         return (uint32_t)(height64 * 2);
101     default:
102         break;
103     }
104
105     return 0; /* manual width */
106 }
107
108 /**
109  * validate a Jpeg XL Size Header
110  * @return >= 0 upon valid size, < 0 upon invalid size found
111  */
112 static int jpegxl_read_size_header(GetBitContext *gb, FFJXLMetadata *meta, int validate)
113 {
114     uint32_t width, height;
115
116     if (get_bits1(gb)) {
117         /* small size header */
118         height = (get_bits(gb, 5) + 1) << 3;
119         width = jpegxl_width_from_ratio(height, get_bits(gb, 3));
120         if (!width)
121             width = (get_bits(gb, 5) + 1) << 3;
122     } else {
123         /* large size header */
124         height = 1 + jxl_u32(gb, 0, 0, 0, 0, 9, 13, 18, 30);
125         width = jpegxl_width_from_ratio(height, get_bits(gb, 3));
126         if (!width)
127             width = 1 + jxl_u32(gb, 0, 0, 0, 0, 9, 13, 18, 30);
128     }
129     if (validate && (width > (1 << 18) || height > (1 << 18)
130         || (width >> 4) * (height >> 4) > (1 << 20)))
131         return AVERROR_INVALIDDATA;
132
133     if (meta) {
134         meta->width = meta->coded_width = width;
135         meta->height = meta->coded_height = height;
136     }
137
138     return 0;
139 }
140
141 /**
142  * validate a Jpeg XL Preview Header
143  * @return >= 0 upon valid size, < 0 upon invalid size found
144  */
145 static int jpegxl_read_preview_header(GetBitContext *gb, int validate)
146 {
147     uint32_t width, height;
148
149     if (get_bits1(gb)) {
150         /* coded height and width divided by eight */
151         height = jxl_u32(gb, 16, 32, 1, 33, 0, 0, 5, 9) << 3;
152         width = jpegxl_width_from_ratio(height, get_bits(gb, 3));
153         if (!width)
154             width = jxl_u32(gb, 16, 32, 1, 33, 0, 0, 5, 9) << 3;
155     } else {
156         /* full height and width coded */
157         height = jxl_u32(gb, 1, 65, 321, 1345, 6, 8, 10, 12);
158         width = jpegxl_width_from_ratio(height, get_bits(gb, 3));
159         if (!width)
160             width = jxl_u32(gb, 1, 65, 321, 1345, 6, 8, 10, 12);
161     }
162     if (validate && (width > 4096 || height > 4096))
163         return AVERROR_INVALIDDATA;
164
165     return 0;
166 }
167
168 /**
169  * get a Jpeg XL BitDepth Header. These cannot be invalid.
170  */
171 static void jpegxl_get_bit_depth(GetBitContext *gb, FFJXLMetadata *meta)
172 {
173     int bit_depth;
174     if (get_bits1(gb)) {
175         /* float samples */
176         bit_depth = jxl_u32(gb, 32, 16, 24, 1, 0, 0, 0, 6); /* mantissa */
177         skip_bits_long(gb, 4); /* exponent */
178     } else {
179         /* integer samples */
180         bit_depth = jxl_u32(gb, 8, 10, 12, 1, 0, 0, 0, 6);
181     }
182     if (meta)
183         meta->bit_depth = bit_depth;
184 }
185
186 /**
187  * validate a Jpeg XL Extra Channel Info bundle
188  * @return >= 0 upon valid, < 0 upon invalid
189  */
190 static int jpegxl_read_extra_channel_info(GetBitContext *gb, FFJXLMetadata *meta, int validate)
191 {
192     int default_alpha = get_bits1(gb);
193     uint32_t type, name_len = 0;
194
195     if (!default_alpha) {
196         type = jxl_enum(gb);
197         if (validate && type > 63)
198             return AVERROR_INVALIDDATA; /* enum types cannot be 64+ */
199         if (validate && validate < 10 && type == JPEGXL_CT_BLACK)
200             return AVERROR_INVALIDDATA;
201         jpegxl_get_bit_depth(gb, NULL);
202         jxl_u32(gb, 0, 3, 4, 1, 0, 0, 0, 3); /* dim-shift */
203         /* max of name_len is 1071 = 48 + 2^10 - 1 */
204         name_len = 8 * jxl_u32(gb, 0, 0, 16, 48, 0, 4, 5, 10);
205     } else {
206         type = JPEGXL_CT_ALPHA;
207     }
208
209     if (get_bits_left(gb) < name_len)
210         return AVERROR_BUFFER_TOO_SMALL;
211
212     /* skip over the name */
213     skip_bits_long(gb, name_len);
214
215     if (!default_alpha && type == JPEGXL_CT_ALPHA)
216         skip_bits1(gb);
217
218     if (type == JPEGXL_CT_SPOT_COLOR)
219         skip_bits_long(gb, 16 * 4);
220
221     if (type == JPEGXL_CT_CFA)
222         jxl_u32(gb, 1, 0, 3, 19, 0, 2, 4, 8);
223
224     if (meta && type == JPEGXL_CT_ALPHA)
225         meta->have_alpha = 1;
226
227     return 0;
228 }
229
230 static int jpegxl_skip_extensions(GetBitContext *gb)
231 {
232     uint64_t extensions = jxl_u64(gb), extensions_len = 0;
233
234     if (get_bits_left(gb) <= 0)
235         return AVERROR_BUFFER_TOO_SMALL;
236
237     if (!extensions)
238         return 0;
239
240     for (int i = 0; i < 64; i++) {
241         if (extensions & (UINT64_C(1) << i))
242             extensions_len += jxl_u64(gb);
243         if (get_bits_left(gb) <= 0)
244             return AVERROR_BUFFER_TOO_SMALL;
245     }
246
247     if (extensions_len > INT_MAX || get_bits_left(gb) <= extensions_len)
248         return AVERROR_BUFFER_TOO_SMALL;
249
250     skip_bits_long(gb, extensions_len);
251
252     return 0;
253 }
254
255 int ff_jpegxl_parse_codestream_header(const uint8_t *buf, int buflen, FFJXLMetadata *meta, int validate)
256 {
257     GetBitContext gbi, *gb = &gbi;
258
259     int all_default, extra_fields = 0;
260     int xyb_encoded = 1, have_icc_profile = 0;
261     int animation_offset = 0, have_timecodes = 0;
262
263     FFJXLPrimaries primaries = JPEGXL_PR_SRGB;
264     FFJXLTransferCharacteristic trc = JPEGXL_TR_SRGB + (1U << 24);
265     FFJXLWhitePoint white_point = JPEGXL_WP_D65;
266     FFJXLColorSpace color_space = JPEGXL_CS_RGB;
267
268     AVRational tb;
269     uint32_t num_extra_channels = 0;
270     int ret;
271
272     ret = init_get_bits8(gb, buf, buflen);
273     if (ret < 0)
274         return ret;
275
276     if (get_bits(gb, 16) != FF_JPEGXL_CODESTREAM_SIGNATURE_LE && validate)
277         return AVERROR_INVALIDDATA;
278
279     ret = jpegxl_read_size_header(gb, meta, validate);
280     if (ret < 0)
281         return ret;
282
283     all_default = get_bits1(gb);
284     if (!all_default)
285         extra_fields = get_bits1(gb);
286
287     if (extra_fields) {
288         int orientation = get_bits(gb, 3);
289         if (orientation > 3 && meta)
290             FFSWAP(uint32_t, meta->width, meta->height);
291
292         /*
293          * intrinstic size
294          * any size header here is valid, but as it
295          * is variable length we have to read it
296          */
297         if (get_bits1(gb))
298             jpegxl_read_size_header(gb, NULL, 0);
299
300         /* preview header */
301         if (get_bits1(gb)) {
302             ret = jpegxl_read_preview_header(gb, 0);
303             if (ret < 0)
304                 return ret;
305         }
306
307         /* animation header */
308         if (get_bits1(gb)) {
309             animation_offset = get_bits_count(gb);
310             tb.den = jxl_u32(gb, 100, 1000, 1, 1, 0, 0, 10, 30);
311             tb.num = jxl_u32(gb, 1, 1001, 1, 1, 0, 0, 8, 10);
312             jxl_u32(gb, 0, 0, 0, 0, 0, 3, 16, 32);
313             have_timecodes = get_bits1(gb);
314         }
315     }
316
317     if (animation_offset && meta) {
318         meta->animation_offset = animation_offset;
319         meta->timebase = tb;
320         meta->have_timecodes = have_timecodes;
321     }
322
323     if (get_bits_left(gb) <= 0)
324         return AVERROR_BUFFER_TOO_SMALL;
325
326     if (!all_default) {
327         jpegxl_get_bit_depth(gb, meta);
328
329         /* modular_16bit_buffers must equal 1 */
330         if (!get_bits1(gb) && validate && validate < 10)
331             return AVERROR_INVALIDDATA;
332
333         num_extra_channels = jxl_u32(gb, 0, 1, 2, 1, 0, 0, 4, 12);
334         if (num_extra_channels > 4 && validate && validate < 10)
335             return AVERROR_INVALIDDATA;
336         for (uint32_t i = 0; i < num_extra_channels; i++) {
337             ret = jpegxl_read_extra_channel_info(gb, meta, validate);
338             if (ret < 0)
339                 return ret;
340             if (get_bits_left(gb) <= 0)
341                 return AVERROR_BUFFER_TOO_SMALL;
342         }
343
344         xyb_encoded = get_bits1(gb);
345
346         /* color encoding bundle */
347         if (!get_bits1(gb)) {
348             have_icc_profile = get_bits1(gb);
349             color_space = jxl_enum(gb);
350             if (color_space > 63 && validate)
351                 return AVERROR_INVALIDDATA;
352             if (!have_icc_profile) {
353                 if (color_space != JPEGXL_CS_XYB) {
354                     white_point = jxl_enum(gb);
355                     if (white_point > 63 && validate)
356                         return AVERROR_INVALIDDATA;
357                     if (white_point == JPEGXL_WP_CUSTOM) {
358                         /* ux and uy values */
359                         jxl_u32(gb, 0, 524288, 1048576, 2097152, 19, 19, 20, 21);
360                         jxl_u32(gb, 0, 524288, 1048576, 2097152, 19, 19, 20, 21);
361                     }
362                     if (color_space != JPEGXL_CS_GRAY) {
363                         /* primaries */
364                         primaries = jxl_enum(gb);
365                         if (primaries > 63 && validate)
366                             return AVERROR_INVALIDDATA;
367                         if (primaries == JPEGXL_PR_CUSTOM) {
368                             /* ux/uy values for r,g,b */
369                             for (int i = 0; i < 6; i++) {
370                                 jxl_u32(gb, 0, 524288, 1048576, 2097152, 19, 19, 20, 21);
371                                 if (get_bits_left(gb) <= 0)
372                                     return AVERROR_BUFFER_TOO_SMALL;
373                             }
374                         }
375                     }
376                 }
377
378                 /* transfer characteristics */
379                 if (get_bits1(gb)) {
380                     /* gamma */
381                     trc = get_bits(gb, 24);
382                 } else {
383                     /* transfer function */
384                     trc = jxl_enum(gb);
385                     if (trc > 63 && validate)
386                         return AVERROR_INVALIDDATA;
387                     trc += (1U << 24);
388                 }
389
390                 /* rendering intent */
391                 if (jxl_enum(gb) > 63 && validate)
392                     return AVERROR_INVALIDDATA;
393             }
394         }
395
396         /* tone mapping bundle */
397         if (extra_fields && !get_bits1(gb))
398             skip_bits_long(gb, 16 + 16 + 1 + 16);
399
400         ret = jpegxl_skip_extensions(gb);
401         if (ret < 0)
402             return ret;
403     }
404
405     if (meta) {
406         meta->xyb_encoded = xyb_encoded;
407         meta->have_icc_profile = have_icc_profile;
408         meta->csp = color_space;
409         meta->primaries = primaries;
410         meta->wp = white_point;
411         meta->trc = trc;
412         if (!meta->bit_depth)
413             meta->bit_depth = 8;
414         meta->num_extra_channels = num_extra_channels;
415     }
416
417     /* default transform */
418     if (!get_bits1(gb)) {
419         /* opsin inverse matrix */
420         if (xyb_encoded && !get_bits1(gb))
421             skip_bits_long(gb, 16 * 16);
422         /* cw_mask and default weights */
423         if (get_bits1(gb))
424             skip_bits_long(gb, 16 * 15);
425         if (get_bits1(gb))
426             skip_bits_long(gb, 16 * 55);
427         if (get_bits1(gb))
428             skip_bits_long(gb, 16 * 210);
429     }
430
431     if (!have_icc_profile) {
432         int bits_remaining = 7 - ((get_bits_count(gb) - 1) & 0x7);
433         if (bits_remaining && get_bits(gb, bits_remaining))
434             return AVERROR_INVALIDDATA;
435     }
436
437     if (get_bits_left(gb) < 0)
438         return AVERROR_BUFFER_TOO_SMALL;
439
440     return get_bits_count(gb);
441 }
442
443 /*
444  * copies as much of the codestream into the buffer as possible
445  * pass a shorter buflen to request less
446  * returns the number of bytes consumed from input, may be greater than input_len
447  * if the input doesn't end on an ISOBMFF-box boundary
448  */
449 int ff_jpegxl_collect_codestream_header(const uint8_t *input_buffer, int input_len,
450                                         uint8_t *buffer, int buflen, int *copied)
451 {
452     GetByteContext gb;
453     int pos = 0, last_box = 0;
454     bytestream2_init(&gb, input_buffer, input_len);
455
456     while (1) {
457         uint64_t size;
458         uint32_t tag;
459         int head_size = 8;
460
461         if (bytestream2_get_bytes_left(&gb) < 8)
462             return AVERROR_BUFFER_TOO_SMALL;
463
464         size = bytestream2_get_be32(&gb);
465         if (size == 1) {
466             if (bytestream2_get_bytes_left(&gb) < 12)
467                 return AVERROR_BUFFER_TOO_SMALL;
468             size = bytestream2_get_be64(&gb);
469             head_size = 16;
470         }
471         /* invalid ISOBMFF size */
472         if (size && size <= head_size)
473             return AVERROR_INVALIDDATA;
474         if (size)
475             size -= head_size;
476
477         tag = bytestream2_get_le32(&gb);
478
479         if (tag == MKTAG('j','x','l','p')) {
480             uint32_t idx;
481             if (bytestream2_get_bytes_left(&gb) < 4)
482                 return AVERROR_BUFFER_TOO_SMALL;
483             idx = bytestream2_get_be32(&gb);
484             if (idx >= UINT32_C(0x80000000))
485                 last_box = 1;
486             if (size) {
487                 if (size <= 4)
488                     return AVERROR_INVALIDDATA;
489                 size -= 4;
490             }
491         }
492         if (tag == MKTAG('j','x','l','c'))
493             last_box = 1;
494
495         /*
496          * size = 0 means "until EOF". this is legal but uncommon
497          * here we just set it to the remaining size of the probe buffer
498          */
499         if (!size)
500             size = bytestream2_get_bytes_left(&gb);
501         else
502             pos += size + head_size;
503
504         if (tag == MKTAG('j','x','l','c') || tag == MKTAG('j','x','l','p')) {
505             if (size > buflen - *copied)
506                 size = buflen - *copied;
507             /*
508              * arbitrary chunking of the payload makes this memcpy hard to avoid
509              * in practice this will only be performed one or two times at most
510              */
511             *copied += bytestream2_get_buffer(&gb, buffer + *copied, size);
512         } else {
513             bytestream2_skip(&gb, size);
514         }
515         if (last_box || bytestream2_get_bytes_left(&gb) <= 0 || *copied >= buflen)
516             break;
517     }
518
519     return pos;
520 }