Skip to main content

mp4_edit/atom/leaf/
text.rs

1use crate::{atom::FourCC, parser::ParseAtomData, writer::SerializeAtom, ParseError};
2
3pub const TEXT: FourCC = FourCC::new(b"text");
4
5#[derive(Debug, Clone)]
6pub struct TextMediaInfoAtom {
7    /// 3x3 transformation matrix for text media
8    pub matrix: [i32; 9],
9}
10
11impl Default for TextMediaInfoAtom {
12    fn default() -> Self {
13        Self {
14            matrix: [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824],
15        }
16    }
17}
18
19impl ParseAtomData for TextMediaInfoAtom {
20    fn parse_atom_data(atom_type: FourCC, input: &[u8]) -> Result<Self, ParseError> {
21        crate::atom::util::parser::assert_atom_type!(atom_type, TEXT);
22        use crate::atom::util::parser::stream;
23        use winnow::Parser;
24        Ok(parser::parse_text_data.parse(stream(input))?)
25    }
26}
27
28impl SerializeAtom for TextMediaInfoAtom {
29    fn atom_type(&self) -> FourCC {
30        TEXT
31    }
32
33    fn into_body_bytes(self) -> Vec<u8> {
34        serializer::serialize_text_data(self)
35    }
36}
37
38mod serializer {
39    use crate::atom::text::TextMediaInfoAtom;
40
41    pub fn serialize_text_data(text: TextMediaInfoAtom) -> Vec<u8> {
42        text.matrix
43            .into_iter()
44            .flat_map(|v| v.to_be_bytes())
45            .collect()
46    }
47}
48
49mod parser {
50    use crate::atom::{
51        text::TextMediaInfoAtom,
52        util::parser::{fixed_array, Stream},
53    };
54    use winnow::{binary::be_i32, combinator::seq, error::StrContext, ModalResult, Parser};
55
56    pub fn parse_text_data(input: &mut Stream<'_>) -> ModalResult<TextMediaInfoAtom> {
57        seq!(TextMediaInfoAtom {
58            matrix: fixed_array(be_i32).context(StrContext::Label("matrix")),
59        })
60        .parse_next(input)
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67    use crate::atom::test_utils::test_atom_roundtrip;
68
69    /// Test round-trip for all available text test data files
70    #[test]
71    fn test_text_roundtrip() {
72        test_atom_roundtrip::<TextMediaInfoAtom>(TEXT);
73    }
74}