Skip to main content

tiff_core/
constants.rs

1// Well-known TIFF tag codes.
2pub const TAG_NEW_SUBFILE_TYPE: u16 = 254;
3pub const TAG_SUBFILE_TYPE: u16 = 255;
4pub const TAG_IMAGE_WIDTH: u16 = 256;
5pub const TAG_IMAGE_LENGTH: u16 = 257;
6pub const TAG_BITS_PER_SAMPLE: u16 = 258;
7pub const TAG_COMPRESSION: u16 = 259;
8pub const TAG_PHOTOMETRIC_INTERPRETATION: u16 = 262;
9pub const TAG_STRIP_OFFSETS: u16 = 273;
10pub const TAG_SAMPLES_PER_PIXEL: u16 = 277;
11pub const TAG_ROWS_PER_STRIP: u16 = 278;
12pub const TAG_STRIP_BYTE_COUNTS: u16 = 279;
13pub const TAG_PLANAR_CONFIGURATION: u16 = 284;
14pub const TAG_PREDICTOR: u16 = 317;
15pub const TAG_TILE_WIDTH: u16 = 322;
16pub const TAG_TILE_LENGTH: u16 = 323;
17pub const TAG_TILE_OFFSETS: u16 = 324;
18pub const TAG_TILE_BYTE_COUNTS: u16 = 325;
19pub const TAG_SAMPLE_FORMAT: u16 = 339;
20pub const TAG_JPEG_TABLES: u16 = 347;
21pub const TAG_LERC_PARAMETERS: u16 = 50674;
22
23/// TIFF compression scheme.
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25pub enum Compression {
26    None,
27    Lzw,
28    OldJpeg,
29    Jpeg,
30    Deflate,
31    PackBits,
32    DeflateOld,
33    Lerc,
34    Zstd,
35}
36
37impl Compression {
38    pub fn from_code(code: u16) -> Option<Self> {
39        match code {
40            1 => Some(Self::None),
41            5 => Some(Self::Lzw),
42            6 => Some(Self::OldJpeg),
43            7 => Some(Self::Jpeg),
44            8 => Some(Self::Deflate),
45            32773 => Some(Self::PackBits),
46            32946 => Some(Self::DeflateOld),
47            34887 => Some(Self::Lerc),
48            50000 => Some(Self::Zstd),
49            _ => None,
50        }
51    }
52
53    pub fn to_code(self) -> u16 {
54        match self {
55            Self::None => 1,
56            Self::Lzw => 5,
57            Self::OldJpeg => 6,
58            Self::Jpeg => 7,
59            Self::Deflate => 8,
60            Self::PackBits => 32773,
61            Self::DeflateOld => 32946,
62            Self::Lerc => 34887,
63            Self::Zstd => 50000,
64        }
65    }
66
67    pub fn name(self) -> &'static str {
68        match self {
69            Self::None => "None",
70            Self::Lzw => "LZW",
71            Self::OldJpeg => "OldJpeg",
72            Self::Jpeg => "JPEG",
73            Self::Deflate => "Deflate",
74            Self::PackBits => "PackBits",
75            Self::DeflateOld => "DeflateOld",
76            Self::Lerc => "LERC",
77            Self::Zstd => "ZSTD",
78        }
79    }
80}
81
82/// TIFF predictor scheme.
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
84pub enum Predictor {
85    None,
86    Horizontal,
87    FloatingPoint,
88}
89
90impl Predictor {
91    pub fn from_code(code: u16) -> Option<Self> {
92        match code {
93            1 => Some(Self::None),
94            2 => Some(Self::Horizontal),
95            3 => Some(Self::FloatingPoint),
96            _ => None,
97        }
98    }
99
100    pub fn to_code(self) -> u16 {
101        match self {
102            Self::None => 1,
103            Self::Horizontal => 2,
104            Self::FloatingPoint => 3,
105        }
106    }
107}
108
109/// TIFF sample format.
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
111pub enum SampleFormat {
112    Uint,
113    Int,
114    Float,
115}
116
117impl SampleFormat {
118    pub fn from_code(code: u16) -> Option<Self> {
119        match code {
120            1 => Some(Self::Uint),
121            2 => Some(Self::Int),
122            3 => Some(Self::Float),
123            _ => None,
124        }
125    }
126
127    pub fn to_code(self) -> u16 {
128        match self {
129            Self::Uint => 1,
130            Self::Int => 2,
131            Self::Float => 3,
132        }
133    }
134}
135
136/// TIFF photometric interpretation.
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
138pub enum PhotometricInterpretation {
139    MinIsWhite,
140    MinIsBlack,
141    Rgb,
142    Palette,
143    Mask,
144}
145
146impl PhotometricInterpretation {
147    pub fn from_code(code: u16) -> Option<Self> {
148        match code {
149            0 => Some(Self::MinIsWhite),
150            1 => Some(Self::MinIsBlack),
151            2 => Some(Self::Rgb),
152            3 => Some(Self::Palette),
153            4 => Some(Self::Mask),
154            _ => None,
155        }
156    }
157
158    pub fn to_code(self) -> u16 {
159        match self {
160            Self::MinIsWhite => 0,
161            Self::MinIsBlack => 1,
162            Self::Rgb => 2,
163            Self::Palette => 3,
164            Self::Mask => 4,
165        }
166    }
167}
168
169/// TIFF planar configuration.
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
171pub enum PlanarConfiguration {
172    Chunky,
173    Planar,
174}
175
176impl PlanarConfiguration {
177    pub fn from_code(code: u16) -> Option<Self> {
178        match code {
179            1 => Some(Self::Chunky),
180            2 => Some(Self::Planar),
181            _ => None,
182        }
183    }
184
185    pub fn to_code(self) -> u16 {
186        match self {
187            Self::Chunky => 1,
188            Self::Planar => 2,
189        }
190    }
191}
192
193#[cfg(test)]
194mod tests {
195    use super::{Compression, TAG_LERC_PARAMETERS};
196
197    #[test]
198    fn compression_roundtrips_lerc() {
199        assert_eq!(Compression::from_code(34887), Some(Compression::Lerc));
200        assert_eq!(Compression::Lerc.to_code(), 34887);
201        assert_eq!(Compression::Lerc.name(), "LERC");
202    }
203
204    #[test]
205    fn lerc_parameters_tag_matches_registered_value() {
206        assert_eq!(TAG_LERC_PARAMETERS, 50674);
207    }
208}