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 pub fn id(&self) -> u32 {
40 unsafe { lh::heif_track_get_id(self.inner) }
41 }
42
43 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 pub fn timescale(&self) -> u32 {
62 unsafe { lh::heif_track_get_timescale(self.inner) }
63 }
64
65 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 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}