Skip to main content

libheif_rs/
enums.rs

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    // Interleaved
14    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    /// Indicates that this image has a special, custom arrangement of components.
31    /// For example, it can have several monochrome channels or
32    /// just a depth component with no color image.
33    /// Images of this type are always planar.
34    #[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    /// Indicates that this image has a special, custom arrangement of components.
41    /// For example, it can have several monochrome channels or
42    /// just a depth component with no color image.
43    /// Images of this type are always planar.
44    Custom,
45    #[cfg(feature = "v1_23")]
46    /// Images of this type are filter-array (CFA / Bayer) mosaics.
47    /// The single mosaicked plane is described as Monochrome.
48    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    /// It is HEIF and can be read by libheif
184    Supported = lh::heif_filetype_result_heif_filetype_yes_supported as _,
185    /// It is HEIF, but cannot be read by libheif
186    Unsupported = lh::heif_filetype_result_heif_filetype_yes_unsupported as _,
187    /// Not sure whether it is an HEIF, try detection with more input data
188    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    /// This value is used when library `libheif` returns unknown value of image orientation.
205    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    /// Combine with `ChromaUpsamplingAlgorithm::Bilinear` for best quality.
216    /// Makes edges look sharper when using YUV 420 with bilinear chroma upsampling.
217    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}