/* 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. */ /** @addtogroup libjxl_encoder * @{ * @file encode.h * @brief Encoding API for JPEG XL. */ #ifndef JXL_ENCODE_H_ #define JXL_ENCODE_H_ #include #include #include #include #include #include #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif /** * Encoder library version. * * @return the encoder 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 JxlEncoderVersion(void); /** * Opaque structure that holds the JPEG XL encoder. * * Allocated and initialized with JxlEncoderCreate(). * Cleaned up and deallocated with JxlEncoderDestroy(). */ typedef struct JxlEncoderStruct JxlEncoder; /** * Settings and metadata for a single image frame. This includes encoder options * for a frame such as compression quality and speed. * * Allocated and initialized with JxlEncoderFrameSettingsCreate(). * Cleaned up and deallocated when the encoder is destroyed with * JxlEncoderDestroy(). */ typedef struct JxlEncoderFrameSettingsStruct JxlEncoderFrameSettings; /** DEPRECATED: Use JxlEncoderFrameSettings instead. */ typedef JxlEncoderFrameSettings JxlEncoderOptions; /** * Return value for multiple encoder functions. */ typedef enum { /** Function call finished successfully, or encoding is finished and there is * nothing more to be done. */ JXL_ENC_SUCCESS = 0, /** An error occurred, for example out of memory. */ JXL_ENC_ERROR = 1, /** The encoder needs more output buffer to continue encoding. */ JXL_ENC_NEED_MORE_OUTPUT = 2, /** DEPRECATED: the encoder does not return this status and there is no need * to handle or expect it. * Instead, JXL_ENC_ERROR is returned with error condition * JXL_ENC_ERR_NOT_SUPPORTED. */ JXL_ENC_NOT_SUPPORTED = 3, } JxlEncoderStatus; /** * Error conditions: * API usage errors have the 0x80 bit set to 1 * Other errors have the 0x80 bit set to 0 */ typedef enum { /** No error */ JXL_ENC_ERR_OK = 0, /** Generic encoder error due to unspecified cause */ JXL_ENC_ERR_GENERIC = 1, /** Out of memory * TODO(jon): actually catch this and return this error */ JXL_ENC_ERR_OOM = 2, /** JPEG bitstream reconstruction data could not be * represented (e.g. too much tail data) */ JXL_ENC_ERR_JBRD = 3, /** Input is invalid (e.g. corrupt JPEG file or ICC profile) */ JXL_ENC_ERR_BAD_INPUT = 4, /** The encoder doesn't (yet) support this. Either no version of libjxl * supports this, and the API is used incorrectly, or the libjxl version * should have been checked before trying to do this. */ JXL_ENC_ERR_NOT_SUPPORTED = 0x80, /** The encoder API is used in an incorrect way. * In this case, a debug build of libjxl should output a specific error * message. (if not, please open an issue about it) */ JXL_ENC_ERR_API_USAGE = 0x81, } JxlEncoderError; /** * Id of encoder options for a frame. This includes options such as setting * encoding effort/speed or overriding the use of certain coding tools, for this * frame. This does not include non-frame related encoder options such as for * boxes. */ typedef enum { /** Sets encoder effort/speed level without affecting decoding speed. Valid * values are, from faster to slower speed: 1:lightning 2:thunder 3:falcon * 4:cheetah 5:hare 6:wombat 7:squirrel 8:kitten 9:tortoise. * Default: squirrel (7). */ JXL_ENC_FRAME_SETTING_EFFORT = 0, /** Sets the decoding speed tier for the provided options. Minimum is 0 * (slowest to decode, best quality/density), and maximum is 4 (fastest to * decode, at the cost of some quality/density). Default is 0. */ JXL_ENC_FRAME_SETTING_DECODING_SPEED = 1, /** Sets resampling option. If enabled, the image is downsampled before * compression, and upsampled to original size in the decoder. Integer option, * use -1 for the default behavior (resampling only applied for low quality), * 1 for no downsampling (1x1), 2 for 2x2 downsampling, 4 for 4x4 * downsampling, 8 for 8x8 downsampling. */ JXL_ENC_FRAME_SETTING_RESAMPLING = 2, /** Similar to JXL_ENC_FRAME_SETTING_RESAMPLING, but for extra channels. * Integer option, use -1 for the default behavior (depends on encoder * implementation), 1 for no downsampling (1x1), 2 for 2x2 downsampling, 4 for * 4x4 downsampling, 8 for 8x8 downsampling. */ JXL_ENC_FRAME_SETTING_EXTRA_CHANNEL_RESAMPLING = 3, /** Indicates the frame added with @ref JxlEncoderAddImageFrame is already * downsampled by the downsampling factor set with @ref * JXL_ENC_FRAME_SETTING_RESAMPLING. The input frame must then be given in the * downsampled resolution, not the full image resolution. The downsampled * resolution is given by ceil(xsize / resampling), ceil(ysize / resampling) * with xsize and ysize the dimensions given in the basic info, and resampling * the factor set with @ref JXL_ENC_FRAME_SETTING_RESAMPLING. * Use 0 to disable, 1 to enable. Default value is 0. */ JXL_ENC_FRAME_SETTING_ALREADY_DOWNSAMPLED = 4, /** Adds noise to the image emulating photographic film noise, the higher the * given number, the grainier the image will be. As an example, a value of 100 * gives low noise whereas a value of 3200 gives a lot of noise. The default * value is 0. */ JXL_ENC_FRAME_SETTING_PHOTON_NOISE = 5, /** Enables adaptive noise generation. This setting is not recommended for * use, please use JXL_ENC_FRAME_SETTING_PHOTON_NOISE instead. Use -1 for the * default (encoder chooses), 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_NOISE = 6, /** Enables or disables dots generation. Use -1 for the default (encoder * chooses), 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_DOTS = 7, /** Enables or disables patches generation. Use -1 for the default (encoder * chooses), 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_PATCHES = 8, /** Edge preserving filter level, -1 to 3. Use -1 for the default (encoder * chooses), 0 to 3 to set a strength. */ JXL_ENC_FRAME_SETTING_EPF = 9, /** Enables or disables the gaborish filter. Use -1 for the default (encoder * chooses), 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_GABORISH = 10, /** Enables modular encoding. Use -1 for default (encoder * chooses), 0 to enforce VarDCT mode (e.g. for photographic images), 1 to * enforce modular mode (e.g. for lossless images). */ JXL_ENC_FRAME_SETTING_MODULAR = 11, /** Enables or disables preserving color of invisible pixels. Use -1 for the * default (1 if lossless, 0 if lossy), 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_KEEP_INVISIBLE = 12, /** Determines the order in which 256x256 regions are stored in the codestream * for progressive rendering. Use -1 for the encoder * default, 0 for scanline order, 1 for center-first order. */ JXL_ENC_FRAME_SETTING_GROUP_ORDER = 13, /** Determines the horizontal position of center for the center-first group * order. Use -1 to automatically use the middle of the image, 0..xsize to * specifically set it. */ JXL_ENC_FRAME_SETTING_GROUP_ORDER_CENTER_X = 14, /** Determines the center for the center-first group order. Use -1 to * automatically use the middle of the image, 0..ysize to specifically set it. */ JXL_ENC_FRAME_SETTING_GROUP_ORDER_CENTER_Y = 15, /** Enables or disables progressive encoding for modular mode. Use -1 for the * encoder default, 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_RESPONSIVE = 16, /** Set the progressive mode for the AC coefficients of VarDCT, using spectral * progression from the DCT coefficients. Use -1 for the encoder default, 0 to * disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_PROGRESSIVE_AC = 17, /** Set the progressive mode for the AC coefficients of VarDCT, using * quantization of the least significant bits. Use -1 for the encoder default, * 0 to disable, 1 to enable. */ JXL_ENC_FRAME_SETTING_QPROGRESSIVE_AC = 18, /** Set the progressive mode using lower-resolution DC images for VarDCT. Use * -1 for the encoder default, 0 to disable, 1 to have an extra 64x64 lower * resolution pass, 2 to have a 512x512 and 64x64 lower resolution pass. */ JXL_ENC_FRAME_SETTING_PROGRESSIVE_DC = 19, /** Use Global channel palette if the amount of colors is smaller than this * percentage of range. Use 0-100 to set an explicit percentage, -1 to use the * encoder default. Used for modular encoding. */ JXL_ENC_FRAME_SETTING_CHANNEL_COLORS_GLOBAL_PERCENT = 20, /** Use Local (per-group) channel palette if the amount of colors is smaller * than this percentage of range. Use 0-100 to set an explicit percentage, -1 * to use the encoder default. Used for modular encoding. */ JXL_ENC_FRAME_SETTING_CHANNEL_COLORS_GROUP_PERCENT = 21, /** Use color palette if amount of colors is smaller than or equal to this * amount, or -1 to use the encoder default. Used for modular encoding. */ JXL_ENC_FRAME_SETTING_PALETTE_COLORS = 22, /** Enables or disables delta palette. Use -1 for the default (encoder * chooses), 0 to disable, 1 to enable. Used in modular mode. */ JXL_ENC_FRAME_SETTING_LOSSY_PALETTE = 23, /** Color transform for internal encoding: -1 = default, 0=XYB, 1=none (RGB), * 2=YCbCr. The XYB setting performs the forward XYB transform. None and * YCbCr both perform no transform, but YCbCr is used to indicate that the * encoded data losslessly represents YCbCr values. */ JXL_ENC_FRAME_SETTING_COLOR_TRANSFORM = 24, /** Reversible color transform for modular encoding: -1=default, 0-41=RCT * index, e.g. index 0 = none, index 6 = YCoCg. * If this option is set to a non-default value, the RCT will be globally * applied to the whole frame. * The default behavior is to try several RCTs locally per modular group, * depending on the speed and distance setting. */ JXL_ENC_FRAME_SETTING_MODULAR_COLOR_SPACE = 25, /** Group size for modular encoding: -1=default, 0=128, 1=256, 2=512, 3=1024. */ JXL_ENC_FRAME_SETTING_MODULAR_GROUP_SIZE = 26, /** Predictor for modular encoding. -1 = default, 0=zero, 1=left, 2=top, * 3=avg0, 4=select, 5=gradient, 6=weighted, 7=topright, 8=topleft, * 9=leftleft, 10=avg1, 11=avg2, 12=avg3, 13=toptop predictive average 14=mix * 5 and 6, 15=mix everything. */ JXL_ENC_FRAME_SETTING_MODULAR_PREDICTOR = 27, /** Fraction of pixels used to learn MA trees as a percentage. -1 = default, * 0 = no MA and fast decode, 50 = default value, 100 = all, values above * 100 are also permitted. Higher values use more encoder memory. */ JXL_ENC_FRAME_SETTING_MODULAR_MA_TREE_LEARNING_PERCENT = 28, /** Number of extra (previous-channel) MA tree properties to use. -1 = * default, 0-11 = valid values. Recommended values are in the range 0 to 3, * or 0 to amount of channels minus 1 (including all extra channels, and * excluding color channels when using VarDCT mode). Higher value gives slower * encoding and slower decoding. */ JXL_ENC_FRAME_SETTING_MODULAR_NB_PREV_CHANNELS = 29, /** Enable or disable CFL (chroma-from-luma) for lossless JPEG recompression. * -1 = default, 0 = disable CFL, 1 = enable CFL. */ JXL_ENC_FRAME_SETTING_JPEG_RECON_CFL = 30, /** Prepare the frame for indexing in the frame index box. * 0 = ignore this frame (same as not setting a value), * 1 = index this frame within the Frame Index Box. * If any frames are indexed, the first frame needs to * be indexed, too. If the first frame is not indexed, and * a later frame is attempted to be indexed, JXL_ENC_ERROR will occur. * If non-keyframes, i.e., frames with cropping, blending or patches are * attempted to be indexed, JXL_ENC_ERROR will occur. */ JXL_ENC_FRAME_INDEX_BOX = 31, /** Sets brotli encode effort for use in JPEG recompression and compressed * metadata boxes (brob). Can be -1 (default) or 0 (fastest) to 11 (slowest). * Default is based on the general encode effort in case of JPEG * recompression, and 4 for brob boxes. */ JXL_ENC_FRAME_SETTING_BROTLI_EFFORT = 32, /** Enables or disables brotli compression of metadata boxes derived from * a JPEG frame when using JxlEncoderAddJPEGFrame. This has no effect on boxes * added using JxlEncoderAddBox. * -1 = default, 0 = disable compression, 1 = enable compression. */ JXL_ENC_FRAME_SETTING_JPEG_COMPRESS_BOXES = 33, /** Enum value not to be used as an option. This value is added to force the * C compiler to have the enum to take a known size. */ JXL_ENC_FRAME_SETTING_FILL_ENUM = 65535, } JxlEncoderFrameSettingId; /** * Creates an instance of JxlEncoder 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 JxlEncoder otherwise */ JXL_EXPORT JxlEncoder* JxlEncoderCreate(const JxlMemoryManager* memory_manager); /** * Re-initializes a JxlEncoder instance, so it can be re-used for encoding * another image. All state and settings are reset as if the object was * newly created with JxlEncoderCreate, but the memory manager is kept. * * @param enc instance to be re-initialized. */ JXL_EXPORT void JxlEncoderReset(JxlEncoder* enc); /** * Deinitializes and frees JxlEncoder instance. * * @param enc instance to be cleaned up and deallocated. */ JXL_EXPORT void JxlEncoderDestroy(JxlEncoder* enc); /** * Sets the color management system (CMS) that will be used for color conversion * (if applicable) during encoding. May only be set before starting encoding. If * left unset, the default CMS implementation will be used. * * @param enc encoder object. * @param cms structure representing a CMS implementation. See JxlCmsInterface * for more details. */ JXL_EXPORT void JxlEncoderSetCms(JxlEncoder* enc, JxlCmsInterface cms); /** * Set the parallel runner for multithreading. May only be set before starting * encoding. * * @param enc encoder 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_ENC_SUCCESS if the runner was set, JXL_ENC_ERROR * otherwise (the previous runner remains set). */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetParallelRunner(JxlEncoder* enc, JxlParallelRunner parallel_runner, void* parallel_runner_opaque); /** * Get the (last) error code in case JXL_ENC_ERROR was returned. * * @param enc encoder object. * @return the JxlEncoderError that caused the (last) JXL_ENC_ERROR to be * returned. */ JXL_EXPORT JxlEncoderError JxlEncoderGetError(JxlEncoder* enc); /** * Encodes JPEG XL file using the available bytes. @p *avail_out indicates how * many output bytes are available, and @p *next_out points to the input bytes. * *avail_out will be decremented by the amount of bytes that have been * processed by the encoder and *next_out will be incremented by the same * amount, so *next_out will now point at the amount of *avail_out unprocessed * bytes. * * The returned status indicates whether the encoder needs more output bytes. * When the return value is not JXL_ENC_ERROR or JXL_ENC_SUCCESS, the encoding * requires more JxlEncoderProcessOutput calls to continue. * * The caller must guarantee that *avail_out >= 32 when calling * JxlEncoderProcessOutput; otherwise, JXL_ENC_NEED_MORE_OUTPUT will be * returned. It is guaranteed that, if *avail_out >= 32, at least one byte of * output will be written. * * This encodes the frames and/or boxes added so far. If the last frame or last * box has been added, @ref JxlEncoderCloseInput, @ref JxlEncoderCloseFrames * and/or @ref JxlEncoderCloseBoxes must be called before the next * @ref JxlEncoderProcessOutput call, or the codestream won't be encoded * correctly. * * @param enc encoder object. * @param next_out pointer to next bytes to write to. * @param avail_out amount of bytes available starting from *next_out. * @return JXL_ENC_SUCCESS when encoding finished and all events handled. * @return JXL_ENC_ERROR when encoding failed, e.g. invalid input. * @return JXL_ENC_NEED_MORE_OUTPUT more output buffer is necessary. */ JXL_EXPORT JxlEncoderStatus JxlEncoderProcessOutput(JxlEncoder* enc, uint8_t** next_out, size_t* avail_out); /** * Sets the frame information for this frame to the encoder. This includes * animation information such as frame duration to store in the frame header. * The frame header fields represent the frame as passed to the encoder, but not * necessarily the exact values as they will be encoded file format: the encoder * could change crop and blending options of a frame for more efficient encoding * or introduce additional internal frames. Animation duration and time code * information is not altered since those are immutable metadata of the frame. * * It is not required to use this function, however if have_animation is set * to true in the basic info, then this function should be used to set the * time duration of this individual frame. By default individual frames have a * time duration of 0, making them form a composite still. See @ref * JxlFrameHeader for more information. * * This information is stored in the JxlEncoderFrameSettings and so is used for * any frame encoded with these JxlEncoderFrameSettings. It is ok to change * between @ref JxlEncoderAddImageFrame calls, each added image frame will have * the frame header that was set in the options at the time of calling * JxlEncoderAddImageFrame. * * The is_last and name_length fields of the JxlFrameHeader are ignored, use * @ref JxlEncoderCloseFrames to indicate last frame, and @ref * JxlEncoderSetFrameName to indicate the name and its length instead. * Calling this function will clear any name that was previously set with @ref * JxlEncoderSetFrameName. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param frame_header frame header data to set. Object owned by the caller and * does not need to be kept in memory, its information is copied internally. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetFrameHeader(JxlEncoderFrameSettings* frame_settings, const JxlFrameHeader* frame_header); /** * Sets blend info of an extra channel. The blend info of extra channels is set * separately from that of the color channels, the color channels are set with * @ref JxlEncoderSetFrameHeader. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param index index of the extra channel to use. * @param blend_info blend info to set for the extra channel * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetExtraChannelBlendInfo( JxlEncoderFrameSettings* frame_settings, size_t index, const JxlBlendInfo* blend_info); /** * Sets the name of the animation frame. This function is optional, frames are * not required to have a name. This setting is a part of the frame header, and * the same principles as for @ref JxlEncoderSetFrameHeader apply. The * name_length field of JxlFrameHeader is ignored by the encoder, this function * determines the name length instead as the length in bytes of the C string. * * The maximum possible name length is 1071 bytes (excluding terminating null * character). * * Calling @ref JxlEncoderSetFrameHeader clears any name that was * previously set. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param frame_name name of the next frame to be encoded, as a UTF-8 encoded C * string (zero terminated). Owned by the caller, and copied internally. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetFrameName( JxlEncoderFrameSettings* frame_settings, const char* frame_name); /** * Sets the bit depth of the input buffer. * * For float pixel formats, only the default JXL_BIT_DEPTH_FROM_PIXEL_FORMAT * setting is allowed, while for unsigned pixel formats, * JXL_BIT_DEPTH_FROM_CODESTREAM setting is also allowed. See the comment on * @ref JxlEncoderAddImageFrame for the effects of the bit depth setting. * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param bit_depth the bit depth setting of the pixel input * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetFrameBitDepth( JxlEncoderFrameSettings* frame_settings, const JxlBitDepth* bit_depth); /** * Sets the buffer to read JPEG encoded bytes from for the next frame to encode. * * If JxlEncoderSetBasicInfo has not yet been called, calling * JxlEncoderAddJPEGFrame will implicitly call it with the parameters of the * added JPEG frame. * * If JxlEncoderSetColorEncoding or JxlEncoderSetICCProfile has not yet been * called, calling JxlEncoderAddJPEGFrame will implicitly call it with the * parameters of the added JPEG frame. * * If the encoder is set to store JPEG reconstruction metadata using @ref * JxlEncoderStoreJPEGMetadata and a single JPEG frame is added, it will be * possible to losslessly reconstruct the JPEG codestream. * * If this is the last frame, @ref JxlEncoderCloseInput or @ref * JxlEncoderCloseFrames must be called before the next * @ref JxlEncoderProcessOutput call. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param buffer bytes to read JPEG from. Owned by the caller and its contents * are copied internally. * @param size size of buffer in bytes. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderAddJPEGFrame(const JxlEncoderFrameSettings* frame_settings, const uint8_t* buffer, size_t size); /** * Sets the buffer to read pixels from for the next image to encode. Must call * JxlEncoderSetBasicInfo before JxlEncoderAddImageFrame. * * Currently only some data types for pixel formats are supported: * - JXL_TYPE_UINT8, with range 0..255 * - JXL_TYPE_UINT16, with range 0..65535 * - JXL_TYPE_FLOAT16, with nominal range 0..1 * - JXL_TYPE_FLOAT, with nominal range 0..1 * * Note: the sample data type in pixel_format is allowed to be different from * what is described in the JxlBasicInfo. The type in pixel_format, together * with an optional @ref JxlBitDepth parameter set by @ref * JxlEncoderSetFrameBitDepth describes the format of the uncompressed pixel * buffer. The bits_per_sample and exponent_bits_per_sample in the JxlBasicInfo * describes what will actually be encoded in the JPEG XL codestream. * For example, to encode a 12-bit image, you would set bits_per_sample to 12, * while the input frame buffer can be in the following formats: * - if pixel format is in JXL_TYPE_UINT16 with default bit depth setting * (i.e. JXL_BIT_DEPTH_FROM_PIXEL_FORMAT), input sample values are rescaled * to 16-bit, i.e. multiplied by 65535/4095; * - if pixel format is in JXL_TYPE_UINT16 with JXL_BIT_DEPTH_FROM_CODESTREAM * bit depth setting, input sample values are provided unscaled; * - if pixel format is in JXL_TYPE_FLOAT, input sample values are rescaled * to 0..1, i.e. multiplied by 1.f/4095.f. * While it is allowed, it is obviously not recommended to use a pixel_format * with lower precision than what is specified in the JxlBasicInfo. * * We support interleaved channels as described by the JxlPixelFormat: * - single-channel data, e.g. grayscale * - single-channel + alpha * - trichromatic, e.g. RGB * - trichromatic + alpha * * Extra channels not handled here need to be set by @ref * JxlEncoderSetExtraChannelBuffer. * If the image has alpha, and alpha is not passed here, it will implicitly be * set to all-opaque (an alpha value of 1.0 everywhere). * * The pixels are assumed to be encoded in the original profile that is set with * JxlEncoderSetColorEncoding or JxlEncoderSetICCProfile. If none of these * functions were used, the pixels are assumed to be nonlinear sRGB for integer * data types (JXL_TYPE_UINT8, JXL_TYPE_UINT16), and linear sRGB for floating * point data types (JXL_TYPE_FLOAT16, JXL_TYPE_FLOAT). * * Sample values in floating-point pixel formats are allowed to be outside the * nominal range, e.g. to represent out-of-sRGB-gamut colors in the * uses_original_profile=false case. They are however not allowed to be NaN or * +-infinity. * * If this is the last frame, @ref JxlEncoderCloseInput or @ref * JxlEncoderCloseFrames must be called before the next * @ref JxlEncoderProcessOutput call. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param pixel_format format for pixels. Object owned by the caller and its * contents are copied internally. * @param buffer buffer type to input the pixel data from. Owned by the caller * and its contents are copied internally. * @param size size of buffer in bytes. This size should match what is implied * by the frame dimensions and the pixel format. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderAddImageFrame( const JxlEncoderFrameSettings* frame_settings, const JxlPixelFormat* pixel_format, const void* buffer, size_t size); /** * Sets the buffer to read pixels from for an extra channel at a given index. * The index must be smaller than the num_extra_channels in the associated * JxlBasicInfo. Must call @ref JxlEncoderSetExtraChannelInfo before * JxlEncoderSetExtraChannelBuffer. * * TODO(firsching): mention what data types in pixel formats are supported. * * It is required to call this function for every extra channel, except for the * alpha channel if that was already set through @ref JxlEncoderAddImageFrame. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param pixel_format format for pixels. Object owned by the caller and its * contents are copied internally. The num_channels value is ignored, since the * number of channels for an extra channel is always assumed to be one. * @param buffer buffer type to input the pixel data from. Owned by the caller * and its contents are copied internally. * @param size size of buffer in bytes. This size should match what is implied * by the frame dimensions and the pixel format. * @param index index of the extra channel to use. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetExtraChannelBuffer( const JxlEncoderFrameSettings* frame_settings, const JxlPixelFormat* pixel_format, const void* buffer, size_t size, uint32_t index); /** Adds a metadata box to the file format. JxlEncoderProcessOutput must be used * to effectively write the box to the output. @ref JxlEncoderUseBoxes must * be enabled before using this function. * * Boxes allow inserting application-specific data and metadata (Exif, XML/XMP, * JUMBF and user defined boxes). * * The box format follows ISO BMFF and shares features and box types with other * image and video formats, including the Exif, XML and JUMBF boxes. The box * format for JPEG XL is specified in ISO/IEC 18181-2. * * Boxes in general don't contain other boxes inside, except a JUMBF superbox. * Boxes follow each other sequentially and are byte-aligned. If the container * format is used, the JXL stream consists of concatenated boxes. * It is also possible to use a direct codestream without boxes, but in that * case metadata cannot be added. * * Each box generally has the following byte structure in the file: * - 4 bytes: box size including box header (Big endian. If set to 0, an * 8-byte 64-bit size follows instead). * - 4 bytes: type, e.g. "JXL " for the signature box, "jxlc" for a codestream * box. * - N bytes: box contents. * * Only the box contents are provided to the contents argument of this function, * the encoder encodes the size header itself. Most boxes are written * automatically by the encoder as needed ("JXL ", "ftyp", "jxll", "jxlc", * "jxlp", "jxli", "jbrd"), and this function only needs to be called to add * optional metadata when encoding from pixels (using JxlEncoderAddImageFrame). * When recompressing JPEG files (using JxlEncoderAddJPEGFrame), if the input * JPEG contains EXIF, XMP or JUMBF metadata, the corresponding boxes are * already added automatically. * * Box types are given by 4 characters. The following boxes can be added with * this function: * - "Exif": a box with EXIF metadata, can be added by libjxl users, or is * automatically added when needed for JPEG reconstruction. The contents of * this box must be prepended by a 4-byte tiff header offset, which may * be 4 zero bytes in case the tiff header follows immediately. * The EXIF metadata must be in sync with what is encoded in the JPEG XL * codestream, specifically the image orientation. While this is not * recommended in practice, in case of conflicting metadata, the JPEG XL * codestream takes precedence. * - "xml ": a box with XML data, in particular XMP metadata, can be added by * libjxl users, or is automatically added when needed for JPEG reconstruction * - "jumb": a JUMBF superbox, which can contain boxes with different types of * metadata inside. This box type can be added by the encoder transparently, * and other libraries to create and handle JUMBF content exist. * - Application-specific boxes. Their typename should not begin with "jxl" or * "JXL" or conflict with other existing typenames, and they should be * registered with MP4RA (mp4ra.org). * * These boxes can be stored uncompressed or Brotli-compressed (using a "brob" * box), depending on the compress_box parameter. * * @param enc encoder object. * @param type the box type, e.g. "Exif" for EXIF metadata, "xml " for XMP or * IPTC metadata, "jumb" for JUMBF metadata. * @param contents the full contents of the box, for example EXIF * data. ISO BMFF box header must not be included, only the contents. Owned by * the caller and its contents are copied internally. * @param size size of the box contents. * @param compress_box Whether to compress this box as a "brob" box. Requires * Brotli support. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error, such as when * using this function without JxlEncoderUseContainer, or adding a box type * that would result in an invalid file format. */ JXL_EXPORT JxlEncoderStatus JxlEncoderAddBox(JxlEncoder* enc, const JxlBoxType type, const uint8_t* contents, size_t size, JXL_BOOL compress_box); /** * Indicates the intention to add metadata boxes. This allows @ref * JxlEncoderAddBox to be used. When using this function, then it is required * to use @ref JxlEncoderCloseBoxes at the end. * * By default the encoder assumes no metadata boxes will be added. * * This setting can only be set at the beginning, before encoding starts. * * @param enc encoder object. */ JXL_EXPORT JxlEncoderStatus JxlEncoderUseBoxes(JxlEncoder* enc); /** * Declares that no further boxes will be added with @ref JxlEncoderAddBox. * This function must be called after the last box is added so the encoder knows * the stream will be finished. It is not necessary to use this function if * @ref JxlEncoderUseBoxes is not used. Further frames may still be added. * * Must be called between JxlEncoderAddBox of the last box * and the next call to JxlEncoderProcessOutput, or @ref JxlEncoderProcessOutput * won't output the last box correctly. * * NOTE: if you don't need to close frames and boxes at separate times, you can * use @ref JxlEncoderCloseInput instead to close both at once. * * @param enc encoder object. */ JXL_EXPORT void JxlEncoderCloseBoxes(JxlEncoder* enc); /** * Declares that no frames will be added and @ref JxlEncoderAddImageFrame and * @ref JxlEncoderAddJPEGFrame won't be called anymore. Further metadata boxes * may still be added. This function or @ref JxlEncoderCloseInput must be called * after adding the last frame and the next call to * @ref JxlEncoderProcessOutput, or the frame won't be properly marked as last. * * NOTE: if you don't need to close frames and boxes at separate times, you can * use @ref JxlEncoderCloseInput instead to close both at once. * * @param enc encoder object. */ JXL_EXPORT void JxlEncoderCloseFrames(JxlEncoder* enc); /** * Closes any input to the encoder, equivalent to calling JxlEncoderCloseFrames * as well as calling JxlEncoderCloseBoxes if needed. No further input of any * kind may be given to the encoder, but further @ref JxlEncoderProcessOutput * calls should be done to create the final output. * * The requirements of both @ref JxlEncoderCloseFrames and @ref * JxlEncoderCloseBoxes apply to this function. Either this function or the * other two must be called after the final frame and/or box, and the next * @ref JxlEncoderProcessOutput call, or the codestream won't be encoded * correctly. * * @param enc encoder object. */ JXL_EXPORT void JxlEncoderCloseInput(JxlEncoder* enc); /** * Sets the original color encoding of the image encoded by this encoder. This * is an alternative to JxlEncoderSetICCProfile and only one of these two must * be used. This one sets the color encoding as a @ref JxlColorEncoding, while * the other sets it as ICC binary data. * Must be called after JxlEncoderSetBasicInfo. * * @param enc encoder object. * @param color color encoding. Object owned by the caller and its contents are * copied internally. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR or * JXL_ENC_NOT_SUPPORTED otherwise */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetColorEncoding(JxlEncoder* enc, const JxlColorEncoding* color); /** * Sets the original color encoding of the image encoded by this encoder as an * ICC color profile. This is an alternative to JxlEncoderSetColorEncoding and * only one of these two must be used. This one sets the color encoding as ICC * binary data, while the other defines it as a @ref JxlColorEncoding. * Must be called after JxlEncoderSetBasicInfo. * * @param enc encoder object. * @param icc_profile bytes of the original ICC profile * @param size size of the icc_profile buffer in bytes * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR or * JXL_ENC_NOT_SUPPORTED otherwise */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetICCProfile(JxlEncoder* enc, const uint8_t* icc_profile, size_t size); /** * Initializes a JxlBasicInfo struct to default values. * For forwards-compatibility, this function has to be called before values * are assigned to the struct fields. * The default values correspond to an 8-bit RGB image, no alpha or any * other extra channels. * * @param info global image metadata. Object owned by the caller. */ JXL_EXPORT void JxlEncoderInitBasicInfo(JxlBasicInfo* info); /** * Initializes a JxlFrameHeader struct to default values. * For forwards-compatibility, this function has to be called before values * are assigned to the struct fields. * The default values correspond to a frame with no animation duration and the * 'replace' blend mode. After using this function, For animation duration must * be set, for composite still blend settings must be set. * * @param frame_header frame metadata. Object owned by the caller. */ JXL_EXPORT void JxlEncoderInitFrameHeader(JxlFrameHeader* frame_header); /** * Initializes a JxlBlendInfo struct to default values. * For forwards-compatibility, this function has to be called before values * are assigned to the struct fields. * * @param blend_info blending info. Object owned by the caller. */ JXL_EXPORT void JxlEncoderInitBlendInfo(JxlBlendInfo* blend_info); /** * Sets the global metadata of the image encoded by this encoder. * * If the JxlBasicInfo contains information of extra channels beyond an alpha * channel, then @ref JxlEncoderSetExtraChannelInfo must be called between * JxlEncoderSetBasicInfo and @ref JxlEncoderAddImageFrame. In order to indicate * extra channels, the value of `info.num_extra_channels` should be set to the * number of extra channels, also counting the alpha channel if present. * * @param enc encoder object. * @param info global image metadata. Object owned by the caller and its * contents are copied internally. * @return JXL_ENC_SUCCESS if the operation was successful, * JXL_ENC_ERROR or JXL_ENC_NOT_SUPPORTED otherwise */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetBasicInfo(JxlEncoder* enc, const JxlBasicInfo* info); /** * Initializes a JxlExtraChannelInfo struct to default values. * For forwards-compatibility, this function has to be called before values * are assigned to the struct fields. * The default values correspond to an 8-bit channel of the provided type. * * @param type type of the extra channel. * @param info global extra channel metadata. Object owned by the caller and its * contents are copied internally. */ JXL_EXPORT void JxlEncoderInitExtraChannelInfo(JxlExtraChannelType type, JxlExtraChannelInfo* info); /** * Sets information for the extra channel at the given index. The index * must be smaller than num_extra_channels in the associated JxlBasicInfo. * * @param enc encoder object * @param index index of the extra channel to set. * @param info global extra channel metadata. Object owned by the caller and its * contents are copied internally. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetExtraChannelInfo( JxlEncoder* enc, size_t index, const JxlExtraChannelInfo* info); /** * Sets the name for the extra channel at the given index in UTF-8. The index * must be smaller than the num_extra_channels in the associated JxlBasicInfo. * * TODO(lode): remove size parameter for consistency with * JxlEncoderSetFrameName * * @param enc encoder object * @param index index of the extra channel to set. * @param name buffer with the name of the extra channel. * @param size size of the name buffer in bytes, not counting the terminating * character. * @return JXL_ENC_SUCCESS on success, JXL_ENC_ERROR on error */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetExtraChannelName(JxlEncoder* enc, size_t index, const char* name, size_t size); /** * Sets a frame-specific option of integer type to the encoder options. * The JxlEncoderFrameSettingId argument determines which option is set. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param option ID of the option to set. * @param value Integer value to set for this option. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR in * case of an error, such as invalid or unknown option id, or invalid integer * value for the given option. If an error is returned, the state of the * JxlEncoderFrameSettings object is still valid and is the same as before this * function was called. */ JXL_EXPORT JxlEncoderStatus JxlEncoderFrameSettingsSetOption( JxlEncoderFrameSettings* frame_settings, JxlEncoderFrameSettingId option, int64_t value); /** * Sets a frame-specific option of float type to the encoder options. * The JxlEncoderFrameSettingId argument determines which option is set. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param option ID of the option to set. * @param value Float value to set for this option. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR in * case of an error, such as invalid or unknown option id, or invalid integer * value for the given option. If an error is returned, the state of the * JxlEncoderFrameSettings object is still valid and is the same as before this * function was called. */ JXL_EXPORT JxlEncoderStatus JxlEncoderFrameSettingsSetFloatOption( JxlEncoderFrameSettings* frame_settings, JxlEncoderFrameSettingId option, float value); /** Forces the encoder to use the box-based container format (BMFF) even * when not necessary. * * When using @ref JxlEncoderUseBoxes, @ref JxlEncoderStoreJPEGMetadata or @ref * JxlEncoderSetCodestreamLevel with level 10, the encoder will automatically * also use the container format, it is not necessary to use * JxlEncoderUseContainer for those use cases. * * By default this setting is disabled. * * This setting can only be set at the beginning, before encoding starts. * * @param enc encoder object. * @param use_container true if the encoder should always output the JPEG XL * container format, false to only output it when necessary. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderUseContainer(JxlEncoder* enc, JXL_BOOL use_container); /** * Configure the encoder to store JPEG reconstruction metadata in the JPEG XL * container. * * If this is set to true and a single JPEG frame is added, it will be * possible to losslessly reconstruct the JPEG codestream. * * This setting can only be set at the beginning, before encoding starts. * * @param enc encoder object. * @param store_jpeg_metadata true if the encoder should store JPEG metadata. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderStoreJPEGMetadata(JxlEncoder* enc, JXL_BOOL store_jpeg_metadata); /** Sets the feature level of the JPEG XL codestream. Valid values are 5 and * 10, or -1 (to choose automatically). Using the minimum required level, or * level 5 in most cases, is recommended for compatibility with all decoders. * * Level 5: for end-user image delivery, this level is the most widely * supported level by image decoders and the recommended level to use unless a * level 10 feature is absolutely necessary. Supports a maximum resolution * 268435456 pixels total with a maximum width or height of 262144 pixels, * maximum 16-bit color channel depth, maximum 120 frames per second for * animation, maximum ICC color profile size of 4 MiB, it allows all color * models and extra channel types except CMYK and the JXL_CHANNEL_BLACK extra * channel, and a maximum of 4 extra channels in addition to the 3 color * channels. It also sets boundaries to certain internally used coding tools. * * Level 10: this level removes or increases the bounds of most of the level * 5 limitations, allows CMYK color and up to 32 bits per color channel, but * may be less widely supported. * * The default value is -1. This means the encoder will automatically choose * between level 5 and level 10 based on what information is inside the @ref * JxlBasicInfo structure. Do note that some level 10 features, particularly * those used by animated JPEG XL codestreams, might require level 10, even * though the @ref JxlBasicInfo only suggests level 5. In this case, the level * must be explicitly set to 10, otherwise the encoder will return an error. * The encoder will restrict internal encoding choices to those compatible with * the level setting. * * This setting can only be set at the beginning, before encoding starts. * * @param enc encoder object. * @param level the level value to set, must be -1, 5, or 10. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetCodestreamLevel(JxlEncoder* enc, int level); /** Returns the codestream level required to support the currently configured * settings and basic info. This function can only be used at the beginning, * before encoding starts, but after setting basic info. * * This does not support per-frame settings, only global configuration, such as * the image dimensions, that are known at the time of writing the header of * the JPEG XL file. * * If this returns 5, nothing needs to be done and the codestream can be * compatible with any decoder. If this returns 10, JxlEncoderSetCodestreamLevel * has to be used to set the codestream level to 10, or the encoder can be * configured differently to allow using the more compatible level 5. * * @param enc encoder object. * @return -1 if no level can support the configuration (e.g. image dimensions * larger than even level 10 supports), 5 if level 5 is supported, 10 if setting * the codestream level to 10 is required. * */ JXL_EXPORT int JxlEncoderGetRequiredCodestreamLevel(const JxlEncoder* enc); /** * Enables lossless encoding. * * This is not an option like the others on itself, but rather while enabled it * overrides a set of existing options (such as distance, modular mode and * color transform) that enables bit-for-bit lossless encoding. * * When disabled, those options are not overridden, but since those options * could still have been manually set to a combination that operates losslessly, * using this function with lossless set to JXL_DEC_FALSE does not guarantee * lossy encoding, though the default set of options is lossy. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param lossless whether to override options for lossless mode * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetFrameLossless( JxlEncoderFrameSettings* frame_settings, JXL_BOOL lossless); /** DEPRECATED: use JxlEncoderSetFrameLossless instead. */ JXL_EXPORT JxlEncoderStatus JxlEncoderOptionsSetLossless(JxlEncoderFrameSettings*, JXL_BOOL); /** * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param effort the effort value to set. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. * * DEPRECATED: use JxlEncoderFrameSettingsSetOption(frame_settings, * JXL_ENC_FRAME_SETTING_EFFORT, effort) instead. */ JXL_DEPRECATED JXL_EXPORT JxlEncoderStatus JxlEncoderOptionsSetEffort(JxlEncoderFrameSettings* frame_settings, int effort); /** * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param tier the decoding speed tier to set. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. * * DEPRECATED: use JxlEncoderFrameSettingsSetOption(frame_settings, * JXL_ENC_FRAME_SETTING_DECODING_SPEED, tier) instead. */ JXL_DEPRECATED JXL_EXPORT JxlEncoderStatus JxlEncoderOptionsSetDecodingSpeed( JxlEncoderFrameSettings* frame_settings, int tier); /** * Sets the distance level for lossy compression: target max butteraugli * distance, lower = higher quality. Range: 0 .. 15. * 0.0 = mathematically lossless (however, use JxlEncoderSetFrameLossless * instead to use true lossless, as setting distance to 0 alone is not the only * requirement). 1.0 = visually lossless. Recommended range: 0.5 .. 3.0. Default * value: 1.0. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param distance the distance value to set. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetFrameDistance( JxlEncoderFrameSettings* frame_settings, float distance); /** DEPRECATED: use JxlEncoderSetFrameDistance instead. */ JXL_DEPRECATED JXL_EXPORT JxlEncoderStatus JxlEncoderOptionsSetDistance(JxlEncoderFrameSettings*, float); /** * Sets the distance level for lossy compression of extra channels. * The distance is as in JxlEncoderSetFrameDistance (lower = higher quality). * If not set, or if set to the special value -1, the distance that was set with * JxlEncoderSetFrameDistance will be used. * * @param frame_settings set of options and metadata for this frame. Also * includes reference to the encoder object. * @param index index of the extra channel to set a distance value for. * @param distance the distance value to set. * @return JXL_ENC_SUCCESS if the operation was successful, JXL_ENC_ERROR * otherwise. */ JXL_EXPORT JxlEncoderStatus JxlEncoderSetExtraChannelDistance( JxlEncoderFrameSettings* frame_settings, size_t index, float distance); /** * Create a new set of encoder options, with all values initially copied from * the @p source options, or set to default if @p source is NULL. * * The returned pointer is an opaque struct tied to the encoder and it will be * deallocated by the encoder when JxlEncoderDestroy() is called. For functions * taking both a @ref JxlEncoder and a @ref JxlEncoderFrameSettings, only * JxlEncoderFrameSettings created with this function for the same encoder * instance can be used. * * @param enc encoder object. * @param source source options to copy initial values from, or NULL to get * defaults initialized to defaults. * @return the opaque struct pointer identifying a new set of encoder options. */ JXL_EXPORT JxlEncoderFrameSettings* JxlEncoderFrameSettingsCreate( JxlEncoder* enc, const JxlEncoderFrameSettings* source); /** DEPRECATED: use JxlEncoderFrameSettingsCreate instead. */ JXL_DEPRECATED JXL_EXPORT JxlEncoderFrameSettings* JxlEncoderOptionsCreate( JxlEncoder*, const JxlEncoderFrameSettings*); /** * Sets a color encoding to be sRGB. * * @param color_encoding color encoding instance. * @param is_gray whether the color encoding should be gray scale or color. */ JXL_EXPORT void JxlColorEncodingSetToSRGB(JxlColorEncoding* color_encoding, JXL_BOOL is_gray); /** * Sets a color encoding to be linear sRGB. * * @param color_encoding color encoding instance. * @param is_gray whether the color encoding should be gray scale or color. */ JXL_EXPORT void JxlColorEncodingSetToLinearSRGB( JxlColorEncoding* color_encoding, JXL_BOOL is_gray); /** * Enables usage of expert options. * * At the moment, the only expert option is setting an effort value of 10, * which gives the best compression for pixel-lossless modes but is very slow. * * @param enc encoder object. */ JXL_EXPORT void JxlEncoderAllowExpertOptions(JxlEncoder* enc); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif /* JXL_ENCODE_H_ */ /** @}*/