jxl_bitstream/
container.rs

1//! Types for JPEG XL container format.
2
3mod box_header;
4mod parse;
5
6pub use box_header::*;
7pub use parse::*;
8
9/// Parser that detects the kind of bitstream and emits parser events.
10#[derive(Debug, Default)]
11pub struct ContainerParser {
12    state: DetectState,
13    jxlp_index_state: JxlpIndexState,
14    previous_consumed_bytes: usize,
15}
16
17#[derive(Debug, Default)]
18enum DetectState {
19    #[default]
20    WaitingSignature,
21    WaitingBoxHeader,
22    WaitingJxlpIndex(ContainerBoxHeader),
23    InAuxBox {
24        header: ContainerBoxHeader,
25        brotli_box_type: Option<ContainerBoxType>,
26        bytes_left: Option<usize>,
27    },
28    InCodestream {
29        kind: BitstreamKind,
30        bytes_left: Option<usize>,
31        pending_no_more_aux_box: bool,
32    },
33}
34
35/// Structure of the decoded bitstream.
36#[derive(Debug, Copy, Clone, Eq, PartialEq)]
37pub enum BitstreamKind {
38    /// Decoder can't determine structure of the bitstream.
39    Unknown,
40    /// Bitstream is a direct JPEG XL codestream without box structure.
41    BareCodestream,
42    /// Bitstream is a JPEG XL container with box structure.
43    Container,
44    /// Bitstream is not a valid JPEG XL image.
45    Invalid,
46}
47
48#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
49enum JxlpIndexState {
50    #[default]
51    Initial,
52    SingleJxlc,
53    Jxlp(u32),
54    JxlpFinished,
55}
56
57impl ContainerParser {
58    /// Creates a new parser.
59    pub fn new() -> Self {
60        Self::default()
61    }
62
63    /// Returns the kind of this bitstream currently recognized.
64    pub fn kind(&self) -> BitstreamKind {
65        match self.state {
66            DetectState::WaitingSignature => BitstreamKind::Unknown,
67            DetectState::WaitingBoxHeader
68            | DetectState::WaitingJxlpIndex(..)
69            | DetectState::InAuxBox { .. } => BitstreamKind::Container,
70            DetectState::InCodestream { kind, .. } => kind,
71        }
72    }
73
74    /// Feeds bytes to the parser, and receives parser events.
75    ///
76    /// The parser might not consume all of the buffer. Use [`previous_consumed_bytes`] to get how
77    /// many bytes are consumed. Bytes not consumed by the parser should be fed into the parser
78    /// again.
79    ///
80    /// [`previous_consumed_bytes`]: Self::previous_consumed_bytes
81    pub fn feed_bytes<'inner, 'buf>(
82        &'inner mut self,
83        input: &'buf [u8],
84    ) -> ParseEvents<'inner, 'buf> {
85        ParseEvents::new(self, input)
86    }
87
88    /// Get how many bytes are consumed by the previous call to [`feed_bytes`].
89    ///
90    /// Bytes not consumed by the parser should be fed into the parser again.
91    ///
92    /// [`feed_bytes`]: Self::feed_bytes
93    pub fn previous_consumed_bytes(&self) -> usize {
94        self.previous_consumed_bytes
95    }
96}