jxl_bitstream/container/
box_header.rs1use crate::Error;
2
3#[derive(Debug, Clone)]
5pub struct ContainerBoxHeader {
6 pub(super) ty: ContainerBoxType,
7 box_size: Option<u64>,
8 is_last: bool,
9}
10
11pub enum HeaderParseResult {
13 Done {
15 header: ContainerBoxHeader,
16 header_size: usize,
17 },
18 NeedMoreData,
20}
21
22impl ContainerBoxHeader {
23 pub(super) fn parse(buf: &[u8]) -> Result<HeaderParseResult, Error> {
24 let (tbox, box_size, header_size) = match *buf {
25 #[rustfmt::skip]
26 [0, 0, 0, 1, t0, t1, t2, t3, s0, s1, s2, s3, s4, s5, s6, s7, ..] => {
27 let xlbox = u64::from_be_bytes([s0, s1, s2, s3, s4, s5, s6, s7]);
28 let tbox = ContainerBoxType([t0, t1, t2, t3]);
29 let xlbox = xlbox.checked_sub(16).ok_or(Error::InvalidBox)?;
30 (tbox, Some(xlbox), 16)
31 }
32 [s0, s1, s2, s3, t0, t1, t2, t3, ..] => {
33 let sbox = u32::from_be_bytes([s0, s1, s2, s3]);
34 let tbox = ContainerBoxType([t0, t1, t2, t3]);
35 let sbox = if sbox == 0 {
36 None
37 } else if let Some(sbox) = sbox.checked_sub(8) {
38 Some(sbox as u64)
39 } else {
40 return Err(Error::InvalidBox);
41 };
42 (tbox, sbox, 8)
43 }
44 _ => return Ok(HeaderParseResult::NeedMoreData),
45 };
46 let is_last = box_size.is_none();
47
48 let header = Self {
49 ty: tbox,
50 box_size,
51 is_last,
52 };
53 Ok(HeaderParseResult::Done {
54 header,
55 header_size,
56 })
57 }
58}
59
60impl ContainerBoxHeader {
61 #[inline]
62 pub fn box_type(&self) -> ContainerBoxType {
63 self.ty
64 }
65
66 #[inline]
67 pub fn box_size(&self) -> Option<u64> {
68 self.box_size
69 }
70
71 #[inline]
72 pub fn is_last(&self) -> bool {
73 self.is_last
74 }
75}
76
77#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
81pub struct ContainerBoxType(pub [u8; 4]);
82
83impl ContainerBoxType {
84 pub const JXL: Self = Self(*b"JXL ");
86
87 pub const FILE_TYPE: Self = Self(*b"ftyp");
89
90 pub const JXL_LEVEL: Self = Self(*b"jxll");
92
93 pub const JUMBF: Self = Self(*b"jumb");
95
96 pub const EXIF: Self = Self(*b"Exif");
98
99 pub const XML: Self = Self(*b"xml ");
101
102 pub const BROTLI_COMPRESSED: Self = Self(*b"brob");
104
105 pub const FRAME_INDEX: Self = Self(*b"jxli");
107
108 pub const CODESTREAM: Self = Self(*b"jxlc");
110
111 pub const PARTIAL_CODESTREAM: Self = Self(*b"jxlp");
113
114 pub const JPEG_RECONSTRUCTION: Self = Self(*b"jbrd");
116
117 pub const HDR_GAIN_MAP: Self = Self(*b"jhgm");
119}