scuffle_mp4/boxes/types/
co64.rs1use std::io;
2
3use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4use bytes::Bytes;
5
6use crate::boxes::header::{BoxHeader, FullBoxHeader};
7use crate::boxes::traits::BoxType;
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct Co64 {
13 pub header: FullBoxHeader,
14 pub chunk_offset: Vec<u32>,
15}
16
17impl BoxType for Co64 {
18 const NAME: [u8; 4] = *b"co64";
19
20 fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
21 let mut reader = io::Cursor::new(data);
22
23 let header = FullBoxHeader::demux(header, &mut reader)?;
24
25 let entry_count = reader.read_u32::<BigEndian>()?;
26 let mut chunk_offset = Vec::with_capacity(entry_count as usize);
27 for _ in 0..entry_count {
28 let offset = reader.read_u32::<BigEndian>()?;
29 chunk_offset.push(offset);
30 }
31
32 Ok(Self { header, chunk_offset })
33 }
34
35 fn primitive_size(&self) -> u64 {
36 self.header.size()
37 + 4 + (self.chunk_offset.len() as u64 * 4) }
40
41 fn primitive_mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
42 self.header.mux(writer)?;
43
44 writer.write_u32::<BigEndian>(self.chunk_offset.len() as u32)?;
45 for offset in &self.chunk_offset {
46 writer.write_u32::<BigEndian>(*offset)?;
47 }
48
49 Ok(())
50 }
51
52 fn validate(&self) -> io::Result<()> {
53 if self.header.flags != 0 {
54 return Err(io::Error::new(io::ErrorKind::InvalidData, "co64 flags must be 0"));
55 }
56
57 if self.header.version != 0 {
58 return Err(io::Error::new(io::ErrorKind::InvalidData, "co64 version must be 0"));
59 }
60
61 Ok(())
62 }
63}