1use thiserror::Error;
2use tiff_core::Compression;
3
4pub type Result<T> = std::result::Result<T, Error>;
5
6#[derive(Debug, Error)]
7pub enum Error {
8 #[error("I/O error reading {1}: {0}")]
9 Io(#[source] std::io::Error, String),
10
11 #[error("not a TIFF file: invalid magic bytes")]
12 InvalidMagic,
13
14 #[error("unsupported TIFF version: {0}")]
15 UnsupportedVersion(u16),
16
17 #[error("IFD index {0} not found")]
18 IfdNotFound(usize),
19
20 #[error("tag {0} not found in IFD")]
21 TagNotFound(u16),
22
23 #[error("unexpected tag type {actual} for tag {tag}, expected {expected}")]
24 UnexpectedTagType {
25 tag: u16,
26 expected: &'static str,
27 actual: u16,
28 },
29
30 #[error(
31 "unsupported compression: {name} ({0})",
32 name = unsupported_compression_name(*.0)
33 )]
34 UnsupportedCompression(u16),
35
36 #[error("unsupported predictor: {0}")]
37 UnsupportedPredictor(u16),
38
39 #[error("unsupported planar configuration: {0}")]
40 UnsupportedPlanarConfiguration(u16),
41
42 #[error("unsupported bits per sample: {0}")]
43 UnsupportedBitsPerSample(u16),
44
45 #[error("unsupported sample format: {0}")]
46 UnsupportedSampleFormat(u16),
47
48 #[error("decompression failed for strip/tile {index}: {reason}")]
49 DecompressionFailed { index: usize, reason: String },
50
51 #[error("decoded output byte length {requested} exceeds decode output budget {limit}")]
52 DecodeOutputTooLarge { requested: usize, limit: usize },
53
54 #[error("failed to allocate {requested} decoded output bytes: {reason}")]
55 DecodeOutputAllocationFailed { requested: usize, reason: String },
56
57 #[error("data truncated at offset {offset}: need {needed} bytes, have {available}")]
58 Truncated {
59 offset: u64,
60 needed: u64,
61 available: u64,
62 },
63
64 #[error("offset {offset} with length {length} is out of bounds for a {data_len}-byte file")]
65 OffsetOutOfBounds {
66 offset: u64,
67 length: u64,
68 data_len: u64,
69 },
70
71 #[error("invalid TIFF tag {tag}: {reason}")]
72 InvalidTagValue { tag: u16, reason: String },
73
74 #[error("invalid image layout: {0}")]
75 InvalidImageLayout(String),
76
77 #[error("type mismatch: expected {expected}, found {actual}")]
78 TypeMismatch {
79 expected: &'static str,
80 actual: String,
81 },
82
83 #[error("band index {index} is out of bounds for {band_count} bands")]
84 BandIndexOutOfBounds { index: usize, band_count: usize },
85
86 #[error("{0}")]
87 Other(String),
88}
89
90fn unsupported_compression_name(code: u16) -> &'static str {
91 Compression::from_code(code)
92 .map(Compression::name)
93 .unwrap_or("unknown")
94}