FFmpeg
jpegxl_parse.c
Go to the documentation of this file.
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)) */
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 
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;
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);
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;
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);
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  */
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;
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 {
207  }
208 
209  if (get_bits_left(gb) < name_len)
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 
231 {
232  uint64_t extensions = jxl_u64(gb), extensions_len = 0;
233 
234  if (get_bits_left(gb) <= 0)
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)
245  }
246 
247  if (extensions_len > INT_MAX || get_bits_left(gb) <= extensions_len)
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 
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))
299 
300  /* preview header */
301  if (get_bits1(gb)) {
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)
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)
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)
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 
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)
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)
463 
464  size = bytestream2_get_be32(&gb);
465  tag = bytestream2_get_le32(&gb);
466 
467  if (size == 1) {
468  if (bytestream2_get_bytes_left(&gb) < 8)
470  size = bytestream2_get_be64(&gb);
471  head_size = 16;
472  }
473  /* invalid ISOBMFF size */
474  if (size && size <= head_size)
475  return AVERROR_INVALIDDATA;
476  if (size)
477  size -= head_size;
478 
479  if (tag == MKTAG('j','x','l','p')) {
480  uint32_t idx;
481  if (bytestream2_get_bytes_left(&gb) < 4)
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)
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 }
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:278
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:695
ff_jpegxl_parse_codestream_header
int ff_jpegxl_parse_codestream_header(const uint8_t *buf, int buflen, FFJXLMetadata *meta, int validate)
Definition: jpegxl_parse.c:255
GetByteContext
Definition: bytestream.h:33
JPEGXL_CT_CFA
@ JPEGXL_CT_CFA
Definition: jpegxl.h:56
FFJXLMetadata::coded_width
uint32_t coded_width
Definition: jpegxl_parse.h:34
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:421
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
JPEGXL_WP_CUSTOM
@ JPEGXL_WP_CUSTOM
Definition: jpegxl.h:71
FFJXLColorSpace
FFJXLColorSpace
Definition: jpegxl.h:62
FFJXLMetadata::have_timecodes
int have_timecodes
Definition: jpegxl_parse.h:52
jpegxl_read_size_header
static int jpegxl_read_size_header(GetBitContext *gb, FFJXLMetadata *meta, int validate)
validate a Jpeg XL Size Header
Definition: jpegxl_parse.c:112
JPEGXL_CS_RGB
@ JPEGXL_CS_RGB
Definition: jpegxl.h:63
c1
static const uint64_t c1
Definition: murmur3.c:52
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
JPEGXL_PR_SRGB
@ JPEGXL_PR_SRGB
Definition: jpegxl.h:77
FFJXLMetadata::primaries
FFJXLPrimaries primaries
Definition: jpegxl_parse.h:46
JPEGXL_CT_ALPHA
@ JPEGXL_CT_ALPHA
Definition: jpegxl.h:51
FFJXLMetadata
Definition: jpegxl_parse.h:31
jpegxl_width_from_ratio
static uint32_t jpegxl_width_from_ratio(uint32_t height, int ratio)
Definition: jpegxl_parse.c:83
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
primaries
enum AVColorPrimaries primaries
Definition: mediacodec_wrapper.c:2482
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
FFJXLWhitePoint
FFJXLWhitePoint
Definition: jpegxl.h:69
GetBitContext
Definition: get_bits.h:108
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
FFJXLMetadata::num_extra_channels
uint32_t num_extra_channels
Definition: jpegxl_parse.h:53
JPEGXL_CT_SPOT_COLOR
@ JPEGXL_CT_SPOT_COLOR
Definition: jpegxl.h:53
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
jxl_u32
static av_always_inline uint32_t jxl_u32(GetBitContext *gb, uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3)
Definition: jpegxl_parse.c:32
FFJXLMetadata::timebase
AVRational timebase
Definition: jpegxl_parse.h:43
JPEGXL_CS_GRAY
@ JPEGXL_CS_GRAY
Definition: jpegxl.h:64
width
#define width
jpegxl_read_preview_header
static int jpegxl_read_preview_header(GetBitContext *gb, int validate)
validate a Jpeg XL Preview Header
Definition: jpegxl_parse.c:145
FFJXLMetadata::height
uint32_t height
Definition: jpegxl_parse.h:33
FFJXLTransferCharacteristic
FFJXLTransferCharacteristic
Definition: jpegxl.h:83
FFJXLMetadata::coded_height
uint32_t coded_height
Definition: jpegxl_parse.h:35
get_bits.h
jpegxl.h
jxl_u64
static uint64_t jxl_u64(GetBitContext *gb)
Definition: jpegxl_parse.c:53
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
jxl_enum
static av_always_inline uint32_t jxl_enum(GetBitContext *gb)
Definition: jpegxl_parse.c:47
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
JPEGXL_PR_CUSTOM
@ JPEGXL_PR_CUSTOM
Definition: jpegxl.h:78
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
jpegxl_skip_extensions
static int jpegxl_skip_extensions(GetBitContext *gb)
Definition: jpegxl_parse.c:230
JPEGXL_TR_SRGB
@ JPEGXL_TR_SRGB
Definition: jpegxl.h:87
shift
static int shift(int a, int b)
Definition: bonk.c:261
FFJXLMetadata::xyb_encoded
int xyb_encoded
Definition: jpegxl_parse.h:50
size
int size
Definition: twinvq_data.h:10344
FFJXLMetadata::animation_offset
int animation_offset
Definition: jpegxl_parse.h:42
height
#define height
FFJXLMetadata::csp
FFJXLColorSpace csp
Definition: jpegxl_parse.h:44
skip_bits1
static void skip_bits1(GetBitContext *s)
Definition: get_bits.h:413
FFJXLPrimaries
FFJXLPrimaries
Definition: jpegxl.h:76
FFJXLMetadata::width
uint32_t width
Definition: jpegxl_parse.h:32
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FF_JPEGXL_CODESTREAM_SIGNATURE_LE
#define FF_JPEGXL_CODESTREAM_SIGNATURE_LE
Definition: jpegxl.h:25
av_always_inline
#define av_always_inline
Definition: attributes.h:49
tb
#define tb
Definition: regdef.h:68
JPEGXL_WP_D65
@ JPEGXL_WP_D65
Definition: jpegxl.h:70
FFJXLMetadata::wp
FFJXLWhitePoint wp
Definition: jpegxl_parse.h:45
tag
uint32_t tag
Definition: movenc.c:1787
ret
ret
Definition: filter_design.txt:187
jpegxl_get_bit_depth
static void jpegxl_get_bit_depth(GetBitContext *gb, FFJXLMetadata *meta)
get a Jpeg XL BitDepth Header.
Definition: jpegxl_parse.c:171
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
jpegxl_read_extra_channel_info
static int jpegxl_read_extra_channel_info(GetBitContext *gb, FFJXLMetadata *meta, int validate)
validate a Jpeg XL Extra Channel Info bundle
Definition: jpegxl_parse.c:190
pos
unsigned int pos
Definition: spdifenc.c:414
FFJXLMetadata::have_alpha
int have_alpha
Definition: jpegxl_parse.h:37
U
#define U(x)
Definition: vpx_arith.h:37
c2
static const uint64_t c2
Definition: murmur3.c:53
JPEGXL_CT_BLACK
@ JPEGXL_CT_BLACK
Definition: jpegxl.h:55
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
constants
static const struct @383 constants[]
FFJXLMetadata::have_icc_profile
int have_icc_profile
Definition: jpegxl_parse.h:51
FFJXLMetadata::bit_depth
int bit_depth
Definition: jpegxl_parse.h:36
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
jpegxl_parse.h
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FFJXLMetadata::trc
FFJXLTransferCharacteristic trc
Definition: jpegxl_parse.h:47
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
JPEGXL_CS_XYB
@ JPEGXL_CS_XYB
Definition: jpegxl.h:65
ff_jpegxl_collect_codestream_header
int ff_jpegxl_collect_codestream_header(const uint8_t *input_buffer, int input_len, uint8_t *buffer, int buflen, int *copied)
Definition: jpegxl_parse.c:449