1pub 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#[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#[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#[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#[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#[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}