1 use std::error::Error; 2 use std::fmt; 3 use std::io; 4 use std::string; 5 6 use decoder::ifd::{Value}; 7 use tags::{CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Tag}; 8 use miniz_oxide::inflate::TINFLStatus; 9 use ColorType; 10 11 /// Tiff error kinds. 12 #[derive(Debug)] 13 pub enum TiffError { 14 /// The Image is not formatted properly. 15 FormatError(TiffFormatError), 16 17 /// The Decoder does not support features required by the image. 18 UnsupportedError(TiffUnsupportedError), 19 20 /// An I/O Error occurred while decoding the image. 21 IoError(io::Error), 22 23 /// The Limits of the Decoder is exceeded. 24 LimitsExceeded, 25 26 /// An integer conversion to or from a platform size failed, either due to 27 /// limits of the platform size or limits of the format. 28 IntSizeError, 29 } 30 31 /// The image is not formatted properly. 32 /// 33 /// This indicates that the encoder producing the image might behave incorrectly or that the input 34 /// file has been corrupted. 35 /// 36 /// The list of variants may grow to incorporate errors of future features. Matching against this 37 /// exhaustively is not covered by interface stability guarantees. 38 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 39 pub enum TiffFormatError { 40 TiffSignatureNotFound, 41 TiffSignatureInvalid, 42 ImageFileDirectoryNotFound, 43 InconsistentSizesEncountered, 44 InvalidTag, 45 InvalidTagValueType(Tag), 46 RequiredTagNotFound(Tag), 47 UnknownPredictor(u16), 48 UnsignedIntegerExpected(Value), 49 SignedIntegerExpected(Value), 50 InflateError(InflateError), 51 #[doc(hidden)] 52 /// Do not match against this variant. It may get removed. 53 __NonExhaustive, 54 } 55 56 impl fmt::Display for TiffFormatError { fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>57 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 58 use self::TiffFormatError::*; 59 match *self { 60 TiffSignatureNotFound => write!(fmt, "TIFF signature not found."), 61 TiffSignatureInvalid => write!(fmt, "TIFF signature invalid."), 62 ImageFileDirectoryNotFound => write!(fmt, "Image file directory not found."), 63 InconsistentSizesEncountered => write!(fmt, "Inconsistent sizes encountered."), 64 InvalidTag => write!(fmt, "Image contains invalid tag."), 65 InvalidTagValueType(ref tag) => 66 write!(fmt, "Tag `{:?}` did not have the expected value type.", tag), 67 RequiredTagNotFound(ref tag) => write!(fmt, "Required tag `{:?}` not found.", tag), 68 UnknownPredictor(ref predictor) => { 69 write!(fmt, "Unknown predictor “{}” encountered", predictor) 70 } 71 UnsignedIntegerExpected(ref val) => { 72 write!(fmt, "Expected unsigned integer, {:?} found.", val) 73 } 74 SignedIntegerExpected(ref val) => { 75 write!(fmt, "Expected signed integer, {:?} found.", val) 76 } 77 InflateError(_) => write!(fmt, "Failed to decode inflate data."), 78 __NonExhaustive => unreachable!(), 79 } 80 } 81 } 82 83 /// Decompression failed due to faulty compressed data. 84 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 85 pub struct InflateError { 86 status: TINFLStatus, 87 } 88 89 impl InflateError { new(status: TINFLStatus) -> Self90 pub(crate) fn new(status: TINFLStatus) -> Self { 91 Self { status } 92 } 93 } 94 95 impl TiffError { from_inflate_status(status: TINFLStatus) -> Self96 pub(crate) fn from_inflate_status(status: TINFLStatus) -> Self { 97 TiffError::FormatError(TiffFormatError::InflateError(InflateError::new(status))) 98 } 99 } 100 101 /// The Decoder does not support features required by the image. 102 /// 103 /// This only captures known failures for which the standard either does not require support or an 104 /// implementation has been planned but not yet completed. Some variants may become unused over 105 /// time and will then get deprecated before being removed. 106 /// 107 /// The list of variants may grow. Matching against this exhaustively is not covered by interface 108 /// stability guarantees. 109 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 110 pub enum TiffUnsupportedError { 111 HorizontalPredictor(ColorType), 112 InterpretationWithBits(PhotometricInterpretation, Vec<u8>), 113 UnknownInterpretation, 114 UnknownCompressionMethod, 115 UnsupportedCompressionMethod(CompressionMethod), 116 UnsupportedSampleDepth(u8), 117 UnsupportedColorType(ColorType), 118 UnsupportedBitsPerChannel(u8), 119 UnsupportedPlanarConfig(Option<PlanarConfiguration>), 120 UnsupportedDataType, 121 #[doc(hidden)] 122 /// Do not match against this variant. It may get removed. 123 __NonExhaustive, 124 } 125 126 impl fmt::Display for TiffUnsupportedError { fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>127 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 128 use self::TiffUnsupportedError::*; 129 match *self { 130 HorizontalPredictor(color_type) => write!( 131 fmt, 132 "Horizontal predictor for {:?} is unsupported.", 133 color_type 134 ), 135 InterpretationWithBits(ref photometric_interpretation, ref bits_per_sample) => write!( 136 fmt, 137 "{:?} with {:?} bits per sample is unsupported", 138 photometric_interpretation, bits_per_sample 139 ), 140 UnknownInterpretation => write!( 141 fmt, 142 "The image is using an unknown photometric interpretation." 143 ), 144 UnknownCompressionMethod => write!(fmt, "Unknown compression method."), 145 UnsupportedCompressionMethod(method) => { 146 write!(fmt, "Compression method {:?} is unsupported", method) 147 } 148 UnsupportedSampleDepth(samples) => { 149 write!(fmt, "{} samples per pixel is unsupported.", samples) 150 } 151 UnsupportedColorType(color_type) => { 152 write!(fmt, "Color type {:?} is unsupported", color_type) 153 } 154 UnsupportedBitsPerChannel(bits) => { 155 write!(fmt, "{} bits per channel not supported", bits) 156 } 157 UnsupportedPlanarConfig(config) => { 158 write!(fmt, "Unsupported planar configuration “{:?}”.", config) 159 } 160 UnsupportedDataType => write!(fmt, "Unsupported data type."), 161 __NonExhaustive => unreachable!(), 162 } 163 } 164 } 165 166 impl fmt::Display for TiffError { fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>167 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 168 match *self { 169 TiffError::FormatError(ref e) => write!(fmt, "Format error: {}", e), 170 TiffError::UnsupportedError(ref f) => write!( 171 fmt, 172 "The Decoder does not support the \ 173 image format `{}`", 174 f 175 ), 176 TiffError::IoError(ref e) => e.fmt(fmt), 177 TiffError::LimitsExceeded => write!(fmt, "The Decoder limits are exceeded"), 178 TiffError::IntSizeError => write!(fmt, "Platform or format size limits exceeded"), 179 } 180 } 181 } 182 183 impl Error for TiffError { description(&self) -> &str184 fn description(&self) -> &str { 185 match *self { 186 TiffError::FormatError(..) => "Format error", 187 TiffError::UnsupportedError(..) => "Unsupported error", 188 TiffError::IoError(..) => "IO error", 189 TiffError::LimitsExceeded => "Decoder limits exceeded", 190 TiffError::IntSizeError => "Platform or format size limits exceeded", 191 } 192 } 193 cause(&self) -> Option<&dyn Error>194 fn cause(&self) -> Option<&dyn Error> { 195 match *self { 196 TiffError::IoError(ref e) => Some(e), 197 _ => None, 198 } 199 } 200 } 201 202 impl From<io::Error> for TiffError { from(err: io::Error) -> TiffError203 fn from(err: io::Error) -> TiffError { 204 TiffError::IoError(err) 205 } 206 } 207 208 impl From<string::FromUtf8Error> for TiffError { from(_err: string::FromUtf8Error) -> TiffError209 fn from(_err: string::FromUtf8Error) -> TiffError { 210 TiffError::FormatError(TiffFormatError::InvalidTag) 211 } 212 } 213 214 impl From<TiffFormatError> for TiffError { from(err: TiffFormatError) -> TiffError215 fn from(err: TiffFormatError) -> TiffError { 216 TiffError::FormatError(err) 217 } 218 } 219 220 impl From<TiffUnsupportedError> for TiffError { from(err: TiffUnsupportedError) -> TiffError221 fn from(err: TiffUnsupportedError) -> TiffError { 222 TiffError::UnsupportedError(err) 223 } 224 } 225 226 impl From<std::num::TryFromIntError> for TiffError { from(_err: std::num::TryFromIntError) -> TiffError227 fn from(_err: std::num::TryFromIntError) -> TiffError { 228 TiffError::IntSizeError 229 } 230 } 231 232 /// Result of an image decoding/encoding process 233 pub type TiffResult<T> = Result<T, TiffError>; 234