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 UnsupportedFeature(&'static str),
99 TooManyBitplanes,
101 TooManyCodingPasses,
103 InvalidBitplaneCount,
105 InvalidPrecinct,
107 InvalidProgressionIterator,
109 UnexpectedEof,
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub enum ColorError {
116 Mct,
118 PaletteResolutionFailed,
120 SyccConversionFailed,
122 LabConversionFailed,
124}
125
126impl fmt::Display for DecodeError {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 match self {
129 Self::Format(e) => write!(f, "{e}"),
130 Self::Marker(e) => write!(f, "{e}"),
131 Self::Tile(e) => write!(f, "{e}"),
132 Self::Validation(e) => write!(f, "{e}"),
133 Self::Decoding(e) => write!(f, "{e}"),
134 Self::Color(e) => write!(f, "{e}"),
135 }
136 }
137}
138
139impl fmt::Display for FormatError {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 match self {
142 Self::InvalidSignature => write!(f, "invalid JP2 signature"),
143 Self::InvalidFileType => write!(f, "invalid JP2 file type"),
144 Self::InvalidBox => write!(f, "invalid JP2 box"),
145 Self::MissingCodestream => write!(f, "missing codestream data"),
146 Self::Unsupported => write!(f, "unsupported JP2 image"),
147 }
148 }
149}
150
151impl fmt::Display for MarkerError {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 match self {
154 Self::Invalid => write!(f, "invalid marker"),
155 Self::Unsupported => write!(f, "unsupported marker"),
156 Self::Expected(marker) => write!(f, "expected {marker} marker"),
157 Self::Missing(marker) => write!(f, "missing {marker} marker"),
158 Self::ParseFailure(marker) => write!(f, "failed to parse {marker} marker"),
159 }
160 }
161}
162
163impl fmt::Display for TileError {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 match self {
166 Self::Invalid => write!(f, "image contains no tiles"),
167 Self::InvalidIndex => write!(f, "invalid tile index in tile-part header"),
168 Self::InvalidOffsets => write!(f, "invalid tile offsets"),
169 Self::PpmPptConflict => {
170 write!(
171 f,
172 "PPT marker present when PPM marker exists in main header"
173 )
174 }
175 }
176 }
177}
178
179impl fmt::Display for ValidationError {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 match self {
182 Self::InvalidDimensions => write!(f, "invalid image dimensions"),
183 Self::ImageTooLarge => write!(f, "image is too large"),
184 Self::TooManyChannels => write!(f, "image has too many channels"),
185 Self::InvalidComponentMetadata => write!(f, "invalid component metadata"),
186 Self::InvalidProgressionOrder => write!(f, "invalid progression order"),
187 Self::InvalidTransformation => write!(f, "invalid transformation type"),
188 Self::InvalidQuantizationStyle => write!(f, "invalid quantization style"),
189 Self::MissingPrecinctExponents => {
190 write!(f, "missing exponents for precinct sizes")
191 }
192 Self::InsufficientExponents => {
193 write!(f, "not enough exponents provided in header")
194 }
195 Self::MissingStepSize => write!(f, "missing exponent step size"),
196 Self::InvalidExponents => write!(f, "invalid quantization exponents"),
197 }
198 }
199}
200
201impl fmt::Display for DecodingError {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 match self {
204 Self::CodeBlockDecodeFailure => write!(f, "failed to decode code-block"),
205 Self::UnsupportedFeature(feature) => {
206 write!(f, "unsupported decoding feature: {feature}")
207 }
208 Self::TooManyBitplanes => write!(f, "number of bitplanes is too large"),
209 Self::TooManyCodingPasses => {
210 write!(f, "code-block contains too many coding passes")
211 }
212 Self::InvalidBitplaneCount => write!(f, "invalid number of bitplanes"),
213 Self::InvalidPrecinct => write!(f, "a precinct was invalid"),
214 Self::InvalidProgressionIterator => {
215 write!(f, "a progression iterator was invalid")
216 }
217 Self::UnexpectedEof => write!(f, "unexpected end of data"),
218 }
219 }
220}
221
222impl fmt::Display for ColorError {
223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224 match self {
225 Self::Mct => write!(f, "multi-component transform failed"),
226 Self::PaletteResolutionFailed => write!(f, "failed to resolve palette indices"),
227 Self::SyccConversionFailed => write!(f, "failed to convert from sYCC to RGB"),
228 Self::LabConversionFailed => write!(f, "failed to convert from LAB to RGB"),
229 }
230 }
231}
232
233impl core::error::Error for DecodeError {}
234impl core::error::Error for FormatError {}
235impl core::error::Error for MarkerError {}
236impl core::error::Error for TileError {}
237impl core::error::Error for ValidationError {}
238impl core::error::Error for DecodingError {}
239impl core::error::Error for ColorError {}
240
241impl From<FormatError> for DecodeError {
242 fn from(e: FormatError) -> Self {
243 Self::Format(e)
244 }
245}
246
247impl From<MarkerError> for DecodeError {
248 fn from(e: MarkerError) -> Self {
249 Self::Marker(e)
250 }
251}
252
253impl From<TileError> for DecodeError {
254 fn from(e: TileError) -> Self {
255 Self::Tile(e)
256 }
257}
258
259impl From<ValidationError> for DecodeError {
260 fn from(e: ValidationError) -> Self {
261 Self::Validation(e)
262 }
263}
264
265impl From<DecodingError> for DecodeError {
266 fn from(e: DecodingError) -> Self {
267 Self::Decoding(e)
268 }
269}
270
271impl From<ColorError> for DecodeError {
272 fn from(e: ColorError) -> Self {
273 Self::Color(e)
274 }
275}
276
277pub type Result<T> = core::result::Result<T, DecodeError>;
279
280macro_rules! bail {
281 ($err:expr) => {
282 return Err($err.into())
283 };
284}
285
286macro_rules! err {
287 ($err:expr) => {
288 Err($err.into())
289 };
290}
291
292pub(crate) use bail;
293pub(crate) use err;