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 From<[u8; 3]> for u24 {
91    fn from(value: [u8; 3]) -> Self {
92        Self(value)
93    }
94}
95
96impl Decode for u24 {
97    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
98        Ok(Self(<[u8; 3]>::decode(buf)?))
99    }
100}
101
102impl Encode for u24 {
103    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
104        self.0.encode(buf)
105    }
106}
107
108impl From<u24> for u32 {
109    fn from(value: u24) -> Self {
110        u32::from_be_bytes([0, value.0[0], value.0[1], value.0[2]])
111    }
112}
113
114impl TryFrom<u32> for u24 {
115    type Error = std::array::TryFromSliceError;
116
117    fn try_from(value: u32) -> std::result::Result<Self, Self::Error> {
118        Ok(Self(value.to_be_bytes()[1..].try_into()?))
119    }
120}
121
122impl ToBytes for u24 {
123    type Bytes = [u8; 3];
124
125    fn to_be_bytes(&self) -> Self::Bytes {
126        self.0
127    }
128
129    fn to_le_bytes(&self) -> Self::Bytes {
130        [self.0[2], self.0[1], self.0[0]]
131    }
132}
133
134#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
135#[allow(non_camel_case_types)]
136#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
137pub struct u48([u8; 6]);
138
139impl Decode for u48 {
140    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
141        Ok(Self(<[u8; 6]>::decode(buf)?))
142    }
143}
144
145impl Encode for u48 {
146    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
147        self.0.encode(buf)
148    }
149}
150
151impl TryFrom<u64> for u48 {
152    type Error = std::array::TryFromSliceError;
153
154    fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
155        Ok(Self(value.to_be_bytes()[2..].try_into()?))
156    }
157}
158
159impl From<u48> for u64 {
160    fn from(value: u48) -> Self {
161        u64::from_be_bytes([
162            0, 0, value.0[0], value.0[1], value.0[2], value.0[3], value.0[4], value.0[5],
163        ])
164    }
165}
166
167impl From<[u8; 6]> for u48 {
168    fn from(value: [u8; 6]) -> Self {
169        u48(value)
170    }
171}
172
173impl AsRef<[u8; 6]> for u48 {
174    fn as_ref(&self) -> &[u8; 6] {
175        &self.0
176    }
177}
178
179// The top N bits are the integer part, the bottom N bits are the fractional part.
180// Somebody who cares should implement some math stuff.
181#[derive(Copy, Clone, Default, PartialEq, Eq)]
182#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
183pub struct FixedPoint<T> {
184    int: T,
185    dec: T,
186}
187
188impl<T: Copy> FixedPoint<T> {
189    pub fn new(int: T, dec: T) -> Self {
190        Self { int, dec }
191    }
192
193    pub fn integer(&self) -> T {
194        self.int
195    }
196
197    pub fn decimal(&self) -> T {
198        self.dec
199    }
200}
201
202impl<T: Decode> Decode for FixedPoint<T> {
203    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
204        Ok(Self {
205            int: T::decode(buf)?,
206            dec: T::decode(buf)?,
207        })
208    }
209}
210
211impl<T: Encode> Encode for FixedPoint<T> {
212    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
213        self.int.encode(buf)?;
214        self.dec.encode(buf)
215    }
216}
217
218impl<T: num::Zero> From<T> for FixedPoint<T> {
219    fn from(value: T) -> Self {
220        Self {
221            int: value,
222            dec: T::zero(),
223        }
224    }
225}
226
227impl<T> fmt::Debug for FixedPoint<T>
228where
229    T: num::Zero + fmt::Debug + PartialEq + Copy,
230    f64: From<T>,
231{
232    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233        if self.dec.is_zero() {
234            write!(f, "{:?}", self.int)
235        } else {
236            write!(f, "{:?}", f64::from(self.int) / f64::from(self.dec))
237        }
238    }
239}
240
241// 32 bytes max
242#[derive(Debug, Clone, PartialEq, Eq, Default)]
243#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
244pub struct Compressor(String);
245
246impl From<&str> for Compressor {
247    fn from(value: &str) -> Self {
248        Self(value.to_string())
249    }
250}
251
252impl From<String> for Compressor {
253    fn from(value: String) -> Self {
254        Self(value)
255    }
256}
257
258impl From<Compressor> for String {
259    fn from(value: Compressor) -> Self {
260        value.0
261    }
262}
263
264impl AsRef<str> for Compressor {
265    fn as_ref(&self) -> &str {
266        &self.0
267    }
268}
269
270impl Encode for Compressor {
271    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
272        let name = self.0.as_bytes();
273        let max = name.len().min(31);
274        (&name[..max]).encode(buf)?;
275
276        let zero = [0u8; 32];
277        (&zero[..32 - max]).encode(buf)
278    }
279}
280
281impl Decode for Compressor {
282    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
283        let name = <[u8; 32]>::decode(buf)?;
284
285        let name = String::from_utf8_lossy(&name)
286            .trim_end_matches('\0')
287            .to_string();
288
289        Ok(Self(name))
290    }
291}
292
293#[derive(Debug, Clone, PartialEq, Eq, Default)]
294#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
295pub struct Zeroed {
296    pub size: usize,
297}
298
299impl Zeroed {
300    pub fn new(size: usize) -> Self {
301        Self { size }
302    }
303}
304
305impl Encode for Zeroed {
306    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
307        let zero = [0u8; 32];
308        let mut size = self.size;
309
310        while size > 0 {
311            let len = zero.len().min(size);
312            (&zero[..len]).encode(buf)?;
313            size -= len;
314        }
315
316        Ok(())
317    }
318}
319
320impl Decode for Zeroed {
321    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
322        let size = buf.remaining();
323        buf.advance(size);
324        Ok(Self { size })
325    }
326}
327
328impl From<usize> for Zeroed {
329    fn from(size: usize) -> Self {
330        Self { size }
331    }
332}