/* Copyright (c) the JPEG XL Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ /** @file decode.h * @brief Decoding API for JPEG XL. */ #ifndef JXL_DECODE_H_ #define JXL_DECODE_H_ #include #include #include "jxl/codestream_header.h" #include "jxl/color_encoding.h" #include "jxl/jxl_export.h" #include "jxl/memory_manager.h" #include "jxl/parallel_runner.h" #include "jxl/types.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif /** * Decoder library version. * * @return the decoder library version as an integer: * MAJOR_VERSION * 1000000 + MINOR_VERSION * 1000 + PATCH_VERSION. For example, * version 1.2.3 would return 1002003. */ JXL_EXPORT uint32_t JxlDecoderVersion(void); /** The result of JxlSignatureCheck. */ typedef enum { /** Not enough bytes were passed to determine if a valid signature was found. */ JXL_SIG_NOT_ENOUGH_BYTES = 0, /** No valid JPEGXL header was found. */ JXL_SIG_INVALID = 1, /** A valid JPEG XL codestream signature was found, that is a JPEG XL image * without container. */ JXL_SIG_CODESTREAM = 2, /** A valid container signature was found, that is a JPEG XL image embedded * in a box format container. */ JXL_SIG_CONTAINER = 3, } JxlSignature; /** * JPEG XL signature identification. * * Checks if the passed buffer contains a valid JPEG XL signature. The passed @p * buf of size * @p size doesn't need to be a full image, only the beginning of the file. * * @return a flag indicating if a JPEG XL signature was found and what type. * - JXL_SIG_NOT_ENOUGH_BYTES not enough bytes were passed to determine * if a valid signature is there. * - JXL_SIG_INVALID: no valid signature found for JPEG XL decoding. * - JXL_SIG_CODESTREAM a valid JPEG XL codestream signature was found. * - JXL_SIG_CONTAINER a valid JPEG XL container signature was found. */ JXL_EXPORT JxlSignature JxlSignatureCheck(const uint8_t* buf, size_t len); /** * Opaque structure that holds the JPEGXL decoder. * * Allocated and initialized with JxlDecoderCreate(). * Cleaned up and deallocated with JxlDecoderDestroy(). */ typedef struct JxlDecoderStruct JxlDecoder; /** * Creates an instance of JxlDecoder and initializes it. * * @p memory_manager will be used for all the library dynamic allocations made * from this instance. The parameter may be NULL, in which case the default * allocator will be used. See jpegxl/memory_manager.h for details. * * @param memory_manager custom allocator function. It may be NULL. The memory * manager will be copied internally. * @return @c NULL if the instance can not be allocated or initialized * @return pointer to initialized JxlDecoder otherwise */ JXL_EXPORT JxlDecoder* JxlDecoderCreate(const JxlMemoryManager* memory_manager); /** * Re-initializes a JxlDecoder instance, so it can be re-used for decoding * another image. All state and settings are reset as if the object was * newly created with JxlDecoderCreate, but the memory manager is kept. * * @param dec instance to be re-initialized. */ JXL_EXPORT void JxlDecoderReset(JxlDecoder* dec); /** * Deinitializes and frees JxlDecoder instance. * * @param dec instance to be cleaned up and deallocated. */ JXL_EXPORT void JxlDecoderDestroy(JxlDecoder* dec); /** * Return value for JxlDecoderProcessInput. * The values above 0x40 are optional informal events that can be subscribed to, * they are never returned if they have not been registered with * JxlDecoderSubscribeEvents. */ typedef enum { /** Function call finished successfully, or decoding is finished and there is * nothing more to be done. */ JXL_DEC_SUCCESS = 0, /** An error occurred, for example invalid input file or out of memory. * TODO(lode): add function to get error information from decoder. */ JXL_DEC_ERROR = 1, /** The decoder needs more input bytes to continue. Before the next * JxlDecoderProcessInput call, more input data must be set, by calling * JxlDecoderReleaseInput (if input was set previously) and then calling * JxlDecoderSetInput. JxlDecoderReleaseInput returns how many bytes are * not yet processed, before a next call to JxlDecoderProcessInput all * unprocessed bytes must be provided again (the address need not match, but * the contents must), and more bytes must be concatenated after the * unprocessed bytes. */ JXL_DEC_NEED_MORE_INPUT = 2, /** The decoder is able to decode a preview image and requests setting a * preview output buffer using JxlDecoderSetPreviewOutBuffer. This occurs if * JXL_DEC_PREVIEW_IMAGE is requested and it is possible to decode a preview * image from the codestream and the preview out buffer was not yet set. There * is maximum one preview image in a codestream. */ JXL_DEC_NEED_PREVIEW_OUT_BUFFER = 3, /** The decoder is able to decode a DC image and requests setting a DC output * buffer using JxlDecoderSetDCOutBuffer. This occurs if JXL_DEC_DC_IMAGE is * requested and it is possible to decode a DC image from the codestream and * the DC out buffer was not yet set. This event re-occurs for new frames * if there are multiple animation frames. * DEPRECATED: the DC feature in this form will be removed. You can use * JxlDecoderFlushImage for progressive rendering. */ JXL_DEC_NEED_DC_OUT_BUFFER = 4, /** The decoder requests an output buffer to store the full resolution image, * which can be set with JxlDecoderSetImageOutBuffer or with * JxlDecoderSetImageOutCallback. This event re-occurs for new frames if there * are multiple animation frames and requires setting an output again. */ JXL_DEC_NEED_IMAGE_OUT_BUFFER = 5, /** Informative event by JxlDecoderProcessInput: JPEG reconstruction buffer is * too small for reconstructed JPEG codestream to fit. * JxlDecoderSetJPEGBuffer must be called again to make room for remaining * bytes. This event may occur multiple times after * JXL_DEC_JPEG_RECONSTRUCTION */ JXL_DEC_JPEG_NEED_MORE_OUTPUT = 6, /** Informative event by JxlDecoderProcessInput: basic information such as * image dimensions and extra channels. This event occurs max once per image. */ JXL_DEC_BASIC_INFO = 0x40, /** Informative event by JxlDecoderProcessInput: user extensions of the * codestream header. This event occurs max once per image and always later * than JXL_DEC_BASIC_INFO and earlier than any pixel data. */ JXL_DEC_EXTENSIONS = 0x80, /** Informative event by JxlDecoderProcessInput: color encoding or ICC * profile from the codestream header. This event occurs max once per image * and always later than JXL_DEC_BASIC_INFO and earlier than any pixel * data. */ JXL_DEC_COLOR_ENCODING = 0x100, /** Informative event by JxlDecoderProcessInput: Preview image, a small * frame, decoded. This event can only happen if the image has a preview * frame encoded. This event occurs max once for the codestream and always * later than JXL_DEC_COLOR_ENCODING and before JXL_DEC_FRAME. */ JXL_DEC_PREVIEW_IMAGE = 0x200, /** Informative event by JxlDecoderProcessInput: Beginning of a frame. * JxlDecoderGetFrameHeader can be used at this point. A note on frames: * a JPEG XL image can have internal frames that are not intended to be * displayed (e.g. used for compositing a final frame), but this only returns * displayed frames. A displayed frame either has an animation duration or is * the only or last frame in the image. This event occurs max once per * displayed frame, always later than JXL_DEC_COLOR_ENCODING, and always * earlier than any pixel data. While JPEG XL supports encoding a single frame * as the composition of multiple internal sub-frames also called frames, this * event is not indicated for the internal frames. */ JXL_DEC_FRAME = 0x400, /** Informative event by JxlDecoderProcessInput: DC image, 8x8 sub-sampled * frame, decoded. It is not guaranteed that the decoder will always return DC * separately, but when it does it will do so before outputting the full * frame. JxlDecoderSetDCOutBuffer must be used after getting the basic * image information to be able to get the DC pixels, if not this return * status only indicates we're past this point in the codestream. This event * occurs max once per frame and always later than JXL_DEC_FRAME_HEADER * and other header events and earlier than full resolution pixel data. * DEPRECATED: the DC feature in this form will be removed. You can use * JxlDecoderFlushImage for progressive rendering. */ JXL_DEC_DC_IMAGE = 0x800, /** Informative event by JxlDecoderProcessInput: full frame decoded. * JxlDecoderSetImageOutBuffer must be used after getting the basic image * information to be able to get the image pixels, if not this return status * only indicates we're past this point in the codestream. This event occurs * max once per frame and always later than JXL_DEC_DC_IMAGE. */ JXL_DEC_FULL_IMAGE = 0x1000, /** Informative event by JxlDecoderProcessInput: JPEG reconstruction data * decoded. JxlDecoderSetJPEGBuffer may be used to set a JPEG * reconstruction buffer after getting the JPEG reconstruction data. If a JPEG * reconstruction buffer is set a byte stream identical to the JPEG codestream * used to encode the image will be written to the JPEG reconstruction buffer * instead of pixels to the image out buffer. This event occurs max once per * image and always before JXL_DEC_FULL_IMAGE. */ JXL_DEC_JPEG_RECONSTRUCTION = 0x2000, } JxlDecoderStatus; /** Rewinds decoder to the beginning. The same input must be given again from * the beginning of the file and the decoder will emit events from the beginning * again. When rewinding (as opposed to JxlDecoderReset), the decoder can keep * state about the image, which it can use to skip to a requested frame more * efficiently with JxlDecoderSkipFrames. After rewind, * JxlDecoderSubscribeEvents can be used again, and it is feasible to leave out * events that were already handled before, such as JXL_DEC_BASIC_INFO and * JXL_DEC_COLOR_ENCODING, since they will provide the same information as * before. * @param dec decoder object */ JXL_EXPORT void JxlDecoderRewind(JxlDecoder* dec); /** Makes the decoder skip the next `amount` frames. It still needs to process * the input, but will not output the frame events. It can be more efficient * when skipping frames, and even more so when using this after * JxlDecoderRewind. If the decoder is already processing a frame (could * have emitted JXL_DEC_FRAME but not yet JXL_DEC_FULL_IMAGE), it starts * skipping from the next frame. If the amount is larger than the amount of * frames remaining in the image, all remaining frames are skipped. Calling this * function multiple times adds the amount to skip to the already existing * amount. * A frame here is defined as a frame that without skipping emits events such as * JXL_DEC_FRAME and JXL_FULL_IMAGE, frames that are internal to the file format * but are not rendered as part of an animation, or are not the final still * frame of a still image, are not counted. * @param dec decoder object * @param amount the amount of frames to skip */ JXL_EXPORT void JxlDecoderSkipFrames(JxlDecoder* dec, size_t amount); /** * Get the default pixel format for this decoder. * * Requires that the decoder can produce JxlBasicInfo. * * @param dec JxlDecoder to query when creating the recommended pixel format. * @param format JxlPixelFormat to populate with the recommended settings for * the data loaded into this decoder. * @return JXL_DEC_SUCCESS if no error, JXL_DEC_NEED_MORE_INPUT if the * basic info isn't yet available, and JXL_DEC_ERROR otherwise. */ JXL_EXPORT JxlDecoderStatus JxlDecoderDefaultPixelFormat(const JxlDecoder* dec, JxlPixelFormat* format); /** * Set the parallel runner for multithreading. May only be set before starting * decoding. * * @param dec decoder object * @param parallel_runner function pointer to runner for multithreading. It may * be NULL to use the default, single-threaded, runner. A multithreaded * runner should be set to reach fast performance. * @param parallel_runner_opaque opaque pointer for parallel_runner. * @return JXL_DEC_SUCCESS if the runner was set, JXL_DEC_ERROR * otherwise (the previous runner remains set). */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetParallelRunner(JxlDecoder* dec, JxlParallelRunner parallel_runner, void* parallel_runner_opaque); /** * Returns a hint indicating how many more bytes the decoder is expected to * need to make JxlDecoderGetBasicInfo available after the next * JxlDecoderProcessInput call. This is a suggested large enough value for * the amount of bytes to provide in the next JxlDecoderSetInput call, but it is * not guaranteed to be an upper bound nor a lower bound. * Can be used before the first JxlDecoderProcessInput call, and is correct * the first time in most cases. If not, JxlDecoderSizeHintBasicInfo can be * called again to get an updated hint. * * @param dec decoder object * @return the size hint in bytes if the basic info is not yet fully decoded. * @return 0 when the basic info is already available. */ JXL_EXPORT size_t JxlDecoderSizeHintBasicInfo(const JxlDecoder* dec); /** Select for which informative events (JXL_DEC_BASIC_INFO, etc...) the * decoder should return with a status. It is not required to subscribe to any * events, data can still be requested from the decoder as soon as it available. * By default, the decoder is subscribed to no events (events_wanted == 0), and * the decoder will then only return when it cannot continue because it needs * more input data or more output buffer. This function may only be be called * before using JxlDecoderProcessInput * * @param dec decoder object * @param events_wanted bitfield of desired events. * @return JXL_DEC_SUCCESS if no error, JXL_DEC_ERROR otherwise. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSubscribeEvents(JxlDecoder* dec, int events_wanted); /** Enables or disables preserving of original orientation. Some images are * encoded with an orientation tag indicating the image is rotated and/or * mirrored (here called the original orientation). * * *) If keep_orientation is JXL_FALSE (the default): the decoder will perform * work to undo the transformation. This ensures the decoded pixels will not * be rotated or mirrored. The decoder will always set the orientation field * of the JxlBasicInfo to JXL_ORIENT_IDENTITY to match the returned pixel data. * The decoder may also swap xsize and ysize in the JxlBasicInfo compared to the * values inside of the codestream, to correctly match the decoded pixel data, * e.g. when a 90 degree rotation was performed. * * *) If this option is JXL_TRUE: then the image is returned as-is, which may be * rotated or mirrored, and the user must check the orientation field in * JxlBasicInfo after decoding to correctly interpret the decoded pixel data. * This may be faster to decode since the decoder doesn't have to apply the * transformation, but can cause wrong display of the image if the orientation * tag is not correctly taken into account by the user. * * By default, this option is disabled, and the decoder automatically corrects * the orientation. * * This function must be called at the beginning, before decoding is performed. * * @see JxlBasicInfo for the orientation field, and @see JxlOrientation for the * possible values. * * @param dec decoder object * @param keep_orientation JXL_TRUE to enable, JXL_FALSE to disable. * @return JXL_DEC_SUCCESS if no error, JXL_DEC_ERROR otherwise. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetKeepOrientation(JxlDecoder* dec, JXL_BOOL keep_orientation); /** * Decodes JPEG XL file using the available bytes. Requires input has been * set with JxlDecoderSetInput. After JxlDecoderProcessInput, input can * optionally be released with JxlDecoderReleaseInput and then set again to * next bytes in the stream. JxlDecoderReleaseInput returns how many bytes are * not yet processed, before a next call to JxlDecoderProcessInput all * unprocessed bytes must be provided again (the address need not match, but the * contents must), and more bytes may be concatenated after the unprocessed * bytes. * * The returned status indicates whether the decoder needs more input bytes, or * more output buffer for a certain type of output data. No matter what the * returned status is (other than JXL_DEC_ERROR), new information, such as * JxlDecoderGetBasicInfo, may have become available after this call. When * the return value is not JXL_DEC_ERROR or JXL_DEC_SUCCESS, the decoding * requires more JxlDecoderProcessInput calls to continue. * * @param dec decoder object * @return JXL_DEC_SUCCESS when decoding finished and all events handled. * @return JXL_DEC_ERROR when decoding failed, e.g. invalid codestream. * TODO(lode) document the input data mechanism * @return JXL_DEC_NEED_MORE_INPUT more input data is necessary. * @return JXL_DEC_BASIC_INFO when basic info such as image dimensions is * available and this informative event is subscribed to. * @return JXL_DEC_EXTENSIONS when JPEG XL codestream user extensions are * available and this informative event is subscribed to. * @return JXL_DEC_COLOR_ENCODING when color profile information is * available and this informative event is subscribed to. * @return JXL_DEC_PREVIEW_IMAGE when preview pixel information is available and * output in the preview buffer. * @return JXL_DEC_DC_IMAGE when DC pixel information (8x8 downscaled version * of the image) is available and output in the DC buffer. * @return JXL_DEC_FULL_IMAGE when all pixel information at highest detail is * available and has been output in the pixel buffer. */ JXL_EXPORT JxlDecoderStatus JxlDecoderProcessInput(JxlDecoder* dec); /** * Sets input data for JxlDecoderProcessInput. The data is owned by the caller * and may be used by the decoder until JxlDecoderReleaseInput is called or * the decoder is destroyed or reset so must be kept alive until then. * @param dec decoder object * @param data pointer to next bytes to read from * @param size amount of bytes available starting from data * @return JXL_DEC_ERROR if input was already set without releasing, * JXL_DEC_SUCCESS otherwise */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetInput(JxlDecoder* dec, const uint8_t* data, size_t size); /** * Releases input which was provided with JxlDecoderSetInput. Between * JxlDecoderProcessInput and JxlDecoderReleaseInput, the user may not alter * the data in the buffer. Calling JxlDecoderReleaseInput is required whenever * any input is already set and new input needs to be added with * JxlDecoderSetInput, but is not required before JxlDecoderDestroy or * JxlDecoderReset. Calling JxlDecoderReleaseInput when no input is set is * not an error and returns 0. * @param dec decoder object * @return the amount of bytes the decoder has not yet processed that are * still remaining in the data set by JxlDecoderSetInput, or 0 if no input is * set or JxlDecoderReleaseInput was already called. For a next call to * JxlDecoderProcessInput, the buffer must start with these unprocessed bytes. * This value doesn't provide information about how many bytes the decoder * truly processed internally or how large the original JPEG XL codestream or * file are. */ JXL_EXPORT size_t JxlDecoderReleaseInput(JxlDecoder* dec); /** * Outputs the basic image information, such as image dimensions, bit depth and * all other JxlBasicInfo fields, if available. * * @param dec decoder object * @param info struct to copy the information into, or NULL to only check * whether the information is available through the return value. * @return JXL_DEC_SUCCESS if the value is available, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * of other error conditions. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetBasicInfo(const JxlDecoder* dec, JxlBasicInfo* info); /** * Outputs information for extra channel at the given index. The index must be * smaller than num_extra_channels in the associated JxlBasicInfo. * * @param dec decoder object * @param index index of the extra channel to query. * @param info struct to copy the information into, or NULL to only check * whether the information is available through the return value. * @return JXL_DEC_SUCCESS if the value is available, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * of other error conditions. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetExtraChannelInfo( const JxlDecoder* dec, size_t index, JxlExtraChannelInfo* info); /** * Outputs name for extra channel at the given index in UTF-8. The index must be * smaller than num_extra_channels in the associated JxlBasicInfo. The buffer * for name must have at least name_length + 1 bytes allocated, gotten from * the associated JxlExtraChannelInfo. * * @param dec decoder object * @param index index of the extra channel to query. * @param name buffer to copy the name into * @param size size of the name buffer in bytes * @return JXL_DEC_SUCCESS if the value is available, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * of other error conditions. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetExtraChannelName(const JxlDecoder* dec, size_t index, char* name, size_t size); /** Defines which color profile to get: the profile from the codestream * metadata header, which represents the color profile of the original image, * or the color profile from the pixel data received by the decoder. Both are * the same if the basic has uses_original_profile set. */ typedef enum { /** Get the color profile of the original image from the metadata.. */ JXL_COLOR_PROFILE_TARGET_ORIGINAL = 0, /** Get the color profile of the pixel data the decoder outputs. */ JXL_COLOR_PROFILE_TARGET_DATA = 1, } JxlColorProfileTarget; /** * Outputs the color profile as JPEG XL encoded structured data, if available. * This is an alternative to an ICC Profile, which can represent a more limited * amount of color spaces, but represents them exactly through enum values. * * It is often possible to use JxlDecoderGetColorAsICCProfile as an * alternative anyway. The following scenarios are possible: * - The JPEG XL image has an attached ICC Profile, in that case, the encoded * structured data is not available, this function will return an error status * and you must use JxlDecoderGetColorAsICCProfile instead. * - The JPEG XL image has an encoded structured color profile, and it * represents an RGB or grayscale color space. This function will return it. * You can still use JxlDecoderGetColorAsICCProfile as well as an * alternative if desired, though depending on which RGB color space is * represented, the ICC profile may be a close approximation. It is also not * always feasible to deduce from an ICC profile which named color space it * exactly represents, if any, as it can represent any arbitrary space. * - The JPEG XL image has an encoded structured color profile, and it indicates * an unknown or xyb color space. In that case, * JxlDecoderGetColorAsICCProfile is not available. * * If you wish to render the image using a system that supports ICC profiles, * use JxlDecoderGetColorAsICCProfile first. If you're looking for a specific * color space possibly indicated in the JPEG XL image, use * JxlDecoderGetColorAsEncodedProfile first. * * @param dec decoder object * @param format pixel format to output the data to. Only used for * JXL_COLOR_PROFILE_TARGET_DATA, may be nullptr otherwise. * @param target whether to get the original color profile from the metadata * or the color profile of the decoded pixels. * @param color_encoding struct to copy the information into, or NULL to only * check whether the information is available through the return value. * @return JXL_DEC_SUCCESS if the data is available and returned, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * the encoded structured color profile does not exist in the codestream. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetColorAsEncodedProfile( const JxlDecoder* dec, const JxlPixelFormat* format, JxlColorProfileTarget target, JxlColorEncoding* color_encoding); /** * Outputs the size in bytes of the ICC profile returned by * JxlDecoderGetColorAsICCProfile, if available, or indicates there is none * available. In most cases, the image will have an ICC profile available, but * if it does not, JxlDecoderGetColorAsEncodedProfile must be used instead. * @see JxlDecoderGetColorAsEncodedProfile for more information. The ICC * profile is either the exact ICC profile attached to the codestream metadata, * or a close approximation generated from JPEG XL encoded structured data, * depending of what is encoded in the codestream. * * @param dec decoder object * @param format pixel format to output the data to. Only used for * JXL_COLOR_PROFILE_TARGET_DATA, may be nullptr otherwise. * @param target whether to get the original color profile from the metadata * or the color profile of the decoded pixels. * @param size variable to output the size into, or NULL to only check the * return status. * @return JXL_DEC_SUCCESS if the ICC profile is available, * JXL_DEC_NEED_MORE_INPUT if the decoder has not yet received enough * input data to determine whether an ICC profile is available or what its * size is, JXL_DEC_ERROR in case the ICC profile is not available and * cannot be generated. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetICCProfileSize(const JxlDecoder* dec, const JxlPixelFormat* format, JxlColorProfileTarget target, size_t* size); /** * Outputs ICC profile if available. The profile is only available if * JxlDecoderGetICCProfileSize returns success. The output buffer must have * at least as many bytes as given by JxlDecoderGetICCProfileSize. * * @param dec decoder object * @param format pixel format to output the data to. Only used for * JXL_COLOR_PROFILE_TARGET_DATA, may be nullptr otherwise. * @param target whether to get the original color profile from the metadata * or the color profile of the decoded pixels. * @param icc_profile buffer to copy the ICC profile into * @param size size of the icc_profile buffer in bytes * @return JXL_DEC_SUCCESS if the profile was successfully returned is * available, JXL_DEC_NEED_MORE_INPUT if not yet available, * JXL_DEC_ERROR if the profile doesn't exist or the output size is not * large enough. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetColorAsICCProfile( const JxlDecoder* dec, const JxlPixelFormat* format, JxlColorProfileTarget target, uint8_t* icc_profile, size_t size); /** Sets the color profile to use for JXL_COLOR_PROFILE_TARGET_DATA for the * special case when the decoder has a choice. This only has effect for a JXL * image where uses_original_profile is false, and the original color profile is * encoded as an ICC color profile rather than a JxlColorEncoding with known * enum values. In most other cases (uses uses_original_profile is true, or the * color profile is already given as a JxlColorEncoding), this setting is * ignored and the decoder uses a profile related to the image. * No matter what, the JXL_COLOR_PROFILE_TARGET_DATA must still be queried to * know the actual data format of the decoded pixels after decoding. * * The intended use case of this function is for cases where you are using * a color management system to parse the original ICC color profile * (JXL_COLOR_PROFILE_TARGET_ORIGINAL), from this you know that the ICC * profile represents one of the color profiles supported by JxlColorEncoding * (such as sRGB, PQ or HLG): in that case it is beneficial (but not necessary) * to use JxlDecoderSetPreferredColorProfile to match the parsed profile. The * JXL decoder has no color management system built in, but can convert XYB * color to any of the ones supported by JxlColorEncoding. * * Can only be set after the JXL_DEC_COLOR_ENCODING event occurred and before * any other event occurred, and can affect the result of * JXL_COLOR_PROFILE_TARGET_DATA (but not of JXL_COLOR_PROFILE_TARGET_ORIGINAL), * so should be used after getting JXL_COLOR_PROFILE_TARGET_ORIGINAL but before * getting JXL_COLOR_PROFILE_TARGET_DATA. The color_encoding must be grayscale * if num_color_channels from the basic info is 1, RGB if num_color_channels * from the basic info is 3. * * If JxlDecoderSetPreferredColorProfile is not used, then for images for which * uses_original_profile is false and with ICC color profile, the decoder will * choose linear sRGB for color images, linear grayscale for grayscale images. * This function only sets a preference, since for other images the decoder has * no choice what color profile to use, it is determined by the image. * * @param dec decoder object * @param color_encoding the default color encoding to set * @return JXL_DEC_SUCCESS if the preference was set successfully, JXL_DEC_ERROR * otherwise. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetPreferredColorProfile( JxlDecoder* dec, const JxlColorEncoding* color_encoding); /** * Returns the minimum size in bytes of the preview image output pixel buffer * for the given format. This is the buffer for JxlDecoderSetPreviewOutBuffer. * Requires the preview header information is available in the decoder. * * @param dec decoder object * @param format format of pixels * @param size output value, buffer size in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * information not available yet. */ JXL_EXPORT JxlDecoderStatus JxlDecoderPreviewOutBufferSize( const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size); /** * Sets the buffer to write the small resolution preview image * to. The size of the buffer must be at least as large as given by * JxlDecoderPreviewOutBufferSize. The buffer follows the format described by * JxlPixelFormat. The preview image dimensions are given by the * JxlPreviewHeader. The buffer is owned by the caller. * * @param dec decoder object * @param format format of pixels. Object owned by user and its contents are * copied internally. * @param buffer buffer type to output the pixel data to * @param size size of buffer in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * size too small. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetPreviewOutBuffer( JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size); /** * Outputs the information from the frame, such as duration when have_animation. * This function can be called when JXL_DEC_FRAME occurred for the current * frame, even when have_animation in the JxlBasicInfo is JXL_FALSE. * * @param dec decoder object * @param header struct to copy the information into, or NULL to only check * whether the information is available through the return value. * @return JXL_DEC_SUCCESS if the value is available, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * of other error conditions. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetFrameHeader(const JxlDecoder* dec, JxlFrameHeader* header); /** * Outputs name for the current frame. The buffer * for name must have at least name_length + 1 bytes allocated, gotten from * the associated JxlFrameHeader. * * @param dec decoder object * @param name buffer to copy the name into * @param size size of the name buffer in bytes, including zero termination * character, so this must be at least JxlFrameHeader.name_length + 1. * @return JXL_DEC_SUCCESS if the value is available, * JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case * of other error conditions. */ JXL_EXPORT JxlDecoderStatus JxlDecoderGetFrameName(const JxlDecoder* dec, char* name, size_t size); /** * Returns the minimum size in bytes of the DC image output buffer * for the given format. This is the buffer for JxlDecoderSetDCOutBuffer. * Requires the basic image information is available in the decoder. * * @param dec decoder object * @param format format of pixels * @param size output value, buffer size in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * information not available yet. * * DEPRECATED: the DC feature in this form will be removed. You can use * JxlDecoderFlushImage for progressive rendering. */ JXL_EXPORT JXL_DEPRECATED JxlDecoderStatus JxlDecoderDCOutBufferSize( const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size); /** * Sets the buffer to write the lower resolution (8x8 sub-sampled) DC image * to. The size of the buffer must be at least as large as given by * JxlDecoderDCOutBufferSize. The buffer follows the format described by * JxlPixelFormat. The DC image has dimensions ceil(xsize / 8) * ceil(ysize / * 8). The buffer is owned by the caller. * * @param dec decoder object * @param format format of pixels. Object owned by user and its contents are * copied internally. * @param buffer buffer type to output the pixel data to * @param size size of buffer in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * size too small. * * DEPRECATED: the DC feature in this form will be removed. You can use * JxlDecoderFlushImage for progressive rendering. */ JXL_EXPORT JXL_DEPRECATED JxlDecoderStatus JxlDecoderSetDCOutBuffer( JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size); /** * Returns the minimum size in bytes of the image output pixel buffer for the * given format. This is the buffer for JxlDecoderSetImageOutBuffer. Requires * the basic image information is available in the decoder. * * @param dec decoder object * @param format format of the pixels. * @param size output value, buffer size in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * information not available yet. */ JXL_EXPORT JxlDecoderStatus JxlDecoderImageOutBufferSize( const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size); /** * Sets the buffer to write the full resolution image to. This can be set when * the JXL_DEC_FRAME event occurs, must be set when the * JXL_DEC_NEED_IMAGE_OUT_BUFFER event occurs, and applies only for the current * frame. The size of the buffer must be at least as large as given by * JxlDecoderImageOutBufferSize. The buffer follows the format described by * JxlPixelFormat. The buffer is owned by the caller. * * @param dec decoder object * @param format format of the pixels. Object owned by user and its contents * are copied internally. * @param buffer buffer type to output the pixel data to * @param size size of buffer in bytes * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * size too small. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetImageOutBuffer( JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size); /** * Callback function type for JxlDecoderSetImageOutCallback. @see * JxlDecoderSetImageOutCallback for usage. * * The callback may be called simultaneously by different threads when using a * threaded parallel runner, on different pixels. * * @param opaque optional user data, as given to JxlDecoderSetImageOutCallback. * @param x horizontal position of leftmost pixel of the pixel data. * @param y vertical position of the pixel data. * @param num_pixels amount of pixels included in the pixel data, horizontally. * This is not the same as xsize of the full image, it may be smaller. * @param pixels pixel data as a horizontal stripe, in the format passed to * JxlDecoderSetImageOutCallback. The memory is not owned by the user, and is * only valid during the time the callback is running. */ typedef void (*JxlImageOutCallback)(void* opaque, size_t x, size_t y, size_t num_pixels, const void* pixels); /** * Sets pixel output callback. This is an alternative to * JxlDecoderSetImageOutBuffer. This can be set when the JXL_DEC_FRAME event * occurs, must be set when the JXL_DEC_NEED_IMAGE_OUT_BUFFER event occurs, and * applies only for the current frame. Only one of JxlDecoderSetImageOutBuffer * or JxlDecoderSetImageOutCallback may be used for the same frame, not both at * the same time. * * The callback will be called multiple times, to receive the image * data in small chunks. The callback receives a horizontal stripe of pixel * data, 1 pixel high, xsize pixels wide, called a scanline. The xsize here is * not the same as the full image width, the scanline may be a partial section, * and xsize may differ between calls. The user can then process and/or copy the * partial scanline to an image buffer. The callback may be called * simultaneously by different threads when using a threaded parallel runner, on * different pixels. * * If JxlDecoderFlushImage is not used, then each pixel will be visited exactly * once by the different callback calls, during processing with one or more * JxlDecoderProcessInput calls. These pixels are decoded to full detail, they * are not part of a lower resolution or lower quality progressive pass, but the * final pass. * * If JxlDecoderFlushImage is used, then in addition each pixel will be visited * zero or one times during the blocking JxlDecoderFlushImage call. Pixels * visited as a result of JxlDecoderFlushImage may represent a lower resolution * or lower quality intermediate progressive pass of the image. Any visited * pixel will be of a quality at least as good or better than previous visits of * this pixel. A pixel may be visited zero times if it cannot be decoded yet * or if it was already decoded to full precision (this behavior is not * guaranteed). * * @param dec decoder object * @param format format of the pixels. Object owned by user and its contents * are copied internally. * @param callback the callback function receiving partial scanlines of pixel * data. * @param opaque optional user data, which will be passed on to the callback, * may be NULL. * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * JxlDecoderSetImageOutBuffer already set. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetImageOutCallback(JxlDecoder* dec, const JxlPixelFormat* format, JxlImageOutCallback callback, void* opaque); /** * Returns the minimum size in bytes of an extra channel pixel buffer for the * given format. This is the buffer for JxlDecoderSetExtraChannelBuffer. * Requires the basic image information is available in the decoder. * * @param dec decoder object * @param format format of the pixels. The num_channels value is ignored and is * always treated to be 1. * @param size output value, buffer size in bytes * @param index which extra channel to get, matching the index used in @see * JxlDecoderGetExtraChannelInfo. Must be smaller than num_extra_channels in the * associated JxlBasicInfo. * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * information not available yet or invalid index. */ JXL_EXPORT JxlDecoderStatus JxlDecoderExtraChannelBufferSize( const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size, uint32_t index); /** * Sets the buffer to write an extra channel to. This can be set when * the JXL_DEC_FRAME or JXL_DEC_NEED_IMAGE_OUT_BUFFER event occurs, and applies * only for the current frame. The size of the buffer must be at least as large * as given by JxlDecoderExtraChannelBufferSize. The buffer follows the format * described by JxlPixelFormat, but where num_channels is 1. The buffer is owned * by the caller. The amount of extra channels is given by the * num_extra_channels field in the associated JxlBasicInfo, and the information * of individual extra channels can be queried with @see * JxlDecoderGetExtraChannelInfo. To get multiple extra channels, this function * must be called multiple times, once for each wanted index. Not all images * have extra channels. The alpha channel is an extra channel and can be gotten * as part of the color channels when using an RGBA pixel buffer with * JxlDecoderSetImageOutBuffer, but additionally also can be gotten separately * as extra channel. The color channels themselves cannot be gotten this way. * * * @param dec decoder object * @param format format of the pixels. Object owned by user and its contents * are copied internally. The num_channels value is ignored and is always * treated to be 1. * @param buffer buffer type to output the pixel data to * @param size size of buffer in bytes * @param index which extra channel to get, matching the index used in @see * JxlDecoderGetExtraChannelInfo. Must be smaller than num_extra_channels in the * associated JxlBasicInfo. * @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as * size too small or invalid index. */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetExtraChannelBuffer(JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size, uint32_t index); /** * Sets output buffer for reconstructed JPEG codestream. * * The data is owned by the caller * and may be used by the decoder until JxlDecoderReleaseJPEGBuffer is called or * the decoder is destroyed or reset so must be kept alive until then. * * @param dec decoder object * @param data pointer to next bytes to write to * @param size amount of bytes available starting from data * @return JXL_DEC_ERROR if input was already set without releasing, * JXL_DEC_SUCCESS otherwise */ JXL_EXPORT JxlDecoderStatus JxlDecoderSetJPEGBuffer(JxlDecoder* dec, uint8_t* data, size_t size); /** * Releases buffer which was provided with JxlDecoderSetJPEGBuffer. * * Calling JxlDecoderReleaseJPEGBuffer is required whenever * a buffer is already set and a new buffer needs to be added with * JxlDecoderSetJPEGBuffer, but is not required before JxlDecoderDestroy or * JxlDecoderReset. * * Calling JxlDecoderReleaseJPEGBuffer when no input is set is * not an error and returns 0. * * @param dec decoder object * @return the amount of bytes the decoder has not yet written to of the data * set by JxlDecoderSetJPEGBuffer, or 0 if no buffer is set or * JxlDecoderReleaseJPEGBuffer was already called. */ JXL_EXPORT size_t JxlDecoderReleaseJPEGBuffer(JxlDecoder* dec); /** * Outputs progressive step towards the decoded image so far when only partial * input was received. If the flush was successful, the buffer set with * JxlDecoderSetImageOutBuffer will contain partial image data. * * Can be called when JxlDecoderProcessInput returns JXL_DEC_NEED_MORE_INPUT, * after the JXL_DEC_FRAME event already occurred and before the * JXL_DEC_FULL_IMAGE event occurred for a frame. * * @param dec decoder object * @return JXL_DEC_SUCCESS if image data was flushed to the output buffer, or * JXL_DEC_ERROR when no flush was done, e.g. if not enough image data was * available yet even for flush, or no output buffer was set yet. An error is * not fatal, it only indicates no flushed image is available now, regular, * decoding can still be performed. */ JXL_EXPORT JxlDecoderStatus JxlDecoderFlushImage(JxlDecoder* dec); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif /* JXL_DECODE_H_ */