Skip to main content

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