home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.5)
-
- FIELD_TYPES = ((0, 'X', 'Proprietary'), (1, 'B', 'Byte'), (1, 'A', 'ASCII'), (2, 'S', 'Short'), (4, 'L', 'Long'), (8, 'R', 'Ratio'), (1, 'SB', 'Signed Byte'), (1, 'U', 'Undefined'), (2, 'SS', 'Signed Short'), (4, 'SL', 'Signed Long'), (8, 'SR', 'Signed Ratio'))
- EXIF_TAGS = {
- 256: ('ImageWidth',),
- 257: ('ImageLength',),
- 258: ('BitsPerSample',),
- 259: ('Compression', {
- 1: 'Uncompressed TIFF',
- 6: 'JPEG Compressed' }),
- 262: ('PhotometricInterpretation',),
- 266: ('FillOrder',),
- 269: ('DocumentName',),
- 270: ('ImageDescription',),
- 271: ('Make',),
- 272: ('Model',),
- 273: ('StripOffsets',),
- 274: ('Orientation',),
- 277: ('SamplesPerPixel',),
- 278: ('RowsPerStrip',),
- 279: ('StripByteCounts',),
- 282: ('XResolution',),
- 283: ('YResolution',),
- 284: ('PlanarConfiguration',),
- 296: ('ResolutionUnit', {
- 1: 'Not Absolute',
- 2: 'Pixels/Inch',
- 3: 'Pixels/Centimeter' }),
- 301: ('TransferFunction',),
- 305: ('Software',),
- 306: ('DateTime',),
- 315: ('Artist',),
- 318: ('WhitePoint',),
- 319: ('PrimaryChromaticities',),
- 342: ('TransferRange',),
- 512: ('JPEGProc',),
- 513: ('JPEGInterchangeFormat',),
- 514: ('JPEGInterchangeFormatLength',),
- 529: ('YCbCrCoefficients',),
- 530: ('YCbCrSubSampling',),
- 531: ('YCbCrPositioning',),
- 532: ('ReferenceBlackWhite',),
- 33421: ('CFARepeatPatternDim',),
- 33422: ('CFAPattern',),
- 33423: ('BatteryLevel',),
- 33432: ('Copyright',),
- 33434: ('ExposureTime',),
- 33437: ('FNumber',),
- 33723: ('IPTC/NAA',),
- 34665: ('ExifOffset',),
- 34675: ('InterColorProfile',),
- 34850: ('ExposureProgram', {
- 0: 'Unidentified',
- 1: 'Manual',
- 2: 'Program Normal',
- 3: 'Aperture Priority',
- 4: 'Shutter Priority',
- 5: 'Program Creative',
- 6: 'Program Action',
- 7: 'Portrait Mode',
- 8: 'Landscape Mode' }),
- 34852: ('SpectralSensitivity',),
- 34853: ('GPSInfo',),
- 34855: ('ISOSpeedRatings',),
- 34856: ('OECF',),
- 36864: ('ExifVersion', (lambda x: ''.join(map(chr, x)))),
- 36867: ('DateTimeOriginal',),
- 36868: ('DateTimeDigitized',),
- 37121: ('ComponentsConfiguration', {
- 0: '',
- 1: 'Y',
- 2: 'Cb',
- 3: 'Cr',
- 4: 'Red',
- 5: 'Green',
- 6: 'Blue' }),
- 37122: ('CompressedBitsPerPixel',),
- 37377: ('ShutterSpeedValue',),
- 37378: ('ApertureValue',),
- 37379: ('BrightnessValue',),
- 37380: ('ExposureBiasValue',),
- 37381: ('MaxApertureValue',),
- 37382: ('SubjectDistance',),
- 37383: ('MeteringMode', {
- 0: 'Unidentified',
- 1: 'Average',
- 2: 'CenterWeightedAverage',
- 3: 'Spot',
- 4: 'MultiSpot' }),
- 37384: ('LightSource', {
- 0: 'Unknown',
- 1: 'Daylight',
- 2: 'Fluorescent',
- 3: 'Tungsten',
- 10: 'Flash',
- 17: 'Standard Light A',
- 18: 'Standard Light B',
- 19: 'Standard Light C',
- 20: 'D55',
- 21: 'D65',
- 22: 'D75',
- 255: 'Other' }),
- 37385: ('Flash', {
- 0: 'No',
- 1: 'Fired',
- 5: 'Fired (?)',
- 7: 'Fired (!)',
- 9: 'Fill Fired',
- 13: 'Fill Fired (?)',
- 15: 'Fill Fired (!)',
- 16: 'Off',
- 24: 'Auto Off',
- 25: 'Auto Fired',
- 29: 'Auto Fired (?)',
- 31: 'Auto Fired (!)',
- 32: 'Not Available' }),
- 37386: ('FocalLength',),
- 37500: ('MakerNote',),
- 37510: ('UserComment', (lambda x: ''.join(map(chr, x)))),
- 37520: ('SubSecTime',),
- 37521: ('SubSecTimeOriginal',),
- 37522: ('SubSecTimeDigitized',),
- 40960: ('FlashPixVersion', (lambda x: ''.join(map(chr, x)))),
- 40961: ('ColorSpace',),
- 40962: ('ExifImageWidth',),
- 40963: ('ExifImageLength',),
- 40965: ('InteroperabilityOffset',),
- 41483: ('FlashEnergy',),
- 41484: ('SpatialFrequencyResponse',),
- 41486: ('FocalPlaneXResolution',),
- 41487: ('FocalPlaneYResolution',),
- 41488: ('FocalPlaneResolutionUnit',),
- 41492: ('SubjectLocation',),
- 41493: ('ExposureIndex',),
- 41495: ('SensingMethod',),
- 41728: ('FileSource', {
- 3: 'Digital Camera' }),
- 41729: ('SceneType', {
- 1: 'Directly Photographed' }) }
- INTR_TAGS = {
- 1: ('InteroperabilityIndex',),
- 2: ('InteroperabilityVersion',),
- 4096: ('RelatedImageFileFormat',),
- 4097: ('RelatedImageWidth',),
- 4098: ('RelatedImageLength',) }
- GPS_TAGS = {
- 0: ('GPSVersionID',),
- 1: ('GPSLatitudeRef',),
- 2: ('GPSLatitude',),
- 3: ('GPSLongitudeRef',),
- 4: ('GPSLongitude',),
- 5: ('GPSAltitudeRef',),
- 6: ('GPSAltitude',),
- 7: ('GPSTimeStamp',),
- 8: ('GPSSatellites',),
- 9: ('GPSStatus',),
- 10: ('GPSMeasureMode',),
- 11: ('GPSDOP',),
- 12: ('GPSSpeedRef',),
- 13: ('GPSSpeed',),
- 14: ('GPSTrackRef',),
- 15: ('GPSTrack',),
- 16: ('GPSImgDirectionRef',),
- 17: ('GPSImgDirection',),
- 18: ('GPSMapDatum',),
- 19: ('GPSDestLatitudeRef',),
- 20: ('GPSDestLatitude',),
- 21: ('GPSDestLongitudeRef',),
- 22: ('GPSDestLongitude',),
- 23: ('GPSDestBearingRef',),
- 24: ('GPSDestBearing',),
- 25: ('GPSDestDistanceRef',),
- 26: ('GPSDestDistance',) }
- MAKERNOTE_NIKON_NEWER_TAGS = {
- 2: ('ISOSetting',),
- 3: ('ColorMode',),
- 4: ('Quality',),
- 5: ('Whitebalance',),
- 6: ('ImageSharpening',),
- 7: ('FocusMode',),
- 8: ('FlashSetting',),
- 15: ('ISOSelection',),
- 128: ('ImageAdjustment',),
- 130: ('AuxiliaryLens',),
- 133: ('ManualFocusDistance',),
- 134: ('DigitalZoomFactor',),
- 136: ('AFFocusPosition', {
- 0: 'Center',
- 256: 'Top',
- 512: 'Bottom',
- 768: 'Left',
- 1024: 'Right' }),
- 148: ('Saturation', {
- -3: 'B&W',
- -2: '-2',
- -1: '-1',
- 0: '0',
- 1: '1',
- 2: '2' }),
- 149: ('NoiseReduction',),
- 16: ('DataDump',) }
- MAKERNOTE_NIKON_OLDER_TAGS = {
- 3: ('Quality', {
- 1: 'VGA Basic',
- 2: 'VGA Normal',
- 3: 'VGA Fine',
- 4: 'SXGA Basic',
- 5: 'SXGA Normal',
- 6: 'SXGA Fine' }),
- 4: ('ColorMode', {
- 1: 'Color',
- 2: 'Monochrome' }),
- 5: ('ImageAdjustment', {
- 0: 'Normal',
- 1: 'Bright+',
- 2: 'Bright-',
- 3: 'Contrast+',
- 4: 'Contrast-' }),
- 6: ('CCDSpeed', {
- 0: 'ISO 80',
- 2: 'ISO 160',
- 4: 'ISO 320',
- 5: 'ISO 100' }),
- 7: ('WhiteBalance', {
- 0: 'Auto',
- 1: 'Preset',
- 2: 'Daylight',
- 3: 'Incandescent',
- 4: 'Fluorescent',
- 5: 'Cloudy',
- 6: 'Speed Light' }) }
-
- def olympus_special_mode(v):
- a = {
- 0: 'Normal',
- 1: 'Unknown',
- 2: 'Fast',
- 3: 'Panorama' }
- b = {
- 0: 'Non-panoramic',
- 1: 'Left to right',
- 2: 'Right to left',
- 3: 'Bottom to top',
- 4: 'Top to bottom' }
- return '%s - sequence %d - %s' % (a[v[0]], v[1], b[v[2]])
-
- MAKERNOTE_OLYMPUS_TAGS = {
- 256: ('JPEGThumbnail',),
- 512: ('SpecialMode', olympus_special_mode),
- 513: ('JPEGQual', {
- 1: 'SQ',
- 2: 'HQ',
- 3: 'SHQ' }),
- 514: ('Macro', {
- 0: 'Normal',
- 1: 'Macro' }),
- 516: ('DigitalZoom',),
- 519: ('SoftwareRelease',),
- 520: ('PictureInfo',),
- 521: ('CameraID', (lambda x: ''.join(map(chr, x)))),
- 3840: ('DataDump',) }
- MAKERNOTE_CASIO_TAGS = {
- 1: ('RecordingMode', {
- 1: 'Single Shutter',
- 2: 'Panorama',
- 3: 'Night Scene',
- 4: 'Portrait',
- 5: 'Landscape' }),
- 2: ('Quality', {
- 1: 'Economy',
- 2: 'Normal',
- 3: 'Fine' }),
- 3: ('FocusingMode', {
- 2: 'Macro',
- 3: 'Auto Focus',
- 4: 'Manual Focus',
- 5: 'Infinity' }),
- 4: ('FlashMode', {
- 1: 'Auto',
- 2: 'On',
- 3: 'Off',
- 4: 'Red Eye Reduction' }),
- 5: ('FlashIntensity', {
- 11: 'Weak',
- 13: 'Normal',
- 15: 'Strong' }),
- 6: ('Object Distance',),
- 7: ('WhiteBalance', {
- 1: 'Auto',
- 2: 'Tungsten',
- 3: 'Daylight',
- 4: 'Fluorescent',
- 5: 'Shade',
- 129: 'Manual' }),
- 11: ('Sharpness', {
- 0: 'Normal',
- 1: 'Soft',
- 2: 'Hard' }),
- 12: ('Contrast', {
- 0: 'Normal',
- 1: 'Low',
- 2: 'High' }),
- 13: ('Saturation', {
- 0: 'Normal',
- 1: 'Low',
- 2: 'High' }),
- 20: ('CCDSpeed', {
- 64: 'Normal',
- 80: 'Normal',
- 100: 'High',
- 125: '+1.0',
- 244: '+3.0',
- 250: '+2.0' }) }
- MAKERNOTE_FUJIFILM_TAGS = {
- 0: ('NoteVersion', (lambda x: ''.join(map(chr, x)))),
- 4096: ('Quality',),
- 4097: ('Sharpness', {
- 1: 'Soft',
- 2: 'Soft',
- 3: 'Normal',
- 4: 'Hard',
- 5: 'Hard' }),
- 4098: ('WhiteBalance', {
- 0: 'Auto',
- 256: 'Daylight',
- 512: 'Cloudy',
- 768: 'DaylightColor-Fluorescent',
- 769: 'DaywhiteColor-Fluorescent',
- 770: 'White-Fluorescent',
- 1024: 'Incandescent',
- 3840: 'Custom' }),
- 4099: ('Color', {
- 0: 'Normal',
- 256: 'High',
- 512: 'Low' }),
- 4100: ('Tone', {
- 0: 'Normal',
- 256: 'High',
- 512: 'Low' }),
- 4112: ('FlashMode', {
- 0: 'Auto',
- 1: 'On',
- 2: 'Off',
- 3: 'Red Eye Reduction' }),
- 4113: ('FlashStrength',),
- 4128: ('Macro', {
- 0: 'Off',
- 1: 'On' }),
- 4129: ('FocusMode', {
- 0: 'Auto',
- 1: 'Manual' }),
- 4144: ('SlowSync', {
- 0: 'Off',
- 1: 'On' }),
- 4145: ('PictureMode', {
- 0: 'Auto',
- 1: 'Portrait',
- 2: 'Landscape',
- 4: 'Sports',
- 5: 'Night',
- 6: 'Program AE',
- 256: 'Aperture Priority AE',
- 512: 'Shutter Priority AE',
- 768: 'Manual Exposure' }),
- 4352: ('MotorOrBracket', {
- 0: 'Off',
- 1: 'On' }),
- 4864: ('BlurWarning', {
- 0: 'Off',
- 1: 'On' }),
- 4865: ('FocusWarning', {
- 0: 'Off',
- 1: 'On' }),
- 4866: ('AEWarning', {
- 0: 'Off',
- 1: 'On' }) }
- MAKERNOTE_CANON_TAGS = {
- 6: ('ImageType',),
- 7: ('FirmwareVersion',),
- 8: ('ImageNumber',),
- 9: ('OwnerName',) }
- MAKERNOTE_CANON_TAG_0x001 = {
- 1: ('Macromode', {
- 1: 'Macro',
- 2: 'Normal' }),
- 2: ('SelfTimer',),
- 3: ('Quality', {
- 2: 'Normal',
- 3: 'Fine',
- 5: 'Superfine' }),
- 4: ('FlashMode', {
- 0: 'Flash Not Fired',
- 1: 'Auto',
- 2: 'On',
- 3: 'Red-Eye Reduction',
- 4: 'Slow Synchro',
- 5: 'Auto + Red-Eye Reduction',
- 6: 'On + Red-Eye Reduction',
- 16: 'external flash' }),
- 5: ('ContinuousDriveMode', {
- 0: 'Single Or Timer',
- 1: 'Continuous' }),
- 7: ('FocusMode', {
- 0: 'One-Shot',
- 1: 'AI Servo',
- 2: 'AI Focus',
- 3: 'MF',
- 4: 'Single',
- 5: 'Continuous',
- 6: 'MF' }),
- 10: ('ImageSize', {
- 0: 'Large',
- 1: 'Medium',
- 2: 'Small' }),
- 11: ('EasyShootingMode', {
- 0: 'Full Auto',
- 1: 'Manual',
- 2: 'Landscape',
- 3: 'Fast Shutter',
- 4: 'Slow Shutter',
- 5: 'Night',
- 6: 'B&W',
- 7: 'Sepia',
- 8: 'Portrait',
- 9: 'Sports',
- 10: 'Macro/Close-Up',
- 11: 'Pan Focus' }),
- 12: ('DigitalZoom', {
- 0: 'None',
- 1: '2x',
- 2: '4x' }),
- 13: ('Contrast', {
- 65535: 'Low',
- 0: 'Normal',
- 1: 'High' }),
- 14: ('Saturation', {
- 65535: 'Low',
- 0: 'Normal',
- 1: 'High' }),
- 15: ('Sharpness', {
- 65535: 'Low',
- 0: 'Normal',
- 1: 'High' }),
- 16: ('ISO', {
- 0: 'See ISOSpeedRatings Tag',
- 15: 'Auto',
- 16: '50',
- 17: '100',
- 18: '200',
- 19: '400' }),
- 17: ('MeteringMode', {
- 3: 'Evaluative',
- 4: 'Partial',
- 5: 'Center-weighted' }),
- 18: ('FocusType', {
- 0: 'Manual',
- 1: 'Auto',
- 3: 'Close-Up (Macro)',
- 8: 'Locked (Pan Mode)' }),
- 19: ('AFPointSelected', {
- 12288: 'None (MF)',
- 12289: 'Auto-Selected',
- 12290: 'Right',
- 12291: 'Center',
- 12292: 'Left' }),
- 20: ('ExposureMode', {
- 0: 'Easy Shooting',
- 1: 'Program',
- 2: 'Tv-priority',
- 3: 'Av-priority',
- 4: 'Manual',
- 5: 'A-DEP' }),
- 23: ('LongFocalLengthOfLensInFocalUnits',),
- 24: ('ShortFocalLengthOfLensInFocalUnits',),
- 25: ('FocalUnitsPerMM',),
- 28: ('FlashActivity', {
- 0: 'Did Not Fire',
- 1: 'Fired' }),
- 29: ('FlashDetails', {
- 14: 'External E-TTL',
- 13: 'Internal Flash',
- 11: 'FP Sync Used',
- 7: '2nd("Rear")-Curtain Sync Used',
- 4: 'FP Sync Enabled' }),
- 32: ('FocusMode', {
- 0: 'Single',
- 1: 'Continuous' }) }
- MAKERNOTE_CANON_TAG_0x004 = {
- 7: ('WhiteBalance', {
- 0: 'Auto',
- 1: 'Sunny',
- 2: 'Cloudy',
- 3: 'Tungsten',
- 4: 'Fluorescent',
- 5: 'Flash',
- 6: 'Custom' }),
- 9: ('SequenceNumber',),
- 14: ('AFPointUsed',),
- 15: ('FlashBias', {
- 65472: '-2 EV',
- 65484: '-1.67 EV',
- 65488: '-1.50 EV',
- 65492: '-1.33 EV',
- 65504: '-1 EV',
- 65516: '-0.67 EV',
- 65520: '-0.50 EV',
- 65524: '-0.33 EV',
- 0: '0 EV',
- 12: '0.33 EV',
- 16: '0.50 EV',
- 20: '0.67 EV',
- 32: '1 EV',
- 44: '1.33 EV',
- 48: '1.50 EV',
- 52: '1.67 EV',
- 64: '2 EV' }),
- 19: ('SubjectDistance',) }
-
- def s2n_motorola(str):
- x = 0
- for c in str:
- x = x << 8 | ord(c)
-
- return x
-
-
- def s2n_intel(str):
- x = 0
- y = 0x0L
- for c in str:
- x = x | ord(c) << y
- y = y + 8
-
- return x
-
-
- def gcd(a, b):
- if b == 0:
- return a
- else:
- return gcd(b, a % b)
-
-
- class Ratio:
-
- def __init__(self, num, den):
- self.num = num
- self.den = den
-
-
- def __repr__(self):
- self.reduce()
- if self.den == 1:
- return str(self.num)
-
- return '%d/%d' % (self.num, self.den)
-
-
- def reduce(self):
- div = gcd(self.num, self.den)
- if div > 1:
- self.num = self.num / div
- self.den = self.den / div
-
-
-
-
- class IFD_Tag:
-
- def __init__(self, printable, tag, field_type, values, field_offset, field_length):
- self.printable = printable
- self.tag = tag
- self.field_type = field_type
- self.field_offset = field_offset
- self.field_length = field_length
- self.values = values
-
-
- def __str__(self):
- return self.printable
-
-
- def __repr__(self):
- return '(0x%04X) %s=%s @ %d' % (self.tag, FIELD_TYPES[self.field_type][2], self.printable, self.field_offset)
-
-
-
- class EXIF_header:
-
- def __init__(self, file, endian, offset, debug = 0):
- self.file = file
- self.endian = endian
- self.offset = offset
- self.debug = debug
- self.tags = { }
-
-
- def s2n(self, offset, length, signed = 0):
- self.file.seek(self.offset + offset)
- slice = self.file.read(length)
- if self.endian == 'I':
- val = s2n_intel(slice)
- else:
- val = s2n_motorola(slice)
- if signed:
- pass
-
- return val
-
-
- def n2s(self, offset, length):
- s = ''
- for i in range(length):
- if self.endian == 'I':
- s = s + chr(offset & 255)
- else:
- s = chr(offset & 255) + s
- offset = offset >> 8
-
- return s
-
-
- def first_IFD(self):
- return self.s2n(4, 4)
-
-
- def next_IFD(self, ifd):
- entries = self.s2n(ifd, 2)
- return self.s2n(ifd + 2 + 12 * entries, 4)
-
-
- def list_IFDs(self):
- i = self.first_IFD()
- a = []
- while i:
- a.append(i)
- i = self.next_IFD(i)
- return a
-
-
- def dump_IFD(self, ifd, ifd_name, dict = EXIF_TAGS):
- entries = self.s2n(ifd, 2)
- for i in range(entries):
- entry = ifd + 2 + 12 * i
- tag = self.s2n(entry, 2)
- field_type = self.s2n(entry + 2, 2)
- if field_type < field_type:
- pass
- elif not field_type < len(FIELD_TYPES):
- raise ValueError, 'unknown type %d in tag 0x%04X' % (field_type, tag)
-
- typelen = FIELD_TYPES[field_type][0]
- count = self.s2n(entry + 4, 4)
- offset = entry + 8
- if count * typelen > 4:
- offset = self.s2n(offset, 4)
-
- field_offset = offset
- if field_type == 2:
- if count != 0:
- self.file.seek(self.offset + offset)
- values = self.file.read(count).strip().replace('\x00', '')
- else:
- values = ''
- else:
- values = []
- signed = field_type in (6, 8, 9, 10)
- for j in range(count):
- if field_type in (5, 10):
- value_j = Ratio(self.s2n(offset, 4, signed), self.s2n(offset + 4, 4, signed))
- else:
- value_j = self.s2n(offset, typelen, signed)
- values.append(value_j)
- offset = offset + typelen
-
- if count == 1 and field_type != 2:
- printable = str(values[0])
- else:
- printable = str(values)
- tag_entry = dict.get(tag)
- if tag_entry:
- tag_name = tag_entry[0]
- if len(tag_entry) != 1:
- if callable(tag_entry[1]):
- printable = tag_entry[1](values)
- else:
- printable = ''
- for i in values:
- printable += tag_entry[1].get(i, repr(i))
-
-
- else:
- tag_name = 'Tag 0x%04X' % tag
- self.tags[ifd_name + ' ' + tag_name] = IFD_Tag(printable, tag, field_type, values, field_offset, count * typelen)
- if self.debug:
- print ' %s: %s' % (tag_name, repr(self.tags[ifd_name + ' ' + tag_name]))
- continue
-
-
-
- def extract_TIFF_thumbnail(self, thumb_ifd):
- entries = self.s2n(thumb_ifd, 2)
- if self.endian == 'M':
- tiff = 'MM\x00*\x00\x00\x00\x08'
- else:
- tiff = 'II*\x00\x08\x00\x00\x00'
- self.file.seek(self.offset + thumb_ifd)
- tiff += self.file.read(entries * 12 + 2) + '\x00\x00\x00\x00'
- for i in range(entries):
- entry = thumb_ifd + 2 + 12 * i
- tag = self.s2n(entry, 2)
- field_type = self.s2n(entry + 2, 2)
- typelen = FIELD_TYPES[field_type][0]
- count = self.s2n(entry + 4, 4)
- oldoff = self.s2n(entry + 8, 4)
- ptr = i * 12 + 18
- if tag == 273:
- strip_off = ptr
- strip_len = count * typelen
-
- if count * typelen > 4:
- newoff = len(tiff)
- tiff = tiff[:ptr] + self.n2s(newoff, 4) + tiff[ptr + 4:]
- if tag == 273:
- strip_off = newoff
- strip_len = 4
-
- self.file.seek(self.offset + oldoff)
- tiff += self.file.read(count * typelen)
- continue
-
- old_offsets = self.tags['Thumbnail StripOffsets'].values
- old_counts = self.tags['Thumbnail StripByteCounts'].values
- for i in range(len(old_offsets)):
- offset = self.n2s(len(tiff), strip_len)
- tiff = tiff[:strip_off] + offset + tiff[strip_off + strip_len:]
- strip_off += strip_len
- self.file.seek(self.offset + old_offsets[i])
- tiff += self.file.read(old_counts[i])
-
- self.tags['TIFFThumbnail'] = tiff
-
-
- def decode_maker_note(self):
- note = self.tags['EXIF MakerNote']
- make = self.tags['Image Make'].printable
- model = self.tags['Image Model'].printable
- if make == 'NIKON':
- if note.values[0:5] == [
- 78,
- 105,
- 107,
- 111,
- 110]:
- self.dump_IFD(note.field_offset + 8, 'MakerNote', dict = MAKERNOTE_NIKON_OLDER_TAGS)
- else:
- self.dump_IFD(note.field_offset, 'MakerNote', dict = MAKERNOTE_NIKON_NEWER_TAGS)
- return None
-
- if make[:7] == 'OLYMPUS':
- self.dump_IFD(note.field_offset + 8, 'MakerNote', dict = MAKERNOTE_OLYMPUS_TAGS)
- return None
-
- if make == 'Casio':
- self.dump_IFD(note.field_offset, 'MakerNote', dict = MAKERNOTE_CASIO_TAGS)
- return None
-
- if make == 'FUJIFILM':
- endian = self.endian
- self.endian = 'I'
- offset = self.offset
- self.offset += note.field_offset
- self.dump_IFD(12, 'MakerNote', dict = MAKERNOTE_FUJIFILM_TAGS)
- self.endian = endian
- self.offset = offset
- return None
-
- if make == 'Canon':
- self.dump_IFD(note.field_offset, 'MakerNote', dict = MAKERNOTE_CANON_TAGS)
- for i in (('MakerNote Tag 0x0001', MAKERNOTE_CANON_TAG_0x001), ('MakerNote Tag 0x0004', MAKERNOTE_CANON_TAG_0x004)):
- self.canon_decode_tag(self.tags[i[0]].values, i[1])
-
- return None
-
-
-
- def canon_decode_tag(self, value, dict):
- for i in range(1, len(value)):
- x = dict.get(i, ('Unknown',))
- if self.debug:
- print i, x
-
- name = x[0]
- if len(x) > 1:
- val = x[1].get(value[i], 'Unknown')
- else:
- val = value[i]
- self.tags['MakerNote ' + name] = IFD_Tag(str(val), None, 0, None, None, None)
-
-
-
-
- def process_file(file, debug = 0):
- data = file.read(12)
- if data[0:4] in ('II*\x00', 'MM\x00*'):
- file.seek(0)
- endian = file.read(1)
- file.read(1)
- offset = 0
- elif data[0:2] == '\xff\xd8':
- while data[2] == '\xff' and data[6:10] in ('JFIF', 'JFXX', 'OLYM'):
- length = ord(data[4]) * 256 + ord(data[5])
- file.read(length - 8)
- data = '\xff\x00' + file.read(10)
- if data[2] == '\xff' and data[6:10] == 'Exif':
- offset = file.tell()
- endian = file.read(1)
- else:
- return { }
- else:
- return { }
- if debug:
- print {
- 'I': 'Intel',
- 'M': 'Motorola' }[endian], 'format'
-
- hdr = EXIF_header(file, endian, offset, debug)
- ifd_list = hdr.list_IFDs()
- ctr = 0
- for i in ifd_list:
- if ctr == 0:
- IFD_name = 'Image'
- elif ctr == 1:
- IFD_name = 'Thumbnail'
- thumb_ifd = i
- else:
- IFD_name = 'IFD %d' % ctr
- if debug:
- print ' IFD %d (%s) at offset %d:' % (ctr, IFD_name, i)
-
- hdr.dump_IFD(i, IFD_name)
- exif_off = hdr.tags.get(IFD_name + ' ExifOffset')
- if exif_off:
- if debug:
- print ' EXIF SubIFD at offset %d:' % exif_off.values[0]
-
- hdr.dump_IFD(exif_off.values[0], 'EXIF')
- intr_off = hdr.tags.get('EXIF SubIFD InteroperabilityOffset')
- if intr_off:
- if debug:
- print ' EXIF Interoperability SubSubIFD at offset %d:' % intr_off.values[0]
-
- hdr.dump_IFD(intr_off.values[0], 'EXIF Interoperability', dict = INTR_TAGS)
-
-
- gps_off = hdr.tags.get(IFD_name + ' GPSInfo')
- if gps_off:
- if debug:
- print ' GPS SubIFD at offset %d:' % gps_off.values[0]
-
- hdr.dump_IFD(gps_off.values[0], 'GPS', dict = GPS_TAGS)
-
- ctr += 1
-
- thumb = hdr.tags.get('Thumbnail Compression')
- if thumb and thumb.printable == 'Uncompressed TIFF':
- hdr.extract_TIFF_thumbnail(thumb_ifd)
-
- thumb_off = hdr.tags.get('Thumbnail JPEGInterchangeFormat')
- if thumb_off:
- file.seek(offset + thumb_off.values[0])
- size = hdr.tags['Thumbnail JPEGInterchangeFormatLength'].values[0]
- hdr.tags['JPEGThumbnail'] = file.read(size)
-
- if hdr.tags.has_key('EXIF MakerNote'):
- hdr.decode_maker_note()
-
- if not hdr.tags.has_key('JPEGThumbnail'):
- thumb_off = hdr.tags.get('MakerNote JPEGThumbnail')
- if thumb_off:
- file.seek(offset + thumb_off.values[0])
- hdr.tags['JPEGThumbnail'] = file.read(thumb_off.field_length)
-
-
- return hdr.tags
-
- if __name__ == '__main__':
- import sys
- if len(sys.argv) < 2:
- print 'Usage: %s files...\n' % sys.argv[0]
- sys.exit(0)
-
- for filename in sys.argv[1:]:
-
- try:
- file = open(filename, 'rb')
- except:
- print filename, 'unreadable'
- print
- continue
-
- print filename + ':'
- data = process_file(file)
- if not data:
- print 'No EXIF information found'
- continue
-
- x = data.keys()
- x.sort()
- for i in x:
- if i in ('JPEGThumbnail', 'TIFFThumbnail'):
- continue
-
-
- try:
- print ' %s (%s): %s' % (i, FIELD_TYPES[data[i].field_type][2], data[i].printable)
- continue
- print 'error', i, '"', data[i], '"'
- continue
-
-
- if data.has_key('JPEGThumbnail'):
- print 'File has JPEG thumbnail'
-
- print
-
-
-