Skip to content

Commit

Permalink
Merge pull request #1625 from radarhere/health
Browse files Browse the repository at this point in the history
Health fixes
  • Loading branch information
hugovk committed Apr 3, 2016
2 parents c4233fd + 677b958 commit 77b5a53
Show file tree
Hide file tree
Showing 20 changed files with 118 additions and 127 deletions.
5 changes: 2 additions & 3 deletions PIL/DdsImagePlugin.py
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
3 changes: 1 addition & 2 deletions PIL/FtexImagePlugin.py
Expand Up @@ -62,7 +62,7 @@ def _open(self):
mipmap_count, format_count = struct.unpack("<2i", self.fp.read(8))

self.mode = "RGB"

# Only support single-format files. I don't know of any multi-format file.
assert format_count == 1

Expand All @@ -83,7 +83,6 @@ def _open(self):
self.fp.close()
self.fp = BytesIO(data)


def load_seek(self, pos):
pass

Expand Down
18 changes: 9 additions & 9 deletions PIL/GbrImagePlugin.py
Expand Up @@ -30,7 +30,7 @@


def _accept(prefix):
return len(prefix) >= 8 and i32(prefix[:4]) >= 20 and i32(prefix[4:8]) in (1,2)
return len(prefix) >= 8 and i32(prefix[:4]) >= 20 and i32(prefix[4:8]) in (1, 2)


##
Expand All @@ -46,17 +46,17 @@ def _open(self):
version = i32(self.fp.read(4))
if header_size < 20:
raise SyntaxError("not a GIMP brush")
if version not in (1,2):
raise SyntaxError("Unsupported GIMP brush version: %s" %version)
if version not in (1, 2):
raise SyntaxError("Unsupported GIMP brush version: %s" % version)

width = i32(self.fp.read(4))
height = i32(self.fp.read(4))
color_depth = i32(self.fp.read(4))
if width <= 0 or height <= 0:
if width <= 0 or height <= 0:
raise SyntaxError("not a GIMP brush")
if color_depth not in (1,4):
raise SyntaxError("Unsupported GMP brush color depth: %s" %color_depth)
if color_depth not in (1, 4):
raise SyntaxError("Unsupported GMP brush color depth: %s" % color_depth)

if version == 1:
comment_length = header_size-20
else:
Expand All @@ -72,15 +72,15 @@ def _open(self):
self.mode = "L"
else:
self.mode = 'RGBA'

self.size = width, height

self.info["comment"] = comment

# Image might not be small
Image._decompression_bomb_check(self.size)

# Data is an uncompressed block of w * h * bytes/pixel
# Data is an uncompressed block of w * h * bytes/pixel
self._data_size = width * height * color_depth

def load(self):
Expand Down
2 changes: 1 addition & 1 deletion PIL/JpegImagePlugin.py
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
21 changes: 10 additions & 11 deletions PIL/TiffImagePlugin.py
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 Down Expand Up @@ -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,7 +284,6 @@ def numerator(a):
def denominator(a):
return a._denominator


def limit_rational(self, max_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 @@ -350,7 +349,6 @@ def delegate(self, *args):
__round__ = _delegate('__round__')



class ImageFileDirectory_v2(collections.MutableMapping):
"""This class represents a TIFF tag directory. To speed things up, we
don't decode tags unless they're asked for.
Expand Down Expand Up @@ -1126,8 +1124,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 @@ -1416,14 +1414,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
33 changes: 17 additions & 16 deletions PIL/TiffTags.py
Expand Up @@ -30,6 +30,7 @@ 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
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
2 changes: 1 addition & 1 deletion Tests/check_fli_overflow.py
Expand Up @@ -10,7 +10,7 @@ def test_fli_overflow(self):
# this should not crash with a malloc error or access violation
im = Image.open(TEST_FILE)
im.load()


if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion Tests/check_libtiff_segfault.py
Expand Up @@ -3,6 +3,7 @@

TEST_FILE = "Tests/images/libtiff_segfault.tif"


class TestLibtiffSegfault(PillowTestCase):
def test_segfault(self):
""" This test should not segfault. It will on Pillow <= 3.1.0 and
Expand All @@ -18,6 +19,5 @@ def test_segfault(self):
self.fail("Should have returned IOError")



if __name__ == '__main__':
unittest.main()
12 changes: 6 additions & 6 deletions Tests/test_file_dds.py
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
3 changes: 2 additions & 1 deletion Tests/test_file_ftex.py
@@ -1,6 +1,7 @@
from helper import unittest, PillowTestCase
from helper import PillowTestCase
from PIL import Image


class TestFileFtex(PillowTestCase):

def test_load_raw(self):
Expand Down
1 change: 0 additions & 1 deletion Tests/test_file_gbr.py
Expand Up @@ -11,7 +11,6 @@ def test_invalid_file(self):
self.assertRaises(SyntaxError,
lambda: GbrImagePlugin.GbrImageFile(invalid_file))


def test_gbr_file(self):
im = Image.open('Tests/images/gbr.gbr')

Expand Down
37 changes: 18 additions & 19 deletions Tests/test_file_jpeg.py
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

0 comments on commit 77b5a53

Please sign in to comment.