44#include <jxl/decode.h>
45#include <jxl/thread_parallel_runner.h>
53#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
75 ctx->events = JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE
76 | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME
78 if (JxlDecoderSubscribeEvents(
ctx->decoder,
ctx->events) != JXL_DEC_SUCCESS) {
83 if (JxlDecoderSetDecompressBoxes(
ctx->decoder, JXL_TRUE) != JXL_DEC_SUCCESS) {
88 if (JxlDecoderSetParallelRunner(
ctx->decoder, JxlThreadParallelRunner,
ctx->runner) != JXL_DEC_SUCCESS) {
94 memset(&
ctx->basic_info, 0,
sizeof(JxlBasicInfo));
95 memset(&
ctx->jxl_pixfmt, 0,
sizeof(JxlPixelFormat));
96 ctx->prev_is_last = 1;
104 JxlMemoryManager manager;
107 ctx->decoder = JxlDecoderCreate(&manager);
129 const JxlBasicInfo *basic_info = &
ctx->basic_info;
130 JxlPixelFormat *
format = &
ctx->jxl_pixfmt;
131 format->endianness = JXL_NATIVE_ENDIAN;
132 format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
133#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
135 ctx->jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
136 ctx->jxl_bit_depth.exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
139 if (basic_info->num_color_channels == 1) {
140 if (basic_info->bits_per_sample <= 8) {
141 format->data_type = JXL_TYPE_UINT8;
144 if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
145 if (!basic_info->alpha_bits) {
146 format->data_type = JXL_TYPE_FLOAT;
151 format->data_type = JXL_TYPE_UINT16;
156 if (basic_info->num_color_channels == 3) {
157 if (basic_info->bits_per_sample <= 8) {
158 format->data_type = JXL_TYPE_UINT8;
161 if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
162 format->data_type = JXL_TYPE_FLOAT;
165 format->data_type = JXL_TYPE_UINT16;
178 desc.prim.r.x =
av_d2q(jxl_color->primaries_red_xy[0], 300000);
179 desc.prim.r.y =
av_d2q(jxl_color->primaries_red_xy[1], 300000);
180 desc.prim.g.x =
av_d2q(jxl_color->primaries_green_xy[0], 300000);
181 desc.prim.g.y =
av_d2q(jxl_color->primaries_green_xy[1], 300000);
182 desc.prim.b.x =
av_d2q(jxl_color->primaries_blue_xy[0], 300000);
183 desc.prim.b.y =
av_d2q(jxl_color->primaries_blue_xy[1], 300000);
184 desc.wp.x =
av_d2q(jxl_color->white_point_xy[0], 300000);
185 desc.wp.y =
av_d2q(jxl_color->white_point_xy[1], 300000);
201 switch (jxl_color->transfer_function) {
208 case JXL_TRANSFER_FUNCTION_GAMMA:
209 if (jxl_color->gamma > 0.45355 && jxl_color->gamma < 0.45555)
211 else if (jxl_color->gamma > 0.35614 && jxl_color->gamma < 0.35814)
227 JxlDecoderStatus jret;
230#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
231 jret = JxlDecoderGetICCProfileSize(
ctx->decoder, &
ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA, &icc_len);
233 jret = JxlDecoderGetICCProfileSize(
ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA, &icc_len);
235 if (jret == JXL_DEC_SUCCESS && icc_len > 0) {
240#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
241 jret = JxlDecoderGetColorAsICCProfile(
ctx->decoder, &
ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA,
242 ctx->iccp->data, icc_len);
244 jret = JxlDecoderGetColorAsICCProfile(
ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA,
ctx->iccp->data, icc_len);
246 if (jret != JXL_DEC_SUCCESS) {
275 JxlDecoderStatus jret;
277 JxlColorEncoding jxl_color;
281#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
282 jret = JxlDecoderGetColorAsEncodedProfile(
ctx->decoder,
NULL, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &jxl_color);
284 jret = JxlDecoderGetColorAsEncodedProfile(
ctx->decoder, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &jxl_color);
286 if (jret == JXL_DEC_SUCCESS) {
288 jret = JxlDecoderSetPreferredColorProfile(
ctx->decoder, &jxl_color);
289 if (jret == JXL_DEC_SUCCESS)
290#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
291 jret = JxlDecoderGetColorAsEncodedProfile(
ctx->decoder, &
ctx->jxl_pixfmt,
292 JXL_COLOR_PROFILE_TARGET_DATA, &jxl_color);
294 jret = JxlDecoderGetColorAsEncodedProfile(
ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA, &jxl_color);
298 if (jret != JXL_DEC_SUCCESS)
302 if (
ctx->basic_info.uses_original_profile) {
318 if (
ctx->basic_info.num_color_channels > 1)
334 jxl_color.primaries = JXL_PRIMARIES_2100;
338 jxl_color.white_point = JXL_WHITE_POINT_D65;
341 if (
ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT
342 ||
ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT16) {
344 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_LINEAR;
348 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
353 jxl_color.rendering_intent = JXL_RENDERING_INTENT_RELATIVE;
354 jxl_color.color_space =
ctx->basic_info.num_color_channels > 1 ? JXL_COLOR_SPACE_RGB : JXL_COLOR_SPACE_GRAY;
355 jret = JxlDecoderSetPreferredColorProfile(
ctx->decoder, &jxl_color);
356 if (jret != JXL_DEC_SUCCESS) {
420 size_t remainder = JxlDecoderReleaseBoxBuffer(
ctx->decoder);
421 ctx->exif_pos =
ctx->exif->size - remainder;
426 ctx->frame_complete = 0;
445 ctx->accumulated_pts = 0;
446 ctx->frame_duration = 0;
449 if (
ctx->jret == JXL_DEC_NEED_MORE_INPUT && !
ctx->frame_complete) {
452 }
else if (
ctx->frame_complete) {
453 ctx->jret = JXL_DEC_SUCCESS;
460 ctx->jret = JxlDecoderSetInput(
ctx->decoder,
pkt->data,
pkt->size);
461 if (
ctx->jret == JXL_DEC_ERROR) {
467 ctx->jret = JxlDecoderProcessInput(
ctx->decoder);
473 remaining = JxlDecoderReleaseInput(
ctx->decoder);
474 size_t consumed =
pkt->size - remaining;
475 pkt->data += consumed;
476 pkt->size = remaining;
489 case JXL_DEC_NEED_MORE_INPUT:
492 case JXL_DEC_BASIC_INFO:
494 if (JxlDecoderGetBasicInfo(
ctx->decoder, &
ctx->basic_info) != JXL_DEC_SUCCESS) {
509 if (
ctx->basic_info.have_animation)
510 ctx->anim_timebase =
av_make_q(
ctx->basic_info.animation.tps_denominator,
511 ctx->basic_info.animation.tps_numerator);
512 if (
ctx->basic_info.alpha_bits) {
513 if (
ctx->basic_info.alpha_premultiplied)
519 case JXL_DEC_COLOR_ENCODING:
525 case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
530 ctx->jxl_pixfmt.align =
ctx->frame->linesize[0];
531 if (JxlDecoderSetImageOutBuffer(
ctx->decoder, &
ctx->jxl_pixfmt,
532 ctx->frame->data[0],
ctx->frame->buf[0]->size)
533 != JXL_DEC_SUCCESS) {
537#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
538 if (JxlDecoderSetImageOutBitDepth(
ctx->decoder, &
ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) {
547 if (
ctx->prev_is_last) {
555 if (JxlDecoderGetFrameHeader(
ctx->decoder, &
header) != JXL_DEC_SUCCESS) {
561 if (
ctx->basic_info.have_animation &&
header.duration)
564 case JXL_DEC_FULL_IMAGE:
567 if (
ctx->basic_info.have_animation) {
572 ctx->frame->duration =
pkt->duration;
575 ctx->frame->pts +=
pkt->pts;
576 ctx->accumulated_pts +=
ctx->frame_duration;
577 ctx->frame->pkt_dts =
pkt->dts;
578 if (
ctx->basic_info.have_animation && !
ctx->prev_is_last) {
582 ctx->frame_complete = 1;
585 case JXL_DEC_SUCCESS:
595 JxlDecoderReset(
ctx->decoder);
603 size_t remainder = JxlDecoderReleaseBoxBuffer(
ctx->decoder);
604 ctx->exif_pos =
ctx->exif->size - remainder;
606 if (JxlDecoderGetBoxType(
ctx->decoder,
type, JXL_TRUE) != JXL_DEC_SUCCESS) {
621 if (JxlDecoderSetBoxBuffer(
ctx->decoder,
ctx->exif->data,
ctx->exif->size) != JXL_DEC_SUCCESS) {
627 case JXL_DEC_BOX_NEED_MORE_OUTPUT: {
629 size_t remainder = JxlDecoderReleaseBoxBuffer(
ctx->decoder);
630 ctx->exif_pos =
ctx->exif->size - remainder;
631 size_t new_size =
ctx->exif->size << 1;
635 if (JxlDecoderSetBoxBuffer(
ctx->decoder,
ctx->exif->data +
ctx->exif_pos,
636 ctx->exif->size -
ctx->exif_pos) != JXL_DEC_SUCCESS) {
654 JxlThreadParallelRunnerDestroy(
ctx->runner);
657 JxlDecoderDestroy(
ctx->decoder);
679 .p.wrapper_name =
"libjxl",
683 .p.name =
"libjxl_anim",
695 .p.wrapper_name =
"libjxl",
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static const char *const format[]
const FFCodec ff_libjxl_decoder
const FFCodec ff_libjxl_anim_decoder
simple assert() macros that are a bit more flexible than ISO C assert().
Libavcodec external API header.
refcounted data buffer API
#define FF_CODEC_RECEIVE_FRAME_CB(func)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
common internal and external API header
Colorspace value utility functions for libavutil.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef **buf)
Similar to ff_frame_new_side_data, but using an existing buffer ref.
int ff_decode_exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd)
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
int(* init)(AVBSFContext *ctx)
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
EXIF metadata parser - internal functions.
reference-counted frame API
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
@ AV_CODEC_ID_JPEGXL_ANIM
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AVERROR_EOF
End of file.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm)
Detects which enum AVColorPrimaries constant corresponds to the given complete gamut description.
const AVColorPrimariesDesc * av_csp_primaries_desc_from_id(enum AVColorPrimaries prm)
Retrieves a complete gamut description from an enum constant describing the color primaries.
static AVRational av_make_q(int num, int den)
Create an AVRational.
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_PICTURE_TYPE_I
Intra.
#define AV_NOPTS_VALUE
Undefined timestamp value.
common internal api header.
size_t ff_libjxl_get_threadcount(int threads)
Transform threadcount in ffmpeg to one used by libjxl.
void ff_libjxl_init_memory_manager(JxlMemoryManager *manager)
Initialize and populate a JxlMemoryManager with av_malloc() and av_free() so libjxl will use these fu...
JPEG XL via libjxl common support header.
static int libjxl_finalize_frame(AVCodecContext *avctx, AVFrame *dst, AVFrame *src)
static int libjxl_attach_sidedata(AVCodecContext *avctx)
static av_cold int libjxl_decode_init(AVCodecContext *avctx)
static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, LibJxlDecodeContext *ctx)
static int libjxl_get_icc(AVCodecContext *avctx)
static av_cold int libjxl_decode_close(AVCodecContext *avctx)
static int libjxl_color_encoding_event(AVCodecContext *avctx, AVFrame *frame)
static int libjxl_receive_frame(AVCodecContext *avctx, AVFrame *frame)
static int libjxl_init_jxl_decoder(AVCodecContext *avctx)
static enum AVColorPrimaries libjxl_get_primaries(void *avctx, const JxlColorEncoding *jxl_color)
static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlColorEncoding *jxl_color)
#define MKTAG(a, b, c, d)
Memory handling functions.
#define AV_PIX_FMT_RGBF32
#define AV_PIX_FMT_RGBAF32
@ AVCOL_RANGE_JPEG
Full range content.
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
#define AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_GRAYF32
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
#define AV_PIX_FMT_GRAY16
AVColorPrimaries
Chromaticity coordinates of the source primaries.
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
@ AVCOL_PRI_BT2020
ITU-R BT2020.
AVColorTransferCharacteristic
Color Transfer Characteristic.
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
@ AVCOL_TRC_SMPTE428
SMPTE ST 428-1.
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
@ AVCOL_TRC_BT709
also ITU-R BT1361
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
static const uint8_t header[24]
A reference to a data buffer.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
enum AVColorSpace colorspace
YUV colorspace type.
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is represented.
struct AVCodecInternal * internal
Private context used for internal data.
AVPacket * in_pkt
This packet is used to hold the packet given to decoders implementing the .decode API; it is unused b...
Struct that contains both white point location and primaries location, providing the complete descrip...
AVWhitepointCoefficients wp
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
JxlBitDepth jxl_bit_depth
JxlPixelFormat jxl_pixfmt
static AVFormatContext * ctx