1use core::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum DecodeError {
8 Format(FormatError),
10 Marker(MarkerError),
12 Tile(TileError),
14 Validation(ValidationError),
16 Decoding(DecodingError),
18 Color(ColorError),
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum FormatError {
25 InvalidSignature,
27 InvalidFileType,
29 InvalidBox,
31 MissingCodestream,
33 Unsupported,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum MarkerError {
40 Invalid,
42 Unsupported,
44 Expected(&'static str),
46 Missing(&'static str),
48 ParseFailure(&'static str),
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum TileError {
55 Invalid,
57 InvalidIndex,
59 InvalidOffsets,
61 PpmPptConflict,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub enum ValidationError {
68 InvalidDimensions,
70 ImageTooLarge,
72 TooManyChannels,
74 InvalidComponentMetadata,
76 InvalidProgressionOrder,
78 InvalidTransformation,
80 InvalidQuantizationStyle,
82 MissingPrecinctExponents,
84 InsufficientExponents,
86 MissingStepSize,
88 InvalidExponents,
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub enum DecodingError {
95 CodeBlockDecodeFailure,
97 TooManyBitplanes,
99 TooManyCodingPasses,
101 InvalidBitplaneCount,
103 InvalidPrecinct,
105 InvalidProgressionIterator,
107 UnexpectedEof,
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum ColorError {
114 Mct,
116 PaletteResolutionFailed,
118 SyccConversionFailed,
120 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
272pub 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;