hayro_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    /// Symbol ID out of valid range.
102    OutOfRange,
103}
104
105impl fmt::Display for DecodeError {
106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107        match self {
108            Self::Parse(e) => write!(f, "{e}"),
109            Self::Format(e) => write!(f, "{e}"),
110            Self::Segment(e) => write!(f, "{e}"),
111            Self::Huffman(e) => write!(f, "{e}"),
112            Self::Region(e) => write!(f, "{e}"),
113            Self::Template(e) => write!(f, "{e}"),
114            Self::Symbol(e) => write!(f, "{e}"),
115            Self::Overflow => write!(f, "arithmetic overflow"),
116            Self::Unsupported => write!(f, "unsupported feature"),
117        }
118    }
119}
120
121impl fmt::Display for ParseError {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        match self {
124            Self::UnexpectedEof => write!(f, "unexpected end of input"),
125        }
126    }
127}
128
129impl fmt::Display for FormatError {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        match self {
132            Self::InvalidHeader => write!(f, "invalid JBIG2 file header"),
133            Self::ReservedBits => write!(f, "reserved bits must be zero"),
134            Self::MissingPageInfo => write!(f, "missing page information segment"),
135            Self::UnknownPageHeight => write!(f, "page height unknown with no stripe segments"),
136        }
137    }
138}
139
140impl fmt::Display for SegmentError {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        match self {
143            Self::UnknownType => write!(f, "unknown or reserved segment type"),
144            Self::InvalidReferredCount => write!(f, "invalid referred-to segment count"),
145            Self::InvalidReference => write!(f, "segment refers to larger segment number"),
146            Self::MissingEndMarker => write!(f, "missing end marker for unknown-length region"),
147            Self::MissingPatternDictionary => write!(f, "missing required pattern dictionary"),
148        }
149    }
150}
151
152impl fmt::Display for HuffmanError {
153    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154        match self {
155            Self::InvalidCode => write!(f, "invalid Huffman code"),
156            Self::InvalidSelection => write!(f, "invalid Huffman table selection"),
157            Self::MissingTables => write!(f, "not enough referred Huffman tables"),
158            Self::UnexpectedOob => write!(f, "unexpected out-of-band value"),
159        }
160    }
161}
162
163impl fmt::Display for RegionError {
164    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165        match self {
166            Self::InvalidCombinationOperator => write!(f, "invalid combination operator"),
167            Self::InvalidDimension => write!(f, "invalid dimension value"),
168            Self::GrayScaleOutOfRange => write!(f, "gray-scale value exceeds pattern count"),
169        }
170    }
171}
172
173impl fmt::Display for TemplateError {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        match self {
176            Self::Invalid => write!(f, "invalid template value"),
177            Self::InvalidAtPixel => write!(f, "invalid adaptive template pixel location"),
178        }
179    }
180}
181
182impl fmt::Display for SymbolError {
183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184        match self {
185            Self::NoSymbols => write!(f, "no symbols available"),
186            Self::OutOfRange => write!(f, "symbol ID out of range"),
187        }
188    }
189}
190
191impl core::error::Error for DecodeError {}
192impl core::error::Error for ParseError {}
193impl core::error::Error for FormatError {}
194impl core::error::Error for SegmentError {}
195impl core::error::Error for HuffmanError {}
196impl core::error::Error for RegionError {}
197impl core::error::Error for TemplateError {}
198impl core::error::Error for SymbolError {}
199
200impl From<ParseError> for DecodeError {
201    fn from(e: ParseError) -> Self {
202        Self::Parse(e)
203    }
204}
205
206impl From<FormatError> for DecodeError {
207    fn from(e: FormatError) -> Self {
208        Self::Format(e)
209    }
210}
211
212impl From<SegmentError> for DecodeError {
213    fn from(e: SegmentError) -> Self {
214        Self::Segment(e)
215    }
216}
217
218impl From<HuffmanError> for DecodeError {
219    fn from(e: HuffmanError) -> Self {
220        Self::Huffman(e)
221    }
222}
223
224impl From<RegionError> for DecodeError {
225    fn from(e: RegionError) -> Self {
226        Self::Region(e)
227    }
228}
229
230impl From<TemplateError> for DecodeError {
231    fn from(e: TemplateError) -> Self {
232        Self::Template(e)
233    }
234}
235
236impl From<SymbolError> for DecodeError {
237    fn from(e: SymbolError) -> Self {
238        Self::Symbol(e)
239    }
240}
241
242/// Result type for JBIG2 decoding operations.
243pub type Result<T> = core::result::Result<T, DecodeError>;
244
245macro_rules! bail {
246    ($err:expr) => {
247        return Err($err.into())
248    };
249}
250
251macro_rules! err {
252    ($err:expr) => {
253        Err($err.into())
254    };
255}
256
257pub(crate) use bail;
258pub(crate) use err;