1macro_rules! tags {
2 {
3 // Permit arbitrary meta items, which include documentation.
4 $( #[$enum_attr:meta] )*
5 $vis:vis enum $name:ident($ty:tt) $(unknown($unknown_doc:literal))* {
6 // Each of the `Name = Val,` permitting documentation.
7 $($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
8 }
9 } => {
10 $( #[$enum_attr] )*
11 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
12 #[non_exhaustive]
13 pub enum $name {
14 $($(#[$ident_attr])* $tag,)*
15 $(
16 #[doc = $unknown_doc]
17 Unknown($ty),
18 )*
19 }
20
21 impl $name {
22 #[inline(always)]
23 fn __from_inner_type(n: $ty) -> Result<Self, $ty> {
24 match n {
25 $( $val => Ok($name::$tag), )*
26 n => Err(n),
27 }
28 }
29
30 #[inline(always)]
31 fn __to_inner_type(&self) -> $ty {
32 match *self {
33 $( $name::$tag => $val, )*
34 $( $name::Unknown(n) => { $unknown_doc; n }, )*
35 }
36 }
37 }
38
39 tags!($name, $ty, $($unknown_doc)*);
40 };
41 // For u16 tags, provide direct inherent primitive conversion methods.
42 ($name:tt, u16, $($unknown_doc:literal)*) => {
43 impl $name {
44 #[inline(always)]
45 pub fn from_u16(val: u16) -> Option<Self> {
46 Self::__from_inner_type(val).ok()
47 }
48
49 $(
50 #[inline(always)]
51 pub fn from_u16_exhaustive(val: u16) -> Self {
52 $unknown_doc;
53 Self::__from_inner_type(val).unwrap_or_else(|_| $name::Unknown(val))
54 }
55 )*
56
57 #[inline(always)]
58 pub fn to_u16(&self) -> u16 {
59 Self::__to_inner_type(self)
60 }
61 }
62 };
63 // For other tag types, do nothing for now. With concat_idents one could
64 // provide inherent conversion methods for all types.
65 ($name:tt, $ty:tt, $($unknown_doc:literal)*) => {};
66}
67
68// Note: These tags appear in the order they are mentioned in the TIFF reference
69tags! {
70/// TIFF tags
71pub enum Tag(u16) unknown("A private or extension tag") {
72 // Baseline tags:
73 Artist = 315,
74 // grayscale images PhotometricInterpretation 1 or 3
75 BitsPerSample = 258,
76 CellLength = 265, // TODO add support
77 CellWidth = 264, // TODO add support
78 // palette-color images (PhotometricInterpretation 3)
79 ColorMap = 320, // TODO add support
80 Compression = 259, // TODO add support for 2 and 32773
81 Copyright = 33_432,
82 DateTime = 306,
83 ExtraSamples = 338, // TODO add support
84 FillOrder = 266, // TODO add support
85 FreeByteCounts = 289, // TODO add support
86 FreeOffsets = 288, // TODO add support
87 GrayResponseCurve = 291, // TODO add support
88 GrayResponseUnit = 290, // TODO add support
89 HostComputer = 316,
90 ImageDescription = 270,
91 ImageLength = 257,
92 ImageWidth = 256,
93 Make = 271,
94 MaxSampleValue = 281, // TODO add support
95 MinSampleValue = 280, // TODO add support
96 Model = 272,
97 NewSubfileType = 254, // TODO add support
98 Orientation = 274, // TODO add support
99 PhotometricInterpretation = 262,
100 PlanarConfiguration = 284,
101 ResolutionUnit = 296, // TODO add support
102 RowsPerStrip = 278,
103 SamplesPerPixel = 277,
104 Software = 305,
105 StripByteCounts = 279,
106 StripOffsets = 273,
107 SubfileType = 255, // TODO add support
108 Threshholding = 263, // TODO add support
109 XResolution = 282,
110 YResolution = 283,
111 // Advanced tags
112 Predictor = 317,
113 TileWidth = 322,
114 TileLength = 323,
115 TileOffsets = 324,
116 TileByteCounts = 325,
117 // Data Sample Format
118 SampleFormat = 339,
119 SMinSampleValue = 340, // TODO add support
120 SMaxSampleValue = 341, // TODO add support
121 // JPEG
122 JPEGTables = 347,
123 // GeoTIFF
124 ModelPixelScaleTag = 33550, // (SoftDesk)
125 ModelTransformationTag = 34264, // (JPL Carto Group)
126 ModelTiepointTag = 33922, // (Intergraph)
127 GeoKeyDirectoryTag = 34735, // (SPOT)
128 GeoDoubleParamsTag = 34736, // (SPOT)
129 GeoAsciiParamsTag = 34737, // (SPOT)
130 GdalNodata = 42113, // Contains areas with missing data
131}
132}
133
134tags! {
135/// The type of an IFD entry (a 2 byte field).
136pub enum Type(u16) {
137 /// 8-bit unsigned integer
138 BYTE = 1,
139 /// 8-bit byte that contains a 7-bit ASCII code; the last byte must be zero
140 ASCII = 2,
141 /// 16-bit unsigned integer
142 SHORT = 3,
143 /// 32-bit unsigned integer
144 LONG = 4,
145 /// Fraction stored as two 32-bit unsigned integers
146 RATIONAL = 5,
147 /// 8-bit signed integer
148 SBYTE = 6,
149 /// 8-bit byte that may contain anything, depending on the field
150 UNDEFINED = 7,
151 /// 16-bit signed integer
152 SSHORT = 8,
153 /// 32-bit signed integer
154 SLONG = 9,
155 /// Fraction stored as two 32-bit signed integers
156 SRATIONAL = 10,
157 /// 32-bit IEEE floating point
158 FLOAT = 11,
159 /// 64-bit IEEE floating point
160 DOUBLE = 12,
161 /// 32-bit unsigned integer (offset)
162 IFD = 13,
163 /// BigTIFF 64-bit unsigned integer
164 LONG8 = 16,
165 /// BigTIFF 64-bit signed integer
166 SLONG8 = 17,
167 /// BigTIFF 64-bit unsigned integer (offset)
168 IFD8 = 18,
169}
170}
171
172tags! {
173/// See [TIFF compression tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html)
174/// for reference.
175pub enum CompressionMethod(u16) unknown("A custom compression method") {
176 None = 1,
177 Huffman = 2,
178 Fax3 = 3,
179 Fax4 = 4,
180 LZW = 5,
181 JPEG = 6,
182 // "Extended JPEG" or "new JPEG" style
183 ModernJPEG = 7,
184 Deflate = 8,
185 OldDeflate = 0x80B2,
186 PackBits = 0x8005,
187}
188}
189
190tags! {
191pub enum PhotometricInterpretation(u16) {
192 WhiteIsZero = 0,
193 BlackIsZero = 1,
194 RGB = 2,
195 RGBPalette = 3,
196 TransparencyMask = 4,
197 CMYK = 5,
198 YCbCr = 6,
199 CIELab = 8,
200}
201}
202
203tags! {
204pub enum PlanarConfiguration(u16) {
205 Chunky = 1,
206 Planar = 2,
207}
208}
209
210tags! {
211pub enum Predictor(u16) {
212 None = 1,
213 Horizontal = 2,
214 FloatingPoint = 3,
215}
216}
217
218tags! {
219/// Type to represent resolution units
220pub enum ResolutionUnit(u16) {
221 None = 1,
222 Inch = 2,
223 Centimeter = 3,
224}
225}
226
227tags! {
228pub enum SampleFormat(u16) unknown("An unknown extension sample format") {
229 Uint = 1,
230 Int = 2,
231 IEEEFP = 3,
232 Void = 4,
233}
234}
235