Skip to main content

libheif_rs/
track.rs

1use std::ptr;
2
3use four_cc::FourCC;
4use libheif_sys as lh;
5
6use crate::decoder::get_decoding_options_ptr;
7use crate::{ColorSpace, DecodingOptions, HeifError, Image, Result};
8
9pub type TrackType = FourCC;
10
11pub mod track_types {
12    use super::{FourCC, TrackType};
13
14    pub const VIDEO: TrackType = FourCC(*b"vide");
15    pub const IMAGE_SEQUENCE: TrackType = FourCC(*b"pict");
16    pub const AUXILIARY: TrackType = FourCC(*b"auxv");
17    pub const METADATA: TrackType = FourCC(*b"meta");
18}
19
20#[derive(Default, Copy, Clone, PartialEq, Eq)]
21pub struct ImageResolution {
22    pub width: u16,
23    pub height: u16,
24}
25
26pub struct Track {
27    pub(crate) inner: *mut lh::heif_track,
28}
29
30impl Track {
31    #[inline]
32    pub(crate) fn from_heif_track(track: *mut lh::heif_track) -> Track {
33        Track { inner: track }
34    }
35
36    /// Get the ID of the track.
37    ///
38    /// The track ID will never be 0.
39    pub fn id(&self) -> u32 {
40        unsafe { lh::heif_track_get_id(self.inner) }
41    }
42
43    /// Get the four-cc track handler type.
44    ///
45    /// Typical codes are "vide" for video sequences, "pict" for image sequences,
46    /// "meta" for metadata tracks.
47    /// These are defined in [`track_types`] module, but files may also contain other types.
48    pub fn handler_type(&self) -> TrackType {
49        let c_track_type = unsafe { lh::heif_track_get_track_handler_type(self.inner) };
50        TrackType::from(c_track_type as u32)
51    }
52
53    #[cfg(feature = "v1_21")]
54    pub fn has_alpha_channel(&self) -> bool {
55        unsafe { lh::heif_track_has_alpha_channel(self.inner) != 0 }
56    }
57
58    /// Get the timescale (clock ticks per second) for this track.
59    ///
60    /// Note that this can be different from the timescale used at sequence level.
61    pub fn timescale(&self) -> u32 {
62        unsafe { lh::heif_track_get_timescale(self.inner) }
63    }
64
65    /// Get the image resolution of the track.
66    ///
67    /// If the track is no visual track, an error is returned.
68    pub fn image_resolution(&self) -> Result<ImageResolution> {
69        let mut res = ImageResolution::default();
70
71        let err = unsafe {
72            lh::heif_track_get_image_resolution(self.inner, &mut res.width, &mut res.height)
73        };
74
75        HeifError::from_heif_error(err)?;
76        Ok(res)
77    }
78
79    /// Decode the next image in the sequence track.
80    ///
81    /// If there is no more image in the sequence,
82    /// error with code [HeifErrorCode::EndOfSequence](crate::HeifErrorCode::EndOfSequence)
83    /// will be returned.
84    /// The parameters `color_space` and `decoding_options` are similar to
85    /// [LibHeif::decode()](crate::LibHeif::decode).
86    /// If you want to let `libheif` decide the output colorspace and chroma,
87    /// set `color_space` parameter to [ColorSpace::Undefined].
88    /// Usually, `libheif` will return the image in the input colorspace,
89    /// but it may also modify it for example when it has to rotate the image.
90    /// If you want to get the image in a specific colorspace/chroma format,
91    /// you can specify this and `libheif` will convert the image to match this format.
92    pub fn decode_next_image(
93        &self,
94        color_space: ColorSpace,
95        decoding_options: Option<DecodingOptions>,
96    ) -> Result<Image> {
97        let mut c_image: *mut lh::heif_image = ptr::null_mut();
98        let err = unsafe {
99            lh::heif_track_decode_next_image(
100                self.inner,
101                &mut c_image,
102                color_space.heif_color_space(),
103                color_space.heif_chroma(),
104                get_decoding_options_ptr(&decoding_options),
105            )
106        };
107        HeifError::from_heif_error(err)?;
108        Ok(Image::from_heif_image(c_image))
109    }
110}
111
112impl Drop for Track {
113    fn drop(&mut self) {
114        unsafe { lh::heif_track_release(self.inner) };
115    }
116}