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