mp4_atom/
types.rs

1use std::fmt;
2
3use crate::*;
4
5// Re-export this common types.
6pub use num::rational::Ratio;
7pub use num::traits::ToBytes;
8
9/// A four-character code used to identify atoms.
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11// TODO serialize as a string
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct FourCC([u8; 4]);
14
15impl FourCC {
16    // Helper function to create a FourCC from a string literal
17    // ex. FourCC::new(b"abcd")
18    pub const fn new(value: &[u8; 4]) -> Self {
19        FourCC(*value)
20    }
21}
22
23impl From<u32> for FourCC {
24    fn from(value: u32) -> Self {
25        FourCC(value.to_be_bytes())
26    }
27}
28
29impl From<FourCC> for u32 {
30    fn from(cc: FourCC) -> Self {
31        u32::from_be_bytes(cc.0)
32    }
33}
34
35impl From<[u8; 4]> for FourCC {
36    fn from(value: [u8; 4]) -> Self {
37        FourCC(value)
38    }
39}
40
41impl From<FourCC> for [u8; 4] {
42    fn from(cc: FourCC) -> Self {
43        cc.0
44    }
45}
46
47impl From<&[u8; 4]> for FourCC {
48    fn from(value: &[u8; 4]) -> Self {
49        FourCC(*value)
50    }
51}
52
53impl fmt::Display for FourCC {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        let s = String::from_utf8_lossy(&self.0);
56        write!(f, "{s}")
57    }
58}
59
60impl fmt::Debug for FourCC {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        let s = String::from_utf8_lossy(&self.0);
63        write!(f, "{s}")
64    }
65}
66
67impl Encode for FourCC {
68    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
69        self.0.encode(buf)
70    }
71}
72
73impl Decode for FourCC {
74    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
75        Ok(FourCC(<[u8; 4]>::decode(buf)?))
76    }
77}
78
79impl AsRef<[u8; 4]> for FourCC {
80    fn as_ref(&self) -> &[u8; 4] {
81        &self.0
82    }
83}
84
85#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
86#[allow(non_camel_case_types)]
87#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88pub struct u24([u8; 3]);
89
90impl u24 {
91    pub const MAX: u32 = 0x00FF_FFFF;
92}
93
94impl From<[u8; 3]> for u24 {
95    fn from(value: [u8; 3]) -> Self {
96        Self(value)
97    }
98}
99
100impl Decode for u24 {
101    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
102        Ok(Self(<[u8; 3]>::decode(buf)?))
103    }
104}
105
106impl Encode for u24 {
107    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
108        self.0.encode(buf)
109    }
110}
111
112impl From<u24> for u32 {
113    fn from(value: u24) -> Self {
114        u32::from_be_bytes([0, value.0[0], value.0[1], value.0[2]])
115    }
116}
117
118impl TryFrom<u32> for u24 {
119    type Error = std::array::TryFromSliceError;
120
121    fn try_from(value: u32) -> std::result::Result<Self, Self::Error> {
122        Ok(Self(value.to_be_bytes()[1..].try_into()?))
123    }
124}
125
126impl ToBytes for u24 {
127    type Bytes = [u8; 3];
128
129    fn to_be_bytes(&self) -> Self::Bytes {
130        self.0
131    }
132
133    fn to_le_bytes(&self) -> Self::Bytes {
134        [self.0[2], self.0[1], self.0[0]]
135    }
136}
137
138#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
139#[allow(non_camel_case_types)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub struct u48([u8; 6]);
142
143impl Decode for u48 {
144    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
145        Ok(Self(<[u8; 6]>::decode(buf)?))
146    }
147}
148
149impl Encode for u48 {
150    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
151        self.0.encode(buf)
152    }
153}
154
155impl TryFrom<u64> for u48 {
156    type Error = std::array::TryFromSliceError;
157
158    fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
159        Ok(Self(value.to_be_bytes()[2..].try_into()?))
160    }
161}
162
163impl From<u48> for u64 {
164    fn from(value: u48) -> Self {
165        u64::from_be_bytes([
166            0, 0, value.0[0], value.0[1], value.0[2], value.0[3], value.0[4], value.0[5],
167        ])
168    }
169}
170
171impl From<[u8; 6]> for u48 {
172    fn from(value: [u8; 6]) -> Self {
173        u48(value)
174    }
175}
176
177impl AsRef<[u8; 6]> for u48 {
178    fn as_ref(&self) -> &[u8; 6] {
179        &self.0
180    }
181}
182
183// The top N bits are the integer part, the bottom N bits are the fractional part.
184// Somebody who cares should implement some math stuff.
185#[derive(Copy, Clone, Default, PartialEq, Eq)]
186#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
187pub struct FixedPoint<T> {
188    int: T,
189    dec: T,
190}
191
192impl<T: Copy> FixedPoint<T> {
193    pub fn new(int: T, dec: T) -> Self {
194        Self { int, dec }
195    }
196
197    pub fn integer(&self) -> T {
198        self.int
199    }
200
201    pub fn decimal(&self) -> T {
202        self.dec
203    }
204}
205
206impl<T: Decode> Decode for FixedPoint<T> {
207    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
208        Ok(Self {
209            int: T::decode(buf)?,
210            dec: T::decode(buf)?,
211        })
212    }
213}
214
215impl<T: Encode> Encode for FixedPoint<T> {
216    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
217        self.int.encode(buf)?;
218        self.dec.encode(buf)
219    }
220}
221
222impl<T: num::Zero> From<T> for FixedPoint<T> {
223    fn from(value: T) -> Self {
224        Self {
225            int: value,
226            dec: T::zero(),
227        }
228    }
229}
230
231impl<T> fmt::Debug for FixedPoint<T>
232where
233    T: num::Zero + fmt::Debug + PartialEq + Copy,
234    f64: From<T>,
235{
236    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
237        if self.dec.is_zero() {
238            write!(f, "{:?}", self.int)
239        } else {
240            write!(f, "{:?}", f64::from(self.int) / f64::from(self.dec))
241        }
242    }
243}
244
245// 32 bytes max
246#[derive(Debug, Clone, PartialEq, Eq, Default)]
247#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
248pub struct Compressor(String);
249
250impl From<&str> for Compressor {
251    fn from(value: &str) -> Self {
252        Self(value.to_string())
253    }
254}
255
256impl From<String> for Compressor {
257    fn from(value: String) -> Self {
258        Self(value)
259    }
260}
261
262impl From<Compressor> for String {
263    fn from(value: Compressor) -> Self {
264        value.0
265    }
266}
267
268impl AsRef<str> for Compressor {
269    fn as_ref(&self) -> &str {
270        &self.0
271    }
272}
273
274impl Encode for Compressor {
275    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
276        let name = self.0.as_bytes();
277        let max = name.len().min(31);
278        (&name[..max]).encode(buf)?;
279
280        let zero = [0u8; 32];
281        (&zero[..32 - max]).encode(buf)
282    }
283}
284
285impl Decode for Compressor {
286    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
287        let name = <[u8; 32]>::decode(buf)?;
288
289        let name = String::from_utf8_lossy(&name)
290            .trim_end_matches('\0')
291            .to_string();
292
293        Ok(Self(name))
294    }
295}
296
297#[derive(Debug, Clone, PartialEq, Eq, Default)]
298#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
299pub struct Zeroed {
300    pub size: usize,
301}
302
303impl Zeroed {
304    pub fn new(size: usize) -> Self {
305        Self { size }
306    }
307}
308
309impl Encode for Zeroed {
310    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
311        let zero = [0u8; 32];
312        let mut size = self.size;
313
314        while size > 0 {
315            let len = zero.len().min(size);
316            (&zero[..len]).encode(buf)?;
317            size -= len;
318        }
319
320        Ok(())
321    }
322}
323
324impl Decode for Zeroed {
325    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
326        let size = buf.remaining();
327        buf.advance(size);
328        Ok(Self { size })
329    }
330}
331
332impl From<usize> for Zeroed {
333    fn from(size: usize) -> Self {
334        Self { size }
335    }
336}