hayro_jpeg2000/
error.rs

1//! Error types for JPEG 2000 decoding.
2
3use core::fmt;
4
5/// The main error type for JPEG 2000 decoding operations.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum DecodeError {
8    /// Errors related to JP2 file format and box parsing.
9    Format(FormatError),
10    /// Errors related to codestream markers.
11    Marker(MarkerError),
12    /// Errors related to tile processing.
13    Tile(TileError),
14    /// Errors related to image dimensions and validation.
15    Validation(ValidationError),
16    /// Errors related to decoding operations.
17    Decoding(DecodingError),
18    /// Errors related to color space and component handling.
19    Color(ColorError),
20}
21
22/// Errors related to JP2 file format and box parsing.
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum FormatError {
25    /// Invalid JP2 signature.
26    InvalidSignature,
27    /// Invalid JP2 file type.
28    InvalidFileType,
29    /// Invalid or malformed JP2 box.
30    InvalidBox,
31    /// Missing codestream data.
32    MissingCodestream,
33    /// Unsupported JP2 image format.
34    Unsupported,
35}
36
37/// Errors related to codestream markers.
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum MarkerError {
40    /// Invalid marker encountered.
41    Invalid,
42    /// Unsupported marker encountered.
43    Unsupported,
44    /// Expected a specific marker.
45    Expected(&'static str),
46    /// Missing a required marker.
47    Missing(&'static str),
48    /// Failed to read or parse a marker.
49    ParseFailure(&'static str),
50}
51
52/// Errors related to tile processing.
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum TileError {
55    /// Invalid image tile was encountered.
56    Invalid,
57    /// Invalid tile index in tile-part header.
58    InvalidIndex,
59    /// Invalid tile or image offsets.
60    InvalidOffsets,
61    /// PPT marker present when PPM marker exists in main header.
62    PpmPptConflict,
63}
64
65/// Errors related to image dimensions and validation.
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub enum ValidationError {
68    /// Invalid image dimensions.
69    InvalidDimensions,
70    /// Image dimensions exceed supported limits.
71    ImageTooLarge,
72    /// Image has too many channels.
73    TooManyChannels,
74    /// Invalid component metadata.
75    InvalidComponentMetadata,
76    /// Invalid progression order.
77    InvalidProgressionOrder,
78    /// Invalid transformation type.
79    InvalidTransformation,
80    /// Invalid quantization style.
81    InvalidQuantizationStyle,
82    /// Missing exponents for precinct sizes.
83    MissingPrecinctExponents,
84    /// Not enough exponents provided in header.
85    InsufficientExponents,
86    /// Missing exponent step size.
87    MissingStepSize,
88    /// Invalid quantization exponents.
89    InvalidExponents,
90}
91
92/// Errors related to decoding operations.
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub enum DecodingError {
95    /// An error occurred while decoding a code-block.
96    CodeBlockDecodeFailure,
97    /// Number of bitplanes in a code-block is too large.
98    TooManyBitplanes,
99    /// A code-block contains too many coding passes.
100    TooManyCodingPasses,
101    /// Invalid number of bitplanes in a code-block.
102    InvalidBitplaneCount,
103    /// A precinct was invalid.
104    InvalidPrecinct,
105    /// A progression iterator ver invalid.
106    InvalidProgressionIterator,
107    /// Unexpected end of data.
108    UnexpectedEof,
109}
110
111/// Errors related to color space and component handling.
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum ColorError {
114    /// Multi-component transform failed.
115    Mct,
116    /// Failed to resolve palette indices.
117    PaletteResolutionFailed,
118    /// Failed to convert from sYCC to RGB.
119    SyccConversionFailed,
120    /// Failed to convert from LAB to RGB.
121    LabConversionFailed,
122}
123
124impl fmt::Display for DecodeError {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        match self {
127            Self::Format(e) => write!(f, "{e}"),
128            Self::Marker(e) => write!(f, "{e}"),
129            Self::Tile(e) => write!(f, "{e}"),
130            Self::Validation(e) => write!(f, "{e}"),
131            Self::Decoding(e) => write!(f, "{e}"),
132            Self::Color(e) => write!(f, "{e}"),
133        }
134    }
135}
136
137impl fmt::Display for FormatError {
138    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139        match self {
140            Self::InvalidSignature => write!(f, "invalid JP2 signature"),
141            Self::InvalidFileType => write!(f, "invalid JP2 file type"),
142            Self::InvalidBox => write!(f, "invalid JP2 box"),
143            Self::MissingCodestream => write!(f, "missing codestream data"),
144            Self::Unsupported => write!(f, "unsupported JP2 image"),
145        }
146    }
147}
148
149impl fmt::Display for MarkerError {
150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151        match self {
152            Self::Invalid => write!(f, "invalid marker"),
153            Self::Unsupported => write!(f, "unsupported marker"),
154            Self::Expected(marker) => write!(f, "expected {marker} marker"),
155            Self::Missing(marker) => write!(f, "missing {marker} marker"),
156            Self::ParseFailure(marker) => write!(f, "failed to parse {marker} marker"),
157        }
158    }
159}
160
161impl fmt::Display for TileError {
162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163        match self {
164            Self::Invalid => write!(f, "image contains no tiles"),
165            Self::InvalidIndex => write!(f, "invalid tile index in tile-part header"),
166            Self::InvalidOffsets => write!(f, "invalid tile offsets"),
167            Self::PpmPptConflict => {
168                write!(
169                    f,
170                    "PPT marker present when PPM marker exists in main header"
171                )
172            }
173        }
174    }
175}
176
177impl fmt::Display for ValidationError {
178    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179        match self {
180            Self::InvalidDimensions => write!(f, "invalid image dimensions"),
181            Self::ImageTooLarge => write!(f, "image is too large"),
182            Self::TooManyChannels => write!(f, "image has too many channels"),
183            Self::InvalidComponentMetadata => write!(f, "invalid component metadata"),
184            Self::InvalidProgressionOrder => write!(f, "invalid progression order"),
185            Self::InvalidTransformation => write!(f, "invalid transformation type"),
186            Self::InvalidQuantizationStyle => write!(f, "invalid quantization style"),
187            Self::MissingPrecinctExponents => {
188                write!(f, "missing exponents for precinct sizes")
189            }
190            Self::InsufficientExponents => {
191                write!(f, "not enough exponents provided in header")
192            }
193            Self::MissingStepSize => write!(f, "missing exponent step size"),
194            Self::InvalidExponents => write!(f, "invalid quantization exponents"),
195        }
196    }
197}
198
199impl fmt::Display for DecodingError {
200    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201        match self {
202            Self::CodeBlockDecodeFailure => write!(f, "failed to decode code-block"),
203            Self::TooManyBitplanes => write!(f, "number of bitplanes is too large"),
204            Self::TooManyCodingPasses => {
205                write!(f, "code-block contains too many coding passes")
206            }
207            Self::InvalidBitplaneCount => write!(f, "invalid number of bitplanes"),
208            Self::InvalidPrecinct => write!(f, "a precinct was invalid"),
209            Self::InvalidProgressionIterator => {
210                write!(f, "a progression iterator was invalid")
211            }
212            Self::UnexpectedEof => write!(f, "unexpected end of data"),
213        }
214    }
215}
216
217impl fmt::Display for ColorError {
218    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219        match self {
220            Self::Mct => write!(f, "multi-component transform failed"),
221            Self::PaletteResolutionFailed => write!(f, "failed to resolve palette indices"),
222            Self::SyccConversionFailed => write!(f, "failed to convert from sYCC to RGB"),
223            Self::LabConversionFailed => write!(f, "failed to convert from LAB to RGB"),
224        }
225    }
226}
227
228impl core::error::Error for DecodeError {}
229impl core::error::Error for FormatError {}
230impl core::error::Error for MarkerError {}
231impl core::error::Error for TileError {}
232impl core::error::Error for ValidationError {}
233impl core::error::Error for DecodingError {}
234impl core::error::Error for ColorError {}
235
236impl From<FormatError> for DecodeError {
237    fn from(e: FormatError) -> Self {
238        Self::Format(e)
239    }
240}
241
242impl From<MarkerError> for DecodeError {
243    fn from(e: MarkerError) -> Self {
244        Self::Marker(e)
245    }
246}
247
248impl From<TileError> for DecodeError {
249    fn from(e: TileError) -> Self {
250        Self::Tile(e)
251    }
252}
253
254impl From<ValidationError> for DecodeError {
255    fn from(e: ValidationError) -> Self {
256        Self::Validation(e)
257    }
258}
259
260impl From<DecodingError> for DecodeError {
261    fn from(e: DecodingError) -> Self {
262        Self::Decoding(e)
263    }
264}
265
266impl From<ColorError> for DecodeError {
267    fn from(e: ColorError) -> Self {
268        Self::Color(e)
269    }
270}
271
272/// Result type for JPEG 2000 decoding operations.
273pub type Result<T> = core::result::Result<T, DecodeError>;
274
275macro_rules! bail {
276    ($err:expr) => {
277        return Err($err.into())
278    };
279}
280
281macro_rules! err {
282    ($err:expr) => {
283        Err($err.into())
284    };
285}
286
287pub(crate) use bail;
288pub(crate) use err;