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}