Skip to content

Commit

Permalink
Merge 8e046c0 into 3d6e137
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jan 25, 2016
2 parents 3d6e137 + 8e046c0 commit eff632f
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 108 deletions.
5 changes: 2 additions & 3 deletions PIL/DdsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def _open(self):
if len(header_bytes) != 120:
raise IOError("Incomplete header: %s bytes" % len(header_bytes))
header = BytesIO(header_bytes)

flags, height, width = struct.unpack("<3I", header.read(12))
self.size = (width, height)
self.mode = "RGBA"
Expand Down Expand Up @@ -253,9 +253,8 @@ def _open(self):
raise IOError("Truncated DDS file")
finally:
self.fp.close()

self.fp = BytesIO(decoded_data)

self.fp = BytesIO(decoded_data)

def load_seek(self, pos):
pass
Expand Down
2 changes: 1 addition & 1 deletion PIL/JpegImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ def _getexif(self):
info = TiffImagePlugin.ImageFileDirectory_v1(head)
info.load(file)
exif[0x8825] = _fixup_dict(info)

return exif


Expand Down
29 changes: 14 additions & 15 deletions PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
import sys
import warnings

from .TiffTags import TYPES, TagInfo
from .TiffTags import TYPES


__version__ = "1.3.5"
Expand Down Expand Up @@ -227,6 +227,7 @@ def _limit_rational(val, max_val):
_load_dispatch = {}
_write_dispatch = {}


class IFDRational(Rational):
""" Implements a rational class where 0/0 is a legal value to match
the in the wild use of exif rationals.
Expand All @@ -238,8 +239,8 @@ class IFDRational(Rational):
as a fractions.Fraction(). Delegate as appropriate
"""
__slots__ = ('_numerator', '_denominator', '_val')

__slots__ = ('_numerator', '_denominator', '_val')

