degal/exif_data.py
branchnew-exif
changeset 102 ef2c1ffdca8f
child 103 63e89dc2d6f1
equal deleted inserted replaced
101:698dc68a985d 102:ef2c1ffdca8f
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 """
       
     5     EXIF file format data, including tag names, types, etc.
       
     6 
       
     7     Most of this was copied with modifications from EXIFpy:
       
     8         # Library to extract EXIF information from digital camera image files
       
     9         # http://sourceforge.net/projects/exif-py/
       
    10         #
       
    11         # VERSION 1.1.0
       
    12         #
       
    13         # Copyright (c) 2002-2007 Gene Cash All rights reserved
       
    14         # Copyright (c) 2007-2008 Ianaré Sévi All rights reserved
       
    15         #
       
    16         # Redistribution and use in source and binary forms, with or without
       
    17         # modification, are permitted provided that the following conditions
       
    18         # are met:
       
    19         #
       
    20         #  1. Redistributions of source code must retain the above copyright
       
    21         #     notice, this list of conditions and the following disclaimer.
       
    22         #
       
    23         #  2. Redistributions in binary form must reproduce the above
       
    24         #     copyright notice, this list of conditions and the following
       
    25         #     disclaimer in the documentation and/or other materials provided
       
    26         #     with the distribution.
       
    27         #
       
    28         #  3. Neither the name of the authors nor the names of its contributors
       
    29         #     may be used to endorse or promote products derived from this
       
    30         #     software without specific prior written permission.
       
    31         #
       
    32         # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    33         # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    34         # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    35         # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    36         # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    37         # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    38         # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    39         # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    40         # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    41         # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    42         # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    43 
       
    44 """
       
    45 
       
    46 def make_string (seq):
       
    47     """
       
    48         Filter a string to strip out non-printing chars
       
    49     """
       
    50     
       
    51     # screen out non-printing characters
       
    52     str = ''.join(c for c in seq if 32 <= c < 256)
       
    53 
       
    54     if not str:
       
    55         # no printing chars
       
    56         return seq
       
    57 
       
    58     else :
       
    59         return str
       
    60 
       
    61 def make_string_uc (seq) :
       
    62     """
       
    63         # Special version to deal with the code in the first 8 bytes of a user comment.
       
    64         # First 8 bytes gives coding system e.g. ASCII vs. JIS vs Unicode
       
    65 
       
    66         XXX: decode?
       
    67     """
       
    68 
       
    69     code = seq[0:8]
       
    70     seq = seq[8:]
       
    71 
       
    72     ## Of course, this is only correct if ASCII, and the standard explicitly
       
    73     ## allows JIS and Unicode.
       
    74     return make_string(seq)
       
    75 
       
    76 # IFD Tag type information, indexed by code
       
    77 #  { type_code: (type_fmt, name) }
       
    78 FIELD_TYPES = {
       
    79 #    0x0000: (None,  'Proprietary'   ), # ??? no such type
       
    80     0x0001: ('B',   'Byte'          ),
       
    81     0x0002: ('s',   'ASCII'         ),
       
    82     0x0003: ('H',   'Short'         ),
       
    83     0x0004: ('L',   'Long'          ),
       
    84     0x0005: ('LL',  'Ratio'         ),
       
    85     0x0006: ('b',   'Signed Byte'   ),
       
    86     0x0007: ('c',   'Undefined'     ),
       
    87     0x0008: ('h',   'Signed Short'  ),
       
    88     0x0009: ('l',   'Signed Long'   ),
       
    89     0x000A: ('ll',  'Signed Ratio'  ),
       
    90 }
       
    91 
       
    92 def map_value (spec, value) :
       
    93     """
       
    94         Map the given tag value to a printable string using the given value spec.
       
    95     """
       
    96     
       
    97     if callable(spec):
       
    98         # call mapping function
       
    99         return spec(value)
       
   100 
       
   101     else:
       
   102         return spec.get(value, repr(value))
       
   103 
       
   104 # dictionary of main EXIF tag names
       
   105 # first element of tuple is tag name, optional second element is
       
   106 # another dictionary giving names to values
       
   107 # { tag_type : (name, spec?) }
       
   108 EXIF_TAGS = {
       
   109     0x0100: ('ImageWidth', ),
       
   110     0x0101: ('ImageLength', ),
       
   111     0x0102: ('BitsPerSample', ),
       
   112     0x0103: ('Compression',
       
   113              {1: 'Uncompressed',
       
   114               2: 'CCITT 1D',
       
   115               3: 'T4/Group 3 Fax',
       
   116               4: 'T6/Group 4 Fax',
       
   117               5: 'LZW',
       
   118               6: 'JPEG (old-style)',
       
   119               7: 'JPEG',
       
   120               8: 'Adobe Deflate',
       
   121               9: 'JBIG B&W',
       
   122               10: 'JBIG Color',
       
   123               32766: 'Next',
       
   124               32769: 'Epson ERF Compressed',
       
   125               32771: 'CCIRLEW',
       
   126               32773: 'PackBits',
       
   127               32809: 'Thunderscan',
       
   128               32895: 'IT8CTPAD',
       
   129               32896: 'IT8LW',
       
   130               32897: 'IT8MP',
       
   131               32898: 'IT8BL',
       
   132               32908: 'PixarFilm',
       
   133               32909: 'PixarLog',
       
   134               32946: 'Deflate',
       
   135               32947: 'DCS',
       
   136               34661: 'JBIG',
       
   137               34676: 'SGILog',
       
   138               34677: 'SGILog24',
       
   139               34712: 'JPEG 2000',
       
   140               34713: 'Nikon NEF Compressed',
       
   141               65000: 'Kodak DCR Compressed',
       
   142               65535: 'Pentax PEF Compressed'}),
       
   143     0x0106: ('PhotometricInterpretation', ),
       
   144     0x0107: ('Thresholding', ),
       
   145     0x010A: ('FillOrder', ),
       
   146     0x010D: ('DocumentName', ),
       
   147     0x010E: ('ImageDescription', ),
       
   148     0x010F: ('Make', ),
       
   149     0x0110: ('Model', ),
       
   150     0x0111: ('StripOffsets', ),
       
   151     0x0112: ('Orientation',
       
   152              {1: 'Horizontal (normal)',
       
   153               2: 'Mirrored horizontal',
       
   154               3: 'Rotated 180',
       
   155               4: 'Mirrored vertical',
       
   156               5: 'Mirrored horizontal then rotated 90 CCW',
       
   157               6: 'Rotated 90 CW',
       
   158               7: 'Mirrored horizontal then rotated 90 CW',
       
   159               8: 'Rotated 90 CCW'}),
       
   160     0x0115: ('SamplesPerPixel', ),
       
   161     0x0116: ('RowsPerStrip', ),
       
   162     0x0117: ('StripByteCounts', ),
       
   163     0x011A: ('XResolution', ),
       
   164     0x011B: ('YResolution', ),
       
   165     0x011C: ('PlanarConfiguration', ),
       
   166     0x011D: ('PageName', make_string),
       
   167     0x0128: ('ResolutionUnit',
       
   168              {1: 'Not Absolute',
       
   169               2: 'Pixels/Inch',
       
   170               3: 'Pixels/Centimeter'}),
       
   171     0x012D: ('TransferFunction', ),
       
   172     0x0131: ('Software', ),
       
   173     0x0132: ('DateTime', ),
       
   174     0x013B: ('Artist', ),
       
   175     0x013E: ('WhitePoint', ),
       
   176     0x013F: ('PrimaryChromaticities', ),
       
   177     0x0156: ('TransferRange', ),
       
   178     0x0200: ('JPEGProc', ),
       
   179     0x0201: ('JPEGInterchangeFormat', ),
       
   180     0x0202: ('JPEGInterchangeFormatLength', ),
       
   181     0x0211: ('YCbCrCoefficients', ),
       
   182     0x0212: ('YCbCrSubSampling', ),
       
   183     0x0213: ('YCbCrPositioning',
       
   184              {1: 'Centered',
       
   185               2: 'Co-sited'}),
       
   186     0x0214: ('ReferenceBlackWhite', ),
       
   187     
       
   188     0x4746: ('Rating', ),
       
   189     
       
   190     0x828D: ('CFARepeatPatternDim', ),
       
   191     0x828E: ('CFAPattern', ),
       
   192     0x828F: ('BatteryLevel', ),
       
   193     0x8298: ('Copyright', ),
       
   194     0x829A: ('ExposureTime', ),
       
   195     0x829D: ('FNumber', ),
       
   196     0x83BB: ('IPTC/NAA', ),
       
   197     0x8769: ('ExifOffset', ),
       
   198     0x8773: ('InterColorProfile', ),
       
   199     0x8822: ('ExposureProgram',
       
   200              {0: 'Unidentified',
       
   201               1: 'Manual',
       
   202               2: 'Program Normal',
       
   203               3: 'Aperture Priority',
       
   204               4: 'Shutter Priority',
       
   205               5: 'Program Creative',
       
   206               6: 'Program Action',
       
   207               7: 'Portrait Mode',
       
   208               8: 'Landscape Mode'}),
       
   209     0x8824: ('SpectralSensitivity', ),
       
   210     0x8825: ('GPSInfo', ),
       
   211     0x8827: ('ISOSpeedRatings', ),
       
   212     0x8828: ('OECF', ),
       
   213     0x9000: ('ExifVersion', make_string),
       
   214     0x9003: ('DateTimeOriginal', ),
       
   215     0x9004: ('DateTimeDigitized', ),
       
   216     0x9101: ('ComponentsConfiguration',
       
   217              {0: '',
       
   218               1: 'Y',
       
   219               2: 'Cb',
       
   220               3: 'Cr',
       
   221               4: 'Red',
       
   222               5: 'Green',
       
   223               6: 'Blue'}),
       
   224     0x9102: ('CompressedBitsPerPixel', ),
       
   225     0x9201: ('ShutterSpeedValue', ),
       
   226     0x9202: ('ApertureValue', ),
       
   227     0x9203: ('BrightnessValue', ),
       
   228     0x9204: ('ExposureBiasValue', ),
       
   229     0x9205: ('MaxApertureValue', ),
       
   230     0x9206: ('SubjectDistance', ),
       
   231     0x9207: ('MeteringMode',
       
   232              {0: 'Unidentified',
       
   233               1: 'Average',
       
   234               2: 'CenterWeightedAverage',
       
   235               3: 'Spot',
       
   236               4: 'MultiSpot',
       
   237               5: 'Pattern'}),
       
   238     0x9208: ('LightSource',
       
   239              {0: 'Unknown',
       
   240               1: 'Daylight',
       
   241               2: 'Fluorescent',
       
   242               3: 'Tungsten',
       
   243               9: 'Fine Weather',
       
   244               10: 'Flash',
       
   245               11: 'Shade',
       
   246               12: 'Daylight Fluorescent',
       
   247               13: 'Day White Fluorescent',
       
   248               14: 'Cool White Fluorescent',
       
   249               15: 'White Fluorescent',
       
   250               17: 'Standard Light A',
       
   251               18: 'Standard Light B',
       
   252               19: 'Standard Light C',
       
   253               20: 'D55',
       
   254               21: 'D65',
       
   255               22: 'D75',
       
   256               255: 'Other'}),
       
   257     0x9209: ('Flash',
       
   258              {0: 'No',
       
   259               1: 'Fired',
       
   260               5: 'Fired (?)', # no return sensed
       
   261               7: 'Fired (!)', # return sensed
       
   262               9: 'Fill Fired',
       
   263               13: 'Fill Fired (?)',
       
   264               15: 'Fill Fired (!)',
       
   265               16: 'Off',
       
   266               24: 'Auto Off',
       
   267               25: 'Auto Fired',
       
   268               29: 'Auto Fired (?)',
       
   269               31: 'Auto Fired (!)',
       
   270               32: 'Not Available'}),
       
   271     0x920A: ('FocalLength', ),
       
   272     0x9214: ('SubjectArea', ),
       
   273     0x927C: ('MakerNote', ),
       
   274     0x9286: ('UserComment', make_string_uc),
       
   275     0x9290: ('SubSecTime', ),
       
   276     0x9291: ('SubSecTimeOriginal', ),
       
   277     0x9292: ('SubSecTimeDigitized', ),
       
   278     
       
   279     # used by Windows Explorer
       
   280     0x9C9B: ('XPTitle', ),
       
   281     0x9C9C: ('XPComment', ),
       
   282     0x9C9D: ('XPAuthor', ), #(ignored by Windows Explorer if Artist exists)
       
   283     0x9C9E: ('XPKeywords', ),
       
   284     0x9C9F: ('XPSubject', ),
       
   285 
       
   286     0xA000: ('FlashPixVersion', make_string),
       
   287     0xA001: ('ColorSpace',
       
   288              {1: 'sRGB',
       
   289               2: 'Adobe RGB',
       
   290               65535: 'Uncalibrated'}),
       
   291     0xA002: ('ExifImageWidth', ),
       
   292     0xA003: ('ExifImageLength', ),
       
   293     0xA005: ('InteroperabilityOffset', ),
       
   294     0xA20B: ('FlashEnergy', ),               # 0x920B in TIFF/EP
       
   295     0xA20C: ('SpatialFrequencyResponse', ),  # 0x920C
       
   296     0xA20E: ('FocalPlaneXResolution', ),     # 0x920E
       
   297     0xA20F: ('FocalPlaneYResolution', ),     # 0x920F
       
   298     0xA210: ('FocalPlaneResolutionUnit', ),  # 0x9210
       
   299     0xA214: ('SubjectLocation', ),           # 0x9214
       
   300     0xA215: ('ExposureIndex', ),             # 0x9215
       
   301     0xA217: ('SensingMethod',                # 0x9217
       
   302              {1: 'Not defined',
       
   303               2: 'One-chip color area',
       
   304               3: 'Two-chip color area',
       
   305               4: 'Three-chip color area',
       
   306               5: 'Color sequential area',
       
   307               7: 'Trilinear',
       
   308               8: 'Color sequential linear'}),             
       
   309     0xA300: ('FileSource',
       
   310              {1: 'Film Scanner',
       
   311               2: 'Reflection Print Scanner',
       
   312               3: 'Digital Camera'}),
       
   313     0xA301: ('SceneType',
       
   314              {1: 'Directly Photographed'}),
       
   315     0xA302: ('CVAPattern', ),
       
   316     0xA401: ('CustomRendered',
       
   317              {0: 'Normal',
       
   318               1: 'Custom'}),
       
   319     0xA402: ('ExposureMode',
       
   320              {0: 'Auto Exposure',
       
   321               1: 'Manual Exposure',
       
   322               2: 'Auto Bracket'}),
       
   323     0xA403: ('WhiteBalance',
       
   324              {0: 'Auto',
       
   325               1: 'Manual'}),
       
   326     0xA404: ('DigitalZoomRatio', ),
       
   327     0xA405: ('FocalLengthIn35mmFilm', ),
       
   328     0xA406: ('SceneCaptureType',
       
   329              {0: 'Standard',
       
   330               1: 'Landscape',
       
   331               2: 'Portrait',
       
   332               3: 'Night)'}),
       
   333     0xA407: ('GainControl',
       
   334              {0: 'None',
       
   335               1: 'Low gain up',
       
   336               2: 'High gain up',
       
   337               3: 'Low gain down',
       
   338               4: 'High gain down'}),
       
   339     0xA408: ('Contrast',
       
   340              {0: 'Normal',
       
   341               1: 'Soft',
       
   342               2: 'Hard'}),
       
   343     0xA409: ('Saturation',
       
   344              {0: 'Normal',
       
   345               1: 'Soft',
       
   346               2: 'Hard'}),
       
   347     0xA40A: ('Sharpness',
       
   348              {0: 'Normal',
       
   349               1: 'Soft',
       
   350               2: 'Hard'}),
       
   351     0xA40B: ('DeviceSettingDescription', ),
       
   352     0xA40C: ('SubjectDistanceRange', ),
       
   353     0xA500: ('Gamma', ),
       
   354     0xC4A5: ('PrintIM', ),
       
   355     0xEA1C:	('Padding', ),
       
   356     }
       
   357 
       
   358 # interoperability tags
       
   359 INTR_TAGS = {
       
   360     0x0001: ('InteroperabilityIndex', ),
       
   361     0x0002: ('InteroperabilityVersion', ),
       
   362     0x1000: ('RelatedImageFileFormat', ),
       
   363     0x1001: ('RelatedImageWidth', ),
       
   364     0x1002: ('RelatedImageLength', ),
       
   365     }
       
   366 
       
   367 # GPS tags (not used yet, haven't seen camera with GPS)
       
   368 GPS_TAGS = {
       
   369     0x0000: ('GPSVersionID', ),
       
   370     0x0001: ('GPSLatitudeRef', ),
       
   371     0x0002: ('GPSLatitude', ),
       
   372     0x0003: ('GPSLongitudeRef', ),
       
   373     0x0004: ('GPSLongitude', ),
       
   374     0x0005: ('GPSAltitudeRef', ),
       
   375     0x0006: ('GPSAltitude', ),
       
   376     0x0007: ('GPSTimeStamp', ),
       
   377     0x0008: ('GPSSatellites', ),
       
   378     0x0009: ('GPSStatus', ),
       
   379     0x000A: ('GPSMeasureMode', ),
       
   380     0x000B: ('GPSDOP', ),
       
   381     0x000C: ('GPSSpeedRef', ),
       
   382     0x000D: ('GPSSpeed', ),
       
   383     0x000E: ('GPSTrackRef', ),
       
   384     0x000F: ('GPSTrack', ),
       
   385     0x0010: ('GPSImgDirectionRef', ),
       
   386     0x0011: ('GPSImgDirection', ),
       
   387     0x0012: ('GPSMapDatum', ),
       
   388     0x0013: ('GPSDestLatitudeRef', ),
       
   389     0x0014: ('GPSDestLatitude', ),
       
   390     0x0015: ('GPSDestLongitudeRef', ),
       
   391     0x0016: ('GPSDestLongitude', ),
       
   392     0x0017: ('GPSDestBearingRef', ),
       
   393     0x0018: ('GPSDestBearing', ),
       
   394     0x0019: ('GPSDestDistanceRef', ),
       
   395     0x001A: ('GPSDestDistance', ),
       
   396     0x001D: ('GPSDate', ),
       
   397     }
       
   398 
       
   399 # Ignore these tags when quick processing
       
   400 # 0x927C is MakerNote Tags
       
   401 # 0x9286 is user comment
       
   402 IGNORE_TAGS=(0x9286, 0x927C)
       
   403 
       
   404 # http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp
       
   405 def nikon_ev_bias(seq):
       
   406     # First digit seems to be in steps of 1/6 EV.
       
   407     # Does the third value mean the step size?  It is usually 6,
       
   408     # but it is 12 for the ExposureDifference.
       
   409     #
       
   410     # Check for an error condition that could cause a crash.
       
   411     # This only happens if something has gone really wrong in
       
   412     # reading the Nikon MakerNote.
       
   413     if len( seq ) < 4 : return ""
       
   414     #
       
   415     if seq == [252, 1, 6, 0]:
       
   416         return "-2/3 EV"
       
   417     if seq == [253, 1, 6, 0]:
       
   418         return "-1/2 EV"
       
   419     if seq == [254, 1, 6, 0]:
       
   420         return "-1/3 EV"
       
   421     if seq == [0, 1, 6, 0]:
       
   422         return "0 EV"
       
   423     if seq == [2, 1, 6, 0]:
       
   424         return "+1/3 EV"
       
   425     if seq == [3, 1, 6, 0]:
       
   426         return "+1/2 EV"
       
   427     if seq == [4, 1, 6, 0]:
       
   428         return "+2/3 EV"
       
   429     # Handle combinations not in the table.
       
   430     a = seq[0]
       
   431     # Causes headaches for the +/- logic, so special case it.
       
   432     if a == 0:
       
   433         return "0 EV"
       
   434     if a > 127:
       
   435         a = 256 - a
       
   436         ret_str = "-"
       
   437     else:
       
   438         ret_str = "+"
       
   439     b = seq[2]	# Assume third value means the step size
       
   440     whole = a / b
       
   441     a = a % b
       
   442     if whole != 0:
       
   443         ret_str = ret_str + str(whole) + " "
       
   444     if a == 0:
       
   445         ret_str = ret_str + "EV"
       
   446     else:
       
   447         r = Ratio(a, b)
       
   448         ret_str = ret_str + r.__repr__() + " EV"
       
   449     return ret_str
       
   450 
       
   451 # Nikon E99x MakerNote Tags
       
   452 MAKERNOTE_NIKON_NEWER_TAGS={
       
   453     0x0001: ('MakernoteVersion', make_string),	# Sometimes binary
       
   454     0x0002: ('ISOSetting', make_string),
       
   455     0x0003: ('ColorMode', ),
       
   456     0x0004: ('Quality', ),
       
   457     0x0005: ('Whitebalance', ),
       
   458     0x0006: ('ImageSharpening', ),
       
   459     0x0007: ('FocusMode', ),
       
   460     0x0008: ('FlashSetting', ),
       
   461     0x0009: ('AutoFlashMode', ),
       
   462     0x000B: ('WhiteBalanceBias', ),
       
   463     0x000C: ('WhiteBalanceRBCoeff', ),
       
   464     0x000D: ('ProgramShift', nikon_ev_bias),
       
   465     # Nearly the same as the other EV vals, but step size is 1/12 EV (?)
       
   466     0x000E: ('ExposureDifference', nikon_ev_bias),
       
   467     0x000F: ('ISOSelection', ),
       
   468     0x0011: ('NikonPreview', ),
       
   469     0x0012: ('FlashCompensation', nikon_ev_bias),
       
   470     0x0013: ('ISOSpeedRequested', ),
       
   471     0x0016: ('PhotoCornerCoordinates', ),
       
   472     # 0x0017: Unknown, but most likely an EV value
       
   473     0x0018: ('FlashBracketCompensationApplied', nikon_ev_bias),
       
   474     0x0019: ('AEBracketCompensationApplied', ),
       
   475     0x001A: ('ImageProcessing', ),
       
   476     0x001B: ('CropHiSpeed', ),
       
   477     0x001D: ('SerialNumber', ),	# Conflict with 0x00A0 ?
       
   478     0x001E: ('ColorSpace', ),
       
   479     0x001F: ('VRInfo', ),
       
   480     0x0020: ('ImageAuthentication', ),
       
   481     0x0022: ('ActiveDLighting', ),
       
   482     0x0023: ('PictureControl', ),
       
   483     0x0024: ('WorldTime', ),
       
   484     0x0025: ('ISOInfo', ),
       
   485     0x0080: ('ImageAdjustment', ),
       
   486     0x0081: ('ToneCompensation', ),
       
   487     0x0082: ('AuxiliaryLens', ),
       
   488     0x0083: ('LensType', ),
       
   489     0x0084: ('LensMinMaxFocalMaxAperture', ),
       
   490     0x0085: ('ManualFocusDistance', ),
       
   491     0x0086: ('DigitalZoomFactor', ),
       
   492     0x0087: ('FlashMode',
       
   493              {0x00: 'Did Not Fire',
       
   494               0x01: 'Fired, Manual',
       
   495               0x07: 'Fired, External',
       
   496               0x08: 'Fired, Commander Mode ',
       
   497               0x09: 'Fired, TTL Mode'}),
       
   498     0x0088: ('AFFocusPosition',
       
   499              {0x0000: 'Center',
       
   500               0x0100: 'Top',
       
   501               0x0200: 'Bottom',
       
   502               0x0300: 'Left',
       
   503               0x0400: 'Right'}),
       
   504     0x0089: ('BracketingMode',
       
   505              {0x00: 'Single frame, no bracketing',
       
   506               0x01: 'Continuous, no bracketing',
       
   507               0x02: 'Timer, no bracketing',
       
   508               0x10: 'Single frame, exposure bracketing',
       
   509               0x11: 'Continuous, exposure bracketing',
       
   510               0x12: 'Timer, exposure bracketing',
       
   511               0x40: 'Single frame, white balance bracketing',
       
   512               0x41: 'Continuous, white balance bracketing',
       
   513               0x42: 'Timer, white balance bracketing'}),
       
   514     0x008A: ('AutoBracketRelease', ),
       
   515     0x008B: ('LensFStops', ),
       
   516     0x008C: ('NEFCurve1', ),	# ExifTool calls this 'ContrastCurve'
       
   517     0x008D: ('ColorMode', ),
       
   518     0x008F: ('SceneMode', ),
       
   519     0x0090: ('LightingType', ),
       
   520     0x0091: ('ShotInfo', ),	# First 4 bytes are a version number in ASCII
       
   521     0x0092: ('HueAdjustment', ),
       
   522     # ExifTool calls this 'NEFCompression', should be 1-4
       
   523     0x0093: ('Compression', ),
       
   524     0x0094: ('Saturation',
       
   525              {-3: 'B&W',
       
   526               -2: '-2',
       
   527               -1: '-1',
       
   528               0: '0',
       
   529               1: '1',
       
   530               2: '2'}),
       
   531     0x0095: ('NoiseReduction', ),
       
   532     0x0096: ('NEFCurve2', ),	# ExifTool calls this 'LinearizationTable'
       
   533     0x0097: ('ColorBalance', ),	# First 4 bytes are a version number in ASCII
       
   534     0x0098: ('LensData', ),	# First 4 bytes are a version number in ASCII
       
   535     0x0099: ('RawImageCenter', ),
       
   536     0x009A: ('SensorPixelSize', ),
       
   537     0x009C: ('Scene Assist', ),
       
   538     0x009E: ('RetouchHistory', ),
       
   539     0x00A0: ('SerialNumber', ),
       
   540     0x00A2: ('ImageDataSize', ),
       
   541     # 00A3: unknown - a single byte 0
       
   542     # 00A4: In NEF, looks like a 4 byte ASCII version number ('0200')
       
   543     0x00A5: ('ImageCount', ),
       
   544     0x00A6: ('DeletedImageCount', ),
       
   545     0x00A7: ('TotalShutterReleases', ),
       
   546     # First 4 bytes are a version number in ASCII, with version specific
       
   547     # info to follow.  Its hard to treat it as a string due to embedded nulls.
       
   548     0x00A8: ('FlashInfo', ),
       
   549     0x00A9: ('ImageOptimization', ),
       
   550     0x00AA: ('Saturation', ),
       
   551     0x00AB: ('DigitalVariProgram', ),
       
   552     0x00AC: ('ImageStabilization', ),
       
   553     0x00AD: ('Responsive AF', ),	# 'AFResponse'
       
   554     0x00B0: ('MultiExposure', ),
       
   555     0x00B1: ('HighISONoiseReduction', ),
       
   556     0x00B7: ('AFInfo', ),
       
   557     0x00B8: ('FileInfo', ),
       
   558     # 00B9: unknown
       
   559     0x0100: ('DigitalICE', ),
       
   560     0x0103: ('PreviewCompression',
       
   561              {1: 'Uncompressed',
       
   562               2: 'CCITT 1D',
       
   563               3: 'T4/Group 3 Fax',
       
   564               4: 'T6/Group 4 Fax',
       
   565               5: 'LZW',
       
   566               6: 'JPEG (old-style)',
       
   567               7: 'JPEG',
       
   568               8: 'Adobe Deflate',
       
   569               9: 'JBIG B&W',
       
   570               10: 'JBIG Color',
       
   571               32766: 'Next',
       
   572               32769: 'Epson ERF Compressed',
       
   573               32771: 'CCIRLEW',
       
   574               32773: 'PackBits',
       
   575               32809: 'Thunderscan',
       
   576               32895: 'IT8CTPAD',
       
   577               32896: 'IT8LW',
       
   578               32897: 'IT8MP',
       
   579               32898: 'IT8BL',
       
   580               32908: 'PixarFilm',
       
   581               32909: 'PixarLog',
       
   582               32946: 'Deflate',
       
   583               32947: 'DCS',
       
   584               34661: 'JBIG',
       
   585               34676: 'SGILog',
       
   586               34677: 'SGILog24',
       
   587               34712: 'JPEG 2000',
       
   588               34713: 'Nikon NEF Compressed',
       
   589               65000: 'Kodak DCR Compressed',
       
   590               65535: 'Pentax PEF Compressed',}),
       
   591     0x0201: ('PreviewImageStart', ),
       
   592     0x0202: ('PreviewImageLength', ),
       
   593     0x0213: ('PreviewYCbCrPositioning',
       
   594              {1: 'Centered',
       
   595               2: 'Co-sited'}), 
       
   596     0x0010: ('DataDump', ),
       
   597     }
       
   598 
       
   599 MAKERNOTE_NIKON_OLDER_TAGS = {
       
   600     0x0003: ('Quality',
       
   601              {1: 'VGA Basic',
       
   602               2: 'VGA Normal',
       
   603               3: 'VGA Fine',
       
   604               4: 'SXGA Basic',
       
   605               5: 'SXGA Normal',
       
   606               6: 'SXGA Fine'}),
       
   607     0x0004: ('ColorMode',
       
   608              {1: 'Color',
       
   609               2: 'Monochrome'}),
       
   610     0x0005: ('ImageAdjustment',
       
   611              {0: 'Normal',
       
   612               1: 'Bright+',
       
   613               2: 'Bright-',
       
   614               3: 'Contrast+',
       
   615               4: 'Contrast-'}),
       
   616     0x0006: ('CCDSpeed',
       
   617              {0: 'ISO 80',
       
   618               2: 'ISO 160',
       
   619               4: 'ISO 320',
       
   620               5: 'ISO 100'}),
       
   621     0x0007: ('WhiteBalance',
       
   622              {0: 'Auto',
       
   623               1: 'Preset',
       
   624               2: 'Daylight',
       
   625               3: 'Incandescent',
       
   626               4: 'Fluorescent',
       
   627               5: 'Cloudy',
       
   628               6: 'Speed Light'}),
       
   629     }
       
   630 
       
   631 # decode Olympus SpecialMode tag in MakerNote
       
   632 def olympus_special_mode(v):
       
   633     a={
       
   634         0: 'Normal',
       
   635         1: 'Unknown',
       
   636         2: 'Fast',
       
   637         3: 'Panorama'}
       
   638     b={
       
   639         0: 'Non-panoramic',
       
   640         1: 'Left to right',
       
   641         2: 'Right to left',
       
   642         3: 'Bottom to top',
       
   643         4: 'Top to bottom'}
       
   644     if v[0] not in a or v[2] not in b:
       
   645         return v
       
   646     return '%s - sequence %d - %s' % (a[v[0]], v[1], b[v[2]])
       
   647 
       
   648 MAKERNOTE_OLYMPUS_TAGS={
       
   649     # ah HAH! those sneeeeeaky bastids! this is how they get past the fact
       
   650     # that a JPEG thumbnail is not allowed in an uncompressed TIFF file
       
   651     0x0100: ('JPEGThumbnail', ),
       
   652     0x0200: ('SpecialMode', olympus_special_mode),
       
   653     0x0201: ('JPEGQual',
       
   654              {1: 'SQ',
       
   655               2: 'HQ',
       
   656               3: 'SHQ'}),
       
   657     0x0202: ('Macro',
       
   658              {0: 'Normal',
       
   659              1: 'Macro',
       
   660              2: 'SuperMacro'}),
       
   661     0x0203: ('BWMode',
       
   662              {0: 'Off',
       
   663              1: 'On'}),
       
   664     0x0204: ('DigitalZoom', ),
       
   665     0x0205: ('FocalPlaneDiagonal', ),
       
   666     0x0206: ('LensDistortionParams', ),
       
   667     0x0207: ('SoftwareRelease', ),
       
   668     0x0208: ('PictureInfo', ),
       
   669     0x0209: ('CameraID', make_string), # print as string
       
   670     0x0F00: ('DataDump', ),
       
   671     0x0300: ('PreCaptureFrames', ),
       
   672     0x0404: ('SerialNumber', ),
       
   673     0x1000: ('ShutterSpeedValue', ),
       
   674     0x1001: ('ISOValue', ),
       
   675     0x1002: ('ApertureValue', ),
       
   676     0x1003: ('BrightnessValue', ),
       
   677     0x1004: ('FlashMode', ),
       
   678     0x1004: ('FlashMode',
       
   679        {2: 'On',
       
   680         3: 'Off'}),
       
   681     0x1005: ('FlashDevice',
       
   682        {0: 'None',
       
   683         1: 'Internal',
       
   684         4: 'External',
       
   685         5: 'Internal + External'}),
       
   686     0x1006: ('ExposureCompensation', ),
       
   687     0x1007: ('SensorTemperature', ),
       
   688     0x1008: ('LensTemperature', ),
       
   689     0x100b: ('FocusMode',
       
   690        {0: 'Auto',
       
   691         1: 'Manual'}),
       
   692     0x1017: ('RedBalance', ),
       
   693     0x1018: ('BlueBalance', ),
       
   694     0x101a: ('SerialNumber', ),
       
   695     0x1023: ('FlashExposureComp', ),
       
   696     0x1026: ('ExternalFlashBounce',
       
   697        {0: 'No',
       
   698         1: 'Yes'}),
       
   699     0x1027: ('ExternalFlashZoom', ),
       
   700     0x1028: ('ExternalFlashMode', ),
       
   701     0x1029: ('Contrast 	int16u',
       
   702        {0: 'High',
       
   703         1: 'Normal',
       
   704         2: 'Low'}),
       
   705     0x102a: ('SharpnessFactor', ),
       
   706     0x102b: ('ColorControl', ),
       
   707     0x102c: ('ValidBits', ),
       
   708     0x102d: ('CoringFilter', ),
       
   709     0x102e: ('OlympusImageWidth', ),
       
   710     0x102f: ('OlympusImageHeight', ),
       
   711     0x1034: ('CompressionRatio', ),
       
   712     0x1035: ('PreviewImageValid',
       
   713        {0: 'No',
       
   714         1: 'Yes'}),
       
   715     0x1036: ('PreviewImageStart', ),
       
   716     0x1037: ('PreviewImageLength', ),
       
   717     0x1039: ('CCDScanMode',
       
   718        {0: 'Interlaced',
       
   719         1: 'Progressive'}),
       
   720     0x103a: ('NoiseReduction',
       
   721        {0: 'Off',
       
   722         1: 'On'}),
       
   723     0x103b: ('InfinityLensStep', ),
       
   724     0x103c: ('NearLensStep', ),
       
   725 
       
   726     # TODO - these need extra definitions
       
   727     # http://search.cpan.org/src/EXIFTOOL/Image-ExifTool-6.90/html/TagNames/Olympus.html
       
   728     0x2010: ('Equipment', ),
       
   729     0x2020: ('CameraSettings', ),
       
   730     0x2030: ('RawDevelopment', ),
       
   731     0x2040: ('ImageProcessing', ),
       
   732     0x2050: ('FocusInfo', ),
       
   733     0x3000: ('RawInfo ', ),
       
   734     }
       
   735 
       
   736 # 0x2020 CameraSettings
       
   737 MAKERNOTE_OLYMPUS_TAG_0x2020={
       
   738     0x0100: ('PreviewImageValid',
       
   739              {0: 'No',
       
   740               1: 'Yes'}),
       
   741     0x0101: ('PreviewImageStart', ),
       
   742     0x0102: ('PreviewImageLength', ),
       
   743     0x0200: ('ExposureMode',
       
   744              {1: 'Manual',
       
   745               2: 'Program',
       
   746               3: 'Aperture-priority AE',
       
   747               4: 'Shutter speed priority AE',
       
   748               5: 'Program-shift'}),
       
   749     0x0201: ('AELock',
       
   750              {0: 'Off',
       
   751               1: 'On'}),
       
   752     0x0202: ('MeteringMode',
       
   753              {2: 'Center Weighted',
       
   754               3: 'Spot',
       
   755               5: 'ESP',
       
   756               261: 'Pattern+AF',
       
   757               515: 'Spot+Highlight control',
       
   758               1027: 'Spot+Shadow control'}),
       
   759     0x0300: ('MacroMode',
       
   760              {0: 'Off',
       
   761               1: 'On'}),
       
   762     0x0301: ('FocusMode',
       
   763              {0: 'Single AF',
       
   764               1: 'Sequential shooting AF',
       
   765               2: 'Continuous AF',
       
   766               3: 'Multi AF',
       
   767               10: 'MF'}),
       
   768     0x0302: ('FocusProcess',
       
   769              {0: 'AF Not Used',
       
   770               1: 'AF Used'}),
       
   771     0x0303: ('AFSearch',
       
   772              {0: 'Not Ready',
       
   773               1: 'Ready'}),
       
   774     0x0304: ('AFAreas', ),
       
   775     0x0401: ('FlashExposureCompensation', ),
       
   776     0x0500: ('WhiteBalance2',
       
   777              {0: 'Auto',
       
   778              16: '7500K (Fine Weather with Shade)',
       
   779              17: '6000K (Cloudy)',
       
   780              18: '5300K (Fine Weather)',
       
   781              20: '3000K (Tungsten light)',
       
   782              21: '3600K (Tungsten light-like)',
       
   783              33: '6600K (Daylight fluorescent)',
       
   784              34: '4500K (Neutral white fluorescent)',
       
   785              35: '4000K (Cool white fluorescent)',
       
   786              48: '3600K (Tungsten light-like)',
       
   787              256: 'Custom WB 1',
       
   788              257: 'Custom WB 2',
       
   789              258: 'Custom WB 3',
       
   790              259: 'Custom WB 4',
       
   791              512: 'Custom WB 5400K',
       
   792              513: 'Custom WB 2900K',
       
   793              514: 'Custom WB 8000K', }),
       
   794     0x0501: ('WhiteBalanceTemperature', ),
       
   795     0x0502: ('WhiteBalanceBracket', ),
       
   796     0x0503: ('CustomSaturation', ), # (3 numbers: 1. CS Value, 2. Min, 3. Max)
       
   797     0x0504: ('ModifiedSaturation',
       
   798              {0: 'Off',
       
   799               1: 'CM1 (Red Enhance)',
       
   800               2: 'CM2 (Green Enhance)',
       
   801               3: 'CM3 (Blue Enhance)',
       
   802               4: 'CM4 (Skin Tones)'}),
       
   803     0x0505: ('ContrastSetting', ), # (3 numbers: 1. Contrast, 2. Min, 3. Max)
       
   804     0x0506: ('SharpnessSetting', ), # (3 numbers: 1. Sharpness, 2. Min, 3. Max)
       
   805     0x0507: ('ColorSpace',
       
   806              {0: 'sRGB',
       
   807               1: 'Adobe RGB',
       
   808               2: 'Pro Photo RGB'}),
       
   809     0x0509: ('SceneMode',
       
   810              {0: 'Standard',
       
   811               6: 'Auto',
       
   812               7: 'Sport',
       
   813               8: 'Portrait',
       
   814               9: 'Landscape+Portrait',
       
   815              10: 'Landscape',
       
   816              11: 'Night scene',
       
   817              13: 'Panorama',
       
   818              16: 'Landscape+Portrait',
       
   819              17: 'Night+Portrait',
       
   820              19: 'Fireworks',
       
   821              20: 'Sunset',
       
   822              22: 'Macro',
       
   823              25: 'Documents',
       
   824              26: 'Museum',
       
   825              28: 'Beach&Snow',
       
   826              30: 'Candle',
       
   827              35: 'Underwater Wide1',
       
   828              36: 'Underwater Macro',
       
   829              39: 'High Key',
       
   830              40: 'Digital Image Stabilization',
       
   831              44: 'Underwater Wide2',
       
   832              45: 'Low Key',
       
   833              46: 'Children',
       
   834              48: 'Nature Macro'}),
       
   835     0x050a: ('NoiseReduction',
       
   836              {0: 'Off',
       
   837               1: 'Noise Reduction',
       
   838               2: 'Noise Filter',
       
   839               3: 'Noise Reduction + Noise Filter',
       
   840               4: 'Noise Filter (ISO Boost)',
       
   841               5: 'Noise Reduction + Noise Filter (ISO Boost)'}),
       
   842     0x050b: ('DistortionCorrection',
       
   843              {0: 'Off',
       
   844               1: 'On'}),
       
   845     0x050c: ('ShadingCompensation',
       
   846              {0: 'Off',
       
   847               1: 'On'}),
       
   848     0x050d: ('CompressionFactor', ),
       
   849     0x050f: ('Gradation',
       
   850              {'-1 -1 1': 'Low Key',
       
   851               '0 -1 1': 'Normal',
       
   852               '1 -1 1': 'High Key'}),
       
   853     0x0520: ('PictureMode',
       
   854              {1: 'Vivid',
       
   855               2: 'Natural',
       
   856               3: 'Muted',
       
   857               256: 'Monotone',
       
   858               512: 'Sepia'}),
       
   859     0x0521: ('PictureModeSaturation', ),
       
   860     0x0522: ('PictureModeHue?', ),
       
   861     0x0523: ('PictureModeContrast', ),
       
   862     0x0524: ('PictureModeSharpness', ),
       
   863     0x0525: ('PictureModeBWFilter',
       
   864              {0: 'n/a',
       
   865               1: 'Neutral',
       
   866               2: 'Yellow',
       
   867               3: 'Orange',
       
   868               4: 'Red',
       
   869               5: 'Green'}),
       
   870     0x0526: ('PictureModeTone',
       
   871              {0: 'n/a',
       
   872               1: 'Neutral',
       
   873               2: 'Sepia',
       
   874               3: 'Blue',
       
   875               4: 'Purple',
       
   876               5: 'Green'}),
       
   877     0x0600: ('Sequence', ), # 2 or 3 numbers: 1. Mode, 2. Shot number, 3. Mode bits
       
   878     0x0601: ('PanoramaMode', ), # (2 numbers: 1. Mode, 2. Shot number)
       
   879     0x0603: ('ImageQuality2',
       
   880              {1: 'SQ',
       
   881               2: 'HQ',
       
   882               3: 'SHQ',
       
   883               4: 'RAW'}),
       
   884     0x0901: ('ManometerReading', ),
       
   885     }
       
   886 
       
   887 
       
   888 MAKERNOTE_CASIO_TAGS={
       
   889     0x0001: ('RecordingMode',
       
   890              {1: 'Single Shutter',
       
   891               2: 'Panorama',
       
   892               3: 'Night Scene',
       
   893               4: 'Portrait',
       
   894               5: 'Landscape'}),
       
   895     0x0002: ('Quality',
       
   896              {1: 'Economy',
       
   897               2: 'Normal',
       
   898               3: 'Fine'}),
       
   899     0x0003: ('FocusingMode',
       
   900              {2: 'Macro',
       
   901               3: 'Auto Focus',
       
   902               4: 'Manual Focus',
       
   903               5: 'Infinity'}),
       
   904     0x0004: ('FlashMode',
       
   905              {1: 'Auto',
       
   906               2: 'On',
       
   907               3: 'Off',
       
   908               4: 'Red Eye Reduction'}),
       
   909     0x0005: ('FlashIntensity',
       
   910              {11: 'Weak',
       
   911               13: 'Normal',
       
   912               15: 'Strong'}),
       
   913     0x0006: ('Object Distance', ),
       
   914     0x0007: ('WhiteBalance',
       
   915              {1: 'Auto',
       
   916               2: 'Tungsten',
       
   917               3: 'Daylight',
       
   918               4: 'Fluorescent',
       
   919               5: 'Shade',
       
   920               129: 'Manual'}),
       
   921     0x000B: ('Sharpness',
       
   922              {0: 'Normal',
       
   923               1: 'Soft',
       
   924               2: 'Hard'}),
       
   925     0x000C: ('Contrast',
       
   926              {0: 'Normal',
       
   927               1: 'Low',
       
   928               2: 'High'}),
       
   929     0x000D: ('Saturation',
       
   930              {0: 'Normal',
       
   931               1: 'Low',
       
   932               2: 'High'}),
       
   933     0x0014: ('CCDSpeed',
       
   934              {64: 'Normal',
       
   935               80: 'Normal',
       
   936               100: 'High',
       
   937               125: '+1.0',
       
   938               244: '+3.0',
       
   939               250: '+2.0'}),
       
   940     }
       
   941 
       
   942 MAKERNOTE_FUJIFILM_TAGS={
       
   943     0x0000: ('NoteVersion', make_string),
       
   944     0x1000: ('Quality', ),
       
   945     0x1001: ('Sharpness',
       
   946              {1: 'Soft',
       
   947               2: 'Soft',
       
   948               3: 'Normal',
       
   949               4: 'Hard',
       
   950               5: 'Hard'}),
       
   951     0x1002: ('WhiteBalance',
       
   952              {0: 'Auto',
       
   953               256: 'Daylight',
       
   954               512: 'Cloudy',
       
   955               768: 'DaylightColor-Fluorescent',
       
   956               769: 'DaywhiteColor-Fluorescent',
       
   957               770: 'White-Fluorescent',
       
   958               1024: 'Incandescent',
       
   959               3840: 'Custom'}),
       
   960     0x1003: ('Color',
       
   961              {0: 'Normal',
       
   962               256: 'High',
       
   963               512: 'Low'}),
       
   964     0x1004: ('Tone',
       
   965              {0: 'Normal',
       
   966               256: 'High',
       
   967               512: 'Low'}),
       
   968     0x1010: ('FlashMode',
       
   969              {0: 'Auto',
       
   970               1: 'On',
       
   971               2: 'Off',
       
   972               3: 'Red Eye Reduction'}),
       
   973     0x1011: ('FlashStrength', ),
       
   974     0x1020: ('Macro',
       
   975              {0: 'Off',
       
   976               1: 'On'}),
       
   977     0x1021: ('FocusMode',
       
   978              {0: 'Auto',
       
   979               1: 'Manual'}),
       
   980     0x1030: ('SlowSync',
       
   981              {0: 'Off',
       
   982               1: 'On'}),
       
   983     0x1031: ('PictureMode',
       
   984              {0: 'Auto',
       
   985               1: 'Portrait',
       
   986               2: 'Landscape',
       
   987               4: 'Sports',
       
   988               5: 'Night',
       
   989               6: 'Program AE',
       
   990               256: 'Aperture Priority AE',
       
   991               512: 'Shutter Priority AE',
       
   992               768: 'Manual Exposure'}),
       
   993     0x1100: ('MotorOrBracket',
       
   994              {0: 'Off',
       
   995               1: 'On'}),
       
   996     0x1300: ('BlurWarning',
       
   997              {0: 'Off',
       
   998               1: 'On'}),
       
   999     0x1301: ('FocusWarning',
       
  1000              {0: 'Off',
       
  1001               1: 'On'}),
       
  1002     0x1302: ('AEWarning',
       
  1003              {0: 'Off',
       
  1004               1: 'On'}),
       
  1005     }
       
  1006 
       
  1007 MAKERNOTE_CANON_TAGS = {
       
  1008     0x0006: ('ImageType', ),
       
  1009     0x0007: ('FirmwareVersion', ),
       
  1010     0x0008: ('ImageNumber', ),
       
  1011     0x0009: ('OwnerName', ),
       
  1012     }
       
  1013 
       
  1014 # this is in element offset, name, optional value dictionary format
       
  1015 MAKERNOTE_CANON_TAG_0x001 = {
       
  1016     1: ('Macromode',
       
  1017         {1: 'Macro',
       
  1018          2: 'Normal'}),
       
  1019     2: ('SelfTimer', ),
       
  1020     3: ('Quality',
       
  1021         {2: 'Normal',
       
  1022          3: 'Fine',
       
  1023          5: 'Superfine'}),
       
  1024     4: ('FlashMode',
       
  1025         {0: 'Flash Not Fired',
       
  1026          1: 'Auto',
       
  1027          2: 'On',
       
  1028          3: 'Red-Eye Reduction',
       
  1029          4: 'Slow Synchro',
       
  1030          5: 'Auto + Red-Eye Reduction',
       
  1031          6: 'On + Red-Eye Reduction',
       
  1032          16: 'external flash'}),
       
  1033     5: ('ContinuousDriveMode',
       
  1034         {0: 'Single Or Timer',
       
  1035          1: 'Continuous'}),
       
  1036     7: ('FocusMode',
       
  1037         {0: 'One-Shot',
       
  1038          1: 'AI Servo',
       
  1039          2: 'AI Focus',
       
  1040          3: 'MF',
       
  1041          4: 'Single',
       
  1042          5: 'Continuous',
       
  1043          6: 'MF'}),
       
  1044     10: ('ImageSize',
       
  1045          {0: 'Large',
       
  1046           1: 'Medium',
       
  1047           2: 'Small'}),
       
  1048     11: ('EasyShootingMode',
       
  1049          {0: 'Full Auto',
       
  1050           1: 'Manual',
       
  1051           2: 'Landscape',
       
  1052           3: 'Fast Shutter',
       
  1053           4: 'Slow Shutter',
       
  1054           5: 'Night',
       
  1055           6: 'B&W',
       
  1056           7: 'Sepia',
       
  1057           8: 'Portrait',
       
  1058           9: 'Sports',
       
  1059           10: 'Macro/Close-Up',
       
  1060           11: 'Pan Focus'}),
       
  1061     12: ('DigitalZoom',
       
  1062          {0: 'None',
       
  1063           1: '2x',
       
  1064           2: '4x'}),
       
  1065     13: ('Contrast',
       
  1066          {0xFFFF: 'Low',
       
  1067           0: 'Normal',
       
  1068           1: 'High'}),
       
  1069     14: ('Saturation',
       
  1070          {0xFFFF: 'Low',
       
  1071           0: 'Normal',
       
  1072           1: 'High'}),
       
  1073     15: ('Sharpness',
       
  1074          {0xFFFF: 'Low',
       
  1075           0: 'Normal',
       
  1076           1: 'High'}),
       
  1077     16: ('ISO',
       
  1078          {0: 'See ISOSpeedRatings Tag',
       
  1079           15: 'Auto',
       
  1080           16: '50',
       
  1081           17: '100',
       
  1082           18: '200',
       
  1083           19: '400'}),
       
  1084     17: ('MeteringMode',
       
  1085          {3: 'Evaluative',
       
  1086           4: 'Partial',
       
  1087           5: 'Center-weighted'}),
       
  1088     18: ('FocusType',
       
  1089          {0: 'Manual',
       
  1090           1: 'Auto',
       
  1091           3: 'Close-Up (Macro)',
       
  1092           8: 'Locked (Pan Mode)'}),
       
  1093     19: ('AFPointSelected',
       
  1094          {0x3000: 'None (MF)',
       
  1095           0x3001: 'Auto-Selected',
       
  1096           0x3002: 'Right',
       
  1097           0x3003: 'Center',
       
  1098           0x3004: 'Left'}),
       
  1099     20: ('ExposureMode',
       
  1100          {0: 'Easy Shooting',
       
  1101           1: 'Program',
       
  1102           2: 'Tv-priority',
       
  1103           3: 'Av-priority',
       
  1104           4: 'Manual',
       
  1105           5: 'A-DEP'}),
       
  1106     23: ('LongFocalLengthOfLensInFocalUnits', ),
       
  1107     24: ('ShortFocalLengthOfLensInFocalUnits', ),
       
  1108     25: ('FocalUnitsPerMM', ),
       
  1109     28: ('FlashActivity',
       
  1110          {0: 'Did Not Fire',
       
  1111           1: 'Fired'}),
       
  1112     29: ('FlashDetails',
       
  1113          {14: 'External E-TTL',
       
  1114           13: 'Internal Flash',
       
  1115           11: 'FP Sync Used',
       
  1116           7: '2nd("Rear")-Curtain Sync Used',
       
  1117           4: 'FP Sync Enabled'}),
       
  1118     32: ('FocusMode',
       
  1119          {0: 'Single',
       
  1120           1: 'Continuous'}),
       
  1121     }
       
  1122 
       
  1123 MAKERNOTE_CANON_TAG_0x004 = {
       
  1124     7: ('WhiteBalance',
       
  1125         {0: 'Auto',
       
  1126          1: 'Sunny',
       
  1127          2: 'Cloudy',
       
  1128          3: 'Tungsten',
       
  1129          4: 'Fluorescent',
       
  1130          5: 'Flash',
       
  1131          6: 'Custom'}),
       
  1132     9: ('SequenceNumber', ),
       
  1133     14: ('AFPointUsed', ),
       
  1134     15: ('FlashBias',
       
  1135          {0xFFC0: '-2 EV',
       
  1136           0xFFCC: '-1.67 EV',
       
  1137           0xFFD0: '-1.50 EV',
       
  1138           0xFFD4: '-1.33 EV',
       
  1139           0xFFE0: '-1 EV',
       
  1140           0xFFEC: '-0.67 EV',
       
  1141           0xFFF0: '-0.50 EV',
       
  1142           0xFFF4: '-0.33 EV',
       
  1143           0x0000: '0 EV',
       
  1144           0x000C: '0.33 EV',
       
  1145           0x0010: '0.50 EV',
       
  1146           0x0014: '0.67 EV',
       
  1147           0x0020: '1 EV',
       
  1148           0x002C: '1.33 EV',
       
  1149           0x0030: '1.50 EV',
       
  1150           0x0034: '1.67 EV',
       
  1151           0x0040: '2 EV'}),
       
  1152     19: ('SubjectDistance', ),
       
  1153     }
       
  1154 
       
  1155 # ratio object that eventually will be able to reduce itself to lowest
       
  1156 # common denominator for printing
       
  1157 def gcd(a, b):
       
  1158     if b == 0:
       
  1159         return a
       
  1160     else:
       
  1161         return gcd(b, a % b)
       
  1162 
       
  1163 class Ratio:
       
  1164     def __init__(self, num, den):
       
  1165         self.num = num
       
  1166         self.den = den
       
  1167 
       
  1168     def __repr__(self):
       
  1169         self.reduce()
       
  1170         if self.den == 1:
       
  1171             return str(self.num)
       
  1172         return '%d/%d' % (self.num, self.den)
       
  1173 
       
  1174     def reduce(self):
       
  1175         div = gcd(self.num, self.den)
       
  1176         if div > 1:
       
  1177             self.num = self.num / div
       
  1178             self.den = self.den / div
       
  1179 
       
  1180