Skip to main content

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}