1use std::fmt;
7
8#[non_exhaustive]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum UnsupportedFeature {
16 ProgressiveJpeg,
18 ExtendedSequentialJpeg,
20 ArithmeticCodedJpeg,
23 LosslessJpeg,
25 HierarchicalJpeg,
27 JpegPrecision {
29 bits: u8,
31 },
32 JpegComponentCount {
35 components: u8,
37 },
38 JpegChromaSubsampling,
42}
43
44impl fmt::Display for UnsupportedFeature {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Self::ProgressiveJpeg => write!(f, "progressive JPEG (SOF2)"),
48 Self::ExtendedSequentialJpeg => {
49 write!(f, "extended sequential JPEG (SOF1)")
50 }
51 Self::ArithmeticCodedJpeg => write!(
52 f,
53 "arithmetic-coded JPEG (SOF9/SOF10/SOF11/SOF13/SOF14/SOF15)"
54 ),
55 Self::LosslessJpeg => write!(f, "lossless JPEG (SOF3)"),
56 Self::HierarchicalJpeg => write!(f, "hierarchical JPEG (SOF5/SOF6/SOF7)"),
57 Self::JpegPrecision { bits } => {
58 write!(f, "JPEG sample precision {bits} (only 8-bit is supported)")
59 }
60 Self::JpegComponentCount { components } => {
61 write!(
62 f,
63 "JPEG component count {components} (only 1 or 3 are supported)"
64 )
65 }
66 Self::JpegChromaSubsampling => {
67 write!(f, "JPEG chroma subsampling that exceeds luma sampling rate")
68 }
69 }
70 }
71}
72
73#[derive(Debug)]
75pub enum CodecError {
76 InsufficientCapacity {
78 image: (usize, usize),
80 tensor: (usize, usize),
82 },
83 UnsupportedDtype(edgefirst_tensor::DType),
85 UnsupportedFormat(edgefirst_tensor::PixelFormat),
87 Unsupported(UnsupportedFeature),
92 InvalidData(String),
94 Io(std::io::Error),
96 Tensor(edgefirst_tensor::Error),
98}
99
100impl fmt::Display for CodecError {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 Self::InsufficientCapacity { image, tensor } => write!(
104 f,
105 "image dimensions {}×{} exceed tensor capacity {}×{}",
106 image.0, image.1, tensor.0, tensor.1,
107 ),
108 Self::UnsupportedDtype(dt) => {
109 write!(f, "unsupported tensor dtype {dt:?} for image decode")
110 }
111 Self::UnsupportedFormat(pf) => {
112 write!(f, "unsupported pixel format {pf:?} for image decode")
113 }
114 Self::Unsupported(feat) => write!(f, "unsupported image feature: {feat}"),
115 Self::InvalidData(msg) => write!(f, "invalid image data: {msg}"),
116 Self::Io(e) => write!(f, "I/O error: {e}"),
117 Self::Tensor(e) => write!(f, "tensor error: {e}"),
118 }
119 }
120}
121
122impl std::error::Error for CodecError {
123 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
124 match self {
125 Self::Io(e) => Some(e),
126 Self::Tensor(e) => Some(e),
127 _ => None,
128 }
129 }
130}
131
132impl From<std::io::Error> for CodecError {
133 fn from(e: std::io::Error) -> Self {
134 Self::Io(e)
135 }
136}
137
138impl From<edgefirst_tensor::Error> for CodecError {
139 fn from(e: edgefirst_tensor::Error) -> Self {
140 Self::Tensor(e)
141 }
142}
143
144impl From<zune_png::error::PngDecodeErrors> for CodecError {
145 fn from(e: zune_png::error::PngDecodeErrors) -> Self {
146 Self::InvalidData(format!("PNG: {e}"))
147 }
148}