zune_jpeg/
errors.rs

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::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}