1use alloc::borrow::Cow;
8use alloc::format;
9
10use super::walk::Kind;
11
12pub fn tag_known(kind: Kind, tag: u16) -> bool {
13 lookup(kind, tag).is_some()
14}
15
16pub fn tag_name(kind: Kind, tag: u16) -> Cow<'static, str> {
17 match lookup(kind, tag) {
18 Some(n) => Cow::Borrowed(n),
19 None => Cow::Owned(format!("tag {tag}")),
20 }
21}
22
23fn lookup(kind: Kind, tag: u16) -> Option<&'static str> {
24 let table = match kind {
25 Kind::Gps => GPS_TAGS,
26 Kind::Interop => INTEROP_TAGS,
27 Kind::MakerNote => return None,
29 _ => TIFF_TAGS,
30 };
31 table
32 .binary_search_by_key(&tag, |&(t, _)| t)
33 .ok()
34 .map(|i| table[i].1)
35}
36
37const INTEROP_TAGS: &[(u16, &str)] = &[
38 (1, "InteropIndex"),
39 (2, "InteropVersion"),
40 (4096, "RelatedImageFileFormat"),
41 (4097, "RelatedImageWidth"),
42 (4098, "RelatedImageHeight"),
43];
44
45const GPS_TAGS: &[(u16, &str)] = &[
46 (0, "GPSVersionID"),
47 (1, "GPSLatitudeRef"),
48 (2, "GPSLatitude"),
49 (3, "GPSLongitudeRef"),
50 (4, "GPSLongitude"),
51 (5, "GPSAltitudeRef"),
52 (6, "GPSAltitude"),
53 (7, "GPSTimeStamp"),
54 (8, "GPSSatellites"),
55 (9, "GPSStatus"),
56 (10, "GPSMeasureMode"),
57 (11, "GPSDOP"),
58 (12, "GPSSpeedRef"),
59 (13, "GPSSpeed"),
60 (14, "GPSTrackRef"),
61 (15, "GPSTrack"),
62 (16, "GPSImgDirectionRef"),
63 (17, "GPSImgDirection"),
64 (18, "GPSMapDatum"),
65 (19, "GPSDestLatitudeRef"),
66 (20, "GPSDestLatitude"),
67 (21, "GPSDestLongitudeRef"),
68 (22, "GPSDestLongitude"),
69 (23, "GPSDestBearingRef"),
70 (24, "GPSDestBearing"),
71 (25, "GPSDestDistanceRef"),
72 (26, "GPSDestDistance"),
73 (27, "GPSProcessingMethod"),
74 (28, "GPSAreaInformation"),
75 (29, "GPSDateStamp"),
76 (30, "GPSDifferential"),
77 (31, "GPSHPositioningError"),
78];
79
80const TIFF_TAGS: &[(u16, &str)] = &[
82 (254, "NewSubfileType"),
83 (255, "SubfileType"),
84 (256, "ImageWidth"),
85 (257, "ImageLength"),
86 (258, "BitsPerSample"),
87 (259, "Compression"),
88 (262, "PhotometricInterpretation"),
89 (263, "Threshholding"),
90 (264, "CellWidth"),
91 (265, "CellLength"),
92 (266, "FillOrder"),
93 (269, "DocumentName"),
94 (270, "ImageDescription"),
95 (271, "Make"),
96 (272, "Model"),
97 (273, "StripOffsets"),
98 (274, "Orientation"),
99 (277, "SamplesPerPixel"),
100 (278, "RowsPerStrip"),
101 (279, "StripByteCounts"),
102 (280, "MinSampleValue"),
103 (281, "MaxSampleValue"),
104 (282, "XResolution"),
105 (283, "YResolution"),
106 (284, "PlanarConfiguration"),
107 (285, "PageName"),
108 (286, "XPosition"),
109 (287, "YPosition"),
110 (288, "FreeOffsets"),
111 (289, "FreeByteCounts"),
112 (290, "GrayResponseUnit"),
113 (291, "GrayResponseCurve"),
114 (292, "T4Options"),
115 (293, "T6Options"),
116 (296, "ResolutionUnit"),
117 (297, "PageNumber"),
118 (301, "TransferFunction"),
119 (305, "Software"),
120 (306, "DateTime"),
121 (315, "Artist"),
122 (316, "HostComputer"),
123 (317, "Predictor"),
124 (318, "WhitePoint"),
125 (319, "PrimaryChromaticities"),
126 (320, "ColorMap"),
127 (321, "HalftoneHints"),
128 (322, "TileWidth"),
129 (323, "TileLength"),
130 (324, "TileOffsets"),
131 (325, "TileByteCounts"),
132 (326, "BadFaxLines"),
133 (327, "CleanFaxData"),
134 (328, "ConsecutiveBadFaxLines"),
135 (330, "SubIFDs"),
136 (332, "InkSet"),
137 (333, "InkNames"),
138 (334, "NumberOfInks"),
139 (336, "DotRange"),
140 (337, "TargetPrinter"),
141 (338, "ExtraSamples"),
142 (339, "SampleFormat"),
143 (340, "SMinSampleValue"),
144 (341, "SMaxSampleValue"),
145 (342, "TransferRange"),
146 (343, "ClipPath"),
147 (344, "XClipPathUnits"),
148 (345, "YClipPathUnits"),
149 (346, "Indexed"),
150 (347, "JPEGTables"),
151 (351, "OPIProxy"),
152 (400, "GlobalParametersIFD"),
153 (401, "ProfileType"),
154 (402, "FaxProfile"),
155 (403, "CodingMethods"),
156 (404, "VersionYear"),
157 (405, "ModeNumber"),
158 (433, "Decode"),
159 (434, "DefaultImageColor"),
160 (512, "JPEGProc"),
161 (513, "JPEGInterchangeFormat"),
162 (514, "JPEGInterchangeFormatLength"),
163 (515, "JPEGRestartInterval"),
164 (517, "JPEGLosslessPredictors"),
165 (518, "JPEGPointTransforms"),
166 (519, "JPEGQTables"),
167 (520, "JPEGDCTables"),
168 (521, "JPEGACTables"),
169 (529, "YCbCrCoefficients"),
170 (530, "YCbCrSubSampling"),
171 (531, "YCbCrPositioning"),
172 (532, "ReferenceBlackWhite"),
173 (559, "StripRowCounts"),
174 (700, "XMP"),
175 (18246, "Rating"),
176 (18249, "RatingPercent"),
177 (32781, "ImageID"),
178 (32932, "WangAnnotation"),
179 (32995, "Matteing"),
180 (32996, "DataType"),
181 (32997, "ImageDepth"),
182 (32998, "TileDepth"),
183 (33421, "CFARepeatPatternDim"),
184 (33422, "CFAPattern"),
185 (33423, "BatteryLevel"),
186 (33432, "Copyright"),
187 (33434, "ExposureTime"),
188 (33437, "FNumber"),
189 (33550, "ModelPixelScale"),
190 (33723, "IPTC-NAA"),
191 (33922, "ModelTiepoint"),
192 (34264, "ModelTransformation"),
193 (34377, "Photoshop"),
194 (34665, "ExifIFD"),
195 (34675, "ICCProfile"),
196 (34732, "ImageLayer"),
197 (34735, "GeoKeyDirectory"),
198 (34736, "GeoDoubleParams"),
199 (34737, "GeoAsciiParams"),
200 (34850, "ExposureProgram"),
201 (34852, "SpectralSensitivity"),
202 (34853, "GPSInfo"),
203 (34855, "ISOSpeedRatings"),
204 (34856, "OECF"),
205 (34857, "Interlace"),
206 (34858, "TimeZoneOffset"),
207 (34859, "SelfTimerMode"),
208 (34864, "SensitivityType"),
209 (34865, "StandardOutputSensitivity"),
210 (34866, "RecommendedExposureIndex"),
211 (34867, "ISOSpeed"),
212 (34868, "ISOSpeedLatitudeyyy"),
213 (34869, "ISOSpeedLatitudezzz"),
214 (36864, "ExifVersion"),
215 (36867, "DateTimeOriginal"),
216 (36868, "DateTimeDigitized"),
217 (36880, "OffsetTime"),
218 (36881, "OffsetTimeOriginal"),
219 (36882, "OffsetTimeDigitized"),
220 (37121, "ComponentsConfiguration"),
221 (37122, "CompressedBitsPerPixel"),
222 (37377, "ShutterSpeedValue"),
223 (37378, "ApertureValue"),
224 (37379, "BrightnessValue"),
225 (37380, "ExposureBiasValue"),
226 (37381, "MaxApertureValue"),
227 (37382, "SubjectDistance"),
228 (37383, "MeteringMode"),
229 (37384, "LightSource"),
230 (37385, "Flash"),
231 (37386, "FocalLength"),
232 (37387, "FlashEnergy"),
233 (37388, "SpatialFrequencyResponse"),
234 (37389, "Noise"),
235 (37390, "FocalPlaneXResolution"),
236 (37391, "FocalPlaneYResolution"),
237 (37392, "FocalPlaneResolutionUnit"),
238 (37393, "ImageNumber"),
239 (37394, "SecurityClassification"),
240 (37395, "ImageHistory"),
241 (37396, "SubjectArea"),
242 (37397, "ExposureIndex"),
243 (37398, "TIFF-EPStandardID"),
244 (37399, "SensingMethod"),
245 (37439, "StoNits"),
246 (37500, "MakerNote"),
247 (37510, "UserComment"),
248 (37520, "SubSecTime"),
249 (37521, "SubSecTimeOriginal"),
250 (37522, "SubSecTimeDigitized"),
251 (37888, "AmbientTemperature"),
252 (37889, "Humidity"),
253 (37890, "Pressure"),
254 (37891, "WaterDepth"),
255 (37892, "Acceleration"),
256 (37893, "CameraElevationAngle"),
257 (40091, "XPTitle"),
258 (40092, "XPComment"),
259 (40093, "XPAuthor"),
260 (40094, "XPKeywords"),
261 (40095, "XPSubject"),
262 (40960, "FlashpixVersion"),
263 (40961, "ColorSpace"),
264 (40962, "PixelXDimension"),
265 (40963, "PixelYDimension"),
266 (40964, "RelatedSoundFile"),
267 (40965, "InteropIFD"),
268 (41483, "FlashEnergy"),
269 (41484, "SpatialFrequencyResponse"),
270 (41486, "FocalPlaneXResolution"),
271 (41487, "FocalPlaneYResolution"),
272 (41488, "FocalPlaneResolutionUnit"),
273 (41492, "SubjectLocation"),
274 (41493, "ExposureIndex"),
275 (41495, "SensingMethod"),
276 (41728, "FileSource"),
277 (41729, "SceneType"),
278 (41730, "CFAPattern"),
279 (41985, "CustomRendered"),
280 (41986, "ExposureMode"),
281 (41987, "WhiteBalance"),
282 (41988, "DigitalZoomRatio"),
283 (41989, "FocalLengthIn35mmFilm"),
284 (41990, "SceneCaptureType"),
285 (41991, "GainControl"),
286 (41992, "Contrast"),
287 (41993, "Saturation"),
288 (41994, "Sharpness"),
289 (41995, "DeviceSettingDescription"),
290 (41996, "SubjectDistanceRange"),
291 (42016, "ImageUniqueID"),
292 (42032, "CameraOwnerName"),
293 (42033, "BodySerialNumber"),
294 (42034, "LensSpecification"),
295 (42035, "LensMake"),
296 (42036, "LensModel"),
297 (42037, "LensSerialNumber"),
298 (42038, "ImageTitle"),
299 (42039, "Photographer"),
300 (42040, "ImageEditor"),
301 (42041, "CameraFirmware"),
302 (42042, "RAWDevelopingSoftware"),
303 (42043, "ImageEditingSoftware"),
304 (42044, "MetadataEditingSoftware"),
305 (42080, "CompositeImage"),
306 (42081, "SourceImageNumberOfCompositeImage"),
307 (42082, "SourceExposureTimesOfCompositeImage"),
308 (42112, "GDAL_METADATA"),
309 (42113, "GDAL_NODATA"),
310 (42240, "Gamma"),
311 (50341, "PrintImageMatching"),
312 (50706, "DNGVersion"),
313 (50707, "DNGBackwardVersion"),
314 (50708, "UniqueCameraModel"),
315 (50709, "LocalizedCameraModel"),
316 (50710, "CFAPlaneColor"),
317 (50711, "CFALayout"),
318 (50712, "LinearizationTable"),
319 (50713, "BlackLevelRepeatDim"),
320 (50714, "BlackLevel"),
321 (50715, "BlackLevelDeltaH"),
322 (50716, "BlackLevelDeltaV"),
323 (50717, "WhiteLevel"),
324 (50718, "DefaultScale"),
325 (50719, "DefaultCropOrigin"),
326 (50720, "DefaultCropSize"),
327 (50721, "ColorMatrix1"),
328 (50722, "ColorMatrix2"),
329 (50723, "CameraCalibration1"),
330 (50724, "CameraCalibration2"),
331 (50725, "ReductionMatrix1"),
332 (50726, "ReductionMatrix2"),
333 (50727, "AnalogBalance"),
334 (50728, "AsShotNeutral"),
335 (50729, "AsShotWhiteXY"),
336 (50730, "BaselineExposure"),
337 (50731, "BaselineNoise"),
338 (50732, "BaselineSharpness"),
339 (50733, "BayerGreenSplit"),
340 (50734, "LinearResponseLimit"),
341 (50735, "CameraSerialNumber"),
342 (50736, "LensInfo"),
343 (50737, "ChromaBlurRadius"),
344 (50738, "AntiAliasStrength"),
345 (50739, "ShadowScale"),
346 (50740, "DNGPrivateData"),
347 (50741, "MakerNoteSafety"),
348 (50778, "CalibrationIlluminant1"),
349 (50779, "CalibrationIlluminant2"),
350 (50780, "BestQualityScale"),
351 (50781, "RawDataUniqueID"),
352 (50827, "OriginalRawFileName"),
353 (50828, "OriginalRawFileData"),
354 (50829, "ActiveArea"),
355 (50830, "MaskedAreas"),
356 (50831, "AsShotICCProfile"),
357 (50832, "AsShotPreProfileMatrix"),
358 (50833, "CurrentICCProfile"),
359 (50834, "CurrentPreProfileMatrix"),
360 (50879, "ColorimetricReference"),
361 (50931, "CameraCalibrationSignature"),
362 (50932, "ProfileCalibrationSignature"),
363 (50933, "ExtraCameraProfiles"),
364 (50934, "AsShotProfileName"),
365 (50935, "NoiseReductionApplied"),
366 (50936, "ProfileName"),
367 (50937, "ProfileHueSatMapDims"),
368 (50938, "ProfileHueSatMapData1"),
369 (50939, "ProfileHueSatMapData2"),
370 (50940, "ProfileToneCurve"),
371 (50941, "ProfileEmbedPolicy"),
372 (50942, "ProfileCopyright"),
373 (50964, "ForwardMatrix1"),
374 (50965, "ForwardMatrix2"),
375 (50966, "PreviewApplicationName"),
376 (50967, "PreviewApplicationVersion"),
377 (50968, "PreviewSettingsName"),
378 (50969, "PreviewSettingsDigest"),
379 (50970, "PreviewColorSpace"),
380 (50971, "PreviewDateTime"),
381 (50972, "RawImageDigest"),
382 (50973, "OriginalRawFileDigest"),
383 (50974, "SubTileBlockSize"),
384 (50975, "RowInterleaveFactor"),
385 (50981, "ProfileLookTableDims"),
386 (50982, "ProfileLookTableData"),
387 (51008, "OpcodeList1"),
388 (51009, "OpcodeList2"),
389 (51022, "OpcodeList3"),
390 (51041, "NoiseProfile"),
391 (51089, "OriginalDefaultFinalSize"),
392 (51090, "OriginalBestQualityFinalSize"),
393 (51091, "OriginalDefaultCropSize"),
394 (51107, "ProfileHueSatMapEncoding"),
395 (51108, "ProfileLookTableEncoding"),
396 (51109, "BaselineExposureOffset"),
397 (51110, "DefaultBlackRender"),
398 (51111, "NewRawImageDigest"),
399 (51112, "RawToPreviewGain"),
400 (51125, "DefaultUserCrop"),
401 (51177, "DepthFormat"),
402 (51178, "DepthNear"),
403 (51179, "DepthFar"),
404 (51180, "DepthUnits"),
405 (51181, "DepthMeasureType"),
406 (51182, "EnhanceParams"),
407 (52525, "ProfileGainTableMap"),
408 (52526, "SemanticName"),
409 (52528, "SemanticInstanceID"),
410 (52529, "CalibrationIlluminant3"),
411 (52530, "CameraCalibration3"),
412 (52531, "ColorMatrix3"),
413 (52532, "ForwardMatrix3"),
414 (52533, "IlluminantData1"),
415 (52534, "IlluminantData2"),
416 (52535, "IlluminantData3"),
417 (52536, "MaskSubArea"),
418 (52537, "ProfileHueSatMapData3"),
419 (52538, "ReductionMatrix3"),
420 (52543, "RGBTables"),
421 (52544, "ProfileGainTableMap2"),
422 (52547, "ColumnInterleaveFactor"),
423 (52548, "ImageSequenceInfo"),
424 (52550, "ImageStats"),
425 (52551, "ProfileDynamicRange"),
426 (52552, "ProfileGroupName"),
427 (52553, "JXLDistance"),
428 (52554, "JXLEffort"),
429 (52555, "JXLDecodeSpeed"),
430 (59932, "Padding"),
431 (59933, "OffsetSchema"),
432];
433
434#[cfg(test)]
435mod tests {
436 use super::*;
437
438 #[test]
439 fn tag_tables_are_sorted() {
440 for table in [TIFF_TAGS, GPS_TAGS, INTEROP_TAGS] {
441 assert!(table.windows(2).all(|p| p[0].0 < p[1].0));
442 }
443 }
444}