Coverage Report

Created: 2026-03-20 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tiff-0.11.3/src/error.rs
Line
Count
Source
1
use std::io;
2
use std::str;
3
use std::string;
4
5
use quick_error::quick_error;
6
7
use crate::decoder::ChunkType;
8
use crate::tags::Type;
9
use crate::tags::{
10
    CompressionMethod, PhotometricInterpretation, PlanarConfiguration, SampleFormat, Tag,
11
};
12
use crate::ColorType;
13
14
quick_error! {
15
    /// Tiff error kinds.
16
    #[derive(Debug)]
17
    pub enum TiffError {
18
        /// The Image is not formatted properly.
19
        FormatError(err: TiffFormatError) {
20
            display("format error: {err}")
21
            from()
22
            source(err)
23
        }
24
        /// The Decoder does not support features required by the image.
25
        UnsupportedError(err: TiffUnsupportedError) {
26
            display("unsupported error: {err}")
27
            from()
28
            source(err)
29
        }
30
        /// An I/O Error occurred while decoding the image.
31
        IoError(err: io::Error) {
32
            display("{err}")
33
            from()
34
            source(err)
35
        }
36
        /// The Limits of the Decoder is exceeded.
37
        LimitsExceeded {
38
            display("decoder limits exceeded")
39
        }
40
        /// An integer conversion to or from a platform size failed.
41
        IntSizeError {
42
            display("platform or format size limits exceeded")
43
        }
44
        /// The image does not support the requested operation
45
        UsageError(err: UsageError) {
46
            display("usage error: {err}")
47
            from()
48
            source(err)
49
        }
50
    }
51
}
52
53
quick_error! {
54
    /// The image is not formatted properly.
55
    ///
56
    /// This indicates that the encoder producing the image might behave incorrectly or that the
57
    /// input file has been corrupted.
58
    #[derive(Debug, Clone, PartialEq)]
59
    #[non_exhaustive]
60
    pub enum TiffFormatError {
61
        TiffSignatureNotFound {
62
            display("TIFF signature not found")
63
        }
64
        TiffSignatureInvalid {
65
            display("TIFF signature invalid")
66
        }
67
        ImageFileDirectoryNotFound {
68
            display("image file directory not found")
69
        }
70
        InconsistentSizesEncountered {
71
            display("inconsistent sizes encountered")
72
        }
73
        InvalidDimensions(width: u32, height: u32) {
74
            display("invalid dimensions: {width}x{height}")
75
        }
76
        InvalidTag {
77
            display("image contains invalid tag")
78
        }
79
        InvalidTagValueType(tag: Tag) {
80
            display("tag `{tag:?}` did not have the expected value type")
81
        }
82
        RequiredTagNotFound(tag: Tag) {
83
            display("required tag `{tag:?}` not found")
84
        }
85
        UnknownPredictor(pred: u16) {
86
            display("unknown predictor “{pred}” encountered")
87
        }
88
        UnknownPlanarConfiguration(cfg: u16) {
89
            display("unknown planar configuration “{cfg}”")
90
        }
91
        InvalidTypeForTag {
92
            display("tag has invalid type")
93
        }
94
        InvalidCountForTag(tag: Tag, len: usize) {
95
            display("tag `{tag:?}` with incorrect number of elements ({len}) encountered")
96
        }
97
        StripTileTagConflict {
98
            display("file should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found")
99
        }
100
        CycleInOffsets {
101
            display("file contained a cycle in the list of IFDs")
102
        }
103
        SamplesPerPixelIsZero {
104
            display("samples per pixel is zero")
105
        }
106
        CompressedDataCorrupt(message: String) {
107
            display("compressed data is corrupt: {message}")
108
        }
109
    }
110
}
111
112
quick_error! {
113
    /// The Decoder does not support features required by the image.
114
    ///
115
    /// This only captures known failures for which the standard either does not require support or an
116
    /// implementation has been planned but not yet completed. Some variants may become unused over
117
    /// time and will then get deprecated before being removed.
118
    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
119
    #[non_exhaustive]
120
    pub enum TiffUnsupportedError {
121
        FloatingPointPredictor(color_type: ColorType) {
122
            display("floating point predictor for {color_type:?} is unsupported")
123
        }
124
        HorizontalPredictor(color_type: ColorType) {
125
            display("horizontal predictor for {color_type:?} is unsupported")
126
        }
127
        InconsistentBitsPerSample(bits_per_sample: Vec<u8>) {
128
            display("inconsistent bits per sample: {bits_per_sample:?}")
129
        }
130
        InterpretationWithBits(interpretation: PhotometricInterpretation, bits_per_sample: Vec<u8>) {
131
            display("Photometric interpretation {interpretation:?} with bits per sample {bits_per_sample:?} is unsupported")
132
        }
133
        UnknownInterpretation {
134
            display("unknown photometric interpretation")
135
        }
136
        UnknownCompressionMethod {
137
            display("unknown compression method")
138
        }
139
        UnsupportedCompressionMethod(method: CompressionMethod) {
140
            display("compression method {method:?} is unsupported")
141
        }
142
        UnsupportedSampleDepth(depth: u8) {
143
            display("{depth} samples per pixel is unsupported")
144
        }
145
        UnsupportedSampleFormat(sample_format: Vec<SampleFormat>) {
146
            display("sample format {sample_format:?} is unsupported")
147
        }
148
        UnsupportedColorType(color_type: ColorType) {
149
            display("color type {color_type:?} is unsupported")
150
        }
151
        UnsupportedBitsPerChannel(bits_per_channel: u8) {
152
            display("{bits_per_channel} bits per channel not supported")
153
        }
154
        UnsupportedPlanarConfig(planar: Option<PlanarConfiguration>) {
155
            display("unsupported planar configuration “{planar:?}”")
156
        }
157
        UnsupportedDataType {
158
            display("unsupported data type.")
159
        }
160
        UnsupportedInterpretation(interpretation: PhotometricInterpretation) {
161
            display("unsupported photometric interpretation \"{interpretation:?}\"")
162
        }
163
        ChromaSubsampling {
164
            display("chroma subsampling of YCbCr color is unsupported")
165
        }
166
        MisalignedTileBoundaries {
167
            display("tile rows are not aligned to byte boundaries")
168
        }
169
    }
170
}
171
172
quick_error! {
173
    /// User attempted to use the Decoder in a way that is incompatible with a specific image.
174
    ///
175
    /// For example: attempting to read a tile from a stripped image.
176
    #[derive(Debug)]
177
    #[non_exhaustive]
178
    pub enum UsageError {
179
        InvalidChunkType(expected: ChunkType, actual: ChunkType) {
180
            display("requested operation is only valid for images with chunk encoding of type {expected:?} but got {actual:?}")
181
        }
182
        InvalidChunkIndex(index: u32) {
183
            display("invalid chunk index ({index}) requested")
184
        }
185
        InvalidPlaneIndex(index: u16) {
186
            display("invalid plane index ({index}) requested")
187
        }
188
        InvalidCodingUnit(index: u32, have: u32) {
189
            display("out of bounds coding unit ({index}) requested, only {have} available")
190
        }
191
        PredictorCompressionMismatch {
192
            display("requested predictor is not compatible with the requested compression")
193
        }
194
        PredictorIncompatible {
195
            display("the requested predictor is not compatible with the image's format")
196
        }
197
        PredictorUnavailable {
198
            display("the requested predictor is not available")
199
        }
200
        InsufficientOutputBufferSize { needed: usize, provided: usize } {
201
            display("the borrowed output buffer is not large enough for the decoded data, needed {needed} but have {provided}")
202
        }
203
        InsufficientOutputRowStride { needed: usize, requested: usize } {
204
            display("the provided output row stride would alias rows of decoded data, needed {needed} but have {requested}")
205
        }
206
        ZeroIfdPointer {
207
            display("the offset 0 can not point to a valid IFD")
208
        }
209
        ReconfiguredAfterImageWrite {
210
            display("attempted to reconfigure the encoder after image writing has started")
211
        }
212
        ByteOrderMismatch {
213
            display("attempted to use data with a byte order that does not match the required one")
214
        }
215
        MismatchedEntryLength {ty: Type, found: usize } {
216
            display("the length of data is not a multiple of the size of the type {ty:?}, found {found}")
217
        }
218
    }
219
}
220
221
impl From<str::Utf8Error> for TiffError {
222
0
    fn from(_err: str::Utf8Error) -> TiffError {
223
0
        TiffError::FormatError(TiffFormatError::InvalidTag)
224
0
    }
225
}
226
227
impl From<string::FromUtf8Error> for TiffError {
228
13
    fn from(_err: string::FromUtf8Error) -> TiffError {
229
13
        TiffError::FormatError(TiffFormatError::InvalidTag)
230
13
    }
231
}
232
233
impl From<std::num::TryFromIntError> for TiffError {
234
553
    fn from(_err: std::num::TryFromIntError) -> TiffError {
235
553
        TiffError::IntSizeError
236
553
    }
237
}
238
239
#[cfg(feature = "lzw")]
240
impl From<weezl::LzwError> for TiffError {
241
0
    fn from(err: weezl::LzwError) -> TiffError {
242
0
        TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string()))
243
0
    }
244
}
245
246
#[cfg(feature = "jpeg")]
247
impl From<zune_jpeg::errors::DecodeErrors> for TiffError {
248
4.08k
    fn from(err: zune_jpeg::errors::DecodeErrors) -> Self {
249
4.08k
        TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string()))
250
4.08k
    }
251
}
252
253
/// Result of an image decoding/encoding process
254
pub type TiffResult<T> = Result<T, TiffError>;