Skip to main content

pdfluent_jbig2/
error.rs

1//! Error types for JBIG2 decoding.
2
3use core::fmt;
4
5/// The main error type for JBIG2 decoding operations.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum DecodeError {
8    /// Errors related to reading/parsing data.
9    Parse(ParseError),
10    /// Errors related to file structure.
11    Format(FormatError),
12    /// Errors related to segment processing.
13    Segment(SegmentError),
14    /// Errors related to Huffman decoding.
15    Huffman(HuffmanError),
16    /// Errors related to region parameters.
17    Region(RegionError),
18    /// Errors related to template configuration.
19    Template(TemplateError),
20    /// Errors related to symbol handling.
21    Symbol(SymbolError),
22    /// Arithmetic overflow in calculations.
23    Overflow,
24    /// Feature not yet implemented.
25    Unsupported,
26}
27
28/// Errors related to reading/parsing data.
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub enum ParseError {
31    /// Unexpected end of input.
32    UnexpectedEof,
33}
34
35/// Errors related to file structure.
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum FormatError {
38    /// Invalid file header signature.
39    InvalidHeader,
40    /// Reserved bits are not zero.
41    ReservedBits,
42    /// Missing required page information segment.
43    MissingPageInfo,
44    /// Page height unknown with no stripe segments.
45    UnknownPageHeight,
46}
47
48/// Errors related to segment processing.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum SegmentError {
51    /// Unknown or reserved segment type.
52    UnknownType,
53    /// Invalid referred-to segment count.
54    InvalidReferredCount,
55    /// Segment refers to a larger segment number.
56    InvalidReference,
57    /// Missing end marker for unknown-length region.
58    MissingEndMarker,
59    /// Missing required pattern dictionary.
60    MissingPatternDictionary,
61}
62
63/// Errors related to Huffman decoding.
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum HuffmanError {
66    /// Invalid Huffman code sequence.
67    InvalidCode,
68    /// Invalid Huffman table selection.
69    InvalidSelection,
70    /// Not enough referred Huffman tables.
71    MissingTables,
72    /// Unexpected out-of-band value.
73    UnexpectedOob,
74}
75
76/// Errors related to region parameters.
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum RegionError {
79    /// Invalid combination operator value.
80    InvalidCombinationOperator,
81    /// Region with invalid dimension.
82    InvalidDimension,
83    /// Gray-scale value exceeds pattern count.
84    GrayScaleOutOfRange,
85}
86
87/// Errors related to template configuration.
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum TemplateError {
90    /// An invalid template value was used.
91    Invalid,
92    /// Invalid adaptive template pixel location.
93    InvalidAtPixel,
94}
95
96/// Errors related to symbol handling.
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum SymbolError {
99    /// No symbols available for text region.
100    NoSymbols,
101    /// The symbol dictionary contains more symbols than expected.
102    TooManySymbols,
103    /// Symbol ID out of valid range.
104    OutOfRange,
105    /// Unexpected out-of-band value.
106    UnexpectedOob,
107    /// An invalid symbol was encountered.
108    Invalid,
109}
110
111impl fmt::Display for DecodeError {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        match self {
114            Self::Parse(e) => write!(f, "{e}"),
115            Self::Format(e) => write!(f, "{e}"),
116            Self::Segment(e) => write!(f, "{e}"),
117            Self::Huffman(e) => write!(f, "{e}"),
118            Self::Region(e) => write!(f, "{e}"),
119            Self::Template(e) => write!(f, "{e}"),
120            Self::Symbol(e) => write!(f, "{e}"),
121            Self::Overflow => write!(f, "arithmetic overflow"),
122            Self::Unsupported => write!(f, "unsupported feature"),
123        }
124    }
125}
126
127impl fmt::Display for ParseError {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        match self {
130            Self::UnexpectedEof => write!(f, "unexpected end of input"),
131        }
132    }
133}
134
135impl fmt::Display for FormatError {
136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137        match self {
138            Self::InvalidHeader => write!(f, "invalid JBIG2 file header"),
139            Self::ReservedBits => write!(f, "reserved bits must be zero"),
140            Self::MissingPageInfo => write!(f, "missing page information segment"),
141            Self::UnknownPageHeight => write!(f, "page height unknown with no stripe segments"),
142        }
143    }
144}
145
146impl fmt::Display for SegmentError {
147    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148        match self {
149            Self::UnknownType => write!(f, "unknown or reserved segment type"),
150            Self::InvalidReferredCount => write!(f, "invalid referred-to segment count"),
151            Self::InvalidReference => write!(f, "segment refers to larger segment number"),
152            Self::MissingEndMarker => write!(f, "missing end marker for unknown-length region"),
153            Self::MissingPatternDictionary => write!(f, "missing required pattern dictionary"),
154        }
155    }
156}
157
158impl fmt::Display for HuffmanError {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        match self {
161            Self::InvalidCode => write!(f, "invalid Huffman code"),
162            Self::InvalidSelection => write!(f, "invalid Huffman table selection"),
163            Self::MissingTables => write!(f, "not enough referred Huffman tables"),
164            Self::UnexpectedOob => write!(f, "unexpected out-of-band value"),
165        }
166    }
167}
168
169impl fmt::Display for RegionError {
170    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171        match self {
172            Self::InvalidCombinationOperator => write!(f, "invalid combination operator"),
173            Self::InvalidDimension => write!(f, "invalid dimension value"),
174            Self::GrayScaleOutOfRange => write!(f, "gray-scale value exceeds pattern count"),
175        }
176    }
177}
178
179impl fmt::Display for TemplateError {
180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181        match self {
182            Self::Invalid => write!(f, "invalid template value"),
183            Self::InvalidAtPixel => write!(f, "invalid adaptive template pixel location"),
184        }
185    }
186}
187
188impl fmt::Display for SymbolError {
189    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190        match self {
191            Self::NoSymbols => write!(f, "no symbols available"),
192            Self::OutOfRange => write!(f, "symbol ID out of range"),
193            Self::UnexpectedOob => write!(f, "unexpected out-of-band value"),
194            Self::TooManySymbols => write!(f, "symbol dictionary contains too many symbols"),
195            Self::Invalid => write!(f, "invalid symbol encountered"),
196        }
197    }
198}
199
200impl core::error::Error for DecodeError {}
201impl core::error::Error for ParseError {}
202impl core::error::Error for FormatError {}
203impl core::error::Error for SegmentError {}
204impl core::error::Error for HuffmanError {}
205impl core::error::Error for RegionError {}
206impl core::error::Error for TemplateError {}
207impl core::error::Error for SymbolError {}
208
209impl From<ParseError> for DecodeError {
210    fn from(e: ParseError) -> Self {
211        Self::Parse(e)
212    }
213}
214
215impl From<FormatError> for DecodeError {
216    fn from(e: FormatError) -> Self {
217        Self::Format(e)
218    }
219}
220
221impl From<SegmentError> for DecodeError {
222    fn from(e: SegmentError) -> Self {
223        Self::Segment(e)
224    }
225}
226
227impl From<HuffmanError> for DecodeError {
228    fn from(e: HuffmanError) -> Self {
229        Self::Huffman(e)
230    }
231}
232
233impl From<RegionError> for DecodeError {
234    fn from(e: RegionError) -> Self {
235        Self::Region(e)
236    }
237}
238
239impl From<TemplateError> for DecodeError {
240    fn from(e: TemplateError) -> Self {
241        Self::Template(e)
242    }
243}
244
245impl From<SymbolError> for DecodeError {
246    fn from(e: SymbolError) -> Self {
247        Self::Symbol(e)
248    }
249}
250
251/// Result type for JBIG2 decoding operations.
252pub type Result<T> = core::result::Result<T, DecodeError>;
253
254macro_rules! bail {
255    ($err:expr) => {
256        return Err($err.into())
257    };
258}
259
260macro_rules! err {
261    ($err:expr) => {
262        Err($err.into())
263    };
264}
265
266pub(crate) use bail;
267pub(crate) use err;