Rolling back exif support to pre-3.0 format

This commit is contained in:
wiredfool 2016-01-01 04:08:44 -08:00
parent b84675dca0
commit a6c1331fdd
2 changed files with 51 additions and 5 deletions

View File

@ -394,6 +394,19 @@ class JpegImageFile(ImageFile.ImageFile):
return _getmp(self) return _getmp(self)
def _fixup_dict(src_dict):
# Helper function for _getexif()
# returns a dict with any single item tuples/lists as individual values
def _fixup(value):
try:
if len(value) == 1 and type(value) != type({}):
return value[0]
except: pass
return value
return dict([(k, _fixup(v)) for k, v in src_dict.items()])
def _getexif(self): def _getexif(self):
# Extract EXIF information. This method is highly experimental, # Extract EXIF information. This method is highly experimental,
# and is likely to be replaced with something better in a future # and is likely to be replaced with something better in a future
@ -408,9 +421,9 @@ def _getexif(self):
file = io.BytesIO(data[6:]) file = io.BytesIO(data[6:])
head = file.read(8) head = file.read(8)
# process dictionary # process dictionary
info = TiffImagePlugin.ImageFileDirectory_v2(head) info = TiffImagePlugin.ImageFileDirectory_v1(head)
info.load(file) info.load(file)
exif = dict(info) exif = dict(_fixup_dict(info))
# get exif extension # get exif extension
try: try:
# exif field 0x8769 is an offset pointer to the location # exif field 0x8769 is an offset pointer to the location
@ -420,9 +433,9 @@ def _getexif(self):
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
else: else:
info = TiffImagePlugin.ImageFileDirectory_v2(head) info = TiffImagePlugin.ImageFileDirectory_v1(head)
info.load(file) info.load(file)
exif.update(info) exif.update(_fixup_dict(info))
# get gpsinfo extension # get gpsinfo extension
try: try:
# exif field 0x8825 is an offset pointer to the location # exif field 0x8825 is an offset pointer to the location
@ -434,7 +447,8 @@ def _getexif(self):
else: else:
info = TiffImagePlugin.ImageFileDirectory_v1(head) info = TiffImagePlugin.ImageFileDirectory_v1(head)
info.load(file) info.load(file)
exif[0x8825] = dict([(k, v[0]) if len(v) == 1 else (k, v) for k, v in info.items()]) exif[0x8825] = _fixup_dict(info)
return exif return exif

View File

@ -188,6 +188,38 @@ class TestFileJpeg(PillowTestCase):
# Assert # Assert
self.assertEqual(exif[gps_index], expected_exif_gps) self.assertEqual(exif[gps_index], expected_exif_gps)
def test_exif_rollback(self):
# rolling back exif support in 3.1 to pre-3.0 formatting.
# expected from 2.9, with b/u qualifiers switched for 3.2 compatibility
# this test passes on 2.9 and 3.1, but not 3.0
expected_exif = {34867: 4294967295,
258: (24, 24, 24),
36867: '2099:09:29 10:10:10',
34853: {0: b'\x00\x00\x00\x01',
2: (4294967295, 1),
5: b'\x01',
30: 65535,
29: '1999:99:99 99:99:99'},
296: 65535,
34665: 185,
41994: 65535,
514: 4294967295,
271: 'Make',
272: 'XXX-XXX',
305: 'PIL',
42034: ((1, 1), (1, 1), (1, 1), (1, 1)),
42035: 'LensMake',
34856: b'\xaa\xaa\xaa\xaa\xaa\xaa',
282: (4294967295, 1),
33434: (4294967295, 1)}
im = Image.open('Tests/images/exif_gps.jpg')
exif = im._getexif()
for tag, value in expected_exif.items():
self.assertEqual(value, exif[tag])
def test_exif_gps_typeerror(self): def test_exif_gps_typeerror(self):
im = Image.open('Tests/images/exif_gps_typeerror.jpg') im = Image.open('Tests/images/exif_gps_typeerror.jpg')