1 use std::borrow::Cow;
2 use super::exifreadable::*;
3 use super::types::*;
4
5 type ReadableFn = fn(&TagValue) -> Option<Cow<'static, str>>;
6
7 /// Convert a numeric tag into ExifTag enumeration, and yields information about the tag. This information
8 /// is used by the main body of the parser to sanity-check the tags found in image
9 /// and make sure that EXIF tags have the right data types
10 ///
11 /// Returns (tag, unit, format, min_count, max_count, more_readable)
tag_to_exif(f: u16) -> (ExifTag, &'static str, IfdFormat, i32, i32, ReadableFn)12 pub fn tag_to_exif(f: u16) -> (ExifTag, &'static str, IfdFormat, i32, i32, ReadableFn)
13 {
14 match f {
15
16 0x010e =>
17 (ExifTag::ImageDescription, "none", IfdFormat::Ascii,
18 -1i32, -1i32, strpass),
19
20 0x010f =>
21 (ExifTag::Make, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
22
23 0x013c =>
24 (ExifTag::HostComputer, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
25
26 0x0110 =>
27 (ExifTag::Model, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
28
29 0x0112 =>
30 (ExifTag::Orientation, "none", IfdFormat::U16, 1, 1, orientation),
31
32 0x011a =>
33 (ExifTag::XResolution, "pixels per res unit",
34 IfdFormat::URational, 1, 1, rational_value),
35
36 0x011b =>
37 (ExifTag::YResolution, "pixels per res unit",
38 IfdFormat::URational, 1, 1, rational_value),
39
40 0x0128 =>
41 (ExifTag::ResolutionUnit, "none", IfdFormat::U16, 1, 1, resolution_unit),
42
43 0x0131 =>
44 (ExifTag::Software, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
45
46 0x0132 =>
47 (ExifTag::DateTime, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
48
49 0x013e =>
50 (ExifTag::WhitePoint, "CIE 1931 coordinates",
51 IfdFormat::URational, 2, 2, rational_values),
52
53 0x013f =>
54 (ExifTag::PrimaryChromaticities, "CIE 1931 coordinates",
55 IfdFormat::URational, 6, 6, rational_values),
56
57 0x0211 =>
58 (ExifTag::YCbCrCoefficients, "none",
59 IfdFormat::URational, 3, 3, rational_values),
60
61 0x0214 =>
62 (ExifTag::ReferenceBlackWhite, "RGB or YCbCr",
63 IfdFormat::URational, 6, 6, rational_values),
64
65 0x8298 =>
66 (ExifTag::Copyright, "none", IfdFormat::Ascii, -1i32, -1i32, strpass),
67
68 0x8769 =>
69 (ExifTag::ExifOffset, "byte offset",
70 IfdFormat::U32, 1, 1, strpass),
71
72 0x8825 =>
73 (ExifTag::GPSOffset, "byte offset",
74 IfdFormat::U32, 1, 1, strpass),
75
76 0x829a =>
77 (ExifTag::ExposureTime, "s",
78 IfdFormat::URational, 1, 1, exposure_time),
79
80 0x829d =>
81 (ExifTag::FNumber, "f-number",
82 IfdFormat::URational, 1, 1, f_number),
83
84 0x8822 =>
85 (ExifTag::ExposureProgram, "none",
86 IfdFormat::U16, 1, 1, exposure_program),
87
88 0x8824 =>
89 (ExifTag::SpectralSensitivity, "ASTM string",
90 IfdFormat::Ascii, -1i32, -1i32, strpass),
91
92 0x8830 =>
93 (ExifTag::SensitivityType, "none",
94 IfdFormat::U16, 1, 1, sensitivity_type),
95
96 0x8827 =>
97 (ExifTag::ISOSpeedRatings, "ISO",
98 IfdFormat::U16, 1, 3, iso_speeds),
99
100 0x8828 =>
101 (ExifTag::OECF, "none",
102 IfdFormat::Undefined, -1i32, -1i32, undefined_as_blob),
103
104 0x9000 =>
105 (ExifTag::ExifVersion, "none",
106 IfdFormat::Undefined, -1i32, -1i32, undefined_as_ascii),
107
108 0x9003 =>
109 (ExifTag::DateTimeOriginal, "none",
110 IfdFormat::Ascii, -1i32, -1i32, strpass),
111
112 0x9004 =>
113 (ExifTag::DateTimeDigitized, "none",
114 IfdFormat::Ascii, -1i32, -1i32, strpass),
115
116 0x9201 =>
117 (ExifTag::ShutterSpeedValue, "APEX",
118 IfdFormat::IRational, 1, 1, apex_tv),
119
120 0x9202 =>
121 (ExifTag::ApertureValue, "APEX",
122 IfdFormat::URational, 1, 1, apex_av),
123
124 0x9203 =>
125 (ExifTag::BrightnessValue, "APEX",
126 IfdFormat::IRational, 1, 1, apex_brightness),
127
128 0x9204 =>
129 (ExifTag::ExposureBiasValue, "APEX",
130 IfdFormat::IRational, 1, 1, apex_ev),
131
132 0x9205 =>
133 (ExifTag::MaxApertureValue,
134 "APEX", IfdFormat::URational, 1, 1, apex_av),
135
136 0x9206 =>
137 (ExifTag::SubjectDistance, "m",
138 IfdFormat::URational, 1, 1, meters),
139
140 0x9207 =>
141 (ExifTag::MeteringMode, "none",
142 IfdFormat::U16, 1, 1, metering_mode),
143
144 0x9208 =>
145 (ExifTag::LightSource, "none",
146 IfdFormat::U16, 1, 1, light_source),
147
148 0x9209 => (ExifTag::Flash, "none",
149 IfdFormat::U16, 1, 2, flash),
150
151 0x920a =>
152 (ExifTag::FocalLength, "mm",
153 IfdFormat::URational, 1, 1, focal_length),
154
155 0x9214 =>
156 (ExifTag::SubjectArea, "px",
157 IfdFormat::U16, 2, 4, subject_area),
158
159 0x927c =>
160 (ExifTag::MakerNote, "none",
161 IfdFormat::Undefined, -1i32, -1i32, undefined_as_blob),
162
163 0x9286 =>
164 (ExifTag::UserComment, "none",
165 IfdFormat::Undefined, -1i32, -1i32, undefined_as_encoded_string),
166
167 0xa000 =>
168 (ExifTag::FlashPixVersion, "none",
169 IfdFormat::Undefined, -1i32, -1i32, undefined_as_ascii),
170
171 0xa001 =>
172 (ExifTag::ColorSpace, "none",
173 IfdFormat::U16, 1, 1, color_space),
174
175 0xa004 =>
176 (ExifTag::RelatedSoundFile, "none",
177 IfdFormat::Ascii, -1i32, -1i32, strpass),
178
179 0xa20b => (ExifTag::FlashEnergy, "BCPS",
180 IfdFormat::URational, 1, 1, flash_energy),
181
182 0xa20e =>
183 (ExifTag::FocalPlaneXResolution, "@FocalPlaneResolutionUnit",
184 IfdFormat::URational, 1, 1, rational_value),
185
186 0xa20f =>
187 (ExifTag::FocalPlaneYResolution, "@FocalPlaneResolutionUnit",
188 IfdFormat::URational, 1, 1, rational_value),
189
190 0xa210 =>
191 (ExifTag::FocalPlaneResolutionUnit, "none",
192 IfdFormat::U16, 1, 1, resolution_unit),
193
194 0xa214 =>
195 (ExifTag::SubjectLocation, "X,Y",
196 IfdFormat::U16, 2, 2, subject_location),
197
198 // TODO check if rational as decimal value is the best for this one
199 0xa215 =>
200 (ExifTag::ExposureIndex, "EI",
201 IfdFormat::URational, 1, 1, rational_value),
202
203 0xa217 =>
204 (ExifTag::SensingMethod, "none",
205 IfdFormat::U16, 1, 1, sensing_method),
206
207 0xa300 =>
208 (ExifTag::FileSource, "none",
209 IfdFormat::Undefined, 1, 1, file_source),
210
211 0xa301 =>
212 (ExifTag::SceneType, "none",
213 IfdFormat::Undefined, 1, 1, scene_type),
214
215 0xa302 =>
216 (ExifTag::CFAPattern, "none",
217 IfdFormat::Undefined, -1i32, -1i32, undefined_as_u8),
218
219 0xa401 =>
220 (ExifTag::CustomRendered, "none",
221 IfdFormat::U16, 1, 1, custom_rendered),
222
223 0xa402 =>
224 (ExifTag::ExposureMode, "none",
225 IfdFormat::U16, 1, 1, exposure_mode),
226
227 0xa403 =>
228 (ExifTag::WhiteBalanceMode, "none",
229 IfdFormat::U16, 1, 1, white_balance_mode),
230
231 0xa404 =>
232 (ExifTag::DigitalZoomRatio, "none",
233 IfdFormat::URational, 1, 1, rational_value),
234
235 0xa405 =>
236 (ExifTag::FocalLengthIn35mmFilm, "mm",
237 IfdFormat::U16, 1, 1, focal_length_35),
238
239 0xa406 =>
240 (ExifTag::SceneCaptureType, "none",
241 IfdFormat::U16, 1, 1, scene_capture_type),
242
243 0xa407 =>
244 (ExifTag::GainControl, "none",
245 IfdFormat::U16, 1, 1, gain_control),
246
247 0xa408 =>
248 (ExifTag::Contrast, "none",
249 IfdFormat::U16, 1, 1, contrast),
250
251 0xa409 =>
252 (ExifTag::Saturation, "none",
253 IfdFormat::U16, 1, 1, saturation),
254
255 0xa40a =>
256 (ExifTag::Sharpness, "none",
257 IfdFormat::U16, 1, 1, sharpness),
258
259 0xa432 =>
260 (ExifTag::LensSpecification, "none",
261 IfdFormat::URational, 4, 4, lens_spec),
262
263 0xa433 =>
264 (ExifTag::LensMake, "none",
265 IfdFormat::Ascii, -1i32, -1i32, strpass),
266
267 0xa434 =>
268 (ExifTag::LensModel, "none",
269 IfdFormat::Ascii, -1i32, -1i32, strpass),
270
271 0xa500 =>
272 (ExifTag::Gamma, "none",
273 IfdFormat::URational, 1, 1, rational_value),
274
275 // collaborate if you have any idea how to interpret this
276 0xa40b =>
277 (ExifTag::DeviceSettingDescription, "none",
278 IfdFormat::Undefined, -1i32, -1i32, undefined_as_blob),
279
280 0xa40c =>
281 (ExifTag::SubjectDistanceRange, "none",
282 IfdFormat::U16, 1, 1, subject_distance_range),
283
284 0xa420 =>
285 (ExifTag::ImageUniqueID, "none",
286 IfdFormat::Ascii, -1i32, -1i32, strpass),
287
288 0x0 =>
289 (ExifTag::GPSVersionID, "none",
290 IfdFormat::U8, 4, 4, strpass),
291
292 0x1 =>
293 (ExifTag::GPSLatitudeRef, "none",
294 IfdFormat::Ascii, -1i32, -1i32, strpass),
295
296 0x2 =>
297 (ExifTag::GPSLatitude, "D/M/S",
298 IfdFormat::URational, 3, 3, dms),
299
300 0x3 =>
301 (ExifTag::GPSLongitudeRef, "none",
302 IfdFormat::Ascii, -1i32, -1i32, strpass),
303
304 0x4 =>
305 (ExifTag::GPSLongitude, "D/M/S",
306 IfdFormat::URational, 3, 3, dms),
307
308 0x5 =>
309 (ExifTag::GPSAltitudeRef, "none",
310 IfdFormat::U8, 1, 1, gps_alt_ref),
311
312 0x6 =>
313 (ExifTag::GPSAltitude, "m",
314 IfdFormat::URational, 1, 1, meters),
315
316 0x7 =>
317 (ExifTag::GPSTimeStamp, "UTC time",
318 IfdFormat::URational, 3, 3, gpstimestamp),
319
320 0x8 => (ExifTag::GPSSatellites, "none",
321 IfdFormat::Ascii, -1i32, -1i32, strpass),
322
323 0x9 => (ExifTag::GPSStatus, "none",
324 IfdFormat::Ascii, -1i32, -1i32, gpsstatus),
325
326 0xa => (ExifTag::GPSMeasureMode, "none",
327 IfdFormat::Ascii, -1i32, -1i32, gpsmeasuremode),
328
329 0xb =>
330 (ExifTag::GPSDOP, "none",
331 IfdFormat::URational, 1, 1, rational_value),
332
333 0xc =>
334 (ExifTag::GPSSpeedRef, "none",
335 IfdFormat::Ascii, -1i32, -1i32, gpsspeedref),
336
337 0xd =>
338 (ExifTag::GPSSpeed, "@GPSSpeedRef",
339 IfdFormat::URational, 1, 1, gpsspeed),
340
341 0xe =>
342 (ExifTag::GPSTrackRef, "none",
343 IfdFormat::Ascii, -1i32, -1i32, gpsbearingref),
344
345 0xf =>
346 (ExifTag::GPSTrack, "deg",
347 IfdFormat::URational, 1, 1, gpsbearing),
348
349 0x10 =>
350 (ExifTag::GPSImgDirectionRef, "none",
351 IfdFormat::Ascii, -1i32, -1i32, gpsbearingref),
352
353 0x11 =>
354 (ExifTag::GPSImgDirection, "deg",
355 IfdFormat::URational, 1, 1, gpsbearing),
356
357 0x12 =>
358 (ExifTag::GPSMapDatum, "none",
359 IfdFormat::Ascii, -1i32, -1i32, strpass),
360
361 0x13 =>
362 (ExifTag::GPSDestLatitudeRef, "none",
363 IfdFormat::Ascii, -1i32, -1i32, strpass),
364
365 0x14 =>
366 (ExifTag::GPSDestLatitude, "D/M/S",
367 IfdFormat::URational, 3, 3, dms),
368
369 0x15 =>
370 (ExifTag::GPSDestLongitudeRef, "none",
371 IfdFormat::Ascii, -1i32, -1i32, strpass),
372
373 0x16 =>
374 (ExifTag::GPSDestLongitude, "D/M/S",
375 IfdFormat::URational, 3, 3, dms),
376
377 0x17 =>
378 (ExifTag::GPSDestBearingRef, "none",
379 IfdFormat::Ascii, -1i32, -1i32, gpsbearingref),
380
381 0x18 =>
382 (ExifTag::GPSDestBearing, "deg",
383 IfdFormat::URational, 1, 1, gpsbearing),
384
385 0x19 =>
386 (ExifTag::GPSDestDistanceRef, "none",
387 IfdFormat::Ascii, -1i32, -1i32, gpsdestdistanceref),
388
389 0x1a =>
390 (ExifTag::GPSDestDistance, "@GPSDestDistanceRef",
391 IfdFormat::URational, 1, 1, gpsdestdistance),
392
393 0x1b =>
394 (ExifTag::GPSProcessingMethod, "none",
395 IfdFormat::Undefined, -1i32, -1i32, undefined_as_encoded_string),
396
397 0x1c => (ExifTag::GPSAreaInformation,
398 "none", IfdFormat::Undefined, -1i32, -1i32, undefined_as_encoded_string),
399
400 0x1d =>
401 (ExifTag::GPSDateStamp, "none",
402 IfdFormat::Ascii, -1i32, -1i32, strpass),
403
404 0x1e =>
405 (ExifTag::GPSDifferential, "none",
406 IfdFormat::U16, 1, 1, gpsdiff),
407
408 _ =>
409 (ExifTag::UnknownToMe, "Unknown unit",
410 IfdFormat::Unknown, -1i32, -1i32, nop)
411 }
412 }
413