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 len = name.len();
278        if len > 31 {
279            return Err(Error::InvalidSize);
280        }
281        (len as u8).encode(buf)?;
282        (&name[..len]).encode(buf)?;
283
284        let zero = [0u8; 31];
285        (&zero[..31 - len]).encode(buf)
286    }
287}
288
289impl Decode for Compressor {
290    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
291        let compressor_name_bytes = <[u8; 32]>::decode(buf)?;
292        match compressor_name_bytes[0] {
293            0 => Ok(Self(String::new())),
294            1..=31 => {
295                let start_bytes = 1;
296                let end_bytes = start_bytes + compressor_name_bytes[0] as usize;
297                let name = String::from_utf8_lossy(&compressor_name_bytes[start_bytes..end_bytes])
298                    .trim_end_matches('\0')
299                    .to_string();
300                Ok(Self(name))
301            }
302            _ => {
303                // try reading as a string
304                let name = String::from_utf8_lossy(&compressor_name_bytes)
305                    .trim_end_matches('\0')
306                    .to_string();
307                Ok(Self(name))
308            }
309        }
310    }
311}
312
313#[derive(Debug, Clone, PartialEq, Eq, Default)]
314#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
315pub struct Zeroed {
316    pub size: usize,
317}
318
319impl Zeroed {
320    pub fn new(size: usize) -> Self {
321        Self { size }
322    }
323}
324
325impl Encode for Zeroed {
326    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
327        let zero = [0u8; 32];
328        let mut size = self.size;
329
330        while size > 0 {
331            let len = zero.len().min(size);
332            (&zero[..len]).encode(buf)?;
333            size -= len;
334        }
335
336        Ok(())
337    }
338}
339
340impl Decode for Zeroed {
341    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
342        let size = buf.remaining();
343        buf.advance(size);
344        Ok(Self { size })
345    }
346}
347
348impl From<usize> for Zeroed {
349    fn from(size: usize) -> Self {
350        Self { size }
351    }
352}
353
354#[cfg(test)]
355mod tests {
356    use crate::{Compressor, Decode as _, Encode as _};
357
358    #[test]
359    fn check_compressor_encode_minimal() {
360        let compressor = Compressor::from("A");
361        let mut buf = Vec::new();
362        compressor.encode(&mut buf).unwrap();
363        assert_eq!(buf.len(), 32);
364        assert_eq!(
365            buf,
366            vec![
367                0x01, b'A', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369                0x00, 0x00, 0x00, 0x00,
370            ]
371        );
372        let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
373        assert_eq!(decode, compressor);
374    }
375
376    #[test]
377    fn check_compressor_encode_empty() {
378        let compressor = Compressor::from("");
379        let mut buf = Vec::new();
380        compressor.encode(&mut buf).unwrap();
381        assert_eq!(buf.len(), 32);
382        assert_eq!(
383            buf,
384            vec![
385                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387                0x00, 0x00, 0x00, 0x00,
388            ]
389        );
390        let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
391        assert_eq!(decode, compressor);
392    }
393
394    #[test]
395    fn check_compressor_encode_maximal() {
396        let compressor = Compressor::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde");
397        let mut buf = Vec::new();
398        compressor.encode(&mut buf).unwrap();
399        assert_eq!(buf.len(), 32);
400        assert_eq!(
401            buf,
402            vec![
403                0x1F, b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M',
404                b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'a',
405                b'b', b'c', b'd', b'e'
406            ]
407        );
408        let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
409        assert_eq!(decode, compressor);
410    }
411
412    #[test]
413    fn check_compressor_encode_too_long() {
414        let compressor = Compressor::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef");
415        let mut buf = Vec::new();
416        let result = compressor.encode(&mut buf);
417        assert!(result.is_err());
418    }
419}