mp4_atom/moov/trak/mdia/minf/stbl/stsd/
tx3g.rs

1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Tx3g {
6    pub data_reference_index: u16,
7    pub display_flags: u32,
8    pub horizontal_justification: i8,
9    pub vertical_justification: i8,
10    pub bg_color_rgba: RgbaColor,
11    pub box_record: [i16; 4],
12    pub style_record: [u8; 12],
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Default)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct RgbaColor {
18    pub red: u8,
19    pub green: u8,
20    pub blue: u8,
21    pub alpha: u8,
22}
23
24impl Default for Tx3g {
25    fn default() -> Self {
26        Tx3g {
27            data_reference_index: 0,
28            display_flags: 0,
29            horizontal_justification: 1,
30            vertical_justification: -1,
31            bg_color_rgba: RgbaColor {
32                red: 0,
33                green: 0,
34                blue: 0,
35                alpha: 255,
36            },
37            box_record: [0, 0, 0, 0],
38            style_record: [0, 0, 0, 0, 0, 1, 0, 16, 255, 255, 255, 255],
39        }
40    }
41}
42
43impl Atom for Tx3g {
44    const KIND: FourCC = FourCC::new(b"tx3g");
45
46    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
47        u32::decode(buf)?; // reserved
48        u16::decode(buf)?; // reserved
49        let data_reference_index = u16::decode(buf)?;
50
51        let display_flags = u32::decode(buf)?;
52        let horizontal_justification = i8::decode(buf)?;
53        let vertical_justification = i8::decode(buf)?;
54        let bg_color_rgba = RgbaColor {
55            red: u8::decode(buf)?,
56            green: u8::decode(buf)?,
57            blue: u8::decode(buf)?,
58            alpha: u8::decode(buf)?,
59        };
60        let box_record: [i16; 4] = [
61            i16::decode(buf)?,
62            i16::decode(buf)?,
63            i16::decode(buf)?,
64            i16::decode(buf)?,
65        ];
66        let style_record = <[u8; 12]>::decode(buf)?;
67
68        Ok(Tx3g {
69            data_reference_index,
70            display_flags,
71            horizontal_justification,
72            vertical_justification,
73            bg_color_rgba,
74            box_record,
75            style_record,
76        })
77    }
78
79    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
80        0u32.encode(buf)?; // reserved
81        0u16.encode(buf)?; // reserved
82        self.data_reference_index.encode(buf)?;
83        self.display_flags.encode(buf)?;
84        self.horizontal_justification.encode(buf)?;
85        self.vertical_justification.encode(buf)?;
86        self.bg_color_rgba.red.encode(buf)?;
87        self.bg_color_rgba.green.encode(buf)?;
88        self.bg_color_rgba.blue.encode(buf)?;
89        self.bg_color_rgba.alpha.encode(buf)?;
90        for n in 0..4 {
91            (self.box_record[n]).encode(buf)?;
92        }
93        for n in 0..12 {
94            (self.style_record[n]).encode(buf)?;
95        }
96
97        Ok(())
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    #[test]
106    fn test_tx3g() {
107        let expected = Tx3g {
108            data_reference_index: 1,
109            display_flags: 0,
110            horizontal_justification: 1,
111            vertical_justification: -1,
112            bg_color_rgba: RgbaColor {
113                red: 0,
114                green: 0,
115                blue: 0,
116                alpha: 255,
117            },
118            box_record: [0, 0, 0, 0],
119            style_record: [0, 0, 0, 0, 0, 1, 0, 16, 255, 255, 255, 255],
120        };
121        let mut buf = Vec::new();
122        expected.encode(&mut buf).unwrap();
123
124        let mut buf = buf.as_ref();
125        let decoded = Tx3g::decode(&mut buf).unwrap();
126        assert_eq!(decoded, expected);
127    }
128}