jpegxl_sys\metadata/
codestream_header.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//! Definitions of structs and enums for the metadata from the JPEG XL
19//! codestream headers (signature, metadata, preview dimensions, ...), excluding
20//! color encoding which is in [`crate::color::color_encoding`].
21
22use crate::common::types::JxlBool;
23
24#[cfg(doc)]
25use crate::{
26    color::color_encoding::{JxlColorEncoding, JxlColorSpace},
27    decode::{
28        JxlColorProfileTarget, JxlDecoderGetExtraChannelBlendInfo, JxlDecoderGetExtraChannelInfo,
29    },
30    encoder::encode::{JxlEncoderCloseFrames, JxlEncoderSetFrameName},
31};
32
33/// Image orientation metadata.
34///
35/// Values 1..8 match the EXIF definitions.
36/// The name indicates the operation to perform to transform from the encoded
37/// image to the display image.
38#[repr(C)]
39#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
40pub enum JxlOrientation {
41    Identity = 1,
42    FlipHorizontal = 2,
43    Rotate180 = 3,
44    FlipVertical = 4,
45    Transpose = 5,
46    Rotate90Cw = 6,
47    AntiTranspose = 7,
48    Rotate90Ccw = 8,
49}
50
51/// Given type of an extra channel.
52#[repr(C)]
53#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
54pub enum JxlExtraChannelType {
55    Alpha,
56    Depth,
57    SpotColor,
58    SelectionMask,
59    Black,
60    Cfa,
61    Thermal,
62    Reserved0,
63    Reserved1,
64    Reserved2,
65    Reserved3,
66    Reserved4,
67    Reserved5,
68    Reserved6,
69    Reserved7,
70    Unknown,
71    Optional,
72}
73
74/// The codestream preview header
75#[repr(C)]
76#[derive(Debug, Clone)]
77pub struct JxlPreviewHeader {
78    /// Preview width in pixels
79    pub xsize: u32,
80    /// Preview height in pixels
81    pub ysize: u32,
82}
83
84/// The codestream animation header, optionally present in the beginning of
85/// the codestream, and if it is it applies to all animation frames, unlike
86/// [`JxlFrameHeader`] which applies to an individual frame.
87#[repr(C)]
88#[derive(Debug, Clone)]
89pub struct JxlAnimationHeader {
90    /// Numerator of ticks per second of a single animation frame time unit
91    pub tps_numerator: u32,
92
93    /// Denominator of ticks per second of a single animation frame time unit
94    pub tps_denominator: u32,
95
96    /// Amount of animation loops, or 0 to repeat infinitely
97    pub num_loops: u32,
98
99    /// Whether animation time codes are present at animation frames in the
100    /// codestream
101    pub have_timecodes: JxlBool,
102}
103
104/// Basic image information. This information is available from the file
105/// signature and first part of the codestream header.
106#[repr(C)]
107#[derive(Debug, Clone)]
108pub struct JxlBasicInfo {
109    /// Whether the codestream is embedded in the container format. If true,
110    /// metadata information and extensions may be available in addition to the
111    /// codestream.
112    pub have_container: JxlBool,
113
114    /// Width of the image in pixels, before applying orientation.
115    pub xsize: u32,
116
117    /// Height of the image in pixels, before applying orientation.
118    pub ysize: u32,
119
120    /// Original image color channel bit depth.
121    pub bits_per_sample: u32,
122
123    /// Original image color channel floating point exponent bits, or 0 if they
124    /// are unsigned integer. For example, if the original data is half-precision
125    /// (binary16) floating point, `bits_per_sample` is 16 and
126    /// `exponent_bits_per_sample` is 5, and so on for other floating point
127    /// precisions.
128    pub exponent_bits_per_sample: u32,
129
130    /// Upper bound on the intensity level present in the image in nits. For
131    /// unsigned integer pixel encodings, this is the brightness of the largest
132    /// representable value. The image does not necessarily contain a pixel
133    /// actually this bright. An encoder is allowed to set 255 for SDR images
134    /// without computing a histogram.
135    /// Leaving this set to its default of 0 lets libjxl choose a sensible default
136    /// value based on the color encoding.
137    pub intensity_target: f32,
138
139    /// Lower bound on the intensity level present in the image. This may be
140    /// loose, i.e. lower than the actual darkest pixel. When tone mapping, a
141    /// decoder will map `[min_nits, intensity_target]` to the display range.
142    pub min_nits: f32,
143
144    /// See the description of [`Self::linear_below`].
145    pub relative_to_max_display: JxlBool,
146
147    /// The tone mapping will leave unchanged (linear mapping) any pixels whose
148    /// brightness is strictly below this. The interpretation depends on
149    /// `relative_to_max_display`. If true, this is a ratio \[0, 1\] of the maximum
150    /// display brightness \[nits\], otherwise an absolute brightness \[nits\].
151    pub linear_below: f32,
152
153    /// Whether the data in the codestream is encoded in the original color
154    /// profile that is attached to the codestream metadata header, or is
155    /// encoded in an internally supported absolute color space (which the decoder
156    /// can always convert to linear or non-linear sRGB or to XYB). If the original
157    /// profile is used, the decoder outputs pixel data in the color space matching
158    /// that profile, but doesn't convert it to any other color space. If the
159    /// original profile is not used, the decoder only outputs the data as sRGB
160    /// (linear if outputting to floating point, nonlinear with standard sRGB
161    /// transfer function if outputting to unsigned integers) but will not convert
162    /// it to to the original color profile. The decoder also does not convert to
163    /// the target display color profile. To convert the pixel data produced by
164    /// the decoder to the original color profile, one of the `JxlDecoderGetColor*`
165    /// functions needs to be called with
166    /// [`JxlColorProfileTarget::Data`] to get the color profile of the decoder
167    /// output, and then an external CMS can be used for conversion. Note that for
168    /// lossy compression, this should be set to false for most use cases, and if
169    /// needed, the image should be converted to the original color profile after
170    /// decoding, as described above.
171    pub uses_original_profile: JxlBool,
172
173    /// Indicates a preview image exists near the beginning of the codestream.
174    /// The preview itself or its dimensions are not included in the basic info.
175    pub have_preview: JxlBool,
176
177    /// Indicates animation frames exist in the codestream. The animation
178    /// information is not included in the basic info.
179    pub have_animation: JxlBool,
180
181    /// Image orientation, value 1-8 matching the values used by JEITA CP-3451C
182    /// (Exif version 2.3).
183    pub orientation: JxlOrientation,
184
185    /// Number of color channels encoded in the image, this is either 1 for
186    /// grayscale data, or 3 for colored data. This count does not include
187    /// the alpha channel or other extra channels. To check presence of an alpha
188    /// channel, such as in the case of RGBA color, check `alpha_bits != 0`.
189    /// If and only if this is `1`, the [`JxlColorSpace`] in the [`JxlColorEncoding`] is
190    /// [`JxlColorSpace::Gray`].
191    pub num_color_channels: u32,
192
193    /// Number of additional image channels. This includes the main alpha channel,
194    /// but can also include additional channels such as depth, additional alpha
195    /// channels, spot colors, and so on. Information about the extra channels
196    /// can be queried with [`JxlDecoderGetExtraChannelInfo`]. The main alpha
197    /// channel, if it exists, also has its information available in the
198    /// `alpha_bits`, `alpha_exponent_bits` and `alpha_premultiplied` fields in this
199    /// [`JxlBasicInfo`].
200    pub num_extra_channels: u32,
201
202    /// Bit depth of the encoded alpha channel, or 0 if there is no alpha channel.
203    /// If present, matches the `alpha_bits` value of the [`JxlExtraChannelInfo`]
204    /// associated with this alpha channel.
205    pub alpha_bits: u32,
206
207    /// Alpha channel floating point exponent bits, or 0 if they are unsigned. If
208    /// present, matches the `alpha_bits` value of the [`JxlExtraChannelInfo`] associated
209    /// with this alpha channel. integer.
210    pub alpha_exponent_bits: u32,
211
212    /// Whether the alpha channel is premultiplied. Only used if there is a main
213    /// alpha channel. Matches the `alpha_premultiplied` value of the
214    /// [`JxlExtraChannelInfo`] associated with this alpha channel.
215    pub alpha_premultiplied: JxlBool,
216
217    /// Dimensions of encoded preview image, only used if `have_preview` is
218    /// [`JxlBool::True`].
219    pub preview: JxlPreviewHeader,
220
221    /// Animation header with global animation properties for all frames, only
222    /// used if `have_animation` is [`JxlBool::True`].
223    pub animation: JxlAnimationHeader,
224
225    /// Intrinsic width of the image.
226    /// The intrinsic size can be different from the actual size in pixels
227    /// (as given by xsize and ysize) and it denotes the recommended dimensions
228    /// for displaying the image, i.e. applications are advised to resample the
229    /// decoded image to the intrinsic dimensions.
230    pub intrinsic_xsize: u32,
231
232    /// Intrinsic height of the image.
233    /// The intrinsic size can be different from the actual size in pixels
234    /// (as given by xsize and ysize) and it denotes the recommended dimensions
235    /// for displaying the image, i.e. applications are advised to resample the
236    /// decoded image to the intrinsic dimensions.
237    pub intrinsic_ysize: u32,
238
239    /// Padding for forwards-compatibility, in case more fields are exposed
240    /// in a future version of the library.
241    _padding: [u8; 100],
242}
243
244/// Information for a single extra channel.
245#[repr(C)]
246#[derive(Debug, Clone)]
247pub struct JxlExtraChannelInfo {
248    /// Given type of an extra channel.
249    pub r#type: JxlExtraChannelType,
250
251    /// Total bits per sample for this channel.
252    pub bits_per_sample: u32,
253
254    /// Floating point exponent bits per channel, or 0 if they are unsigned
255    /// integer.
256    pub exponent_bits_per_sample: u32,
257
258    /// The exponent the channel is downsampled by on each axis.
259    /// TODO(lode): expand this comment to match the JPEG XL specification,
260    /// specify how to upscale, how to round the size computation, and to which
261    /// extra channels this field applies.
262    pub dim_shift: u32,
263
264    /// Length of the extra channel name in bytes, or 0 if no name.
265    /// Excludes null termination character.
266    pub name_length: u32,
267
268    /// Whether alpha channel uses premultiplied alpha. Only applicable if
269    /// type is [`JxlExtraChannelType::Alpha`].
270    pub alpha_premultiplied: JxlBool,
271
272    /// Spot color of the current spot channel in linear RGBA. Only applicable if
273    /// type is [`JxlExtraChannelType::SpotColor`].
274    pub spot_color: [f32; 4],
275
276    /// Only applicable if type is [`JxlExtraChannelType::Cfa`].
277    /// TODO(lode): add comment about the meaning of this field.
278    pub cfa_channel: u32,
279}
280/// Extensions in the codestream header.
281#[repr(C)]
282#[derive(Debug, Clone)]
283pub struct JxlHeaderExtensions {
284    /// Extension bits.
285    pub extensions: u64,
286}
287/// Frame blend modes.
288/// When decoding, if coalescing is enabled (default), this can be ignored.
289#[repr(C)]
290#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
291pub enum JxlBlendMode {
292    Replace = 0,
293    Add = 1,
294    Blend = 2,
295    MULADD = 3,
296    MUL = 4,
297}
298
299/// The information about blending the color channels or a single extra channel.
300/// When decoding, if coalescing is enabled (default), this can be ignored and
301/// the blend mode is considered to be [`JxlBlendMode::Replace`].
302/// When encoding, these settings apply to the pixel data given to the encoder.
303#[repr(C)]
304#[derive(Debug, Clone)]
305pub struct JxlBlendInfo {
306    /// Blend mode.
307    pub blendmode: JxlBlendMode,
308    /// Reference frame ID to use as the 'bottom' layer (0-3).
309    pub source: u32,
310    /// Which extra channel to use as the 'alpha' channel for blend modes
311    /// [`JxlBlendMode::Blend`] and [`JxlBlendMode::MULADD`].
312    pub alpha: u32,
313    /// Clamp values to \[0,1\] for the purpose of blending.
314    pub clamp: JxlBool,
315}
316
317/// The information about layers.
318/// When decoding, if coalescing is enabled (default), this can be ignored.
319/// When encoding, these settings apply to the pixel data given to the encoder,
320/// the encoder could choose an internal representation that differs.
321#[repr(C)]
322#[derive(Debug, Clone)]
323pub struct JxlLayerInfo {
324    /// Whether cropping is applied for this frame. When decoding, if false,
325    /// [`Self::crop_x0`] and [`Self::crop_y0`] are set to zero, and [`Self::xsize`] and [`Self::ysize`] to the main
326    /// image dimensions. When encoding and this is false, those fields are
327    /// ignored. When decoding, if coalescing is enabled (default), this is always
328    /// false, regardless of the internal encoding in the JPEG XL codestream.
329    pub have_crop: JxlBool,
330
331    /// Horizontal offset of the frame (can be negative).
332    pub crop_x0: i32,
333
334    /// Vertical offset of the frame (can be negative).
335    pub crop_y0: i32,
336
337    /// Width of the frame (number of columns).
338    pub xsize: u32,
339
340    /// Height of the frame (number of rows).
341    pub ysize: u32,
342
343    /// The blending info for the color channels. Blending info for extra channels
344    /// has to be retrieved separately using [`JxlDecoderGetExtraChannelBlendInfo`].
345    pub blend_info: JxlBlendInfo,
346
347    /// After blending, save the frame as reference frame with this ID (0-3).
348    /// Special case: if the frame duration is nonzero, ID 0 means "will not be
349    /// referenced in the future". This value is not used for the last frame.
350    /// When encoding, ID 3 is reserved to frames that are generated internally by
351    /// the encoder, and should not be used by applications.
352    pub save_as_reference: u32,
353}
354
355///The header of one displayed frame or non-coalesced layer.
356#[repr(C)]
357#[derive(Debug, Clone)]
358pub struct JxlFrameHeader {
359    /// How long to wait after rendering in ticks. The duration in seconds of a
360    /// tick is given by [`JxlAnimationHeader::tps_numerator`] and [`JxlAnimationHeader::tps_denominator`] in
361    /// [`JxlAnimationHeader`].
362    pub duration: u32,
363
364    /// SMPTE timecode of the current frame in form 0xHHMMSSFF, or 0. The bits are
365    /// interpreted from most-significant to least-significant as hour, minute,
366    /// second, and frame. If timecode is nonzero, it is strictly larger than that
367    /// of a previous frame with nonzero duration. These values are only available
368    /// if `have_timecodes` in [`JxlAnimationHeader`] is [`JxlBool::True`].
369    /// This value is only used if `have_timecodes` in [`JxlAnimationHeader`] is
370    /// [`JxlBool::True`].
371    pub timecode: u32,
372
373    /// Length of the frame name in bytes, or 0 if no name.
374    /// Excludes null termination character. This value is set by the decoder.
375    /// For the encoder, this value is ignored and [`JxlEncoderSetFrameName`] is
376    /// used instead to set the name and the length.
377    pub name_length: u32,
378
379    /** Indicates this is the last animation frame. This value is set by the
380     * decoder to indicate no further frames follow. For the encoder, it is not
381     * required to set this value and it is ignored, [`JxlEncoderCloseFrames`] is
382     * used to indicate the last frame to the encoder instead.
383     */
384    pub is_last: JxlBool,
385    /** Information about the layer in case of no coalescing.
386     */
387    pub layer_info: JxlLayerInfo,
388}