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,
14 Rgba,
15 HdrRgbBe,
16 HdrRgbaBe,
17 HdrRgbLe,
18 HdrRgbaLe,
19}
20
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22pub enum ColorSpace {
23 Undefined,
24 YCbCr(Chroma),
25 Rgb(RgbChroma),
26 Monochrome,
27 #[cfg(feature = "v1_19")]
29 NonVisual,
30}
31
32impl ColorSpace {
33 pub(crate) fn from_libheif(color_space: lh::heif_colorspace, chroma: lh::heif_chroma) -> Option<Self> {
34 match color_space {
35 lh::heif_colorspace_heif_colorspace_undefined => Some(ColorSpace::Undefined),
36 lh::heif_colorspace_heif_colorspace_monochrome => Some(ColorSpace::Monochrome),
37 lh::heif_colorspace_heif_colorspace_YCbCr => match chroma {
38 lh::heif_chroma_heif_chroma_420 => Some(ColorSpace::YCbCr(Chroma::C420)),
39 lh::heif_chroma_heif_chroma_422 => Some(ColorSpace::YCbCr(Chroma::C422)),
40 lh::heif_chroma_heif_chroma_444 => Some(ColorSpace::YCbCr(Chroma::C444)),
41 _ => None,
42 },
43 lh::heif_colorspace_heif_colorspace_RGB => match chroma {
44 lh::heif_chroma_heif_chroma_444 => Some(ColorSpace::Rgb(RgbChroma::C444)),
45 lh::heif_chroma_heif_chroma_interleaved_RGB => Some(ColorSpace::Rgb(RgbChroma::Rgb)),
46 lh::heif_chroma_heif_chroma_interleaved_RGBA => Some(ColorSpace::Rgb(RgbChroma::Rgba)),
47 lh::heif_chroma_heif_chroma_interleaved_RRGGBB_BE => Some(ColorSpace::Rgb(RgbChroma::HdrRgbBe)),
48 lh::heif_chroma_heif_chroma_interleaved_RRGGBB_LE => Some(ColorSpace::Rgb(RgbChroma::HdrRgbLe)),
49 lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_BE => Some(ColorSpace::Rgb(RgbChroma::HdrRgbaBe)),
50 lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_LE => Some(ColorSpace::Rgb(RgbChroma::HdrRgbaLe)),
51 _ => None,
52 },
53 #[cfg(feature = "v1_19")]
54 lh::heif_colorspace_heif_colorspace_nonvisual => Some(ColorSpace::NonVisual),
55 _ => None,
56 }
57 }
58
59 pub(crate) fn heif_color_space(self) -> lh::heif_colorspace {
60 match self {
61 ColorSpace::YCbCr(_) => lh::heif_colorspace_heif_colorspace_YCbCr,
62 ColorSpace::Rgb(_) => lh::heif_colorspace_heif_colorspace_RGB,
63 ColorSpace::Monochrome => lh::heif_colorspace_heif_colorspace_monochrome,
64 ColorSpace::Undefined => lh::heif_colorspace_heif_colorspace_undefined,
65 #[cfg(feature = "v1_19")]
66 ColorSpace::NonVisual => lh::heif_colorspace_heif_colorspace_nonvisual,
67 }
68 }
69
70 pub(crate) fn heif_chroma(self) -> lh::heif_chroma {
71 match self {
72 ColorSpace::YCbCr(chroma) => match chroma {
73 Chroma::C420 => lh::heif_chroma_heif_chroma_420,
74 Chroma::C422 => lh::heif_chroma_heif_chroma_422,
75 Chroma::C444 => lh::heif_chroma_heif_chroma_444,
76 },
77 ColorSpace::Rgb(chroma) => match chroma {
78 RgbChroma::C444 => lh::heif_chroma_heif_chroma_444,
79 RgbChroma::Rgb => lh::heif_chroma_heif_chroma_interleaved_RGB,
80 RgbChroma::Rgba => lh::heif_chroma_heif_chroma_interleaved_RGBA,
81 RgbChroma::HdrRgbBe => lh::heif_chroma_heif_chroma_interleaved_RRGGBB_BE,
82 RgbChroma::HdrRgbLe => lh::heif_chroma_heif_chroma_interleaved_RRGGBB_LE,
83 RgbChroma::HdrRgbaBe => lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_BE,
84 RgbChroma::HdrRgbaLe => lh::heif_chroma_heif_chroma_interleaved_RRGGBBAA_LE,
85 },
86 ColorSpace::Undefined => lh::heif_chroma_heif_chroma_undefined,
87 ColorSpace::Monochrome => lh::heif_chroma_heif_chroma_monochrome,
88 #[cfg(feature = "v1_19")]
89 ColorSpace::NonVisual => lh::heif_chroma_heif_chroma_undefined,
90 }
91 }
92}
93
94#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
95#[repr(C)]
96pub enum Channel {
97 Y = lh::heif_channel_heif_channel_Y as _,
98 Cb = lh::heif_channel_heif_channel_Cb as _,
99 Cr = lh::heif_channel_heif_channel_Cr as _,
100 R = lh::heif_channel_heif_channel_R as _,
101 G = lh::heif_channel_heif_channel_G as _,
102 B = lh::heif_channel_heif_channel_B as _,
103 Alpha = lh::heif_channel_heif_channel_Alpha as _,
104 Interleaved = lh::heif_channel_heif_channel_interleaved as _,
105 #[cfg(feature = "v1_19")]
106 FilterArray = lh::heif_channel_heif_channel_filter_array as _,
107 #[cfg(feature = "v1_19")]
108 Depth = lh::heif_channel_heif_channel_depth as _,
109 #[cfg(feature = "v1_19")]
110 Disparity = lh::heif_channel_heif_channel_disparity as _,
111}
112
113#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
114pub enum ReaderGrowStatus {
115 SizeReached = lh::heif_reader_grow_status_heif_reader_grow_status_size_reached as _,
116 Timeout = lh::heif_reader_grow_status_heif_reader_grow_status_timeout as _,
117 SizeBeyondEof = lh::heif_reader_grow_status_heif_reader_grow_status_size_beyond_eof as _,
118 #[cfg(feature = "v1_19")]
119 Error = lh::heif_reader_grow_status_heif_reader_grow_status_error as _,
120}
121
122#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
123#[repr(C)]
124pub enum FileTypeResult {
125 No = lh::heif_filetype_result_heif_filetype_no as _,
126 Supported = lh::heif_filetype_result_heif_filetype_yes_supported as _,
128 Unsupported = lh::heif_filetype_result_heif_filetype_yes_unsupported as _,
130 MayBe = lh::heif_filetype_result_heif_filetype_maybe as _,
132}
133
134#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
135#[repr(C)]
136pub enum ImageOrientation {
137 Normal = lh::heif_orientation_heif_orientation_normal as _,
138 FlipHorizontally = lh::heif_orientation_heif_orientation_flip_horizontally as _,
139 Rotate180 = lh::heif_orientation_heif_orientation_rotate_180 as _,
140 FlipVertically = lh::heif_orientation_heif_orientation_flip_vertically as _,
141 Rotate90CwThenFlipHorizontally = lh::heif_orientation_heif_orientation_rotate_90_cw_then_flip_horizontally as _,
142 Rotate90Cw = lh::heif_orientation_heif_orientation_rotate_90_cw as _,
143 Rotate90CwThenFlipVertically = lh::heif_orientation_heif_orientation_rotate_90_cw_then_flip_vertically as _,
144 Rotate270Cw = lh::heif_orientation_heif_orientation_rotate_270_cw as _,
145 Unknown,
147}
148
149#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
150#[non_exhaustive]
151#[repr(C)]
152pub enum ChromaDownsamplingAlgorithm {
153 NearestNeighbor = lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_nearest_neighbor as _,
154 Average = lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_average as _,
155 SharpYuv = lh::heif_chroma_downsampling_algorithm_heif_chroma_downsampling_sharp_yuv as _,
158}
159
160#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, enumn::N)]
161#[non_exhaustive]
162#[repr(C)]
163pub enum ChromaUpsamplingAlgorithm {
164 NearestNeighbor = lh::heif_chroma_upsampling_algorithm_heif_chroma_upsampling_nearest_neighbor as _,
165 Bilinear = lh::heif_chroma_upsampling_algorithm_heif_chroma_upsampling_bilinear as _,
166}
167
168#[cfg(feature = "v1_20")]
169#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
170#[non_exhaustive]
171pub enum AlphaCompositionMode {
172 #[default]
173 None,
174 SolidColor {
175 background_rgb: [u16; 3],
176 },
177 Checkerboard {
178 background_rgb: [u16; 3],
179 secondary_background_rgb: [u16; 3],
180 square_size: u16,
181 },
182}
183
184#[cfg(feature = "v1_20")]
185#[allow(unsafe_code)]
186impl AlphaCompositionMode {
187 pub(crate) fn from_libheif(cc_options_ext: *const lh::heif_color_conversion_options_ext) -> Self {
188 let cc_options_ext = unsafe { cc_options_ext.as_ref() };
189 let Some(cc_options_ext) = cc_options_ext else {
190 return Self::None;
191 };
192 match cc_options_ext.alpha_composition_mode {
193 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_none => AlphaCompositionMode::None,
194 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_solid_color => {
195 AlphaCompositionMode::SolidColor {
196 background_rgb: [
197 cc_options_ext.background_red,
198 cc_options_ext.background_green,
199 cc_options_ext.background_blue,
200 ],
201 }
202 }
203 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_checkerboard => {
204 AlphaCompositionMode::Checkerboard {
205 background_rgb: [
206 cc_options_ext.background_red,
207 cc_options_ext.background_green,
208 cc_options_ext.background_blue,
209 ],
210 secondary_background_rgb: [
211 cc_options_ext.secondary_background_red,
212 cc_options_ext.secondary_background_green,
213 cc_options_ext.secondary_background_blue,
214 ],
215 square_size: cc_options_ext.checkerboard_square_size,
216 }
217 }
218 _ => AlphaCompositionMode::None,
219 }
220 }
221
222 pub(crate) fn fill_libheif_cc_options_ext(&self, cc_options_ext_ptr: *mut lh::heif_color_conversion_options_ext) {
223 if let Some(cc_options_ext) = unsafe { cc_options_ext_ptr.as_mut() } {
224 match self {
225 AlphaCompositionMode::None => {
226 cc_options_ext.alpha_composition_mode =
227 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_none;
228 }
229 AlphaCompositionMode::SolidColor { background_rgb } => {
230 cc_options_ext.alpha_composition_mode =
231 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_solid_color;
232 cc_options_ext.background_red = background_rgb[0];
233 cc_options_ext.background_green = background_rgb[1];
234 cc_options_ext.background_blue = background_rgb[2];
235 }
236 AlphaCompositionMode::Checkerboard {
237 background_rgb,
238 secondary_background_rgb,
239 square_size,
240 } => {
241 cc_options_ext.alpha_composition_mode =
242 lh::heif_alpha_composition_mode_heif_alpha_composition_mode_checkerboard;
243 cc_options_ext.background_red = background_rgb[0];
244 cc_options_ext.background_green = background_rgb[1];
245 cc_options_ext.background_blue = background_rgb[2];
246 cc_options_ext.secondary_background_red = secondary_background_rgb[0];
247 cc_options_ext.secondary_background_green = secondary_background_rgb[1];
248 cc_options_ext.secondary_background_blue = secondary_background_rgb[2];
249 cc_options_ext.checkerboard_square_size = *square_size;
250 }
251 }
252 }
253 }
254}