1 macro_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 pub enum $name { 13 $($(#[$ident_attr])* $tag,)* 14 // FIXME: switch to non_exhaustive once stabilized and compiler requirement new enough 15 #[doc(hidden)] 16 __NonExhaustive, 17 $( 18 #[doc = $unknown_doc] 19 Unknown($ty), 20 )* 21 } 22 23 impl $name { 24 #[inline(always)] 25 fn __from_inner_type(n: $ty) -> Result<Self, $ty> { 26 match n { 27 $( $val => Ok($name::$tag), )* 28 n => Err(n), 29 } 30 } 31 32 #[inline(always)] 33 fn __to_inner_type(&self) -> $ty { 34 match *self { 35 $( $name::$tag => $val, )* 36 $( $name::Unknown(n) => { $unknown_doc; n }, )* 37 $name::__NonExhaustive => unreachable!(), 38 } 39 } 40 } 41 42 tags!($name, $ty, $($unknown_doc)*); 43 }; 44 // For u16 tags, provide direct inherent primitive conversion methods. 45 ($name:tt, u16, $($unknown_doc:literal)*) => { 46 impl $name { 47 #[inline(always)] 48 pub fn from_u16(val: u16) -> Option<Self> { 49 Self::__from_inner_type(val).ok() 50 } 51 52 $( 53 #[inline(always)] 54 pub fn from_u16_exhaustive(val: u16) -> Self { 55 $unknown_doc; 56 Self::__from_inner_type(val).unwrap_or_else(|_| $name::Unknown(val)) 57 } 58 )* 59 60 #[inline(always)] 61 pub fn to_u16(&self) -> u16 { 62 Self::__to_inner_type(self) 63 } 64 } 65 }; 66 // For other tag types, do nothing for now. With concat_idents one could 67 // provide inherent conversion methods for all types. 68 ($name:tt, $ty:tt, $($unknown_doc:literal)*) => {}; 69 } 70 71 // Note: These tags appear in the order they are mentioned in the TIFF reference 72 tags! { 73 /// TIFF tags 74 pub enum Tag(u16) unknown("A private or extension tag") { 75 // Baseline tags: 76 Artist = 315, 77 // grayscale images PhotometricInterpretation 1 or 3 78 BitsPerSample = 258, 79 CellLength = 265, // TODO add support 80 CellWidth = 264, // TODO add support 81 // palette-color images (PhotometricInterpretation 3) 82 ColorMap = 320, // TODO add support 83 Compression = 259, // TODO add support for 2 and 32773 84 Copyright = 33_432, 85 DateTime = 306, 86 ExtraSamples = 338, // TODO add support 87 FillOrder = 266, // TODO add support 88 FreeByteCounts = 289, // TODO add support 89 FreeOffsets = 288, // TODO add support 90 GrayResponseCurve = 291, // TODO add support 91 GrayResponseUnit = 290, // TODO add support 92 HostComputer = 316, 93 ImageDescription = 270, 94 ImageLength = 257, 95 ImageWidth = 256, 96 Make = 271, 97 MaxSampleValue = 281, // TODO add support 98 MinSampleValue = 280, // TODO add support 99 Model = 272, 100 NewSubfileType = 254, // TODO add support 101 Orientation = 274, // TODO add support 102 PhotometricInterpretation = 262, 103 PlanarConfiguration = 284, 104 ResolutionUnit = 296, // TODO add support 105 RowsPerStrip = 278, 106 SamplesPerPixel = 277, 107 Software = 305, 108 StripByteCounts = 279, 109 StripOffsets = 273, 110 SubfileType = 255, // TODO add support 111 Threshholding = 263, // TODO add support 112 XResolution = 282, 113 YResolution = 283, 114 // JPEG 115 JPEGTables = 347, 116 // Advanced tags 117 Predictor = 317, 118 TileWidth = 322, 119 TileLength = 323, 120 TileOffsets = 324, 121 TileByteCounts = 325, 122 SampleFormat = 339, 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 134 tags! { 135 /// The type of an IFD entry (a 2 byte field). 136 pub enum Type(u16) { 137 BYTE = 1, 138 ASCII = 2, 139 SHORT = 3, 140 LONG = 4, 141 RATIONAL = 5, 142 SBYTE = 6, 143 UNDEFINED = 7, 144 SSHORT = 8, 145 SLONG = 9, 146 SRATIONAL = 10, 147 FLOAT = 11, 148 DOUBLE = 12, 149 /// BigTIFF 64-bit unsigned integer 150 LONG8 = 16, 151 } 152 } 153 154 tags! { 155 /// See [TIFF compression tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html) 156 /// for reference. 157 pub enum CompressionMethod(u16) { 158 None = 1, 159 Huffman = 2, 160 Fax3 = 3, 161 Fax4 = 4, 162 LZW = 5, 163 JPEG = 6, 164 // "Extended JPEG" or "new JPEG" style 165 ModernJPEG = 7, 166 Deflate = 8, 167 OldDeflate = 0x80B2, 168 PackBits = 0x8005, 169 } 170 } 171 172 tags! { 173 pub enum PhotometricInterpretation(u16) { 174 WhiteIsZero = 0, 175 BlackIsZero = 1, 176 RGB = 2, 177 RGBPalette = 3, 178 TransparencyMask = 4, 179 CMYK = 5, 180 YCbCr = 6, 181 CIELab = 8, 182 } 183 } 184 185 tags! { 186 pub enum PlanarConfiguration(u16) { 187 Chunky = 1, 188 Planar = 2, 189 } 190 } 191 192 tags! { 193 pub enum Predictor(u16) { 194 None = 1, 195 Horizontal = 2, 196 } 197 } 198 199 tags! { 200 /// Type to represent resolution units 201 pub enum ResolutionUnit(u16) { 202 None = 1, 203 Inch = 2, 204 Centimeter = 3, 205 } 206 } 207 208 tags! { 209 pub enum SampleFormat(u16) unknown("An unknown extension sample format") { 210 Uint = 1, 211 Int = 2, 212 IEEEFP = 3, 213 Void = 4, 214 } 215 } 216