12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541 |
- /**
- * JPEG XL parser
- * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include <errno.h>
- #include <stdint.h>
- #include <string.h>
- #include "libavutil/attributes.h"
- #include "libavutil/error.h"
- #include "libavutil/intmath.h"
- #include "libavutil/macros.h"
- #include "libavutil/mem.h"
- #include "libavutil/pixfmt.h"
- #include "bytestream.h"
- #include "codec_id.h"
- #define UNCHECKED_BITSTREAM_READER 0
- #define BITSTREAM_READER_LE
- #include "get_bits.h"
- #include "jpegxl.h"
- #include "jpegxl_parse.h"
- #include "parser.h"
- #include "vlc.h"
- #define JXL_FLAG_NOISE 1
- #define JXL_FLAG_PATCHES 2
- #define JXL_FLAG_SPLINES 16
- #define JXL_FLAG_USE_LF_FRAME 32
- #define JXL_FLAG_SKIP_ADAPTIVE_LF_SMOOTH 128
- #define MAX_PREFIX_ALPHABET_SIZE (1u << 15)
- #define clog1p(x) (ff_log2(x) + !!(x))
- #define unpack_signed(x) (((x) & 1 ? -(x)-1 : (x))/2)
- #define div_ceil(x, y) (((x) - 1) / (y) + 1)
- #define vlm(a,b) {.sym = (a), .len = (b)}
- typedef struct JXLHybridUintConf {
- int split_exponent;
- uint32_t msb_in_token;
- uint32_t lsb_in_token;
- } JXLHybridUintConf;
- typedef struct JXLSymbolDistribution {
- JXLHybridUintConf config;
- int log_bucket_size;
- /* this is the actual size of the alphabet */
- int alphabet_size;
- /* ceil(log(alphabet_size)) */
- int log_alphabet_size;
- /* for prefix code distributions */
- VLC vlc;
- /* in case bits == 0 */
- uint32_t default_symbol;
- /*
- * each (1 << log_alphabet_size) length
- * with log_alphabet_size <= 8
- */
- /* frequencies associated with this Distribution */
- uint32_t freq[258];
- /* cutoffs for using the symbol table */
- uint16_t cutoffs[258];
- /* the symbol table for this distribution */
- uint16_t symbols[258];
- /* the offset for symbols */
- uint16_t offsets[258];
- /* if this distribution contains only one symbol this is its index */
- int uniq_pos;
- } JXLSymbolDistribution;
- typedef struct JXLDistributionBundle {
- /* lz77 flags */
- int lz77_enabled;
- uint32_t lz77_min_symbol;
- uint32_t lz77_min_length;
- JXLHybridUintConf lz_len_conf;
- /* one entry for each distribution */
- uint8_t *cluster_map;
- /* length of cluster_map */
- int num_dist;
- /* one for each cluster */
- JXLSymbolDistribution *dists;
- int num_clusters;
- /* whether to use brotli prefixes or ans */
- int use_prefix_code;
- /* bundle log alphabet size, dist ones may be smaller */
- int log_alphabet_size;
- } JXLDistributionBundle;
- typedef struct JXLEntropyDecoder {
- /* state is a positive 32-bit integer, or -1 if unset */
- int64_t state;
- /* lz77 values */
- uint32_t num_to_copy;
- uint32_t copy_pos;
- uint32_t num_decoded;
- /* length is (1 << 20) */
- /* if lz77 is enabled for this bundle */
- /* if lz77 is disabled it's NULL */
- uint32_t *window;
- /* primary bundle associated with this distribution */
- JXLDistributionBundle bundle;
- /* for av_log */
- void *logctx;
- } JXLEntropyDecoder;
- typedef struct JXLFrame {
- FFJXLFrameType type;
- FFJXLFrameEncoding encoding;
- int is_last;
- int full_frame;
- uint32_t total_length;
- uint32_t body_length;
- } JXLFrame;
- typedef struct JXLCodestream {
- FFJXLMetadata meta;
- JXLFrame frame;
- } JXLCodestream;
- typedef struct JXLParseContext {
- ParseContext pc;
- JXLCodestream codestream;
- /* using ISOBMFF-based container */
- int container;
- int skip;
- int copied;
- int collected_size;
- int codestream_length;
- int skipped_icc;
- int next;
- uint8_t cs_buffer[4096 + AV_INPUT_BUFFER_PADDING_SIZE];
- } JXLParseContext;
- /* used for reading brotli prefixes */
- static const VLCElem level0_table[16] = {
- vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(2, 3), vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(1, 4),
- vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(2, 3), vlm(0, 2), vlm(4, 2), vlm(3, 2), vlm(5, 4),
- };
- /* prefix table for populating ANS distribution */
- static const VLCElem dist_prefix_table[128] = {
- vlm(10, 3), vlm(12, 7), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(11, 6), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(13, 7), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(11, 6), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- vlm(10, 3), vlm(0, 5), vlm(7, 3), vlm(3, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(5, 4),
- vlm(10, 3), vlm(4, 4), vlm(7, 3), vlm(1, 4), vlm(6, 3), vlm(8, 3), vlm(9, 3), vlm(2, 4),
- };
- static const uint8_t prefix_codelen_map[18] = {
- 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- };
- /**
- * Read a variable-length 8-bit integer.
- * Used when populating the ANS frequency tables.
- */
- static av_always_inline uint8_t jxl_u8(GetBitContext *gb)
- {
- int n;
- if (!get_bits1(gb))
- return 0;
- n = get_bits(gb, 3);
- return get_bitsz(gb, n) | (1 << n);
- }
- /* read a U32(c_i + u(u_i)) */
- 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)
- {
- const uint32_t constants[4] = {c0, c1, c2, c3};
- const uint32_t ubits [4] = {u0, u1, u2, u3};
- uint32_t ret, choice = get_bits(gb, 2);
- ret = constants[choice];
- if (ubits[choice])
- ret += get_bits_long(gb, ubits[choice]);
- return ret;
- }
- /* read a U64() */
- static uint64_t jxl_u64(GetBitContext *gb)
- {
- uint64_t shift = 12, ret;
- switch (get_bits(gb, 2)) {
- case 1:
- ret = 1 + get_bits(gb, 4);
- break;
- case 2:
- ret = 17 + get_bits(gb, 8);
- break;
- case 3:
- ret = get_bits(gb, 12);
- while (get_bits1(gb)) {
- if (shift < 60) {
- ret |= (uint64_t)get_bits(gb, 8) << shift;
- shift += 8;
- } else {
- ret |= (uint64_t)get_bits(gb, 4) << shift;
- break;
- }
- }
- break;
- default:
- ret = 0;
- }
- return ret;
- }
- static int read_hybrid_uint_conf(GetBitContext *gb, JXLHybridUintConf *conf, int log_alphabet_size)
- {
- conf->split_exponent = get_bitsz(gb, clog1p(log_alphabet_size));
- if (conf->split_exponent == log_alphabet_size) {
- conf->msb_in_token = conf->lsb_in_token = 0;
- return 0;
- }
- conf->msb_in_token = get_bitsz(gb, clog1p(conf->split_exponent));
- if (conf->msb_in_token > conf->split_exponent)
- return AVERROR_INVALIDDATA;
- conf->lsb_in_token = get_bitsz(gb, clog1p(conf->split_exponent - conf->msb_in_token));
- if (conf->msb_in_token + conf->lsb_in_token > conf->split_exponent)
- return AVERROR_INVALIDDATA;
- return 0;
- }
- static int read_hybrid_uint(GetBitContext *gb, const JXLHybridUintConf *conf, uint32_t token, uint32_t *hybrid_uint)
- {
- uint32_t n, low, split = 1 << conf->split_exponent;
- if (token < split) {
- *hybrid_uint = token;
- return 0;
- }
- n = conf->split_exponent - conf->lsb_in_token - conf->msb_in_token +
- ((token - split) >> (conf->msb_in_token + conf->lsb_in_token));
- if (n >= 32)
- return AVERROR_INVALIDDATA;
- low = token & ((1 << conf->lsb_in_token) - 1);
- token >>= conf->lsb_in_token;
- token &= (1 << conf->msb_in_token) - 1;
- token |= 1 << conf->msb_in_token;
- *hybrid_uint = (((token << n) | get_bits_long(gb, n)) << conf->lsb_in_token ) | low;
- return 0;
- }
- static inline uint32_t read_prefix_symbol(GetBitContext *gb, const JXLSymbolDistribution *dist)
- {
- if (!dist->vlc.bits)
- return dist->default_symbol;
- return get_vlc2(gb, dist->vlc.table, dist->vlc.bits, 1);
- }
- static uint32_t read_ans_symbol(GetBitContext *gb, JXLEntropyDecoder *dec, const JXLSymbolDistribution *dist)
- {
- uint32_t index, i, pos, symbol, offset;
- if (dec->state < 0)
- dec->state = get_bits_long(gb, 32);
- index = dec->state & 0xFFF;
- i = index >> dist->log_bucket_size;
- pos = index & ((1 << dist->log_bucket_size) - 1);
- symbol = pos >= dist->cutoffs[i] ? dist->symbols[i] : i;
- offset = pos >= dist->cutoffs[i] ? dist->offsets[i] + pos : pos;
- dec->state = dist->freq[symbol] * (dec->state >> 12) + offset;
- if (dec->state < (1 << 16))
- dec->state = (dec->state << 16) | get_bits(gb, 16);
- dec->state &= 0xFFFFFFFF;
- return symbol;
- }
- static int decode_hybrid_varlen_uint(GetBitContext *gb, JXLEntropyDecoder *dec,
- const JXLDistributionBundle *bundle,
- uint32_t context, uint32_t *hybrid_uint)
- {
- int ret;
- uint32_t token, distance;
- const JXLSymbolDistribution *dist;
- if (dec->num_to_copy > 0) {
- *hybrid_uint = dec->window[dec->copy_pos++ & 0xFFFFF];
- dec->num_to_copy--;
- dec->window[dec->num_decoded++ & 0xFFFFF] = *hybrid_uint;
- return 0;
- }
- if (context >= bundle->num_dist)
- return AVERROR(EINVAL);
- if (bundle->cluster_map[context] >= bundle->num_clusters)
- return AVERROR_INVALIDDATA;
- dist = &bundle->dists[bundle->cluster_map[context]];
- if (bundle->use_prefix_code)
- token = read_prefix_symbol(gb, dist);
- else
- token = read_ans_symbol(gb, dec, dist);
- if (bundle->lz77_enabled && token >= bundle->lz77_min_symbol) {
- const JXLSymbolDistribution *lz77dist = &bundle->dists[bundle->cluster_map[bundle->num_dist - 1]];
- if (!dec->num_decoded)
- return AVERROR_INVALIDDATA;
- ret = read_hybrid_uint(gb, &bundle->lz_len_conf, token - bundle->lz77_min_symbol, &dec->num_to_copy);
- if (ret < 0)
- return ret;
- dec->num_to_copy += bundle->lz77_min_length;
- if (bundle->use_prefix_code)
- token = read_prefix_symbol(gb, lz77dist);
- else
- token = read_ans_symbol(gb, dec, lz77dist);
- ret = read_hybrid_uint(gb, &lz77dist->config, token, &distance);
- if (ret < 0)
- return ret;
- distance++;
- distance = FFMIN3(distance, dec->num_decoded, 1 << 20);
- dec->copy_pos = dec->num_decoded - distance;
- return decode_hybrid_varlen_uint(gb, dec, bundle, context, hybrid_uint);
- }
- ret = read_hybrid_uint(gb, &dist->config, token, hybrid_uint);
- if (ret < 0)
- return ret;
- if (bundle->lz77_enabled)
- dec->window[dec->num_decoded++ & 0xFFFFF] = *hybrid_uint;
- return 0;
- }
- static int populate_distribution(GetBitContext *gb, JXLSymbolDistribution *dist, int log_alphabet_size)
- {
- int len = 0, shift, omit_log = -1, omit_pos = -1;
- int prev = 0, num_same = 0;
- uint32_t total_count = 0;
- uint8_t logcounts[258] = { 0 };
- uint8_t same[258] = { 0 };
- const int table_size = 1 << log_alphabet_size;
- dist->uniq_pos = -1;
- if (get_bits1(gb)) {
- /* simple code */
- if (get_bits1(gb)) {
- uint8_t v1 = jxl_u8(gb);
- uint8_t v2 = jxl_u8(gb);
- if (v1 == v2)
- return AVERROR_INVALIDDATA;
- dist->freq[v1] = get_bits(gb, 12);
- dist->freq[v2] = (1 << 12) - dist->freq[v1];
- if (!dist->freq[v1])
- dist->uniq_pos = v2;
- dist->alphabet_size = 1 + FFMAX(v1, v2);
- } else {
- uint8_t x = jxl_u8(gb);
- dist->freq[x] = 1 << 12;
- dist->uniq_pos = x;
- dist->alphabet_size = 1 + x;
- }
- if (dist->alphabet_size > table_size)
- return AVERROR_INVALIDDATA;
- return 0;
- }
- if (get_bits1(gb)) {
- /* flat code */
- dist->alphabet_size = jxl_u8(gb) + 1;
- if (dist->alphabet_size > table_size)
- return AVERROR_INVALIDDATA;
- for (int i = 0; i < dist->alphabet_size; i++)
- dist->freq[i] = (1 << 12) / dist->alphabet_size;
- for (int i = 0; i < (1 << 12) % dist->alphabet_size; i++)
- dist->freq[i]++;
- return 0;
- }
- do {
- if (!get_bits1(gb))
- break;
- } while (++len < 3);
- shift = (get_bitsz(gb, len) | (1 << len)) - 1;
- if (shift > 13)
- return AVERROR_INVALIDDATA;
- dist->alphabet_size = jxl_u8(gb) + 3;
- if (dist->alphabet_size > table_size)
- return AVERROR_INVALIDDATA;
- for (int i = 0; i < dist->alphabet_size; i++) {
- logcounts[i] = get_vlc2(gb, dist_prefix_table, 7, 1);
- if (logcounts[i] == 13) {
- int rle = jxl_u8(gb);
- same[i] = rle + 5;
- i += rle + 3;
- continue;
- }
- if (logcounts[i] > omit_log) {
- omit_log = logcounts[i];
- omit_pos = i;
- }
- }
- if (omit_pos < 0 || omit_pos + 1 < dist->alphabet_size && logcounts[omit_pos + 1] == 13)
- return AVERROR_INVALIDDATA;
- for (int i = 0; i < dist->alphabet_size; i++) {
- if (same[i]) {
- num_same = same[i] - 1;
- prev = i > 0 ? dist->freq[i - 1] : 0;
- }
- if (num_same) {
- dist->freq[i] = prev;
- num_same--;
- } else {
- if (i == omit_pos || !logcounts[i])
- continue;
- if (logcounts[i] == 1) {
- dist->freq[i] = 1;
- } else {
- int bitcount = FFMIN(FFMAX(0, shift - ((12 - logcounts[i] + 1) >> 1)), logcounts[i] - 1);
- dist->freq[i] = (1 << (logcounts[i] - 1)) + (get_bitsz(gb, bitcount) << (logcounts[i] - 1 - bitcount));
- }
- }
- total_count += dist->freq[i];
- }
- dist->freq[omit_pos] = (1 << 12) - total_count;
- return 0;
- }
- static void dist_bundle_close(JXLDistributionBundle *bundle)
- {
- if (bundle->use_prefix_code && bundle->dists)
- for (int i = 0; i < bundle->num_clusters; i++)
- ff_vlc_free(&bundle->dists[i].vlc);
- av_freep(&bundle->dists);
- av_freep(&bundle->cluster_map);
- }
- static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
- JXLDistributionBundle *bundle, int num_dist, int disallow_lz77);
- static int read_dist_clustering(GetBitContext *gb, JXLEntropyDecoder *dec, JXLDistributionBundle *bundle)
- {
- int ret;
- bundle->cluster_map = av_malloc(bundle->num_dist);
- if (!bundle->cluster_map)
- return AVERROR(ENOMEM);
- if (bundle->num_dist == 1) {
- bundle->cluster_map[0] = 0;
- bundle->num_clusters = 1;
- return 0;
- }
- if (get_bits1(gb)) {
- /* simple clustering */
- uint32_t nbits = get_bits(gb, 2);
- for (int i = 0; i < bundle->num_dist; i++)
- bundle->cluster_map[i] = get_bitsz(gb, nbits);
- } else {
- /* complex clustering */
- int use_mtf = get_bits1(gb);
- JXLDistributionBundle nested = { 0 };
- /* num_dist == 1 prevents this from recursing again */
- ret = read_distribution_bundle(gb, dec, &nested, 1, bundle->num_dist <= 2);
- if (ret < 0) {
- dist_bundle_close(&nested);
- return ret;
- }
- for (int i = 0; i < bundle->num_dist; i++) {
- uint32_t clust;
- ret = decode_hybrid_varlen_uint(gb, dec, &nested, 0, &clust);
- if (ret < 0) {
- dist_bundle_close(&nested);
- return ret;
- }
- bundle->cluster_map[i] = clust;
- }
- dec->state = -1;
- /* it's not going to necessarily be zero after reading */
- dec->num_to_copy = 0;
- dec->num_decoded = 0;
- dist_bundle_close(&nested);
- if (use_mtf) {
- uint8_t mtf[256];
- for (int i = 0; i < 256; i++)
- mtf[i] = i;
- for (int i = 0; i < bundle->num_dist; i++) {
- int index = bundle->cluster_map[i];
- bundle->cluster_map[i] = mtf[index];
- if (index) {
- int value = mtf[index];
- for (int j = index; j > 0; j--)
- mtf[j] = mtf[j - 1];
- mtf[0] = value;
- }
- }
- }
- }
- for (int i = 0; i < bundle->num_dist; i++) {
- if (bundle->cluster_map[i] >= bundle->num_clusters)
- bundle->num_clusters = bundle->cluster_map[i] + 1;
- }
- if (bundle->num_clusters > bundle->num_dist)
- return AVERROR_INVALIDDATA;
- return 0;
- }
- static int gen_alias_map(JXLEntropyDecoder *dec, JXLSymbolDistribution *dist, int log_alphabet_size)
- {
- uint32_t bucket_size, table_size;
- uint8_t overfull[256], underfull[256];
- int overfull_pos = 0, underfull_pos = 0;
- dist->log_bucket_size = 12 - log_alphabet_size;
- bucket_size = 1 << dist->log_bucket_size;
- table_size = 1 << log_alphabet_size;
- if (dist->uniq_pos >= 0) {
- for (int i = 0; i < table_size; i++) {
- dist->symbols[i] = dist->uniq_pos;
- dist->offsets[i] = bucket_size * i;
- dist->cutoffs[i] = 0;
- }
- return 0;
- }
- for (int i = 0; i < dist->alphabet_size; i++) {
- dist->cutoffs[i] = dist->freq[i];
- dist->symbols[i] = i;
- if (dist->cutoffs[i] > bucket_size)
- overfull[overfull_pos++] = i;
- else if (dist->cutoffs[i] < bucket_size)
- underfull[underfull_pos++] = i;
- }
- for (int i = dist->alphabet_size; i < table_size; i++) {
- dist->cutoffs[i] = 0;
- underfull[underfull_pos++] = i;
- }
- while (overfull_pos) {
- int o, u, by;
- /* this should be impossible */
- if (!underfull_pos)
- return AVERROR_INVALIDDATA;
- u = underfull[--underfull_pos];
- o = overfull[--overfull_pos];
- by = bucket_size - dist->cutoffs[u];
- dist->cutoffs[o] -= by;
- dist->symbols[u] = o;
- dist->offsets[u] = dist->cutoffs[o];
- if (dist->cutoffs[o] < bucket_size)
- underfull[underfull_pos++] = o;
- else if (dist->cutoffs[o] > bucket_size)
- overfull[overfull_pos++] = o;
- }
- for (int i = 0; i < table_size; i++) {
- if (dist->cutoffs[i] == bucket_size) {
- dist->symbols[i] = i;
- dist->offsets[i] = 0;
- dist->cutoffs[i] = 0;
- } else {
- dist->offsets[i] -= dist->cutoffs[i];
- }
- }
- return 0;
- }
- static int read_simple_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
- {
- int nsym, tree_select, bits;
- int8_t lens[4];
- int16_t symbols[4];
- nsym = 1 + get_bits(gb, 2);
- for (int i = 0; i < nsym; i++)
- symbols[i] = get_bitsz(gb, dist->log_alphabet_size);
- if (nsym == 4)
- tree_select = get_bits1(gb);
- switch (nsym) {
- case 1:
- dist->vlc.bits = 0;
- dist->default_symbol = symbols[0];
- return 0;
- case 2:
- bits = 1;
- lens[0] = 1, lens[1] = 1, lens[2] = 0, lens[3] = 0;
- if (symbols[1] < symbols[0])
- FFSWAP(int16_t, symbols[0], symbols[1]);
- break;
- case 3:
- bits = 2;
- lens[0] = 1, lens[1] = 2, lens[2] = 2, lens[3] = 0;
- if (symbols[2] < symbols[1])
- FFSWAP(int16_t, symbols[1], symbols[2]);
- break;
- case 4:
- if (tree_select) {
- bits = 3;
- lens[0] = 1, lens[1] = 2, lens[2] = 3, lens[3] = 3;
- if (symbols[3] < symbols[2])
- FFSWAP(int16_t, symbols[2], symbols[3]);
- } else {
- bits = 2;
- lens[0] = 2, lens[1] = 2, lens[2] = 2, lens[3] = 2;
- while (1) {
- if (symbols[1] < symbols[0])
- FFSWAP(int16_t, symbols[0], symbols[1]);
- if (symbols[3] < symbols[2])
- FFSWAP(int16_t, symbols[2], symbols[3]);
- if (symbols[1] <= symbols[2])
- break;
- FFSWAP(int16_t, symbols[1], symbols[2]);
- }
- }
- break;
- default:
- // Challenge Complete! How did we get here?
- return AVERROR_BUG;
- }
- return ff_vlc_init_from_lengths(&dist->vlc, bits, nsym, lens, 1, symbols,
- 2, 2, 0, VLC_INIT_LE, dec->logctx);
- }
- static int read_vlc_prefix(GetBitContext *gb, JXLEntropyDecoder *dec, JXLSymbolDistribution *dist)
- {
- int8_t level1_lens[18] = { 0 };
- int8_t level1_lens_s[18] = { 0 };
- int16_t level1_syms[18] = { 0 };
- uint32_t level1_codecounts[19] = { 0 };
- uint8_t *buf = NULL;
- int8_t *level2_lens, *level2_lens_s;
- int16_t *level2_syms;
- uint32_t *level2_codecounts;
- int repeat_count_prev = 0, repeat_count_zero = 0, prev = 8;
- int total_code = 0, len, hskip, num_codes = 0, ret;
- VLC level1_vlc = { 0 };
- if (dist->alphabet_size == 1) {
- dist->vlc.bits = 0;
- dist->default_symbol = 0;
- return 0;
- }
- hskip = get_bits(gb, 2);
- if (hskip == 1)
- return read_simple_vlc_prefix(gb, dec, dist);
- level1_codecounts[0] = hskip;
- for (int i = hskip; i < 18; i++) {
- len = level1_lens[prefix_codelen_map[i]] = get_vlc2(gb, level0_table, 4, 1);
- if (len < 0) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- level1_codecounts[len]++;
- if (len) {
- total_code += (32 >> len);
- num_codes++;
- }
- if (total_code >= 32) {
- level1_codecounts[0] += 18 - i - 1;
- break;
- }
- }
- if (total_code != 32 && num_codes >= 2 || num_codes < 1) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- for (int i = 1; i < 19; i++)
- level1_codecounts[i] += level1_codecounts[i - 1];
- for (int i = 17; i >= 0; i--) {
- int idx = --level1_codecounts[level1_lens[i]];
- level1_lens_s[idx] = level1_lens[i];
- level1_syms[idx] = i;
- }
- ret = ff_vlc_init_from_lengths(&level1_vlc, 5, 18, level1_lens_s, 1, level1_syms, 2, 2,
- 0, VLC_INIT_LE, dec->logctx);
- if (ret < 0)
- goto end;
- buf = av_mallocz(MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t) + sizeof(uint32_t))
- + sizeof(uint32_t));
- if (!buf) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- level2_lens = (int8_t *)buf;
- level2_lens_s = (int8_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * sizeof(int8_t));
- level2_syms = (int16_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t)));
- level2_codecounts = (uint32_t *)(buf + MAX_PREFIX_ALPHABET_SIZE * (2 * sizeof(int8_t) + sizeof(int16_t)));
- total_code = 0;
- for (int i = 0; i < dist->alphabet_size; i++) {
- len = get_vlc2(gb, level1_vlc.table, 5, 1);
- if (len < 0) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- if (get_bits_left(gb) < 0) {
- ret = AVERROR_BUFFER_TOO_SMALL;
- goto end;
- }
- if (len == 16) {
- int extra = 3 + get_bits(gb, 2);
- if (repeat_count_prev)
- extra += 4 * (repeat_count_prev - 2) - repeat_count_prev;
- extra = FFMIN(extra, dist->alphabet_size - i);
- for (int j = 0; j < extra; j++)
- level2_lens[i + j] = prev;
- total_code += (32768 >> prev) * extra;
- i += extra - 1;
- repeat_count_prev += extra;
- repeat_count_zero = 0;
- level2_codecounts[prev] += extra;
- } else if (len == 17) {
- int extra = 3 + get_bits(gb, 3);
- if (repeat_count_zero > 0)
- extra += 8 * (repeat_count_zero - 2) - repeat_count_zero;
- extra = FFMIN(extra, dist->alphabet_size - i);
- i += extra - 1;
- repeat_count_prev = 0;
- repeat_count_zero += extra;
- level2_codecounts[0] += extra;
- } else {
- level2_lens[i] = len;
- repeat_count_prev = repeat_count_zero = 0;
- if (len) {
- total_code += (32768 >> len);
- prev = len;
- }
- level2_codecounts[len]++;
- }
- if (total_code >= 32768) {
- level2_codecounts[0] += dist->alphabet_size - i - 1;
- break;
- }
- }
- if (total_code != 32768 && level2_codecounts[0] < dist->alphabet_size - 1) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- for (int i = 1; i < dist->alphabet_size + 1; i++)
- level2_codecounts[i] += level2_codecounts[i - 1];
- for (int i = dist->alphabet_size - 1; i >= 0; i--) {
- int idx = --level2_codecounts[level2_lens[i]];
- level2_lens_s[idx] = level2_lens[i];
- level2_syms[idx] = i;
- }
- ret = ff_vlc_init_from_lengths(&dist->vlc, 15, dist->alphabet_size, level2_lens_s,
- 1, level2_syms, 2, 2, 0, VLC_INIT_LE, dec->logctx);
- end:
- av_freep(&buf);
- ff_vlc_free(&level1_vlc);
- return ret;
- }
- static int read_distribution_bundle(GetBitContext *gb, JXLEntropyDecoder *dec,
- JXLDistributionBundle *bundle, int num_dist, int disallow_lz77)
- {
- int ret;
- if (num_dist <= 0)
- return AVERROR(EINVAL);
- bundle->num_dist = num_dist;
- bundle->lz77_enabled = get_bits1(gb);
- if (bundle->lz77_enabled) {
- if (disallow_lz77)
- return AVERROR_INVALIDDATA;
- bundle->lz77_min_symbol = jxl_u32(gb, 224, 512, 4096, 8, 0, 0, 0, 15);
- bundle->lz77_min_length = jxl_u32(gb, 3, 4, 5, 9, 0, 0, 2, 8);
- bundle->num_dist++;
- ret = read_hybrid_uint_conf(gb, &bundle->lz_len_conf, 8);
- if (ret < 0)
- return ret;
- }
- if (bundle->lz77_enabled && !dec->window) {
- dec->window = av_malloc_array(1 << 20, sizeof(uint32_t));
- if (!dec->window)
- return AVERROR(ENOMEM);
- }
- ret = read_dist_clustering(gb, dec, bundle);
- if (ret < 0)
- return ret;
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- bundle->dists = av_calloc(bundle->num_clusters, sizeof(JXLSymbolDistribution));
- if (!bundle->dists)
- return AVERROR(ENOMEM);
- bundle->use_prefix_code = get_bits1(gb);
- bundle->log_alphabet_size = bundle->use_prefix_code ? 15 : 5 + get_bits(gb, 2);
- for (int i = 0; i < bundle->num_clusters; i++) {
- ret = read_hybrid_uint_conf(gb, &bundle->dists[i].config, bundle->log_alphabet_size);
- if (ret < 0)
- return ret;
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (bundle->use_prefix_code) {
- for (int i = 0; i < bundle->num_clusters; i++) {
- JXLSymbolDistribution *dist = &bundle->dists[i];
- if (get_bits1(gb)) {
- int n = get_bits(gb, 4);
- dist->alphabet_size = 1 + (1 << n) + get_bitsz(gb, n);
- if (dist->alphabet_size > MAX_PREFIX_ALPHABET_SIZE)
- return AVERROR_INVALIDDATA;
- } else {
- dist->alphabet_size = 1;
- }
- dist->log_alphabet_size = clog1p(dist->alphabet_size - 1);
- }
- for (int i = 0; i < bundle->num_clusters; i++) {
- ret = read_vlc_prefix(gb, dec, &bundle->dists[i]);
- if (ret < 0)
- return ret;
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- } else {
- for (int i = 0; i < bundle->num_clusters; i++) {
- ret = populate_distribution(gb, &bundle->dists[i], bundle->log_alphabet_size);
- if (ret < 0)
- return ret;
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- for (int i = 0; i < bundle->num_clusters; i++) {
- ret = gen_alias_map(dec, &bundle->dists[i], bundle->log_alphabet_size);
- if (ret < 0)
- return ret;
- }
- }
- return 0;
- }
- static void entropy_decoder_close(JXLEntropyDecoder *dec)
- {
- if (!dec)
- return;
- av_freep(&dec->window);
- dist_bundle_close(&dec->bundle);
- }
- static int entropy_decoder_init(void *avctx, GetBitContext *gb, JXLEntropyDecoder *dec, int num_dist)
- {
- int ret;
- memset(dec, 0, sizeof(*dec));
- dec->logctx = avctx;
- dec->state = -1;
- ret = read_distribution_bundle(gb, dec, &dec->bundle, num_dist, 0);
- if (ret < 0) {
- entropy_decoder_close(dec);
- return ret;
- }
- return 0;
- }
- static int64_t entropy_decoder_read_symbol(GetBitContext *gb, JXLEntropyDecoder *dec, uint32_t context)
- {
- int ret;
- uint32_t hybrid_uint;
- ret = decode_hybrid_varlen_uint(gb, dec, &dec->bundle, context, &hybrid_uint);
- if (ret < 0)
- return ret;
- return hybrid_uint;
- }
- static inline uint32_t icc_context(uint64_t i, uint32_t b1, uint32_t b2)
- {
- uint32_t p1, p2;
- if (i <= 128)
- return 0;
- if (b1 >= 'a' && b1 <= 'z' || b1 >= 'A' && b1 <= 'Z')
- p1 = 0;
- else if (b1 >= '0' && b1 <= '9' || b1 == '.' || b1 == ',')
- p1 = 1;
- else if (b1 <= 1)
- p1 = b1 + 2;
- else if (b1 > 1 && b1 < 16)
- p1 = 4;
- else if (b1 > 240 && b1 < 255)
- p1 = 5;
- else if (b1 == 255)
- p1 = 6;
- else
- p1 = 7;
- if (b2 >= 'a' && b2 <= 'z' || b2 >= 'A' && b2 <= 'Z')
- p2 = 0;
- else if (b2 >= '0' && b2 <= '9' || b2 == '.' || b2 == ',')
- p2 = 1;
- else if (b2 < 16)
- p2 = 2;
- else if (b2 > 240)
- p2 = 3;
- else
- p2 = 4;
- return 1 + p1 + p2 * 8;
- }
- static inline uint32_t toc_context(uint32_t x)
- {
- return FFMIN(7, clog1p(x));
- }
- static void populate_fields(AVCodecParserContext *s, AVCodecContext *avctx, const FFJXLMetadata *meta)
- {
- s->width = meta->width;
- s->height = meta->height;
- switch (meta->csp) {
- case JPEGXL_CS_RGB:
- case JPEGXL_CS_XYB:
- avctx->colorspace = AVCOL_SPC_RGB;
- break;
- default:
- avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
- }
- if (meta->wp == JPEGXL_WP_D65) {
- switch (meta->primaries) {
- case JPEGXL_PR_SRGB:
- avctx->color_primaries = AVCOL_PRI_BT709;
- break;
- case JPEGXL_PR_P3:
- avctx->color_primaries = AVCOL_PRI_SMPTE432;
- break;
- case JPEGXL_PR_2100:
- avctx->color_primaries = AVCOL_PRI_BT2020;
- break;
- default:
- avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
- }
- } else if (meta->wp == JPEGXL_WP_DCI && meta->primaries == JPEGXL_PR_P3) {
- avctx->color_primaries = AVCOL_PRI_SMPTE431;
- } else {
- avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
- }
- if (meta->trc > JPEGXL_TR_GAMMA) {
- FFJXLTransferCharacteristic trc = meta->trc - JPEGXL_TR_GAMMA;
- switch (trc) {
- case JPEGXL_TR_BT709:
- avctx->color_trc = AVCOL_TRC_BT709;
- break;
- case JPEGXL_TR_LINEAR:
- avctx->color_trc = AVCOL_TRC_LINEAR;
- break;
- case JPEGXL_TR_SRGB:
- avctx->color_trc = AVCOL_TRC_IEC61966_2_1;
- break;
- case JPEGXL_TR_PQ:
- avctx->color_trc = AVCOL_TRC_SMPTEST2084;
- break;
- case JPEGXL_TR_DCI:
- avctx->color_trc = AVCOL_TRC_SMPTE428;
- break;
- case JPEGXL_TR_HLG:
- avctx->color_trc = AVCOL_TRC_ARIB_STD_B67;
- break;
- default:
- avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
- }
- } else if (meta->trc > 0) {
- if (meta->trc > 45355 && meta->trc < 45555)
- avctx->color_trc = AVCOL_TRC_GAMMA22;
- else if (meta->trc > 35614 && meta->trc < 35814)
- avctx->color_trc = AVCOL_TRC_GAMMA28;
- else
- avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
- } else {
- avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
- }
- if (meta->csp == JPEGXL_CS_GRAY) {
- if (meta->bit_depth <= 8)
- s->format = meta->have_alpha ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
- else if (meta->bit_depth <= 16)
- s->format = meta->have_alpha ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
- else
- s->format = meta->have_alpha ? AV_PIX_FMT_NONE : AV_PIX_FMT_GRAYF32;
- } else {
- if (meta->bit_depth <= 8)
- s->format = meta->have_alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
- else if (meta->bit_depth <= 16)
- s->format = meta->have_alpha ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
- else
- s->format = meta->have_alpha ? AV_PIX_FMT_RGBAF32 : AV_PIX_FMT_RGBF32;
- }
- }
- static int skip_icc_profile(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
- {
- int64_t ret;
- uint32_t last = 0, last2 = 0;
- JXLEntropyDecoder dec = { 0 };
- uint64_t enc_size = jxl_u64(gb);
- uint64_t output_size = 0;
- int out_size_shift = 0;
- if (!enc_size || enc_size > (1 << 22))
- return AVERROR_INVALIDDATA;
- ret = entropy_decoder_init(avctx, gb, &dec, 41);
- if (ret < 0)
- goto end;
- if (get_bits_left(gb) < 0) {
- ret = AVERROR_BUFFER_TOO_SMALL;
- goto end;
- }
- for (uint64_t read = 0; read < enc_size; read++) {
- ret = entropy_decoder_read_symbol(gb, &dec, icc_context(read, last, last2));
- if (ret < 0)
- goto end;
- if (ret > 255) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- if (get_bits_left(gb) < 0) {
- ret = AVERROR_BUFFER_TOO_SMALL;
- goto end;
- }
- last2 = last;
- last = ret;
- if (out_size_shift < 63) {
- output_size += (ret & UINT64_C(0x7F)) << out_size_shift;
- if (!(ret & 0x80)) {
- out_size_shift = 63;
- } else {
- out_size_shift += 7;
- if (out_size_shift > 56) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- }
- } else if (output_size < 132) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- }
- ret = 0;
- end:
- entropy_decoder_close(&dec);
- return ret;
- }
- static int skip_extensions(GetBitContext *gb)
- {
- uint64_t extensions = jxl_u64(gb), extensions_len = 0;
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- if (!extensions)
- return 0;
- for (int i = 0; i < 64; i++) {
- if (extensions & (UINT64_C(1) << i))
- extensions_len += jxl_u64(gb);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (extensions_len > INT_MAX || get_bits_left(gb) < extensions_len)
- return AVERROR_BUFFER_TOO_SMALL;
- skip_bits_long(gb, extensions_len);
- return 0;
- }
- static int parse_frame_header(void *avctx, JXLParseContext *ctx, GetBitContext *gb)
- {
- int all_default, do_yCbCr = 0, num_passes = 1, ret;
- int group_size_shift = 1, lf_level = 0, save_as_ref = 0;
- int have_crop = 0, full_frame = 1, resets_canvas = 1, upsampling = 1;
- JXLFrame *frame = &ctx->codestream.frame;
- const FFJXLMetadata *meta = &ctx->codestream.meta;
- int32_t x0 = 0, y0 = 0;
- uint32_t duration = 0, width = meta->coded_width, height = meta->coded_height;
- uint32_t name_len, num_groups, num_lf_groups, group_dim, lf_group_dim, toc_count;
- uint64_t flags = 0;
- int start_len = get_bits_count(gb);
- memset(frame, 0, sizeof(*frame));
- frame->is_last = 1;
- all_default = get_bits1(gb);
- if (!all_default) {
- frame->type = get_bits(gb, 2);
- frame->encoding = get_bits1(gb);
- flags = jxl_u64(gb);
- if (!meta->xyb_encoded)
- do_yCbCr = get_bits1(gb);
- if (!(flags & JXL_FLAG_USE_LF_FRAME)) {
- if (do_yCbCr)
- skip_bits(gb, 6); // jpeg upsampling
- upsampling = jxl_u32(gb, 1, 2, 4, 8, 0, 0, 0, 0);
- skip_bits_long(gb, 2 * meta->num_extra_channels);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (frame->encoding == JPEGXL_ENC_MODULAR)
- group_size_shift = get_bits(gb, 2);
- else if (meta->xyb_encoded)
- skip_bits(gb, 6); // xqm and bqm scales
- if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
- num_passes = jxl_u32(gb, 1, 2, 3, 4, 0, 0, 0, 3);
- if (num_passes != 1) {
- int num_ds = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 1);
- skip_bits(gb, 2 * (num_passes - 1)); // shift
- skip_bits(gb, 2 * num_ds); // downsample
- for (int i = 0; i < num_ds; i++)
- jxl_u32(gb, 0, 1, 2, 0, 0, 0, 0, 3);
- }
- }
- if (frame->type == JPEGXL_FRAME_LF)
- lf_level = 1 + get_bits(gb, 2);
- else
- have_crop = get_bits1(gb);
- if (have_crop) {
- if (frame->type != JPEGXL_FRAME_REFERENCE_ONLY) {
- uint32_t ux0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
- uint32_t uy0 = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
- x0 = unpack_signed(ux0);
- y0 = unpack_signed(uy0);
- }
- width = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
- height = jxl_u32(gb, 0, 256, 2304, 18688, 8, 11, 14, 30);
- full_frame = x0 <= 0 && y0 <= 0 && width + x0 >= meta->coded_width
- && height + y0 >= meta->coded_height;
- }
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- if (frame->type == JPEGXL_FRAME_REGULAR || frame->type == JPEGXL_FRAME_SKIP_PROGRESSIVE) {
- for (int i = 0; i <= meta->num_extra_channels; i++) {
- int mode = jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
- if (meta->num_extra_channels && (mode == JPEGXL_BM_BLEND || mode == JPEGXL_BM_MULADD))
- jxl_u32(gb, 0, 1, 2, 3, 0, 0, 0, 2);
- if (meta->num_extra_channels && (mode == JPEGXL_BM_BLEND || mode == JPEGXL_BM_MULADD
- || mode == JPEGXL_BM_MUL))
- skip_bits1(gb);
- if (!i)
- resets_canvas = mode == JPEGXL_BM_REPLACE && full_frame;
- if (!resets_canvas)
- skip_bits(gb, 2);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (meta->animation_offset)
- duration = jxl_u32(gb, 0, 1, 0, 0, 0, 0, 8, 32);
- if (meta->have_timecodes)
- skip_bits_long(gb, 32);
- frame->is_last = get_bits1(gb);
- } else {
- frame->is_last = 0;
- }
- if (frame->type != JPEGXL_FRAME_LF && !frame->is_last)
- save_as_ref = get_bits(gb, 2);
- if (frame->type == JPEGXL_FRAME_REFERENCE_ONLY ||
- (resets_canvas && !frame->is_last && (!duration || save_as_ref)
- && frame->type != JPEGXL_FRAME_LF))
- skip_bits1(gb); // save before color transform
- name_len = 8 * jxl_u32(gb, 0, 0, 16, 48, 0, 4, 5, 10);
- if (get_bits_left(gb) < name_len)
- return AVERROR_BUFFER_TOO_SMALL;
- skip_bits_long(gb, name_len);
- }
- if (!all_default) {
- int restd = get_bits1(gb), gab = 1;
- if (!restd)
- gab = get_bits1(gb);
- if (gab && !restd && get_bits1(gb))
- // gab custom
- skip_bits_long(gb, 16 * 6);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- if (!restd) {
- int epf = get_bits(gb, 2);
- if (epf) {
- if (frame->encoding == JPEGXL_ENC_VARDCT && get_bits1(gb)) {
- skip_bits_long(gb, 16 * 8); // custom epf sharpness
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (get_bits1(gb)) {
- skip_bits_long(gb, 3 * 16 + 32); // custom epf weight
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (get_bits1(gb)) { // custom epf sigma
- if (frame->encoding == JPEGXL_ENC_VARDCT)
- skip_bits(gb, 16);
- skip_bits_long(gb, 16 * 3);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- if (frame->encoding == JPEGXL_ENC_MODULAR)
- skip_bits(gb, 16);
- }
- ret = skip_extensions(gb);
- if (ret < 0)
- return ret;
- }
- ret = skip_extensions(gb);
- if (ret < 0)
- return ret;
- }
- width = div_ceil(div_ceil(width, upsampling), 1 << (3 * lf_level));
- height = div_ceil(div_ceil(height, upsampling), 1 << (3 * lf_level));
- group_dim = 128 << group_size_shift;
- lf_group_dim = group_dim << 3;
- num_groups = div_ceil(width, group_dim) * div_ceil(height, group_dim);
- num_lf_groups = div_ceil(width, lf_group_dim) * div_ceil(height, lf_group_dim);
- if (num_groups == 1 && num_passes == 1)
- toc_count = 1;
- else
- toc_count = 2 + num_lf_groups + num_groups * num_passes;
- // permuted toc
- if (get_bits1(gb)) {
- JXLEntropyDecoder dec;
- int64_t end, lehmer = 0;
- ret = entropy_decoder_init(avctx, gb, &dec, 8);
- if (ret < 0)
- return ret;
- if (get_bits_left(gb) < 0) {
- entropy_decoder_close(&dec);
- return AVERROR_BUFFER_TOO_SMALL;
- }
- end = entropy_decoder_read_symbol(gb, &dec, toc_context(toc_count));
- if (end < 0 || end > toc_count) {
- entropy_decoder_close(&dec);
- return AVERROR_INVALIDDATA;
- }
- for (uint32_t i = 0; i < end; i++) {
- lehmer = entropy_decoder_read_symbol(gb, &dec, toc_context(lehmer));
- if (lehmer < 0 || get_bits_left(gb) < 0) {
- entropy_decoder_close(&dec);
- return AVERROR_BUFFER_TOO_SMALL;
- }
- }
- entropy_decoder_close(&dec);
- }
- align_get_bits(gb);
- for (uint32_t i = 0; i < toc_count; i++) {
- frame->body_length += 8 * jxl_u32(gb, 0, 1024, 17408, 4211712, 10, 14, 22, 30);
- if (get_bits_left(gb) < 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- align_get_bits(gb);
- frame->total_length = frame->body_length + get_bits_count(gb) - start_len;
- return 0;
- }
- static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size)
- {
- GetByteContext gb;
- if (ctx->skip > buf_size)
- return AVERROR_BUFFER_TOO_SMALL;
- buf += ctx->skip;
- buf_size -= ctx->skip;
- bytestream2_init(&gb, buf, buf_size);
- while (1) {
- uint64_t size;
- int head_size = 8;
- if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
- break;
- if (bytestream2_peek_le64(&gb) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
- break;
- if (bytestream2_get_bytes_left(&gb) < 8)
- return AVERROR_BUFFER_TOO_SMALL;
- size = bytestream2_get_be32(&gb);
- bytestream2_skip(&gb, 4); // tag
- if (size == 1) {
- if (bytestream2_get_bytes_left(&gb) < 8)
- return AVERROR_BUFFER_TOO_SMALL;
- size = bytestream2_get_be64(&gb);
- head_size = 16;
- }
- if (!size)
- return AVERROR_INVALIDDATA;
- /* invalid ISOBMFF size */
- if (size <= head_size || size > INT_MAX - ctx->skip)
- return AVERROR_INVALIDDATA;
- ctx->skip += size;
- bytestream2_skip(&gb, size - head_size);
- if (bytestream2_get_bytes_left(&gb) <= 0)
- return AVERROR_BUFFER_TOO_SMALL;
- }
- return 0;
- }
- static int try_parse(AVCodecParserContext *s, AVCodecContext *avctx, JXLParseContext *ctx,
- const uint8_t *buf, int buf_size)
- {
- int ret, cs_buflen, header_skip;
- const uint8_t *cs_buffer;
- GetBitContext gb;
- if (ctx->skip > buf_size)
- return AVERROR_BUFFER_TOO_SMALL;
- buf += ctx->skip;
- buf_size -= ctx->skip;
- if (ctx->container || AV_RL64(buf) == FF_JPEGXL_CONTAINER_SIGNATURE_LE) {
- ctx->container = 1;
- ret = ff_jpegxl_collect_codestream_header(buf, buf_size, ctx->cs_buffer,
- sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, &ctx->copied);
- if (ret < 0)
- return ret;
- ctx->collected_size = ret;
- if (!ctx->copied) {
- ctx->skip += ret;
- return AVERROR_BUFFER_TOO_SMALL;
- }
- cs_buffer = ctx->cs_buffer;
- cs_buflen = FFMIN(sizeof(ctx->cs_buffer) - AV_INPUT_BUFFER_PADDING_SIZE, ctx->copied);
- } else {
- cs_buffer = buf;
- cs_buflen = buf_size;
- }
- if (!ctx->codestream_length) {
- header_skip = ff_jpegxl_parse_codestream_header(cs_buffer, cs_buflen, &ctx->codestream.meta, 0);
- if (header_skip < 0)
- return header_skip;
- ctx->codestream_length = header_skip;
- populate_fields(s, avctx, &ctx->codestream.meta);
- }
- if (ctx->container)
- return ctx->collected_size;
- ret = init_get_bits8(&gb, cs_buffer, cs_buflen);
- if (ret < 0)
- return ret;
- skip_bits_long(&gb, ctx->codestream_length);
- if (!ctx->skipped_icc && ctx->codestream.meta.have_icc_profile) {
- ret = skip_icc_profile(avctx, ctx, &gb);
- if (ret < 0)
- return ret;
- ctx->skipped_icc = 1;
- align_get_bits(&gb);
- ctx->codestream_length = get_bits_count(&gb);
- }
- if (get_bits_left(&gb) <= 0)
- return AVERROR_BUFFER_TOO_SMALL;
- while (1) {
- ret = parse_frame_header(avctx, ctx, &gb);
- if (ret < 0)
- return ret;
- ctx->codestream_length += ctx->codestream.frame.total_length;
- if (ctx->codestream.frame.is_last)
- return ctx->codestream_length / 8;
- if (get_bits_left(&gb) <= ctx->codestream.frame.body_length)
- return AVERROR_BUFFER_TOO_SMALL;
- skip_bits_long(&gb, ctx->codestream.frame.body_length);
- }
- }
- static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx,
- const uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size)
- {
- JXLParseContext *ctx = s->priv_data;
- int next = END_NOT_FOUND, ret;
- const uint8_t *pbuf = ctx->pc.buffer;
- int pindex = ctx->pc.index;
- *poutbuf_size = 0;
- *poutbuf = NULL;
- if (!ctx->pc.index) {
- if (ctx->pc.overread)
- goto flush;
- pbuf = buf;
- pindex = buf_size;
- }
- if ((!ctx->container || !ctx->codestream_length) && !ctx->next) {
- ret = try_parse(s, avctx, ctx, pbuf, pindex);
- if (ret < 0)
- goto flush;
- ctx->next = ret;
- if (ctx->container)
- ctx->skip += ctx->next;
- }
- if (ctx->container && ctx->next >= 0) {
- ret = skip_boxes(ctx, pbuf, pindex);
- if (ret < 0) {
- if (ret == AVERROR_INVALIDDATA)
- ctx->next = -1;
- goto flush;
- }
- ctx->next = ret + ctx->skip;
- }
- if (ctx->next >= 0)
- next = ctx->next - ctx->pc.index;
- flush:
- if (next > buf_size)
- next = END_NOT_FOUND;
- ret = ff_combine_frame(&ctx->pc, next, &buf, &buf_size);
- if (ret < 0)
- return buf_size;
- *poutbuf = buf;
- *poutbuf_size = buf_size;
- ctx->codestream_length = 0;
- ctx->collected_size = 0;
- ctx->container = 0;
- ctx->copied = 0;
- ctx->skip = 0;
- ctx->skipped_icc = 0;
- ctx->next = 0;
- memset(&ctx->codestream, 0, sizeof(ctx->codestream));
- return next;
- }
- const AVCodecParser ff_jpegxl_parser = {
- .codec_ids = { AV_CODEC_ID_JPEGXL, AV_CODEC_ID_JPEGXL_ANIM },
- .priv_data_size = sizeof(JXLParseContext),
- .parser_parse = jpegxl_parse,
- .parser_close = ff_parse_close,
- };
|