diff --git a/PIL/DdsImagePlugin.py b/PIL/DdsImagePlugin.py index 86145ca8f..2ebfdf037 100644 --- a/PIL/DdsImagePlugin.py +++ b/PIL/DdsImagePlugin.py @@ -219,7 +219,7 @@ class DdsImageFile(ImageFile.ImageFile): 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 @@ class DdsImageFile(ImageFile.ImageFile): 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 24e4c0e7d..f3a2d7fa7 100644 --- a/PIL/FtexImagePlugin.py +++ b/PIL/FtexImagePlugin.py @@ -62,7 +62,7 @@ class FtexImageFile(ImageFile.ImageFile): 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 @@ class FtexImageFile(ImageFile.ImageFile): self.fp.close() self.fp = BytesIO(data) - def load_seek(self, pos): pass diff --git a/PIL/GbrImagePlugin.py b/PIL/GbrImagePlugin.py index 8edb8f487..5fef39960 100644 --- a/PIL/GbrImagePlugin.py +++ b/PIL/GbrImagePlugin.py @@ -30,7 +30,7 @@ i32 = _binary.i32be 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 @@ class GbrImageFile(ImageFile.ImageFile): 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 @@ class GbrImageFile(ImageFile.ImageFile): self.mode = "L" else: self.mode = 'RGBA' - + self.size = width, height self.info["comment"] = comment @@ -80,7 +80,7 @@ class GbrImageFile(ImageFile.ImageFile): # 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 beda4f7a0..386939ba7 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 cc739aec6..f899676e8 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -57,7 +57,7 @@ import struct 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. @@ -266,7 +267,6 @@ class IFDRational(Rational): self._val = float('nan') return - elif denominator == 1: if sys.hexversion < 0x2070000 and type(value) == float: # python 2.6 is different. @@ -284,7 +284,6 @@ class IFDRational(Rational): def denominator(a): return a._denominator - def limit_rational(self, max_denominator): """ @@ -304,12 +303,12 @@ class IFDRational(Rational): 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', @@ -350,7 +349,6 @@ class IFDRational(Rational): __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. @@ -1126,8 +1124,8 @@ class TiffImageFile(ImageFile.ImageFile): 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) @@ -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" diff --git a/PIL/TiffTags.py b/PIL/TiffTags.py index bc565e09c..bee921dcd 100644 --- a/PIL/TiffTags.py +++ b/PIL/TiffTags.py @@ -30,6 +30,7 @@ class TagInfo(namedtuple("_TagInfo", "value name type length enum")): def cvt_enum(self, value): return self.enum.get(value, value) + def lookup(tag): """ :param tag: Integer tag number @@ -378,22 +379,22 @@ TYPES = {} # 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 = 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(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.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 d89a82761..9b370da3c 100644 --- a/Tests/check_fli_overflow.py +++ b/Tests/check_fli_overflow.py @@ -10,7 +10,7 @@ class TestFliOverflow(PillowTestCase): # 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 898a165d4..c2e01dd55 100644 --- a/Tests/check_libtiff_segfault.py +++ b/Tests/check_libtiff_segfault.py @@ -3,6 +3,7 @@ from PIL import Image 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 @@ class TestLibtiffSegfault(PillowTestCase): 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 d2c7a306f..a4442a2e8 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -17,12 +17,12 @@ class TestFileDds(PillowTestCase): 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 @@ class TestFileDds(PillowTestCase): # 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 @@ class TestFileDds(PillowTestCase): 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 7a99aea9a..97bf08747 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 d38b4a70f..479f5b83f 100644 --- a/Tests/test_file_gbr.py +++ b/Tests/test_file_gbr.py @@ -11,7 +11,6 @@ class TestFileGbr(PillowTestCase): 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 c54d08713..7b60f60b1 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -191,26 +191,26 @@ class TestFileJpeg(PillowTestCase): 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 @@ class TestFileJpeg(PillowTestCase): 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 313fb545f..bca638e22 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -176,19 +176,20 @@ class TestFileLibTiff(LibTiffTestCase): # 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 @@ class TestFileLibTiff(LibTiffTestCase): # 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,18 +213,16 @@ class TestFileLibTiff(LibTiffTestCase): 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 - - def test_g3_compression(self): i = Image.open('Tests/images/hopper_g4_500.tif') out = self.tempfile("temp.tif") @@ -459,7 +457,6 @@ class TestFileLibTiff(LibTiffTestCase): TiffImagePlugin.WRITE_LIBTIFF = False - if __name__ == '__main__': unittest.main() diff --git a/Tests/test_file_pcd.py b/Tests/test_file_pcd.py index f26482072..06fd33043 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 0fc8a5bad..43240216e 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -84,7 +84,7 @@ class TestFileTiff(PillowTestCase): 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 1b88fca99..fa93b5f08 100644 --- a/Tests/test_file_tiff_metadata.py +++ b/Tests/test_file_tiff_metadata.py @@ -122,21 +122,22 @@ class TestFileTiffMetadata(PillowTestCase): 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 @@ class TestFileTiffMetadata(PillowTestCase): 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 @@ class TestFileTiffMetadata(PillowTestCase): 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 83c857975..a5e1d4e42 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 @@ class TestImageGetIm(PillowTestCase): 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 9e8f735f6..1bba40f8f 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 @@ class TestImagingCoreResize(PillowTestCase): 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 d9dd13102..c2c58acd5 100644 --- a/Tests/test_tiff_ifdrational.py +++ b/Tests/test_tiff_ifdrational.py @@ -7,8 +7,8 @@ from PIL.TiffImagePlugin import IFDRational from fractions import Fraction -class Test_IFDRational(PillowTestCase): +class Test_IFDRational(PillowTestCase): def _test_equal(self, num, denom, target): @@ -20,17 +20,16 @@ class Test_IFDRational(PillowTestCase): 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(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(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 @@ class Test_IFDRational(PillowTestCase): 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 cad3a408c..7f0a7f052 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.