diff --git a/PIL/DdsImagePlugin.py b/PIL/DdsImagePlugin.py index 86145ca8f22..2ebfdf03752 100644 --- a/PIL/DdsImagePlugin.py +++ b/PIL/DdsImagePlugin.py @@ -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" @@ -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 diff --git a/PIL/FtexImagePlugin.py b/PIL/FtexImagePlugin.py index 24e4c0e7dd7..f3a2d7fa7b6 100644 --- a/PIL/FtexImagePlugin.py +++ b/PIL/FtexImagePlugin.py @@ -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 @@ -83,7 +83,6 @@ def _open(self): self.fp.close() self.fp = BytesIO(data) - def load_seek(self, pos): pass diff --git a/PIL/GbrImagePlugin.py b/PIL/GbrImagePlugin.py index 8edb8f487b3..5fef39960dc 100644 --- a/PIL/GbrImagePlugin.py +++ b/PIL/GbrImagePlugin.py @@ -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) ## @@ -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: @@ -72,7 +72,7 @@ def _open(self): self.mode = "L" else: self.mode = 'RGBA' - + self.size = width, height self.info["comment"] = comment @@ -80,7 +80,7 @@ def _open(self): # 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): diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index beda4f7a0c9..386939ba715 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -448,7 +448,7 @@ def _getexif(self): info = TiffImagePlugin.ImageFileDirectory_v1(head) info.load(file) exif[0x8825] = _fixup_dict(info) - + return exif diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py index 096be6f5653..fdf60a61139 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -57,7 +57,7 @@ import sys import warnings -from .TiffTags import TYPES, TagInfo +from .TiffTags import TYPES __version__ = "1.3.5" @@ -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. @@ -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): """ @@ -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 @@ -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. @@ -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) """ @@ -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', @@ -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 @@ -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) @@ -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" diff --git a/PIL/TiffTags.py b/PIL/TiffTags.py index 07d594e1a04..bc66df8efc4 100644 --- a/PIL/TiffTags.py +++ b/PIL/TiffTags.py @@ -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'))) @@ -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: @@ -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 diff --git a/Tests/check_fli_overflow.py b/Tests/check_fli_overflow.py index d89a82761be..9b370da3ca0 100644 --- a/Tests/check_fli_overflow.py +++ b/Tests/check_fli_overflow.py @@ -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() diff --git a/Tests/check_libtiff_segfault.py b/Tests/check_libtiff_segfault.py index 898a165d44a..c2e01dd5583 100644 --- a/Tests/check_libtiff_segfault.py +++ b/Tests/check_libtiff_segfault.py @@ -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 @@ -18,6 +19,5 @@ def test_segfault(self): self.fail("Should have returned IOError") - if __name__ == '__main__': unittest.main() diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index d2c7a306fe7..a4442a2e8e5 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -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): @@ -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): @@ -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) diff --git a/Tests/test_file_ftex.py b/Tests/test_file_ftex.py index 7a99aea9adf..97bf08747d9 100644 --- a/Tests/test_file_ftex.py +++ b/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): diff --git a/Tests/test_file_gbr.py b/Tests/test_file_gbr.py index d38b4a70fc5..479f5b83f8a 100644 --- a/Tests/test_file_gbr.py +++ b/Tests/test_file_gbr.py @@ -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') diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index c54d087139b..7b60f60b1c1 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -191,26 +191,26 @@ 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') @@ -218,7 +218,6 @@ def test_exif_rollback(self): 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') diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index 313fb545f72..bca638e2216 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -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", @@ -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(): @@ -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') @@ -459,7 +457,6 @@ def test_crashing_metadata(self): TiffImagePlugin.WRITE_LIBTIFF = False - if __name__ == '__main__': unittest.main() diff --git a/Tests/test_file_pcd.py b/Tests/test_file_pcd.py index f2648207225..06fd3304352 100644 --- a/Tests/test_file_pcd.py +++ b/Tests/test_file_pcd.py @@ -1,22 +1,22 @@ -from helper import unittest, PillowTestCase, hopper +from helper import unittest, PillowTestCase from PIL import Image + class TestFilePcd(PillowTestCase): def test_load_raw(self): im = Image.open('Tests/images/hopper.pcd') - im.load() # should not segfault. + im.load() # should not segfault. # Note that this image was created with a resized hopper # image, which was then converted to pcd with imagemagick # and the colors are wonky in Pillow. It's unclear if this # is a pillow or a convert issue, as other images not generated # from convert look find on pillow and not imagemagick. - - #target = hopper().resize((768,512)) - #self.assert_image_similar(im, target, 10) + + # target = hopper().resize((768,512)) + # self.assert_image_similar(im, target, 10) if __name__ == '__main__': unittest.main() - diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 20a0e93e384..e4e674b9f4c 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -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) diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py index 1b88fca9990..fa93b5f0865 100644 --- a/Tests/test_file_tiff_metadata.py +++ b/Tests/test_file_tiff_metadata.py @@ -122,21 +122,22 @@ def test_write_metadata(self): original = img.tag_v2.named() reloaded = loaded.tag_v2.named() - for k,v in original.items(): + for k, v in original.items(): if type(v) == IFDRational: - original[k] = IFDRational(*_limit_rational(v,2**31)) + original[k] = IFDRational(*_limit_rational(v, 2**31)) if type(v) == tuple and \ - type(v[0]) == IFDRational: + type(v[0]) == IFDRational: original[k] = tuple([IFDRational( - *_limit_rational(elt, 2**31)) for elt in v]) + *_limit_rational(elt, 2**31)) for elt in v]) ignored = ['StripByteCounts', 'RowsPerStrip', 'PageNumber', 'StripOffsets'] for tag, value in reloaded.items(): - if tag in ignored: continue + if tag in ignored: + continue if (type(original[tag]) == tuple - and type(original[tag][0]) == IFDRational): + and type(original[tag][0]) == IFDRational): # Need to compare element by element in the tuple, # not comparing tuples of object references self.assert_deep_equal(original[tag], @@ -188,7 +189,7 @@ def test_iccprofile_binary(self): def test_exif_div_zero(self): im = hopper() info = TiffImagePlugin.ImageFileDirectory_v2() - info[41988] = TiffImagePlugin.IFDRational(0,0) + info[41988] = TiffImagePlugin.IFDRational(0, 0) out = self.tempfile('temp.tiff') im.save(out, tiffinfo=info, compression='raw') @@ -198,8 +199,6 @@ def test_exif_div_zero(self): self.assertEqual(0, reloaded.tag_v2[41988][0].denominator) - - if __name__ == '__main__': unittest.main() diff --git a/Tests/test_image_getim.py b/Tests/test_image_getim.py index 83c8579754d..a5e1d4e4235 100644 --- a/Tests/test_image_getim.py +++ b/Tests/test_image_getim.py @@ -1,6 +1,7 @@ from helper import unittest, PillowTestCase, hopper, py3 import sys + class TestImageGetIm(PillowTestCase): def test_sanity(self): @@ -10,7 +11,6 @@ def test_sanity(self): if py3: self.assertIn("PyCapsule", type_repr) - if sys.hexversion < 0x2070000: # py2.6 x64, windows target_types = (int, long) diff --git a/Tests/test_image_resample.py b/Tests/test_image_resample.py index 9e8f735f6a6..1bba40f8f83 100644 --- a/Tests/test_image_resample.py +++ b/Tests/test_image_resample.py @@ -1,15 +1,16 @@ from helper import unittest, PillowTestCase, hopper from PIL import Image + class TestImagingCoreResize(PillowTestCase): - #see https://github.com/python-pillow/Pillow/issues/1710 + # see https://github.com/python-pillow/Pillow/issues/1710 def test_overflow(self): im = hopper('L') xsize = 0x100000008 // 4 - ysize = 1000 # unimportant + ysize = 1000 # unimportant try: # any resampling filter will do here - im.im.resize((xsize, ysize), Image.LINEAR) + im.im.resize((xsize, ysize), Image.LINEAR) self.fail("Resize should raise MemoryError on invalid xsize") except MemoryError: self.assertTrue(True, "Should raise MemoryError") @@ -17,17 +18,17 @@ def test_overflow(self): def test_invalid_size(self): im = hopper() - im.resize((100,100)) + im.resize((100, 100)) self.assertTrue(True, "Should not Crash") - + try: - im.resize((-100,100)) + im.resize((-100, 100)) self.fail("Resize should raise a value error on x negative size") except ValueError: self.assertTrue(True, "Should raise ValueError") try: - im.resize((100,-100)) + im.resize((100, -100)) self.fail("Resize should raise a value error on y negative size") except ValueError: self.assertTrue(True, "Should raise ValueError") diff --git a/Tests/test_tiff_ifdrational.py b/Tests/test_tiff_ifdrational.py index d9dd1310231..c2c58acd5a3 100644 --- a/Tests/test_tiff_ifdrational.py +++ b/Tests/test_tiff_ifdrational.py @@ -7,8 +7,8 @@ from fractions import Fraction -class Test_IFDRational(PillowTestCase): +class Test_IFDRational(PillowTestCase): def _test_equal(self, num, denom, target): @@ -20,17 +20,16 @@ def _test_equal(self, num, denom, target): def test_sanity(self): self._test_equal(1, 1, 1) - self._test_equal(1, 1, Fraction(1,1)) + self._test_equal(1, 1, Fraction(1, 1)) self._test_equal(2, 2, 1) - self._test_equal(1.0, 1, Fraction(1,1)) - - self._test_equal(Fraction(1,1), 1, Fraction(1,1)) - self._test_equal(IFDRational(1,1), 1, 1) + self._test_equal(1.0, 1, Fraction(1, 1)) + self._test_equal(Fraction(1, 1), 1, Fraction(1, 1)) + self._test_equal(IFDRational(1, 1), 1, 1) - self._test_equal(1, 2, Fraction(1,2)) - self._test_equal(1, 2, IFDRational(1,2)) + self._test_equal(1, 2, Fraction(1, 2)) + self._test_equal(1, 2, IFDRational(1, 2)) def test_nonetype(self): " Fails if the _delegate function doesn't return a valid function" @@ -45,17 +44,15 @@ def test_nonetype(self): self.assertTrue(xres and 1) self.assertTrue(xres and yres) - def test_ifd_rational_save(self): for libtiff in (True, False): TiffImagePlugin.WRITE_LIBTIFF = libtiff im = hopper() out = self.tempfile('temp.tiff') - res = IFDRational(301,1) - im.save(out, dpi=(res,res), compression='raw') + res = IFDRational(301, 1) + im.save(out, dpi=(res, res), compression='raw') reloaded = Image.open(out) - self.assertEqual(float(IFDRational(301,1)), + self.assertEqual(float(IFDRational(301, 1)), float(reloaded.tag_v2[282])) - diff --git a/docs/releasenotes/3.1.0.rst b/docs/releasenotes/3.1.0.rst index cad3a408c0c..7f0a7f0520b 100644 --- a/docs/releasenotes/3.1.0.rst +++ b/docs/releasenotes/3.1.0.rst @@ -47,14 +47,14 @@ When used in a ``ImageFileDirectory_v1``, a 2 item tuple is returned of the numerator and denominator, as was done previously. This class should be used when adding a rational value to an -ImageFileDirectory for saving to image metadata. +ImageFileDirectory for saving to image metadata. JpegImagePlugin._getexif ++++++++++++++++++++++++ In Pillow 3.0, the dictionary returned from the private, experimental, but generally widely used ``_getexif`` function changed to reflect the -ImageFileDirectory_v2 format, without a fallback to the previous format. +ImageFileDirectory_v2 format, without a fallback to the previous format. In Pillow 3.1, ``_getexif`` now returns a dictionary compatible with Pillow 2.9 and earlier, built with @@ -70,6 +70,6 @@ Out of Spec Metadata In Pillow 3.0 and 3.1, images that contain metadata that is internally consistent but not in agreement with the TIFF spec may cause an exception when reading the metadata. This can happen when a tag that -is specified to have a single value is stored with an array of values. +is specified to have a single value is stored with an array of values. -It is anticipated that this behavior will change in future releases. +It is anticipated that this behavior will change in future releases.