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
30#[allow(unsafe_code)]
31impl Track {
32 #[inline]
33 pub(crate) fn from_heif_track(track: *mut lh::heif_track) -> Track {
34 Track { inner: track }
35 }
36
37 #[allow(unsafe_code)]
41 pub fn id(&self) -> u32 {
42 unsafe { lh::heif_track_get_id(self.inner) }
43 }
44
45 #[allow(unsafe_code)]
51 pub fn handler_type(&self) -> TrackType {
52 let c_track_type = unsafe { lh::heif_track_get_track_handler_type(self.inner) };
53 TrackType::from(c_track_type as u32)
54 }
55
56 #[cfg(feature = "v1_21")]
57 #[allow(unsafe_code)]
58 pub fn has_alpha_channel(&self) -> bool {
59 unsafe { lh::heif_track_has_alpha_channel(self.inner) != 0 }
60 }
61
62 #[allow(unsafe_code)]
66 pub fn timescale(&self) -> u32 {
67 unsafe { lh::heif_track_get_timescale(self.inner) }
68 }
69
70 #[allow(unsafe_code)]
74 pub fn image_resolution(&self) -> Result<ImageResolution> {
75 let mut res = ImageResolution::default();
76
77 let err = unsafe { lh::heif_track_get_image_resolution(self.inner, &mut res.width, &mut res.height) };
78
79 HeifError::from_heif_error(err)?;
80 Ok(res)
81 }
82
83 #[allow(unsafe_code)]
97 pub fn decode_next_image(
98 &self,
99 color_space: ColorSpace,
100 decoding_options: Option<DecodingOptions>,
101 ) -> Result<Image> {
102 let mut c_image: *mut lh::heif_image = ptr::null_mut();
103 let err = unsafe {
104 lh::heif_track_decode_next_image(
105 self.inner,
106 &mut c_image,
107 color_space.heif_color_space(),
108 color_space.heif_chroma(),
109 get_decoding_options_ptr(&decoding_options),
110 )
111 };
112 HeifError::from_heif_error(err)?;
113 Ok(Image::from_heif_image(c_image))
114 }
115}
116
117#[allow(unsafe_code)]
118impl Drop for Track {
119 #[allow(unsafe_code)]
120 fn drop(&mut self) {
121 unsafe { lh::heif_track_release(self.inner) };
122 }
123}