1use core::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum DecodeError {
9 Format(FormatError),
11 Marker(MarkerError),
13 Tile(TileError),
15 Validation(ValidationError),
17 Decoding(DecodingError),
19 Color(ColorError),
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum FormatError {
27 InvalidSignature,
29 InvalidFileType,
31 InvalidBox,
33 MissingCodestream,
35 Unsupported,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41#[non_exhaustive]
42pub enum MarkerError {
43 Invalid,
45 Unsupported,
47 Expected(&'static str),
49 Missing(&'static str),
51 ParseFailure(&'static str),
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[non_exhaustive]
58pub enum TileError {
59 Invalid,
61 InvalidIndex,
63 InvalidOffsets,
65 PpmPptConflict,
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71#[non_exhaustive]
72pub enum ValidationError {
73 InvalidDimensions,
75 ImageTooLarge,
77 TooManyChannels,
79 TooManyTiles,
81 InvalidComponentMetadata,
83 InvalidChannelDefinition,
85 InvalidProgressionOrder,
87 InvalidTransformation,
89 InvalidQuantizationStyle,
91 MissingPrecinctExponents,
93 InsufficientExponents,
95 MissingStepSize,
97 InvalidExponents,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103#[non_exhaustive]
104pub enum DecodingError {
105 CodeBlockDecodeFailure,
107 UnsupportedFeature(&'static str),
109 TooManyBitplanes,
111 TooManyCodingPasses,
113 InvalidBitplaneCount,
115 InvalidPrecinct,
117 InvalidProgressionIterator,
119 UnexpectedEof,
121 OutputBufferTooSmall,
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
127#[non_exhaustive]
128pub enum ColorError {
129 Mct,
131 PaletteResolutionFailed,
133 SyccConversionFailed,
135 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
293pub 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;