1/*
2 * Copyright (c) 2023.
3 *
4 * This software is free software;
5 *
6 * You can redistribute it or modify it under terms of the MIT, Apache License or Zlib license
7 */
8
9//! Contains most common errors that may be encountered in decoding a Decoder
10//! image
11
12use alloc::string::String;
13use core::fmt::{Debug, Display, Formatter};
14
15use crate::misc::{
16 START_OF_FRAME_EXT_AR, START_OF_FRAME_EXT_SEQ, START_OF_FRAME_LOS_SEQ,
17 START_OF_FRAME_LOS_SEQ_AR, START_OF_FRAME_PROG_DCT_AR
18};
19
20/// Common Decode errors
21#[allow(clippy::module_name_repetitions)]
22#[derive(Clone)]
23pub enum DecodeErrors {
24 /// Any other thing we do not know
25 Format(String),
26 /// Any other thing we do not know but we
27 /// don't need to allocate space on the heap
28 FormatStatic(&'static str),
29 /// Illegal Magic Bytes
30 IllegalMagicBytes(u16),
31 /// problems with the Huffman Tables in a Decoder file
32 HuffmanDecode(String),
33 /// Image has zero width
34 ZeroError,
35 /// Discrete Quantization Tables error
36 DqtError(String),
37 /// Start of scan errors
38 SosError(String),
39 /// Start of frame errors
40 SofError(String),
41 /// UnsupportedImages
42 Unsupported(UnsupportedSchemes),
43 /// MCU errors
44 MCUError(String),
45 /// Exhausted data
46 ExhaustedData,
47 /// Large image dimensions(Corrupted data)?
48 LargeDimensions(usize),
49 /// Too small output for size
50 TooSmallOutput(usize, usize)
51}
52
53#[cfg(feature = "std")]
54impl std::error::Error for DecodeErrors {}
55
56impl From<&'static str> for DecodeErrors {
57 fn from(data: &'static str) -> Self {
58 return Self::FormatStatic(data);
59 }
60}
61
62impl Debug for DecodeErrors {
63 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
64 match &self
65 {
66 Self::Format(ref a) => write!(f, "{a:?}"),
67 Self::FormatStatic(a) => write!(f, "{:?}", &a),
68
69 Self::HuffmanDecode(ref reason) =>
70 {
71 write!(f, "Error decoding huffman values: {reason}")
72 }
73 Self::ZeroError => write!(f, "Image width or height is set to zero, cannot continue"),
74 Self::DqtError(ref reason) => write!(f, "Error parsing DQT segment. Reason:{reason}"),
75 Self::SosError(ref reason) => write!(f, "Error parsing SOS Segment. Reason:{reason}"),
76 Self::SofError(ref reason) => write!(f, "Error parsing SOF segment. Reason:{reason}"),
77 Self::IllegalMagicBytes(bytes) =>
78 {
79 write!(f, "Error parsing image. Illegal start bytes:{bytes:X}")
80 }
81 Self::MCUError(ref reason) => write!(f, "Error in decoding MCU. Reason {reason}"),
82 Self::Unsupported(ref image_type) =>
83 {
84 write!(f, "{image_type:?}")
85 }
86 Self::ExhaustedData => write!(f, "Exhausted data in the image"),
87 Self::LargeDimensions(ref dimensions) => write!(
88 f,
89 "Too large dimensions {dimensions},library supports up to {}", crate::decoder::MAX_DIMENSIONS
90 ),
91 Self::TooSmallOutput(expected, found) => write!(f, "Too small output, expected buffer with at least {expected} bytes but got one with {found} bytes")
92 }
93 }
94}
95
96impl Display for DecodeErrors {
97 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
98 write!(f, "{self:?}")
99 }
100}
101
102/// Contains Unsupported/Yet-to-be supported Decoder image encoding types.
103#[derive(Eq, PartialEq, Copy, Clone)]
104pub enum UnsupportedSchemes {
105 /// SOF_1 Extended sequential DCT,Huffman coding
106 ExtendedSequentialHuffman,
107 /// Lossless (sequential), huffman coding,
108 LosslessHuffman,
109 /// Extended sequential DEC, arithmetic coding
110 ExtendedSequentialDctArithmetic,
111 /// Progressive DCT, arithmetic coding,
112 ProgressiveDctArithmetic,
113 /// Lossless ( sequential), arithmetic coding
114 LosslessArithmetic
115}
116
117impl Debug for UnsupportedSchemes {
118 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
119 match &self {
120 Self::ExtendedSequentialHuffman => {
121 write!(f, "The library cannot yet decode images encoded using Extended Sequential Huffman encoding scheme yet.")
122 }
123 Self::LosslessHuffman => {
124 write!(f, "The library cannot yet decode images encoded with Lossless Huffman encoding scheme")
125 }
126 Self::ExtendedSequentialDctArithmetic => {
127 write!(f,"The library cannot yet decode Images Encoded with Extended Sequential DCT Arithmetic scheme")
128 }
129 Self::ProgressiveDctArithmetic => {
130 write!(f,"The library cannot yet decode images encoded with Progressive DCT Arithmetic scheme")
131 }
132 Self::LosslessArithmetic => {
133 write!(f,"The library cannot yet decode images encoded with Lossless Arithmetic encoding scheme")
134 }
135 }
136 }
137}
138
139impl UnsupportedSchemes {
140 #[must_use]
141 /// Create an unsupported scheme from an integer
142 ///
143 /// # Returns
144 /// `Some(UnsupportedScheme)` if the int refers to a specific scheme,
145 /// otherwise returns `None`
146 pub fn from_int(int: u8) -> Option<UnsupportedSchemes> {
147 let int: u16 = u16::from_be_bytes([0xff, int]);
148
149 match int {
150 START_OF_FRAME_PROG_DCT_AR => Some(Self::ProgressiveDctArithmetic),
151 START_OF_FRAME_LOS_SEQ => Some(Self::LosslessHuffman),
152 START_OF_FRAME_LOS_SEQ_AR => Some(Self::LosslessArithmetic),
153 START_OF_FRAME_EXT_SEQ => Some(Self::ExtendedSequentialHuffman),
154 START_OF_FRAME_EXT_AR => Some(Self::ExtendedSequentialDctArithmetic),
155 _ => None
156 }
157 }
158}
159