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    // palette-color images (PhotometricInterpretation 3)
88    ColorMap = 320,
89    Compression = 259,
90    Copyright = 33_432,
91    DateTime = 306,
92    ExtraSamples = 338,
93    FillOrder = 266,
94    FreeByteCounts = 289,
95    FreeOffsets = 288,
96    GrayResponseCurve = 291,
97    GrayResponseUnit = 290,
98    HostComputer = 316,
99    ImageDescription = 270,
100    ImageLength = 257,
101    ImageWidth = 256,
102    Make = 271,
103    MaxSampleValue = 281,
104    MinSampleValue = 280,
105    Model = 272,
106    NewSubfileType = 254,
107    Orientation = 274,
108    PhotometricInterpretation = 262,
109    PlanarConfiguration = 284,
110    ResolutionUnit = 296,
111    RowsPerStrip = 278,
112    SamplesPerPixel = 277,
113    Software = 305,
114    StripByteCounts = 279,
115    StripOffsets = 273,
116    SubfileType = 255,
117    Threshholding = 263,
118    XResolution = 282,
119    YResolution = 283,
120    Predictor = 317,
121    TileWidth = 322,
122    TileLength = 323,
123    TileOffsets = 324,
124    TileByteCounts = 325,
125    // Data Sample Format
126    SampleFormat = 339,
127    SMinSampleValue = 340,
128    SMaxSampleValue = 341,
129    // JPEG
130    JPEGTables = 347,
131    // GeoTIFF
132    ModelPixelScale = 33550, // (SoftDesk)
133    ModelTransformation = 34264, // (JPL Carto Group)
134    ModelTiepoint = 33922, // (Intergraph)
135    GeoKeyDirectory = 34735, // (SPOT)
136    GeoDoubleParams = 34736, // (SPOT)
137    GeoAsciiParams = 34737, // (SPOT)
138    GdalNodata = 42113, // Contains areas with missing data
139    GdalMetadata = 42112, // XML metadata string
140}
141}
142
143tags! {
144/// The type of an IFD entry (a 2 byte field).
145pub enum Type(u16) {
146    /// 8-bit unsigned integer
147    BYTE = 1,
148    /// 8-bit byte that contains a 7-bit ASCII code; the last byte must be zero
149    ASCII = 2,
150    /// 16-bit unsigned integer
151    SHORT = 3,
152    /// 32-bit unsigned integer
153    LONG = 4,
154    /// Fraction stored as two 32-bit unsigned integers
155    RATIONAL = 5,
156    /// 8-bit signed integer
157    SBYTE = 6,
158    /// 8-bit byte that may contain anything, depending on the field
159    UNDEFINED = 7,
160    /// 16-bit signed integer
161    SSHORT = 8,
162    /// 32-bit signed integer
163    SLONG = 9,
164    /// Fraction stored as two 32-bit signed integers
165    SRATIONAL = 10,
166    /// 32-bit IEEE floating point
167    FLOAT = 11,
168    /// 64-bit IEEE floating point
169    DOUBLE = 12,
170    /// 32-bit unsigned integer (offset)
171    IFD = 13,
172    /// BigTIFF 64-bit unsigned integer
173    LONG8 = 16,
174    /// BigTIFF 64-bit signed integer
175    SLONG8 = 17,
176    /// BigTIFF 64-bit unsigned integer (offset)
177    IFD8 = 18,
178}
179}
180
181tags! {
182/// Known compression methods.
183///
184/// See [TIFF compression tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html)
185/// for reference.
186pub enum CompressionMethod(u16) unknown("A custom compression method") {
187    None = 1,
188    Huffman = 2,
189    Fax3 = 3,
190    Fax4 = 4,
191    LZW = 5,
192    JPEG = 6,
193    // "Extended JPEG" or "new JPEG" style
194    ModernJPEG = 7,
195    Deflate = 8,
196    OldDeflate = 0x80B2,
197    PackBits = 0x8005,
198    JPEG2k = 34712,
199
200    // Self-assigned by libtiff
201    ZSTD = 0xC350,
202}
203}
204
205tags! {
206/// The color space of the image data.
207pub enum PhotometricInterpretation(u16) {
208    WhiteIsZero = 0,
209    BlackIsZero = 1,
210    RGB = 2,
211    RGBPalette = 3,
212    TransparencyMask = 4,
213    CMYK = 5,
214    YCbCr = 6,
215    CIELab = 8,
216}
217}
218
219tags! {
220/// How pixel components are stored: contiguously (chunky) or in separate planes (planar).
221pub enum PlanarConfiguration(u16) {
222    Chunky = 1,
223    Planar = 2,
224}
225}
226
227tags! {
228/// A mathematical operator applied to image data before compression to improve compression ratios.
229pub enum Predictor(u16) {
230    /// No changes were made to the data
231    None = 1,
232    /// The images' rows were processed to contain the difference of each pixel from the previous one.
233    ///
234    /// This means that instead of having in order `[r1, g1. b1, r2, g2 ...]` you will find
235    /// `[r1, g1, b1, r2-r1, g2-g1, b2-b1, r3-r2, g3-g2, ...]`
236    Horizontal = 2,
237    /// Not currently supported
238    FloatingPoint = 3,
239}
240}
241
242tags! {
243/// The unit of pixel resolution.
244pub enum ResolutionUnit(u16) {
245    None = 1,
246    Inch = 2,
247    Centimeter = 3,
248}
249}
250
251tags! {
252/// The format of sample values in each pixel (unsigned int, signed int, or floating point).
253pub enum SampleFormat(u16) unknown("An unknown extension sample format") {
254    /// Unsigned integer data
255    Uint = 1,
256    /// Signed integer data
257    Int = 2,
258    /// Floating point data (either 32-bit or 64-bit)
259    Float = 3,
260    Void = 4,
261}
262}