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