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