def __init__(self, value, denominator=1):
"""
Expand All @@ -255,7 +256,7 @@ def __init__(self, value, denominator=1):
self._numerator = value.numerator
self._denominator = value.denominator
self._val = value

if type(value) == IFDRational:
self._denominator = value.denominator
self._numerator = value.numerator
Expand All @@ -266,7 +267,6 @@ def __init__(self, value, denominator=1):
self._val = float('nan')
return


elif denominator == 1:
if sys.hexversion < 0x2070000 and type(value) == float:
# python 2.6 is different.
Expand All @@ -284,10 +284,9 @@ def numerator(a):
def denominator(a):
return a._denominator


def limit_rational(self, max_denominator):
"""
:param max_denominator: Integer, the maximum denominator value
:returns: Tuple of (numerator, denominator)
"""
Expand All @@ -304,12 +303,12 @@ def __repr__(self):
def __hash__(self):
return self._val.__hash__()

def __eq__(self,other):
def __eq__(self, other):
return self._val == other

def _delegate(op):
def delegate(self, *args):
return getattr(self._val,op)(*args)
return getattr(self._val, op)(*args)
return delegate

""" a = ['add','radd', 'sub', 'rsub','div', 'rdiv', 'mul', 'rmul',
Expand Down Expand Up @@ -349,7 +348,6 @@ def delegate(self, *args):
__floor__ = _delegate('__floor__')
__round__ = _delegate('__round__')



class ImageFileDirectory_v2(collections.MutableMapping):
"""This class represents a TIFF tag directory. To speed things up, we
Expand Down Expand Up @@ -1121,8 +1119,8 @@ def _setup(self):

self.info["compression"] = self._compression

xres = self.tag_v2.get(X_RESOLUTION,1)
yres = self.tag_v2.get(Y_RESOLUTION,1)
xres = self.tag_v2.get(X_RESOLUTION, 1)
yres = self.tag_v2.get(Y_RESOLUTION, 1)

if xres and yres:
resunit = self.tag_v2.get(RESOLUTION_UNIT, 1)
Expand Down Expand Up @@ -1411,14 +1409,15 @@ def _save(im, fp, filename):
if hasattr(im, 'tag'):
legacy_ifd = im.tag.to_v2()
for tag, value in itertools.chain(ifd.items(),
getattr(im, 'tag_v2', {}).items(),
legacy_ifd.items()):
getattr(im, 'tag_v2', {}).items(),
legacy_ifd.items()):
# Libtiff can only process certain core items without adding
# them to the custom dictionary. It will segfault if it attempts
# to add a custom tag without the dictionary entry
#
# UNDONE -- add code for the custom dictionary
if tag not in TiffTags.LIBTIFF_CORE: continue
if tag not in TiffTags.LIBTIFF_CORE:
continue
if tag not in atts and tag not in blocklist:
if isinstance(value, unicode if bytes is str else str):
atts[tag] = value.encode('ascii', 'replace') + b"\0"
Expand Down
39 changes: 20 additions & 19 deletions PIL/TiffTags.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ def __new__(cls, value=None, name="unknown", type=None, length=0, enum=None):
def cvt_enum(self, value):
return self.enum.get(value, value)


def lookup(tag):
"""
:param tag: Integer tag number
:returns: Taginfo namedtuple, From the TAGS_V2 info if possible,
otherwise just populating the value and name from TAGS.
If the tag is not recognized, "unknown" is returned for the name
"""

return TAGS_V2.get(tag, TagInfo(tag, TAGS.get(tag, 'unknown')))


Expand Down Expand Up @@ -336,7 +337,7 @@ def _populate():
# These tags are handled by default in libtiff, without
# adding to the custom dictionary. From tif_dir.c, searching for
# case TIFFTAG in the _TIFFVSetField function:
# Line: item.
# Line: item.
# 148: case TIFFTAG_SUBFILETYPE:
# 151: case TIFFTAG_IMAGEWIDTH:
# 154: case TIFFTAG_IMAGELENGTH:
Expand Down Expand Up @@ -378,22 +379,22 @@ def _populate():

# some of these are not in our TAGS_V2 dict and were included from tiff.h

LIBTIFF_CORE = set ([255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
32996, 339, 32997, 330, 531, 530, 301, 532, 333,
# as above
269 # this has been in our tests forever, and works
])

LIBTIFF_CORE.remove(320) # Array of short, crashes
LIBTIFF_CORE.remove(301) # Array of short, crashes
LIBTIFF_CORE.remove(532) # Array of long, crashes

LIBTIFF_CORE.remove(255) # We don't have support for subfiletypes
LIBTIFF_CORE.remove(322) # We don't have support for tiled images in libtiff
LIBTIFF_CORE.remove(323) # Tiled images
LIBTIFF_CORE.remove(333) # Ink Names either
LIBTIFF_CORE = set([255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
32996, 339, 32997, 330, 531, 530, 301, 532, 333,
# as above
269 # this has been in our tests forever, and works
])

LIBTIFF_CORE.remove(320) # Array of short, crashes
LIBTIFF_CORE.remove(301) # Array of short, crashes
LIBTIFF_CORE.remove(532) # Array of long, crashes

LIBTIFF_CORE.remove(255) # We don't have support for subfiletypes
LIBTIFF_CORE.remove(322) # We don't have support for tiled images in libtiff
LIBTIFF_CORE.remove(323) # Tiled images
LIBTIFF_CORE.remove(333) # Ink Names either

# Note to advanced users: There may be combinations of these
# parameters and values that when added properly, will work and
Expand Down
12 changes: 6 additions & 6 deletions Tests/test_file_dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def test_sanity_dxt1(self):

im = Image.open(TEST_FILE_DXT1)
im.load()

self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))

# This target image is from the test set of images, and is exact.
# This target image is from the test set of images, and is exact.
self.assert_image_equal(target.convert('RGBA'), im)

def test_sanity_dxt5(self):
Expand All @@ -42,7 +42,7 @@ def test_sanity_dxt5(self):
# a little brighter. The 0,0 pixel is (00,6c,f8,ff) by our code,
# and by the target image for the DXT1, and the imagemagick .png
# is giving (00, 6d, ff, ff). So, assert similar, pretty tight
# I'm currently seeing about a 3 for the epsilon.
# I'm currently seeing about a 3 for the epsilon.
self.assert_image_similar(target, im, 5)

def test_sanity_dxt3(self):
Expand Down Expand Up @@ -78,18 +78,18 @@ def test_short_header(self):
img_file = f.read()

def short_header():
im = Image.open(BytesIO(img_file[:119]))
Image.open(BytesIO(img_file[:119]))

self.assertRaises(IOError, short_header)

def test_short_file(self):
""" Check that the appropriate error is thrown for a short file"""

with open(TEST_FILE_DXT5, 'rb') as f:
img_file = f.read()

def short_file():
im = Image.open(BytesIO(img_file[:-100]))
Image.open(BytesIO(img_file[:-100]))

self.assertRaises(IOError, short_file)

Expand Down
37 changes: 18 additions & 19 deletions Tests/test_file_jpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,34 +191,33 @@ def test_exif_gps(self):
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
# 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,
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),
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):
im = Image.open('Tests/images/exif_gps_typeerror.jpg')
Expand Down
27 changes: 12 additions & 15 deletions Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,20 @@ def test_additional_metadata(self):
# these should not crash. Seriously dummy data, most of it doesn't make
# any sense, so we're running up against limits where we're asking
# libtiff to do stupid things.

# Get the list of the ones that we should be able to write

core_items = dict((tag, info) for tag, info in [(s,TiffTags.lookup(s)) for s
core_items = dict((tag, info) for tag, info in [(s, TiffTags.lookup(s)) for s
in TiffTags.LIBTIFF_CORE]
if info.type is not None)

# Exclude ones that have special meaning that we're already testing them
im = Image.open('Tests/images/hopper_g4.tif')
for tag in im.tag_v2.keys():
try:
del(core_items[tag])
except: pass
except:
pass

# Type codes:
# 2: "ascii",
Expand All @@ -197,12 +198,11 @@ def test_additional_metadata(self):
# 5: "rational",
# 12: "double",
# type: dummy value
values = { 2: 'test',
3: 1,
4: 2**20,
5: TiffImagePlugin.IFDRational(100,1),
12: 1.05 }

values = {2: 'test',
3: 1,
4: 2**20,
5: TiffImagePlugin.IFDRational(100, 1),
12: 1.05}

new_ifd = TiffImagePlugin.ImageFileDirectory_v2()
for tag, info in core_items.items():
Expand All @@ -213,17 +213,15 @@ def test_additional_metadata(self):
else:
new_ifd[tag] = tuple(values[info.type] for _ in range(info.length))

# Extra samples really doesn't make sense in this application.
# Extra samples really doesn't make sense in this application.
del(new_ifd[338])

out = self.tempfile("temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True

im.save(out, tiffinfo=new_ifd)

TiffImagePlugin.WRITE_LIBTIFF = False


TiffImagePlugin.WRITE_LIBTIFF = False

def test_g3_compression(self):
i = Image.open('Tests/images/hopper_g4_500.tif')
Expand Down Expand Up @@ -459,7 +457,6 @@ def test_crashing_metadata(self):
TiffImagePlugin.WRITE_LIBTIFF = False



if __name__ == '__main__':
unittest.main()

Expand Down
2 changes: 1 addition & 1 deletion Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_xyres_tiff(self):
self.assertIsInstance(im.tag[X_RESOLUTION][0], tuple)
self.assertIsInstance(im.tag[Y_RESOLUTION][0], tuple)

#v2 api
# v2 api
self.assertIsInstance(im.tag_v2[X_RESOLUTION], TiffImagePlugin.IFDRational)
self.assertIsInstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational)

Expand Down
Loading

0 comments on commit eff632f

Please sign in to comment.