1use libheif_sys as lh;
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4pub enum Chroma {
5 C420,
6 C422,
7 C444,
8}
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11pub enum RgbChroma {
12 C444,
13 Rgb,
15 Rgba,
16 HdrRgbBe,
17 HdrRgbaBe,
18 HdrRgbLe,
19 HdrRgbaLe,
20}
21
22#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
23#[non_exhaustive]
24pub enum ColorSpace {
25 Undefined,
26 YCbCr(Chroma),
27 Rgb(RgbChroma),
28 Monochrome,
29 #[cfg(feature = "v1_19")]
30 #[cfg_attr(
35 feature = "v1_23",
36 deprecated(since = "2.8.0", note = "use [ColorSpace::Custom] instead.")
37 )]
38 NonVisual,
39 #[cfg(feature = "v1_23")]
40 Custom,
45 #[cfg(feature = "v1_23")]
46 FilterArray,
49}
50
51impl ColorSpace {
52 pub(crate) fn from_libheif(
53 color_space: lh::heif_colorspace,
54 chroma: lh::heif_chroma,
55 ) -> Option<Self> {
56 match color_space {
57 lh::heif_colorspace_heif_colorspace_undefined => Some(ColorSpace::Undefined),
58 lh::heif_colorspace_heif_colorspace_monochrome => Some(ColorSpace::Monochrome),
59 lh::heif_colorspace_heif_colorspace_YCbCr => match chroma {
60 lh::heif_chroma_heif_chroma_420 => Some(ColorSpace::YCbCr(Chroma::C420)),
61 lh::heif_chroma_heif_chroma_422 => Some(ColorSpace::YCbCr(Chroma::C422)),
62 lh::heif_chroma_heif_chroma_444 => Some(ColorSpace::YCbCr(Chroma::C444)),
63 _ => None,
64 },
65 lh::heif_colorspace_heif_colorspace_RGB => match chroma {
66 lh::heif_chroma_heif_chroma_444 => Some(ColorSpace::Rgb(RgbChroma::C444)),
67 lh::heif_chroma_heif_chroma_interleaved_RGB => {
68 Some(ColorSpace::Rgb(RgbChroma::Rgb))
69 }
70 lh::heif_chroma_heif_chroma_interleaved_RGBA => {
71 Some(ColorSpace::Rgb(RgbChroma::Rgba))
72 }
73 lh::heif_chroma_heif_chroma_interleaved_RRGGBB_BE => {
74 Some(ColorSpace::Rgb(RgbChroma::HdrRgbBe))
75 }
76 lh::heif_chroma_heif_chroma_interleaved_RRGGBB_LE => {
77 Some(ColorSpace::Rgb(RgbChroma::HdrRgbLe))
78 }
79 lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_BE => {
80 Some(ColorSpace::Rgb(RgbChroma::HdrRgbaBe))
81 }
82 lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_LE => {
83 Some(ColorSpace::Rgb(RgbChroma::HdrRgbaLe))
84 }
85 _ => None,
86 },
87 #[cfg(all(feature = "v1_19", not(feature = "v1_23")))]
88 lh::heif_colorspace_heif_colorspace_nonvisual => Some(ColorSpace::NonVisual),
89 #[cfg(feature = "v1_23")]
90 lh::heif_colorspace_heif_colorspace_custom => Some(ColorSpace::Custom),
91 #[cfg(feature = "v1_23")]
92 lh::heif_colorspace_heif_colorspace_filter_array => Some(ColorSpace::FilterArray),
93 _ => None,
94 }
95 }
96
97 pub(crate) fn heif_color_space(self) -> lh::heif_colorspace {
98 match self {
99 ColorSpace::YCbCr(_) => lh::heif_colorspace_heif_colorspace_YCbCr,
100 ColorSpace::Rgb(_) => lh::heif_colorspace_heif_colorspace_RGB,
101 ColorSpace::Monochrome => lh::heif_colorspace_heif_colorspace_monochrome,
102 ColorSpace::Undefined => lh::heif_colorspace_heif_colorspace_undefined,
103 #[cfg(all(feature = "v1_19", not(feature = "v1_23")))]
104 ColorSpace::NonVisual => lh::heif_colorspace_heif_colorspace_nonvisual,
105 #[cfg(feature = "v1_23")]
106 #[allow(deprecated)]
107 ColorSpace::NonVisual => lh::heif_colorspace_heif_colorspace_custom,
108 #[cfg(feature = "v1_23")]
109 ColorSpace::Custom => lh::heif_colorspace_heif_colorspace_custom,
110 #[cfg(feature = "v1_23")]
111 ColorSpace::FilterArray => lh::heif_colorspace_heif_colorspace_filter_array,
112 }
113 }
114
115 pub(crate) fn heif_chroma(self) -> lh::heif_chroma {
116 match self {
117 ColorSpace::YCbCr(chroma) => match chroma {
118 Chroma::C420 => lh::heif_chroma_heif_chroma_420,
119 Chroma::C422 => lh::heif_chroma_heif_chroma_422,
120 Chroma::C444 => lh::heif_chroma_heif_chroma_444,
121 },
122 ColorSpace::Rgb(chroma) => match chroma {
123 RgbChroma::C444 => lh::heif_chroma_heif_chroma_444,
124 RgbChroma::Rgb => lh::heif_chroma_heif_chroma_interleaved_RGB,
125 RgbChroma::Rgba => lh::heif_chroma_heif_chroma_interleaved_RGBA,
126 RgbChroma::HdrRgbBe => lh::heif_chroma_heif_chroma_interleaved_RRGGBB_BE,
127 RgbChroma::HdrRgbLe => lh::heif_chroma_heif_chroma_interleaved_RRGGBB_LE,
128 RgbChroma::HdrRgbaBe => lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_BE,
129 RgbChroma::HdrRgbaLe => lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_LE,
130 },
131 ColorSpace::Undefined => lh::heif_chroma_heif_chroma_undefined,
132 #[cfg(not(feature = "v1_23"))]
133 ColorSpace::Monochrome => lh::heif_chroma_heif_chroma_monochrome,
134 #[cfg(feature = "v1_23")]
135 ColorSpace::Monochrome => lh::heif_chroma_heif_chroma_planar,
136 #[cfg(all(feature = "v1_19", not(feature = "v1_23")))]
137 ColorSpace::NonVisual => lh::heif_chroma_heif_chroma_undefined,
138 #[cfg(feature = "v1_23")]
139 #[allow(deprecated)]
140 ColorSpace::NonVisual => lh::heif_chroma_heif_chroma_planar,
141 #[cfg(feature = "v1_23")]
142 ColorSpace::Custom => lh::heif_chroma_heif_chroma_planar,
143 #[cfg(feature = "v1_23")]
144 ColorSpace::FilterArray => lh::heif_chroma_heif_chroma_planar,
145 }
146 }
147}
148
149#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
150#[repr(C)]
151pub enum Channel {
152 Y = lh::heif_channel_heif_channel_Y as _,
153 Cb = lh::heif_channel_heif_channel_Cb as _,
154 Cr = lh::heif_channel_heif_channel_Cr as _,
155 R = lh::heif_channel_heif_channel_R as _,
156 G = lh::heif_channel_heif_channel_G as _,
157 B = lh::heif_channel_heif_channel_B as _,
158 Alpha = lh::heif_channel_heif_channel_Alpha as _,
159 Interleaved = lh::heif_channel_heif_channel_interleaved as _,
160 #[cfg(feature = "v1_19")]
161 FilterArray = lh::heif_channel_heif_channel_filter_array as _,
162 #[cfg(feature = "v1_19")]
163 Depth = lh::heif_channel_heif_channel_depth as _,
164 #[cfg(feature = "v1_19")]
165 Disparity = lh::heif_channel_heif_channel_disparity as _,
166 #[cfg(feature = "v1_23")]
167 Unknown = lh::heif_channel_heif_channel_unknown as _,
168}
169
170#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
171pub enum ReaderGrowStatus {
172 SizeReached = lh::heif_reader_grow_status_heif_reader_grow_status_size_reached as _,
173 Timeout = lh::heif_reader_grow_status_heif_reader_grow_status_timeout as _,
174 SizeBeyondEof = lh::heif_reader_grow_status_heif_reader_grow_status_size_beyond_eof as _,
175 #[cfg(feature = "v1_19")]
176 Error = lh::heif_reader_grow_status_heif_reader_grow_status_error as _,
177}
178
179#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
180#[repr(C)]
181pub enum FileTypeResult {
182 No = lh::heif_filetype_result_heif_filetype_no as _,
183 Supported = lh::heif_filetype_result_heif_filetype_yes_supported as _,
185 Unsupported = lh::heif_filetype_result_heif_filetype_yes_unsupported as _,
187 MayBe = lh::heif_filetype_result_heif_filetype_maybe as _,
189}
190
191#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
192#[repr(C)]
193pub enum ImageOrientation {
194 Normal = lh::heif_orientation_heif_orientation_normal as _,
195 FlipHorizontally = lh::heif_orientation_heif_orientation_flip_horizontally as _,
196 Rotate180 = lh::heif_orientation_heif_orientation_rotate_180 as _,
197 FlipVertically = lh::heif_orientation_heif_orientation_flip_vertically as _,
198 Rotate90CwThenFlipHorizontally =
199 lh::heif_orientation_heif_orientation_rotate_90_cw_then_flip_horizontally as _,
200 Rotate90Cw = lh::heif_orientation_heif_orientation_rotate_90_cw as _,
201 Rotate90CwThenFlipVertically =
202 lh::heif_orientation_heif_orientation_rotate_90_cw_then_flip_vertically as _,
203 Rotate270Cw = lh::heif_orientation_heif_orientation_rotate_270_cw as _,
204 Unknown,
206}
207
208#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
209#[non_exhaustive]
210#[repr(C)]
211pub enum ChromaDownsamplingAlgorithm {
212 NearestNeighbor =
213 lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_nearest_neighbor as _,
214 Average = lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_average as _,
215 SharpYuv = lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_sharp_yuv as _,
218}
219
220#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
221#[non_exhaustive]
222#[repr(C)]
223pub enum ChromaUpsamplingAlgorithm {
224 NearestNeighbor =
225 lh::heif_chroma_upsampling_algorithm_heif_chroma_upsampling_nearest_neighbor as _,
226 Bilinear = lh::heif_chroma_upsampling_algorithm_heif_chroma_upsampling_bilinear as _,
227}
228
229#[cfg(feature = "v1_20")]
230#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
231#[non_exhaustive]
232pub enum AlphaCompositionMode {
233 #[default]
234 None,
235 SolidColor {
236 background_rgb: [u16; 3],
237 },
238 Checkerboard {
239 background_rgb: [u16; 3],
240 secondary_background_rgb: [u16; 3],
241 square_size: u16,
242 },
243}
244
245#[cfg(feature = "v1_20")]
246impl AlphaCompositionMode {
247 pub(crate) fn from_libheif(
248 cc_options_ext: *const lh::heif_color_conversion_options_ext,
249 ) -> Self {
250 let cc_options_ext = unsafe { cc_options_ext.as_ref() };
251 let Some(cc_options_ext) = cc_options_ext else {
252 return Self::None;
253 };
254 match cc_options_ext.alpha_composition_mode {
255 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_none => {
256 AlphaCompositionMode::None
257 }
258 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_solid_color => {
259 AlphaCompositionMode::SolidColor {
260 background_rgb: [
261 cc_options_ext.background_red,
262 cc_options_ext.background_green,
263 cc_options_ext.background_blue,
264 ],
265 }
266 }
267 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_checkerboard => {
268 AlphaCompositionMode::Checkerboard {
269 background_rgb: [
270 cc_options_ext.background_red,
271 cc_options_ext.background_green,
272 cc_options_ext.background_blue,
273 ],
274 secondary_background_rgb: [
275 cc_options_ext.secondary_background_red,
276 cc_options_ext.secondary_background_green,
277 cc_options_ext.secondary_background_blue,
278 ],
279 square_size: cc_options_ext.checkerboard_square_size,
280 }
281 }
282 _ => AlphaCompositionMode::None,
283 }
284 }
285
286 pub(crate) fn fill_libheif_cc_options_ext(
287 &self,
288 cc_options_ext_ptr: *mut lh::heif_color_conversion_options_ext,
289 ) {
290 if let Some(cc_options_ext) = unsafe { cc_options_ext_ptr.as_mut() } {
291 match self {
292 AlphaCompositionMode::None => {
293 cc_options_ext.alpha_composition_mode =
294 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_none;
295 }
296 AlphaCompositionMode::SolidColor { background_rgb } => {
297 cc_options_ext.alpha_composition_mode =
298 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_solid_color;
299 cc_options_ext.background_red = background_rgb[0];
300 cc_options_ext.background_green = background_rgb[1];
301 cc_options_ext.background_blue = background_rgb[2];
302 }
303 AlphaCompositionMode::Checkerboard {
304 background_rgb,
305 secondary_background_rgb,
306 square_size,
307 } => {
308 cc_options_ext.alpha_composition_mode =
309 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_checkerboard;
310 cc_options_ext.background_red = background_rgb[0];
311 cc_options_ext.background_green = background_rgb[1];
312 cc_options_ext.background_blue = background_rgb[2];
313 cc_options_ext.secondary_background_red = secondary_background_rgb[0];
314 cc_options_ext.secondary_background_green = secondary_background_rgb[1];
315 cc_options_ext.secondary_background_blue = secondary_background_rgb[2];
316 cc_options_ext.checkerboard_square_size = *square_size;
317 }
318 }
319 }
320 }
321}