mp4_edit/atom/leaf/
gmin.rs1use crate::{
2 atom::{util::ColorRgb, FourCC},
3 parser::ParseAtomData,
4 writer::SerializeAtom,
5 ParseError,
6};
7
8pub const GMIN: FourCC = FourCC::new(b"gmin");
9
10#[derive(Debug, Clone)]
11pub struct BaseMediaInfoAtom {
12 pub version: u8,
13 pub flags: [u8; 3],
14 pub graphics_mode: u16,
15 pub op_color: ColorRgb,
16 pub balance: f32,
18 }
20
21impl Default for BaseMediaInfoAtom {
22 fn default() -> Self {
23 Self {
24 version: 0,
25 flags: [0, 0, 0],
26 graphics_mode: 64,
27 op_color: ColorRgb {
28 red: 32768,
29 green: 32768,
30 blue: 32768,
31 },
32 balance: 0.0,
33 }
34 }
35}
36
37impl ParseAtomData for BaseMediaInfoAtom {
38 fn parse_atom_data(atom_type: FourCC, input: &[u8]) -> Result<Self, ParseError> {
39 crate::atom::util::parser::assert_atom_type!(atom_type, GMIN);
40 use crate::atom::util::parser::stream;
41 use winnow::Parser;
42 Ok(parser::parse_gmin_data.parse(stream(input))?)
43 }
44}
45
46impl SerializeAtom for BaseMediaInfoAtom {
47 fn atom_type(&self) -> FourCC {
48 GMIN
49 }
50
51 fn into_body_bytes(self) -> Vec<u8> {
52 serializer::serialize_gmin_data(self)
53 }
54}
55
56mod serializer {
57 use crate::atom::{
58 gmin::BaseMediaInfoAtom,
59 util::serializer::{color_rgb, fixed_point_8x8},
60 };
61
62 pub fn serialize_gmin_data(gmin: BaseMediaInfoAtom) -> Vec<u8> {
63 let mut data = Vec::new();
64 data.push(gmin.version);
65 data.extend(gmin.flags);
66 data.extend(gmin.graphics_mode.to_be_bytes());
67 data.extend(color_rgb(gmin.op_color));
68 data.extend(fixed_point_8x8(gmin.balance));
69 data.extend([0u8; 2]); data
71 }
72}
73
74mod parser {
75 use crate::atom::{
76 gmin::BaseMediaInfoAtom,
77 util::parser::{byte_array, color_rgb, fixed_point_8x8, flags3, version, Stream},
78 };
79 use winnow::{binary::be_u16, combinator::seq, error::StrContext, ModalResult, Parser};
80
81 pub fn parse_gmin_data(input: &mut Stream<'_>) -> ModalResult<BaseMediaInfoAtom> {
82 seq!(BaseMediaInfoAtom {
83 version: version,
84 flags: flags3,
85 graphics_mode: be_u16.context(StrContext::Label("graphics_mode")),
86 op_color: color_rgb.context(StrContext::Label("op_color")),
87 balance: fixed_point_8x8.context(StrContext::Label("balance")),
88 _: byte_array::<2>.context(StrContext::Label("reserved")),
89 })
90 .parse_next(input)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use crate::atom::test_utils::test_atom_roundtrip;
98
99 #[test]
101 fn test_gmin_roundtrip() {
102 test_atom_roundtrip::<BaseMediaInfoAtom>(GMIN);
103 }
104}