89 0x0008: ('h', 'Signed Short', None ), |
91 0x0008: ('h', 'Signed Short', None ), |
90 0x0009: ('l', 'Signed Long', None ), |
92 0x0009: ('l', 'Signed Long', None ), |
91 0x000A: ('ll', 'Signed Ratio', filter_ratio ), |
93 0x000A: ('ll', 'Signed Ratio', filter_ratio ), |
92 } |
94 } |
93 |
95 |
94 def map_value (spec, value) : |
96 def map_values (spec, values) : |
95 """ |
97 """ |
96 Map the given tag value to a printable string using the given value spec. |
98 Map the given tag value to a printable string using the given value spec. |
97 """ |
99 """ |
|
100 |
|
101 # XXX: ensure that this always returns a str/unicode |
98 |
102 |
99 if callable(spec): |
103 if spec is None : |
|
104 # nothing to map |
|
105 return ", ".join(str(value) for value in values) |
|
106 |
|
107 elif callable(spec): |
100 # call mapping function |
108 # call mapping function |
101 return spec(value) |
109 return spec(values) |
102 |
110 |
103 else: |
111 elif isinstance(spec, dict) : |
104 return spec.get(value, repr(value)) |
112 # lookup value, default to repr |
105 |
113 return ", ".join(spec.get(value, repr(value)) for value in values) |
106 |
114 |
107 def make_string (seq): |
115 else : |
108 """ |
116 # unknown kind of spec |
109 Filter a string to strip out non-printing chars |
117 raise ValueError(spec) |
110 """ |
118 |
|
119 USER_COMMENT_CHARSETS = { |
|
120 'ASCII': ('ascii', 'replace' ), |
|
121 'JIS': ('jis', 'error' ), |
|
122 |
|
123 # XXX: WTF? What kind of charset is 'Unicode' supposed to be? |
|
124 # UTF-16? Little-endian? Big-endian? |
|
125 # Confusing reigns: http://www.cpanforum.com/threads/7329 |
|
126 'UNICODE': ('utf16', 'error' ), |
|
127 } |
|
128 |
|
129 |
|
130 def decode_UserComment (values) : |
|
131 """ |
|
132 A UserComment field starts with an eight-byte encoding designator. |
|
133 """ |
|
134 |
|
135 # single binary string |
|
136 value, = values |
111 |
137 |
112 # screen out non-printing characters |
138 # split up |
113 str = ''.join(c for c in seq if 32 <= c < 256) |
139 charset, comment_raw = value[:8], value[8:] |
114 |
140 |
115 if not str: |
141 # strip NILs |
116 # no printing chars |
142 charset = charset.rstrip('\x00') |
117 return seq |
143 |
118 |
144 # map |
119 else : |
145 encoding, replace = USER_COMMENT_CHARSETS.get(charset, ('ascii', 'replace')) |
120 return str |
146 |
121 |
147 # decode |
122 def make_string_uc (seq) : |
148 return [comment_raw.decode(encoding, replace)] |
123 """ |
149 |
124 # Special version to deal with the code in the first 8 bytes of a user comment. |
150 # Mappings of Exif tag codes to name and decoding information. |
125 # First 8 bytes gives coding system e.g. ASCII vs. JIS vs Unicode |
151 # { tag : (name, value_dict/value_func/None) } |
126 |
152 # |
127 XXX: decode? |
153 # name is the official Exif tag name |
128 """ |
154 # value_dict is a { value: value_name } mapping for human-readable values |
129 |
155 # value_func is a `(values) -> values` mapping function which *overrides* the tag's type_func. |
130 code = seq[0:8] |
156 # XXX: or does it? |
131 seq = seq[8:] |
157 # otherwise, the value is left as-is. |
132 |
|
133 ## Of course, this is only correct if ASCII, and the standard explicitly |
|
134 ## allows JIS and Unicode. |
|
135 return make_string(seq) |
|
136 |
|
137 |
|
138 # dictionary of main EXIF tag names |
|
139 # first element of tuple is tag name, optional second element is |
|
140 # another dictionary giving names to values |
|
141 # { tag_type : (name, spec?) } |
|
142 EXIF_TAGS = { |
158 EXIF_TAGS = { |
143 0x0100: ('ImageWidth', ), |
159 0x0100: ('ImageWidth', None), |
144 0x0101: ('ImageLength', ), |
160 0x0101: ('ImageLength', None), |
145 0x0102: ('BitsPerSample', ), |
161 0x0102: ('BitsPerSample', None), |
146 0x0103: ('Compression', |
162 0x0103: ('Compression', |
147 {1: 'Uncompressed', |
163 {1: 'Uncompressed', |
148 2: 'CCITT 1D', |
164 2: 'CCITT 1D', |
149 3: 'T4/Group 3 Fax', |
165 3: 'T4/Group 3 Fax', |
150 4: 'T6/Group 4 Fax', |
166 4: 'T6/Group 4 Fax', |
172 34677: 'SGILog24', |
188 34677: 'SGILog24', |
173 34712: 'JPEG 2000', |
189 34712: 'JPEG 2000', |
174 34713: 'Nikon NEF Compressed', |
190 34713: 'Nikon NEF Compressed', |
175 65000: 'Kodak DCR Compressed', |
191 65000: 'Kodak DCR Compressed', |
176 65535: 'Pentax PEF Compressed'}), |
192 65535: 'Pentax PEF Compressed'}), |
177 0x0106: ('PhotometricInterpretation', ), |
193 0x0106: ('PhotometricInterpretation', None), |
178 0x0107: ('Thresholding', ), |
194 0x0107: ('Thresholding', None), |
179 0x010A: ('FillOrder', ), |
195 0x010A: ('FillOrder', None), |
180 0x010D: ('DocumentName', ), |
196 0x010D: ('DocumentName', None), |
181 0x010E: ('ImageDescription', ), |
197 0x010E: ('ImageDescription', None), |
182 0x010F: ('Make', ), |
198 0x010F: ('Make', None), |
183 0x0110: ('Model', ), |
199 0x0110: ('Model', None), |
184 0x0111: ('StripOffsets', ), |
200 0x0111: ('StripOffsets', None), |
185 0x0112: ('Orientation', |
201 0x0112: ('Orientation', |
186 {1: 'Horizontal (normal)', |
202 {1: 'Horizontal (normal)', |
187 2: 'Mirrored horizontal', |
203 2: 'Mirrored horizontal', |
188 3: 'Rotated 180', |
204 3: 'Rotated 180', |
189 4: 'Mirrored vertical', |
205 4: 'Mirrored vertical', |
190 5: 'Mirrored horizontal then rotated 90 CCW', |
206 5: 'Mirrored horizontal then rotated 90 CCW', |
191 6: 'Rotated 90 CW', |
207 6: 'Rotated 90 CW', |
192 7: 'Mirrored horizontal then rotated 90 CW', |
208 7: 'Mirrored horizontal then rotated 90 CW', |
193 8: 'Rotated 90 CCW'}), |
209 8: 'Rotated 90 CCW'}), |
194 0x0115: ('SamplesPerPixel', ), |
210 0x0115: ('SamplesPerPixel', None), |
195 0x0116: ('RowsPerStrip', ), |
211 0x0116: ('RowsPerStrip', None), |
196 0x0117: ('StripByteCounts', ), |
212 0x0117: ('StripByteCounts', None), |
197 0x011A: ('XResolution', ), |
213 0x011A: ('XResolution', None), |
198 0x011B: ('YResolution', ), |
214 0x011B: ('YResolution', None), |
199 0x011C: ('PlanarConfiguration', ), |
215 0x011C: ('PlanarConfiguration', None), |
200 0x011D: ('PageName', make_string), |
216 0x011D: ('PageName', None), |
201 0x0128: ('ResolutionUnit', |
217 0x0128: ('ResolutionUnit', |
202 {1: 'Not Absolute', |
218 {1: 'Not Absolute', |
203 2: 'Pixels/Inch', |
219 2: 'Pixels/Inch', |
204 3: 'Pixels/Centimeter'}), |
220 3: 'Pixels/Centimeter'}), |
205 0x012D: ('TransferFunction', ), |
221 0x012D: ('TransferFunction', None), |
206 0x0131: ('Software', ), |
222 0x0131: ('Software', None), |
207 0x0132: ('DateTime', ), |
223 0x0132: ('DateTime', None), |
208 0x013B: ('Artist', ), |
224 0x013B: ('Artist', None), |
209 0x013E: ('WhitePoint', ), |
225 0x013E: ('WhitePoint', None), |
210 0x013F: ('PrimaryChromaticities', ), |
226 0x013F: ('PrimaryChromaticities', None), |
211 0x0156: ('TransferRange', ), |
227 0x0156: ('TransferRange', None), |
212 0x0200: ('JPEGProc', ), |
228 0x0200: ('JPEGProc', None), |
213 0x0201: ('JPEGInterchangeFormat', ), |
229 0x0201: ('JPEGInterchangeFormat', None), |
214 0x0202: ('JPEGInterchangeFormatLength', ), |
230 0x0202: ('JPEGInterchangeFormatLength', None), |
215 0x0211: ('YCbCrCoefficients', ), |
231 0x0211: ('YCbCrCoefficients', None), |
216 0x0212: ('YCbCrSubSampling', ), |
232 0x0212: ('YCbCrSubSampling', None), |
217 0x0213: ('YCbCrPositioning', |
233 0x0213: ('YCbCrPositioning', |
218 {1: 'Centered', |
234 {1: 'Centered', |
219 2: 'Co-sited'}), |
235 2: 'Co-sited'}), |
220 0x0214: ('ReferenceBlackWhite', ), |
236 0x0214: ('ReferenceBlackWhite', None), |
221 |
237 |
222 0x4746: ('Rating', ), |
238 0x4746: ('Rating', None), |
223 |
239 |
224 0x828D: ('CFARepeatPatternDim', ), |
240 0x828D: ('CFARepeatPatternDim', None), |
225 0x828E: ('CFAPattern', ), |
241 0x828E: ('CFAPattern', None), |
226 0x828F: ('BatteryLevel', ), |
242 0x828F: ('BatteryLevel', None), |
227 0x8298: ('Copyright', ), |
243 0x8298: ('Copyright', None), |
228 0x829A: ('ExposureTime', ), |
244 0x829A: ('ExposureTime', None), |
229 0x829D: ('FNumber', ), |
245 0x829D: ('FNumber', None), |
230 0x83BB: ('IPTC/NAA', ), |
246 0x83BB: ('IPTC/NAA', None), |
231 0x8769: ('ExifOffset', ), |
247 0x8769: ('ExifOffset', None), |
232 0x8773: ('InterColorProfile', ), |
248 0x8773: ('InterColorProfile', None), |
233 0x8822: ('ExposureProgram', |
249 0x8822: ('ExposureProgram', |
234 {0: 'Unidentified', |
250 {0: 'Unidentified', |
235 1: 'Manual', |
251 1: 'Manual', |
236 2: 'Program Normal', |
252 2: 'Program Normal', |
237 3: 'Aperture Priority', |
253 3: 'Aperture Priority', |
238 4: 'Shutter Priority', |
254 4: 'Shutter Priority', |
239 5: 'Program Creative', |
255 5: 'Program Creative', |
240 6: 'Program Action', |
256 6: 'Program Action', |
241 7: 'Portrait Mode', |
257 7: 'Portrait Mode', |
242 8: 'Landscape Mode'}), |
258 8: 'Landscape Mode'}), |
243 0x8824: ('SpectralSensitivity', ), |
259 0x8824: ('SpectralSensitivity', None), |
244 0x8825: ('GPSInfo', ), |
260 0x8825: ('GPSInfo', None), |
245 0x8827: ('ISOSpeedRatings', ), |
261 0x8827: ('ISOSpeedRatings', None), |
246 0x8828: ('OECF', ), |
262 0x8828: ('OECF', None), |
247 0x9000: ('ExifVersion', make_string), |
263 0x9000: ('ExifVersion', None), |
248 0x9003: ('DateTimeOriginal', ), |
264 0x9003: ('DateTimeOriginal', None), |
249 0x9004: ('DateTimeDigitized', ), |
265 0x9004: ('DateTimeDigitized', None), |
250 0x9101: ('ComponentsConfiguration', |
266 0x9101: ('ComponentsConfiguration', |
251 {0: '', |
267 {0: '', |
252 1: 'Y', |
268 1: 'Y', |
253 2: 'Cb', |
269 2: 'Cb', |
254 3: 'Cr', |
270 3: 'Cr', |
255 4: 'Red', |
271 4: 'Red', |
256 5: 'Green', |
272 5: 'Green', |
257 6: 'Blue'}), |
273 6: 'Blue'}), |
258 0x9102: ('CompressedBitsPerPixel', ), |
274 0x9102: ('CompressedBitsPerPixel', None), |
259 0x9201: ('ShutterSpeedValue', ), |
275 0x9201: ('ShutterSpeedValue', None), |
260 0x9202: ('ApertureValue', ), |
276 0x9202: ('ApertureValue', None), |
261 0x9203: ('BrightnessValue', ), |
277 0x9203: ('BrightnessValue', None), |
262 0x9204: ('ExposureBiasValue', ), |
278 0x9204: ('ExposureBiasValue', None), |
263 0x9205: ('MaxApertureValue', ), |
279 0x9205: ('MaxApertureValue', None), |
264 0x9206: ('SubjectDistance', ), |
280 0x9206: ('SubjectDistance', None), |
265 0x9207: ('MeteringMode', |
281 0x9207: ('MeteringMode', |
266 {0: 'Unidentified', |
282 {0: 'Unidentified', |
267 1: 'Average', |
283 1: 'Average', |
268 2: 'CenterWeightedAverage', |
284 2: 'CenterWeightedAverage', |
269 3: 'Spot', |
285 3: 'Spot', |
300 24: 'Auto Off', |
316 24: 'Auto Off', |
301 25: 'Auto Fired', |
317 25: 'Auto Fired', |
302 29: 'Auto Fired (?)', |
318 29: 'Auto Fired (?)', |
303 31: 'Auto Fired (!)', |
319 31: 'Auto Fired (!)', |
304 32: 'Not Available'}), |
320 32: 'Not Available'}), |
305 0x920A: ('FocalLength', ), |
321 0x920A: ('FocalLength', None), |
306 0x9214: ('SubjectArea', ), |
322 0x9214: ('SubjectArea', None), |
307 0x927C: ('MakerNote', ), |
323 0x927C: ('MakerNote', None), |
308 0x9286: ('UserComment', make_string_uc), |
324 0x9286: ('UserComment', decode_UserComment), |
309 0x9290: ('SubSecTime', ), |
325 0x9290: ('SubSecTime', None), |
310 0x9291: ('SubSecTimeOriginal', ), |
326 0x9291: ('SubSecTimeOriginal', None), |
311 0x9292: ('SubSecTimeDigitized', ), |
327 0x9292: ('SubSecTimeDigitized', None), |
312 |
328 |
313 # used by Windows Explorer |
329 # used by Windows Explorer |
314 0x9C9B: ('XPTitle', ), |
330 0x9C9B: ('XPTitle', None), |
315 0x9C9C: ('XPComment', ), |
331 0x9C9C: ('XPComment', None), |
316 0x9C9D: ('XPAuthor', ), #(ignored by Windows Explorer if Artist exists) |
332 0x9C9D: ('XPAuthor', None), #(ignored by Windows Explorer if Artist exists) |
317 0x9C9E: ('XPKeywords', ), |
333 0x9C9E: ('XPKeywords', None), |
318 0x9C9F: ('XPSubject', ), |
334 0x9C9F: ('XPSubject', None), |
319 |
335 |
320 0xA000: ('FlashPixVersion', make_string), |
336 0xA000: ('FlashPixVersion', None), |
321 0xA001: ('ColorSpace', |
337 0xA001: ('ColorSpace', |
322 {1: 'sRGB', |
338 {1: 'sRGB', |
323 2: 'Adobe RGB', |
339 2: 'Adobe RGB', |
324 65535: 'Uncalibrated'}), |
340 65535: 'Uncalibrated'}), |
325 0xA002: ('ExifImageWidth', ), |
341 0xA002: ('ExifImageWidth', None), |
326 0xA003: ('ExifImageLength', ), |
342 0xA003: ('ExifImageLength', None), |
327 0xA005: ('InteroperabilityOffset', ), |
343 0xA005: ('InteroperabilityOffset', None), |
328 0xA20B: ('FlashEnergy', ), # 0x920B in TIFF/EP |
344 0xA20B: ('FlashEnergy', None), # 0x920B in TIFF/EP |
329 0xA20C: ('SpatialFrequencyResponse', ), # 0x920C |
345 0xA20C: ('SpatialFrequencyResponse', None), # 0x920C |
330 0xA20E: ('FocalPlaneXResolution', ), # 0x920E |
346 0xA20E: ('FocalPlaneXResolution', None), # 0x920E |
331 0xA20F: ('FocalPlaneYResolution', ), # 0x920F |
347 0xA20F: ('FocalPlaneYResolution', None), # 0x920F |
332 0xA210: ('FocalPlaneResolutionUnit', ), # 0x9210 |
348 0xA210: ('FocalPlaneResolutionUnit', None), # 0x9210 |
333 0xA214: ('SubjectLocation', ), # 0x9214 |
349 0xA214: ('SubjectLocation', None), # 0x9214 |
334 0xA215: ('ExposureIndex', ), # 0x9215 |
350 0xA215: ('ExposureIndex', None), # 0x9215 |
335 0xA217: ('SensingMethod', # 0x9217 |
351 0xA217: ('SensingMethod', # 0x9217 |
336 {1: 'Not defined', |
352 {1: 'Not defined', |
337 2: 'One-chip color area', |
353 2: 'One-chip color area', |
338 3: 'Two-chip color area', |
354 3: 'Two-chip color area', |
339 4: 'Three-chip color area', |
355 4: 'Three-chip color area', |
380 2: 'Hard'}), |
396 2: 'Hard'}), |
381 0xA40A: ('Sharpness', |
397 0xA40A: ('Sharpness', |
382 {0: 'Normal', |
398 {0: 'Normal', |
383 1: 'Soft', |
399 1: 'Soft', |
384 2: 'Hard'}), |
400 2: 'Hard'}), |
385 0xA40B: ('DeviceSettingDescription', ), |
401 0xA40B: ('DeviceSettingDescription', None), |
386 0xA40C: ('SubjectDistanceRange', ), |
402 0xA40C: ('SubjectDistanceRange', None), |
387 0xA500: ('Gamma', ), |
403 0xA500: ('Gamma', None), |
388 0xC4A5: ('PrintIM', ), |
404 0xC4A5: ('PrintIM', None), |
389 0xEA1C: ('Padding', ), |
405 0xEA1C: ('Padding', None), |
390 } |
406 } |
391 |
407 |
392 # interoperability tags |
408 # interoperability tags |
393 INTR_TAGS = { |
409 INTR_TAGS = { |
394 0x0001: ('InteroperabilityIndex', ), |
410 0x0001: ('InteroperabilityIndex', None), |
395 0x0002: ('InteroperabilityVersion', ), |
411 0x0002: ('InteroperabilityVersion', None), |
396 0x1000: ('RelatedImageFileFormat', ), |
412 0x1000: ('RelatedImageFileFormat', None), |
397 0x1001: ('RelatedImageWidth', ), |
413 0x1001: ('RelatedImageWidth', None), |
398 0x1002: ('RelatedImageLength', ), |
414 0x1002: ('RelatedImageLength', None), |
399 } |
415 } |
400 |
416 |
401 # GPS tags (not used yet, haven't seen camera with GPS) |
417 # GPS tags (not used yet, haven't seen camera with GPS) |
402 GPS_TAGS = { |
418 GPS_TAGS = { |
403 0x0000: ('GPSVersionID', ), |
419 0x0000: ('GPSVersionID', None), |
404 0x0001: ('GPSLatitudeRef', ), |
420 0x0001: ('GPSLatitudeRef', None), |
405 0x0002: ('GPSLatitude', ), |
421 0x0002: ('GPSLatitude', None), |
406 0x0003: ('GPSLongitudeRef', ), |
422 0x0003: ('GPSLongitudeRef', None), |
407 0x0004: ('GPSLongitude', ), |
423 0x0004: ('GPSLongitude', None), |
408 0x0005: ('GPSAltitudeRef', ), |
424 0x0005: ('GPSAltitudeRef', None), |
409 0x0006: ('GPSAltitude', ), |
425 0x0006: ('GPSAltitude', None), |
410 0x0007: ('GPSTimeStamp', ), |
426 0x0007: ('GPSTimeStamp', None), |
411 0x0008: ('GPSSatellites', ), |
427 0x0008: ('GPSSatellites', None), |
412 0x0009: ('GPSStatus', ), |
428 0x0009: ('GPSStatus', None), |
413 0x000A: ('GPSMeasureMode', ), |
429 0x000A: ('GPSMeasureMode', None), |
414 0x000B: ('GPSDOP', ), |
430 0x000B: ('GPSDOP', None), |
415 0x000C: ('GPSSpeedRef', ), |
431 0x000C: ('GPSSpeedRef', None), |
416 0x000D: ('GPSSpeed', ), |
432 0x000D: ('GPSSpeed', None), |
417 0x000E: ('GPSTrackRef', ), |
433 0x000E: ('GPSTrackRef', None), |
418 0x000F: ('GPSTrack', ), |
434 0x000F: ('GPSTrack', None), |
419 0x0010: ('GPSImgDirectionRef', ), |
435 0x0010: ('GPSImgDirectionRef', None), |
420 0x0011: ('GPSImgDirection', ), |
436 0x0011: ('GPSImgDirection', None), |
421 0x0012: ('GPSMapDatum', ), |
437 0x0012: ('GPSMapDatum', None), |
422 0x0013: ('GPSDestLatitudeRef', ), |
438 0x0013: ('GPSDestLatitudeRef', None), |
423 0x0014: ('GPSDestLatitude', ), |
439 0x0014: ('GPSDestLatitude', None), |
424 0x0015: ('GPSDestLongitudeRef', ), |
440 0x0015: ('GPSDestLongitudeRef', None), |
425 0x0016: ('GPSDestLongitude', ), |
441 0x0016: ('GPSDestLongitude', None), |
426 0x0017: ('GPSDestBearingRef', ), |
442 0x0017: ('GPSDestBearingRef', None), |
427 0x0018: ('GPSDestBearing', ), |
443 0x0018: ('GPSDestBearing', None), |
428 0x0019: ('GPSDestDistanceRef', ), |
444 0x0019: ('GPSDestDistanceRef', None), |
429 0x001A: ('GPSDestDistance', ), |
445 0x001A: ('GPSDestDistance', None), |
430 0x001D: ('GPSDate', ), |
446 0x001D: ('GPSDate', None), |
431 } |
447 } |
432 |
|
433 # Ignore these tags when quick processing |
|
434 # 0x927C is MakerNote Tags |
|
435 # 0x9286 is user comment |
|
436 IGNORE_TAGS=(0x9286, 0x927C) |
|
437 |
448 |
438 # http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp |
449 # http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp |
439 def nikon_ev_bias(seq): |
450 def nikon_ev_bias (seq) : |
440 # First digit seems to be in steps of 1/6 EV. |
451 """ |
441 # Does the third value mean the step size? It is usually 6, |
452 # First digit seems to be in steps of 1/6 EV. |
442 # but it is 12 for the ExposureDifference. |
453 # Does the third value mean the step size? It is usually 6, |
443 # |
454 # but it is 12 for the ExposureDifference. |
444 # Check for an error condition that could cause a crash. |
455 """ |
445 # This only happens if something has gone really wrong in |
456 |
|
457 # check for an error condition that could cause a crash. |
|
458 # this only happens if something has gone really wrong in |
446 # reading the Nikon MakerNote. |
459 # reading the Nikon MakerNote. |
447 if len( seq ) < 4 : return "" |
460 if len(seq) < 4 : |
448 # |
461 return "" |
|
462 |
449 if seq == [252, 1, 6, 0]: |
463 if seq == [252, 1, 6, 0]: |
450 return "-2/3 EV" |
464 return "-2/3 EV" |
|
465 |
451 if seq == [253, 1, 6, 0]: |
466 if seq == [253, 1, 6, 0]: |
452 return "-1/2 EV" |
467 return "-1/2 EV" |
|
468 |
453 if seq == [254, 1, 6, 0]: |
469 if seq == [254, 1, 6, 0]: |
454 return "-1/3 EV" |
470 return "-1/3 EV" |
|
471 |
455 if seq == [0, 1, 6, 0]: |
472 if seq == [0, 1, 6, 0]: |
456 return "0 EV" |
473 return "0 EV" |
|
474 |
457 if seq == [2, 1, 6, 0]: |
475 if seq == [2, 1, 6, 0]: |
458 return "+1/3 EV" |
476 return "+1/3 EV" |
|
477 |
459 if seq == [3, 1, 6, 0]: |
478 if seq == [3, 1, 6, 0]: |
460 return "+1/2 EV" |
479 return "+1/2 EV" |
|
480 |
461 if seq == [4, 1, 6, 0]: |
481 if seq == [4, 1, 6, 0]: |
462 return "+2/3 EV" |
482 return "+2/3 EV" |
463 # Handle combinations not in the table. |
483 |
|
484 # handle combinations not in the table. |
464 a = seq[0] |
485 a = seq[0] |
465 # Causes headaches for the +/- logic, so special case it. |
486 |
|
487 # causes headaches for the +/- logic, so special case it. |
466 if a == 0: |
488 if a == 0: |
467 return "0 EV" |
489 return "0 EV" |
|
490 |
468 if a > 127: |
491 if a > 127: |
469 a = 256 - a |
492 a = 256 - a |
470 ret_str = "-" |
493 ret_str = "-" |
471 else: |
494 else: |
472 ret_str = "+" |
495 ret_str = "+" |
473 b = seq[2] # Assume third value means the step size |
496 |
|
497 b = seq[2] # assume third value means the step size |
|
498 |
474 whole = a / b |
499 whole = a / b |
|
500 |
475 a = a % b |
501 a = a % b |
476 if whole != 0: |
502 |
|
503 if whole != 0 : |
477 ret_str = ret_str + str(whole) + " " |
504 ret_str = ret_str + str(whole) + " " |
478 if a == 0: |
505 |
|
506 if a == 0 : |
479 ret_str = ret_str + "EV" |
507 ret_str = ret_str + "EV" |
480 else: |
508 else : |
481 r = Ratio(a, b) |
509 r = Ratio(a, b) |
482 ret_str = ret_str + r.__repr__() + " EV" |
510 ret_str = ret_str + r.__repr__() + " EV" |
|
511 |
483 return ret_str |
512 return ret_str |
484 |
513 |
485 # Nikon E99x MakerNote Tags |
514 # Nikon E99x MakerNote Tags |
486 MAKERNOTE_NIKON_NEWER_TAGS={ |
515 MAKERNOTE_NIKON_NEWER_TAGS={ |
487 0x0001: ('MakernoteVersion', make_string), # Sometimes binary |
516 0x0001: ('MakernoteVersion', None), # Sometimes binary |
488 0x0002: ('ISOSetting', make_string), |
517 0x0002: ('ISOSetting', None), |
489 0x0003: ('ColorMode', ), |
518 0x0003: ('ColorMode', None), |
490 0x0004: ('Quality', ), |
519 0x0004: ('Quality', None), |
491 0x0005: ('Whitebalance', ), |
520 0x0005: ('Whitebalance', None), |
492 0x0006: ('ImageSharpening', ), |
521 0x0006: ('ImageSharpening', None), |
493 0x0007: ('FocusMode', ), |
522 0x0007: ('FocusMode', None), |
494 0x0008: ('FlashSetting', ), |
523 0x0008: ('FlashSetting', None), |
495 0x0009: ('AutoFlashMode', ), |
524 0x0009: ('AutoFlashMode', None), |
496 0x000B: ('WhiteBalanceBias', ), |
525 0x000B: ('WhiteBalanceBias', None), |
497 0x000C: ('WhiteBalanceRBCoeff', ), |
526 0x000C: ('WhiteBalanceRBCoeff', None), |
498 0x000D: ('ProgramShift', nikon_ev_bias), |
527 0x000D: ('ProgramShift', nikon_ev_bias), |
499 # Nearly the same as the other EV vals, but step size is 1/12 EV (?) |
528 # Nearly the same as the other EV vals, but step size is 1/12 EV (?) |
500 0x000E: ('ExposureDifference', nikon_ev_bias), |
529 0x000E: ('ExposureDifference', nikon_ev_bias), |
501 0x000F: ('ISOSelection', ), |
530 0x000F: ('ISOSelection', None), |
502 0x0011: ('NikonPreview', ), |
531 0x0011: ('NikonPreview', None), |
503 0x0012: ('FlashCompensation', nikon_ev_bias), |
532 0x0012: ('FlashCompensation', nikon_ev_bias), |
504 0x0013: ('ISOSpeedRequested', ), |
533 0x0013: ('ISOSpeedRequested', None), |
505 0x0016: ('PhotoCornerCoordinates', ), |
534 0x0016: ('PhotoCornerCoordinates', None), |
506 # 0x0017: Unknown, but most likely an EV value |
535 # 0x0017: Unknown, but most likely an EV value |
507 0x0018: ('FlashBracketCompensationApplied', nikon_ev_bias), |
536 0x0018: ('FlashBracketCompensationApplied', nikon_ev_bias), |
508 0x0019: ('AEBracketCompensationApplied', ), |
537 0x0019: ('AEBracketCompensationApplied', None), |
509 0x001A: ('ImageProcessing', ), |
538 0x001A: ('ImageProcessing', None), |
510 0x001B: ('CropHiSpeed', ), |
539 0x001B: ('CropHiSpeed', None), |
511 0x001D: ('SerialNumber', ), # Conflict with 0x00A0 ? |
540 0x001D: ('SerialNumber', None), # Conflict with 0x00A0 ? |
512 0x001E: ('ColorSpace', ), |
541 0x001E: ('ColorSpace', None), |
513 0x001F: ('VRInfo', ), |
542 0x001F: ('VRInfo', None), |
514 0x0020: ('ImageAuthentication', ), |
543 0x0020: ('ImageAuthentication', None), |
515 0x0022: ('ActiveDLighting', ), |
544 0x0022: ('ActiveDLighting', None), |
516 0x0023: ('PictureControl', ), |
545 0x0023: ('PictureControl', None), |
517 0x0024: ('WorldTime', ), |
546 0x0024: ('WorldTime', None), |
518 0x0025: ('ISOInfo', ), |
547 0x0025: ('ISOInfo', None), |
519 0x0080: ('ImageAdjustment', ), |
548 0x0080: ('ImageAdjustment', None), |
520 0x0081: ('ToneCompensation', ), |
549 0x0081: ('ToneCompensation', None), |
521 0x0082: ('AuxiliaryLens', ), |
550 0x0082: ('AuxiliaryLens', None), |
522 0x0083: ('LensType', ), |
551 0x0083: ('LensType', None), |
523 0x0084: ('LensMinMaxFocalMaxAperture', ), |
552 0x0084: ('LensMinMaxFocalMaxAperture', None), |
524 0x0085: ('ManualFocusDistance', ), |
553 0x0085: ('ManualFocusDistance', None), |
525 0x0086: ('DigitalZoomFactor', ), |
554 0x0086: ('DigitalZoomFactor', None), |
526 0x0087: ('FlashMode', |
555 0x0087: ('FlashMode', |
527 {0x00: 'Did Not Fire', |
556 {0x00: 'Did Not Fire', |
528 0x01: 'Fired, Manual', |
557 0x01: 'Fired, Manual', |
529 0x07: 'Fired, External', |
558 0x07: 'Fired, External', |
530 0x08: 'Fired, Commander Mode ', |
559 0x08: 'Fired, Commander Mode ', |
543 0x11: 'Continuous, exposure bracketing', |
572 0x11: 'Continuous, exposure bracketing', |
544 0x12: 'Timer, exposure bracketing', |
573 0x12: 'Timer, exposure bracketing', |
545 0x40: 'Single frame, white balance bracketing', |
574 0x40: 'Single frame, white balance bracketing', |
546 0x41: 'Continuous, white balance bracketing', |
575 0x41: 'Continuous, white balance bracketing', |
547 0x42: 'Timer, white balance bracketing'}), |
576 0x42: 'Timer, white balance bracketing'}), |
548 0x008A: ('AutoBracketRelease', ), |
577 0x008A: ('AutoBracketRelease', None), |
549 0x008B: ('LensFStops', ), |
578 0x008B: ('LensFStops', None), |
550 0x008C: ('NEFCurve1', ), # ExifTool calls this 'ContrastCurve' |
579 0x008C: ('NEFCurve1', None), # ExifTool calls this 'ContrastCurve' |
551 0x008D: ('ColorMode', ), |
580 0x008D: ('ColorMode', None), |
552 0x008F: ('SceneMode', ), |
581 0x008F: ('SceneMode', None), |
553 0x0090: ('LightingType', ), |
582 0x0090: ('LightingType', None), |
554 0x0091: ('ShotInfo', ), # First 4 bytes are a version number in ASCII |
583 0x0091: ('ShotInfo', None), # First 4 bytes are a version number in ASCII |
555 0x0092: ('HueAdjustment', ), |
584 0x0092: ('HueAdjustment', None), |
556 # ExifTool calls this 'NEFCompression', should be 1-4 |
585 # ExifTool calls this 'NEFCompression', should be 1-4 |
557 0x0093: ('Compression', ), |
586 0x0093: ('Compression', None), |
558 0x0094: ('Saturation', |
587 0x0094: ('Saturation', |
559 {-3: 'B&W', |
588 {-3: 'B&W', |
560 -2: '-2', |
589 -2: '-2', |
561 -1: '-1', |
590 -1: '-1', |
562 0: '0', |
591 0: '0', |
563 1: '1', |
592 1: '1', |
564 2: '2'}), |
593 2: '2'}), |
565 0x0095: ('NoiseReduction', ), |
594 0x0095: ('NoiseReduction', None), |
566 0x0096: ('NEFCurve2', ), # ExifTool calls this 'LinearizationTable' |
595 0x0096: ('NEFCurve2', None), # ExifTool calls this 'LinearizationTable' |
567 0x0097: ('ColorBalance', ), # First 4 bytes are a version number in ASCII |
596 0x0097: ('ColorBalance', None), # First 4 bytes are a version number in ASCII |
568 0x0098: ('LensData', ), # First 4 bytes are a version number in ASCII |
597 0x0098: ('LensData', None), # First 4 bytes are a version number in ASCII |
569 0x0099: ('RawImageCenter', ), |
598 0x0099: ('RawImageCenter', None), |
570 0x009A: ('SensorPixelSize', ), |
599 0x009A: ('SensorPixelSize', None), |
571 0x009C: ('Scene Assist', ), |
600 0x009C: ('Scene Assist', None), |
572 0x009E: ('RetouchHistory', ), |
601 0x009E: ('RetouchHistory', None), |
573 0x00A0: ('SerialNumber', ), |
602 0x00A0: ('SerialNumber', None), |
574 0x00A2: ('ImageDataSize', ), |
603 0x00A2: ('ImageDataSize', None), |
575 # 00A3: unknown - a single byte 0 |
604 # 00A3: unknown - a single byte 0 |
576 # 00A4: In NEF, looks like a 4 byte ASCII version number ('0200') |
605 # 00A4: In NEF, looks like a 4 byte ASCII version number ('0200') |
577 0x00A5: ('ImageCount', ), |
606 0x00A5: ('ImageCount', None), |
578 0x00A6: ('DeletedImageCount', ), |
607 0x00A6: ('DeletedImageCount', None), |
579 0x00A7: ('TotalShutterReleases', ), |
608 0x00A7: ('TotalShutterReleases', None), |
580 # First 4 bytes are a version number in ASCII, with version specific |
609 # First 4 bytes are a version number in ASCII, with version specific |
581 # info to follow. Its hard to treat it as a string due to embedded nulls. |
610 # info to follow. Its hard to treat it as a string due to embedded nulls. |
582 0x00A8: ('FlashInfo', ), |
611 0x00A8: ('FlashInfo', None), |
583 0x00A9: ('ImageOptimization', ), |
612 0x00A9: ('ImageOptimization', None), |
584 0x00AA: ('Saturation', ), |
613 0x00AA: ('Saturation', None), |
585 0x00AB: ('DigitalVariProgram', ), |
614 0x00AB: ('DigitalVariProgram', None), |
586 0x00AC: ('ImageStabilization', ), |
615 0x00AC: ('ImageStabilization', None), |
587 0x00AD: ('Responsive AF', ), # 'AFResponse' |
616 0x00AD: ('Responsive AF', None), # 'AFResponse' |
588 0x00B0: ('MultiExposure', ), |
617 0x00B0: ('MultiExposure', None), |
589 0x00B1: ('HighISONoiseReduction', ), |
618 0x00B1: ('HighISONoiseReduction', None), |
590 0x00B7: ('AFInfo', ), |
619 0x00B7: ('AFInfo', None), |
591 0x00B8: ('FileInfo', ), |
620 0x00B8: ('FileInfo', None), |
592 # 00B9: unknown |
621 # 00B9: unknown |
593 0x0100: ('DigitalICE', ), |
622 0x0100: ('DigitalICE', None), |
594 0x0103: ('PreviewCompression', |
623 0x0103: ('PreviewCompression', |
595 {1: 'Uncompressed', |
624 {1: 'Uncompressed', |
596 2: 'CCITT 1D', |
625 2: 'CCITT 1D', |
597 3: 'T4/Group 3 Fax', |
626 3: 'T4/Group 3 Fax', |
598 4: 'T6/Group 4 Fax', |
627 4: 'T6/Group 4 Fax', |
693 1: 'Macro', |
730 1: 'Macro', |
694 2: 'SuperMacro'}), |
731 2: 'SuperMacro'}), |
695 0x0203: ('BWMode', |
732 0x0203: ('BWMode', |
696 {0: 'Off', |
733 {0: 'Off', |
697 1: 'On'}), |
734 1: 'On'}), |
698 0x0204: ('DigitalZoom', ), |
735 0x0204: ('DigitalZoom', None), |
699 0x0205: ('FocalPlaneDiagonal', ), |
736 0x0205: ('FocalPlaneDiagonal', None), |
700 0x0206: ('LensDistortionParams', ), |
737 0x0206: ('LensDistortionParams', None), |
701 0x0207: ('SoftwareRelease', ), |
738 0x0207: ('SoftwareRelease', None), |
702 0x0208: ('PictureInfo', ), |
739 0x0208: ('PictureInfo', None), |
703 0x0209: ('CameraID', make_string), # print as string |
740 0x0209: ('CameraID', None), # print as string |
704 0x0F00: ('DataDump', ), |
741 0x0F00: ('DataDump', None), |
705 0x0300: ('PreCaptureFrames', ), |
742 0x0300: ('PreCaptureFrames', None), |
706 0x0404: ('SerialNumber', ), |
743 0x0404: ('SerialNumber', None), |
707 0x1000: ('ShutterSpeedValue', ), |
744 0x1000: ('ShutterSpeedValue', None), |
708 0x1001: ('ISOValue', ), |
745 0x1001: ('ISOValue', None), |
709 0x1002: ('ApertureValue', ), |
746 0x1002: ('ApertureValue', None), |
710 0x1003: ('BrightnessValue', ), |
747 0x1003: ('BrightnessValue', None), |
711 0x1004: ('FlashMode', ), |
748 0x1004: ('FlashMode', None), |
712 0x1004: ('FlashMode', |
749 0x1004: ('FlashMode', |
713 {2: 'On', |
750 {2: 'On', |
714 3: 'Off'}), |
751 3: 'Off'}), |
715 0x1005: ('FlashDevice', |
752 0x1005: ('FlashDevice', |
716 {0: 'None', |
753 {0: 'None', |
717 1: 'Internal', |
754 1: 'Internal', |
718 4: 'External', |
755 4: 'External', |
719 5: 'Internal + External'}), |
756 5: 'Internal + External'}), |
720 0x1006: ('ExposureCompensation', ), |
757 0x1006: ('ExposureCompensation', None), |
721 0x1007: ('SensorTemperature', ), |
758 0x1007: ('SensorTemperature', None), |
722 0x1008: ('LensTemperature', ), |
759 0x1008: ('LensTemperature', None), |
723 0x100b: ('FocusMode', |
760 0x100b: ('FocusMode', |
724 {0: 'Auto', |
761 {0: 'Auto', |
725 1: 'Manual'}), |
762 1: 'Manual'}), |
726 0x1017: ('RedBalance', ), |
763 0x1017: ('RedBalance', None), |
727 0x1018: ('BlueBalance', ), |
764 0x1018: ('BlueBalance', None), |
728 0x101a: ('SerialNumber', ), |
765 0x101a: ('SerialNumber', None), |
729 0x1023: ('FlashExposureComp', ), |
766 0x1023: ('FlashExposureComp', None), |
730 0x1026: ('ExternalFlashBounce', |
767 0x1026: ('ExternalFlashBounce', |
731 {0: 'No', |
768 {0: 'No', |
732 1: 'Yes'}), |
769 1: 'Yes'}), |
733 0x1027: ('ExternalFlashZoom', ), |
770 0x1027: ('ExternalFlashZoom', None), |
734 0x1028: ('ExternalFlashMode', ), |
771 0x1028: ('ExternalFlashMode', None), |
735 0x1029: ('Contrast int16u', |
772 0x1029: ('Contrast int16u', |
736 {0: 'High', |
773 {0: 'High', |
737 1: 'Normal', |
774 1: 'Normal', |
738 2: 'Low'}), |
775 2: 'Low'}), |
739 0x102a: ('SharpnessFactor', ), |
776 0x102a: ('SharpnessFactor', None), |
740 0x102b: ('ColorControl', ), |
777 0x102b: ('ColorControl', None), |
741 0x102c: ('ValidBits', ), |
778 0x102c: ('ValidBits', None), |
742 0x102d: ('CoringFilter', ), |
779 0x102d: ('CoringFilter', None), |
743 0x102e: ('OlympusImageWidth', ), |
780 0x102e: ('OlympusImageWidth', None), |
744 0x102f: ('OlympusImageHeight', ), |
781 0x102f: ('OlympusImageHeight', None), |
745 0x1034: ('CompressionRatio', ), |
782 0x1034: ('CompressionRatio', None), |
746 0x1035: ('PreviewImageValid', |
783 0x1035: ('PreviewImageValid', |
747 {0: 'No', |
784 {0: 'No', |
748 1: 'Yes'}), |
785 1: 'Yes'}), |
749 0x1036: ('PreviewImageStart', ), |
786 0x1036: ('PreviewImageStart', None), |
750 0x1037: ('PreviewImageLength', ), |
787 0x1037: ('PreviewImageLength', None), |
751 0x1039: ('CCDScanMode', |
788 0x1039: ('CCDScanMode', |
752 {0: 'Interlaced', |
789 {0: 'Interlaced', |
753 1: 'Progressive'}), |
790 1: 'Progressive'}), |
754 0x103a: ('NoiseReduction', |
791 0x103a: ('NoiseReduction', |
755 {0: 'Off', |
792 {0: 'Off', |
756 1: 'On'}), |
793 1: 'On'}), |
757 0x103b: ('InfinityLensStep', ), |
794 0x103b: ('InfinityLensStep', None), |
758 0x103c: ('NearLensStep', ), |
795 0x103c: ('NearLensStep', None), |
759 |
796 |
760 # TODO - these need extra definitions |
797 # TODO - these need extra definitions |
761 # http://search.cpan.org/src/EXIFTOOL/Image-ExifTool-6.90/html/TagNames/Olympus.html |
798 # http://search.cpan.org/src/EXIFTOOL/Image-ExifTool-6.90/html/TagNames/Olympus.html |
762 0x2010: ('Equipment', ), |
799 0x2010: ('Equipment', None), |
763 0x2020: ('CameraSettings', ), |
800 0x2020: ('CameraSettings', None), |
764 0x2030: ('RawDevelopment', ), |
801 0x2030: ('RawDevelopment', None), |
765 0x2040: ('ImageProcessing', ), |
802 0x2040: ('ImageProcessing', None), |
766 0x2050: ('FocusInfo', ), |
803 0x2050: ('FocusInfo', None), |
767 0x3000: ('RawInfo ', ), |
804 0x3000: ('RawInfo ', None), |
768 } |
805 } |
769 |
806 |
770 # 0x2020 CameraSettings |
807 # 0x2020 CameraSettings |
771 MAKERNOTE_OLYMPUS_TAG_0x2020={ |
808 MAKERNOTE_OLYMPUS_TAG_0x2020={ |
772 0x0100: ('PreviewImageValid', |
809 0x0100: ('PreviewImageValid', |
773 {0: 'No', |
810 {0: 'No', |
774 1: 'Yes'}), |
811 1: 'Yes'}), |
775 0x0101: ('PreviewImageStart', ), |
812 0x0101: ('PreviewImageStart', None), |
776 0x0102: ('PreviewImageLength', ), |
813 0x0102: ('PreviewImageLength', None), |
777 0x0200: ('ExposureMode', |
814 0x0200: ('ExposureMode', |
778 {1: 'Manual', |
815 {1: 'Manual', |
779 2: 'Program', |
816 2: 'Program', |
780 3: 'Aperture-priority AE', |
817 3: 'Aperture-priority AE', |
781 4: 'Shutter speed priority AE', |
818 4: 'Shutter speed priority AE', |