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