async_tiff/tags.rs
1//! TIFF tag definitions and enum types.
2
3#![allow(clippy::no_effect)]
4#![allow(missing_docs)]
5#![allow(clippy::upper_case_acronyms)]
6
7macro_rules! tags {
8 {
9 // Permit arbitrary meta items, which include documentation.
10 $( #[$enum_attr:meta] )*
11 $vis:vis enum $name:ident($ty:tt) $(unknown($unknown_doc:literal))* {
12 // Each of the `Name = Val,` permitting documentation.
13 $($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
14 }
15 } => {
16 $( #[$enum_attr] )*
17 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
18 #[non_exhaustive]
19 $vis enum $name {
20 $($(#[$ident_attr])* $tag,)*
21 $(
22 #[doc = $unknown_doc]
23 Unknown($ty),
24 )*
25 }
26
27 impl $name {
28 #[inline(always)]
29 fn __from_inner_type(n: $ty) -> Result<Self, $ty> {
30 match n {
31 $( $val => Ok($name::$tag), )*
32 n => Err(n),
33 }
34 }
35
36 #[inline(always)]
37 fn __to_inner_type(&self) -> $ty {
38 match *self {
39 $( $name::$tag => $val, )*
40 $( $name::Unknown(n) => { $unknown_doc; n }, )*
41 }
42 }
43 }
44
45 tags!($name, $ty, $($unknown_doc)*);
46 };
47 // For u16 tags, provide direct inherent primitive conversion methods.
48 ($name:tt, u16, $($unknown_doc:literal)*) => {
49 impl $name {
50 /// Construct from a u16 value, returning `None` if the value is not a known tag.
51 #[inline(always)]
52 pub fn from_u16(val: u16) -> Option<Self> {
53 Self::__from_inner_type(val).ok()
54 }
55
56 $(
57 /// Construct from a u16 value, storing `Unknown` if the value is not a known tag.
58 #[inline(always)]
59 pub fn from_u16_exhaustive(val: u16) -> Self {
60 $unknown_doc;
61 Self::__from_inner_type(val).unwrap_or_else(|_| $name::Unknown(val))
62 }
63 )*
64
65 /// Convert to a u16 value.
66 #[inline(always)]
67 pub fn to_u16(self) -> u16 {
68 Self::__to_inner_type(&self)
69 }
70 }
71 };
72 // For other tag types, do nothing for now. With concat_idents one could
73 // provide inherent conversion methods for all types.
74 ($name:tt, $ty:tt, $($unknown_doc:literal)*) => {};
75}
76
77// Note: These tags appear in the order they are mentioned in the TIFF reference
78tags! {
79/// Tag identifiers.
80pub enum Tag(u16) unknown("A private or extension tag") {
81 // Baseline tags:
82 Artist = 315,
83 // grayscale images PhotometricInterpretation 1 or 3
84 BitsPerSample = 258,
85 CellLength = 265,
86 CellWidth = 264,
87 /// Color map for palette-color images (PhotometricInterpretation 3)
88 ColorMap = 320,
89 /// Compression scheme used on the image data
90 Compression = 259,
91 Copyright = 33_432,
92 DateTime = 306,
93 /// The meaning of each extra sample beyond that defined by PhotometricInterpretation
94 ExtraSamples = 338,
95 FillOrder = 266,
96 FreeByteCounts = 289,
97 FreeOffsets = 288,
98 GrayResponseCurve = 291,
99 GrayResponseUnit = 290,
100 HostComputer = 316,
101 ImageDescription = 270,
102 ImageLength = 257,
103 ImageWidth = 256,
104 Make = 271,
105 MaxSampleValue = 281,
106 MinSampleValue = 280,
107 Model = 272,
108 NewSubfileType = 254,
109 Orientation = 274,
110 PhotometricInterpretation = 262,
111 PlanarConfiguration = 284,
112 ResolutionUnit = 296,
113 RowsPerStrip = 278,
114 SamplesPerPixel = 277,
115 Software = 305,
116 StripByteCounts = 279,
117 StripOffsets = 273,
118 SubfileType = 255,
119 Threshholding = 263,
120 XResolution = 282,
121 YResolution = 283,
122 Predictor = 317,
123 TileWidth = 322,
124 TileLength = 323,
125 TileOffsets = 324,
126 TileByteCounts = 325,
127 // Data Sample Format
128 SampleFormat = 339,
129 SMinSampleValue = 340,
130 SMaxSampleValue = 341,
131 // JPEG
132 JPEGTables = 347,
133 // GeoTIFF
134 ModelPixelScale = 33550, // (SoftDesk)
135 ModelTransformation = 34264, // (JPL Carto Group)
136 ModelTiepoint = 33922, // (Intergraph)
137 GeoKeyDirectory = 34735, // (SPOT)
138 GeoDoubleParams = 34736, // (SPOT)
139 GeoAsciiParams = 34737, // (SPOT)
140 /// GDAL-specific NoData value
141 GdalNodata = 42113,
142 GdalMetadata = 42112, // XML metadata string
143 /// Extra parameters for LERC decompression
144 /// Defines a `Vec<u32>` of `[Version (u32), CompressionType (u32), ...]`
145 LercParameters = 0xC5F2, // (LERC)
146}
147}
148
149tags! {
150/// The type of an IFD entry (a 2 byte field).
151pub enum Type(u16) {
152 /// 8-bit unsigned integer
153 BYTE = 1,
154 /// 8-bit byte that contains a 7-bit ASCII code; the last byte must be zero
155 ASCII = 2,
156 /// 16-bit unsigned integer
157 SHORT = 3,
158 /// 32-bit unsigned integer
159 LONG = 4,
160 /// Fraction stored as two 32-bit unsigned integers
161 RATIONAL = 5,
162 /// 8-bit signed integer
163 SBYTE = 6,
164 /// 8-bit byte that may contain anything, depending on the field
165 UNDEFINED = 7,
166 /// 16-bit signed integer
167 SSHORT = 8,
168 /// 32-bit signed integer
169 SLONG = 9,
170 /// Fraction stored as two 32-bit signed integers
171 SRATIONAL = 10,
172 /// 32-bit IEEE floating point
173 FLOAT = 11,
174 /// 64-bit IEEE floating point
175 DOUBLE = 12,
176 /// 32-bit unsigned integer (offset)
177 IFD = 13,
178 /// BigTIFF 64-bit unsigned integer
179 LONG8 = 16,
180 /// BigTIFF 64-bit signed integer
181 SLONG8 = 17,
182 /// BigTIFF 64-bit unsigned integer (offset)
183 IFD8 = 18,
184}
185}
186
187tags! {
188/// Known compression methods.
189///
190/// See [TIFF compression tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html)
191/// for reference.
192pub enum Compression(u16) unknown("A custom compression method") {
193 None = 1,
194 Huffman = 2,
195 Fax3 = 3,
196 Fax4 = 4,
197 LZW = 5,
198 JPEG = 6,
199 // "Extended JPEG" or "new JPEG" style
200 ModernJPEG = 7,
201 Deflate = 8,
202 OldDeflate = 0x80B2,
203 PackBits = 0x8005,
204 LERC = 34887,
205 LZMA = 34925,
206 // https://github.com/OSGeo/gdal/blob/4769b527b275fdb286cba95c8b35bbd131168e54/frmts/gtiff/gtiff.h#L136C26-L136C31
207 WebP = 50001,
208 JPEG2k = 34712,
209
210 // Self-assigned by libtiff
211 ZSTD = 0xC350,
212}
213}
214
215tags! {
216/// Description of extra components.
217pub enum ExtraSamples(u16) {
218 Unspecified = 0,
219 AssociatedAlpha = 1,
220 UnassociatedAlpha = 2,
221}
222}
223
224tags! {
225/// The color space of the image data.
226pub enum PhotometricInterpretation(u16) {
227 WhiteIsZero = 0,
228 BlackIsZero = 1,
229 RGB = 2,
230 RGBPalette = 3,
231 TransparencyMask = 4,
232 CMYK = 5,
233 YCbCr = 6,
234 CIELab = 8,
235}
236}
237
238tags! {
239/// How pixel components are stored: contiguously (chunky) or in separate planes (planar).
240pub enum PlanarConfiguration(u16) {
241 Chunky = 1,
242 Planar = 2,
243}
244}
245
246tags! {
247/// A mathematical operator applied to image data before compression to improve compression ratios.
248pub enum Predictor(u16) {
249 /// No changes were made to the data
250 None = 1,
251 /// The images' rows were processed to contain the difference of each pixel from the previous one.
252 ///
253 /// This means that instead of having in order `[r1, g1. b1, r2, g2 ...]` you will find
254 /// `[r1, g1, b1, r2-r1, g2-g1, b2-b1, r3-r2, g3-g2, ...]`
255 Horizontal = 2,
256 /// Not currently supported
257 FloatingPoint = 3,
258}
259}
260
261tags! {
262/// The unit of pixel resolution.
263pub enum ResolutionUnit(u16) {
264 None = 1,
265 Inch = 2,
266 Centimeter = 3,
267}
268}
269
270tags! {
271/// The format of sample values in each pixel (unsigned int, signed int, or floating point).
272pub enum SampleFormat(u16) unknown("An unknown extension sample format") {
273 /// Unsigned integer data
274 Uint = 1,
275 /// Signed integer data
276 Int = 2,
277 /// Floating point data (either 32-bit or 64-bit)
278 Float = 3,
279 Void = 4,
280}
281}