mp4_atom/
types.rs

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