use std::io; use std::str; use std::string; use quick_error::quick_error; use crate::decoder::ChunkType; use crate::tags::Type; use crate::tags::{ CompressionMethod, PhotometricInterpretation, PlanarConfiguration, SampleFormat, Tag, }; use crate::ColorType; quick_error! { /// Tiff error kinds. #[derive(Debug)] pub enum TiffError { /// The Image is not formatted properly. FormatError(err: TiffFormatError) { display("format error: {err}") from() source(err) } /// The Decoder does not support features required by the image. UnsupportedError(err: TiffUnsupportedError) { display("unsupported error: {err}") from() source(err) } /// An I/O Error occurred while decoding the image. IoError(err: io::Error) { display("{err}") from() source(err) } /// The Limits of the Decoder is exceeded. LimitsExceeded { display("decoder limits exceeded") } /// An integer conversion to or from a platform size failed. IntSizeError { display("platform or format size limits exceeded") } /// The image does not support the requested operation UsageError(err: UsageError) { display("usage error: {err}") from() source(err) } } } quick_error! { /// The image is not formatted properly. /// /// This indicates that the encoder producing the image might behave incorrectly or that the /// input file has been corrupted. #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub enum TiffFormatError { TiffSignatureNotFound { display("TIFF signature not found") } TiffSignatureInvalid { display("TIFF signature invalid") } ImageFileDirectoryNotFound { display("image file directory not found") } InconsistentSizesEncountered { display("inconsistent sizes encountered") } InvalidDimensions(width: u32, height: u32) { display("invalid dimensions: {width}x{height}") } InvalidTag { display("image contains invalid tag") } InvalidTagValueType(tag: Tag) { display("tag `{tag:?}` did not have the expected value type") } RequiredTagNotFound(tag: Tag) { display("required tag `{tag:?}` not found") } UnknownPredictor(pred: u16) { display("unknown predictor “{pred}” encountered") } UnknownPlanarConfiguration(cfg: u16) { display("unknown planar configuration “{cfg}”") } InvalidTypeForTag { display("tag has invalid type") } InvalidCountForTag(tag: Tag, len: usize) { display("tag `{tag:?}` with incorrect number of elements ({len}) encountered") } StripTileTagConflict { display("file should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found") } CycleInOffsets { display("file contained a cycle in the list of IFDs") } SamplesPerPixelIsZero { display("samples per pixel is zero") } CompressedDataCorrupt(message: String) { display("compressed data is corrupt: {message}") } } } quick_error! { /// The Decoder does not support features required by the image. /// /// This only captures known failures for which the standard either does not require support or an /// implementation has been planned but not yet completed. Some variants may become unused over /// time and will then get deprecated before being removed. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum TiffUnsupportedError { FloatingPointPredictor(color_type: ColorType) { display("floating point predictor for {color_type:?} is unsupported") } HorizontalPredictor(color_type: ColorType) { display("horizontal predictor for {color_type:?} is unsupported") } InconsistentBitsPerSample(bits_per_sample: Vec) { display("inconsistent bits per sample: {bits_per_sample:?}") } InterpretationWithBits(interpretation: PhotometricInterpretation, bits_per_sample: Vec) { display("Photometric interpretation {interpretation:?} with bits per sample {bits_per_sample:?} is unsupported") } UnknownInterpretation { display("unknown photometric interpretation") } UnknownCompressionMethod { display("unknown compression method") } UnsupportedCompressionMethod(method: CompressionMethod) { display("compression method {method:?} is unsupported") } UnsupportedSampleDepth(depth: u8) { display("{depth} samples per pixel is unsupported") } UnsupportedSampleFormat(sample_format: Vec) { display("sample format {sample_format:?} is unsupported") } UnsupportedColorType(color_type: ColorType) { display("color type {color_type:?} is unsupported") } UnsupportedBitsPerChannel(bits_per_channel: u8) { display("{bits_per_channel} bits per channel not supported") } UnsupportedPlanarConfig(planar: Option) { display("unsupported planar configuration “{planar:?}”") } UnsupportedDataType { display("unsupported data type.") } UnsupportedInterpretation(interpretation: PhotometricInterpretation) { display("unsupported photometric interpretation \"{interpretation:?}\"") } ChromaSubsampling { display("chroma subsampling of YCbCr color is unsupported") } MisalignedTileBoundaries { display("tile rows are not aligned to byte boundaries") } } } quick_error! { /// User attempted to use the Decoder in a way that is incompatible with a specific image. /// /// For example: attempting to read a tile from a stripped image. #[derive(Debug)] #[non_exhaustive] pub enum UsageError { InvalidChunkType(expected: ChunkType, actual: ChunkType) { display("requested operation is only valid for images with chunk encoding of type {expected:?} but got {actual:?}") } InvalidChunkIndex(index: u32) { display("invalid chunk index ({index}) requested") } InvalidPlaneIndex(index: u16) { display("invalid plane index ({index}) requested") } InvalidCodingUnit(index: u32, have: u32) { display("out of bounds coding unit ({index}) requested, only {have} available") } PredictorCompressionMismatch { display("requested predictor is not compatible with the requested compression") } PredictorIncompatible { display("the requested predictor is not compatible with the image's format") } PredictorUnavailable { display("the requested predictor is not available") } InsufficientOutputBufferSize { needed: usize, provided: usize } { display("the borrowed output buffer is not large enough for the decoded data, needed {needed} but have {provided}") } InsufficientOutputRowStride { needed: usize, requested: usize } { display("the provided output row stride would alias rows of decoded data, needed {needed} but have {requested}") } ZeroIfdPointer { display("the offset 0 can not point to a valid IFD") } ReconfiguredAfterImageWrite { display("attempted to reconfigure the encoder after image writing has started") } ByteOrderMismatch { display("attempted to use data with a byte order that does not match the required one") } MismatchedEntryLength {ty: Type, found: usize } { display("the length of data is not a multiple of the size of the type {ty:?}, found {found}") } } } impl From for TiffError { fn from(_err: str::Utf8Error) -> TiffError { TiffError::FormatError(TiffFormatError::InvalidTag) } } impl From for TiffError { fn from(_err: string::FromUtf8Error) -> TiffError { TiffError::FormatError(TiffFormatError::InvalidTag) } } impl From for TiffError { fn from(_err: std::num::TryFromIntError) -> TiffError { TiffError::IntSizeError } } #[cfg(feature = "lzw")] impl From for TiffError { fn from(err: weezl::LzwError) -> TiffError { TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string())) } } #[cfg(feature = "jpeg")] impl From for TiffError { fn from(err: zune_jpeg::errors::DecodeErrors) -> Self { TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string())) } } /// Result of an image decoding/encoding process pub type TiffResult = Result;