mp4_atom/meta/properties/
clap.rs

1use crate::*;
2
3// CleanApertureProperty.
4// ISO/IEC 23008-12:2022 Section 6.5.9.
5// Cropping operation (transformative property).
6// Same syntax as CleanApertureBox, ISO/IEC 14496:2022 Section 12.1.4.
7// Note the syntax says horizOffN and vertOffN are unsigned. That is wrong. See the definition text and https://github.com/MPEGGroup/FileFormat/issues/41
8
9#[derive(Debug, Clone, PartialEq, Eq, Default)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Clap {
12    pub clean_aperture_width_n: u32,
13    pub clean_aperture_width_d: u32,
14    pub clean_aperture_height_n: u32,
15    pub clean_aperture_height_d: u32,
16    pub horiz_off_n: i32,
17    pub horiz_off_d: u32,
18    pub vert_off_n: i32,
19    pub vert_off_d: u32,
20}
21
22impl Atom for Clap {
23    const KIND: FourCC = FourCC::new(b"clap");
24
25    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
26        let clean_aperture_width_n = u32::decode(buf)?;
27        let clean_aperture_width_d = u32::decode(buf)?;
28        let clean_aperture_height_n = u32::decode(buf)?;
29        let clean_aperture_height_d = u32::decode(buf)?;
30        let horiz_off_n = i32::decode(buf)?;
31        let horiz_off_d = u32::decode(buf)?;
32        let vert_off_n = i32::decode(buf)?;
33        let vert_off_d = u32::decode(buf)?;
34        Ok(Clap {
35            clean_aperture_width_n,
36            clean_aperture_width_d,
37            clean_aperture_height_n,
38            clean_aperture_height_d,
39            horiz_off_n,
40            horiz_off_d,
41            vert_off_n,
42            vert_off_d,
43        })
44    }
45
46    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
47        self.clean_aperture_width_n.encode(buf)?;
48        self.clean_aperture_width_d.encode(buf)?;
49        self.clean_aperture_height_n.encode(buf)?;
50        self.clean_aperture_height_d.encode(buf)?;
51        self.horiz_off_n.encode(buf)?;
52        self.horiz_off_d.encode(buf)?;
53        self.vert_off_n.encode(buf)?;
54        self.vert_off_d.encode(buf)?;
55        Ok(())
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn test_clap() {
65        let expected = Clap {
66            clean_aperture_width_n: 100,
67            clean_aperture_width_d: 1,
68            clean_aperture_height_n: 200,
69            clean_aperture_height_d: 3,
70            horiz_off_n: 300,
71            horiz_off_d: 5,
72            vert_off_n: 499,
73            vert_off_d: 7,
74        };
75        let mut buf = Vec::new();
76        expected.encode(&mut buf).unwrap();
77
78        let mut buf = buf.as_ref();
79        let decoded = Clap::decode(&mut buf).unwrap();
80        assert_eq!(decoded, expected);
81    }
82}