/src/mp4san/webpsan/src/parse/vp8x.rs
Line | Count | Source |
1 | | #![allow(missing_docs)] |
2 | | |
3 | | use std::num::NonZeroU32; |
4 | | |
5 | | use bytes::{BufMut, BytesMut}; |
6 | | use mediasan_common::parse::FourCC; |
7 | | use mediasan_common::{ensure_attach, Result}; |
8 | | |
9 | | use super::chunk_type::VP8X; |
10 | | use super::error::ParseResultExt; |
11 | | use super::{OneBasedU24, ParseChunk, ParseError, ParsedChunk, Reserved, WebmFlags, WebmPrim}; |
12 | | |
13 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
14 | | pub struct Vp8xChunk { |
15 | | pub flags: Vp8xFlags, |
16 | | reserved: Reserved<3>, |
17 | | canvas_width: OneBasedU24, |
18 | | canvas_height: OneBasedU24, |
19 | | } |
20 | | |
21 | | bitflags::bitflags! { |
22 | | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] |
23 | | pub struct Vp8xFlags: u8 { |
24 | | const HAS_ICCP_CHUNK = 0b0010_0000; |
25 | | const HAS_ALPH_CHUNK = 0b0001_0000; |
26 | | const HAS_EXIF_CHUNK = 0b0000_1000; |
27 | | const HAS_XMP_CHUNK = 0b0000_0100; |
28 | | const IS_ANIMATED = 0b0000_0010; |
29 | | } |
30 | | } |
31 | | |
32 | | // |
33 | | // Vp8xChunk impls |
34 | | // |
35 | | |
36 | | impl Vp8xChunk { |
37 | 6.62k | pub fn canvas_width(&self) -> NonZeroU32 { |
38 | 6.62k | self.canvas_width.get() |
39 | 6.62k | } |
40 | | |
41 | 6.62k | pub fn canvas_height(&self) -> NonZeroU32 { |
42 | 6.62k | self.canvas_height.get() |
43 | 6.62k | } |
44 | | } |
45 | | |
46 | | impl ParseChunk for Vp8xChunk { |
47 | | const NAME: FourCC = VP8X; |
48 | | |
49 | | const ENCODED_LEN: u32 = |
50 | | Vp8xFlags::ENCODED_LEN + Reserved::<3>::ENCODED_LEN + OneBasedU24::ENCODED_LEN + OneBasedU24::ENCODED_LEN; |
51 | | |
52 | 3.44k | fn parse(mut buf: &mut BytesMut) -> Result<Self, ParseError> { |
53 | 3.44k | let flags = Vp8xFlags::parse(&mut buf).while_parsing_field(Self::NAME, "flags")?; |
54 | 3.44k | let reserved = Reserved::parse(&mut buf).while_parsing_field(Self::NAME, "reserved")?; |
55 | 3.42k | let canvas_width = OneBasedU24::parse(&mut buf).while_parsing_field(Self::NAME, "canvas_width")?; |
56 | 3.42k | let canvas_height = OneBasedU24::parse(&mut buf).while_parsing_field(Self::NAME, "canvas_height")?; |
57 | 3.42k | ensure_attach!( |
58 | 3.42k | canvas_height.get().checked_mul(canvas_width.get()).is_some(), |
59 | 1 | ParseError::InvalidInput, |
60 | | "canvas pixel count overflow", |
61 | | ); |
62 | 3.41k | Ok(Self { flags, reserved, canvas_width, canvas_height }) |
63 | 3.44k | } |
64 | | } |
65 | | |
66 | | impl ParsedChunk for Vp8xChunk { |
67 | 0 | fn put_buf(&self, mut buf: &mut dyn BufMut) { |
68 | 0 | let Self { flags, reserved, canvas_width, canvas_height } = self; |
69 | 0 | flags.put_buf(&mut buf); |
70 | 0 | reserved.put_buf(&mut buf); |
71 | 0 | canvas_width.put_buf(&mut buf); |
72 | 0 | canvas_height.put_buf(&mut buf); |
73 | 0 | } |
74 | | } |
75 | | |
76 | | // |
77 | | // Vp8xFlags impls |
78 | | // |
79 | | |
80 | | impl WebmFlags for Vp8xFlags {} |