1use crate::media::{Error, Result};
2use crate::mp4::truncated;
3use std::fmt;
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
6pub struct FourCc(pub [u8; 4]);
7
8impl FourCc {
9 pub const fn new(b: &[u8; 4]) -> Self {
10 FourCc(*b)
11 }
12 pub fn as_u32(self) -> u32 {
13 u32::from_be_bytes(self.0)
14 }
15 pub fn to_string_lossy(self) -> String {
16 self.0
17 .iter()
18 .map(|&b| match b {
19 0xA9 => '©',
20 0x20..=0x7E => b as char,
21 _ => '?',
22 })
23 .collect()
24 }
25}
26
27impl fmt::Display for FourCc {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 f.write_str(&self.to_string_lossy())
30 }
31}
32impl fmt::Debug for FourCc {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 write!(f, "FourCc({:?})", self.to_string_lossy())
35 }
36}
37impl From<&[u8; 4]> for FourCc {
38 fn from(b: &[u8; 4]) -> Self {
39 FourCc(*b)
40 }
41}
42impl PartialEq<[u8; 4]> for FourCc {
43 fn eq(&self, other: &[u8; 4]) -> bool {
44 &self.0 == other
45 }
46}
47impl PartialEq<&[u8; 4]> for FourCc {
48 fn eq(&self, other: &&[u8; 4]) -> bool {
49 &self.0 == *other
50 }
51}
52impl PartialEq<&&[u8; 4]> for FourCc {
53 fn eq(&self, other: &&&[u8; 4]) -> bool {
54 &self.0 == **other
55 }
56}
57
58#[derive(Clone)]
59pub(crate) struct Cur<'a> {
60 pub data: &'a [u8],
61 pub pos: usize,
62 what: &'static str,
63}
64
65impl<'a> Cur<'a> {
66 pub fn new(data: &'a [u8], what: &'static str) -> Self {
67 Cur { data, pos: 0, what }
68 }
69 pub fn remaining(&self) -> usize {
70 self.data.len().saturating_sub(self.pos)
71 }
72 pub fn rest(&self) -> &'a [u8] {
73 self.data.get(self.pos..).unwrap_or(&[])
74 }
75 pub fn bytes(&mut self, n: usize) -> Result<&'a [u8]> {
76 let end = self
77 .pos
78 .checked_add(n)
79 .ok_or_else(|| truncated(self.what))?;
80 let s = self
81 .data
82 .get(self.pos..end)
83 .ok_or_else(|| truncated(self.what))?;
84 self.pos = end;
85 Ok(s)
86 }
87 pub fn skip(&mut self, n: usize) -> Result<()> {
88 self.bytes(n).map(|_| ())
89 }
90 pub fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
91 let s = self.bytes(N)?;
92 let mut a = [0u8; N];
93 a.copy_from_slice(s);
94 Ok(a)
95 }
96 pub fn u8(&mut self) -> Result<u8> {
97 Ok(self.array::<1>()?[0])
98 }
99 pub fn u16(&mut self) -> Result<u16> {
100 Ok(u16::from_be_bytes(self.array()?))
101 }
102 pub fn u24(&mut self) -> Result<u32> {
103 let a = self.array::<3>()?;
104 Ok(((a[0] as u32) << 16) | ((a[1] as u32) << 8) | a[2] as u32)
105 }
106 pub fn u32(&mut self) -> Result<u32> {
107 Ok(u32::from_be_bytes(self.array()?))
108 }
109 pub fn i32(&mut self) -> Result<i32> {
110 Ok(i32::from_be_bytes(self.array()?))
111 }
112 pub fn u64(&mut self) -> Result<u64> {
113 Ok(u64::from_be_bytes(self.array()?))
114 }
115 pub fn i64(&mut self) -> Result<i64> {
116 Ok(i64::from_be_bytes(self.array()?))
117 }
118 pub fn f64(&mut self) -> Result<f64> {
119 Ok(f64::from_be_bytes(self.array()?))
120 }
121 pub fn fourcc(&mut self) -> Result<FourCc> {
122 Ok(FourCc(self.array()?))
123 }
124 pub fn full_header(&mut self) -> Result<(u8, u32)> {
125 let v = self.u32()?;
126 Ok(((v >> 24) as u8, v & 0x00FF_FFFF))
127 }
128 pub fn count(&mut self, entry_size: usize) -> Result<usize> {
129 let n = self.u32()? as usize;
130 self.check_count(n, entry_size)?;
131 Ok(n)
132 }
133 pub fn check_count(&self, n: usize, entry_size: usize) -> Result<()> {
134 match n.checked_mul(entry_size) {
135 Some(b) if b <= self.remaining() => Ok(()),
136 _ => Err(truncated(self.what)),
137 }
138 }
139}
140
141#[derive(Clone, Copy, Debug, PartialEq, Eq)]
142pub(crate) struct BoxHeader {
143 pub kind: FourCc,
144 pub header_len: u64,
145 pub size: Option<u64>,
146}
147
148pub(crate) fn parse_box_header(buf: &[u8]) -> Result<BoxHeader> {
149 let mut c = Cur::new(buf, "box header");
150 let size32 = c.u32()?;
151 let kind = c.fourcc()?;
152 let mut header_len = 8u64;
153 let size = match size32 {
154 0 => None,
155 1 => {
156 header_len += 8;
157 let s = c.u64()?;
158 Some(s)
159 }
160 s => Some(s as u64),
161 };
162 if kind == b"uuid" {
163 header_len += 16;
164 c.array::<16>()?;
165 }
166 if let Some(s) = size
167 && s < header_len
168 {
169 return Err(Error::Invalid(format!(
170 "box '{kind}' size {s} smaller than its header"
171 )));
172 }
173 Ok(BoxHeader {
174 kind,
175 header_len,
176 size,
177 })
178}
179
180#[derive(Clone, Copy, Debug)]
181pub(crate) struct RawBox<'a> {
182 pub kind: FourCc,
183 pub payload: &'a [u8],
184}
185
186pub(crate) struct Boxes<'a> {
187 data: &'a [u8],
188 pos: usize,
189 done: bool,
190}
191
192pub(crate) fn boxes(data: &[u8]) -> Boxes<'_> {
193 Boxes {
194 data,
195 pos: 0,
196 done: false,
197 }
198}
199
200impl<'a> Iterator for Boxes<'a> {
201 type Item = Result<RawBox<'a>>;
202 fn next(&mut self) -> Option<Self::Item> {
203 if self.done {
204 return None;
205 }
206 let rest = &self.data[self.pos..];
207 if rest.is_empty() {
208 self.done = true;
209 return None;
210 }
211 if rest.len() < 8 {
212 self.done = true;
213 if rest.iter().all(|&b| b == 0) {
214 return None;
215 }
216 return Some(Err(truncated("box header")));
217 }
218 let h = match parse_box_header(rest) {
219 Ok(h) => h,
220 Err(e) => {
221 self.done = true;
222 return Some(Err(e));
223 }
224 };
225 let size = h.size.unwrap_or(rest.len() as u64);
226 if size > rest.len() as u64 {
227 self.done = true;
228 return Some(Err(Error::Invalid(format!(
229 "box '{}' size {} exceeds its container ({} bytes left)",
230 h.kind,
231 size,
232 rest.len()
233 ))));
234 }
235 let size = size as usize;
236 let payload = &rest[h.header_len as usize..size];
237 self.pos += size;
238 Some(Ok(RawBox {
239 kind: h.kind,
240 payload,
241 }))
242 }
243}
244
245pub(crate) fn find<'a>(data: &'a [u8], kind: &[u8; 4]) -> Option<&'a [u8]> {
246 boxes(data)
247 .map_while(|b| b.ok())
248 .find(|b| b.kind == kind)
249 .map(|b| b.payload)
250}
251
252#[derive(Default, Clone, Debug)]
253pub(crate) struct BoxBuf {
254 pub buf: Vec<u8>,
255}
256
257impl BoxBuf {
258 pub fn new() -> Self {
259 Self::default()
260 }
261 pub fn start(&mut self, kind: &[u8; 4]) -> usize {
262 let at = self.buf.len();
263 self.buf.extend_from_slice(&[0, 0, 0, 0]);
264 self.buf.extend_from_slice(kind);
265 at
266 }
267 pub fn start_full(&mut self, kind: &[u8; 4], version: u8, flags: u32) -> usize {
268 let at = self.start(kind);
269 self.u32(((version as u32) << 24) | (flags & 0xFF_FFFF));
270 at
271 }
272 pub fn end(&mut self, at: usize) {
273 let size = (self.buf.len() - at) as u32;
274 self.buf[at..at + 4].copy_from_slice(&size.to_be_bytes());
275 }
276 pub fn leaf(&mut self, kind: &[u8; 4], payload: &[u8]) {
277 let at = self.start(kind);
278 self.bytes(payload);
279 self.end(at);
280 }
281 pub fn u8(&mut self, v: u8) {
282 self.buf.push(v);
283 }
284 pub fn u16(&mut self, v: u16) {
285 self.buf.extend_from_slice(&v.to_be_bytes());
286 }
287 pub fn i16(&mut self, v: i16) {
288 self.buf.extend_from_slice(&v.to_be_bytes());
289 }
290 pub fn u32(&mut self, v: u32) {
291 self.buf.extend_from_slice(&v.to_be_bytes());
292 }
293 pub fn i32(&mut self, v: i32) {
294 self.buf.extend_from_slice(&v.to_be_bytes());
295 }
296 pub fn u64(&mut self, v: u64) {
297 self.buf.extend_from_slice(&v.to_be_bytes());
298 }
299 pub fn i64(&mut self, v: i64) {
300 self.buf.extend_from_slice(&v.to_be_bytes());
301 }
302 pub fn bytes(&mut self, b: &[u8]) {
303 self.buf.extend_from_slice(b);
304 }
305 pub fn zeros(&mut self, n: usize) {
306 self.buf.resize(self.buf.len() + n, 0);
307 }
308 pub fn len(&self) -> usize {
309 self.buf.len()
310 }
311}