jpegxl_sys\encoder/
encode.rs

1/*
2This file is part of jpegxl-sys.
3
4jpegxl-sys is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9jpegxl-sys is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with jpegxl-sys.  If not, see <https://www.gnu.org/licenses/>.
16*/
17
18//! Encoding API for JPEG XL.
19
20use std::ffi::{c_char, c_void};
21
22use super::stats::JxlEncoderStats;
23use crate::{
24    color::{cms_interface::JxlCmsInterface, color_encoding::JxlColorEncoding},
25    common::memory_manager::JxlMemoryManager,
26    common::types::{JxlBitDepth, JxlBool, JxlBoxType, JxlPixelFormat},
27    metadata::codestream_header::{
28        JxlBasicInfo, JxlBlendInfo, JxlExtraChannelInfo, JxlExtraChannelType, JxlFrameHeader,
29    },
30    threads::parallel_runner::JxlParallelRunner,
31};
32
33#[cfg(doc)]
34use crate::{
35    common::types::{JxlBitDepthType, JxlDataType},
36    encoder::stats::JxlEncoderStatsCreate,
37};
38
39/// Opaque structure that holds the JPEG XL encoder.
40///
41/// Allocated and initialized with [`JxlEncoderCreate`].
42/// Cleaned up and deallocated with [`JxlEncoderDestroy`].
43#[repr(C)]
44pub struct JxlEncoder {
45    _unused: [u8; 0],
46}
47
48/// Settings and metadata for a single image frame. This includes encoder options
49/// for a frame such as compression quality and speed.
50///
51/// Allocated and initialized with [`JxlEncoderFrameSettingsCreate`].
52/// Cleaned up and deallocated when the encoder is destroyed with
53/// [`JxlEncoderDestroy`].
54#[repr(C)]
55pub struct JxlEncoderFrameSettings {
56    _unused: [u8; 0],
57}
58
59/// Return value for multiple encoder functions.
60#[repr(C)]
61#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
62pub enum JxlEncoderStatus {
63    /// Function call finished successfully, or encoding is finished and there is
64    /// nothing more to be done
65    Success = 0,
66    /// An error occurred, for example out of memory.
67    Error = 1,
68    /// The encoder needs more output buffer to continue encoding.
69    NeedMoreOutput = 2,
70}
71
72/// Error conditions:
73/// API usage errors have the 0x80 bit set to 1
74/// Other errors have the 0x80 bit set to 0
75#[repr(C)]
76#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
77pub enum JxlEncoderError {
78    /// No error
79    OK = 0,
80
81    /// Generic encoder error due to unspecified cause
82    Generic = 1,
83
84    /// Out of memory. TODO: not really used
85    OutOfMemory = 2,
86
87    /// JPEG bitstream reconstruction data could not be represented (e.g. too much tail data)
88    Jbrd = 3,
89
90    /// Input is invalid (e.g. corrupt JPEG file or ICC profile)
91    BadInput = 4,
92
93    /// The encoder doesn't (yet) support this. Either no version of libjxl
94    /// supports this, and the API is used incorrectly, or the libjxl version
95    /// should have been checked before trying to do this.
96    NotSupported = 0x80,
97
98    /// The encoder API is used in an incorrect way.
99    /// In this case, a debug build of libjxl should output a specific error
100    /// message. (if not, please open an issue about it)
101    ApiUsage = 0x81,
102}
103
104/// Id of encoder options for a frame. This includes options such as setting
105/// encoding effort/speed or overriding the use of certain coding tools, for this
106/// frame. This does not include non-frame related encoder options such as for
107/// boxes.
108#[repr(C)]
109#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
110pub enum JxlEncoderFrameSettingId {
111    /// Sets encoder effort/speed level without affecting decoding speed. Valid
112    /// values are, from faster to slower speed: 1:lightning 2:thunder 3:falcon
113    /// 4:cheetah 5:hare 6:wombat 7:squirrel 8:kitten 9:tortoise 10:glacier.
114    /// Default: squirrel (7).
115    Effort = 0,
116
117    /// Sets the decoding speed tier for the provided options. Minimum is 0
118    /// (slowest to decode, best quality/density), and maximum is 4 (fastest to
119    /// decode, at the cost of some quality/density). Default is 0.
120    DecodingSpeed = 1,
121
122    /// Sets resampling option. If enabled, the image is downsampled before
123    /// compression, and upsampled to original size in the decoder. Integer option,
124    /// use -1 for the default behavior (resampling only applied for low quality),
125    /// 1 for no downsampling (1x1), 2 for 2x2 downsampling, 4 for 4x4
126    /// downsampling, 8 for 8x8 downsampling.
127    Resampling = 2,
128
129    /// Similar to [`Self::Resampling`], but for extra channels.
130    /// Integer option, use -1 for the default behavior (depends on encoder
131    /// implementation), 1 for no downsampling (1x1), 2 for 2x2 downsampling, 4 for
132    /// 4x4 downsampling, 8 for 8x8 downsampling.
133    ExtraChannelResampling = 3,
134
135    /// Indicates the frame added with [`JxlEncoderAddImageFrame`] is already
136    /// downsampled by the downsampling factor set with [`Self::Resampling`]. The input frame
137    /// must then be given in the downsampled resolution, not the full image resolution.
138    /// The downsampled resolution is given by `ceil(xsize / resampling)`, `ceil(ysize / resampling)`
139    /// with `xsize` and `ysize` the dimensions given in the basic info, and `resampling`
140    /// the factor set with [`Self::Resampling`].
141    /// Use 0 to disable, 1 to enable. Default value is 0.
142    AlreadyDownsampled = 4,
143
144    /// Adds noise to the image emulating photographic film noise, the higher the
145    /// given number, the grainier the image will be. As an example, a value of 100
146    /// gives low noise whereas a value of 3200 gives a lot of noise. The default
147    /// value is 0.
148    PhotonNoise = 5,
149
150    /// Enables adaptive noise generation. This setting is not recommended for
151    /// use, please use [`Self::PhotonNoise`] instead.
152    /// Use -1 for the default (encoder chooses), 0 to disable, 1 to enable.
153    Noise = 6,
154
155    /// Enables or disables dots generation. Use -1 for the default (encoder
156    /// chooses), 0 to disable, 1 to enable.
157    Dots = 7,
158
159    /// Enables or disables patches generation. Use -1 for the default (encoder
160    /// chooses), 0 to disable, 1 to enable.
161    Patches = 8,
162
163    /// Edge preserving filter level, -1 to 3. Use -1 for the default (encoder
164    /// chooses), 0 to 3 to set a strength.
165    Epf = 9,
166
167    /// Enables or disables the gaborish filter. Use -1 for the default (encoder
168    /// chooses), 0 to disable, 1 to enable.
169    Gaborish = 10,
170
171    /// Enables modular encoding. Use -1 for default (encoder
172    /// chooses), 0 to enforce `VarDCT` mode (e.g. for photographic images), 1 to
173    /// enforce modular mode (e.g. for lossless images).
174    Modular = 11,
175
176    /// Enables or disables preserving color of invisible pixels. Use -1 for the
177    /// default (1 if lossless, 0 if lossy), 0 to disable, 1 to enable.
178    KeepInvisible = 12,
179
180    /// Determines the order in which 256x256 regions are stored in the codestream
181    /// for progressive rendering. Use -1 for the encoder
182    /// default, 0 for scanline order, 1 for center-first order.
183    GroupOrder = 13,
184
185    /// Determines the horizontal position of center for the center-first group
186    /// order. Use -1 to automatically use the middle of the image, 0..xsize to
187    /// specifically set it.
188    GroupOrderCenterX = 14,
189
190    /// Determines the center for the center-first group order. Use -1 to
191    /// automatically use the middle of the image, 0..ysize to specifically set it.
192    GroupOrderCenterY = 15,
193
194    /// Enables or disables progressive encoding for modular mode. Use -1 for the
195    /// encoder default, 0 to disable, 1 to enable.
196    Responsive = 16,
197
198    /// Set the progressive mode for the AC coefficients of `VarDCT`, using spectral
199    /// progression from the DCT coefficients. Use -1 for the encoder default, 0 to
200    /// disable, 1 to enable.
201    ProgressiveAc = 17,
202
203    /// Set the progressive mode for the AC coefficients of `VarDCT`, using
204    /// quantization of the least significant bits. Use -1 for the encoder default,
205    /// 0 to disable, 1 to enable.
206    QprogressiveAc = 18,
207
208    /// Set the progressive mode using lower-resolution DC images for `VarDCT`. Use
209    /// -1 for the encoder default, 0 to disable, 1 to have an extra 64x64 lower
210    /// resolution pass, 2 to have a 512x512 and 64x64 lower resolution pass.
211    ProgressiveDc = 19,
212
213    /// Use Global channel palette if the amount of colors is smaller than this
214    /// percentage of range. Use 0-100 to set an explicit percentage, -1 to use the
215    /// encoder default. Used for modular encoding.
216    ChannelColorsGlobalPercent = 20,
217
218    /// Use Local (per-group) channel palette if the amount of colors is smaller
219    /// than this percentage of range. Use 0-100 to set an explicit percentage, -1
220    /// to use the encoder default. Used for modular encoding.
221    ChannelColorsGroupPercent = 21,
222
223    /// Use color palette if amount of colors is smaller than or equal to this
224    /// amount, or -1 to use the encoder default. Used for modular encoding.
225    PaletteColors = 22,
226
227    /// Enables or disables delta palette. Use -1 for the default (encoder
228    /// chooses), 0 to disable, 1 to enable. Used in modular mode.
229    LossyPalette = 23,
230
231    /// Color transform for internal encoding: -1 = default, 0=XYB, 1=none (RGB),
232    /// 2=YCbCr. The XYB setting performs the forward XYB transform. None and
233    /// YCbCr both perform no transform, but YCbCr is used to indicate that the
234    /// encoded data losslessly represents YCbCr values.
235    ColorTransform = 24,
236
237    /// Reversible color transform for modular encoding: -1=default, 0-41=RCT
238    /// index, e.g. index 0 = none, index 6 = `YCoCg`.
239    /// If this option is set to a non-default value, the RCT will be globally
240    /// applied to the whole frame.
241    /// The default behavior is to try several RCTs locally per modular group,
242    /// depending on the speed and distance setting.
243    ModularColorSpace = 25,
244
245    /// Group size for modular encoding: -1=default, 0=128, 1=256, 2=512, 3=1024.
246    ModularGroupSize = 26,
247
248    /// Predictor for modular encoding. -1 = default, 0=zero, 1=left, 2=top,
249    /// 3=avg0, 4=select, 5=gradient, 6=weighted, 7=topright, 8=topleft,
250    /// 9=leftleft, 10=avg1, 11=avg2, 12=avg3, 13=toptop predictive average 14=mix
251    /// 5 and 6, 15=mix everything.
252    ModularPredictor = 27,
253
254    /// Fraction of pixels used to learn MA trees as a percentage. -1 = default,
255    /// 0 = no MA and fast decode, 50 = default value, 100 = all, values above
256    /// 100 are also permitted. Higher values use more encoder memory.
257    ModularMaTreeLearningPercent = 28,
258
259    /// Number of extra (previous-channel) MA tree properties to use. -1 =
260    /// default, 0-11 = valid values. Recommended values are in the range 0 to 3,
261    /// or 0 to amount of channels minus 1 (including all extra channels, and
262    /// excluding color channels when using `VarDCT` mode). Higher value gives slower
263    /// encoding and slower decoding.
264    ModularNbPrevChannels = 29,
265
266    /// Enable or disable CFL (chroma-from-luma) for lossless JPEG recompression.
267    /// -1 = default, 0 = disable CFL, 1 = enable CFL.
268    JpegReconCfl = 30,
269
270    /// Prepare the frame for indexing in the frame index box.
271    /// 0 = ignore this frame (same as not setting a value),
272    /// 1 = index this frame within the Frame Index Box.
273    /// If any frames are indexed, the first frame needs to
274    /// be indexed, too. If the first frame is not indexed, and
275    /// a later frame is attempted to be indexed, [`JxlEncoderStatus::Error`] will occur.
276    /// If non-keyframes, i.e., frames with cropping, blending or patches are
277    /// attempted to be indexed, [`JxlEncoderStatus::Error`] will occur.
278    IndexBox = 31,
279
280    /// Sets brotli encode effort for use in JPEG recompression and
281    /// compressed metadata boxes (brob). Can be -1 (default) or 0 (fastest) to 11
282    /// (slowest). Default is based on the general encode effort in case of JPEG
283    /// recompression, and 4 for brob boxes.
284    BrotliEffort = 32,
285
286    /// Enables or disables brotli compression of metadata boxes derived from
287    /// a JPEG frame when using [`JxlEncoderAddJPEGFrame`]. This has no effect on
288    /// boxes added using [`JxlEncoderAddBox`]. -1 = default, 0 = disable
289    /// compression, 1 = enable compression.
290    JpegCompressBoxes = 33,
291
292    /// Control what kind of buffering is used, when using chunked image frames.
293    /// -1 = default (let the encoder decide)
294    /// 0 = buffers everything, basically the same as non-streamed code path
295    /// (mainly for testing)
296    /// 1 = buffers everything for images that are smaller than 2048 x 2048, and
297    ///     uses streaming input and output for larger images
298    /// 2 = uses streaming input and output for all images that are larger than
299    ///     one group, i.e. 256 x 256 pixels by default
300    /// 3 = currently same as 2
301    ///
302    /// When using streaming input and output the encoder minimizes memory usage at
303    /// the cost of compression density. Also note that images produced with
304    /// streaming mode might not be progressively decodeable.
305    Buffering = 34,
306
307    /// Keep or discard Exif metadata boxes derived from a JPEG frame when using
308    /// [`JxlEncoderAddJPEGFrame`]. This has no effect on boxes added using
309    /// [`JxlEncoderAddBox`]. When [`JxlEncoderStoreJPEGMetadata`] is set to 1,
310    /// this option cannot be set to 0. Even when Exif metadata is discarded, the
311    /// orientation will still be applied. 0 = discard Exif metadata, 1 = keep Exif
312    /// metadata (default).
313    JpegKeepExif = 35,
314
315    /// Keep or discard XMP metadata boxes derived from a JPEG frame when using
316    /// [`JxlEncoderAddJPEGFrame`]. This has no effect on boxes added using
317    /// [`JxlEncoderAddBox`]. When [`JxlEncoderStoreJPEGMetadata`] is set to 1,
318    /// this option cannot be set to 0. 0 = discard XMP metadata, 1 = keep XMP
319    /// metadata (default).
320    JpegKeepXmp = 36,
321
322    /// Keep or discard JUMBF metadata boxes derived from a JPEG frame when using
323    /// [`JxlEncoderAddJPEGFrame`]. This has no effect on boxes added using
324    /// [`JxlEncoderAddBox`]. 0 = discard JUMBF metadata, 1 = keep JUMBF metadata
325    /// (default).
326    JpegKeepJumbf = 37,
327
328    /// If this mode is disabled, the encoder will not make any image quality
329    /// decisions that are computed based on the full image, but stored only once
330    /// (e.g. the X quant multiplier in the frame header). Used mainly for testing
331    /// equivalence of streaming and non-streaming code.
332    /// 0 = disabled, 1 = enabled (default)
333    UseFullImageHeuristics = 38,
334
335    /// Disable perceptual optimizations. 0 = optimizations enabled (default), 1 =
336    /// optimizations disabled.
337    DisablePerceptualHeuristics = 39,
338
339    /// Enum value not to be used as an option. This value is added to force the
340    /// C compiler to have the enum to take a known size.
341    FillEnum = 65535,
342}
343
344/// The [`JxlEncoderOutputProcessor`] structure provides an interface for the
345/// encoder's output processing. Users of the library, who want to do streaming
346/// encoding, should implement the required callbacks for buffering, writing,
347/// seeking (if supported), and setting a finalized position during the encoding
348/// process.
349///
350/// At a high level, the processor can be in one of two states:
351/// - With an active buffer: This indicates that a buffer has been acquired using
352///   `get_buffer` and encoded data can be written to it.
353/// - Without an active buffer: In this state, no data can be written. A new
354///   buffer must be acquired after releasing any previously active buffer.
355///
356/// The library will not acquire more than one buffer at a given time.
357///
358/// The state of the processor includes `position` and `finalized position`,
359/// which have the following meaning.
360///
361/// - position: Represents the current position, in bytes, within the output
362///   stream where the encoded data will be written next. This position moves
363///   forward with each `release_buffer` call as data is written, and can also be
364///   adjusted through the optional seek callback, if provided. At this position
365///   the next write will occur.
366///
367/// - finalized position: A position in the output stream that ensures all bytes
368///   before this point are finalized and won't be changed by later writes.
369///
370/// All fields but `seek` are required, `seek` is optional and can be `None`.
371#[repr(C)]
372#[derive(Debug, Clone)]
373pub struct JxlEncoderOutputProcessor {
374    /// An opaque pointer that the client can use to store custom data.
375    /// This data will be passed to the associated callback functions.
376    opaque: *mut c_void,
377    /// Acquires a buffer at the current position into which the library will write
378    /// the output data.
379    ///
380    /// If the `size` argument points to 0 and the returned value is NULL, this
381    /// will be interpreted as asking the output writing to stop. In such a case,
382    /// the library will return an error. The client is expected to set the size of
383    /// the returned buffer based on the suggested `size` when this function is
384    /// called.
385    ///
386    /// # Parameters
387    /// - `opaque`: User supplied parameters to the callback.
388    /// - `size`: Points to a suggested buffer size when called; must be set to
389    ///   the size of the returned buffer once the function returns.
390    ///
391    /// # Returns
392    /// A pointer to the acquired buffer or NULL to indicate a stop
393    /// condition.
394    get_buffer: extern "C-unwind" fn(opaque: *mut c_void, size: *mut usize) -> *mut c_void,
395    /// Notifies the user of library that the current buffer's data has been
396    /// written and can be released. This function should advance the current
397    /// osition of the buffer by `written_bytes` number of bytes.
398    ///
399    /// # Parameters
400    /// - `opaque`: user supplied parameters to the callback
401    /// - `written_bytes`: the number of bytes written to the buffer.
402    release_buffer: extern "C-unwind" fn(opaque: *mut c_void, written_bytes: usize),
403    /// Seeks to a specific position in the output. This function is optional and
404    /// can be set to `None` if the output doesn't support seeking. Can only be done
405    /// when there is no buffer. Cannot be used to seek before the finalized
406    /// position.
407    ///
408    /// # Parameters
409    /// - `opaque`: User supplied parameters to the callback.
410    /// - `position`: The position to seek to, in bytes.
411    seek: Option<extern "C-unwind" fn(opaque: *mut c_void, position: u64)>,
412    /// Sets a finalized position on the output data, at a specific position.
413    /// Seeking will never request a position before the finalized position.
414    ///
415    /// Will only be called if there is no active buffer.
416    ///
417    /// # Parameters
418    /// - `opaque`: User supplied parameters to the callback.
419    /// - `finalized_position`: The position, in bytes, where the finalized
420    ///   position should be set.
421    set_finalized_position: extern "C-unwind" fn(opaque: *mut c_void, finalized_position: u64),
422}
423
424/// This struct provides callback functions to pass pixel data in a streaming
425/// manner instead of requiring the entire frame data in memory at once.
426#[repr(C)]
427#[derive(Debug, Clone)]
428pub struct JxlChunkedFrameInputSource {
429    /// A pointer to any user-defined data or state. This can be used to pass
430    /// information to the callback functions.
431    opaque: *mut c_void,
432
433    /// Get the pixel format that color channel data will be provided in.
434    /// When called, `pixel_format` points to a suggested pixel format; if
435    /// color channel data can be given in this pixel format, processing might
436    /// be more efficient.
437    ///
438    /// This function will be called exactly once, before any call to
439    /// [`Self::get_color_channels_data`].
440    ///
441    /// # Parameters
442    /// - `opaque`: User supplied parameters to the callback.
443    /// - `pixel_format`: Format for pixels.
444    get_color_channels_pixel_format:
445        extern "C-unwind" fn(opaque: *mut c_void, pixel_format: *mut JxlPixelFormat),
446
447    /// Callback to retrieve a rectangle of color channel data at a specific
448    /// location. It is guaranteed that `xpos` and `ypos` are multiples of 8. `xsize`,
449    /// `ysize` will be multiples of 8, unless the resulting rectangle would be out
450    /// of image bounds. Moreover, `xsize` and `ysize` will be at most 2048. The
451    /// returned data will be assumed to be in the format returned by the
452    /// (preceding) call to [`Self::get_color_channels_pixel_format`], except the `align`
453    /// parameter of the pixel format will be ignored. Instead, the `i`-th row will
454    /// be assumed to start at position `return_value + i * *row_offset`, with the
455    /// value of `*row_offset` decided by the callee.
456    ///
457    /// Note that multiple calls to `get_color_channel_data_at` may happen before a
458    /// call to [`Self::release_buffer`].
459    ///
460    /// # Parameters
461    /// - `opaque`: User supplied parameters to the callback.
462    /// - `xpos`: Horizontal position for the data.
463    /// - `ypos`: Vertical position for the data.
464    /// - `xsize`: Horizontal size of the requested rectangle of data.
465    /// - `ysize`: Vertical size of the requested rectangle of data.
466    /// - `row_offset`: Pointer to the byte offset between consecutive rows of
467    ///   the retrieved pixel data.
468    ///
469    /// # Returns
470    /// Pointer to the retrieved pixel data.
471    get_color_channels_data_at: extern "C-unwind" fn(
472        opaque: *mut c_void,
473        xpos: usize,
474        ypos: usize,
475        xsize: usize,
476        ysize: usize,
477        row_offset: *mut usize,
478    ) -> *const c_void,
479
480    /// Get the pixel format that extra channel data will be provided in.
481    /// When called, `pixel_format` points to a suggested pixel format; if
482    /// extra channel data can be given in this pixel format, processing might
483    /// be more efficient.
484    ///
485    /// This function will be called exactly once per index, before any call to
486    /// [`Self::get_extra_channel_data_at`] with that given index.
487    ///
488    /// # Parameters
489    /// - `opaque`: User supplied parameters to the callback.
490    /// - `ec_index`: Zero-indexed index of the extra channel.
491    /// - `pixel_format`: Format for extra channel data.
492    get_extra_channel_pixel_format: extern "C-unwind" fn(
493        opaque: *mut c_void,
494        ec_index: usize,
495        pixel_format: *mut JxlPixelFormat,
496    ),
497
498    /// Callback to retrieve a rectangle of extra channel `ec_index` data at a
499    /// specific location. It is guaranteed that `xpos` and `ypos` are multiples of
500    /// 8. `xsize`, `ysize` will be multiples of 8, unless the resulting rectangle
501    /// would be out of image bounds. Moreover, `xsize` and `ysize` will be at most
502    /// 2048. The returned data will be assumed to be in the format returned by the
503    /// (preceding) call to [`Self::get_extra_channel_pixel_format`] with the
504    /// corresponding extra channel index `ec_index`, except the `align` parameter
505    /// of the pixel format will be ignored. Instead, the `i`-th row will be
506    /// assumed to start at position `return_value + i * *row_offset`, with the
507    /// value of `*row_offset` decided by the callee.
508    ///
509    /// Note that multiple calls to `get_extra_channel_data_at` may happen before a
510    /// call to [`Self::release_buffer`].
511    ///
512    /// # Parameters
513    /// - `opaque`: User supplied parameters to the callback.
514    /// - `xpos`: Horizontal position for the data.
515    /// - `ypos`: Vertical position for the data.
516    /// - `xsize`: Horizontal size of the requested rectangle of data.
517    /// - `ysize`: Vertical size of the requested rectangle of data.
518    /// - `row_offset`: Pointer to the byte offset between consecutive rows of
519    ///   the retrieved pixel data.
520    ///
521    /// # Returns
522    /// Pointer to the retrieved pixel data.
523    get_extra_channel_data_at: extern "C-unwind" fn(
524        opaque: *mut c_void,
525        ec_index: usize,
526        xpos: usize,
527        ypos: usize,
528        xsize: usize,
529        ysize: usize,
530        row_offset: *mut usize,
531    ) -> *const c_void,
532
533    /// Releases the buffer `buf` (obtained through a call to
534    /// [`Self::get_color_channels_data_at`] or [`Self::get_extra_channel_data_at`]). This function
535    /// will be called exactly once per call to [`Self::get_color_channels_data_at`] or
536    /// [`Self::get_extra_channel_data_at`].
537    ///
538    /// # Parameters
539    /// - `opaque`: User supplied parameters to the callback.
540    /// - `buf`: Pointer returned by [`Self::get_color_channels_data_at`] or
541    ///   [`Self::get_extra_channel_data_at`].
542    release_buffer: extern "C-unwind" fn(opaque: *mut c_void, buf: *const c_void),
543}
544
545/// Function type for [`JxlEncoderSetDebugImageCallback`].
546///
547/// The callback may be called simultaneously by different threads when using a
548/// threaded parallel runner, on different debug images.
549///
550/// # Parameters
551/// - `opaque`: Optional user data, as given to [`JxlEncoderSetDebugImageCallback`].
552/// - `label`: Label of debug image, can be used in filenames.
553/// - `xsize`: Width of debug image.
554/// - `ysize`: Height of debug image.
555/// - `color`: Color encoding of debug image.
556/// - `pixels`: Pixel data of debug image as big-endian 16-bit unsigned samples.
557///   The memory is not owned by the user, and is only valid during the time the
558///   callback is running.
559pub type JxlDebugImageCallback = extern "C-unwind" fn(
560    opaque: *mut c_void,
561    label: *const c_char,
562    xsize: usize,
563    ysize: usize,
564    color: *const JxlColorEncoding,
565    pixels: *const u16,
566);
567
568extern "C-unwind" {
569    /// Encoder library version.
570    ///
571    /// # Returns
572    /// The encoder library version as an integer:
573    /// `MAJOR_VERSION * 1000000 + MINOR_VERSION * 1000 + PATCH_VERSION`.
574    /// For example, version 1.2.3 would return 1002003.
575    pub fn JxlEncoderVersion() -> u32;
576
577    /// Creates an instance of `JxlEncoder` and initializes it.
578    ///
579    /// # Parameters
580    /// - `memory_manager`: Custom allocator function. It may be `NULL`. The memory
581    ///   manager will be copied internally. If `NULL`, the default allocator will be used.
582    ///   See [`crate::common::memory_manager`] for details.
583    ///
584    /// # Returns
585    /// - `NULL` if the instance cannot be allocated or initialized.
586    /// - Pointer to initialized [`JxlEncoder`] otherwise.
587    pub fn JxlEncoderCreate(memory_manager: *const JxlMemoryManager) -> *mut JxlEncoder;
588
589    /// Re-initializes a [`JxlEncoder`] instance, so it can be re-used for encoding
590    /// another image. All state and settings are reset as if the object was
591    /// newly created with [`JxlEncoderCreate`], but the memory manager is kept.
592    ///
593    /// # Parameters
594    /// - `enc`: Instance to be re-initialized.
595    pub fn JxlEncoderReset(enc: *mut JxlEncoder);
596
597    /// Deinitializes and frees a [`JxlEncoder`] instance.
598    ///
599    /// # Parameters
600    /// - `enc`: Instance to be cleaned up and deallocated.
601    pub fn JxlEncoderDestroy(enc: *mut JxlEncoder);
602
603    /// Sets the color management system (CMS) that will be used for color conversion
604    /// (if applicable) during encoding. May only be set before starting encoding. If
605    /// left unset, the default CMS implementation will be used.
606    ///
607    /// # Parameters
608    /// - `enc`: Encoder object.
609    /// - `cms`: Structure representing a CMS implementation. See [`JxlCmsInterface`] for more details.
610    pub fn JxlEncoderSetCms(enc: *mut JxlEncoder, cms: JxlCmsInterface);
611
612    /// Set the parallel runner for multithreading. May only be set before starting
613    /// encoding.
614    ///
615    /// # Parameters
616    /// - `enc`: Encoder object.
617    /// - `parallel_runner`: Function pointer to runner for multithreading. It may
618    ///   be `NULL` to use the default, single-threaded, runner. A multithreaded
619    ///   runner should be set to reach fast performance.
620    /// - `parallel_runner_opaque`: Opaque pointer for `parallel_runner`.
621    ///
622    /// # Returns
623    /// - `JxlEncoderStatus::Success` if the runner was set.
624    /// - `JxlEncoderStatus::Error` otherwise (the previous runner remains set).
625    pub fn JxlEncoderSetParallelRunner(
626        enc: *mut JxlEncoder,
627        parallel_runner: JxlParallelRunner,
628        parallel_runner_opaque: *mut c_void,
629    ) -> JxlEncoderStatus;
630
631    /// Get the (last) error code in case [`JxlEncoderStatus::Error`] was returned.
632    ///
633    /// # Parameters
634    /// - `enc`: Encoder object.
635    ///
636    /// # Returns
637    /// The [`JxlEncoderError`] that caused the (last) [`JxlEncoderStatus::Error`] to be returned.
638    pub fn JxlEncoderGetError(enc: *mut JxlEncoder) -> JxlEncoderError;
639
640    /// Encodes a JPEG XL file using the available bytes. `*avail_out` indicates how
641    /// many output bytes are available, and `*next_out` points to the input bytes.
642    /// `*avail_out` will be decremented by the amount of bytes that have been
643    /// processed by the encoder and `*next_out` will be incremented by the same
644    /// amount, so `*next_out` will now point at the amount of `*avail_out` unprocessed
645    /// bytes.
646    ///
647    /// The returned status indicates whether the encoder needs more output bytes.
648    /// When the return value is not [`JxlEncoderStatus::Error`] or [`JxlEncoderStatus::Success`], the
649    /// encoding requires more [`JxlEncoderProcessOutput`] calls to continue.
650    ///
651    /// The caller must guarantee that `*avail_out >= 32` when calling
652    /// [`JxlEncoderProcessOutput`]; otherwise, [`JxlEncoderStatus::NeedMoreOutput`] will
653    /// be returned. It is guaranteed that, if `*avail_out >= 32`, at least one byte of
654    /// output will be written.
655    ///
656    /// This encodes the frames and/or boxes added so far. If the last frame or last
657    /// box has been added, [`JxlEncoderCloseInput`], [`JxlEncoderCloseFrames`]
658    /// and/or [`JxlEncoderCloseBoxes`] must be called before the next
659    /// [`JxlEncoderProcessOutput`] call, or the codestream won't be encoded
660    /// correctly.
661    ///
662    /// # Parameters
663    /// - `enc`: Encoder object.
664    /// - `next_out`: Pointer to next bytes to write to.
665    /// - `avail_out`: Amount of bytes available starting from `*next_out`.
666    ///
667    /// # Returns
668    /// - [`JxlEncoderStatus::Success`] when encoding finished and all events handled.
669    /// - [`JxlEncoderStatus::Error`] when encoding failed, e.g. invalid input.
670    /// - [`JxlEncoderStatus::NeedMoreOutput`] more output buffer is necessary.
671    pub fn JxlEncoderProcessOutput(
672        enc: *mut JxlEncoder,
673        next_out: *mut *mut u8,
674        avail_out: *mut usize,
675    ) -> JxlEncoderStatus;
676
677    /// Sets the frame information for this frame to the encoder. This includes
678    /// animation information such as frame duration to store in the frame header.
679    /// The frame header fields represent the frame as passed to the encoder, but not
680    /// necessarily the exact values as they will be encoded file format: the encoder
681    /// could change crop and blending options of a frame for more efficient encoding
682    /// or introduce additional internal frames. Animation duration and time code
683    /// information is not altered since those are immutable metadata of the frame.
684    ///
685    /// It is not required to use this function, however if `have_animation` is set
686    /// to true in the basic info, then this function should be used to set the
687    /// time duration of this individual frame. By default individual frames have a
688    /// time duration of 0, making them form a composite still. See [`JxlFrameHeader`]
689    /// for more information.
690    ///
691    /// This information is stored in the [`JxlEncoderFrameSettings`] and so is used
692    /// for any frame encoded with these [`JxlEncoderFrameSettings`]. It is ok to
693    /// change between [`JxlEncoderAddImageFrame`] calls, each added image frame
694    /// will have the frame header that was set in the options at the time of calling
695    /// [`JxlEncoderAddImageFrame`].
696    ///
697    /// The `is_last` and `name_length` fields of the [`JxlFrameHeader`] are ignored,
698    /// use [`JxlEncoderCloseFrames`] to indicate last frame, and [`JxlEncoderSetFrameName`]
699    /// to indicate the name and its length instead.
700    /// Calling this function will clear any name that was previously set with [`JxlEncoderSetFrameName`].
701    ///
702    /// # Parameters
703    /// - `frame_settings`: set of options and metadata for this frame. Also
704    ///   includes reference to the encoder object.
705    /// - `frame_header`: frame header data to set. Object owned by the caller and
706    ///   does not need to be kept in memory, its information is copied internally.
707    ///
708    /// # Returns
709    /// - [`JxlEncoderStatus::Success`] on success
710    /// - [`JxlEncoderStatus::Error`] on error
711    pub fn JxlEncoderSetFrameHeader(
712        frame_settings: *mut JxlEncoderFrameSettings,
713        frame_header: *const JxlFrameHeader,
714    ) -> JxlEncoderStatus;
715
716    /// Sets blend info of an extra channel. The blend info of extra channels is set
717    /// separately from that of the color channels, the color channels are set with
718    /// [`JxlEncoderSetFrameHeader`].
719    ///
720    /// # Parameters
721    /// - `frame_settings`: set of options and metadata for this frame. Also
722    ///   includes reference to the encoder object.
723    /// - `index`: index of the extra channel to use.
724    /// - `blend_info`: blend info to set for the extra channel.
725    ///
726    /// # Returns
727    /// - [`JxlEncoderStatus::Success`] on success.
728    /// - [`JxlEncoderStatus::Error`] on error.
729    pub fn JxlEncoderSetExtraChannelBlendInfo(
730        frame_settings: *mut JxlEncoderFrameSettings,
731        index: usize,
732        blend_info: *const JxlBlendInfo,
733    ) -> JxlEncoderStatus;
734
735    /// Sets the name of the animation frame. This function is optional, frames are
736    /// not required to have a name. This setting is a part of the frame header, and
737    /// the same principles as for [`JxlEncoderSetFrameHeader`] apply. The
738    /// `name_length` field of [`JxlFrameHeader`] is ignored by the encoder, this
739    /// function determines the name length instead as the length in bytes of the C
740    /// string.
741    ///
742    /// The maximum possible name length is 1071 bytes (excluding terminating null
743    /// character).
744    ///
745    /// Calling [`JxlEncoderSetFrameHeader`] clears any name that was
746    /// previously set.
747    ///
748    /// # Parameters
749    /// - `frame_settings`: set of options and metadata for this frame. Also
750    ///   includes reference to the encoder object.
751    /// - `frame_name`: name of the next frame to be encoded, as a UTF-8 encoded C
752    ///   string (zero terminated). Owned by the caller, and copied internally.
753    ///
754    /// # Returns
755    /// - [`JxlEncoderStatus::Success`] on success
756    /// - [`JxlEncoderStatus::Error`] on error
757    pub fn JxlEncoderSetFrameName(
758        frame_settings: *mut JxlEncoderFrameSettings,
759        frame_name: *const u8,
760    ) -> JxlEncoderStatus;
761
762    /// Sets the bit depth of the input buffer.
763    ///
764    /// For float pixel formats, only the default [`JxlBitDepthType::FromPixelFormat`]
765    /// setting is allowed, while for unsigned pixel formats,
766    /// [`JxlBitDepthType::FromCodestream`] setting is also allowed. See the comment
767    /// on [`JxlEncoderAddImageFrame`] for the effects of the bit depth setting.
768    ///
769    /// # Parameters
770    /// - `frame_settings`: Set of options and metadata for this frame. Also
771    ///   includes reference to the encoder object.
772    /// - `bit_depth`: The bit depth setting of the pixel input.
773    ///
774    /// # Returns
775    /// - [`JxlEncoderStatus::Success`] on success.
776    /// - [`JxlEncoderStatus::Error`] on error.
777    pub fn JxlEncoderSetFrameBitDepth(
778        frame_settings: *mut JxlEncoderFrameSettings,
779        bit_depth: *const JxlBitDepth,
780    ) -> JxlEncoderStatus;
781
782    /// Sets the buffer to read JPEG encoded bytes from for the next frame to encode.
783    ///
784    /// If [`JxlEncoderSetBasicInfo`] has not yet been called, calling
785    /// [`JxlEncoderAddJPEGFrame`] will implicitly call it with the parameters of
786    /// the added JPEG frame.
787    ///
788    /// If [`JxlEncoderSetColorEncoding`] or [`JxlEncoderSetICCProfile`] has not
789    /// yet been called, calling [`JxlEncoderAddJPEGFrame`] will implicitly call it
790    /// with the parameters of the added JPEG frame.
791    ///
792    /// If the encoder is set to store JPEG reconstruction metadata using [`JxlEncoderStoreJPEGMetadata`]
793    /// and a single JPEG frame is added, it will be possible to losslessly reconstruct the JPEG codestream.
794    ///
795    /// If this is the last frame, [`JxlEncoderCloseInput`] or [`JxlEncoderCloseFrames`] must be called before the next
796    /// [`JxlEncoderProcessOutput`] call.
797    ///
798    /// Note, this can only be used to add JPEG frames for lossless compression. To
799    /// encode with lossy compression, the JPEG must be decoded manually and a pixel
800    /// buffer added using [`JxlEncoderAddImageFrame`].
801    ///
802    /// # Parameters
803    /// - `frame_settings`: set of options and metadata for this frame. Also
804    ///   includes reference to the encoder object.
805    /// - `buffer`: bytes to read JPEG from. Owned by the caller and its contents
806    ///   are copied internally.
807    /// - `size`: size of buffer in bytes.
808    ///
809    /// # Returns
810    /// - [`JxlEncoderStatus::Success`] on success
811    /// - [`JxlEncoderStatus::Error`] on error
812    pub fn JxlEncoderAddJPEGFrame(
813        options: *const JxlEncoderFrameSettings,
814        buffer: *const u8,
815        size: usize,
816    ) -> JxlEncoderStatus;
817
818    /// Sets the buffer to read pixels from for the next image to encode. Must call
819    /// [`JxlEncoderSetBasicInfo`] before [`JxlEncoderAddImageFrame`].
820    ///
821    /// Currently only some data types for pixel formats are supported:
822    /// - [`JxlDataType::Uint8`], with range 0..255
823    /// - [`JxlDataType::Uint16`], with range 0..65535
824    /// - [`JxlDataType::Float16`], with nominal range 0..1
825    /// - [`JxlDataType::Float`], with nominal range 0..1
826    ///
827    /// Note: the sample data type in `pixel_format` is allowed to be different from
828    /// what is described in the [`JxlBasicInfo`]. The type in `pixel_format`,
829    /// together with an optional [`JxlBitDepth`] parameter set by [`JxlEncoderSetFrameBitDepth`]
830    /// describes the format of the uncompressed pixel buffer. The `bits_per_sample` and `exponent_bits_per_sample`
831    /// in the [`JxlBasicInfo`] describes what will actually be encoded in the JPEG XL
832    /// codestream. For example, to encode a 12-bit image, you would set
833    /// `bits_per_sample` to 12, while the input frame buffer can be in the following
834    /// formats:
835    /// - if pixel format is in [`JxlDataType::Uint16`] with default bit depth setting
836    ///   (i.e. [`JxlBitDepthType::FromPixelFormat`]), input sample values are
837    ///   rescaled to 16-bit, i.e. multiplied by 65535/4095;
838    /// - if pixel format is in [`JxlDataType::Uint16`] with [`JxlBitDepthType::FromCodestream`] bit depth setting,
839    ///   input sample values are provided unscaled;
840    /// - if pixel format is in [`JxlDataType::Float`], input sample values are
841    ///   rescaled to 0..1, i.e. multiplied by 1.0/4095.0. While it is allowed, it is
842    ///   obviously not recommended to use a `pixel_format` with lower precision than
843    ///   what is specified in the [`JxlBasicInfo`].
844    ///
845    /// We support interleaved channels as described by the [`JxlPixelFormat`]:
846    /// - single-channel data, e.g. grayscale
847    /// - single-channel + alpha
848    /// - trichromatic, e.g. RGB
849    /// - trichromatic + alpha
850    ///
851    /// Extra channels not handled here need to be set by [`JxlEncoderSetExtraChannelBuffer`].
852    /// If the image has alpha, and alpha is not passed here, it will implicitly be
853    /// set to all-opaque (an alpha value of 1.0 everywhere).
854    ///
855    /// The pixels are assumed to be encoded in the original profile that is set with
856    /// [`JxlEncoderSetColorEncoding`] or [`JxlEncoderSetICCProfile`]. If none of
857    /// these functions were used, the pixels are assumed to be nonlinear sRGB for
858    /// integer data types ([`JxlDataType::Uint8`], [`JxlDataType::Uint16`]), and linear
859    /// sRGB for floating point data types ([`JxlDataType::Float16`], [`JxlDataType::Float`]).
860    ///
861    /// Sample values in floating-point pixel formats are allowed to be outside the
862    /// nominal range, e.g. to represent out-of-sRGB-gamut colors in the
863    /// `uses_original_profile=false` case. They are however not allowed to be NaN or
864    /// +-infinity.
865    ///
866    /// If this is the last frame, [`JxlEncoderCloseInput`] or [`JxlEncoderCloseFrames`] must be called before the next
867    /// [`JxlEncoderProcessOutput`] call.
868    ///
869    /// # Parameters
870    /// - `frame_settings`: set of options and metadata for this frame. Also
871    ///   includes reference to the encoder object.
872    /// - `pixel_format`: format for pixels. Object owned by the caller and its
873    ///   contents are copied internally.
874    /// - `buffer`: buffer type to input the pixel data from. Owned by the caller
875    ///   and its contents are copied internally.
876    /// - `size`: size of buffer in bytes. This size should match what is implied
877    ///   by the frame dimensions and the pixel format.
878    ///
879    /// # Returns
880    /// - [`JxlEncoderStatus::Success`] on success
881    /// - [`JxlEncoderStatus::Error`] on error
882    pub fn JxlEncoderAddImageFrame(
883        options: *const JxlEncoderFrameSettings,
884        pixel_format: *const JxlPixelFormat,
885        buffer: *const c_void,
886        size: usize,
887    ) -> JxlEncoderStatus;
888
889    /// Sets the output processor for the encoder. This processor determines how the
890    /// encoder will handle buffering, writing, seeking (if supported), and
891    /// setting a finalized position during the encoding process.
892    ///
893    /// This should not be used when using [`JxlEncoderProcessOutput`].
894    ///
895    /// # Parameters
896    /// - `enc`: Encoder object.
897    /// - `output_processor`: The struct containing the callbacks for managing
898    ///   output.
899    ///
900    /// # Returns
901    /// - [`JxlEncoderStatus::Success`] on success.
902    /// - [`JxlEncoderStatus::Error`] on error.
903    pub fn JxlEncoderSetOutputProcessor(
904        enc: *mut JxlEncoder,
905        output_processor: JxlEncoderOutputProcessor,
906    ) -> JxlEncoderStatus;
907
908    /// Flushes any buffered input in the encoder, ensuring that all available input
909    /// data has been processed and written to the output.
910    ///
911    /// This function can only be used after [`JxlEncoderSetOutputProcessor`].
912    /// Before making the last call to [`JxlEncoderFlushInput`], users should call
913    /// [`JxlEncoderCloseInput`] to signal the end of input data.
914    ///
915    /// This should not be used when using [`JxlEncoderProcessOutput`].
916    ///
917    /// # Parameters
918    /// - `enc`: Encoder object.
919    ///
920    /// # Returns
921    /// - [`JxlEncoderStatus::Success`] on success.
922    /// - [`JxlEncoderStatus::Error`] on error.
923    pub fn JxlEncoderFlushInput(enc: *mut JxlEncoder) -> JxlEncoderStatus;
924
925    /// Adds a frame to the encoder using a chunked input source.
926    ///
927    /// This function gives a way to encode a frame by providing pixel data in a
928    /// chunked or streaming manner, which can be especially useful when dealing with
929    /// large images that may not fit entirely in memory or when trying to optimize
930    /// memory usage. The input data is provided through callbacks defined in the
931    /// [`JxlChunkedFrameInputSource`] struct. Once the frame data has been
932    /// completely retrieved, this function will flush the input and close it if it
933    /// is the last frame.
934    ///
935    /// # Parameters
936    /// - `frame_settings`: Set of options and metadata for this frame. Also
937    ///   includes reference to the encoder object.
938    /// - `is_last_frame`: Indicates if this is the last frame.
939    /// - `chunked_frame_input`: Struct providing callback methods for retrieving
940    ///   pixel data in chunks.
941    ///
942    /// # Returns
943    /// Returns a status indicating the success or failure of adding the
944    /// frame.
945    pub fn JxlEncoderAddChunkedFrame(
946        frame_settings: *const JxlEncoderFrameSettings,
947        is_last_frame: JxlBool,
948        chunked_frame_input: JxlChunkedFrameInputSource,
949    ) -> JxlEncoderStatus;
950
951    /// Sets the buffer to read pixels from for an extra channel at a given index.
952    /// The index must be smaller than the `num_extra_channels` in the associated
953    /// [`JxlBasicInfo`]. Must call [`JxlEncoderSetExtraChannelInfo`] before
954    /// [`JxlEncoderSetExtraChannelBuffer`].
955    ///
956    /// TODO: mention what data types in pixel formats are supported.
957    ///
958    /// It is required to call this function for every extra channel, except for the
959    /// alpha channel if that was already set through [`JxlEncoderAddImageFrame`].
960    ///
961    /// # Parameters
962    /// - `frame_settings`: Set of options and metadata for this frame. Also
963    ///   includes reference to the encoder object.
964    /// - `pixel_format`: Format for pixels. Object owned by the caller and its
965    ///   contents are copied internally. The `num_channels` value is ignored, since the
966    ///   number of channels for an extra channel is always assumed to be one.
967    /// - `buffer`: Buffer type to input the pixel data from. Owned by the caller
968    ///   and its contents are copied internally.
969    /// - `size`: Size of buffer in bytes. This size should match what is implied
970    ///   by the frame dimensions and the pixel format.
971    /// - `index`: Index of the extra channel to use.
972    ///
973    /// # Returns
974    /// - [`JxlEncoderStatus::Success`] on success.
975    /// - [`JxlEncoderStatus::Error`] on error.
976    pub fn JxlEncoderSetExtraChannelBuffer(
977        frame_settings: *const JxlEncoderFrameSettings,
978        pixel_format: *const JxlPixelFormat,
979        buffer: *const c_void,
980        size: usize,
981        index: u32,
982    ) -> JxlEncoderStatus;
983
984    /// Adds a metadata box to the file format. [`JxlEncoderProcessOutput`] must be
985    /// used to effectively write the box to the output. [`JxlEncoderUseBoxes`] must
986    /// be enabled before using this function.
987    ///
988    /// Boxes allow inserting application-specific data and metadata (Exif, XML/XMP,
989    /// JUMBF and user defined boxes).
990    ///
991    /// The box format follows ISO BMFF and shares features and box types with other
992    /// image and video formats, including the Exif, XML and JUMBF boxes. The box
993    /// format for JPEG XL is specified in ISO/IEC 18181-2.
994    ///
995    /// Boxes in general don't contain other boxes inside, except a JUMBF superbox.
996    /// Boxes follow each other sequentially and are byte-aligned. If the container
997    /// format is used, the JXL stream consists of concatenated boxes.
998    /// It is also possible to use a direct codestream without boxes, but in that
999    /// case metadata cannot be added.
1000    ///
1001    /// Each box generally has the following byte structure in the file:
1002    /// - 4 bytes: box size including box header (Big endian. If set to 0, an
1003    ///   8-byte 64-bit size follows instead).
1004    /// - 4 bytes: type, e.g. "JXL " for the signature box, "jxlc" for a codestream
1005    ///   box.
1006    /// - N bytes: box contents.
1007    ///
1008    /// Only the box contents are provided to the contents argument of this function,
1009    /// the encoder encodes the size header itself. Most boxes are written
1010    /// automatically by the encoder as needed ("JXL ", "ftyp", "jxll", "jxlc",
1011    /// "jxlp", "jxli", "jbrd"), and this function only needs to be called to add
1012    /// optional metadata when encoding from pixels (using [`JxlEncoderAddImageFrame`]).
1013    /// When recompressing JPEG files (using [`JxlEncoderAddJPEGFrame`]),
1014    /// if the input JPEG contains EXIF, XMP or JUMBF
1015    /// metadata, the corresponding boxes are already added automatically.
1016    ///
1017    /// Box types are given by 4 characters. The following boxes can be added with
1018    /// this function:
1019    /// - "Exif": a box with EXIF metadata, can be added by libjxl users, or is
1020    ///   automatically added when needed for JPEG reconstruction. The contents of
1021    ///   this box must be prepended by a 4-byte tiff header offset, which may
1022    ///   be 4 zero bytes in case the tiff header follows immediately.
1023    ///   The EXIF metadata must be in sync with what is encoded in the JPEG XL
1024    ///   codestream, specifically the image orientation. While this is not
1025    ///   recommended in practice, in case of conflicting metadata, the JPEG XL
1026    ///   codestream takes precedence.
1027    /// - "xml ": a box with XML data, in particular XMP metadata, can be added by
1028    ///   libjxl users, or is automatically added when needed for JPEG reconstruction
1029    /// - "jumb": a JUMBF superbox, which can contain boxes with different types of
1030    ///   metadata inside. This box type can be added by the encoder transparently,
1031    ///   and other libraries to create and handle JUMBF content exist.
1032    /// - Application-specific boxes. Their typename should not begin with "jxl" or
1033    ///   "JXL" or conflict with other existing typenames, and they should be
1034    ///   registered with MP4RA (mp4ra.org).
1035    ///
1036    /// These boxes can be stored uncompressed or Brotli-compressed (using a "brob"
1037    /// box), depending on the `compress_box` parameter.
1038    ///
1039    /// # Parameters
1040    /// - `enc`: encoder object.
1041    /// - `box_type`: the box type, e.g. "Exif" for EXIF metadata, "xml " for XMP or
1042    ///   IPTC metadata, "jumb" for JUMBF metadata.
1043    /// - `contents`: the full contents of the box, for example EXIF
1044    ///   data. ISO BMFF box header must not be included, only the contents. Owned by
1045    ///   the caller and its contents are copied internally.
1046    /// - `size`: size of the box contents.
1047    /// - `compress_box`: Whether to compress this box as a "brob" box. Requires
1048    ///   Brotli support.
1049    ///
1050    /// # Returns
1051    /// - [`JxlEncoderStatus::Success`] on success.
1052    /// - [`JxlEncoderStatus::Error`] on error, such as
1053    ///   when using this function without [`JxlEncoderUseContainer`], or adding a box
1054    ///   type that would result in an invalid file format.
1055    pub fn JxlEncoderAddBox(
1056        enc: *mut JxlEncoder,
1057        box_type: *const JxlBoxType,
1058        contents: *const u8,
1059        size: usize,
1060        compress_box: JxlBool,
1061    ) -> JxlEncoderStatus;
1062
1063    /// Indicates the intention to add metadata boxes. This allows [`JxlEncoderAddBox`] to be used.
1064    /// When using this function, then it is required to use [`JxlEncoderCloseBoxes`] at the end.
1065    ///
1066    /// By default the encoder assumes no metadata boxes will be added.
1067    ///
1068    /// This setting can only be set at the beginning, before encoding starts.
1069    ///
1070    /// # Parameters
1071    /// - `enc`: encoder object.
1072    pub fn JxlEncoderUseBoxes(enc: *mut JxlEncoder) -> JxlEncoderStatus;
1073
1074    /// Declares that no further boxes will be added with [`JxlEncoderAddBox`].
1075    /// This function must be called after the last box is added so the encoder knows
1076    /// the stream will be finished. It is not necessary to use this function if
1077    /// [`JxlEncoderUseBoxes`] is not used. Further frames may still be added.
1078    ///
1079    /// Must be called between [`JxlEncoderAddBox`] of the last box
1080    /// and the next call to [`JxlEncoderProcessOutput`], or [`JxlEncoderProcessOutput`]
1081    /// won't output the last box correctly.
1082    ///
1083    /// NOTE: if you don't need to close frames and boxes at separate times, you can
1084    /// use [`JxlEncoderCloseInput`] instead to close both at once.
1085    ///
1086    /// # Parameters
1087    /// - `enc`: encoder object.
1088    pub fn JxlEncoderCloseBoxes(enc: *mut JxlEncoder);
1089
1090    /// Declares that no frames will be added and [`JxlEncoderAddImageFrame`] and
1091    /// [`JxlEncoderAddJPEGFrame`] won't be called anymore. Further metadata boxes
1092    /// may still be added. This function or [`JxlEncoderCloseInput`] must be called
1093    /// after adding the last frame and the next call to
1094    /// [`JxlEncoderProcessOutput`], or the frame won't be properly marked as last.
1095    ///
1096    /// NOTE: if you don't need to close frames and boxes at separate times, you can
1097    /// use [`JxlEncoderCloseInput`] instead to close both at once.
1098    ///
1099    /// # Parameters
1100    /// - `enc`: encoder object.
1101    pub fn JxlEncoderCloseFrames(enc: *mut JxlEncoder);
1102
1103    /// Closes any input to the encoder, equivalent to calling [`JxlEncoderCloseFrames`]
1104    /// as well as calling [`JxlEncoderCloseBoxes`] if needed. No further input of any kind
1105    /// may be given to the encoder, but further [`JxlEncoderProcessOutput`] calls should be
1106    /// done to create the final output.
1107    ///
1108    /// The requirements of both [`JxlEncoderCloseFrames`] and [`JxlEncoderCloseBoxes`] apply
1109    /// to this function. Either this function or the other two must be called after the final
1110    /// frame and/or box, and the next [`JxlEncoderProcessOutput`] call, or the codestream won't
1111    /// be encoded correctly.
1112    ///
1113    /// # Parameters
1114    /// - `enc`: encoder object.
1115    pub fn JxlEncoderCloseInput(enc: *mut JxlEncoder);
1116
1117    /// Sets the original color encoding of the image encoded by this encoder. This
1118    /// is an alternative to [`JxlEncoderSetICCProfile`] and only one of these two
1119    /// must be used. This one sets the color encoding as a [`JxlColorEncoding`],
1120    /// while the other sets it as ICC binary data. Must be called after
1121    /// [`JxlEncoderSetBasicInfo`].
1122    ///
1123    /// # Parameters
1124    /// - `enc`: encoder object.
1125    /// - `color`: color encoding. Object owned by the caller and its contents are
1126    ///   copied internally.
1127    ///
1128    /// # Returns
1129    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1130    /// - [`JxlEncoderStatus::Error`] otherwise.
1131    pub fn JxlEncoderSetColorEncoding(
1132        enc: *mut JxlEncoder,
1133        color: *const JxlColorEncoding,
1134    ) -> JxlEncoderStatus;
1135
1136    /// Sets the original color encoding of the image encoded by this encoder as an
1137    /// ICC color profile. This is an alternative to [`JxlEncoderSetColorEncoding`]
1138    /// and only one of these two must be used. This one sets the color encoding as
1139    /// ICC binary data, while the other defines it as a [`JxlColorEncoding`]. Must
1140    /// be called after [`JxlEncoderSetBasicInfo`].
1141    ///
1142    /// # Parameters
1143    /// - `enc`: encoder object.
1144    /// - `icc_profile`: bytes of the original ICC profile
1145    /// - `size`: size of the `icc_profile` buffer in bytes
1146    ///
1147    /// # Returns
1148    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1149    /// - [`JxlEncoderStatus::Error`] otherwise.
1150    pub fn JxlEncoderSetICCProfile(
1151        enc: *mut JxlEncoder,
1152        icc_profile: *const u8,
1153        size: usize,
1154    ) -> JxlEncoderStatus;
1155
1156    /// Initializes a [`JxlBasicInfo`] struct to default values.
1157    /// For forwards-compatibility, this function has to be called before values
1158    /// are assigned to the struct fields.
1159    /// The default values correspond to an 8-bit RGB image, no alpha or any
1160    /// other extra channels.
1161    ///
1162    /// # Parameters
1163    /// - `info`: global image metadata. Object owned by the caller.
1164    pub fn JxlEncoderInitBasicInfo(info: *mut JxlBasicInfo);
1165
1166    /// Initializes a [`JxlFrameHeader`] struct to default values.
1167    /// For forwards-compatibility, this function has to be called before values
1168    /// are assigned to the struct fields.
1169    /// The default values correspond to a frame with no animation duration and the
1170    /// 'replace' blend mode. After using this function, animation duration must
1171    /// be set, and for composite still, blend settings must be set.
1172    ///
1173    /// # Parameters
1174    /// - `frame_header`: frame metadata. Object owned by the caller.
1175    pub fn JxlEncoderInitFrameHeader(frame_header: *mut JxlFrameHeader);
1176
1177    /// Initializes a [`JxlBlendInfo`] struct to default values.
1178    /// For forwards-compatibility, this function has to be called before values
1179    /// are assigned to the struct fields.
1180    ///
1181    /// # Parameters
1182    /// - `blend_info`: blending info. Object owned by the caller.
1183    pub fn JxlEncoderInitBlendInfo(blend_info: *mut JxlBlendInfo);
1184
1185    /// Sets the global metadata of the image encoded by this encoder.
1186    ///
1187    /// If the [`JxlBasicInfo`] contains information of extra channels beyond an
1188    /// alpha channel, then [`JxlEncoderSetExtraChannelInfo`] must be called between
1189    /// [`JxlEncoderSetBasicInfo`] and [`JxlEncoderAddImageFrame`]. In order to
1190    /// indicate extra channels, the value of `info.num_extra_channels` should be set
1191    /// to the number of extra channels, also counting the alpha channel if present.
1192    ///
1193    /// # Parameters
1194    /// - `enc`: encoder object.
1195    /// - `info`: global image metadata. Object owned by the caller and its
1196    ///   contents are copied internally.
1197    ///
1198    /// # Returns
1199    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1200    /// - [`JxlEncoderStatus::Error`] otherwise.
1201    pub fn JxlEncoderSetBasicInfo(
1202        enc: *mut JxlEncoder,
1203        info: *const JxlBasicInfo,
1204    ) -> JxlEncoderStatus;
1205
1206    /// Sets the upsampling method the decoder will use in case there are frames
1207    /// with [`JxlEncoderFrameSettingsSetOption`] set. This is useful in combination
1208    /// with the [`JxlEncoderFrameSettingsSetOption`] option, to control
1209    /// the type of upsampling that will be used.
1210    ///
1211    /// # Parameters
1212    /// - `enc`: encoder object.
1213    /// - `factor`: upsampling factor to configure (1, 2, 4 or 8; for 1 this
1214    ///   function has no effect at all)
1215    /// - `mode`: upsampling mode to use for this upsampling:
1216    ///   - `-1`: default (good for photographic images, no signaling overhead)
1217    ///   - `0`: nearest neighbor (good for pixel art)
1218    ///   - `1`: 'pixel dots' (same as NN for 2x, diamond-shaped 'pixel dots' for 4x/8x)
1219    ///
1220    /// # Returns
1221    /// - [`JxlEncoderStatus::Success`] if the operation was successful,
1222    /// - [`JxlEncoderStatus::Error`] otherwise
1223    pub fn JxlEncoderSetUpsamplingMode(
1224        enc: *mut JxlEncoder,
1225        factor: i64,
1226        mode: i64,
1227    ) -> JxlEncoderStatus;
1228
1229    /// Initializes a [`JxlExtraChannelInfo`] struct to default values.
1230    /// For forwards-compatibility, this function has to be called before values
1231    /// are assigned to the struct fields.
1232    /// The default values correspond to an 8-bit channel of the provided type.
1233    ///
1234    /// # Parameters
1235    /// - `channel_type`: type of the extra channel.
1236    /// - `info`: global extra channel metadata. Object owned by the caller and its
1237    ///   contents are copied internally.
1238    pub fn JxlEncoderInitExtraChannelInfo(
1239        channel_type: JxlExtraChannelType,
1240        info: *mut JxlExtraChannelInfo,
1241    );
1242
1243    /// Sets information for the extra channel at the given index. The index
1244    /// must be smaller than `num_extra_channels` in the associated [`JxlBasicInfo`].
1245    ///
1246    /// # Parameters
1247    /// - `enc`: encoder object.
1248    /// - `index`: index of the extra channel to set.
1249    /// - `info`: global extra channel metadata. Object owned by the caller and its
1250    ///   contents are copied internally.
1251    ///
1252    /// # Returns
1253    /// - [`JxlEncoderStatus::Success`] on success.
1254    /// - [`JxlEncoderStatus::Error`] on error.
1255    pub fn JxlEncoderSetExtraChannelInfo(
1256        enc: *mut JxlEncoder,
1257        index: usize,
1258        info: *const JxlExtraChannelInfo,
1259    ) -> JxlEncoderStatus;
1260
1261    /// Sets the name for the extra channel at the given index in UTF-8. The index
1262    /// must be smaller than the `num_extra_channels` in the associated [`JxlBasicInfo`].
1263    ///
1264    /// TODO: remove size parameter for consistency with [`JxlEncoderSetFrameName`]
1265    ///
1266    /// # Parameters
1267    /// - `enc`: encoder object.
1268    /// - `index`: index of the extra channel to set.
1269    /// - `name`: buffer with the name of the extra channel.
1270    /// - `size`: size of the name buffer in bytes, not counting the terminating
1271    ///   character.
1272    ///
1273    /// # Returns
1274    /// - [`JxlEncoderStatus::Success`] on success.
1275    /// - [`JxlEncoderStatus::Error`] on error.
1276    pub fn JxlEncoderSetExtraChannelName(
1277        enc: *mut JxlEncoder,
1278        index: usize,
1279        name: *const u8,
1280        size: usize,
1281    ) -> JxlEncoderStatus;
1282
1283    /// Sets a frame-specific option of integer type to the encoder options.
1284    /// The [`JxlEncoderFrameSettingId`] argument determines which option is set.
1285    ///
1286    /// # Parameters
1287    /// - `frame_settings`: set of options and metadata for this frame. Also
1288    ///   includes reference to the encoder object.
1289    /// - `option`: ID of the option to set.
1290    /// - `value`: Integer value to set for this option.
1291    ///
1292    /// # Returns
1293    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1294    /// - [`JxlEncoderStatus::Error`] in case of an error, such as invalid or unknown option id, or
1295    ///   invalid integer value for the given option. If an error is returned, the
1296    ///   state of the [`JxlEncoderFrameSettings`] object is still valid and is the same as before
1297    ///   this function was called.
1298    pub fn JxlEncoderFrameSettingsSetOption(
1299        frame_settings: *mut JxlEncoderFrameSettings,
1300        option: JxlEncoderFrameSettingId,
1301        value: i64,
1302    ) -> JxlEncoderStatus;
1303
1304    /// Sets a frame-specific option of float type to the encoder options.
1305    /// The [`JxlEncoderFrameSettingId`] argument determines which option is set.
1306    ///
1307    /// # Parameters
1308    /// - `frame_settings`: set of options and metadata for this frame. Also
1309    ///   includes reference to the encoder object.
1310    /// - `option`: ID of the option to set.
1311    /// - `value`: Float value to set for this option.
1312    ///
1313    /// # Returns
1314    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1315    /// - [`JxlEncoderStatus::Error`] in case of an error, such as invalid or unknown option id, or
1316    ///   invalid float value for the given option. If an error is returned, the
1317    ///   state of the [`JxlEncoderFrameSettings`] object is still valid and is the same as before
1318    ///   this function was called.
1319    pub fn JxlEncoderFrameSettingsSetFloatOption(
1320        frame_settings: *mut JxlEncoderFrameSettings,
1321        option: JxlEncoderFrameSettingId,
1322        value: f32,
1323    ) -> JxlEncoderStatus;
1324
1325    /// Forces the encoder to use the box-based container format (BMFF) even
1326    /// when not necessary.
1327    ///
1328    /// When using [`JxlEncoderUseBoxes`], [`JxlEncoderStoreJPEGMetadata`] or
1329    /// [`JxlEncoderSetCodestreamLevel`] with level 10, the encoder will automatically
1330    /// also use the container format, it is not necessary to use
1331    /// [`JxlEncoderUseContainer`] for those use cases.
1332    ///
1333    /// By default this setting is disabled.
1334    ///
1335    /// This setting can only be set at the beginning, before encoding starts.
1336    ///
1337    /// # Parameters
1338    /// - `enc`: encoder object.
1339    /// - `use_container`: true if the encoder should always output the JPEG XL
1340    ///   container format, false to only output it when necessary.
1341    ///
1342    /// # Returns
1343    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1344    /// - [`JxlEncoderStatus::Error`] otherwise.
1345    pub fn JxlEncoderUseContainer(enc: *mut JxlEncoder, use_container: JxlBool)
1346        -> JxlEncoderStatus;
1347
1348    /// Configure the encoder to store JPEG reconstruction metadata in the JPEG XL
1349    /// container.
1350    ///
1351    /// If this is set to true and a single JPEG frame is added, it will be
1352    /// possible to losslessly reconstruct the JPEG codestream.
1353    ///
1354    /// This setting can only be set at the beginning, before encoding starts.
1355    ///
1356    /// # Parameters
1357    /// - `enc`: encoder object.
1358    /// - `store_jpeg_metadata`: true if the encoder should store JPEG metadata.
1359    ///
1360    /// # Returns
1361    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1362    /// - [`JxlEncoderStatus::Error`] otherwise.
1363    pub fn JxlEncoderStoreJPEGMetadata(
1364        enc: *mut JxlEncoder,
1365        store_jpeg_metadata: JxlBool,
1366    ) -> JxlEncoderStatus;
1367
1368    /// Sets the feature level of the JPEG XL codestream. Valid values are 5 and
1369    /// 10, or -1 (to choose automatically). Using the minimum required level, or
1370    /// level 5 in most cases, is recommended for compatibility with all decoders.
1371    ///
1372    /// Level 5: for end-user image delivery, this level is the most widely
1373    /// supported level by image decoders and the recommended level to use unless a
1374    /// level 10 feature is absolutely necessary. Supports a maximum resolution
1375    /// 268435456 pixels total with a maximum width or height of 262144 pixels,
1376    /// maximum 16-bit color channel depth, maximum 120 frames per second for
1377    /// animation, maximum ICC color profile size of 4 MiB, it allows all color
1378    /// models and extra channel types except CMYK and the [`JxlExtraChannelType::Black`]
1379    /// extra channel, and a maximum of 4 extra channels in addition to the 3 color
1380    /// channels. It also sets boundaries to certain internally used coding tools.
1381    ///
1382    /// Level 10: this level removes or increases the bounds of most of the level
1383    /// 5 limitations, allows CMYK color and up to 32 bits per color channel, but
1384    /// may be less widely supported.
1385    ///
1386    /// The default value is -1. This means the encoder will automatically choose
1387    /// between level 5 and level 10 based on what information is inside the [`JxlBasicInfo`]
1388    /// structure. Do note that some level 10 features, particularly those used by animated
1389    /// JPEG XL codestreams, might require level 10, even though the [`JxlBasicInfo`] only
1390    /// suggests level 5. In this case, the level must be explicitly set to 10, otherwise
1391    /// the encoder will return an error. The encoder will restrict internal encoding choices
1392    /// to those compatible with the level setting.
1393    ///
1394    /// This setting can only be set at the beginning, before encoding starts.
1395    ///
1396    /// # Parameters
1397    /// - `enc`: encoder object.
1398    /// - `level`: the level value to set, must be -1, 5, or 10.
1399    ///
1400    /// # Returns
1401    /// - [`JxlEncoderStatus::Success`] if the operation was successful.
1402    /// - [`JxlEncoderStatus::Error`] otherwise.
1403    pub fn JxlEncoderSetCodestreamLevel(enc: *mut JxlEncoder, level: i32) -> JxlEncoderStatus;
1404
1405    /// Returns the codestream level required to support the currently configured
1406    /// settings and basic info. This function can only be used at the beginning,
1407    /// before encoding starts, but after setting basic info.
1408    ///
1409    /// This does not support per-frame settings, only global configuration, such as
1410    /// the image dimensions, that are known at the time of writing the header of
1411    /// the JPEG XL file.
1412    ///
1413    /// If this returns 5, nothing needs to be done and the codestream can be
1414    /// compatible with any decoder. If this returns 10, [`JxlEncoderSetCodestreamLevel`]
1415    /// has to be used to set the codestream level to 10, or the encoder can be configured
1416    /// differently to allow using the more compatible level 5.
1417    ///
1418    /// # Parameters
1419    /// - `enc`: encoder object.
1420    ///
1421    /// # Returns
1422    /// - `-1`: if no level can support the configuration (e.g. image dimensions
1423    ///   larger than even level 10 supports),
1424    /// - `5`: if level 5 is supported,
1425    /// - `10`: if setting the codestream level to 10 is required.
1426    pub fn JxlEncoderGetRequiredCodestreamLevel(enc: *mut JxlEncoder) -> i32;
1427
1428    /// Enables lossless encoding.
1429    ///
1430    /// This is not an option like the others on itself, but rather while enabled it
1431    /// overrides a set of existing options (such as distance, modular mode and
1432    /// color transform) that enables bit-for-bit lossless encoding.
1433    ///
1434    /// When disabled, those options are not overridden, but since those options
1435    /// could still have been manually set to a combination that operates losslessly,
1436    /// using this function with lossless set to [`JxlBool::False`] does not
1437    /// guarantee lossy encoding, though the default set of options is lossy.
1438    ///
1439    /// # Parameters
1440    /// - `frame_settings`: set of options and metadata for this frame. Also
1441    ///   includes reference to the encoder object.
1442    /// - `lossless`: whether to override options for lossless mode
1443    ///
1444    /// # Returns
1445    /// - [`JxlEncoderStatus::Success`] if the operation was successful, [`JxlEncoderStatus::Error`] otherwise.
1446    pub fn JxlEncoderSetFrameLossless(
1447        frame_settings: *mut JxlEncoderFrameSettings,
1448        lossless: JxlBool,
1449    ) -> JxlEncoderStatus;
1450
1451    /// Sets the distance level for lossy compression: target max butteraugli
1452    /// distance, lower = higher quality. Range: 0 .. 25.
1453    /// 0.0 = mathematically lossless (however, use [`JxlEncoderSetFrameLossless`]
1454    /// instead to use true lossless, as setting distance to 0 alone is not the only
1455    /// requirement). 1.0 = visually lossless. Recommended range: 0.5 .. 3.0. Default
1456    /// value: 1.0.
1457    ///
1458    /// # Parameters
1459    /// - `frame_settings`: set of options and metadata for this frame. Also
1460    ///   includes reference to the encoder object.
1461    /// - `distance`: the distance value to set.
1462    ///
1463    /// # Returns
1464    /// - [`JxlEncoderStatus::Success`] if the operation was successful, [`JxlEncoderStatus::Error`] otherwise.
1465    pub fn JxlEncoderSetFrameDistance(
1466        options: *mut JxlEncoderFrameSettings,
1467        distance: f32,
1468    ) -> JxlEncoderStatus;
1469
1470    /// Sets the distance level for lossy compression of extra channels.
1471    /// The distance is as in [`JxlEncoderSetFrameDistance`] (lower = higher
1472    /// quality). If not set, or if set to the special value -1, the distance that
1473    /// was set with [`JxlEncoderSetFrameDistance`] will be used.
1474    ///
1475    /// # Parameters
1476    /// - `frame_settings`: set of options and metadata for this frame. Also
1477    ///   includes reference to the encoder object.
1478    /// - `index`: index of the extra channel to set a distance value for.
1479    /// - `distance`: the distance value to set.
1480    ///
1481    /// # Returns
1482    /// - [`JxlEncoderStatus::Success`] if the operation was successful, [`JxlEncoderStatus::Error`] otherwise.
1483    pub fn JxlEncoderSetExtraChannelDistance(
1484        frame_settings: *mut JxlEncoderFrameSettings,
1485        index: usize,
1486        distance: f32,
1487    ) -> JxlEncoderStatus;
1488
1489    /// Maps JPEG-style quality factor to distance.
1490    ///
1491    /// This function takes in input a JPEG-style quality factor `quality` and
1492    /// produces as output a `distance` value suitable to be used with
1493    /// [`JxlEncoderSetFrameDistance`] and [`JxlEncoderSetExtraChannelDistance`].
1494    ///
1495    /// The `distance` value influences the level of compression, with lower values
1496    /// indicating higher quality:
1497    /// - 0.0 implies lossless compression (however, note that calling
1498    ///   [`JxlEncoderSetFrameLossless`] is required).
1499    /// - 1.0 represents a visually lossy compression, which is also the default
1500    ///   setting.
1501    ///
1502    /// The `quality` parameter, ranging up to 100, is inversely related to
1503    /// `distance`:
1504    /// - A `quality` of 100.0 maps to a `distance` of 0.0 (lossless).
1505    /// - A `quality` of 90.0 corresponds to a `distance` of 1.0.
1506    ///
1507    /// Recommended Range:
1508    /// - `distance`: 0.5 to 3.0.
1509    /// - corresponding `quality`: approximately 96 to 68.
1510    ///
1511    /// Allowed Range:
1512    /// - `distance`: 0.0 to 25.0.
1513    /// - corresponding `quality`: 100.0 to 0.0.
1514    ///
1515    /// Note: the `quality` parameter has no consistent psychovisual meaning
1516    /// across different codecs and libraries. Using the mapping defined by
1517    /// [`JxlEncoderDistanceFromQuality`] will result in a visual quality roughly
1518    /// equivalent to what would be obtained with `libjpeg-turbo` with the same
1519    /// `quality` parameter, but that is by no means guaranteed; do not assume that
1520    /// the same quality value will result in similar file sizes and image quality
1521    /// across different codecs.
1522    pub fn JxlEncoderDistanceFromQuality(quality: f32) -> f32;
1523
1524    /// Create a new set of encoder options, with all values initially copied from
1525    /// the `source` options, or set to default if `source` is `NULL`.
1526    ///
1527    /// The returned pointer is an opaque struct tied to the encoder and it will be
1528    /// deallocated by the encoder when [`JxlEncoderDestroy`] is called. For
1529    /// functions taking both a [`JxlEncoder`] and a [`JxlEncoderFrameSettings`],
1530    /// only [`JxlEncoderFrameSettings`] created with this function for the same
1531    /// encoder instance can be used.
1532    ///
1533    /// # Parameters
1534    /// - `enc`: encoder object.
1535    /// - `source`: source options to copy initial values from, or `NULL` to get
1536    ///   defaults initialized to defaults.
1537    ///
1538    /// # Returns
1539    /// The opaque struct pointer identifying a new set of encoder options.
1540    pub fn JxlEncoderFrameSettingsCreate(
1541        enc: *mut JxlEncoder,
1542        source: *const JxlEncoderFrameSettings,
1543    ) -> *mut JxlEncoderFrameSettings;
1544
1545    /// Sets a color encoding to be sRGB.
1546    ///
1547    /// # Parameters
1548    /// - `color_encoding`: color encoding instance.
1549    /// - `is_gray`: whether the color encoding should be gray scale or color.
1550    pub fn JxlColorEncodingSetToSRGB(color_encoding: *mut JxlColorEncoding, is_gray: JxlBool);
1551
1552    /// Sets a color encoding to be linear sRGB.
1553    ///
1554    /// # Parameters
1555    /// - `color_encoding`: [color encoding instance](JxlColorEncoding).
1556    /// - `is_gray`: whether the color encoding should be gray scale or color.
1557    pub fn JxlColorEncodingSetToLinearSRGB(color_encoding: *mut JxlColorEncoding, is_gray: JxlBool);
1558
1559    /// Enables usage of expert options.
1560    ///
1561    /// At the moment, the only expert option is setting an effort value of 11,
1562    /// which gives the best compression for pixel-lossless modes but is very slow.
1563    ///
1564    /// # Parameters
1565    /// - `enc`: encoder object.
1566    pub fn JxlEncoderAllowExpertOptions(enc: *mut JxlEncoder);
1567
1568    /// Sets the given debug image callback that will be used by the encoder to
1569    /// output various debug images during encoding.
1570    ///
1571    /// This only has any effect if the encoder was compiled with the appropriate
1572    /// debug build flags.
1573    ///
1574    /// # Parameters
1575    /// - `frame_settings`: set of options and metadata for this frame. Also
1576    ///   includes reference to the encoder object.
1577    /// - `callback`: used to return the debug image.
1578    /// - `opaque`: user supplied parameter to the image callback.
1579    pub fn JxlEncoderSetDebugImageCallback(
1580        frame_settings: *mut JxlEncoderFrameSettings,
1581        callback: JxlDebugImageCallback,
1582        opaque: *mut c_void,
1583    );
1584
1585    /// Sets the given stats object for gathering various statistics during encoding.
1586    ///
1587    /// This only has any effect if the encoder was compiled with the appropriate
1588    /// debug build flags.
1589    ///
1590    /// # Parameters
1591    /// - `frame_settings`: set of options and metadata for this frame. Also
1592    ///   includes reference to the encoder object.
1593    /// - `stats`: object that can be used to query the gathered stats (created
1594    ///   by [`JxlEncoderStatsCreate`])
1595    pub fn JxlEncoderCollectStats(
1596        frame_settings: *mut JxlEncoderFrameSettings,
1597        stats: *mut JxlEncoderStats,
1598    );
1599}