Skip to main content

kreuzberg_libheif/
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(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    /// It is HEIF and can be read by libheif
128    Supported = lh::heif_filetype_result_heif_filetype_yes_supported as _,
129    /// It is HEIF, but cannot be read by libheif
130    Unsupported = lh::heif_filetype_result_heif_filetype_yes_unsupported as _,
131    /// Not sure whether it is an HEIF, try detection with more input data
132    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    /// This value is used when library `libheif` returns unknown value of image orientation.
147    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    /// Combine with `ChromaUpsamplingAlgorithm::Bilinear` for best quality.
157    /// Makes edges look sharper when using YUV 420 with bilinear chroma upsampling.
158    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}