mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Improve handling of file resources (#3577)
Improve handling of file resources
This commit is contained in:
		
						commit
						2cf510e596
					
				| 
						 | 
					@ -24,8 +24,8 @@ class TestBmpReference(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            def open(f):
 | 
					            def open(f):
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    im = Image.open(f)
 | 
					                    with Image.open(f) as im:
 | 
				
			||||||
                    im.load()
 | 
					                        im.load()
 | 
				
			||||||
                except Exception:  # as msg:
 | 
					                except Exception:  # as msg:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,8 +48,8 @@ class TestBmpReference(PillowTestCase):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        for f in self.get_files("q"):
 | 
					        for f in self.get_files("q"):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                im = Image.open(f)
 | 
					                with Image.open(f) as im:
 | 
				
			||||||
                im.load()
 | 
					                    im.load()
 | 
				
			||||||
                if os.path.basename(f) not in supported:
 | 
					                if os.path.basename(f) not in supported:
 | 
				
			||||||
                    print("Please add %s to the partially supported bmp specs." % f)
 | 
					                    print("Please add %s to the partially supported bmp specs." % f)
 | 
				
			||||||
            except Exception:  # as msg:
 | 
					            except Exception:  # as msg:
 | 
				
			||||||
| 
						 | 
					@ -89,17 +89,17 @@ class TestBmpReference(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for f in self.get_files("g"):
 | 
					        for f in self.get_files("g"):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                im = Image.open(f)
 | 
					                with Image.open(f) as im:
 | 
				
			||||||
                im.load()
 | 
					                    im.load()
 | 
				
			||||||
                compare = Image.open(get_compare(f))
 | 
					                    with Image.open(get_compare(f)) as compare:
 | 
				
			||||||
                compare.load()
 | 
					                        compare.load()
 | 
				
			||||||
                if im.mode == "P":
 | 
					                        if im.mode == "P":
 | 
				
			||||||
                    # assert image similar doesn't really work
 | 
					                            # assert image similar doesn't really work
 | 
				
			||||||
                    # with paletized image, since the palette might
 | 
					                            # with paletized image, since the palette might
 | 
				
			||||||
                    # be differently ordered for an equivalent image.
 | 
					                            # be differently ordered for an equivalent image.
 | 
				
			||||||
                    im = im.convert("RGBA")
 | 
					                            im = im.convert("RGBA")
 | 
				
			||||||
                    compare = im.convert("RGBA")
 | 
					                            compare = im.convert("RGBA")
 | 
				
			||||||
                self.assert_image_similar(im, compare, 5)
 | 
					                        self.assert_image_similar(im, compare, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            except Exception as msg:
 | 
					            except Exception as msg:
 | 
				
			||||||
                # there are three here that are unsupported:
 | 
					                # there are three here that are unsupported:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,8 @@ class TestDecompressionBomb(PillowTestCase):
 | 
				
			||||||
    def test_no_warning_small_file(self):
 | 
					    def test_no_warning_small_file(self):
 | 
				
			||||||
        # Implicit assert: no warning.
 | 
					        # Implicit assert: no warning.
 | 
				
			||||||
        # A warning would cause a failure.
 | 
					        # A warning would cause a failure.
 | 
				
			||||||
        Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_no_warning_no_limit(self):
 | 
					    def test_no_warning_no_limit(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -25,21 +26,28 @@ class TestDecompressionBomb(PillowTestCase):
 | 
				
			||||||
        # Act / Assert
 | 
					        # Act / Assert
 | 
				
			||||||
        # Implicit assert: no warning.
 | 
					        # Implicit assert: no warning.
 | 
				
			||||||
        # A warning would cause a failure.
 | 
					        # A warning would cause a failure.
 | 
				
			||||||
        Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_warning(self):
 | 
					    def test_warning(self):
 | 
				
			||||||
        # Set limit to trigger warning on the test file
 | 
					        # Set limit to trigger warning on the test file
 | 
				
			||||||
        Image.MAX_IMAGE_PIXELS = 128 * 128 - 1
 | 
					        Image.MAX_IMAGE_PIXELS = 128 * 128 - 1
 | 
				
			||||||
        self.assertEqual(Image.MAX_IMAGE_PIXELS, 128 * 128 - 1)
 | 
					        self.assertEqual(Image.MAX_IMAGE_PIXELS, 128 * 128 - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(Image.DecompressionBombWarning, Image.open, TEST_FILE)
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(TEST_FILE):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(Image.DecompressionBombWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exception(self):
 | 
					    def test_exception(self):
 | 
				
			||||||
        # Set limit to trigger exception on the test file
 | 
					        # Set limit to trigger exception on the test file
 | 
				
			||||||
        Image.MAX_IMAGE_PIXELS = 64 * 128 - 1
 | 
					        Image.MAX_IMAGE_PIXELS = 64 * 128 - 1
 | 
				
			||||||
        self.assertEqual(Image.MAX_IMAGE_PIXELS, 64 * 128 - 1)
 | 
					        self.assertEqual(Image.MAX_IMAGE_PIXELS, 64 * 128 - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertRaises(Image.DecompressionBombError, lambda: Image.open(TEST_FILE))
 | 
					        with self.assertRaises(Image.DecompressionBombError):
 | 
				
			||||||
 | 
					            with Image.open(TEST_FILE):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exception_ico(self):
 | 
					    def test_exception_ico(self):
 | 
				
			||||||
        with self.assertRaises(Image.DecompressionBombError):
 | 
					        with self.assertRaises(Image.DecompressionBombError):
 | 
				
			||||||
| 
						 | 
					@ -53,6 +61,7 @@ class TestDecompressionBomb(PillowTestCase):
 | 
				
			||||||
class TestDecompressionCrop(PillowTestCase):
 | 
					class TestDecompressionCrop(PillowTestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.src = hopper()
 | 
					        self.src = hopper()
 | 
				
			||||||
 | 
					        self.addCleanup(self.src.close)
 | 
				
			||||||
        Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width * 4 - 1
 | 
					        Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width * 4 - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tearDown(self):
 | 
					    def tearDown(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,14 +5,14 @@ from .helper import PillowTestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileBlp(PillowTestCase):
 | 
					class TestFileBlp(PillowTestCase):
 | 
				
			||||||
    def test_load_blp2_raw(self):
 | 
					    def test_load_blp2_raw(self):
 | 
				
			||||||
        im = Image.open("Tests/images/blp/blp2_raw.blp")
 | 
					        with Image.open("Tests/images/blp/blp2_raw.blp") as im:
 | 
				
			||||||
        target = Image.open("Tests/images/blp/blp2_raw.png")
 | 
					            with Image.open("Tests/images/blp/blp2_raw.png") as target:
 | 
				
			||||||
        self.assert_image_equal(im, target)
 | 
					                self.assert_image_equal(im, target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_blp2_dxt1(self):
 | 
					    def test_load_blp2_dxt1(self):
 | 
				
			||||||
        im = Image.open("Tests/images/blp/blp2_dxt1.blp")
 | 
					        with Image.open("Tests/images/blp/blp2_dxt1.blp") as im:
 | 
				
			||||||
        target = Image.open("Tests/images/blp/blp2_dxt1.png")
 | 
					            with Image.open("Tests/images/blp/blp2_dxt1.png") as target:
 | 
				
			||||||
        self.assert_image_equal(im, target)
 | 
					                self.assert_image_equal(im, target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_blp2_dxt1a(self):
 | 
					    def test_load_blp2_dxt1a(self):
 | 
				
			||||||
        im = Image.open("Tests/images/blp/blp2_dxt1a.blp")
 | 
					        im = Image.open("Tests/images/blp/blp2_dxt1a.blp")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,13 +46,12 @@ class TestFileBmp(PillowTestCase):
 | 
				
			||||||
        dpi = (72, 72)
 | 
					        dpi = (72, 72)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        output = io.BytesIO()
 | 
					        output = io.BytesIO()
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        im.save(output, "BMP", dpi=dpi)
 | 
					            im.save(output, "BMP", dpi=dpi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        output.seek(0)
 | 
					        output.seek(0)
 | 
				
			||||||
        reloaded = Image.open(output)
 | 
					        with Image.open(output) as reloaded:
 | 
				
			||||||
 | 
					            self.assertEqual(reloaded.info["dpi"], dpi)
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], dpi)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_bmp_with_dpi(self):
 | 
					    def test_save_bmp_with_dpi(self):
 | 
				
			||||||
        # Test for #1301
 | 
					        # Test for #1301
 | 
				
			||||||
| 
						 | 
					@ -72,24 +71,24 @@ class TestFileBmp(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dpi_rounding(self):
 | 
					    def test_load_dpi_rounding(self):
 | 
				
			||||||
        # Round up
 | 
					        # Round up
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.bmp")
 | 
					        with Image.open("Tests/images/hopper.bmp") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (96, 96))
 | 
					            self.assertEqual(im.info["dpi"], (96, 96))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Round down
 | 
					        # Round down
 | 
				
			||||||
        im = Image.open("Tests/images/hopper_roundDown.bmp")
 | 
					        with Image.open("Tests/images/hopper_roundDown.bmp") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (72, 72))
 | 
					            self.assertEqual(im.info["dpi"], (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_dpi_rounding(self):
 | 
					    def test_save_dpi_rounding(self):
 | 
				
			||||||
        outfile = self.tempfile("temp.bmp")
 | 
					        outfile = self.tempfile("temp.bmp")
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.bmp")
 | 
					        im = Image.open("Tests/images/hopper.bmp")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(outfile, dpi=(72.2, 72.2))
 | 
					        im.save(outfile, dpi=(72.2, 72.2))
 | 
				
			||||||
        reloaded = Image.open(outfile)
 | 
					        with Image.open(outfile) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], (72, 72))
 | 
					            self.assertEqual(reloaded.info["dpi"], (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(outfile, dpi=(72.8, 72.8))
 | 
					            im.save(outfile, dpi=(72.8, 72.8))
 | 
				
			||||||
        reloaded = Image.open(outfile)
 | 
					        with Image.open(outfile) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], (73, 73))
 | 
					            self.assertEqual(reloaded.info["dpi"], (73, 73))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dib(self):
 | 
					    def test_load_dib(self):
 | 
				
			||||||
        # test for #1293, Imagegrab returning Unsupported Bitfields Format
 | 
					        # test for #1293, Imagegrab returning Unsupported Bitfields Format
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,14 @@ TEST_FILE = "Tests/images/gfs.t06z.rassda.tm00.bufr_d"
 | 
				
			||||||
class TestFileBufrStub(PillowTestCase):
 | 
					class TestFileBufrStub(PillowTestCase):
 | 
				
			||||||
    def test_open(self):
 | 
					    def test_open(self):
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.format, "BUFR")
 | 
					            self.assertEqual(im.format, "BUFR")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Dummy data from the stub
 | 
					            # Dummy data from the stub
 | 
				
			||||||
        self.assertEqual(im.mode, "F")
 | 
					            self.assertEqual(im.mode, "F")
 | 
				
			||||||
        self.assertEqual(im.size, (1, 1))
 | 
					            self.assertEqual(im.size, (1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -28,10 +28,10 @@ class TestFileBufrStub(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load(self):
 | 
					    def test_load(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot load without an implemented handler
 | 
					            # Act / Assert: stub cannot load without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.load)
 | 
					            self.assertRaises(IOError, im.load)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,8 @@ class TestFileContainer(PillowTestCase):
 | 
				
			||||||
        dir(ContainerIO)
 | 
					        dir(ContainerIO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_isatty(self):
 | 
					    def test_isatty(self):
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        container = ContainerIO.ContainerIO(im, 0, 0)
 | 
					            container = ContainerIO.ContainerIO(im, 0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertFalse(container.isatty())
 | 
					        self.assertFalse(container.isatty())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import DcxImagePlugin, Image
 | 
					from PIL import DcxImagePlugin, Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper
 | 
					from .helper import PillowTestCase, hopper, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Created with ImageMagick: convert hopper.ppm hopper.dcx
 | 
					# Created with ImageMagick: convert hopper.ppm hopper.dcx
 | 
				
			||||||
TEST_FILE = "Tests/images/hopper.dcx"
 | 
					TEST_FILE = "Tests/images/hopper.dcx"
 | 
				
			||||||
| 
						 | 
					@ -11,19 +13,35 @@ class TestFileDcx(PillowTestCase):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertIsInstance(im, DcxImagePlugin.DcxImageFile)
 | 
					            self.assertIsInstance(im, DcxImagePlugin.DcxImageFile)
 | 
				
			||||||
        orig = hopper()
 | 
					            orig = hopper()
 | 
				
			||||||
        self.assert_image_equal(im, orig)
 | 
					            self.assert_image_equal(im, orig)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(TEST_FILE)
 | 
					            im = Image.open(TEST_FILE)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(TEST_FILE)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
| 
						 | 
					@ -32,34 +50,34 @@ class TestFileDcx(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tell(self):
 | 
					    def test_tell(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        frame = im.tell()
 | 
					            frame = im.tell()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(frame, 0)
 | 
					            self.assertEqual(frame, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_too_far(self):
 | 
					    def test_seek_too_far(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        frame = 999  # too big on purpose
 | 
					            frame = 999  # too big on purpose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					        # Act / Assert
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, frame)
 | 
					        self.assertRaises(EOFError, im.seek, frame)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,30 +25,30 @@ class TestFileEps(PillowTestCase):
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        # Regular scale
 | 
					        # Regular scale
 | 
				
			||||||
        image1 = Image.open(file1)
 | 
					        with Image.open(file1) as image1:
 | 
				
			||||||
        image1.load()
 | 
					            image1.load()
 | 
				
			||||||
        self.assertEqual(image1.mode, "RGB")
 | 
					            self.assertEqual(image1.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(image1.size, (460, 352))
 | 
					            self.assertEqual(image1.size, (460, 352))
 | 
				
			||||||
        self.assertEqual(image1.format, "EPS")
 | 
					            self.assertEqual(image1.format, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image2 = Image.open(file2)
 | 
					        with Image.open(file2) as image2:
 | 
				
			||||||
        image2.load()
 | 
					            image2.load()
 | 
				
			||||||
        self.assertEqual(image2.mode, "RGB")
 | 
					            self.assertEqual(image2.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(image2.size, (360, 252))
 | 
					            self.assertEqual(image2.size, (360, 252))
 | 
				
			||||||
        self.assertEqual(image2.format, "EPS")
 | 
					            self.assertEqual(image2.format, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Double scale
 | 
					        # Double scale
 | 
				
			||||||
        image1_scale2 = Image.open(file1)
 | 
					        with Image.open(file1) as image1_scale2:
 | 
				
			||||||
        image1_scale2.load(scale=2)
 | 
					            image1_scale2.load(scale=2)
 | 
				
			||||||
        self.assertEqual(image1_scale2.mode, "RGB")
 | 
					            self.assertEqual(image1_scale2.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(image1_scale2.size, (920, 704))
 | 
					            self.assertEqual(image1_scale2.size, (920, 704))
 | 
				
			||||||
        self.assertEqual(image1_scale2.format, "EPS")
 | 
					            self.assertEqual(image1_scale2.format, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image2_scale2 = Image.open(file2)
 | 
					        with Image.open(file2) as image2_scale2:
 | 
				
			||||||
        image2_scale2.load(scale=2)
 | 
					            image2_scale2.load(scale=2)
 | 
				
			||||||
        self.assertEqual(image2_scale2.mode, "RGB")
 | 
					            self.assertEqual(image2_scale2.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(image2_scale2.size, (720, 504))
 | 
					            self.assertEqual(image2_scale2.size, (720, 504))
 | 
				
			||||||
        self.assertEqual(image2_scale2.format, "EPS")
 | 
					            self.assertEqual(image2_scale2.format, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        invalid_file = "Tests/images/flower.jpg"
 | 
					        invalid_file = "Tests/images/flower.jpg"
 | 
				
			||||||
| 
						 | 
					@ -57,43 +57,42 @@ class TestFileEps(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_cmyk(self):
 | 
					    def test_cmyk(self):
 | 
				
			||||||
        cmyk_image = Image.open("Tests/images/pil_sample_cmyk.eps")
 | 
					        with Image.open("Tests/images/pil_sample_cmyk.eps") as cmyk_image:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(cmyk_image.mode, "CMYK")
 | 
					            self.assertEqual(cmyk_image.mode, "CMYK")
 | 
				
			||||||
        self.assertEqual(cmyk_image.size, (100, 100))
 | 
					            self.assertEqual(cmyk_image.size, (100, 100))
 | 
				
			||||||
        self.assertEqual(cmyk_image.format, "EPS")
 | 
					            self.assertEqual(cmyk_image.format, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cmyk_image.load()
 | 
					            cmyk_image.load()
 | 
				
			||||||
        self.assertEqual(cmyk_image.mode, "RGB")
 | 
					            self.assertEqual(cmyk_image.mode, "RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if "jpeg_decoder" in dir(Image.core):
 | 
					            if "jpeg_decoder" in dir(Image.core):
 | 
				
			||||||
            target = Image.open("Tests/images/pil_sample_rgb.jpg")
 | 
					                target = Image.open("Tests/images/pil_sample_rgb.jpg")
 | 
				
			||||||
            self.assert_image_similar(cmyk_image, target, 10)
 | 
					                self.assert_image_similar(cmyk_image, target, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_showpage(self):
 | 
					    def test_showpage(self):
 | 
				
			||||||
        # See https://github.com/python-pillow/Pillow/issues/2615
 | 
					        # See https://github.com/python-pillow/Pillow/issues/2615
 | 
				
			||||||
        plot_image = Image.open("Tests/images/reqd_showpage.eps")
 | 
					        with Image.open("Tests/images/reqd_showpage.eps") as plot_image:
 | 
				
			||||||
        target = Image.open("Tests/images/reqd_showpage.png")
 | 
					            with Image.open("Tests/images/reqd_showpage.png") as target:
 | 
				
			||||||
 | 
					                # should not crash/hang
 | 
				
			||||||
        # should not crash/hang
 | 
					                plot_image.load()
 | 
				
			||||||
        plot_image.load()
 | 
					                #  fonts could be slightly different
 | 
				
			||||||
        #  fonts could be slightly different
 | 
					                self.assert_image_similar(plot_image, target, 6)
 | 
				
			||||||
        self.assert_image_similar(plot_image, target, 6)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_file_object(self):
 | 
					    def test_file_object(self):
 | 
				
			||||||
        # issue 479
 | 
					        # issue 479
 | 
				
			||||||
        image1 = Image.open(file1)
 | 
					        with Image.open(file1) as image1:
 | 
				
			||||||
        with open(self.tempfile("temp_file.eps"), "wb") as fh:
 | 
					            with open(self.tempfile("temp_file.eps"), "wb") as fh:
 | 
				
			||||||
            image1.save(fh, "EPS")
 | 
					                image1.save(fh, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_iobase_object(self):
 | 
					    def test_iobase_object(self):
 | 
				
			||||||
        # issue 479
 | 
					        # issue 479
 | 
				
			||||||
        image1 = Image.open(file1)
 | 
					        with Image.open(file1) as image1:
 | 
				
			||||||
        with io.open(self.tempfile("temp_iobase.eps"), "wb") as fh:
 | 
					            with io.open(self.tempfile("temp_iobase.eps"), "wb") as fh:
 | 
				
			||||||
            image1.save(fh, "EPS")
 | 
					                image1.save(fh, "EPS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_bytesio_object(self):
 | 
					    def test_bytesio_object(self):
 | 
				
			||||||
| 
						 | 
					@ -120,18 +119,18 @@ class TestFileEps(PillowTestCase):
 | 
				
			||||||
            self.skipTest("zip/deflate support not available")
 | 
					            self.skipTest("zip/deflate support not available")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Zero bounding box
 | 
					        # Zero bounding box
 | 
				
			||||||
        image1_scale1 = Image.open(file1)
 | 
					        with Image.open(file1) as image1_scale1:
 | 
				
			||||||
        image1_scale1.load()
 | 
					            image1_scale1.load()
 | 
				
			||||||
        image1_scale1_compare = Image.open(file1_compare).convert("RGB")
 | 
					            image1_scale1_compare = Image.open(file1_compare).convert("RGB")
 | 
				
			||||||
        image1_scale1_compare.load()
 | 
					            image1_scale1_compare.load()
 | 
				
			||||||
        self.assert_image_similar(image1_scale1, image1_scale1_compare, 5)
 | 
					            self.assert_image_similar(image1_scale1, image1_scale1_compare, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Non-Zero bounding box
 | 
					        # Non-Zero bounding box
 | 
				
			||||||
        image2_scale1 = Image.open(file2)
 | 
					        with Image.open(file2) as image2_scale1:
 | 
				
			||||||
        image2_scale1.load()
 | 
					            image2_scale1.load()
 | 
				
			||||||
        image2_scale1_compare = Image.open(file2_compare).convert("RGB")
 | 
					            image2_scale1_compare = Image.open(file2_compare).convert("RGB")
 | 
				
			||||||
        image2_scale1_compare.load()
 | 
					            image2_scale1_compare.load()
 | 
				
			||||||
        self.assert_image_similar(image2_scale1, image2_scale1_compare, 10)
 | 
					            self.assert_image_similar(image2_scale1, image2_scale1_compare, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_render_scale2(self):
 | 
					    def test_render_scale2(self):
 | 
				
			||||||
| 
						 | 
					@ -141,57 +140,44 @@ class TestFileEps(PillowTestCase):
 | 
				
			||||||
            self.skipTest("zip/deflate support not available")
 | 
					            self.skipTest("zip/deflate support not available")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Zero bounding box
 | 
					        # Zero bounding box
 | 
				
			||||||
        image1_scale2 = Image.open(file1)
 | 
					        with Image.open(file1) as image1_scale2:
 | 
				
			||||||
        image1_scale2.load(scale=2)
 | 
					            image1_scale2.load(scale=2)
 | 
				
			||||||
        image1_scale2_compare = Image.open(file1_compare_scale2).convert("RGB")
 | 
					            image1_scale2_compare = Image.open(file1_compare_scale2).convert("RGB")
 | 
				
			||||||
        image1_scale2_compare.load()
 | 
					            image1_scale2_compare.load()
 | 
				
			||||||
        self.assert_image_similar(image1_scale2, image1_scale2_compare, 5)
 | 
					            self.assert_image_similar(image1_scale2, image1_scale2_compare, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Non-Zero bounding box
 | 
					        # Non-Zero bounding box
 | 
				
			||||||
        image2_scale2 = Image.open(file2)
 | 
					        with Image.open(file2) as image2_scale2:
 | 
				
			||||||
        image2_scale2.load(scale=2)
 | 
					            image2_scale2.load(scale=2)
 | 
				
			||||||
        image2_scale2_compare = Image.open(file2_compare_scale2).convert("RGB")
 | 
					            image2_scale2_compare = Image.open(file2_compare_scale2).convert("RGB")
 | 
				
			||||||
        image2_scale2_compare.load()
 | 
					            image2_scale2_compare.load()
 | 
				
			||||||
        self.assert_image_similar(image2_scale2, image2_scale2_compare, 10)
 | 
					            self.assert_image_similar(image2_scale2, image2_scale2_compare, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_resize(self):
 | 
					    def test_resize(self):
 | 
				
			||||||
        # Arrange
 | 
					        files = [file1, file2, "Tests/images/illu10_preview.eps"]
 | 
				
			||||||
        image1 = Image.open(file1)
 | 
					        for fn in files:
 | 
				
			||||||
        image2 = Image.open(file2)
 | 
					            with Image.open(fn) as im:
 | 
				
			||||||
        image3 = Image.open("Tests/images/illu10_preview.eps")
 | 
					                new_size = (100, 100)
 | 
				
			||||||
        new_size = (100, 100)
 | 
					                im = im.resize(new_size)
 | 
				
			||||||
 | 
					                self.assertEqual(im.size, new_size)
 | 
				
			||||||
        # Act
 | 
					 | 
				
			||||||
        image1 = image1.resize(new_size)
 | 
					 | 
				
			||||||
        image2 = image2.resize(new_size)
 | 
					 | 
				
			||||||
        image3 = image3.resize(new_size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Assert
 | 
					 | 
				
			||||||
        self.assertEqual(image1.size, new_size)
 | 
					 | 
				
			||||||
        self.assertEqual(image2.size, new_size)
 | 
					 | 
				
			||||||
        self.assertEqual(image3.size, new_size)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_thumbnail(self):
 | 
					    def test_thumbnail(self):
 | 
				
			||||||
        # Issue #619
 | 
					        # Issue #619
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        image1 = Image.open(file1)
 | 
					        files = [file1, file2]
 | 
				
			||||||
        image2 = Image.open(file2)
 | 
					        for fn in files:
 | 
				
			||||||
        new_size = (100, 100)
 | 
					            with Image.open(file1) as im:
 | 
				
			||||||
 | 
					                new_size = (100, 100)
 | 
				
			||||||
        # Act
 | 
					                im.thumbnail(new_size)
 | 
				
			||||||
        image1.thumbnail(new_size)
 | 
					                self.assertEqual(max(im.size), max(new_size))
 | 
				
			||||||
        image2.thumbnail(new_size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Assert
 | 
					 | 
				
			||||||
        self.assertEqual(max(image1.size), max(new_size))
 | 
					 | 
				
			||||||
        self.assertEqual(max(image2.size), max(new_size))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_read_binary_preview(self):
 | 
					    def test_read_binary_preview(self):
 | 
				
			||||||
        # Issue 302
 | 
					        # Issue 302
 | 
				
			||||||
        # open image with binary preview
 | 
					        # open image with binary preview
 | 
				
			||||||
        Image.open(file3)
 | 
					        with Image.open(file3):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _test_readline(self, t, ending):
 | 
					    def _test_readline(self, t, ending):
 | 
				
			||||||
        ending = "Failure with line ending: %s" % (
 | 
					        ending = "Failure with line ending: %s" % (
 | 
				
			||||||
| 
						 | 
					@ -239,16 +225,16 @@ class TestFileEps(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					        # Act / Assert
 | 
				
			||||||
        for filename in FILES:
 | 
					        for filename in FILES:
 | 
				
			||||||
            img = Image.open(filename)
 | 
					            with Image.open(filename) as img:
 | 
				
			||||||
            self.assertEqual(img.mode, "RGB")
 | 
					                self.assertEqual(img.mode, "RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
					    @unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
 | 
				
			||||||
    def test_emptyline(self):
 | 
					    def test_emptyline(self):
 | 
				
			||||||
        # Test file includes an empty line in the header data
 | 
					        # Test file includes an empty line in the header data
 | 
				
			||||||
        emptyline_file = "Tests/images/zero_bb_emptyline.eps"
 | 
					        emptyline_file = "Tests/images/zero_bb_emptyline.eps"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image = Image.open(emptyline_file)
 | 
					        with Image.open(emptyline_file) as image:
 | 
				
			||||||
        image.load()
 | 
					            image.load()
 | 
				
			||||||
        self.assertEqual(image.mode, "RGB")
 | 
					        self.assertEqual(image.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(image.size, (460, 352))
 | 
					        self.assertEqual(image.size, (460, 352))
 | 
				
			||||||
        self.assertEqual(image.format, "EPS")
 | 
					        self.assertEqual(image.format, "EPS")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,14 @@ TEST_FILE = "Tests/images/hopper.fits"
 | 
				
			||||||
class TestFileFitsStub(PillowTestCase):
 | 
					class TestFileFitsStub(PillowTestCase):
 | 
				
			||||||
    def test_open(self):
 | 
					    def test_open(self):
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.format, "FITS")
 | 
					            self.assertEqual(im.format, "FITS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Dummy data from the stub
 | 
					            # Dummy data from the stub
 | 
				
			||||||
        self.assertEqual(im.mode, "F")
 | 
					            self.assertEqual(im.mode, "F")
 | 
				
			||||||
        self.assertEqual(im.size, (1, 1))
 | 
					            self.assertEqual(im.size, (1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -28,19 +28,19 @@ class TestFileFitsStub(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load(self):
 | 
					    def test_load(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot load without an implemented handler
 | 
					            # Act / Assert: stub cannot load without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.load)
 | 
					            self.assertRaises(IOError, im.load)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        dummy_fp = None
 | 
					            dummy_fp = None
 | 
				
			||||||
        dummy_filename = "dummy.filename"
 | 
					            dummy_filename = "dummy.filename"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot save without an implemented handler
 | 
					            # Act / Assert: stub cannot save without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.save, dummy_filename)
 | 
					            self.assertRaises(IOError, im.save, dummy_filename)
 | 
				
			||||||
        self.assertRaises(
 | 
					            self.assertRaises(
 | 
				
			||||||
            IOError, FitsStubImagePlugin._save, im, dummy_fp, dummy_filename
 | 
					                IOError, FitsStubImagePlugin._save, im, dummy_fp, dummy_filename
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import FliImagePlugin, Image
 | 
					from PIL import FliImagePlugin, Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase
 | 
					from .helper import PillowTestCase, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# created as an export of a palette image from Gimp2.6
 | 
					# created as an export of a palette image from Gimp2.6
 | 
				
			||||||
# save as...-> hopper.fli, default options.
 | 
					# save as...-> hopper.fli, default options.
 | 
				
			||||||
| 
						 | 
					@ -12,36 +14,52 @@ animated_test_file = "Tests/images/a.fli"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileFli(PillowTestCase):
 | 
					class TestFileFli(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(static_test_file)
 | 
					        with Image.open(static_test_file) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "P")
 | 
					            self.assertEqual(im.mode, "P")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "FLI")
 | 
					            self.assertEqual(im.format, "FLI")
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(animated_test_file)
 | 
					        with Image.open(animated_test_file) as im:
 | 
				
			||||||
        self.assertEqual(im.mode, "P")
 | 
					            self.assertEqual(im.mode, "P")
 | 
				
			||||||
        self.assertEqual(im.size, (320, 200))
 | 
					            self.assertEqual(im.size, (320, 200))
 | 
				
			||||||
        self.assertEqual(im.format, "FLI")
 | 
					            self.assertEqual(im.format, "FLI")
 | 
				
			||||||
        self.assertEqual(im.info["duration"], 71)
 | 
					            self.assertEqual(im.info["duration"], 71)
 | 
				
			||||||
        self.assertTrue(im.is_animated)
 | 
					            self.assertTrue(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(static_test_file)
 | 
					            im = Image.open(static_test_file)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(static_test_file)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(static_test_file) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tell(self):
 | 
					    def test_tell(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(static_test_file)
 | 
					        with Image.open(static_test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        frame = im.tell()
 | 
					            frame = im.tell()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(frame, 0)
 | 
					            self.assertEqual(frame, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        invalid_file = "Tests/images/flower.jpg"
 | 
					        invalid_file = "Tests/images/flower.jpg"
 | 
				
			||||||
| 
						 | 
					@ -49,50 +67,50 @@ class TestFileFli(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(SyntaxError, FliImagePlugin.FliImageFile, invalid_file)
 | 
					        self.assertRaises(SyntaxError, FliImagePlugin.FliImageFile, invalid_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open(static_test_file)
 | 
					        with Image.open(static_test_file) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(animated_test_file)
 | 
					        with Image.open(animated_test_file) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 384)
 | 
					            self.assertEqual(im.n_frames, 384)
 | 
				
			||||||
        self.assertTrue(im.is_animated)
 | 
					            self.assertTrue(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open(animated_test_file)
 | 
					        with Image.open(animated_test_file) as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_tell(self):
 | 
					    def test_seek_tell(self):
 | 
				
			||||||
        im = Image.open(animated_test_file)
 | 
					        with Image.open(animated_test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 0)
 | 
					            self.assertEqual(layer_number, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 0)
 | 
					            self.assertEqual(layer_number, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 1)
 | 
					            self.assertEqual(layer_number, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(2)
 | 
					            im.seek(2)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 2)
 | 
					            self.assertEqual(layer_number, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 1)
 | 
					            self.assertEqual(layer_number, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek(self):
 | 
					    def test_seek(self):
 | 
				
			||||||
        im = Image.open(animated_test_file)
 | 
					        with Image.open(animated_test_file) as im:
 | 
				
			||||||
        im.seek(50)
 | 
					            im.seek(50)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expected = Image.open("Tests/images/a_fli.png")
 | 
					            with Image.open("Tests/images/a_fli.png") as expected:
 | 
				
			||||||
        self.assert_image_equal(im, expected)
 | 
					                self.assert_image_equal(im, expected)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,8 +10,6 @@ class TestFileGbr(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(SyntaxError, GbrImagePlugin.GbrImageFile, invalid_file)
 | 
					        self.assertRaises(SyntaxError, GbrImagePlugin.GbrImageFile, invalid_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_gbr_file(self):
 | 
					    def test_gbr_file(self):
 | 
				
			||||||
        im = Image.open("Tests/images/gbr.gbr")
 | 
					        with Image.open("Tests/images/gbr.gbr") as im:
 | 
				
			||||||
 | 
					            with Image.open("Tests/images/gbr.png") as target:
 | 
				
			||||||
        target = Image.open("Tests/images/gbr.png")
 | 
					                self.assert_image_equal(target, im)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assert_image_equal(target, im)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,9 +7,9 @@ TEST_GD_FILE = "Tests/images/hopper.gd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileGd(PillowTestCase):
 | 
					class TestFileGd(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = GdImageFile.open(TEST_GD_FILE)
 | 
					        with GdImageFile.open(TEST_GD_FILE) as im:
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "GD")
 | 
					            self.assertEqual(im.format, "GD")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_bad_mode(self):
 | 
					    def test_bad_mode(self):
 | 
				
			||||||
        self.assertRaises(ValueError, GdImageFile.open, TEST_GD_FILE, "bad mode")
 | 
					        self.assertRaises(ValueError, GdImageFile.open, TEST_GD_FILE, "bad mode")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ from io import BytesIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette
 | 
					from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper, netpbm_available, unittest
 | 
					from .helper import PillowTestCase, hopper, is_pypy, netpbm_available, unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from PIL import _webp
 | 
					    from PIL import _webp
 | 
				
			||||||
| 
						 | 
					@ -26,18 +26,34 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            self.skipTest("gif support not available")  # can this happen?
 | 
					            self.skipTest("gif support not available")  # can this happen?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(TEST_GIF)
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "P")
 | 
					            self.assertEqual(im.mode, "P")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "GIF")
 | 
					            self.assertEqual(im.format, "GIF")
 | 
				
			||||||
        self.assertEqual(im.info["version"], b"GIF89a")
 | 
					            self.assertEqual(im.info["version"], b"GIF89a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(TEST_GIF)
 | 
					            im = Image.open(TEST_GIF)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(TEST_GIF)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(TEST_GIF) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
| 
						 | 
					@ -112,67 +128,67 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = hopper()
 | 
					        im = hopper()
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(reread.convert("RGB"), im, 50)
 | 
					            self.assert_image_similar(reread.convert("RGB"), im, 50)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_roundtrip2(self):
 | 
					    def test_roundtrip2(self):
 | 
				
			||||||
        # see https://github.com/python-pillow/Pillow/issues/403
 | 
					        # see https://github.com/python-pillow/Pillow/issues/403
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = Image.open(TEST_GIF)
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        im2 = im.copy()
 | 
					            im2 = im.copy()
 | 
				
			||||||
        im2.save(out)
 | 
					            im2.save(out)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(reread.convert("RGB"), hopper(), 50)
 | 
					            self.assert_image_similar(reread.convert("RGB"), hopper(), 50)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_roundtrip_save_all(self):
 | 
					    def test_roundtrip_save_all(self):
 | 
				
			||||||
        # Single frame image
 | 
					        # Single frame image
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = hopper()
 | 
					        im = hopper()
 | 
				
			||||||
        im.save(out, save_all=True)
 | 
					        im.save(out, save_all=True)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(reread.convert("RGB"), im, 50)
 | 
					            self.assert_image_similar(reread.convert("RGB"), im, 50)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Multiframe image
 | 
					        # Multiframe image
 | 
				
			||||||
        im = Image.open("Tests/images/dispose_bgnd.gif")
 | 
					        with Image.open("Tests/images/dispose_bgnd.gif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					            out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out, save_all=True)
 | 
					            im.save(out, save_all=True)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 5)
 | 
					            self.assertEqual(reread.n_frames, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_headers_saving_for_animated_gifs(self):
 | 
					    def test_headers_saving_for_animated_gifs(self):
 | 
				
			||||||
        important_headers = ["background", "version", "duration", "loop"]
 | 
					        important_headers = ["background", "version", "duration", "loop"]
 | 
				
			||||||
        # Multiframe image
 | 
					        # Multiframe image
 | 
				
			||||||
        im = Image.open("Tests/images/dispose_bgnd.gif")
 | 
					        with Image.open("Tests/images/dispose_bgnd.gif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        info = im.info.copy()
 | 
					            info = im.info.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					            out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out, save_all=True)
 | 
					            im.save(out, save_all=True)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for header in important_headers:
 | 
					            for header in important_headers:
 | 
				
			||||||
            self.assertEqual(info[header], reread.info[header])
 | 
					                self.assertEqual(info[header], reread.info[header])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_handling(self):
 | 
					    def test_palette_handling(self):
 | 
				
			||||||
        # see https://github.com/python-pillow/Pillow/issues/513
 | 
					        # see https://github.com/python-pillow/Pillow/issues/513
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(TEST_GIF)
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        im = im.convert("RGB")
 | 
					            im = im.convert("RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = im.resize((100, 100), Image.LANCZOS)
 | 
					            im = im.resize((100, 100), Image.LANCZOS)
 | 
				
			||||||
        im2 = im.convert("P", palette=Image.ADAPTIVE, colors=256)
 | 
					            im2 = im.convert("P", palette=Image.ADAPTIVE, colors=256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        f = self.tempfile("temp.gif")
 | 
					            f = self.tempfile("temp.gif")
 | 
				
			||||||
        im2.save(f, optimize=True)
 | 
					            im2.save(f, optimize=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(f)
 | 
					        with Image.open(f) as reloaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(im, reloaded.convert("RGB"), 10)
 | 
					            self.assert_image_similar(im, reloaded.convert("RGB"), 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_434(self):
 | 
					    def test_palette_434(self):
 | 
				
			||||||
        # see https://github.com/python-pillow/Pillow/issues/434
 | 
					        # see https://github.com/python-pillow/Pillow/issues/434
 | 
				
			||||||
| 
						 | 
					@ -185,108 +201,115 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            return reloaded
 | 
					            return reloaded
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        orig = "Tests/images/test.colors.gif"
 | 
					        orig = "Tests/images/test.colors.gif"
 | 
				
			||||||
        im = Image.open(orig)
 | 
					        with Image.open(orig) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(im, roundtrip(im), 1)
 | 
					            with roundtrip(im) as reloaded:
 | 
				
			||||||
        self.assert_image_similar(im, roundtrip(im, optimize=True), 1)
 | 
					                self.assert_image_similar(im, reloaded, 1)
 | 
				
			||||||
 | 
					            with roundtrip(im, optimize=True) as reloaded:
 | 
				
			||||||
 | 
					                self.assert_image_similar(im, reloaded, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = im.convert("RGB")
 | 
					            im = im.convert("RGB")
 | 
				
			||||||
        # check automatic P conversion
 | 
					            # check automatic P conversion
 | 
				
			||||||
        reloaded = roundtrip(im).convert("RGB")
 | 
					            with roundtrip(im) as reloaded:
 | 
				
			||||||
        self.assert_image_equal(im, reloaded)
 | 
					                reloaded = reloaded.convert("RGB")
 | 
				
			||||||
 | 
					                self.assert_image_equal(im, reloaded)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
					    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
				
			||||||
    def test_save_netpbm_bmp_mode(self):
 | 
					    def test_save_netpbm_bmp_mode(self):
 | 
				
			||||||
        img = Image.open(TEST_GIF).convert("RGB")
 | 
					        with Image.open(TEST_GIF) as img:
 | 
				
			||||||
 | 
					            img = img.convert("RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tempfile = self.tempfile("temp.gif")
 | 
					            tempfile = self.tempfile("temp.gif")
 | 
				
			||||||
        GifImagePlugin._save_netpbm(img, 0, tempfile)
 | 
					            GifImagePlugin._save_netpbm(img, 0, tempfile)
 | 
				
			||||||
        self.assert_image_similar(img, Image.open(tempfile).convert("RGB"), 0)
 | 
					            with Image.open(tempfile) as reloaded:
 | 
				
			||||||
 | 
					                self.assert_image_similar(img, reloaded.convert("RGB"), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
					    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
				
			||||||
    def test_save_netpbm_l_mode(self):
 | 
					    def test_save_netpbm_l_mode(self):
 | 
				
			||||||
        img = Image.open(TEST_GIF).convert("L")
 | 
					        with Image.open(TEST_GIF) as img:
 | 
				
			||||||
 | 
					            img = img.convert("L")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tempfile = self.tempfile("temp.gif")
 | 
					            tempfile = self.tempfile("temp.gif")
 | 
				
			||||||
        GifImagePlugin._save_netpbm(img, 0, tempfile)
 | 
					            GifImagePlugin._save_netpbm(img, 0, tempfile)
 | 
				
			||||||
        self.assert_image_similar(img, Image.open(tempfile).convert("L"), 0)
 | 
					            with Image.open(tempfile) as reloaded:
 | 
				
			||||||
 | 
					                self.assert_image_similar(img, reloaded.convert("L"), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek(self):
 | 
					    def test_seek(self):
 | 
				
			||||||
        img = Image.open("Tests/images/dispose_none.gif")
 | 
					        with Image.open("Tests/images/dispose_none.gif") as img:
 | 
				
			||||||
        framecount = 0
 | 
					            framecount = 0
 | 
				
			||||||
        try:
 | 
					            try:
 | 
				
			||||||
            while True:
 | 
					                while True:
 | 
				
			||||||
                framecount += 1
 | 
					                    framecount += 1
 | 
				
			||||||
                img.seek(img.tell() + 1)
 | 
					                    img.seek(img.tell() + 1)
 | 
				
			||||||
        except EOFError:
 | 
					            except EOFError:
 | 
				
			||||||
            self.assertEqual(framecount, 5)
 | 
					                self.assertEqual(framecount, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_info(self):
 | 
					    def test_seek_info(self):
 | 
				
			||||||
        im = Image.open("Tests/images/iss634.gif")
 | 
					        with Image.open("Tests/images/iss634.gif") as im:
 | 
				
			||||||
        info = im.info.copy()
 | 
					            info = im.info.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.info, info)
 | 
					            self.assertEqual(im.info, info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_rewind(self):
 | 
					    def test_seek_rewind(self):
 | 
				
			||||||
        im = Image.open("Tests/images/iss634.gif")
 | 
					        with Image.open("Tests/images/iss634.gif") as im:
 | 
				
			||||||
        im.seek(2)
 | 
					            im.seek(2)
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expected = Image.open("Tests/images/iss634.gif")
 | 
					            with Image.open("Tests/images/iss634.gif") as expected:
 | 
				
			||||||
        expected.seek(1)
 | 
					                expected.seek(1)
 | 
				
			||||||
        self.assert_image_equal(im, expected)
 | 
					                self.assert_image_equal(im, expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        for path, n_frames in [[TEST_GIF, 1], ["Tests/images/iss634.gif", 42]]:
 | 
					        for path, n_frames in [[TEST_GIF, 1], ["Tests/images/iss634.gif", 42]]:
 | 
				
			||||||
            # Test is_animated before n_frames
 | 
					            # Test is_animated before n_frames
 | 
				
			||||||
            im = Image.open(path)
 | 
					            with Image.open(path) as im:
 | 
				
			||||||
            self.assertEqual(im.is_animated, n_frames != 1)
 | 
					                self.assertEqual(im.is_animated, n_frames != 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Test is_animated after n_frames
 | 
					            # Test is_animated after n_frames
 | 
				
			||||||
            im = Image.open(path)
 | 
					            with Image.open(path) as im:
 | 
				
			||||||
            self.assertEqual(im.n_frames, n_frames)
 | 
					                self.assertEqual(im.n_frames, n_frames)
 | 
				
			||||||
            self.assertEqual(im.is_animated, n_frames != 1)
 | 
					                self.assertEqual(im.is_animated, n_frames != 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open(TEST_GIF)
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose_none(self):
 | 
					    def test_dispose_none(self):
 | 
				
			||||||
        img = Image.open("Tests/images/dispose_none.gif")
 | 
					        with Image.open("Tests/images/dispose_none.gif") as img:
 | 
				
			||||||
        try:
 | 
					            try:
 | 
				
			||||||
            while True:
 | 
					                while True:
 | 
				
			||||||
                img.seek(img.tell() + 1)
 | 
					                    img.seek(img.tell() + 1)
 | 
				
			||||||
                self.assertEqual(img.disposal_method, 1)
 | 
					                    self.assertEqual(img.disposal_method, 1)
 | 
				
			||||||
        except EOFError:
 | 
					            except EOFError:
 | 
				
			||||||
            pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose_background(self):
 | 
					    def test_dispose_background(self):
 | 
				
			||||||
        img = Image.open("Tests/images/dispose_bgnd.gif")
 | 
					        with Image.open("Tests/images/dispose_bgnd.gif") as img:
 | 
				
			||||||
        try:
 | 
					            try:
 | 
				
			||||||
            while True:
 | 
					                while True:
 | 
				
			||||||
                img.seek(img.tell() + 1)
 | 
					                    img.seek(img.tell() + 1)
 | 
				
			||||||
                self.assertEqual(img.disposal_method, 2)
 | 
					                    self.assertEqual(img.disposal_method, 2)
 | 
				
			||||||
        except EOFError:
 | 
					            except EOFError:
 | 
				
			||||||
            pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose_previous(self):
 | 
					    def test_dispose_previous(self):
 | 
				
			||||||
        img = Image.open("Tests/images/dispose_prev.gif")
 | 
					        with Image.open("Tests/images/dispose_prev.gif") as img:
 | 
				
			||||||
        try:
 | 
					            try:
 | 
				
			||||||
            while True:
 | 
					                while True:
 | 
				
			||||||
                img.seek(img.tell() + 1)
 | 
					                    img.seek(img.tell() + 1)
 | 
				
			||||||
                self.assertEqual(img.disposal_method, 3)
 | 
					                    self.assertEqual(img.disposal_method, 3)
 | 
				
			||||||
        except EOFError:
 | 
					            except EOFError:
 | 
				
			||||||
            pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_dispose(self):
 | 
					    def test_save_dispose(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -299,10 +322,10 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            im_list[0].save(
 | 
					            im_list[0].save(
 | 
				
			||||||
                out, save_all=True, append_images=im_list[1:], disposal=method
 | 
					                out, save_all=True, append_images=im_list[1:], disposal=method
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            img = Image.open(out)
 | 
					            with Image.open(out) as img:
 | 
				
			||||||
            for _ in range(2):
 | 
					                for _ in range(2):
 | 
				
			||||||
                img.seek(img.tell() + 1)
 | 
					                    img.seek(img.tell() + 1)
 | 
				
			||||||
                self.assertEqual(img.disposal_method, method)
 | 
					                    self.assertEqual(img.disposal_method, method)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # check per frame disposal
 | 
					        # check per frame disposal
 | 
				
			||||||
        im_list[0].save(
 | 
					        im_list[0].save(
 | 
				
			||||||
| 
						 | 
					@ -312,11 +335,11 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            disposal=tuple(range(len(im_list))),
 | 
					            disposal=tuple(range(len(im_list))),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        img = Image.open(out)
 | 
					        with Image.open(out) as img:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in range(2):
 | 
					            for i in range(2):
 | 
				
			||||||
            img.seek(img.tell() + 1)
 | 
					                img.seek(img.tell() + 1)
 | 
				
			||||||
            self.assertEqual(img.disposal_method, i + 1)
 | 
					                self.assertEqual(img.disposal_method, i + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose2_palette(self):
 | 
					    def test_dispose2_palette(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -336,17 +359,16 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im_list[0].save(out, save_all=True, append_images=im_list[1:], disposal=2)
 | 
					        im_list[0].save(out, save_all=True, append_images=im_list[1:], disposal=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        img = Image.open(out)
 | 
					        with Image.open(out) as img:
 | 
				
			||||||
 | 
					            for i, circle in enumerate(circles):
 | 
				
			||||||
 | 
					                img.seek(i)
 | 
				
			||||||
 | 
					                rgb_img = img.convert("RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i, circle in enumerate(circles):
 | 
					                # Check top left pixel matches background
 | 
				
			||||||
            img.seek(i)
 | 
					                self.assertEqual(rgb_img.getpixel((0, 0)), (255, 0, 0))
 | 
				
			||||||
            rgb_img = img.convert("RGB")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Check top left pixel matches background
 | 
					                # Center remains red every frame
 | 
				
			||||||
            self.assertEqual(rgb_img.getpixel((0, 0)), (255, 0, 0))
 | 
					                self.assertEqual(rgb_img.getpixel((50, 50)), circle)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Center remains red every frame
 | 
					 | 
				
			||||||
            self.assertEqual(rgb_img.getpixel((50, 50)), circle)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose2_diff(self):
 | 
					    def test_dispose2_diff(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -375,20 +397,19 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            out, save_all=True, append_images=im_list[1:], disposal=2, transparency=0
 | 
					            out, save_all=True, append_images=im_list[1:], disposal=2, transparency=0
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        img = Image.open(out)
 | 
					        with Image.open(out) as img:
 | 
				
			||||||
 | 
					            for i, colours in enumerate(circles):
 | 
				
			||||||
 | 
					                img.seek(i)
 | 
				
			||||||
 | 
					                rgb_img = img.convert("RGBA")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i, colours in enumerate(circles):
 | 
					                # Check left circle is correct colour
 | 
				
			||||||
            img.seek(i)
 | 
					                self.assertEqual(rgb_img.getpixel((20, 50)), colours[0])
 | 
				
			||||||
            rgb_img = img.convert("RGBA")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Check left circle is correct colour
 | 
					                # Check right circle is correct colour
 | 
				
			||||||
            self.assertEqual(rgb_img.getpixel((20, 50)), colours[0])
 | 
					                self.assertEqual(rgb_img.getpixel((80, 50)), colours[1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Check right circle is correct colour
 | 
					                # Check BG is correct colour
 | 
				
			||||||
            self.assertEqual(rgb_img.getpixel((80, 50)), colours[1])
 | 
					                self.assertEqual(rgb_img.getpixel((1, 1)), (255, 255, 255, 0))
 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Check BG is correct colour
 | 
					 | 
				
			||||||
            self.assertEqual(rgb_img.getpixel((1, 1)), (255, 255, 255, 0))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dispose2_background(self):
 | 
					    def test_dispose2_background(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -411,17 +432,17 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            out, save_all=True, append_images=im_list[1:], disposal=[0, 2], background=1
 | 
					            out, save_all=True, append_images=im_list[1:], disposal=[0, 2], background=1
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(out)
 | 
					        with Image.open(out) as im:
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        self.assertEqual(im.getpixel((0, 0)), 0)
 | 
					            self.assertEqual(im.getpixel((0, 0)), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_iss634(self):
 | 
					    def test_iss634(self):
 | 
				
			||||||
        img = Image.open("Tests/images/iss634.gif")
 | 
					        with Image.open("Tests/images/iss634.gif") as img:
 | 
				
			||||||
        # seek to the second frame
 | 
					            # seek to the second frame
 | 
				
			||||||
        img.seek(img.tell() + 1)
 | 
					            img.seek(img.tell() + 1)
 | 
				
			||||||
        # all transparent pixels should be replaced with the color from the
 | 
					            # all transparent pixels should be replaced with the color from the
 | 
				
			||||||
        # first frame
 | 
					            # first frame
 | 
				
			||||||
        self.assertEqual(img.histogram()[img.info["transparency"]], 0)
 | 
					            self.assertEqual(img.histogram()[img.info["transparency"]], 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_duration(self):
 | 
					    def test_duration(self):
 | 
				
			||||||
        duration = 1000
 | 
					        duration = 1000
 | 
				
			||||||
| 
						 | 
					@ -433,8 +454,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        im.info["duration"] = 100
 | 
					        im.info["duration"] = 100
 | 
				
			||||||
        im.save(out, duration=duration)
 | 
					        im.save(out, duration=duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual(reread.info["duration"], duration)
 | 
					            self.assertEqual(reread.info["duration"], duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multiple_duration(self):
 | 
					    def test_multiple_duration(self):
 | 
				
			||||||
        duration_list = [1000, 2000, 3000]
 | 
					        duration_list = [1000, 2000, 3000]
 | 
				
			||||||
| 
						 | 
					@ -450,27 +471,27 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        im_list[0].save(
 | 
					        im_list[0].save(
 | 
				
			||||||
            out, save_all=True, append_images=im_list[1:], duration=duration_list
 | 
					            out, save_all=True, append_images=im_list[1:], duration=duration_list
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for duration in duration_list:
 | 
					            for duration in duration_list:
 | 
				
			||||||
            self.assertEqual(reread.info["duration"], duration)
 | 
					                self.assertEqual(reread.info["duration"], duration)
 | 
				
			||||||
            try:
 | 
					                try:
 | 
				
			||||||
                reread.seek(reread.tell() + 1)
 | 
					                    reread.seek(reread.tell() + 1)
 | 
				
			||||||
            except EOFError:
 | 
					                except EOFError:
 | 
				
			||||||
                pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # duration as tuple
 | 
					        # duration as tuple
 | 
				
			||||||
        im_list[0].save(
 | 
					        im_list[0].save(
 | 
				
			||||||
            out, save_all=True, append_images=im_list[1:], duration=tuple(duration_list)
 | 
					            out, save_all=True, append_images=im_list[1:], duration=tuple(duration_list)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for duration in duration_list:
 | 
					            for duration in duration_list:
 | 
				
			||||||
            self.assertEqual(reread.info["duration"], duration)
 | 
					                self.assertEqual(reread.info["duration"], duration)
 | 
				
			||||||
            try:
 | 
					                try:
 | 
				
			||||||
                reread.seek(reread.tell() + 1)
 | 
					                    reread.seek(reread.tell() + 1)
 | 
				
			||||||
            except EOFError:
 | 
					                except EOFError:
 | 
				
			||||||
                pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_identical_frames(self):
 | 
					    def test_identical_frames(self):
 | 
				
			||||||
        duration_list = [1000, 1500, 2000, 4000]
 | 
					        duration_list = [1000, 1500, 2000, 4000]
 | 
				
			||||||
| 
						 | 
					@ -487,13 +508,13 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        im_list[0].save(
 | 
					        im_list[0].save(
 | 
				
			||||||
            out, save_all=True, append_images=im_list[1:], duration=duration_list
 | 
					            out, save_all=True, append_images=im_list[1:], duration=duration_list
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert that the first three frames were combined
 | 
					            # Assert that the first three frames were combined
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 2)
 | 
					            self.assertEqual(reread.n_frames, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert that the new duration is the total of the identical frames
 | 
					            # Assert that the new duration is the total of the identical frames
 | 
				
			||||||
        self.assertEqual(reread.info["duration"], 4500)
 | 
					            self.assertEqual(reread.info["duration"], 4500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_identical_frames_to_single_frame(self):
 | 
					    def test_identical_frames_to_single_frame(self):
 | 
				
			||||||
        for duration in ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500):
 | 
					        for duration in ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500):
 | 
				
			||||||
| 
						 | 
					@ -507,13 +528,12 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            im_list[0].save(
 | 
					            im_list[0].save(
 | 
				
			||||||
                out, save_all=True, append_images=im_list[1:], duration=duration
 | 
					                out, save_all=True, append_images=im_list[1:], duration=duration
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            reread = Image.open(out)
 | 
					            with Image.open(out) as reread:
 | 
				
			||||||
 | 
					                # Assert that all frames were combined
 | 
				
			||||||
 | 
					                self.assertEqual(reread.n_frames, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Assert that all frames were combined
 | 
					                # Assert that the new duration is the total of the identical frames
 | 
				
			||||||
            self.assertEqual(reread.n_frames, 1)
 | 
					                self.assertEqual(reread.info["duration"], 8500)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Assert that the new duration is the total of the identical frames
 | 
					 | 
				
			||||||
            self.assertEqual(reread.info["duration"], 8500)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_number_of_loops(self):
 | 
					    def test_number_of_loops(self):
 | 
				
			||||||
        number_of_loops = 2
 | 
					        number_of_loops = 2
 | 
				
			||||||
| 
						 | 
					@ -521,18 +541,18 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = Image.new("L", (100, 100), "#000")
 | 
					        im = Image.new("L", (100, 100), "#000")
 | 
				
			||||||
        im.save(out, loop=number_of_loops)
 | 
					        im.save(out, loop=number_of_loops)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reread.info["loop"], number_of_loops)
 | 
					            self.assertEqual(reread.info["loop"], number_of_loops)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_background(self):
 | 
					    def test_background(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = Image.new("L", (100, 100), "#000")
 | 
					        im = Image.new("L", (100, 100), "#000")
 | 
				
			||||||
        im.info["background"] = 1
 | 
					        im.info["background"] = 1
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reread.info["background"], im.info["background"])
 | 
					            self.assertEqual(reread.info["background"], im.info["background"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if HAVE_WEBP and _webp.HAVE_WEBPANIM:
 | 
					        if HAVE_WEBP and _webp.HAVE_WEBPANIM:
 | 
				
			||||||
            im = Image.open("Tests/images/hopper.webp")
 | 
					            im = Image.open("Tests/images/hopper.webp")
 | 
				
			||||||
| 
						 | 
					@ -540,16 +560,18 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            im.save(out)
 | 
					            im.save(out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_comment(self):
 | 
					    def test_comment(self):
 | 
				
			||||||
        im = Image.open(TEST_GIF)
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        self.assertEqual(im.info["comment"], b"File written by Adobe Photoshop\xa8 4.0")
 | 
					            self.assertEqual(
 | 
				
			||||||
 | 
					                im.info["comment"], b"File written by Adobe Photoshop\xa8 4.0"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					            out = self.tempfile("temp.gif")
 | 
				
			||||||
        im = Image.new("L", (100, 100), "#000")
 | 
					            im = Image.new("L", (100, 100), "#000")
 | 
				
			||||||
        im.info["comment"] = b"Test comment text"
 | 
					            im.info["comment"] = b"Test comment text"
 | 
				
			||||||
        im.save(out)
 | 
					            im.save(out)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reread.info["comment"], im.info["comment"])
 | 
					            self.assertEqual(reread.info["comment"], im.info["comment"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_comment_over_255(self):
 | 
					    def test_comment_over_255(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -559,22 +581,22 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
            comment += comment
 | 
					            comment += comment
 | 
				
			||||||
        im.info["comment"] = comment
 | 
					        im.info["comment"] = comment
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reread.info["comment"], comment)
 | 
					            self.assertEqual(reread.info["comment"], comment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_zero_comment_subblocks(self):
 | 
					    def test_zero_comment_subblocks(self):
 | 
				
			||||||
        im = Image.open("Tests/images/hopper_zero_comment_subblocks.gif")
 | 
					        with Image.open("Tests/images/hopper_zero_comment_subblocks.gif") as im:
 | 
				
			||||||
        expected = Image.open(TEST_GIF)
 | 
					            with Image.open(TEST_GIF) as expected:
 | 
				
			||||||
        self.assert_image_equal(im, expected)
 | 
					                self.assert_image_equal(im, expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_version(self):
 | 
					    def test_version(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def assertVersionAfterSave(im, version):
 | 
					        def assertVersionAfterSave(im, version):
 | 
				
			||||||
            im.save(out)
 | 
					            im.save(out)
 | 
				
			||||||
            reread = Image.open(out)
 | 
					            with Image.open(out) as reread:
 | 
				
			||||||
            self.assertEqual(reread.info["version"], version)
 | 
					                self.assertEqual(reread.info["version"], version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that GIF87a is used by default
 | 
					        # Test that GIF87a is used by default
 | 
				
			||||||
        im = Image.new("L", (100, 100), "#000")
 | 
					        im = Image.new("L", (100, 100), "#000")
 | 
				
			||||||
| 
						 | 
					@ -590,12 +612,12 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        assertVersionAfterSave(im, b"GIF89a")
 | 
					        assertVersionAfterSave(im, b"GIF89a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that a GIF87a image is also saved in that format
 | 
					        # Test that a GIF87a image is also saved in that format
 | 
				
			||||||
        im = Image.open("Tests/images/test.colors.gif")
 | 
					        with Image.open("Tests/images/test.colors.gif") as im:
 | 
				
			||||||
        assertVersionAfterSave(im, b"GIF87a")
 | 
					            assertVersionAfterSave(im, b"GIF87a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that a GIF89a image is also saved in that format
 | 
					            # Test that a GIF89a image is also saved in that format
 | 
				
			||||||
        im.info["version"] = b"GIF89a"
 | 
					            im.info["version"] = b"GIF89a"
 | 
				
			||||||
        assertVersionAfterSave(im, b"GIF87a")
 | 
					            assertVersionAfterSave(im, b"GIF87a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_append_images(self):
 | 
					    def test_append_images(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -605,8 +627,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        ims = [Image.new("RGB", (100, 100), color) for color in ["#0f0", "#00f"]]
 | 
					        ims = [Image.new("RGB", (100, 100), color) for color in ["#0f0", "#00f"]]
 | 
				
			||||||
        im.copy().save(out, save_all=True, append_images=ims)
 | 
					        im.copy().save(out, save_all=True, append_images=ims)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 3)
 | 
					            self.assertEqual(reread.n_frames, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Tests appending using a generator
 | 
					        # Tests appending using a generator
 | 
				
			||||||
        def imGenerator(ims):
 | 
					        def imGenerator(ims):
 | 
				
			||||||
| 
						 | 
					@ -615,16 +637,16 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(out, save_all=True, append_images=imGenerator(ims))
 | 
					        im.save(out, save_all=True, append_images=imGenerator(ims))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 3)
 | 
					            self.assertEqual(reread.n_frames, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Tests appending single and multiple frame images
 | 
					        # Tests appending single and multiple frame images
 | 
				
			||||||
        im = Image.open("Tests/images/dispose_none.gif")
 | 
					        with Image.open("Tests/images/dispose_none.gif") as im:
 | 
				
			||||||
        ims = [Image.open("Tests/images/dispose_prev.gif")]
 | 
					            with Image.open("Tests/images/dispose_prev.gif") as im2:
 | 
				
			||||||
        im.save(out, save_all=True, append_images=ims)
 | 
					                im.save(out, save_all=True, append_images=[im2])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 10)
 | 
					            self.assertEqual(reread.n_frames, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_transparent_optimize(self):
 | 
					    def test_transparent_optimize(self):
 | 
				
			||||||
        # from issue #2195, if the transparent color is incorrectly
 | 
					        # from issue #2195, if the transparent color is incorrectly
 | 
				
			||||||
| 
						 | 
					@ -642,9 +664,9 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out, transparency=253)
 | 
					        im.save(out, transparency=253)
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(reloaded.info["transparency"], 253)
 | 
					            self.assertEqual(reloaded.info["transparency"], 253)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_rgb_transparency(self):
 | 
					    def test_rgb_transparency(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -654,8 +676,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        im.info["transparency"] = (255, 0, 0)
 | 
					        im.info["transparency"] = (255, 0, 0)
 | 
				
			||||||
        self.assert_warning(UserWarning, im.save, out)
 | 
					        self.assert_warning(UserWarning, im.save, out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertNotIn("transparency", reloaded.info)
 | 
					            self.assertNotIn("transparency", reloaded.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Multiple frames
 | 
					        # Multiple frames
 | 
				
			||||||
        im = Image.new("RGB", (1, 1))
 | 
					        im = Image.new("RGB", (1, 1))
 | 
				
			||||||
| 
						 | 
					@ -663,8 +685,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        ims = [Image.new("RGB", (1, 1))]
 | 
					        ims = [Image.new("RGB", (1, 1))]
 | 
				
			||||||
        self.assert_warning(UserWarning, im.save, out, save_all=True, append_images=ims)
 | 
					        self.assert_warning(UserWarning, im.save, out, save_all=True, append_images=ims)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertNotIn("transparency", reloaded.info)
 | 
					            self.assertNotIn("transparency", reloaded.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_bbox(self):
 | 
					    def test_bbox(self):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
| 
						 | 
					@ -673,8 +695,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        ims = [Image.new("RGB", (100, 100), "#000")]
 | 
					        ims = [Image.new("RGB", (100, 100), "#000")]
 | 
				
			||||||
        im.save(out, save_all=True, append_images=ims)
 | 
					        im.save(out, save_all=True, append_images=ims)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual(reread.n_frames, 2)
 | 
					            self.assertEqual(reread.n_frames, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_save_L(self):
 | 
					    def test_palette_save_L(self):
 | 
				
			||||||
        # generate an L mode image with a separate palette
 | 
					        # generate an L mode image with a separate palette
 | 
				
			||||||
| 
						 | 
					@ -686,9 +708,9 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im_l.save(out, palette=palette)
 | 
					        im_l.save(out, palette=palette)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_equal(reloaded.convert("RGB"), im.convert("RGB"))
 | 
					            self.assert_image_equal(reloaded.convert("RGB"), im.convert("RGB"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_save_P(self):
 | 
					    def test_palette_save_P(self):
 | 
				
			||||||
        # pass in a different palette, then construct what the image
 | 
					        # pass in a different palette, then construct what the image
 | 
				
			||||||
| 
						 | 
					@ -701,9 +723,9 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out, palette=palette)
 | 
					        im.save(out, palette=palette)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        im.putpalette(palette)
 | 
					            im.putpalette(palette)
 | 
				
			||||||
        self.assert_image_equal(reloaded, im)
 | 
					            self.assert_image_equal(reloaded, im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_save_ImagePalette(self):
 | 
					    def test_palette_save_ImagePalette(self):
 | 
				
			||||||
        # pass in a different palette, as an ImagePalette.ImagePalette
 | 
					        # pass in a different palette, as an ImagePalette.ImagePalette
 | 
				
			||||||
| 
						 | 
					@ -715,9 +737,9 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out, palette=palette)
 | 
					        im.save(out, palette=palette)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        im.putpalette(palette)
 | 
					            im.putpalette(palette)
 | 
				
			||||||
        self.assert_image_equal(reloaded, im)
 | 
					            self.assert_image_equal(reloaded, im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_I(self):
 | 
					    def test_save_I(self):
 | 
				
			||||||
        # Test saving something that would trigger the auto-convert to 'L'
 | 
					        # Test saving something that would trigger the auto-convert to 'L'
 | 
				
			||||||
| 
						 | 
					@ -727,8 +749,8 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.gif")
 | 
					        out = self.tempfile("temp.gif")
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assert_image_equal(reloaded.convert("L"), im.convert("L"))
 | 
					            self.assert_image_equal(reloaded.convert("L"), im.convert("L"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getdata(self):
 | 
					    def test_getdata(self):
 | 
				
			||||||
        # test getheader/getdata against legacy values
 | 
					        # test getheader/getdata against legacy values
 | 
				
			||||||
| 
						 | 
					@ -759,14 +781,13 @@ class TestFileGif(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_lzw_bits(self):
 | 
					    def test_lzw_bits(self):
 | 
				
			||||||
        # see https://github.com/python-pillow/Pillow/issues/2811
 | 
					        # see https://github.com/python-pillow/Pillow/issues/2811
 | 
				
			||||||
        im = Image.open("Tests/images/issue_2811.gif")
 | 
					        with Image.open("Tests/images/issue_2811.gif") as im:
 | 
				
			||||||
 | 
					            self.assertEqual(im.tile[0][3][0], 11)  # LZW bits
 | 
				
			||||||
        self.assertEqual(im.tile[0][3][0], 11)  # LZW bits
 | 
					            # codec error prepatch
 | 
				
			||||||
        # codec error prepatch
 | 
					            im.load()
 | 
				
			||||||
        im.load()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_extents(self):
 | 
					    def test_extents(self):
 | 
				
			||||||
        im = Image.open("Tests/images/test_extents.gif")
 | 
					        with Image.open("Tests/images/test_extents.gif") as im:
 | 
				
			||||||
        self.assertEqual(im.size, (100, 100))
 | 
					            self.assertEqual(im.size, (100, 100))
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        self.assertEqual(im.size, (150, 150))
 | 
					            self.assertEqual(im.size, (150, 150))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,14 @@ TEST_FILE = "Tests/images/WAlaska.wind.7days.grb"
 | 
				
			||||||
class TestFileGribStub(PillowTestCase):
 | 
					class TestFileGribStub(PillowTestCase):
 | 
				
			||||||
    def test_open(self):
 | 
					    def test_open(self):
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.format, "GRIB")
 | 
					            self.assertEqual(im.format, "GRIB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Dummy data from the stub
 | 
					            # Dummy data from the stub
 | 
				
			||||||
        self.assertEqual(im.mode, "F")
 | 
					            self.assertEqual(im.mode, "F")
 | 
				
			||||||
        self.assertEqual(im.size, (1, 1))
 | 
					            self.assertEqual(im.size, (1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -28,10 +28,10 @@ class TestFileGribStub(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load(self):
 | 
					    def test_load(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot load without an implemented handler
 | 
					            # Act / Assert: stub cannot load without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.load)
 | 
					            self.assertRaises(IOError, im.load)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,14 @@ TEST_FILE = "Tests/images/hdf5.h5"
 | 
				
			||||||
class TestFileHdf5Stub(PillowTestCase):
 | 
					class TestFileHdf5Stub(PillowTestCase):
 | 
				
			||||||
    def test_open(self):
 | 
					    def test_open(self):
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.format, "HDF5")
 | 
					            self.assertEqual(im.format, "HDF5")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Dummy data from the stub
 | 
					            # Dummy data from the stub
 | 
				
			||||||
        self.assertEqual(im.mode, "F")
 | 
					            self.assertEqual(im.mode, "F")
 | 
				
			||||||
        self.assertEqual(im.size, (1, 1))
 | 
					            self.assertEqual(im.size, (1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -28,19 +28,19 @@ class TestFileHdf5Stub(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load(self):
 | 
					    def test_load(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot load without an implemented handler
 | 
					            # Act / Assert: stub cannot load without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.load)
 | 
					            self.assertRaises(IOError, im.load)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        dummy_fp = None
 | 
					            dummy_fp = None
 | 
				
			||||||
        dummy_filename = "dummy.filename"
 | 
					            dummy_filename = "dummy.filename"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert: stub cannot save without an implemented handler
 | 
					            # Act / Assert: stub cannot save without an implemented handler
 | 
				
			||||||
        self.assertRaises(IOError, im.save, dummy_filename)
 | 
					            self.assertRaises(IOError, im.save, dummy_filename)
 | 
				
			||||||
        self.assertRaises(
 | 
					            self.assertRaises(
 | 
				
			||||||
            IOError, Hdf5StubImagePlugin._save, im, dummy_fp, dummy_filename
 | 
					                IOError, Hdf5StubImagePlugin._save, im, dummy_fp, dummy_filename
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,14 +15,14 @@ class TestFileIcns(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        # Loading this icon by default should result in the largest size
 | 
					        # Loading this icon by default should result in the largest size
 | 
				
			||||||
        # (512x512@2x) being loaded
 | 
					        # (512x512@2x) being loaded
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert that there is no unclosed file warning
 | 
					            # Assert that there is no unclosed file warning
 | 
				
			||||||
        self.assert_warning(None, im.load)
 | 
					            self.assert_warning(None, im.load)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.mode, "RGBA")
 | 
					            self.assertEqual(im.mode, "RGBA")
 | 
				
			||||||
        self.assertEqual(im.size, (1024, 1024))
 | 
					            self.assertEqual(im.size, (1024, 1024))
 | 
				
			||||||
        self.assertEqual(im.format, "ICNS")
 | 
					            self.assertEqual(im.format, "ICNS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipIf(sys.platform != "darwin", "requires macOS")
 | 
					    @unittest.skipIf(sys.platform != "darwin", "requires macOS")
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
| 
						 | 
					@ -56,31 +56,31 @@ class TestFileIcns(PillowTestCase):
 | 
				
			||||||
    def test_sizes(self):
 | 
					    def test_sizes(self):
 | 
				
			||||||
        # Check that we can load all of the sizes, and that the final pixel
 | 
					        # Check that we can load all of the sizes, and that the final pixel
 | 
				
			||||||
        # dimensions are as expected
 | 
					        # dimensions are as expected
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        for w, h, r in im.info["sizes"]:
 | 
					            for w, h, r in im.info["sizes"]:
 | 
				
			||||||
            wr = w * r
 | 
					                wr = w * r
 | 
				
			||||||
            hr = h * r
 | 
					                hr = h * r
 | 
				
			||||||
            im.size = (w, h, r)
 | 
					                im.size = (w, h, r)
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
            self.assertEqual(im.mode, "RGBA")
 | 
					                self.assertEqual(im.mode, "RGBA")
 | 
				
			||||||
            self.assertEqual(im.size, (wr, hr))
 | 
					                self.assertEqual(im.size, (wr, hr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check that we cannot load an incorrect size
 | 
					            # Check that we cannot load an incorrect size
 | 
				
			||||||
        with self.assertRaises(ValueError):
 | 
					            with self.assertRaises(ValueError):
 | 
				
			||||||
            im.size = (1, 1)
 | 
					                im.size = (1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_older_icon(self):
 | 
					    def test_older_icon(self):
 | 
				
			||||||
        # This icon was made with Icon Composer rather than iconutil; it still
 | 
					        # This icon was made with Icon Composer rather than iconutil; it still
 | 
				
			||||||
        # uses PNG rather than JP2, however (since it was made on 10.9).
 | 
					        # uses PNG rather than JP2, however (since it was made on 10.9).
 | 
				
			||||||
        im = Image.open("Tests/images/pillow2.icns")
 | 
					        with Image.open("Tests/images/pillow2.icns") as im:
 | 
				
			||||||
        for w, h, r in im.info["sizes"]:
 | 
					            for w, h, r in im.info["sizes"]:
 | 
				
			||||||
            wr = w * r
 | 
					                wr = w * r
 | 
				
			||||||
            hr = h * r
 | 
					                hr = h * r
 | 
				
			||||||
            im2 = Image.open("Tests/images/pillow2.icns")
 | 
					                with Image.open("Tests/images/pillow2.icns") as im2:
 | 
				
			||||||
            im2.size = (w, h, r)
 | 
					                    im2.size = (w, h, r)
 | 
				
			||||||
            im2.load()
 | 
					                    im2.load()
 | 
				
			||||||
            self.assertEqual(im2.mode, "RGBA")
 | 
					                    self.assertEqual(im2.mode, "RGBA")
 | 
				
			||||||
            self.assertEqual(im2.size, (wr, hr))
 | 
					                    self.assertEqual(im2.size, (wr, hr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_jp2_icon(self):
 | 
					    def test_jp2_icon(self):
 | 
				
			||||||
        # This icon was made by using Uli Kusterer's oldiconutil to replace
 | 
					        # This icon was made by using Uli Kusterer's oldiconutil to replace
 | 
				
			||||||
| 
						 | 
					@ -93,15 +93,15 @@ class TestFileIcns(PillowTestCase):
 | 
				
			||||||
        if not enable_jpeg2k:
 | 
					        if not enable_jpeg2k:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/pillow3.icns")
 | 
					        with Image.open("Tests/images/pillow3.icns") as im:
 | 
				
			||||||
        for w, h, r in im.info["sizes"]:
 | 
					            for w, h, r in im.info["sizes"]:
 | 
				
			||||||
            wr = w * r
 | 
					                wr = w * r
 | 
				
			||||||
            hr = h * r
 | 
					                hr = h * r
 | 
				
			||||||
            im2 = Image.open("Tests/images/pillow3.icns")
 | 
					                with Image.open("Tests/images/pillow3.icns") as im2:
 | 
				
			||||||
            im2.size = (w, h, r)
 | 
					                    im2.size = (w, h, r)
 | 
				
			||||||
            im2.load()
 | 
					                    im2.load()
 | 
				
			||||||
            self.assertEqual(im2.mode, "RGBA")
 | 
					                    self.assertEqual(im2.mode, "RGBA")
 | 
				
			||||||
            self.assertEqual(im2.size, (wr, hr))
 | 
					                    self.assertEqual(im2.size, (wr, hr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getimage(self):
 | 
					    def test_getimage(self):
 | 
				
			||||||
        with open(TEST_FILE, "rb") as fp:
 | 
					        with open(TEST_FILE, "rb") as fp:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,8 +9,8 @@ TEST_ICO_FILE = "Tests/images/hopper.ico"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileIco(PillowTestCase):
 | 
					class TestFileIco(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(TEST_ICO_FILE)
 | 
					        with Image.open(TEST_ICO_FILE) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGBA")
 | 
					        self.assertEqual(im.mode, "RGBA")
 | 
				
			||||||
        self.assertEqual(im.size, (16, 16))
 | 
					        self.assertEqual(im.size, (16, 16))
 | 
				
			||||||
        self.assertEqual(im.format, "ICO")
 | 
					        self.assertEqual(im.format, "ICO")
 | 
				
			||||||
| 
						 | 
					@ -46,22 +46,22 @@ class TestFileIco(PillowTestCase):
 | 
				
			||||||
        self.assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS))
 | 
					        self.assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_incorrect_size(self):
 | 
					    def test_incorrect_size(self):
 | 
				
			||||||
        im = Image.open(TEST_ICO_FILE)
 | 
					        with Image.open(TEST_ICO_FILE) as im:
 | 
				
			||||||
        with self.assertRaises(ValueError):
 | 
					            with self.assertRaises(ValueError):
 | 
				
			||||||
            im.size = (1, 1)
 | 
					                im.size = (1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_256x256(self):
 | 
					    def test_save_256x256(self):
 | 
				
			||||||
        """Issue #2264 https://github.com/python-pillow/Pillow/issues/2264"""
 | 
					        """Issue #2264 https://github.com/python-pillow/Pillow/issues/2264"""
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open("Tests/images/hopper_256x256.ico")
 | 
					        with Image.open("Tests/images/hopper_256x256.ico") as im:
 | 
				
			||||||
        outfile = self.tempfile("temp_saved_hopper_256x256.ico")
 | 
					            outfile = self.tempfile("temp_saved_hopper_256x256.ico")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        im.save(outfile)
 | 
					            im.save(outfile)
 | 
				
			||||||
        im_saved = Image.open(outfile)
 | 
					        with Image.open(outfile) as im_saved:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im_saved.size, (256, 256))
 | 
					            self.assertEqual(im_saved.size, (256, 256))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_only_save_relevant_sizes(self):
 | 
					    def test_only_save_relevant_sizes(self):
 | 
				
			||||||
        """Issue #2266 https://github.com/python-pillow/Pillow/issues/2266
 | 
					        """Issue #2266 https://github.com/python-pillow/Pillow/issues/2266
 | 
				
			||||||
| 
						 | 
					@ -69,35 +69,35 @@ class TestFileIco(PillowTestCase):
 | 
				
			||||||
        and not in 16x16, 24x24, 32x32, 48x48, 48x48, 48x48, 48x48 sizes
 | 
					        and not in 16x16, 24x24, 32x32, 48x48, 48x48, 48x48, 48x48 sizes
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open("Tests/images/python.ico")  # 16x16, 32x32, 48x48
 | 
					        with Image.open("Tests/images/python.ico") as im:  # 16x16, 32x32, 48x48
 | 
				
			||||||
        outfile = self.tempfile("temp_saved_python.ico")
 | 
					            outfile = self.tempfile("temp_saved_python.ico")
 | 
				
			||||||
 | 
					            # Act
 | 
				
			||||||
 | 
					            im.save(outfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        with Image.open(outfile) as im_saved:
 | 
				
			||||||
        im.save(outfile)
 | 
					            # Assert
 | 
				
			||||||
        im_saved = Image.open(outfile)
 | 
					            self.assertEqual(
 | 
				
			||||||
 | 
					                im_saved.info["sizes"], {(16, 16), (24, 24), (32, 32), (48, 48)}
 | 
				
			||||||
        # Assert
 | 
					            )
 | 
				
			||||||
        self.assertEqual(
 | 
					 | 
				
			||||||
            im_saved.info["sizes"], {(16, 16), (24, 24), (32, 32), (48, 48)}
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_unexpected_size(self):
 | 
					    def test_unexpected_size(self):
 | 
				
			||||||
        # This image has been manually hexedited to state that it is 16x32
 | 
					        # This image has been manually hexedited to state that it is 16x32
 | 
				
			||||||
        # while the image within is still 16x16
 | 
					        # while the image within is still 16x16
 | 
				
			||||||
        im = self.assert_warning(
 | 
					        def open():
 | 
				
			||||||
            UserWarning, Image.open, "Tests/images/hopper_unexpected.ico"
 | 
					            with Image.open("Tests/images/hopper_unexpected.ico") as im:
 | 
				
			||||||
        )
 | 
					                self.assertEqual(im.size, (16, 16))
 | 
				
			||||||
        self.assertEqual(im.size, (16, 16))
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(UserWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_draw_reloaded(self):
 | 
					    def test_draw_reloaded(self):
 | 
				
			||||||
        im = Image.open(TEST_ICO_FILE)
 | 
					        with Image.open(TEST_ICO_FILE) as im:
 | 
				
			||||||
        outfile = self.tempfile("temp_saved_hopper_draw.ico")
 | 
					            outfile = self.tempfile("temp_saved_hopper_draw.ico")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        draw = ImageDraw.Draw(im)
 | 
					            draw = ImageDraw.Draw(im)
 | 
				
			||||||
        draw.line((0, 0) + im.size, "#f00")
 | 
					            draw.line((0, 0) + im.size, "#f00")
 | 
				
			||||||
        im.save(outfile)
 | 
					            im.save(outfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(outfile)
 | 
					        with Image.open(outfile) as im:
 | 
				
			||||||
        im.save("Tests/images/hopper_draw.ico")
 | 
					            im.save("Tests/images/hopper_draw.ico")
 | 
				
			||||||
        reloaded = Image.open("Tests/images/hopper_draw.ico")
 | 
					            with Image.open("Tests/images/hopper_draw.ico") as reloaded:
 | 
				
			||||||
        self.assert_image_equal(im, reloaded)
 | 
					                self.assert_image_equal(im, reloaded)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, ImImagePlugin
 | 
					from PIL import Image, ImImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper
 | 
					from .helper import PillowTestCase, hopper, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# sample im
 | 
					# sample im
 | 
				
			||||||
TEST_IM = "Tests/images/hopper.im"
 | 
					TEST_IM = "Tests/images/hopper.im"
 | 
				
			||||||
| 
						 | 
					@ -8,53 +10,69 @@ TEST_IM = "Tests/images/hopper.im"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFileIm(PillowTestCase):
 | 
					class TestFileIm(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(TEST_IM)
 | 
					        with Image.open(TEST_IM) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGB")
 | 
					            self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "IM")
 | 
					            self.assertEqual(im.format, "IM")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(TEST_IM)
 | 
					            im = Image.open(TEST_IM)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(TEST_IM)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(TEST_IM) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tell(self):
 | 
					    def test_tell(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_IM)
 | 
					        with Image.open(TEST_IM) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        frame = im.tell()
 | 
					            frame = im.tell()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertEqual(frame, 0)
 | 
					        self.assertEqual(frame, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open(TEST_IM)
 | 
					        with Image.open(TEST_IM) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open(TEST_IM)
 | 
					        with Image.open(TEST_IM) as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_roundtrip(self):
 | 
					    def test_roundtrip(self):
 | 
				
			||||||
        for mode in ["RGB", "P", "PA"]:
 | 
					        for mode in ["RGB", "P", "PA"]:
 | 
				
			||||||
            out = self.tempfile("temp.im")
 | 
					            out = self.tempfile("temp.im")
 | 
				
			||||||
            im = hopper(mode)
 | 
					            im = hopper(mode)
 | 
				
			||||||
            im.save(out)
 | 
					            im.save(out)
 | 
				
			||||||
            reread = Image.open(out)
 | 
					            with Image.open(out) as reread:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.assert_image_equal(reread, im)
 | 
					                self.assert_image_equal(reread, im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_unsupported_mode(self):
 | 
					    def test_save_unsupported_mode(self):
 | 
				
			||||||
        out = self.tempfile("temp.im")
 | 
					        out = self.tempfile("temp.im")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,20 +8,20 @@ TEST_FILE = "Tests/images/iptc.jpg"
 | 
				
			||||||
class TestFileIptc(PillowTestCase):
 | 
					class TestFileIptc(PillowTestCase):
 | 
				
			||||||
    def test_getiptcinfo_jpg_none(self):
 | 
					    def test_getiptcinfo_jpg_none(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        iptc = IptcImagePlugin.getiptcinfo(im)
 | 
					            iptc = IptcImagePlugin.getiptcinfo(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertIsNone(iptc)
 | 
					        self.assertIsNone(iptc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getiptcinfo_jpg_found(self):
 | 
					    def test_getiptcinfo_jpg_found(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        iptc = IptcImagePlugin.getiptcinfo(im)
 | 
					            iptc = IptcImagePlugin.getiptcinfo(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertIsInstance(iptc, dict)
 | 
					        self.assertIsInstance(iptc, dict)
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,10 @@ class TestFileIptc(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getiptcinfo_tiff_none(self):
 | 
					    def test_getiptcinfo_tiff_none(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.tif")
 | 
					        with Image.open("Tests/images/hopper.tif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        iptc = IptcImagePlugin.getiptcinfo(im)
 | 
					            iptc = IptcImagePlugin.getiptcinfo(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertIsNone(iptc)
 | 
					        self.assertIsNone(iptc)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,14 +53,14 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_app(self):
 | 
					    def test_app(self):
 | 
				
			||||||
        # Test APP/COM reader (@PIL135)
 | 
					        # Test APP/COM reader (@PIL135)
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            im.applist[0], ("APP0", b"JFIF\x00\x01\x01\x01\x00`\x00`\x00\x00")
 | 
					                im.applist[0], ("APP0", b"JFIF\x00\x01\x01\x01\x00`\x00`\x00\x00")
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            im.applist[1], ("COM", b"File written by Adobe Photoshop\xa8 4.0\x00")
 | 
					                im.applist[1], ("COM", b"File written by Adobe Photoshop\xa8 4.0\x00")
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
        self.assertEqual(len(im.applist), 2)
 | 
					            self.assertEqual(len(im.applist), 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_cmyk(self):
 | 
					    def test_cmyk(self):
 | 
				
			||||||
        # Test CMYK handling.  Thanks to Tim and Charlie for test data,
 | 
					        # Test CMYK handling.  Thanks to Tim and Charlie for test data,
 | 
				
			||||||
| 
						 | 
					@ -99,20 +99,20 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_icc(self):
 | 
					    def test_icc(self):
 | 
				
			||||||
        # Test ICC support
 | 
					        # Test ICC support
 | 
				
			||||||
        im1 = Image.open("Tests/images/rgb.jpg")
 | 
					        with Image.open("Tests/images/rgb.jpg") as im1:
 | 
				
			||||||
        icc_profile = im1.info["icc_profile"]
 | 
					            icc_profile = im1.info["icc_profile"]
 | 
				
			||||||
        self.assertEqual(len(icc_profile), 3144)
 | 
					            self.assertEqual(len(icc_profile), 3144)
 | 
				
			||||||
        # Roundtrip via physical file.
 | 
					            # Roundtrip via physical file.
 | 
				
			||||||
        f = self.tempfile("temp.jpg")
 | 
					            f = self.tempfile("temp.jpg")
 | 
				
			||||||
        im1.save(f, icc_profile=icc_profile)
 | 
					            im1.save(f, icc_profile=icc_profile)
 | 
				
			||||||
        im2 = Image.open(f)
 | 
					        with Image.open(f) as im2:
 | 
				
			||||||
        self.assertEqual(im2.info.get("icc_profile"), icc_profile)
 | 
					            self.assertEqual(im2.info.get("icc_profile"), icc_profile)
 | 
				
			||||||
        # Roundtrip via memory buffer.
 | 
					            # Roundtrip via memory buffer.
 | 
				
			||||||
        im1 = self.roundtrip(hopper())
 | 
					            im1 = self.roundtrip(hopper())
 | 
				
			||||||
        im2 = self.roundtrip(hopper(), icc_profile=icc_profile)
 | 
					            im2 = self.roundtrip(hopper(), icc_profile=icc_profile)
 | 
				
			||||||
        self.assert_image_equal(im1, im2)
 | 
					            self.assert_image_equal(im1, im2)
 | 
				
			||||||
        self.assertFalse(im1.info.get("icc_profile"))
 | 
					            self.assertFalse(im1.info.get("icc_profile"))
 | 
				
			||||||
        self.assertTrue(im2.info.get("icc_profile"))
 | 
					            self.assertTrue(im2.info.get("icc_profile"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_icc_big(self):
 | 
					    def test_icc_big(self):
 | 
				
			||||||
        # Make sure that the "extra" support handles large blocks
 | 
					        # Make sure that the "extra" support handles large blocks
 | 
				
			||||||
| 
						 | 
					@ -205,24 +205,24 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
        im.save(f, "JPEG", quality=90, exif=b"1" * 65532)
 | 
					        im.save(f, "JPEG", quality=90, exif=b"1" * 65532)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif_typeerror(self):
 | 
					    def test_exif_typeerror(self):
 | 
				
			||||||
        im = Image.open("Tests/images/exif_typeerror.jpg")
 | 
					        with Image.open("Tests/images/exif_typeerror.jpg") as im:
 | 
				
			||||||
        # Should not raise a TypeError
 | 
					            # Should not raise a TypeError
 | 
				
			||||||
        im._getexif()
 | 
					            im._getexif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif_gps(self):
 | 
					    def test_exif_gps(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open("Tests/images/exif_gps.jpg")
 | 
					        with Image.open("Tests/images/exif_gps.jpg") as im:
 | 
				
			||||||
        gps_index = 34853
 | 
					            gps_index = 34853
 | 
				
			||||||
        expected_exif_gps = {
 | 
					            expected_exif_gps = {
 | 
				
			||||||
            0: b"\x00\x00\x00\x01",
 | 
					                0: b"\x00\x00\x00\x01",
 | 
				
			||||||
            2: (4294967295, 1),
 | 
					                2: (4294967295, 1),
 | 
				
			||||||
            5: b"\x01",
 | 
					                5: b"\x01",
 | 
				
			||||||
            30: 65535,
 | 
					                30: 65535,
 | 
				
			||||||
            29: "1999:99:99 99:99:99",
 | 
					                29: "1999:99:99 99:99:99",
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        exif = im._getexif()
 | 
					            exif = im._getexif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertEqual(exif[gps_index], expected_exif_gps)
 | 
					        self.assertEqual(exif[gps_index], expected_exif_gps)
 | 
				
			||||||
| 
						 | 
					@ -256,17 +256,17 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
            33434: (4294967295, 1),
 | 
					            33434: (4294967295, 1),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/exif_gps.jpg")
 | 
					        with Image.open("Tests/images/exif_gps.jpg") as im:
 | 
				
			||||||
        exif = im._getexif()
 | 
					            exif = im._getexif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for tag, value in expected_exif.items():
 | 
					        for tag, value in expected_exif.items():
 | 
				
			||||||
            self.assertEqual(value, exif[tag])
 | 
					            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")
 | 
					        with Image.open("Tests/images/exif_gps_typeerror.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Should not raise a TypeError
 | 
					            # Should not raise a TypeError
 | 
				
			||||||
        im._getexif()
 | 
					            im._getexif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_progressive_compat(self):
 | 
					    def test_progressive_compat(self):
 | 
				
			||||||
        im1 = self.roundtrip(hopper())
 | 
					        im1 = self.roundtrip(hopper())
 | 
				
			||||||
| 
						 | 
					@ -329,13 +329,13 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(TypeError, self.roundtrip, hopper(), subsampling="1:1:1")
 | 
					        self.assertRaises(TypeError, self.roundtrip, hopper(), subsampling="1:1:1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif(self):
 | 
					    def test_exif(self):
 | 
				
			||||||
        im = Image.open("Tests/images/pil_sample_rgb.jpg")
 | 
					        with Image.open("Tests/images/pil_sample_rgb.jpg") as im:
 | 
				
			||||||
        info = im._getexif()
 | 
					            info = im._getexif()
 | 
				
			||||||
        self.assertEqual(info[305], "Adobe Photoshop CS Macintosh")
 | 
					            self.assertEqual(info[305], "Adobe Photoshop CS Macintosh")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mp(self):
 | 
					    def test_mp(self):
 | 
				
			||||||
        im = Image.open("Tests/images/pil_sample_rgb.jpg")
 | 
					        with Image.open("Tests/images/pil_sample_rgb.jpg") as im:
 | 
				
			||||||
        self.assertIsNone(im._getmp())
 | 
					            self.assertIsNone(im._getmp())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_quality_keep(self):
 | 
					    def test_quality_keep(self):
 | 
				
			||||||
        # RGB
 | 
					        # RGB
 | 
				
			||||||
| 
						 | 
					@ -354,11 +354,13 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
    def test_junk_jpeg_header(self):
 | 
					    def test_junk_jpeg_header(self):
 | 
				
			||||||
        # https://github.com/python-pillow/Pillow/issues/630
 | 
					        # https://github.com/python-pillow/Pillow/issues/630
 | 
				
			||||||
        filename = "Tests/images/junk_jpeg_header.jpg"
 | 
					        filename = "Tests/images/junk_jpeg_header.jpg"
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ff00_jpeg_header(self):
 | 
					    def test_ff00_jpeg_header(self):
 | 
				
			||||||
        filename = "Tests/images/jpeg_ff00_header.jpg"
 | 
					        filename = "Tests/images/jpeg_ff00_header.jpg"
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_truncated_jpeg_should_read_all_the_data(self):
 | 
					    def test_truncated_jpeg_should_read_all_the_data(self):
 | 
				
			||||||
        filename = "Tests/images/truncated_jpeg.jpg"
 | 
					        filename = "Tests/images/truncated_jpeg.jpg"
 | 
				
			||||||
| 
						 | 
					@ -370,14 +372,13 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_truncated_jpeg_throws_IOError(self):
 | 
					    def test_truncated_jpeg_throws_IOError(self):
 | 
				
			||||||
        filename = "Tests/images/truncated_jpeg.jpg"
 | 
					        filename = "Tests/images/truncated_jpeg.jpg"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					            with self.assertRaises(IOError):
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.assertRaises(IOError):
 | 
					            # Test that the error is raised if loaded a second time
 | 
				
			||||||
            im.load()
 | 
					            with self.assertRaises(IOError):
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
        # Test that the error is raised if loaded a second time
 | 
					 | 
				
			||||||
        with self.assertRaises(IOError):
 | 
					 | 
				
			||||||
            im.load()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _n_qtables_helper(self, n, test_file):
 | 
					    def _n_qtables_helper(self, n, test_file):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        im = Image.open(test_file)
 | 
				
			||||||
| 
						 | 
					@ -483,9 +484,9 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(djpeg_available(), "djpeg not available")
 | 
					    @unittest.skipUnless(djpeg_available(), "djpeg not available")
 | 
				
			||||||
    def test_load_djpeg(self):
 | 
					    def test_load_djpeg(self):
 | 
				
			||||||
        img = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as img:
 | 
				
			||||||
        img.load_djpeg()
 | 
					            img.load_djpeg()
 | 
				
			||||||
        self.assert_image_similar(img, Image.open(TEST_FILE), 0)
 | 
					            self.assert_image_similar(img, Image.open(TEST_FILE), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(cjpeg_available(), "cjpeg not available")
 | 
					    @unittest.skipUnless(cjpeg_available(), "cjpeg not available")
 | 
				
			||||||
    def test_save_cjpeg(self):
 | 
					    def test_save_cjpeg(self):
 | 
				
			||||||
| 
						 | 
					@ -525,10 +526,10 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        # Shouldn't raise error
 | 
					        # Shouldn't raise error
 | 
				
			||||||
        fn = "Tests/images/sugarshack_bad_mpo_header.jpg"
 | 
					        fn = "Tests/images/sugarshack_bad_mpo_header.jpg"
 | 
				
			||||||
        im = self.assert_warning(UserWarning, Image.open, fn)
 | 
					        with self.assert_warning(UserWarning, Image.open, fn) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.format, "JPEG")
 | 
					            self.assertEqual(im.format, "JPEG")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_correct_modes(self):
 | 
					    def test_save_correct_modes(self):
 | 
				
			||||||
        out = BytesIO()
 | 
					        out = BytesIO()
 | 
				
			||||||
| 
						 | 
					@ -558,106 +559,106 @@ class TestFileJpeg(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dpi_rounding(self):
 | 
					    def test_load_dpi_rounding(self):
 | 
				
			||||||
        # Round up
 | 
					        # Round up
 | 
				
			||||||
        im = Image.open("Tests/images/iptc_roundUp.jpg")
 | 
					        with Image.open("Tests/images/iptc_roundUp.jpg") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (44, 44))
 | 
					            self.assertEqual(im.info["dpi"], (44, 44))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Round down
 | 
					        # Round down
 | 
				
			||||||
        im = Image.open("Tests/images/iptc_roundDown.jpg")
 | 
					        with Image.open("Tests/images/iptc_roundDown.jpg") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (2, 2))
 | 
					            self.assertEqual(im.info["dpi"], (2, 2))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_dpi_rounding(self):
 | 
					    def test_save_dpi_rounding(self):
 | 
				
			||||||
        outfile = self.tempfile("temp.jpg")
 | 
					        outfile = self.tempfile("temp.jpg")
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.jpg")
 | 
					        im = Image.open("Tests/images/hopper.jpg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(outfile, dpi=(72.2, 72.2))
 | 
					        im.save(outfile, dpi=(72.2, 72.2))
 | 
				
			||||||
        reloaded = Image.open(outfile)
 | 
					        with Image.open(outfile) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], (72, 72))
 | 
					            self.assertEqual(reloaded.info["dpi"], (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(outfile, dpi=(72.8, 72.8))
 | 
					            im.save(outfile, dpi=(72.8, 72.8))
 | 
				
			||||||
        reloaded = Image.open(outfile)
 | 
					        with Image.open(outfile) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], (73, 73))
 | 
					            self.assertEqual(reloaded.info["dpi"], (73, 73))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dpi_tuple_from_exif(self):
 | 
					    def test_dpi_tuple_from_exif(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This Photoshop CC 2017 image has DPI in EXIF not metadata
 | 
					        # This Photoshop CC 2017 image has DPI in EXIF not metadata
 | 
				
			||||||
        # EXIF XResolution is (2000000, 10000)
 | 
					        # EXIF XResolution is (2000000, 10000)
 | 
				
			||||||
        im = Image.open("Tests/images/photoshop-200dpi.jpg")
 | 
					        with Image.open("Tests/images/photoshop-200dpi.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (200, 200))
 | 
					            self.assertEqual(im.info.get("dpi"), (200, 200))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dpi_int_from_exif(self):
 | 
					    def test_dpi_int_from_exif(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This image has DPI in EXIF not metadata
 | 
					        # This image has DPI in EXIF not metadata
 | 
				
			||||||
        # EXIF XResolution is 72
 | 
					        # EXIF XResolution is 72
 | 
				
			||||||
        im = Image.open("Tests/images/exif-72dpi-int.jpg")
 | 
					        with Image.open("Tests/images/exif-72dpi-int.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
					            self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dpi_from_dpcm_exif(self):
 | 
					    def test_dpi_from_dpcm_exif(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This is photoshop-200dpi.jpg with EXIF resolution unit set to cm:
 | 
					        # This is photoshop-200dpi.jpg with EXIF resolution unit set to cm:
 | 
				
			||||||
        # exiftool -exif:ResolutionUnit=cm photoshop-200dpi.jpg
 | 
					        # exiftool -exif:ResolutionUnit=cm photoshop-200dpi.jpg
 | 
				
			||||||
        im = Image.open("Tests/images/exif-200dpcm.jpg")
 | 
					        with Image.open("Tests/images/exif-200dpcm.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (508, 508))
 | 
					            self.assertEqual(im.info.get("dpi"), (508, 508))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dpi_exif_zero_division(self):
 | 
					    def test_dpi_exif_zero_division(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This is photoshop-200dpi.jpg with EXIF resolution set to 0/0:
 | 
					        # This is photoshop-200dpi.jpg with EXIF resolution set to 0/0:
 | 
				
			||||||
        # exiftool -XResolution=0/0 -YResolution=0/0 photoshop-200dpi.jpg
 | 
					        # exiftool -XResolution=0/0 -YResolution=0/0 photoshop-200dpi.jpg
 | 
				
			||||||
        im = Image.open("Tests/images/exif-dpi-zerodivision.jpg")
 | 
					        with Image.open("Tests/images/exif-dpi-zerodivision.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        # This should return the default, and not raise a ZeroDivisionError
 | 
					            # This should return the default, and not raise a ZeroDivisionError
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
					            self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_no_dpi_in_exif(self):
 | 
					    def test_no_dpi_in_exif(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This is photoshop-200dpi.jpg with resolution removed from EXIF:
 | 
					        # This is photoshop-200dpi.jpg with resolution removed from EXIF:
 | 
				
			||||||
        # exiftool "-*resolution*"= photoshop-200dpi.jpg
 | 
					        # exiftool "-*resolution*"= photoshop-200dpi.jpg
 | 
				
			||||||
        im = Image.open("Tests/images/no-dpi-in-exif.jpg")
 | 
					        with Image.open("Tests/images/no-dpi-in-exif.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        # "When the image resolution is unknown, 72 [dpi] is designated."
 | 
					            # "When the image resolution is unknown, 72 [dpi] is designated."
 | 
				
			||||||
        # http://www.exiv2.org/tags.html
 | 
					            # http://www.exiv2.org/tags.html
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
					            self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_exif(self):
 | 
					    def test_invalid_exif(self):
 | 
				
			||||||
        # This is no-dpi-in-exif with the tiff header of the exif block
 | 
					        # This is no-dpi-in-exif with the tiff header of the exif block
 | 
				
			||||||
        # hexedited from MM * to FF FF FF FF
 | 
					        # hexedited from MM * to FF FF FF FF
 | 
				
			||||||
        im = Image.open("Tests/images/invalid-exif.jpg")
 | 
					        with Image.open("Tests/images/invalid-exif.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # This should return the default, and not a SyntaxError or
 | 
					            # This should return the default, and not a SyntaxError or
 | 
				
			||||||
        # OSError for unidentified image.
 | 
					            # OSError for unidentified image.
 | 
				
			||||||
        self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
					            self.assertEqual(im.info.get("dpi"), (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ifd_offset_exif(self):
 | 
					    def test_ifd_offset_exif(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # This image has been manually hexedited to have an IFD offset of 10,
 | 
					        # This image has been manually hexedited to have an IFD offset of 10,
 | 
				
			||||||
        # in contrast to normal 8
 | 
					        # in contrast to normal 8
 | 
				
			||||||
        im = Image.open("Tests/images/exif-ifd-offset.jpg")
 | 
					        with Image.open("Tests/images/exif-ifd-offset.jpg") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        self.assertEqual(im._getexif()[306], "2017:03:13 23:03:09")
 | 
					            self.assertEqual(im._getexif()[306], "2017:03:13 23:03:09")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_photoshop(self):
 | 
					    def test_photoshop(self):
 | 
				
			||||||
        im = Image.open("Tests/images/photoshop-200dpi.jpg")
 | 
					        with Image.open("Tests/images/photoshop-200dpi.jpg") as im:
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            im.info["photoshop"][0x03ED],
 | 
					                im.info["photoshop"][0x03ED],
 | 
				
			||||||
            {
 | 
					                {
 | 
				
			||||||
                "XResolution": 200.0,
 | 
					                    "XResolution": 200.0,
 | 
				
			||||||
                "DisplayedUnitsX": 1,
 | 
					                    "DisplayedUnitsX": 1,
 | 
				
			||||||
                "YResolution": 200.0,
 | 
					                    "YResolution": 200.0,
 | 
				
			||||||
                "DisplayedUnitsY": 1,
 | 
					                    "DisplayedUnitsY": 1,
 | 
				
			||||||
            },
 | 
					                },
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # This image does not contain a Photoshop header string
 | 
					        # This image does not contain a Photoshop header string
 | 
				
			||||||
        im = Image.open("Tests/images/app13.jpg")
 | 
					        with Image.open("Tests/images/app13.jpg") as im:
 | 
				
			||||||
        self.assertNotIn("photoshop", im.info)
 | 
					            self.assertNotIn("photoshop", im.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@unittest.skipUnless(is_win32(), "Windows only")
 | 
					@unittest.skipUnless(is_win32(), "Windows only")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,9 +42,9 @@ class TestFileJpeg2k(PillowTestCase):
 | 
				
			||||||
        self.assertEqual(im.get_format_mimetype(), "image/jp2")
 | 
					        self.assertEqual(im.get_format_mimetype(), "image/jp2")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_jpf(self):
 | 
					    def test_jpf(self):
 | 
				
			||||||
        im = Image.open("Tests/images/balloon.jpf")
 | 
					        with Image.open("Tests/images/balloon.jpf") as im:
 | 
				
			||||||
        self.assertEqual(im.format, "JPEG2000")
 | 
					            self.assertEqual(im.format, "JPEG2000")
 | 
				
			||||||
        self.assertEqual(im.get_format_mimetype(), "image/jpx")
 | 
					            self.assertEqual(im.get_format_mimetype(), "image/jpx")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        invalid_file = "Tests/images/flower.jpg"
 | 
					        invalid_file = "Tests/images/flower.jpg"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,15 +144,14 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
    def test_write_metadata(self):
 | 
					    def test_write_metadata(self):
 | 
				
			||||||
        """ Test metadata writing through libtiff """
 | 
					        """ Test metadata writing through libtiff """
 | 
				
			||||||
        for legacy_api in [False, True]:
 | 
					        for legacy_api in [False, True]:
 | 
				
			||||||
            img = Image.open("Tests/images/hopper_g4.tif")
 | 
					 | 
				
			||||||
            f = self.tempfile("temp.tiff")
 | 
					            f = self.tempfile("temp.tiff")
 | 
				
			||||||
 | 
					            with Image.open("Tests/images/hopper_g4.tif") as img:
 | 
				
			||||||
 | 
					                img.save(f, tiffinfo=img.tag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            img.save(f, tiffinfo=img.tag)
 | 
					                if legacy_api:
 | 
				
			||||||
 | 
					                    original = img.tag.named()
 | 
				
			||||||
            if legacy_api:
 | 
					                else:
 | 
				
			||||||
                original = img.tag.named()
 | 
					                    original = img.tag_v2.named()
 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                original = img.tag_v2.named()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # PhotometricInterpretation is set from SAVE_INFO,
 | 
					            # PhotometricInterpretation is set from SAVE_INFO,
 | 
				
			||||||
            # not the original image.
 | 
					            # not the original image.
 | 
				
			||||||
| 
						 | 
					@ -163,11 +162,11 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
                "PhotometricInterpretation",
 | 
					                "PhotometricInterpretation",
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            loaded = Image.open(f)
 | 
					            with Image.open(f) as loaded:
 | 
				
			||||||
            if legacy_api:
 | 
					                if legacy_api:
 | 
				
			||||||
                reloaded = loaded.tag.named()
 | 
					                    reloaded = loaded.tag.named()
 | 
				
			||||||
            else:
 | 
					                else:
 | 
				
			||||||
                reloaded = loaded.tag_v2.named()
 | 
					                    reloaded = loaded.tag_v2.named()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for tag, value in itertools.chain(reloaded.items(), original.items()):
 | 
					            for tag, value in itertools.chain(reloaded.items(), original.items()):
 | 
				
			||||||
                if tag not in ignored:
 | 
					                if tag not in ignored:
 | 
				
			||||||
| 
						 | 
					@ -302,21 +301,21 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
                out = self.tempfile("temp.tif")
 | 
					                out = self.tempfile("temp.tif")
 | 
				
			||||||
                im.save(out, tiffinfo=tiffinfo)
 | 
					                im.save(out, tiffinfo=tiffinfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                reloaded = Image.open(out)
 | 
					                with Image.open(out) as reloaded:
 | 
				
			||||||
                for tag, value in tiffinfo.items():
 | 
					                    for tag, value in tiffinfo.items():
 | 
				
			||||||
                    reloaded_value = reloaded.tag_v2[tag]
 | 
					                        reloaded_value = reloaded.tag_v2[tag]
 | 
				
			||||||
                    if (
 | 
					                        if (
 | 
				
			||||||
                        isinstance(reloaded_value, TiffImagePlugin.IFDRational)
 | 
					                            isinstance(reloaded_value, TiffImagePlugin.IFDRational)
 | 
				
			||||||
                        and libtiff
 | 
					                            and libtiff
 | 
				
			||||||
                    ):
 | 
					                        ):
 | 
				
			||||||
                        # libtiff does not support real RATIONALS
 | 
					                            # libtiff does not support real RATIONALS
 | 
				
			||||||
                        self.assertAlmostEqual(float(reloaded_value), float(value))
 | 
					                            self.assertAlmostEqual(float(reloaded_value), float(value))
 | 
				
			||||||
                        continue
 | 
					                            continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if libtiff and isinstance(value, bytes):
 | 
					                        if libtiff and isinstance(value, bytes):
 | 
				
			||||||
                        value = value.decode()
 | 
					                            value = value.decode()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    self.assertEqual(reloaded_value, value)
 | 
					                        self.assertEqual(reloaded_value, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Test with types
 | 
					            # Test with types
 | 
				
			||||||
            ifd = TiffImagePlugin.ImageFileDirectory_v2()
 | 
					            ifd = TiffImagePlugin.ImageFileDirectory_v2()
 | 
				
			||||||
| 
						 | 
					@ -343,8 +342,8 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
        TiffImagePlugin.WRITE_LIBTIFF = True
 | 
					        TiffImagePlugin.WRITE_LIBTIFF = True
 | 
				
			||||||
        im.save(out, dpi=(72, 72))
 | 
					        im.save(out, dpi=(72, 72))
 | 
				
			||||||
        TiffImagePlugin.WRITE_LIBTIFF = False
 | 
					        TiffImagePlugin.WRITE_LIBTIFF = False
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["dpi"], (72.0, 72.0))
 | 
					            self.assertEqual(reloaded.info["dpi"], (72.0, 72.0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_g3_compression(self):
 | 
					    def test_g3_compression(self):
 | 
				
			||||||
        i = Image.open("Tests/images/hopper_g4_500.tif")
 | 
					        i = Image.open("Tests/images/hopper_g4_500.tif")
 | 
				
			||||||
| 
						 | 
					@ -412,9 +411,9 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
        orig.tag[269] = "temp.tif"
 | 
					        orig.tag[269] = "temp.tif"
 | 
				
			||||||
        orig.save(out)
 | 
					        orig.save(out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out)
 | 
					        with Image.open(out) as reread:
 | 
				
			||||||
        self.assertEqual("temp.tif", reread.tag_v2[269])
 | 
					            self.assertEqual("temp.tif", reread.tag_v2[269])
 | 
				
			||||||
        self.assertEqual("temp.tif", reread.tag[269][0])
 | 
					            self.assertEqual("temp.tif", reread.tag[269][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_12bit_rawmode(self):
 | 
					    def test_12bit_rawmode(self):
 | 
				
			||||||
        """ Are we generating the same interpretation
 | 
					        """ Are we generating the same interpretation
 | 
				
			||||||
| 
						 | 
					@ -521,36 +520,36 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
    def test_multipage(self):
 | 
					    def test_multipage(self):
 | 
				
			||||||
        # issue #862
 | 
					        # issue #862
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = True
 | 
					        TiffImagePlugin.READ_LIBTIFF = True
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        # file is a multipage tiff,  10x10 green, 10x10 red, 20x20 blue
 | 
					            # file is a multipage tiff,  10x10 green, 10x10 red, 20x20 blue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
				
			||||||
        self.assertTrue(im.tag.next)
 | 
					            self.assertTrue(im.tag.next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (255, 0, 0))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (255, 0, 0))
 | 
				
			||||||
        self.assertTrue(im.tag.next)
 | 
					            self.assertTrue(im.tag.next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(2)
 | 
					            im.seek(2)
 | 
				
			||||||
        self.assertFalse(im.tag.next)
 | 
					            self.assertFalse(im.tag.next)
 | 
				
			||||||
        self.assertEqual(im.size, (20, 20))
 | 
					            self.assertEqual(im.size, (20, 20))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = False
 | 
					        TiffImagePlugin.READ_LIBTIFF = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multipage_nframes(self):
 | 
					    def test_multipage_nframes(self):
 | 
				
			||||||
        # issue #862
 | 
					        # issue #862
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = True
 | 
					        TiffImagePlugin.READ_LIBTIFF = True
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        frames = im.n_frames
 | 
					            frames = im.n_frames
 | 
				
			||||||
        self.assertEqual(frames, 3)
 | 
					            self.assertEqual(frames, 3)
 | 
				
			||||||
        for _ in range(frames):
 | 
					            for _ in range(frames):
 | 
				
			||||||
            im.seek(0)
 | 
					                im.seek(0)
 | 
				
			||||||
            # Should not raise ValueError: I/O operation on closed file
 | 
					                # Should not raise ValueError: I/O operation on closed file
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = False
 | 
					        TiffImagePlugin.READ_LIBTIFF = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,9 +655,9 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
        # /usr/bin/gs -q -sDEVICE=tiffg3 -sOutputFile=total-pages-zero.tif
 | 
					        # /usr/bin/gs -q -sDEVICE=tiffg3 -sOutputFile=total-pages-zero.tif
 | 
				
			||||||
        # -dNOPAUSE /tmp/test.pdf -c quit
 | 
					        # -dNOPAUSE /tmp/test.pdf -c quit
 | 
				
			||||||
        infile = "Tests/images/total-pages-zero.tif"
 | 
					        infile = "Tests/images/total-pages-zero.tif"
 | 
				
			||||||
        im = Image.open(infile)
 | 
					        with Image.open(infile) as im:
 | 
				
			||||||
        # Should not divide by zero
 | 
					            # Should not divide by zero
 | 
				
			||||||
        im.save(outfile)
 | 
					            im.save(outfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_fd_duplication(self):
 | 
					    def test_fd_duplication(self):
 | 
				
			||||||
        # https://github.com/python-pillow/Pillow/issues/1651
 | 
					        # https://github.com/python-pillow/Pillow/issues/1651
 | 
				
			||||||
| 
						 | 
					@ -686,21 +685,21 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
        self.assertEqual(icc, icc_libtiff)
 | 
					        self.assertEqual(icc, icc_libtiff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multipage_compression(self):
 | 
					    def test_multipage_compression(self):
 | 
				
			||||||
        im = Image.open("Tests/images/compression.tif")
 | 
					        with Image.open("Tests/images/compression.tif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im._compression, "tiff_ccitt")
 | 
					            self.assertEqual(im._compression, "tiff_ccitt")
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        self.assertEqual(im._compression, "packbits")
 | 
					            self.assertEqual(im._compression, "packbits")
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im._compression, "tiff_ccitt")
 | 
					            self.assertEqual(im._compression, "tiff_ccitt")
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_tiff_with_jpegtables(self):
 | 
					    def test_save_tiff_with_jpegtables(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -836,8 +835,8 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
				
			||||||
    def test_no_rows_per_strip(self):
 | 
					    def test_no_rows_per_strip(self):
 | 
				
			||||||
        # This image does not have a RowsPerStrip TIFF tag
 | 
					        # This image does not have a RowsPerStrip TIFF tag
 | 
				
			||||||
        infile = "Tests/images/no_rows_per_strip.tif"
 | 
					        infile = "Tests/images/no_rows_per_strip.tif"
 | 
				
			||||||
        im = Image.open(infile)
 | 
					        with Image.open(infile) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.size, (950, 975))
 | 
					        self.assertEqual(im.size, (950, 975))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_orientation(self):
 | 
					    def test_orientation(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,42 +16,42 @@ TEST_FILE = "Tests/images/hopper.mic"
 | 
				
			||||||
@unittest.skipUnless(features.check("libtiff"), "libtiff not installed")
 | 
					@unittest.skipUnless(features.check("libtiff"), "libtiff not installed")
 | 
				
			||||||
class TestFileMic(PillowTestCase):
 | 
					class TestFileMic(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGBA")
 | 
					            self.assertEqual(im.mode, "RGBA")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "MIC")
 | 
					            self.assertEqual(im.format, "MIC")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Adjust for the gamma of 2.2 encoded into the file
 | 
					            # Adjust for the gamma of 2.2 encoded into the file
 | 
				
			||||||
        lut = ImagePalette.make_gamma_lut(1 / 2.2)
 | 
					            lut = ImagePalette.make_gamma_lut(1 / 2.2)
 | 
				
			||||||
        im = Image.merge("RGBA", [chan.point(lut) for chan in im.split()])
 | 
					            im = Image.merge("RGBA", [chan.point(lut) for chan in im.split()])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im2 = hopper("RGBA")
 | 
					            im2 = hopper("RGBA")
 | 
				
			||||||
        self.assert_image_similar(im, im2, 10)
 | 
					            self.assert_image_similar(im, im2, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_is_animated(self):
 | 
					    def test_is_animated(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tell(self):
 | 
					    def test_tell(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.tell(), 0)
 | 
					            self.assertEqual(im.tell(), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek(self):
 | 
					    def test_seek(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im.tell(), 0)
 | 
					            self.assertEqual(im.tell(), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, 99)
 | 
					            self.assertRaises(EOFError, im.seek, 99)
 | 
				
			||||||
        self.assertEqual(im.tell(), 0)
 | 
					            self.assertEqual(im.tell(), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
        # Test an invalid OLE file
 | 
					        # Test an invalid OLE file
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
from io import BytesIO
 | 
					from io import BytesIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image
 | 
					from PIL import Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase
 | 
					from .helper import PillowTestCase, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
 | 
					test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,78 +26,97 @@ class TestFileMpo(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
            self.assertEqual(im.mode, "RGB")
 | 
					                self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
            self.assertEqual(im.size, (640, 480))
 | 
					                self.assertEqual(im.size, (640, 480))
 | 
				
			||||||
            self.assertEqual(im.format, "MPO")
 | 
					                self.assertEqual(im.format, "MPO")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(test_files[0])
 | 
					            im = Image.open(test_files[0])
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(test_files[0])
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(test_files[0]) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_app(self):
 | 
					    def test_app(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            # Test APP/COM reader (@PIL135)
 | 
					            # Test APP/COM reader (@PIL135)
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            self.assertEqual(im.applist[0][0], "APP1")
 | 
					                self.assertEqual(im.applist[0][0], "APP1")
 | 
				
			||||||
            self.assertEqual(im.applist[1][0], "APP2")
 | 
					                self.assertEqual(im.applist[1][0], "APP2")
 | 
				
			||||||
            self.assertEqual(
 | 
					                self.assertEqual(
 | 
				
			||||||
                im.applist[1][1][:16], b"MPF\x00MM\x00*\x00\x00\x00\x08\x00\x03\xb0\x00"
 | 
					                    im.applist[1][1][:16],
 | 
				
			||||||
            )
 | 
					                    b"MPF\x00MM\x00*\x00\x00\x00\x08\x00\x03\xb0\x00",
 | 
				
			||||||
            self.assertEqual(len(im.applist), 2)
 | 
					                )
 | 
				
			||||||
 | 
					                self.assertEqual(len(im.applist), 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif(self):
 | 
					    def test_exif(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            info = im._getexif()
 | 
					                info = im._getexif()
 | 
				
			||||||
            self.assertEqual(info[272], "Nintendo 3DS")
 | 
					                self.assertEqual(info[272], "Nintendo 3DS")
 | 
				
			||||||
            self.assertEqual(info[296], 2)
 | 
					                self.assertEqual(info[296], 2)
 | 
				
			||||||
            self.assertEqual(info[34665], 188)
 | 
					                self.assertEqual(info[34665], 188)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_frame_size(self):
 | 
					    def test_frame_size(self):
 | 
				
			||||||
        # This image has been hexedited to contain a different size
 | 
					        # This image has been hexedited to contain a different size
 | 
				
			||||||
        # in the EXIF data of the second frame
 | 
					        # in the EXIF data of the second frame
 | 
				
			||||||
        im = Image.open("Tests/images/sugarshack_frame_size.mpo")
 | 
					        with Image.open("Tests/images/sugarshack_frame_size.mpo") as im:
 | 
				
			||||||
        self.assertEqual(im.size, (640, 480))
 | 
					            self.assertEqual(im.size, (640, 480))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        self.assertEqual(im.size, (680, 480))
 | 
					            self.assertEqual(im.size, (680, 480))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_parallax(self):
 | 
					    def test_parallax(self):
 | 
				
			||||||
        # Nintendo
 | 
					        # Nintendo
 | 
				
			||||||
        im = Image.open("Tests/images/sugarshack.mpo")
 | 
					        with Image.open("Tests/images/sugarshack.mpo") as im:
 | 
				
			||||||
        exif = im.getexif()
 | 
					            exif = im.getexif()
 | 
				
			||||||
        self.assertEqual(exif.get_ifd(0x927C)[0x1101]["Parallax"], -44.798187255859375)
 | 
					            self.assertEqual(
 | 
				
			||||||
 | 
					                exif.get_ifd(0x927C)[0x1101]["Parallax"], -44.798187255859375
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Fujifilm
 | 
					        # Fujifilm
 | 
				
			||||||
        im = Image.open("Tests/images/fujifilm.mpo")
 | 
					        with Image.open("Tests/images/fujifilm.mpo") as im:
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        exif = im.getexif()
 | 
					            exif = im.getexif()
 | 
				
			||||||
        self.assertEqual(exif.get_ifd(0x927C)[0xB211], -3.125)
 | 
					            self.assertEqual(exif.get_ifd(0x927C)[0xB211], -3.125)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mp(self):
 | 
					    def test_mp(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            mpinfo = im._getmp()
 | 
					                mpinfo = im._getmp()
 | 
				
			||||||
            self.assertEqual(mpinfo[45056], b"0100")
 | 
					                self.assertEqual(mpinfo[45056], b"0100")
 | 
				
			||||||
            self.assertEqual(mpinfo[45057], 2)
 | 
					                self.assertEqual(mpinfo[45057], 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mp_offset(self):
 | 
					    def test_mp_offset(self):
 | 
				
			||||||
        # This image has been manually hexedited to have an IFD offset of 10
 | 
					        # This image has been manually hexedited to have an IFD offset of 10
 | 
				
			||||||
        # in APP2 data, in contrast to normal 8
 | 
					        # in APP2 data, in contrast to normal 8
 | 
				
			||||||
        im = Image.open("Tests/images/sugarshack_ifd_offset.mpo")
 | 
					        with Image.open("Tests/images/sugarshack_ifd_offset.mpo") as im:
 | 
				
			||||||
        mpinfo = im._getmp()
 | 
					            mpinfo = im._getmp()
 | 
				
			||||||
        self.assertEqual(mpinfo[45056], b"0100")
 | 
					            self.assertEqual(mpinfo[45056], b"0100")
 | 
				
			||||||
        self.assertEqual(mpinfo[45057], 2)
 | 
					            self.assertEqual(mpinfo[45057], 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mp_attribute(self):
 | 
					    def test_mp_attribute(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            mpinfo = im._getmp()
 | 
					                mpinfo = im._getmp()
 | 
				
			||||||
            frameNumber = 0
 | 
					            frameNumber = 0
 | 
				
			||||||
            for mpentry in mpinfo[45058]:
 | 
					            for mpentry in mpinfo[45058]:
 | 
				
			||||||
                mpattr = mpentry["Attribute"]
 | 
					                mpattr = mpentry["Attribute"]
 | 
				
			||||||
| 
						 | 
					@ -113,62 +133,62 @@ class TestFileMpo(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek(self):
 | 
					    def test_seek(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
            # prior to first image raises an error, both blatant and borderline
 | 
					                # prior to first image raises an error, both blatant and borderline
 | 
				
			||||||
            self.assertRaises(EOFError, im.seek, -1)
 | 
					                self.assertRaises(EOFError, im.seek, -1)
 | 
				
			||||||
            self.assertRaises(EOFError, im.seek, -523)
 | 
					                self.assertRaises(EOFError, im.seek, -523)
 | 
				
			||||||
            # after the final image raises an error,
 | 
					                # after the final image raises an error,
 | 
				
			||||||
            # both blatant and borderline
 | 
					                # both blatant and borderline
 | 
				
			||||||
            self.assertRaises(EOFError, im.seek, 2)
 | 
					                self.assertRaises(EOFError, im.seek, 2)
 | 
				
			||||||
            self.assertRaises(EOFError, im.seek, 523)
 | 
					                self.assertRaises(EOFError, im.seek, 523)
 | 
				
			||||||
            # bad calls shouldn't change the frame
 | 
					                # bad calls shouldn't change the frame
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
            # this one will work
 | 
					                # this one will work
 | 
				
			||||||
            im.seek(1)
 | 
					                im.seek(1)
 | 
				
			||||||
            self.assertEqual(im.tell(), 1)
 | 
					                self.assertEqual(im.tell(), 1)
 | 
				
			||||||
            # and this one, too
 | 
					                # and this one, too
 | 
				
			||||||
            im.seek(0)
 | 
					                im.seek(0)
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open("Tests/images/sugarshack.mpo")
 | 
					        with Image.open("Tests/images/sugarshack.mpo") as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 2)
 | 
					            self.assertEqual(im.n_frames, 2)
 | 
				
			||||||
        self.assertTrue(im.is_animated)
 | 
					            self.assertTrue(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open("Tests/images/sugarshack.mpo")
 | 
					        with Image.open("Tests/images/sugarshack.mpo") as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_image_grab(self):
 | 
					    def test_image_grab(self):
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
            im0 = im.tobytes()
 | 
					                im0 = im.tobytes()
 | 
				
			||||||
            im.seek(1)
 | 
					                im.seek(1)
 | 
				
			||||||
            self.assertEqual(im.tell(), 1)
 | 
					                self.assertEqual(im.tell(), 1)
 | 
				
			||||||
            im1 = im.tobytes()
 | 
					                im1 = im.tobytes()
 | 
				
			||||||
            im.seek(0)
 | 
					                im.seek(0)
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
            im02 = im.tobytes()
 | 
					                im02 = im.tobytes()
 | 
				
			||||||
            self.assertEqual(im0, im02)
 | 
					                self.assertEqual(im0, im02)
 | 
				
			||||||
            self.assertNotEqual(im0, im1)
 | 
					                self.assertNotEqual(im0, im1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        # Note that only individual frames can be saved at present
 | 
					        # Note that only individual frames can be saved at present
 | 
				
			||||||
        for test_file in test_files:
 | 
					        for test_file in test_files:
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            with Image.open(test_file) as im:
 | 
				
			||||||
            self.assertEqual(im.tell(), 0)
 | 
					                self.assertEqual(im.tell(), 0)
 | 
				
			||||||
            jpg0 = self.frame_roundtrip(im)
 | 
					                jpg0 = self.frame_roundtrip(im)
 | 
				
			||||||
            self.assert_image_similar(im, jpg0, 30)
 | 
					                self.assert_image_similar(im, jpg0, 30)
 | 
				
			||||||
            im.seek(1)
 | 
					                im.seek(1)
 | 
				
			||||||
            self.assertEqual(im.tell(), 1)
 | 
					                self.assertEqual(im.tell(), 1)
 | 
				
			||||||
            jpg1 = self.frame_roundtrip(im)
 | 
					                jpg1 = self.frame_roundtrip(im)
 | 
				
			||||||
            self.assert_image_similar(im, jpg1, 30)
 | 
					                self.assert_image_similar(im, jpg1, 30)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,27 +82,27 @@ class TestFilePdf(PillowTestCase):
 | 
				
			||||||
        self.helper_save_as_pdf("RGB", save_all=True)
 | 
					        self.helper_save_as_pdf("RGB", save_all=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Multiframe image
 | 
					        # Multiframe image
 | 
				
			||||||
        im = Image.open("Tests/images/dispose_bgnd.gif")
 | 
					        with Image.open("Tests/images/dispose_bgnd.gif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        outfile = self.tempfile("temp.pdf")
 | 
					            outfile = self.tempfile("temp.pdf")
 | 
				
			||||||
        im.save(outfile, save_all=True)
 | 
					            im.save(outfile, save_all=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertTrue(os.path.isfile(outfile))
 | 
					            self.assertTrue(os.path.isfile(outfile))
 | 
				
			||||||
        self.assertGreater(os.path.getsize(outfile), 0)
 | 
					            self.assertGreater(os.path.getsize(outfile), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Append images
 | 
					            # Append images
 | 
				
			||||||
        ims = [hopper()]
 | 
					            ims = [hopper()]
 | 
				
			||||||
        im.copy().save(outfile, save_all=True, append_images=ims)
 | 
					            im.copy().save(outfile, save_all=True, append_images=ims)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertTrue(os.path.isfile(outfile))
 | 
					            self.assertTrue(os.path.isfile(outfile))
 | 
				
			||||||
        self.assertGreater(os.path.getsize(outfile), 0)
 | 
					            self.assertGreater(os.path.getsize(outfile), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test appending using a generator
 | 
					            # Test appending using a generator
 | 
				
			||||||
        def imGenerator(ims):
 | 
					            def imGenerator(ims):
 | 
				
			||||||
            for im in ims:
 | 
					                for im in ims:
 | 
				
			||||||
                yield im
 | 
					                    yield im
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(outfile, save_all=True, append_images=imGenerator(ims))
 | 
					            im.save(outfile, save_all=True, append_images=imGenerator(ims))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertTrue(os.path.isfile(outfile))
 | 
					        self.assertTrue(os.path.isfile(outfile))
 | 
				
			||||||
        self.assertGreater(os.path.getsize(outfile), 0)
 | 
					        self.assertGreater(os.path.getsize(outfile), 0)
 | 
				
			||||||
| 
						 | 
					@ -116,10 +116,10 @@ class TestFilePdf(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multiframe_normal_save(self):
 | 
					    def test_multiframe_normal_save(self):
 | 
				
			||||||
        # Test saving a multiframe image without save_all
 | 
					        # Test saving a multiframe image without save_all
 | 
				
			||||||
        im = Image.open("Tests/images/dispose_bgnd.gif")
 | 
					        with Image.open("Tests/images/dispose_bgnd.gif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        outfile = self.tempfile("temp.pdf")
 | 
					            outfile = self.tempfile("temp.pdf")
 | 
				
			||||||
        im.save(outfile)
 | 
					            im.save(outfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertTrue(os.path.isfile(outfile))
 | 
					        self.assertTrue(os.path.isfile(outfile))
 | 
				
			||||||
        self.assertGreater(os.path.getsize(outfile), 0)
 | 
					        self.assertGreater(os.path.getsize(outfile), 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,12 +81,12 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("RGB").save(test_file)
 | 
					        hopper("RGB").save(test_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGB")
 | 
					            self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "PNG")
 | 
					            self.assertEqual(im.format, "PNG")
 | 
				
			||||||
        self.assertEqual(im.get_format_mimetype(), "image/png")
 | 
					            self.assertEqual(im.get_format_mimetype(), "image/png")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for mode in ["1", "L", "P", "RGB", "I", "I;16"]:
 | 
					        for mode in ["1", "L", "P", "RGB", "I", "I;16"]:
 | 
				
			||||||
            im = hopper(mode)
 | 
					            im = hopper(mode)
 | 
				
			||||||
| 
						 | 
					@ -393,12 +393,12 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dpi_rounding(self):
 | 
					    def test_load_dpi_rounding(self):
 | 
				
			||||||
        # Round up
 | 
					        # Round up
 | 
				
			||||||
        im = Image.open(TEST_PNG_FILE)
 | 
					        with Image.open(TEST_PNG_FILE) as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (96, 96))
 | 
					            self.assertEqual(im.info["dpi"], (96, 96))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Round down
 | 
					        # Round down
 | 
				
			||||||
        im = Image.open("Tests/images/icc_profile_none.png")
 | 
					        with Image.open("Tests/images/icc_profile_none.png") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (72, 72))
 | 
					            self.assertEqual(im.info["dpi"], (72, 72))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_dpi_rounding(self):
 | 
					    def test_save_dpi_rounding(self):
 | 
				
			||||||
        im = Image.open(TEST_PNG_FILE)
 | 
					        im = Image.open(TEST_PNG_FILE)
 | 
				
			||||||
| 
						 | 
					@ -462,8 +462,13 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
        if py3:
 | 
					        if py3:
 | 
				
			||||||
            rt_text(" Aa" + chr(0xA0) + chr(0xC4) + chr(0xFF))  # Latin1
 | 
					            rt_text(" Aa" + chr(0xA0) + chr(0xC4) + chr(0xFF))  # Latin1
 | 
				
			||||||
            rt_text(chr(0x400) + chr(0x472) + chr(0x4FF))  # Cyrillic
 | 
					            rt_text(chr(0x400) + chr(0x472) + chr(0x4FF))  # Cyrillic
 | 
				
			||||||
            # CJK:
 | 
					            rt_text(
 | 
				
			||||||
            rt_text(chr(0x4E00) + chr(0x66F0) + chr(0x9FBA) + chr(0x3042) + chr(0xAC00))
 | 
					                chr(0x4E00)
 | 
				
			||||||
 | 
					                + chr(0x66F0)
 | 
				
			||||||
 | 
					                + chr(0x9FBA)  # CJK
 | 
				
			||||||
 | 
					                + chr(0x3042)
 | 
				
			||||||
 | 
					                + chr(0xAC00)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            rt_text("A" + chr(0xC4) + chr(0x472) + chr(0x3042))  # Combined
 | 
					            rt_text("A" + chr(0xC4) + chr(0x472) + chr(0x3042))  # Combined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_scary(self):
 | 
					    def test_scary(self):
 | 
				
			||||||
| 
						 | 
					@ -509,19 +514,19 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
    def test_trns_null(self):
 | 
					    def test_trns_null(self):
 | 
				
			||||||
        # Check reading images with null tRNS value, issue #1239
 | 
					        # Check reading images with null tRNS value, issue #1239
 | 
				
			||||||
        test_file = "Tests/images/tRNS_null_1x1.png"
 | 
					        test_file = "Tests/images/tRNS_null_1x1.png"
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.info["transparency"], 0)
 | 
					            self.assertEqual(im.info["transparency"], 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_icc_profile(self):
 | 
					    def test_save_icc_profile(self):
 | 
				
			||||||
        im = Image.open("Tests/images/icc_profile_none.png")
 | 
					        with Image.open("Tests/images/icc_profile_none.png") as im:
 | 
				
			||||||
        self.assertIsNone(im.info["icc_profile"])
 | 
					            self.assertIsNone(im.info["icc_profile"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with_icc = Image.open("Tests/images/icc_profile.png")
 | 
					            with Image.open("Tests/images/icc_profile.png") as with_icc:
 | 
				
			||||||
        expected_icc = with_icc.info["icc_profile"]
 | 
					                expected_icc = with_icc.info["icc_profile"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = roundtrip(im, icc_profile=expected_icc)
 | 
					                im = roundtrip(im, icc_profile=expected_icc)
 | 
				
			||||||
        self.assertEqual(im.info["icc_profile"], expected_icc)
 | 
					                self.assertEqual(im.info["icc_profile"], expected_icc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_discard_icc_profile(self):
 | 
					    def test_discard_icc_profile(self):
 | 
				
			||||||
        im = Image.open("Tests/images/icc_profile.png")
 | 
					        im = Image.open("Tests/images/icc_profile.png")
 | 
				
			||||||
| 
						 | 
					@ -614,8 +619,8 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
        test_file = self.tempfile("temp.png")
 | 
					        test_file = self.tempfile("temp.png")
 | 
				
			||||||
        im.save(test_file)
 | 
					        im.save(test_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(test_file)
 | 
					        with Image.open(test_file) as reloaded:
 | 
				
			||||||
        exif = reloaded._getexif()
 | 
					            exif = reloaded._getexif()
 | 
				
			||||||
        self.assertEqual(exif[274], 1)
 | 
					        self.assertEqual(exif[274], 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif_from_jpg(self):
 | 
					    def test_exif_from_jpg(self):
 | 
				
			||||||
| 
						 | 
					@ -624,8 +629,8 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
        test_file = self.tempfile("temp.png")
 | 
					        test_file = self.tempfile("temp.png")
 | 
				
			||||||
        im.save(test_file)
 | 
					        im.save(test_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(test_file)
 | 
					        with Image.open(test_file) as reloaded:
 | 
				
			||||||
        exif = reloaded._getexif()
 | 
					            exif = reloaded._getexif()
 | 
				
			||||||
        self.assertEqual(exif[305], "Adobe Photoshop CS Macintosh")
 | 
					        self.assertEqual(exif[305], "Adobe Photoshop CS Macintosh")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif_argument(self):
 | 
					    def test_exif_argument(self):
 | 
				
			||||||
| 
						 | 
					@ -634,8 +639,8 @@ class TestFilePng(PillowTestCase):
 | 
				
			||||||
        test_file = self.tempfile("temp.png")
 | 
					        test_file = self.tempfile("temp.png")
 | 
				
			||||||
        im.save(test_file, exif=b"exifstring")
 | 
					        im.save(test_file, exif=b"exifstring")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(test_file)
 | 
					        with Image.open(test_file) as reloaded:
 | 
				
			||||||
        self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
 | 
					            self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(
 | 
					    @unittest.skipUnless(
 | 
				
			||||||
        HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP support not installed with animation"
 | 
					        HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP support not installed with animation"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,10 +66,10 @@ class TestFilePpm(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with open(path, "w") as f:
 | 
					        with open(path, "w") as f:
 | 
				
			||||||
            f.write("P4\n128 128\n255")
 | 
					            f.write("P4\n128 128\n255")
 | 
				
			||||||
        im = Image.open(path)
 | 
					        with Image.open(path) as im:
 | 
				
			||||||
        self.assertEqual(im.get_format_mimetype(), "image/x-portable-bitmap")
 | 
					            self.assertEqual(im.get_format_mimetype(), "image/x-portable-bitmap")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with open(path, "w") as f:
 | 
					        with open(path, "w") as f:
 | 
				
			||||||
            f.write("PyCMYK\n128 128\n255")
 | 
					            f.write("PyCMYK\n128 128\n255")
 | 
				
			||||||
        im = Image.open(path)
 | 
					        with Image.open(path) as im:
 | 
				
			||||||
        self.assertEqual(im.get_format_mimetype(), "image/x-portable-anymap")
 | 
					            self.assertEqual(im.get_format_mimetype(), "image/x-portable-anymap")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,26 +1,45 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, PsdImagePlugin
 | 
					from PIL import Image, PsdImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper
 | 
					from .helper import PillowTestCase, hopper, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_file = "Tests/images/hopper.psd"
 | 
					test_file = "Tests/images/hopper.psd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestImagePsd(PillowTestCase):
 | 
					class TestImagePsd(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGB")
 | 
					            self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "PSD")
 | 
					            self.assertEqual(im.format, "PSD")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im2 = hopper()
 | 
					            im2 = hopper()
 | 
				
			||||||
        self.assert_image_similar(im, im2, 4.8)
 | 
					            self.assert_image_similar(im, im2, 4.8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(test_file)
 | 
					            im = Image.open(test_file)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(test_file)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(test_file)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_invalid_file(self):
 | 
					    def test_invalid_file(self):
 | 
				
			||||||
| 
						 | 
					@ -29,64 +48,63 @@ class TestImagePsd(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(SyntaxError, PsdImagePlugin.PsdImageFile, invalid_file)
 | 
					        self.assertRaises(SyntaxError, PsdImagePlugin.PsdImageFile, invalid_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open("Tests/images/hopper_merged.psd")
 | 
					        with Image.open("Tests/images/hopper_merged.psd") as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 2)
 | 
					            self.assertEqual(im.n_frames, 2)
 | 
				
			||||||
        self.assertTrue(im.is_animated)
 | 
					            self.assertTrue(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        # PSD seek index starts at 1 rather than 0
 | 
					            # PSD seek index starts at 1 rather than 0
 | 
				
			||||||
        n_frames = im.n_frames + 1
 | 
					            n_frames = im.n_frames + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_tell(self):
 | 
					    def test_seek_tell(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 1)
 | 
					            self.assertEqual(layer_number, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, 0)
 | 
					            self.assertRaises(EOFError, im.seek, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 1)
 | 
					            self.assertEqual(layer_number, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(2)
 | 
					            im.seek(2)
 | 
				
			||||||
        layer_number = im.tell()
 | 
					            layer_number = im.tell()
 | 
				
			||||||
        self.assertEqual(layer_number, 2)
 | 
					            self.assertEqual(layer_number, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_eoferror(self):
 | 
					    def test_seek_eoferror(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, -1)
 | 
					            self.assertRaises(EOFError, im.seek, -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_open_after_exclusive_load(self):
 | 
					    def test_open_after_exclusive_load(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        im.seek(im.tell() + 1)
 | 
					            im.seek(im.tell() + 1)
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_icc_profile(self):
 | 
					    def test_icc_profile(self):
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
        self.assertIn("icc_profile", im.info)
 | 
					            self.assertIn("icc_profile", im.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        icc_profile = im.info["icc_profile"]
 | 
					            icc_profile = im.info["icc_profile"]
 | 
				
			||||||
        self.assertEqual(len(icc_profile), 3144)
 | 
					            self.assertEqual(len(icc_profile), 3144)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_no_icc_profile(self):
 | 
					    def test_no_icc_profile(self):
 | 
				
			||||||
        im = Image.open("Tests/images/hopper_merged.psd")
 | 
					        with Image.open("Tests/images/hopper_merged.psd") as im:
 | 
				
			||||||
 | 
					            self.assertNotIn("icc_profile", im.info)
 | 
				
			||||||
        self.assertNotIn("icc_profile", im.info)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_combined_larger_than_size(self):
 | 
					    def test_combined_larger_than_size(self):
 | 
				
			||||||
        # The 'combined' sizes of the individual parts is larger than the
 | 
					        # The 'combined' sizes of the individual parts is larger than the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,26 +1,43 @@
 | 
				
			||||||
import tempfile
 | 
					import tempfile
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
from io import BytesIO
 | 
					from io import BytesIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, ImageSequence, SpiderImagePlugin
 | 
					from PIL import Image, ImageSequence, SpiderImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper
 | 
					from .helper import PillowTestCase, hopper, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_FILE = "Tests/images/hopper.spider"
 | 
					TEST_FILE = "Tests/images/hopper.spider"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestImageSpider(PillowTestCase):
 | 
					class TestImageSpider(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "F")
 | 
					            self.assertEqual(im.mode, "F")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "SPIDER")
 | 
					            self.assertEqual(im.format, "SPIDER")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open(TEST_FILE)
 | 
					            im = Image.open(TEST_FILE)
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open(TEST_FILE)
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
| 
						 | 
					@ -32,10 +49,10 @@ class TestImageSpider(PillowTestCase):
 | 
				
			||||||
        im.save(temp, "SPIDER")
 | 
					        im.save(temp, "SPIDER")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        im2 = Image.open(temp)
 | 
					        with Image.open(temp) as im2:
 | 
				
			||||||
        self.assertEqual(im2.mode, "F")
 | 
					            self.assertEqual(im2.mode, "F")
 | 
				
			||||||
        self.assertEqual(im2.size, (128, 128))
 | 
					            self.assertEqual(im2.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im2.format, "SPIDER")
 | 
					            self.assertEqual(im2.format, "SPIDER")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tempfile(self):
 | 
					    def test_tempfile(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -57,18 +74,18 @@ class TestImageSpider(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tell(self):
 | 
					    def test_tell(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        index = im.tell()
 | 
					            index = im.tell()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(index, 0)
 | 
					            self.assertEqual(index, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_n_frames(self):
 | 
					    def test_n_frames(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_loadImageSeries(self):
 | 
					    def test_loadImageSeries(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -109,15 +126,14 @@ class TestImageSpider(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(IOError, Image.open, invalid_file)
 | 
					        self.assertRaises(IOError, Image.open, invalid_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_nonstack_file(self):
 | 
					    def test_nonstack_file(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
 | 
					            self.assertRaises(EOFError, im.seek, 0)
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, 0)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_nonstack_dos(self):
 | 
					    def test_nonstack_dos(self):
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        for i, frame in enumerate(ImageSequence.Iterator(im)):
 | 
					            for i, frame in enumerate(ImageSequence.Iterator(im)):
 | 
				
			||||||
            if i > 1:
 | 
					                if i > 1:
 | 
				
			||||||
                self.fail("Non-stack DOS file test failed")
 | 
					                    self.fail("Non-stack DOS file test failed")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # for issue #4093
 | 
					    # for issue #4093
 | 
				
			||||||
    def test_odd_size(self):
 | 
					    def test_odd_size(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, TarIO
 | 
					from PIL import Image, TarIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase
 | 
					from .helper import PillowTestCase, is_pypy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
codecs = dir(Image.core)
 | 
					codecs = dir(Image.core)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,17 +21,30 @@ class TestFileTar(PillowTestCase):
 | 
				
			||||||
            ["jpeg_decoder", "hopper.jpg", "JPEG"],
 | 
					            ["jpeg_decoder", "hopper.jpg", "JPEG"],
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            if codec in codecs:
 | 
					            if codec in codecs:
 | 
				
			||||||
                tar = TarIO.TarIO(TEST_TAR_FILE, test_path)
 | 
					                with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar:
 | 
				
			||||||
                im = Image.open(tar)
 | 
					                    im = Image.open(tar)
 | 
				
			||||||
                im.load()
 | 
					                    im.load()
 | 
				
			||||||
                self.assertEqual(im.mode, "RGB")
 | 
					                    self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
                self.assertEqual(im.size, (128, 128))
 | 
					                    self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
                self.assertEqual(im.format, format)
 | 
					                    self.assertEqual(im.format, format)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_close(self):
 | 
					    def test_close(self):
 | 
				
			||||||
        tar = TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg")
 | 
					        def open():
 | 
				
			||||||
        tar.close()
 | 
					            tar = TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg")
 | 
				
			||||||
 | 
					            tar.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_contextmanager(self):
 | 
					    def test_contextmanager(self):
 | 
				
			||||||
        with TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg"):
 | 
					        def open():
 | 
				
			||||||
            pass
 | 
					            with TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg"):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,20 +76,20 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
        test_file = "Tests/images/tga_id_field.tga"
 | 
					        test_file = "Tests/images/tga_id_field.tga"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.size, (100, 100))
 | 
					            self.assertEqual(im.size, (100, 100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_id_field_rle(self):
 | 
					    def test_id_field_rle(self):
 | 
				
			||||||
        # tga file with id field
 | 
					        # tga file with id field
 | 
				
			||||||
        test_file = "Tests/images/rgb32rle.tga"
 | 
					        test_file = "Tests/images/rgb32rle.tga"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.size, (199, 199))
 | 
					            self.assertEqual(im.size, (199, 199))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        test_file = "Tests/images/tga_id_field.tga"
 | 
					        test_file = "Tests/images/tga_id_field.tga"
 | 
				
			||||||
| 
						 | 
					@ -99,14 +99,14 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save
 | 
					        # Save
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.size, (100, 100))
 | 
					            self.assertEqual(test_im.size, (100, 100))
 | 
				
			||||||
        self.assertEqual(test_im.info["id_section"], im.info["id_section"])
 | 
					            self.assertEqual(test_im.info["id_section"], im.info["id_section"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # RGBA save
 | 
					        # RGBA save
 | 
				
			||||||
        im.convert("RGBA").save(out)
 | 
					        im.convert("RGBA").save(out)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.size, (100, 100))
 | 
					            self.assertEqual(test_im.size, (100, 100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_id_section(self):
 | 
					    def test_save_id_section(self):
 | 
				
			||||||
        test_file = "Tests/images/rgb32rle.tga"
 | 
					        test_file = "Tests/images/rgb32rle.tga"
 | 
				
			||||||
| 
						 | 
					@ -116,27 +116,27 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check there is no id section
 | 
					        # Check there is no id section
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertNotIn("id_section", test_im.info)
 | 
					            self.assertNotIn("id_section", test_im.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save with custom id section
 | 
					        # Save with custom id section
 | 
				
			||||||
        im.save(out, id_section=b"Test content")
 | 
					        im.save(out, id_section=b"Test content")
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.info["id_section"], b"Test content")
 | 
					            self.assertEqual(test_im.info["id_section"], b"Test content")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save with custom id section greater than 255 characters
 | 
					        # Save with custom id section greater than 255 characters
 | 
				
			||||||
        id_section = b"Test content" * 25
 | 
					        id_section = b"Test content" * 25
 | 
				
			||||||
        self.assert_warning(UserWarning, lambda: im.save(out, id_section=id_section))
 | 
					        self.assert_warning(UserWarning, lambda: im.save(out, id_section=id_section))
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.info["id_section"], id_section[:255])
 | 
					            self.assertEqual(test_im.info["id_section"], id_section[:255])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_file = "Tests/images/tga_id_field.tga"
 | 
					        test_file = "Tests/images/tga_id_field.tga"
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        with Image.open(test_file) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save with no id section
 | 
					            # Save with no id section
 | 
				
			||||||
        im.save(out, id_section="")
 | 
					            im.save(out, id_section="")
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertNotIn("id_section", test_im.info)
 | 
					            self.assertNotIn("id_section", test_im.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_orientation(self):
 | 
					    def test_save_orientation(self):
 | 
				
			||||||
        test_file = "Tests/images/rgb32rle.tga"
 | 
					        test_file = "Tests/images/rgb32rle.tga"
 | 
				
			||||||
| 
						 | 
					@ -146,8 +146,8 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.tga")
 | 
					        out = self.tempfile("temp.tga")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(out, orientation=1)
 | 
					        im.save(out, orientation=1)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.info["orientation"], 1)
 | 
					            self.assertEqual(test_im.info["orientation"], 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_rle(self):
 | 
					    def test_save_rle(self):
 | 
				
			||||||
        test_file = "Tests/images/rgb32rle.tga"
 | 
					        test_file = "Tests/images/rgb32rle.tga"
 | 
				
			||||||
| 
						 | 
					@ -158,19 +158,19 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save
 | 
					        # Save
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.size, (199, 199))
 | 
					            self.assertEqual(test_im.size, (199, 199))
 | 
				
			||||||
        self.assertEqual(test_im.info["compression"], "tga_rle")
 | 
					            self.assertEqual(test_im.info["compression"], "tga_rle")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save without compression
 | 
					        # Save without compression
 | 
				
			||||||
        im.save(out, compression=None)
 | 
					        im.save(out, compression=None)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertNotIn("compression", test_im.info)
 | 
					            self.assertNotIn("compression", test_im.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # RGBA save
 | 
					        # RGBA save
 | 
				
			||||||
        im.convert("RGBA").save(out)
 | 
					        im.convert("RGBA").save(out)
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.size, (199, 199))
 | 
					            self.assertEqual(test_im.size, (199, 199))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_file = "Tests/images/tga_id_field.tga"
 | 
					        test_file = "Tests/images/tga_id_field.tga"
 | 
				
			||||||
        im = Image.open(test_file)
 | 
					        im = Image.open(test_file)
 | 
				
			||||||
| 
						 | 
					@ -178,8 +178,8 @@ class TestFileTga(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save with compression
 | 
					        # Save with compression
 | 
				
			||||||
        im.save(out, compression="tga_rle")
 | 
					        im.save(out, compression="tga_rle")
 | 
				
			||||||
        test_im = Image.open(out)
 | 
					        with Image.open(out) as test_im:
 | 
				
			||||||
        self.assertEqual(test_im.info["compression"], "tga_rle")
 | 
					            self.assertEqual(test_im.info["compression"], "tga_rle")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_l_transparency(self):
 | 
					    def test_save_l_transparency(self):
 | 
				
			||||||
        # There are 559 transparent pixels in la.tga.
 | 
					        # There are 559 transparent pixels in la.tga.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ from PIL import Image, TiffImagePlugin
 | 
				
			||||||
from PIL._util import py3
 | 
					from PIL._util import py3
 | 
				
			||||||
from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
 | 
					from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase, hopper, is_win32, unittest
 | 
					from .helper import PillowTestCase, hopper, is_pypy, is_win32, unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger = logging.getLogger(__name__)
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,32 +18,53 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("RGB").save(filename)
 | 
					        hopper("RGB").save(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.mode, "RGB")
 | 
					        self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					        self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
        self.assertEqual(im.format, "TIFF")
 | 
					        self.assertEqual(im.format, "TIFF")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("1").save(filename)
 | 
					        hopper("1").save(filename)
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("L").save(filename)
 | 
					        hopper("L").save(filename)
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("P").save(filename)
 | 
					        hopper("P").save(filename)
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("RGB").save(filename)
 | 
					        hopper("RGB").save(filename)
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hopper("I").save(filename)
 | 
					        hopper("I").save(filename)
 | 
				
			||||||
        Image.open(filename)
 | 
					        with Image.open(filename):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @unittest.skipIf(is_pypy(), "Requires CPython")
 | 
				
			||||||
    def test_unclosed_file(self):
 | 
					    def test_unclosed_file(self):
 | 
				
			||||||
        def open():
 | 
					        def open():
 | 
				
			||||||
            im = Image.open("Tests/images/multipage.tiff")
 | 
					            im = Image.open("Tests/images/multipage.tiff")
 | 
				
			||||||
            im.load()
 | 
					            im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(ResourceWarning, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_closed_file(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            im = Image.open("Tests/images/multipage.tiff")
 | 
				
			||||||
 | 
					            im.load()
 | 
				
			||||||
 | 
					            im.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_context_manager(self):
 | 
				
			||||||
 | 
					        def open():
 | 
				
			||||||
 | 
					            with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_warning(None, open)
 | 
					        self.assert_warning(None, open)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mac_tiff(self):
 | 
					    def test_mac_tiff(self):
 | 
				
			||||||
| 
						 | 
					@ -75,55 +96,55 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_xyres_tiff(self):
 | 
					    def test_xyres_tiff(self):
 | 
				
			||||||
        filename = "Tests/images/pil168.tif"
 | 
					        filename = "Tests/images/pil168.tif"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # legacy api
 | 
					            # legacy api
 | 
				
			||||||
        self.assertIsInstance(im.tag[X_RESOLUTION][0], tuple)
 | 
					            self.assertIsInstance(im.tag[X_RESOLUTION][0], tuple)
 | 
				
			||||||
        self.assertIsInstance(im.tag[Y_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[X_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
				
			||||||
        self.assertIsInstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
					            self.assertIsInstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (72.0, 72.0))
 | 
					            self.assertEqual(im.info["dpi"], (72.0, 72.0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_xyres_fallback_tiff(self):
 | 
					    def test_xyres_fallback_tiff(self):
 | 
				
			||||||
        filename = "Tests/images/compression.tif"
 | 
					        filename = "Tests/images/compression.tif"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # v2 api
 | 
					            # v2 api
 | 
				
			||||||
        self.assertIsInstance(im.tag_v2[X_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
					            self.assertIsInstance(im.tag_v2[X_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
				
			||||||
        self.assertIsInstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
					            self.assertIsInstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational)
 | 
				
			||||||
        self.assertRaises(KeyError, lambda: im.tag_v2[RESOLUTION_UNIT])
 | 
					            self.assertRaises(KeyError, lambda: im.tag_v2[RESOLUTION_UNIT])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Legacy.
 | 
					            # Legacy.
 | 
				
			||||||
        self.assertEqual(im.info["resolution"], (100.0, 100.0))
 | 
					            self.assertEqual(im.info["resolution"], (100.0, 100.0))
 | 
				
			||||||
        # Fallback "inch".
 | 
					            # Fallback "inch".
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (100.0, 100.0))
 | 
					            self.assertEqual(im.info["dpi"], (100.0, 100.0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_int_resolution(self):
 | 
					    def test_int_resolution(self):
 | 
				
			||||||
        filename = "Tests/images/pil168.tif"
 | 
					        filename = "Tests/images/pil168.tif"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Try to read a file where X,Y_RESOLUTION are ints
 | 
					            # Try to read a file where X,Y_RESOLUTION are ints
 | 
				
			||||||
        im.tag_v2[X_RESOLUTION] = 71
 | 
					            im.tag_v2[X_RESOLUTION] = 71
 | 
				
			||||||
        im.tag_v2[Y_RESOLUTION] = 71
 | 
					            im.tag_v2[Y_RESOLUTION] = 71
 | 
				
			||||||
        im._setup()
 | 
					            im._setup()
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], (71.0, 71.0))
 | 
					            self.assertEqual(im.info["dpi"], (71.0, 71.0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dpi_rounding(self):
 | 
					    def test_load_dpi_rounding(self):
 | 
				
			||||||
        for resolutionUnit, dpi in ((None, (72, 73)), (2, (72, 73)), (3, (183, 185))):
 | 
					        for resolutionUnit, dpi in ((None, (72, 73)), (2, (72, 73)), (3, (183, 185))):
 | 
				
			||||||
            im = Image.open(
 | 
					            with Image.open(
 | 
				
			||||||
                "Tests/images/hopper_roundDown_" + str(resolutionUnit) + ".tif"
 | 
					                "Tests/images/hopper_roundDown_" + str(resolutionUnit) + ".tif"
 | 
				
			||||||
            )
 | 
					            ) as im:
 | 
				
			||||||
            self.assertEqual(im.tag_v2.get(RESOLUTION_UNIT), resolutionUnit)
 | 
					                self.assertEqual(im.tag_v2.get(RESOLUTION_UNIT), resolutionUnit)
 | 
				
			||||||
            self.assertEqual(im.info["dpi"], (dpi[0], dpi[0]))
 | 
					                self.assertEqual(im.info["dpi"], (dpi[0], dpi[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            im = Image.open(
 | 
					            with Image.open(
 | 
				
			||||||
                "Tests/images/hopper_roundUp_" + str(resolutionUnit) + ".tif"
 | 
					                "Tests/images/hopper_roundUp_" + str(resolutionUnit) + ".tif"
 | 
				
			||||||
            )
 | 
					            ) as im:
 | 
				
			||||||
            self.assertEqual(im.tag_v2.get(RESOLUTION_UNIT), resolutionUnit)
 | 
					                self.assertEqual(im.tag_v2.get(RESOLUTION_UNIT), resolutionUnit)
 | 
				
			||||||
            self.assertEqual(im.info["dpi"], (dpi[1], dpi[1]))
 | 
					                self.assertEqual(im.info["dpi"], (dpi[1], dpi[1]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_dpi_rounding(self):
 | 
					    def test_save_dpi_rounding(self):
 | 
				
			||||||
        outfile = self.tempfile("temp.tif")
 | 
					        outfile = self.tempfile("temp.tif")
 | 
				
			||||||
| 
						 | 
					@ -155,9 +176,9 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
        TiffImagePlugin.PREFIXES.pop()
 | 
					        TiffImagePlugin.PREFIXES.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_bad_exif(self):
 | 
					    def test_bad_exif(self):
 | 
				
			||||||
        i = Image.open("Tests/images/hopper_bad_exif.jpg")
 | 
					        with Image.open("Tests/images/hopper_bad_exif.jpg") as i:
 | 
				
			||||||
        # Should not raise struct.error.
 | 
					            # Should not raise struct.error.
 | 
				
			||||||
        self.assert_warning(UserWarning, i._getexif)
 | 
					            self.assert_warning(UserWarning, i._getexif)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_rgba(self):
 | 
					    def test_save_rgba(self):
 | 
				
			||||||
        im = hopper("RGBA")
 | 
					        im = hopper("RGBA")
 | 
				
			||||||
| 
						 | 
					@ -238,44 +259,44 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
            ["Tests/images/multipage-lastframe.tif", 1],
 | 
					            ["Tests/images/multipage-lastframe.tif", 1],
 | 
				
			||||||
            ["Tests/images/multipage.tiff", 3],
 | 
					            ["Tests/images/multipage.tiff", 3],
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            im = Image.open(path)
 | 
					            with Image.open(path) as im:
 | 
				
			||||||
            self.assertEqual(im.n_frames, n_frames)
 | 
					                self.assertEqual(im.n_frames, n_frames)
 | 
				
			||||||
            self.assertEqual(im.is_animated, n_frames != 1)
 | 
					                self.assertEqual(im.is_animated, n_frames != 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_eoferror(self):
 | 
					    def test_eoferror(self):
 | 
				
			||||||
        im = Image.open("Tests/images/multipage-lastframe.tif")
 | 
					        with Image.open("Tests/images/multipage-lastframe.tif") as im:
 | 
				
			||||||
        n_frames = im.n_frames
 | 
					            n_frames = im.n_frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test seeking past the last frame
 | 
					            # Test seeking past the last frame
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, n_frames)
 | 
					            self.assertRaises(EOFError, im.seek, n_frames)
 | 
				
			||||||
        self.assertLess(im.tell(), n_frames)
 | 
					            self.assertLess(im.tell(), n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that seeking to the last frame does not raise an error
 | 
					            # Test that seeking to the last frame does not raise an error
 | 
				
			||||||
        im.seek(n_frames - 1)
 | 
					            im.seek(n_frames - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multipage(self):
 | 
					    def test_multipage(self):
 | 
				
			||||||
        # issue #862
 | 
					        # issue #862
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        # file is a multipage tiff: 10x10 green, 10x10 red, 20x20 blue
 | 
					            # file is a multipage tiff: 10x10 green, 10x10 red, 20x20 blue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(1)
 | 
					            im.seek(1)
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (255, 0, 0))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (255, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 128, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.seek(2)
 | 
					            im.seek(2)
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.size, (20, 20))
 | 
					            self.assertEqual(im.size, (20, 20))
 | 
				
			||||||
        self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
 | 
					            self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multipage_last_frame(self):
 | 
					    def test_multipage_last_frame(self):
 | 
				
			||||||
        im = Image.open("Tests/images/multipage-lastframe.tif")
 | 
					        im = Image.open("Tests/images/multipage-lastframe.tif")
 | 
				
			||||||
| 
						 | 
					@ -285,62 +306,62 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test___str__(self):
 | 
					    def test___str__(self):
 | 
				
			||||||
        filename = "Tests/images/pil136.tiff"
 | 
					        filename = "Tests/images/pil136.tiff"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        ret = str(im.ifd)
 | 
					            ret = str(im.ifd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertIsInstance(ret, str)
 | 
					            self.assertIsInstance(ret, str)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dict(self):
 | 
					    def test_dict(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        filename = "Tests/images/pil136.tiff"
 | 
					        filename = "Tests/images/pil136.tiff"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # v2 interface
 | 
					            # v2 interface
 | 
				
			||||||
        v2_tags = {
 | 
					            v2_tags = {
 | 
				
			||||||
            256: 55,
 | 
					                256: 55,
 | 
				
			||||||
            257: 43,
 | 
					                257: 43,
 | 
				
			||||||
            258: (8, 8, 8, 8),
 | 
					                258: (8, 8, 8, 8),
 | 
				
			||||||
            259: 1,
 | 
					                259: 1,
 | 
				
			||||||
            262: 2,
 | 
					                262: 2,
 | 
				
			||||||
            296: 2,
 | 
					                296: 2,
 | 
				
			||||||
            273: (8,),
 | 
					                273: (8,),
 | 
				
			||||||
            338: (1,),
 | 
					                338: (1,),
 | 
				
			||||||
            277: 4,
 | 
					                277: 4,
 | 
				
			||||||
            279: (9460,),
 | 
					                279: (9460,),
 | 
				
			||||||
            282: 72.0,
 | 
					                282: 72.0,
 | 
				
			||||||
            283: 72.0,
 | 
					                283: 72.0,
 | 
				
			||||||
            284: 1,
 | 
					                284: 1,
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
        self.assertEqual(dict(im.tag_v2), v2_tags)
 | 
					            self.assertEqual(dict(im.tag_v2), v2_tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # legacy interface
 | 
					            # legacy interface
 | 
				
			||||||
        legacy_tags = {
 | 
					            legacy_tags = {
 | 
				
			||||||
            256: (55,),
 | 
					                256: (55,),
 | 
				
			||||||
            257: (43,),
 | 
					                257: (43,),
 | 
				
			||||||
            258: (8, 8, 8, 8),
 | 
					                258: (8, 8, 8, 8),
 | 
				
			||||||
            259: (1,),
 | 
					                259: (1,),
 | 
				
			||||||
            262: (2,),
 | 
					                262: (2,),
 | 
				
			||||||
            296: (2,),
 | 
					                296: (2,),
 | 
				
			||||||
            273: (8,),
 | 
					                273: (8,),
 | 
				
			||||||
            338: (1,),
 | 
					                338: (1,),
 | 
				
			||||||
            277: (4,),
 | 
					                277: (4,),
 | 
				
			||||||
            279: (9460,),
 | 
					                279: (9460,),
 | 
				
			||||||
            282: ((720000, 10000),),
 | 
					                282: ((720000, 10000),),
 | 
				
			||||||
            283: ((720000, 10000),),
 | 
					                283: ((720000, 10000),),
 | 
				
			||||||
            284: (1,),
 | 
					                284: (1,),
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
        self.assertEqual(dict(im.tag), legacy_tags)
 | 
					            self.assertEqual(dict(im.tag), legacy_tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test__delitem__(self):
 | 
					    def test__delitem__(self):
 | 
				
			||||||
        filename = "Tests/images/pil136.tiff"
 | 
					        filename = "Tests/images/pil136.tiff"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
        len_before = len(dict(im.ifd))
 | 
					            len_before = len(dict(im.ifd))
 | 
				
			||||||
        del im.ifd[256]
 | 
					            del im.ifd[256]
 | 
				
			||||||
        len_after = len(dict(im.ifd))
 | 
					            len_after = len(dict(im.ifd))
 | 
				
			||||||
        self.assertEqual(len_before, len_after + 1)
 | 
					            self.assertEqual(len_before, len_after + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_byte(self):
 | 
					    def test_load_byte(self):
 | 
				
			||||||
        for legacy_api in [False, True]:
 | 
					        for legacy_api in [False, True]:
 | 
				
			||||||
| 
						 | 
					@ -369,16 +390,16 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek(self):
 | 
					    def test_seek(self):
 | 
				
			||||||
        filename = "Tests/images/pil136.tiff"
 | 
					        filename = "Tests/images/pil136.tiff"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        self.assertEqual(im.tell(), 0)
 | 
					            self.assertEqual(im.tell(), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_seek_eof(self):
 | 
					    def test_seek_eof(self):
 | 
				
			||||||
        filename = "Tests/images/pil136.tiff"
 | 
					        filename = "Tests/images/pil136.tiff"
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
        self.assertEqual(im.tell(), 0)
 | 
					            self.assertEqual(im.tell(), 0)
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, -1)
 | 
					            self.assertRaises(EOFError, im.seek, -1)
 | 
				
			||||||
        self.assertRaises(EOFError, im.seek, 1)
 | 
					            self.assertRaises(EOFError, im.seek, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test__limit_rational_int(self):
 | 
					    def test__limit_rational_int(self):
 | 
				
			||||||
        from PIL.TiffImagePlugin import _limit_rational
 | 
					        from PIL.TiffImagePlugin import _limit_rational
 | 
				
			||||||
| 
						 | 
					@ -439,15 +460,15 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
        kwargs = {"resolution_unit": "inch", "x_resolution": 72, "y_resolution": 36}
 | 
					        kwargs = {"resolution_unit": "inch", "x_resolution": 72, "y_resolution": 36}
 | 
				
			||||||
        filename = self.tempfile("temp.tif")
 | 
					        filename = self.tempfile("temp.tif")
 | 
				
			||||||
        hopper("RGB").save(filename, **kwargs)
 | 
					        hopper("RGB").save(filename, **kwargs)
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # legacy interface
 | 
					            # legacy interface
 | 
				
			||||||
        self.assertEqual(im.tag[X_RESOLUTION][0][0], 72)
 | 
					            self.assertEqual(im.tag[X_RESOLUTION][0][0], 72)
 | 
				
			||||||
        self.assertEqual(im.tag[Y_RESOLUTION][0][0], 36)
 | 
					            self.assertEqual(im.tag[Y_RESOLUTION][0][0], 36)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # v2 interface
 | 
					            # v2 interface
 | 
				
			||||||
        self.assertEqual(im.tag_v2[X_RESOLUTION], 72)
 | 
					            self.assertEqual(im.tag_v2[X_RESOLUTION], 72)
 | 
				
			||||||
        self.assertEqual(im.tag_v2[Y_RESOLUTION], 36)
 | 
					            self.assertEqual(im.tag_v2[Y_RESOLUTION], 36)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_roundtrip_tiff_uint16(self):
 | 
					    def test_roundtrip_tiff_uint16(self):
 | 
				
			||||||
        # Test an image of all '0' values
 | 
					        # Test an image of all '0' values
 | 
				
			||||||
| 
						 | 
					@ -480,9 +501,8 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
    def test_strip_planar_raw_with_overviews(self):
 | 
					    def test_strip_planar_raw_with_overviews(self):
 | 
				
			||||||
        # gdaladdo tiff_strip_planar_raw2.tif 2 4 8 16
 | 
					        # gdaladdo tiff_strip_planar_raw2.tif 2 4 8 16
 | 
				
			||||||
        infile = "Tests/images/tiff_strip_planar_raw_with_overviews.tif"
 | 
					        infile = "Tests/images/tiff_strip_planar_raw_with_overviews.tif"
 | 
				
			||||||
        im = Image.open(infile)
 | 
					        with Image.open(infile) as im:
 | 
				
			||||||
 | 
					            self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
 | 
				
			||||||
        self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tiled_planar_raw(self):
 | 
					    def test_tiled_planar_raw(self):
 | 
				
			||||||
        # gdal_translate -of GTiff -co TILED=YES -co BLOCKXSIZE=32 \
 | 
					        # gdal_translate -of GTiff -co TILED=YES -co BLOCKXSIZE=32 \
 | 
				
			||||||
| 
						 | 
					@ -545,9 +565,8 @@ class TestFileTiff(PillowTestCase):
 | 
				
			||||||
        # Try save-load round trip to make sure both handle icc_profile.
 | 
					        # Try save-load round trip to make sure both handle icc_profile.
 | 
				
			||||||
        tmpfile = self.tempfile("temp.tif")
 | 
					        tmpfile = self.tempfile("temp.tif")
 | 
				
			||||||
        im.save(tmpfile, "TIFF", compression="raw")
 | 
					        im.save(tmpfile, "TIFF", compression="raw")
 | 
				
			||||||
        reloaded = Image.open(tmpfile)
 | 
					        with Image.open(tmpfile) as reloaded:
 | 
				
			||||||
 | 
					            self.assertEqual(b"Dummy value", reloaded.info["icc_profile"])
 | 
				
			||||||
        self.assertEqual(b"Dummy value", reloaded.info["icc_profile"])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_close_on_load_exclusive(self):
 | 
					    def test_close_on_load_exclusive(self):
 | 
				
			||||||
        # similar to test_fd_leak, but runs on unixlike os
 | 
					        # similar to test_fd_leak, but runs on unixlike os
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,77 +52,81 @@ class TestFileTiffMetadata(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        img.save(f, tiffinfo=info)
 | 
					        img.save(f, tiffinfo=info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        loaded = Image.open(f)
 | 
					        with Image.open(f) as loaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(loaded.tag[ImageJMetaDataByteCounts], (len(bindata),))
 | 
					            self.assertEqual(loaded.tag[ImageJMetaDataByteCounts], (len(bindata),))
 | 
				
			||||||
        self.assertEqual(loaded.tag_v2[ImageJMetaDataByteCounts], (len(bindata),))
 | 
					            self.assertEqual(loaded.tag_v2[ImageJMetaDataByteCounts], (len(bindata),))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(loaded.tag[ImageJMetaData], bindata)
 | 
					            self.assertEqual(loaded.tag[ImageJMetaData], bindata)
 | 
				
			||||||
        self.assertEqual(loaded.tag_v2[ImageJMetaData], bindata)
 | 
					            self.assertEqual(loaded.tag_v2[ImageJMetaData], bindata)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(loaded.tag[ImageDescription], (reloaded_textdata,))
 | 
					            self.assertEqual(loaded.tag[ImageDescription], (reloaded_textdata,))
 | 
				
			||||||
        self.assertEqual(loaded.tag_v2[ImageDescription], reloaded_textdata)
 | 
					            self.assertEqual(loaded.tag_v2[ImageDescription], reloaded_textdata)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        loaded_float = loaded.tag[tag_ids["RollAngle"]][0]
 | 
					            loaded_float = loaded.tag[tag_ids["RollAngle"]][0]
 | 
				
			||||||
        self.assertAlmostEqual(loaded_float, floatdata, places=5)
 | 
					            self.assertAlmostEqual(loaded_float, floatdata, places=5)
 | 
				
			||||||
        loaded_double = loaded.tag[tag_ids["YawAngle"]][0]
 | 
					            loaded_double = loaded.tag[tag_ids["YawAngle"]][0]
 | 
				
			||||||
        self.assertAlmostEqual(loaded_double, doubledata)
 | 
					            self.assertAlmostEqual(loaded_double, doubledata)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # check with 2 element ImageJMetaDataByteCounts, issue #2006
 | 
					        # check with 2 element ImageJMetaDataByteCounts, issue #2006
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        info[ImageJMetaDataByteCounts] = (8, len(bindata) - 8)
 | 
					        info[ImageJMetaDataByteCounts] = (8, len(bindata) - 8)
 | 
				
			||||||
        img.save(f, tiffinfo=info)
 | 
					        img.save(f, tiffinfo=info)
 | 
				
			||||||
        loaded = Image.open(f)
 | 
					        with Image.open(f) as loaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(loaded.tag[ImageJMetaDataByteCounts], (8, len(bindata) - 8))
 | 
					            self.assertEqual(
 | 
				
			||||||
        self.assertEqual(loaded.tag_v2[ImageJMetaDataByteCounts], (8, len(bindata) - 8))
 | 
					                loaded.tag[ImageJMetaDataByteCounts], (8, len(bindata) - 8)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            self.assertEqual(
 | 
				
			||||||
 | 
					                loaded.tag_v2[ImageJMetaDataByteCounts], (8, len(bindata) - 8)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_read_metadata(self):
 | 
					    def test_read_metadata(self):
 | 
				
			||||||
        img = Image.open("Tests/images/hopper_g4.tif")
 | 
					        with Image.open("Tests/images/hopper_g4.tif") as img:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            {
 | 
					                {
 | 
				
			||||||
                "YResolution": IFDRational(4294967295, 113653537),
 | 
					                    "YResolution": IFDRational(4294967295, 113653537),
 | 
				
			||||||
                "PlanarConfiguration": 1,
 | 
					                    "PlanarConfiguration": 1,
 | 
				
			||||||
                "BitsPerSample": (1,),
 | 
					                    "BitsPerSample": (1,),
 | 
				
			||||||
                "ImageLength": 128,
 | 
					                    "ImageLength": 128,
 | 
				
			||||||
                "Compression": 4,
 | 
					                    "Compression": 4,
 | 
				
			||||||
                "FillOrder": 1,
 | 
					                    "FillOrder": 1,
 | 
				
			||||||
                "RowsPerStrip": 128,
 | 
					                    "RowsPerStrip": 128,
 | 
				
			||||||
                "ResolutionUnit": 3,
 | 
					                    "ResolutionUnit": 3,
 | 
				
			||||||
                "PhotometricInterpretation": 0,
 | 
					                    "PhotometricInterpretation": 0,
 | 
				
			||||||
                "PageNumber": (0, 1),
 | 
					                    "PageNumber": (0, 1),
 | 
				
			||||||
                "XResolution": IFDRational(4294967295, 113653537),
 | 
					                    "XResolution": IFDRational(4294967295, 113653537),
 | 
				
			||||||
                "ImageWidth": 128,
 | 
					                    "ImageWidth": 128,
 | 
				
			||||||
                "Orientation": 1,
 | 
					                    "Orientation": 1,
 | 
				
			||||||
                "StripByteCounts": (1968,),
 | 
					                    "StripByteCounts": (1968,),
 | 
				
			||||||
                "SamplesPerPixel": 1,
 | 
					                    "SamplesPerPixel": 1,
 | 
				
			||||||
                "StripOffsets": (8,),
 | 
					                    "StripOffsets": (8,),
 | 
				
			||||||
            },
 | 
					                },
 | 
				
			||||||
            img.tag_v2.named(),
 | 
					                img.tag_v2.named(),
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            {
 | 
					                {
 | 
				
			||||||
                "YResolution": ((4294967295, 113653537),),
 | 
					                    "YResolution": ((4294967295, 113653537),),
 | 
				
			||||||
                "PlanarConfiguration": (1,),
 | 
					                    "PlanarConfiguration": (1,),
 | 
				
			||||||
                "BitsPerSample": (1,),
 | 
					                    "BitsPerSample": (1,),
 | 
				
			||||||
                "ImageLength": (128,),
 | 
					                    "ImageLength": (128,),
 | 
				
			||||||
                "Compression": (4,),
 | 
					                    "Compression": (4,),
 | 
				
			||||||
                "FillOrder": (1,),
 | 
					                    "FillOrder": (1,),
 | 
				
			||||||
                "RowsPerStrip": (128,),
 | 
					                    "RowsPerStrip": (128,),
 | 
				
			||||||
                "ResolutionUnit": (3,),
 | 
					                    "ResolutionUnit": (3,),
 | 
				
			||||||
                "PhotometricInterpretation": (0,),
 | 
					                    "PhotometricInterpretation": (0,),
 | 
				
			||||||
                "PageNumber": (0, 1),
 | 
					                    "PageNumber": (0, 1),
 | 
				
			||||||
                "XResolution": ((4294967295, 113653537),),
 | 
					                    "XResolution": ((4294967295, 113653537),),
 | 
				
			||||||
                "ImageWidth": (128,),
 | 
					                    "ImageWidth": (128,),
 | 
				
			||||||
                "Orientation": (1,),
 | 
					                    "Orientation": (1,),
 | 
				
			||||||
                "StripByteCounts": (1968,),
 | 
					                    "StripByteCounts": (1968,),
 | 
				
			||||||
                "SamplesPerPixel": (1,),
 | 
					                    "SamplesPerPixel": (1,),
 | 
				
			||||||
                "StripOffsets": (8,),
 | 
					                    "StripOffsets": (8,),
 | 
				
			||||||
            },
 | 
					                },
 | 
				
			||||||
            img.tag.named(),
 | 
					                img.tag.named(),
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write_metadata(self):
 | 
					    def test_write_metadata(self):
 | 
				
			||||||
        """ Test metadata writing through the python code """
 | 
					        """ Test metadata writing through the python code """
 | 
				
			||||||
| 
						 | 
					@ -131,10 +135,10 @@ class TestFileTiffMetadata(PillowTestCase):
 | 
				
			||||||
        f = self.tempfile("temp.tiff")
 | 
					        f = self.tempfile("temp.tiff")
 | 
				
			||||||
        img.save(f, tiffinfo=img.tag)
 | 
					        img.save(f, tiffinfo=img.tag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        loaded = Image.open(f)
 | 
					        with Image.open(f) as loaded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        original = img.tag_v2.named()
 | 
					            original = img.tag_v2.named()
 | 
				
			||||||
        reloaded = loaded.tag_v2.named()
 | 
					            reloaded = loaded.tag_v2.named()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for k, v in original.items():
 | 
					        for k, v in original.items():
 | 
				
			||||||
            if isinstance(v, IFDRational):
 | 
					            if isinstance(v, IFDRational):
 | 
				
			||||||
| 
						 | 
					@ -187,18 +191,18 @@ class TestFileTiffMetadata(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.tiff")
 | 
					        out = self.tempfile("temp.tiff")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertNotIsInstance(im.info["icc_profile"], tuple)
 | 
					            self.assertNotIsInstance(im.info["icc_profile"], tuple)
 | 
				
			||||||
        self.assertEqual(im.info["icc_profile"], reloaded.info["icc_profile"])
 | 
					            self.assertEqual(im.info["icc_profile"], reloaded.info["icc_profile"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_iccprofile_binary(self):
 | 
					    def test_iccprofile_binary(self):
 | 
				
			||||||
        # https://github.com/python-pillow/Pillow/issues/1526
 | 
					        # https://github.com/python-pillow/Pillow/issues/1526
 | 
				
			||||||
        # We should be able to load this,
 | 
					        # We should be able to load this,
 | 
				
			||||||
        # but probably won't be able to save it.
 | 
					        # but probably won't be able to save it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.iccprofile_binary.tif")
 | 
					        with Image.open("Tests/images/hopper.iccprofile_binary.tif") as im:
 | 
				
			||||||
        self.assertEqual(im.tag_v2.tagtype[34675], 1)
 | 
					            self.assertEqual(im.tag_v2.tagtype[34675], 1)
 | 
				
			||||||
        self.assertTrue(im.info["icc_profile"])
 | 
					            self.assertTrue(im.info["icc_profile"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_iccprofile_save_png(self):
 | 
					    def test_iccprofile_save_png(self):
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.iccprofile.tif")
 | 
					        im = Image.open("Tests/images/hopper.iccprofile.tif")
 | 
				
			||||||
| 
						 | 
					@ -218,9 +222,9 @@ class TestFileTiffMetadata(PillowTestCase):
 | 
				
			||||||
        out = self.tempfile("temp.tiff")
 | 
					        out = self.tempfile("temp.tiff")
 | 
				
			||||||
        im.save(out, tiffinfo=info, compression="raw")
 | 
					        im.save(out, tiffinfo=info, compression="raw")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertEqual(0, reloaded.tag_v2[41988].numerator)
 | 
					            self.assertEqual(0, reloaded.tag_v2[41988].numerator)
 | 
				
			||||||
        self.assertEqual(0, reloaded.tag_v2[41988].denominator)
 | 
					            self.assertEqual(0, reloaded.tag_v2[41988].denominator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_empty_values(self):
 | 
					    def test_empty_values(self):
 | 
				
			||||||
        data = io.BytesIO(
 | 
					        data = io.BytesIO(
 | 
				
			||||||
| 
						 | 
					@ -243,9 +247,9 @@ class TestFileTiffMetadata(PillowTestCase):
 | 
				
			||||||
        self.assertIsInstance(im.tag_v2[34377][0], bytes)
 | 
					        self.assertIsInstance(im.tag_v2[34377][0], bytes)
 | 
				
			||||||
        out = self.tempfile("temp.tiff")
 | 
					        out = self.tempfile("temp.tiff")
 | 
				
			||||||
        im.save(out)
 | 
					        im.save(out)
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        self.assertEqual(len(reloaded.tag_v2[34377]), 1)
 | 
					            self.assertEqual(len(reloaded.tag_v2[34377]), 1)
 | 
				
			||||||
        self.assertIsInstance(reloaded.tag_v2[34377][0], bytes)
 | 
					            self.assertIsInstance(reloaded.tag_v2[34377][0], bytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_too_many_entries(self):
 | 
					    def test_too_many_entries(self):
 | 
				
			||||||
        ifd = TiffImagePlugin.ImageFileDirectory_v2()
 | 
					        ifd = TiffImagePlugin.ImageFileDirectory_v2()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,19 +158,19 @@ class TestFileWebp(PillowTestCase):
 | 
				
			||||||
        HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP save all not available"
 | 
					        HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP save all not available"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    def test_background_from_gif(self):
 | 
					    def test_background_from_gif(self):
 | 
				
			||||||
        im = Image.open("Tests/images/chi.gif")
 | 
					        with Image.open("Tests/images/chi.gif") as im:
 | 
				
			||||||
        original_value = im.convert("RGB").getpixel((1, 1))
 | 
					            original_value = im.convert("RGB").getpixel((1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save as WEBP
 | 
					            # Save as WEBP
 | 
				
			||||||
        out_webp = self.tempfile("temp.webp")
 | 
					            out_webp = self.tempfile("temp.webp")
 | 
				
			||||||
        im.save(out_webp, save_all=True)
 | 
					            im.save(out_webp, save_all=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save as GIF
 | 
					        # Save as GIF
 | 
				
			||||||
        out_gif = self.tempfile("temp.gif")
 | 
					        out_gif = self.tempfile("temp.gif")
 | 
				
			||||||
        Image.open(out_webp).save(out_gif)
 | 
					        Image.open(out_webp).save(out_gif)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reread = Image.open(out_gif)
 | 
					        with Image.open(out_gif) as reread:
 | 
				
			||||||
        reread_value = reread.convert("RGB").getpixel((1, 1))
 | 
					            reread_value = reread.convert("RGB").getpixel((1, 1))
 | 
				
			||||||
        difference = sum(
 | 
					        difference = sum(
 | 
				
			||||||
            [abs(original_value[i] - reread_value[i]) for i in range(0, 3)]
 | 
					            [abs(original_value[i] - reread_value[i]) for i in range(0, 3)]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,7 +103,8 @@ class TestFileWebpAlpha(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        temp_file = self.tempfile("temp.webp")
 | 
					        temp_file = self.tempfile("temp.webp")
 | 
				
			||||||
        file_path = "Tests/images/transparent.gif"
 | 
					        file_path = "Tests/images/transparent.gif"
 | 
				
			||||||
        Image.open(file_path).save(temp_file)
 | 
					        with Image.open(file_path) as im:
 | 
				
			||||||
 | 
					            im.save(temp_file)
 | 
				
			||||||
        image = Image.open(temp_file)
 | 
					        image = Image.open(temp_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(image.mode, "RGBA")
 | 
					        self.assertEqual(image.mode, "RGBA")
 | 
				
			||||||
| 
						 | 
					@ -112,6 +113,7 @@ class TestFileWebpAlpha(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image.load()
 | 
					        image.load()
 | 
				
			||||||
        image.getdata()
 | 
					        image.getdata()
 | 
				
			||||||
        target = Image.open(file_path).convert("RGBA")
 | 
					        with Image.open(file_path) as im:
 | 
				
			||||||
 | 
					            target = im.convert("RGBA")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assert_image_similar(image, target, 25.0)
 | 
					        self.assert_image_similar(image, target, 25.0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,13 +28,13 @@ class TestFileWebpAnimation(PillowTestCase):
 | 
				
			||||||
        attributes correctly.
 | 
					        attributes correctly.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.webp")
 | 
					        with Image.open("Tests/images/hopper.webp") as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 1)
 | 
					            self.assertEqual(im.n_frames, 1)
 | 
				
			||||||
        self.assertFalse(im.is_animated)
 | 
					            self.assertFalse(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/iss634.webp")
 | 
					        with Image.open("Tests/images/iss634.webp") as im:
 | 
				
			||||||
        self.assertEqual(im.n_frames, 42)
 | 
					            self.assertEqual(im.n_frames, 42)
 | 
				
			||||||
        self.assertTrue(im.is_animated)
 | 
					            self.assertTrue(im.is_animated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write_animation_L(self):
 | 
					    def test_write_animation_L(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -43,23 +43,23 @@ class TestFileWebpAnimation(PillowTestCase):
 | 
				
			||||||
        visually similar.
 | 
					        visually similar.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        orig = Image.open("Tests/images/iss634.gif")
 | 
					        with Image.open("Tests/images/iss634.gif") as orig:
 | 
				
			||||||
        self.assertGreater(orig.n_frames, 1)
 | 
					            self.assertGreater(orig.n_frames, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        temp_file = self.tempfile("temp.webp")
 | 
					            temp_file = self.tempfile("temp.webp")
 | 
				
			||||||
        orig.save(temp_file, save_all=True)
 | 
					            orig.save(temp_file, save_all=True)
 | 
				
			||||||
        im = Image.open(temp_file)
 | 
					            im = Image.open(temp_file)
 | 
				
			||||||
        self.assertEqual(im.n_frames, orig.n_frames)
 | 
					            self.assertEqual(im.n_frames, orig.n_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Compare first and last frames to the original animated GIF
 | 
					            # Compare first and last frames to the original animated GIF
 | 
				
			||||||
        orig.load()
 | 
					            orig.load()
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | 
					            self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | 
				
			||||||
        orig.seek(orig.n_frames - 1)
 | 
					            orig.seek(orig.n_frames - 1)
 | 
				
			||||||
        im.seek(im.n_frames - 1)
 | 
					            im.seek(im.n_frames - 1)
 | 
				
			||||||
        orig.load()
 | 
					            orig.load()
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | 
					            self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write_animation_RGB(self):
 | 
					    def test_write_animation_RGB(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,21 +24,21 @@ class TestFileWebpMetadata(PillowTestCase):
 | 
				
			||||||
    def test_read_exif_metadata(self):
 | 
					    def test_read_exif_metadata(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        file_path = "Tests/images/flower.webp"
 | 
					        file_path = "Tests/images/flower.webp"
 | 
				
			||||||
        image = Image.open(file_path)
 | 
					        with Image.open(file_path) as image:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(image.format, "WEBP")
 | 
					            self.assertEqual(image.format, "WEBP")
 | 
				
			||||||
        exif_data = image.info.get("exif", None)
 | 
					            exif_data = image.info.get("exif", None)
 | 
				
			||||||
        self.assertTrue(exif_data)
 | 
					            self.assertTrue(exif_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        exif = image._getexif()
 | 
					            exif = image._getexif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # camera make
 | 
					            # camera make
 | 
				
			||||||
        self.assertEqual(exif[271], "Canon")
 | 
					            self.assertEqual(exif[271], "Canon")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        jpeg_image = Image.open("Tests/images/flower.jpg")
 | 
					            with Image.open("Tests/images/flower.jpg") as jpeg_image:
 | 
				
			||||||
        expected_exif = jpeg_image.info["exif"]
 | 
					                expected_exif = jpeg_image.info["exif"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(exif_data, expected_exif)
 | 
					                self.assertEqual(exif_data, expected_exif)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write_exif_metadata(self):
 | 
					    def test_write_exif_metadata(self):
 | 
				
			||||||
        file_path = "Tests/images/flower.jpg"
 | 
					        file_path = "Tests/images/flower.jpg"
 | 
				
			||||||
| 
						 | 
					@ -60,17 +60,17 @@ class TestFileWebpMetadata(PillowTestCase):
 | 
				
			||||||
    def test_read_icc_profile(self):
 | 
					    def test_read_icc_profile(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        file_path = "Tests/images/flower2.webp"
 | 
					        file_path = "Tests/images/flower2.webp"
 | 
				
			||||||
        image = Image.open(file_path)
 | 
					        with Image.open(file_path) as image:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(image.format, "WEBP")
 | 
					            self.assertEqual(image.format, "WEBP")
 | 
				
			||||||
        self.assertTrue(image.info.get("icc_profile", None))
 | 
					            self.assertTrue(image.info.get("icc_profile", None))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        icc = image.info["icc_profile"]
 | 
					            icc = image.info["icc_profile"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        jpeg_image = Image.open("Tests/images/flower2.jpg")
 | 
					            with Image.open("Tests/images/flower2.jpg") as jpeg_image:
 | 
				
			||||||
        expected_icc = jpeg_image.info["icc_profile"]
 | 
					                expected_icc = jpeg_image.info["icc_profile"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(icc, expected_icc)
 | 
					                self.assertEqual(icc, expected_icc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write_icc_metadata(self):
 | 
					    def test_write_icc_metadata(self):
 | 
				
			||||||
        file_path = "Tests/images/flower2.jpg"
 | 
					        file_path = "Tests/images/flower2.jpg"
 | 
				
			||||||
| 
						 | 
					@ -126,10 +126,10 @@ class TestFileWebpMetadata(PillowTestCase):
 | 
				
			||||||
            xmp=xmp_data,
 | 
					            xmp=xmp_data,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image = Image.open(temp_file)
 | 
					        with Image.open(temp_file) as image:
 | 
				
			||||||
        self.assertIn("icc_profile", image.info)
 | 
					            self.assertIn("icc_profile", image.info)
 | 
				
			||||||
        self.assertIn("exif", image.info)
 | 
					            self.assertIn("exif", image.info)
 | 
				
			||||||
        self.assertIn("xmp", image.info)
 | 
					            self.assertIn("xmp", image.info)
 | 
				
			||||||
        self.assertEqual(iccp_data, image.info.get("icc_profile", None))
 | 
					            self.assertEqual(iccp_data, image.info.get("icc_profile", None))
 | 
				
			||||||
        self.assertEqual(exif_data, image.info.get("exif", None))
 | 
					            self.assertEqual(exif_data, image.info.get("exif", None))
 | 
				
			||||||
        self.assertEqual(xmp_data, image.info.get("xmp", None))
 | 
					            self.assertEqual(xmp_data, image.info.get("xmp", None))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,24 +7,24 @@ class TestFileWmf(PillowTestCase):
 | 
				
			||||||
    def test_load_raw(self):
 | 
					    def test_load_raw(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test basic EMF open and rendering
 | 
					        # Test basic EMF open and rendering
 | 
				
			||||||
        im = Image.open("Tests/images/drawing.emf")
 | 
					        with Image.open("Tests/images/drawing.emf") as im:
 | 
				
			||||||
        if hasattr(Image.core, "drawwmf"):
 | 
					            if hasattr(Image.core, "drawwmf"):
 | 
				
			||||||
            # Currently, support for WMF/EMF is Windows-only
 | 
					                # Currently, support for WMF/EMF is Windows-only
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
            # Compare to reference rendering
 | 
					                # Compare to reference rendering
 | 
				
			||||||
            imref = Image.open("Tests/images/drawing_emf_ref.png")
 | 
					                imref = Image.open("Tests/images/drawing_emf_ref.png")
 | 
				
			||||||
            imref.load()
 | 
					                imref.load()
 | 
				
			||||||
            self.assert_image_similar(im, imref, 0)
 | 
					                self.assert_image_similar(im, imref, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test basic WMF open and rendering
 | 
					        # Test basic WMF open and rendering
 | 
				
			||||||
        im = Image.open("Tests/images/drawing.wmf")
 | 
					        with Image.open("Tests/images/drawing.wmf") as im:
 | 
				
			||||||
        if hasattr(Image.core, "drawwmf"):
 | 
					            if hasattr(Image.core, "drawwmf"):
 | 
				
			||||||
            # Currently, support for WMF/EMF is Windows-only
 | 
					                # Currently, support for WMF/EMF is Windows-only
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
            # Compare to reference rendering
 | 
					                # Compare to reference rendering
 | 
				
			||||||
            imref = Image.open("Tests/images/drawing_wmf_ref.png")
 | 
					                imref = Image.open("Tests/images/drawing_wmf_ref.png")
 | 
				
			||||||
            imref.load()
 | 
					                imref.load()
 | 
				
			||||||
            self.assert_image_similar(im, imref, 2.0)
 | 
					                self.assert_image_similar(im, imref, 2.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_register_handler(self):
 | 
					    def test_register_handler(self):
 | 
				
			||||||
        class TestHandler:
 | 
					        class TestHandler:
 | 
				
			||||||
| 
						 | 
					@ -46,12 +46,12 @@ class TestFileWmf(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_dpi_rounding(self):
 | 
					    def test_load_dpi_rounding(self):
 | 
				
			||||||
        # Round up
 | 
					        # Round up
 | 
				
			||||||
        im = Image.open("Tests/images/drawing.emf")
 | 
					        with Image.open("Tests/images/drawing.emf") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], 1424)
 | 
					            self.assertEqual(im.info["dpi"], 1424)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Round down
 | 
					        # Round down
 | 
				
			||||||
        im = Image.open("Tests/images/drawing_roundDown.emf")
 | 
					        with Image.open("Tests/images/drawing_roundDown.emf") as im:
 | 
				
			||||||
        self.assertEqual(im.info["dpi"], 1426)
 | 
					            self.assertEqual(im.info["dpi"], 1426)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save(self):
 | 
					    def test_save(self):
 | 
				
			||||||
        im = hopper()
 | 
					        im = hopper()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,11 +42,11 @@ class TestFileXbm(PillowTestCase):
 | 
				
			||||||
        filename = "Tests/images/hopper.xbm"
 | 
					        filename = "Tests/images/hopper.xbm"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.mode, "1")
 | 
					            self.assertEqual(im.mode, "1")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_open_filename_with_underscore(self):
 | 
					    def test_open_filename_with_underscore(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,8 @@ class TestFileXbm(PillowTestCase):
 | 
				
			||||||
        filename = "Tests/images/hopper_underscore.xbm"
 | 
					        filename = "Tests/images/hopper_underscore.xbm"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        im = Image.open(filename)
 | 
					        with Image.open(filename) as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					            # Assert
 | 
				
			||||||
        self.assertEqual(im.mode, "1")
 | 
					            self.assertEqual(im.mode, "1")
 | 
				
			||||||
        self.assertEqual(im.size, (128, 128))
 | 
					            self.assertEqual(im.size, (128, 128))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,11 +23,11 @@ class TestFileXpm(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_read(self):
 | 
					    def test_load_read(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = Image.open(TEST_FILE)
 | 
					        with Image.open(TEST_FILE) as im:
 | 
				
			||||||
        dummy_bytes = 1
 | 
					            dummy_bytes = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					            # Act
 | 
				
			||||||
        data = im.load_read(dummy_bytes)
 | 
					            data = im.load_read(dummy_bytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Assert
 | 
					        # Assert
 | 
				
			||||||
        self.assertEqual(len(data), 16384)
 | 
					        self.assertEqual(len(data), 16384)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,9 +97,9 @@ class TestImage(PillowTestCase):
 | 
				
			||||||
    def test_pathlib(self):
 | 
					    def test_pathlib(self):
 | 
				
			||||||
        from PIL.Image import Path
 | 
					        from PIL.Image import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(Path("Tests/images/multipage-mmap.tiff"))
 | 
					        with Image.open(Path("Tests/images/multipage-mmap.tiff")) as im:
 | 
				
			||||||
        self.assertEqual(im.mode, "P")
 | 
					            self.assertEqual(im.mode, "P")
 | 
				
			||||||
        self.assertEqual(im.size, (10, 10))
 | 
					            self.assertEqual(im.size, (10, 10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open(Path("Tests/images/hopper.jpg"))
 | 
					        im = Image.open(Path("Tests/images/hopper.jpg"))
 | 
				
			||||||
        self.assertEqual(im.mode, "RGB")
 | 
					        self.assertEqual(im.mode, "RGB")
 | 
				
			||||||
| 
						 | 
					@ -346,7 +346,8 @@ class TestImage(PillowTestCase):
 | 
				
			||||||
    def test_registered_extensions(self):
 | 
					    def test_registered_extensions(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        # Open an image to trigger plugin registration
 | 
					        # Open an image to trigger plugin registration
 | 
				
			||||||
        Image.open("Tests/images/rgb.jpg")
 | 
					        with Image.open("Tests/images/rgb.jpg"):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act
 | 
					        # Act
 | 
				
			||||||
        extensions = Image.registered_extensions()
 | 
					        extensions = Image.registered_extensions()
 | 
				
			||||||
| 
						 | 
					@ -448,10 +449,10 @@ class TestImage(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_offset_not_implemented(self):
 | 
					    def test_offset_not_implemented(self):
 | 
				
			||||||
        # Arrange
 | 
					        # Arrange
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Act / Assert
 | 
					            # Act / Assert
 | 
				
			||||||
        self.assertRaises(NotImplementedError, im.offset, None)
 | 
					            self.assertRaises(NotImplementedError, im.offset, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_fromstring(self):
 | 
					    def test_fromstring(self):
 | 
				
			||||||
        self.assertRaises(NotImplementedError, Image.fromstring)
 | 
					        self.assertRaises(NotImplementedError, Image.fromstring)
 | 
				
			||||||
| 
						 | 
					@ -522,8 +523,8 @@ class TestImage(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_remap_palette(self):
 | 
					    def test_remap_palette(self):
 | 
				
			||||||
        # Test illegal image mode
 | 
					        # Test illegal image mode
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        self.assertRaises(ValueError, im.remap_palette, None)
 | 
					            self.assertRaises(ValueError, im.remap_palette, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test__new(self):
 | 
					    def test__new(self):
 | 
				
			||||||
        from PIL import ImagePalette
 | 
					        from PIL import ImagePalette
 | 
				
			||||||
| 
						 | 
					@ -587,12 +588,12 @@ class TestImage(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_overrun(self):
 | 
					    def test_overrun(self):
 | 
				
			||||||
        for file in ["fli_overrun.bin", "sgi_overrun.bin", "pcx_overrun.bin"]:
 | 
					        for file in ["fli_overrun.bin", "sgi_overrun.bin", "pcx_overrun.bin"]:
 | 
				
			||||||
            im = Image.open(os.path.join("Tests/images", file))
 | 
					            with Image.open(os.path.join("Tests/images", file)) as im:
 | 
				
			||||||
            try:
 | 
					                try:
 | 
				
			||||||
                im.load()
 | 
					                    im.load()
 | 
				
			||||||
                self.assertFail()
 | 
					                    self.assertFail()
 | 
				
			||||||
            except IOError as e:
 | 
					                except IOError as e:
 | 
				
			||||||
                self.assertEqual(str(e), "buffer overrun when reading image file")
 | 
					                    self.assertEqual(str(e), "buffer overrun when reading image file")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockEncoder(object):
 | 
					class MockEncoder(object):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,11 +144,11 @@ class TestImageConvert(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_gif_with_rgba_palette_to_p(self):
 | 
					    def test_gif_with_rgba_palette_to_p(self):
 | 
				
			||||||
        # See https://github.com/python-pillow/Pillow/issues/2433
 | 
					        # See https://github.com/python-pillow/Pillow/issues/2433
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.gif")
 | 
					        with Image.open("Tests/images/hopper.gif") as im:
 | 
				
			||||||
        im.info["transparency"] = 255
 | 
					            im.info["transparency"] = 255
 | 
				
			||||||
        im.load()
 | 
					            im.load()
 | 
				
			||||||
        self.assertEqual(im.palette.mode, "RGBA")
 | 
					            self.assertEqual(im.palette.mode, "RGBA")
 | 
				
			||||||
        im_p = im.convert("P")
 | 
					            im_p = im.convert("P")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Should not raise ValueError: unrecognized raw mode
 | 
					        # Should not raise ValueError: unrecognized raw mode
 | 
				
			||||||
        im_p.load()
 | 
					        im_p.load()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,12 +5,15 @@ from .test_imageqt import PillowQtTestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFromQImage(PillowQtTestCase, PillowTestCase):
 | 
					class TestFromQImage(PillowQtTestCase, PillowTestCase):
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
    files_to_test = [
 | 
					        super(TestFromQImage, self).setUp()
 | 
				
			||||||
        hopper(),
 | 
					        self.files_to_test = [
 | 
				
			||||||
        Image.open("Tests/images/transparent.png"),
 | 
					            hopper(),
 | 
				
			||||||
        Image.open("Tests/images/7x13.png"),
 | 
					            Image.open("Tests/images/transparent.png"),
 | 
				
			||||||
    ]
 | 
					            Image.open("Tests/images/7x13.png"),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        for im in self.files_to_test:
 | 
				
			||||||
 | 
					            self.addCleanup(im.close)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def roundtrip(self, expected):
 | 
					    def roundtrip(self, expected):
 | 
				
			||||||
        # PIL -> Qt
 | 
					        # PIL -> Qt
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ from .helper import PillowTestCase, hopper
 | 
				
			||||||
class TestImageMode(PillowTestCase):
 | 
					class TestImageMode(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        im.mode
 | 
					            im.mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        from PIL import ImageMode
 | 
					        from PIL import ImageMode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,5 +148,5 @@ class TestImageResize(PillowTestCase):
 | 
				
			||||||
            resize(mode, (188, 214))
 | 
					            resize(mode, (188, 214))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test unknown resampling filter
 | 
					        # Test unknown resampling filter
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        self.assertRaises(ValueError, im.resize, (10, 10), "unknown")
 | 
					            self.assertRaises(ValueError, im.resize, (10, 10), "unknown")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,11 +39,11 @@ class TestImageThumbnail(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_no_resize(self):
 | 
					    def test_no_resize(self):
 | 
				
			||||||
        # Check that draft() can resize the image to the destination size
 | 
					        # Check that draft() can resize the image to the destination size
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.jpg")
 | 
					        with Image.open("Tests/images/hopper.jpg") as im:
 | 
				
			||||||
        im.draft(None, (64, 64))
 | 
					            im.draft(None, (64, 64))
 | 
				
			||||||
        self.assertEqual(im.size, (64, 64))
 | 
					            self.assertEqual(im.size, (64, 64))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test thumbnail(), where only draft() is necessary to resize the image
 | 
					        # Test thumbnail(), where only draft() is necessary to resize the image
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.jpg")
 | 
					        with Image.open("Tests/images/hopper.jpg") as im:
 | 
				
			||||||
        im.thumbnail((64, 64))
 | 
					            im.thumbnail((64, 64))
 | 
				
			||||||
        self.assert_image(im, im.mode, (64, 64))
 | 
					            self.assert_image(im, im.mode, (64, 64))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,21 +156,21 @@ class TestImageTransform(PillowTestCase):
 | 
				
			||||||
        self.test_mesh()
 | 
					        self.test_mesh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_missing_method_data(self):
 | 
					    def test_missing_method_data(self):
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        self.assertRaises(ValueError, im.transform, (100, 100), None)
 | 
					            self.assertRaises(ValueError, im.transform, (100, 100), None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_unknown_resampling_filter(self):
 | 
					    def test_unknown_resampling_filter(self):
 | 
				
			||||||
        im = hopper()
 | 
					        with hopper() as im:
 | 
				
			||||||
        (w, h) = im.size
 | 
					            (w, h) = im.size
 | 
				
			||||||
        for resample in (Image.BOX, "unknown"):
 | 
					            for resample in (Image.BOX, "unknown"):
 | 
				
			||||||
            self.assertRaises(
 | 
					                self.assertRaises(
 | 
				
			||||||
                ValueError,
 | 
					                    ValueError,
 | 
				
			||||||
                im.transform,
 | 
					                    im.transform,
 | 
				
			||||||
                (100, 100),
 | 
					                    (100, 100),
 | 
				
			||||||
                Image.EXTENT,
 | 
					                    Image.EXTENT,
 | 
				
			||||||
                (0, 0, w, h),
 | 
					                    (0, 0, w, h),
 | 
				
			||||||
                resample,
 | 
					                    resample,
 | 
				
			||||||
            )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestImageTransformAffine(PillowTestCase):
 | 
					class TestImageTransformAffine(PillowTestCase):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,10 +58,10 @@ class TestImageCms(PillowTestCase):
 | 
				
			||||||
        i = ImageCms.applyTransform(hopper(), t)
 | 
					        i = ImageCms.applyTransform(hopper(), t)
 | 
				
			||||||
        self.assert_image(i, "RGB", (128, 128))
 | 
					        self.assert_image(i, "RGB", (128, 128))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        i = hopper()
 | 
					        with hopper() as i:
 | 
				
			||||||
        t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB")
 | 
					            t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB")
 | 
				
			||||||
        ImageCms.applyTransform(hopper(), t, inPlace=True)
 | 
					            ImageCms.applyTransform(hopper(), t, inPlace=True)
 | 
				
			||||||
        self.assert_image(i, "RGB", (128, 128))
 | 
					            self.assert_image(i, "RGB", (128, 128))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        p = ImageCms.createProfile("sRGB")
 | 
					        p = ImageCms.createProfile("sRGB")
 | 
				
			||||||
        o = ImageCms.getOpenProfile(SRGB)
 | 
					        o = ImageCms.getOpenProfile(SRGB)
 | 
				
			||||||
| 
						 | 
					@ -151,8 +151,8 @@ class TestImageCms(PillowTestCase):
 | 
				
			||||||
    def test_extensions(self):
 | 
					    def test_extensions(self):
 | 
				
			||||||
        # extensions
 | 
					        # extensions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        i = Image.open("Tests/images/rgb.jpg")
 | 
					        with Image.open("Tests/images/rgb.jpg") as i:
 | 
				
			||||||
        p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"]))
 | 
					            p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"]))
 | 
				
			||||||
        self.assertEqual(
 | 
					        self.assertEqual(
 | 
				
			||||||
            ImageCms.getProfileName(p).strip(),
 | 
					            ImageCms.getProfileName(p).strip(),
 | 
				
			||||||
            "IEC 61966-2.1 Default RGB colour space - sRGB",
 | 
					            "IEC 61966-2.1 Default RGB colour space - sRGB",
 | 
				
			||||||
| 
						 | 
					@ -166,9 +166,10 @@ class TestImageCms(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(ValueError, t.apply_in_place, hopper("RGBA"))
 | 
					        self.assertRaises(ValueError, t.apply_in_place, hopper("RGBA"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # the procedural pyCMS API uses PyCMSError for all sorts of errors
 | 
					        # the procedural pyCMS API uses PyCMSError for all sorts of errors
 | 
				
			||||||
        self.assertRaises(
 | 
					        with hopper() as im:
 | 
				
			||||||
            ImageCms.PyCMSError, ImageCms.profileToProfile, hopper(), "foo", "bar"
 | 
					            self.assertRaises(
 | 
				
			||||||
        )
 | 
					                ImageCms.PyCMSError, ImageCms.profileToProfile, im, "foo", "bar"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        self.assertRaises(
 | 
					        self.assertRaises(
 | 
				
			||||||
            ImageCms.PyCMSError, ImageCms.buildTransform, "foo", "bar", "RGB", "RGB"
 | 
					            ImageCms.PyCMSError, ImageCms.buildTransform, "foo", "bar", "RGB", "RGB"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -266,8 +267,8 @@ class TestImageCms(PillowTestCase):
 | 
				
			||||||
        self.assert_image_similar(hopper(), out, 2)
 | 
					        self.assert_image_similar(hopper(), out, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_profile_tobytes(self):
 | 
					    def test_profile_tobytes(self):
 | 
				
			||||||
        i = Image.open("Tests/images/rgb.jpg")
 | 
					        with Image.open("Tests/images/rgb.jpg") as i:
 | 
				
			||||||
        p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"]))
 | 
					            p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes()))
 | 
					        p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,10 +45,10 @@ class TestImageDraw(PillowTestCase):
 | 
				
			||||||
        draw.rectangle(list(range(4)))
 | 
					        draw.rectangle(list(range(4)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_valueerror(self):
 | 
					    def test_valueerror(self):
 | 
				
			||||||
        im = Image.open("Tests/images/chi.gif")
 | 
					        with Image.open("Tests/images/chi.gif") as im:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        draw = ImageDraw.Draw(im)
 | 
					            draw = ImageDraw.Draw(im)
 | 
				
			||||||
        draw.line((0, 0), fill=(0, 0, 0))
 | 
					            draw.line((0, 0), fill=(0, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mode_mismatch(self):
 | 
					    def test_mode_mismatch(self):
 | 
				
			||||||
        im = hopper("RGB").copy()
 | 
					        im = hopper("RGB").copy()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,13 +115,13 @@ class TestImageFile(PillowTestCase):
 | 
				
			||||||
        if "zip_encoder" not in codecs:
 | 
					        if "zip_encoder" not in codecs:
 | 
				
			||||||
            self.skipTest("PNG (zlib) encoder not available")
 | 
					            self.skipTest("PNG (zlib) encoder not available")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/truncated_image.png")
 | 
					        with Image.open("Tests/images/truncated_image.png") as im:
 | 
				
			||||||
        with self.assertRaises(IOError):
 | 
					            with self.assertRaises(IOError):
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test that the error is raised if loaded a second time
 | 
					            # Test that the error is raised if loaded a second time
 | 
				
			||||||
        with self.assertRaises(IOError):
 | 
					            with self.assertRaises(IOError):
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_truncated_without_errors(self):
 | 
					    def test_truncated_without_errors(self):
 | 
				
			||||||
        if "zip_encoder" not in codecs:
 | 
					        if "zip_encoder" not in codecs:
 | 
				
			||||||
| 
						 | 
					@ -258,12 +258,12 @@ class TestPyDecoder(PillowTestCase):
 | 
				
			||||||
        exif[40963] = 455
 | 
					        exif[40963] = 455
 | 
				
			||||||
        exif[11] = "Pillow test"
 | 
					        exif[11] = "Pillow test"
 | 
				
			||||||
        im.save(out, exif=exif)
 | 
					        im.save(out, exif=exif)
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        reloaded_exif = reloaded.getexif()
 | 
					            reloaded_exif = reloaded.getexif()
 | 
				
			||||||
        self.assertEqual(reloaded_exif[258], 8)
 | 
					            self.assertEqual(reloaded_exif[258], 8)
 | 
				
			||||||
        self.assertNotIn(40960, exif)
 | 
					            self.assertNotIn(40960, exif)
 | 
				
			||||||
        self.assertEqual(reloaded_exif[40963], 455)
 | 
					            self.assertEqual(reloaded_exif[40963], 455)
 | 
				
			||||||
        self.assertEqual(exif[11], "Pillow test")
 | 
					            self.assertEqual(exif[11], "Pillow test")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im = Image.open("Tests/images/no-dpi-in-exif.jpg")  # Big endian
 | 
					        im = Image.open("Tests/images/no-dpi-in-exif.jpg")  # Big endian
 | 
				
			||||||
        exif = im.getexif()
 | 
					        exif = im.getexif()
 | 
				
			||||||
| 
						 | 
					@ -278,12 +278,12 @@ class TestPyDecoder(PillowTestCase):
 | 
				
			||||||
        exif[40963] = 455
 | 
					        exif[40963] = 455
 | 
				
			||||||
        exif[305] = "Pillow test"
 | 
					        exif[305] = "Pillow test"
 | 
				
			||||||
        im.save(out, exif=exif)
 | 
					        im.save(out, exif=exif)
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        reloaded_exif = reloaded.getexif()
 | 
					            reloaded_exif = reloaded.getexif()
 | 
				
			||||||
        self.assertEqual(reloaded_exif[258], 8)
 | 
					            self.assertEqual(reloaded_exif[258], 8)
 | 
				
			||||||
        self.assertNotIn(40960, exif)
 | 
					            self.assertNotIn(40960, exif)
 | 
				
			||||||
        self.assertEqual(reloaded_exif[40963], 455)
 | 
					            self.assertEqual(reloaded_exif[40963], 455)
 | 
				
			||||||
        self.assertEqual(exif[305], "Pillow test")
 | 
					            self.assertEqual(exif[305], "Pillow test")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipIf(
 | 
					    @unittest.skipIf(
 | 
				
			||||||
        not HAVE_WEBP or not _webp.HAVE_WEBPANIM,
 | 
					        not HAVE_WEBP or not _webp.HAVE_WEBPANIM,
 | 
				
			||||||
| 
						 | 
					@ -300,11 +300,11 @@ class TestPyDecoder(PillowTestCase):
 | 
				
			||||||
        exif[305] = "Pillow test"
 | 
					        exif[305] = "Pillow test"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def check_exif():
 | 
					        def check_exif():
 | 
				
			||||||
            reloaded = Image.open(out)
 | 
					            with Image.open(out) as reloaded:
 | 
				
			||||||
            reloaded_exif = reloaded.getexif()
 | 
					                reloaded_exif = reloaded.getexif()
 | 
				
			||||||
            self.assertEqual(reloaded_exif[258], 8)
 | 
					                self.assertEqual(reloaded_exif[258], 8)
 | 
				
			||||||
            self.assertEqual(reloaded_exif[40963], 455)
 | 
					                self.assertEqual(reloaded_exif[40963], 455)
 | 
				
			||||||
            self.assertEqual(exif[305], "Pillow test")
 | 
					                self.assertEqual(exif[305], "Pillow test")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        im.save(out, exif=exif)
 | 
					        im.save(out, exif=exif)
 | 
				
			||||||
        check_exif()
 | 
					        check_exif()
 | 
				
			||||||
| 
						 | 
					@ -323,23 +323,13 @@ class TestPyDecoder(PillowTestCase):
 | 
				
			||||||
        exif[305] = "Pillow test"
 | 
					        exif[305] = "Pillow test"
 | 
				
			||||||
        im.save(out, exif=exif)
 | 
					        im.save(out, exif=exif)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reloaded = Image.open(out)
 | 
					        with Image.open(out) as reloaded:
 | 
				
			||||||
        reloaded_exif = reloaded.getexif()
 | 
					            reloaded_exif = reloaded.getexif()
 | 
				
			||||||
        self.assertEqual(reloaded_exif, {258: 8, 40963: 455, 305: "Pillow test"})
 | 
					            self.assertEqual(reloaded_exif, {258: 8, 40963: 455, 305: "Pillow test"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exif_interop(self):
 | 
					    def test_exif_interop(self):
 | 
				
			||||||
        im = Image.open("Tests/images/flower.jpg")
 | 
					        with Image.open("Tests/images/flower.jpg") as im:
 | 
				
			||||||
        exif = im.getexif()
 | 
					            exif = im.getexif()
 | 
				
			||||||
        self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
            exif.get_ifd(0xA005), {1: "R98", 2: b"0100", 4097: 2272, 4098: 1704}
 | 
					                exif.get_ifd(0xA005), {1: "R98", 2: b"0100", 4097: 2272, 4098: 1704}
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_exif_shared(self):
 | 
					 | 
				
			||||||
        im = Image.open("Tests/images/exif.png")
 | 
					 | 
				
			||||||
        exif = im.getexif()
 | 
					 | 
				
			||||||
        self.assertIs(im.getexif(), exif)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_exif_str(self):
 | 
					 | 
				
			||||||
        im = Image.open("Tests/images/exif.png")
 | 
					 | 
				
			||||||
        exif = im.getexif()
 | 
					 | 
				
			||||||
        self.assertEqual(str(exif), "{274: 1}")
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,57 +2,61 @@ from PIL import Image, ImageFilter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helper import PillowTestCase
 | 
					from .helper import PillowTestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
im = Image.open("Tests/images/hopper.ppm")
 | 
					 | 
				
			||||||
snakes = Image.open("Tests/images/color_snakes.png")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestImageOpsUsm(PillowTestCase):
 | 
					class TestImageOpsUsm(PillowTestCase):
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestImageOpsUsm, self).setUp()
 | 
				
			||||||
 | 
					        self.im = Image.open("Tests/images/hopper.ppm")
 | 
				
			||||||
 | 
					        self.addCleanup(self.im.close)
 | 
				
			||||||
 | 
					        self.snakes = Image.open("Tests/images/color_snakes.png")
 | 
				
			||||||
 | 
					        self.addCleanup(self.snakes.close)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_filter_api(self):
 | 
					    def test_filter_api(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_filter = ImageFilter.GaussianBlur(2.0)
 | 
					        test_filter = ImageFilter.GaussianBlur(2.0)
 | 
				
			||||||
        i = im.filter(test_filter)
 | 
					        i = self.im.filter(test_filter)
 | 
				
			||||||
        self.assertEqual(i.mode, "RGB")
 | 
					        self.assertEqual(i.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(i.size, (128, 128))
 | 
					        self.assertEqual(i.size, (128, 128))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_filter = ImageFilter.UnsharpMask(2.0, 125, 8)
 | 
					        test_filter = ImageFilter.UnsharpMask(2.0, 125, 8)
 | 
				
			||||||
        i = im.filter(test_filter)
 | 
					        i = self.im.filter(test_filter)
 | 
				
			||||||
        self.assertEqual(i.mode, "RGB")
 | 
					        self.assertEqual(i.mode, "RGB")
 | 
				
			||||||
        self.assertEqual(i.size, (128, 128))
 | 
					        self.assertEqual(i.size, (128, 128))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_usm_formats(self):
 | 
					    def test_usm_formats(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        usm = ImageFilter.UnsharpMask
 | 
					        usm = ImageFilter.UnsharpMask
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("1").filter, usm)
 | 
					        self.assertRaises(ValueError, self.im.convert("1").filter, usm)
 | 
				
			||||||
        im.convert("L").filter(usm)
 | 
					        self.im.convert("L").filter(usm)
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("I").filter, usm)
 | 
					        self.assertRaises(ValueError, self.im.convert("I").filter, usm)
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("F").filter, usm)
 | 
					        self.assertRaises(ValueError, self.im.convert("F").filter, usm)
 | 
				
			||||||
        im.convert("RGB").filter(usm)
 | 
					        self.im.convert("RGB").filter(usm)
 | 
				
			||||||
        im.convert("RGBA").filter(usm)
 | 
					        self.im.convert("RGBA").filter(usm)
 | 
				
			||||||
        im.convert("CMYK").filter(usm)
 | 
					        self.im.convert("CMYK").filter(usm)
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("YCbCr").filter, usm)
 | 
					        self.assertRaises(ValueError, self.im.convert("YCbCr").filter, usm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_blur_formats(self):
 | 
					    def test_blur_formats(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        blur = ImageFilter.GaussianBlur
 | 
					        blur = ImageFilter.GaussianBlur
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("1").filter, blur)
 | 
					        self.assertRaises(ValueError, self.im.convert("1").filter, blur)
 | 
				
			||||||
        blur(im.convert("L"))
 | 
					        blur(self.im.convert("L"))
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("I").filter, blur)
 | 
					        self.assertRaises(ValueError, self.im.convert("I").filter, blur)
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("F").filter, blur)
 | 
					        self.assertRaises(ValueError, self.im.convert("F").filter, blur)
 | 
				
			||||||
        im.convert("RGB").filter(blur)
 | 
					        self.im.convert("RGB").filter(blur)
 | 
				
			||||||
        im.convert("RGBA").filter(blur)
 | 
					        self.im.convert("RGBA").filter(blur)
 | 
				
			||||||
        im.convert("CMYK").filter(blur)
 | 
					        self.im.convert("CMYK").filter(blur)
 | 
				
			||||||
        self.assertRaises(ValueError, im.convert("YCbCr").filter, blur)
 | 
					        self.assertRaises(ValueError, self.im.convert("YCbCr").filter, blur)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_usm_accuracy(self):
 | 
					    def test_usm_accuracy(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        src = snakes.convert("RGB")
 | 
					        src = self.snakes.convert("RGB")
 | 
				
			||||||
        i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0))
 | 
					        i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0))
 | 
				
			||||||
        # Image should not be changed because it have only 0 and 255 levels.
 | 
					        # Image should not be changed because it have only 0 and 255 levels.
 | 
				
			||||||
        self.assertEqual(i.tobytes(), src.tobytes())
 | 
					        self.assertEqual(i.tobytes(), src.tobytes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_blur_accuracy(self):
 | 
					    def test_blur_accuracy(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        i = snakes.filter(ImageFilter.GaussianBlur(0.4))
 | 
					        i = self.snakes.filter(ImageFilter.GaussianBlur(0.4))
 | 
				
			||||||
        # These pixels surrounded with pixels with 255 intensity.
 | 
					        # These pixels surrounded with pixels with 255 intensity.
 | 
				
			||||||
        # They must be very close to 255.
 | 
					        # They must be very close to 255.
 | 
				
			||||||
        for x, y, c in [
 | 
					        for x, y, c in [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,25 +24,25 @@ class TestImageSequence(PillowTestCase):
 | 
				
			||||||
        self.assertRaises(AttributeError, ImageSequence.Iterator, 0)
 | 
					        self.assertRaises(AttributeError, ImageSequence.Iterator, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_iterator(self):
 | 
					    def test_iterator(self):
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        i = ImageSequence.Iterator(im)
 | 
					            i = ImageSequence.Iterator(im)
 | 
				
			||||||
        for index in range(0, im.n_frames):
 | 
					            for index in range(0, im.n_frames):
 | 
				
			||||||
            self.assertEqual(i[index], next(i))
 | 
					                self.assertEqual(i[index], next(i))
 | 
				
			||||||
        self.assertRaises(IndexError, lambda: i[index + 1])
 | 
					            self.assertRaises(IndexError, lambda: i[index + 1])
 | 
				
			||||||
        self.assertRaises(StopIteration, next, i)
 | 
					            self.assertRaises(StopIteration, next, i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_iterator_min_frame(self):
 | 
					    def test_iterator_min_frame(self):
 | 
				
			||||||
        im = Image.open("Tests/images/hopper.psd")
 | 
					        with Image.open("Tests/images/hopper.psd") as im:
 | 
				
			||||||
        i = ImageSequence.Iterator(im)
 | 
					            i = ImageSequence.Iterator(im)
 | 
				
			||||||
        for index in range(1, im.n_frames):
 | 
					            for index in range(1, im.n_frames):
 | 
				
			||||||
            self.assertEqual(i[index], next(i))
 | 
					                self.assertEqual(i[index], next(i))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _test_multipage_tiff(self):
 | 
					    def _test_multipage_tiff(self):
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        for index, frame in enumerate(ImageSequence.Iterator(im)):
 | 
					            for index, frame in enumerate(ImageSequence.Iterator(im)):
 | 
				
			||||||
            frame.load()
 | 
					                frame.load()
 | 
				
			||||||
            self.assertEqual(index, im.tell())
 | 
					                self.assertEqual(index, im.tell())
 | 
				
			||||||
            frame.convert("RGB")
 | 
					                frame.convert("RGB")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_tiff(self):
 | 
					    def test_tiff(self):
 | 
				
			||||||
        self._test_multipage_tiff()
 | 
					        self._test_multipage_tiff()
 | 
				
			||||||
| 
						 | 
					@ -58,41 +58,41 @@ class TestImageSequence(PillowTestCase):
 | 
				
			||||||
        TiffImagePlugin.READ_LIBTIFF = False
 | 
					        TiffImagePlugin.READ_LIBTIFF = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_consecutive(self):
 | 
					    def test_consecutive(self):
 | 
				
			||||||
        im = Image.open("Tests/images/multipage.tiff")
 | 
					        with Image.open("Tests/images/multipage.tiff") as im:
 | 
				
			||||||
        firstFrame = None
 | 
					            firstFrame = None
 | 
				
			||||||
        for frame in ImageSequence.Iterator(im):
 | 
					            for frame in ImageSequence.Iterator(im):
 | 
				
			||||||
            if firstFrame is None:
 | 
					                if firstFrame is None:
 | 
				
			||||||
                firstFrame = frame.copy()
 | 
					                    firstFrame = frame.copy()
 | 
				
			||||||
        for frame in ImageSequence.Iterator(im):
 | 
					            for frame in ImageSequence.Iterator(im):
 | 
				
			||||||
            self.assert_image_equal(frame, firstFrame)
 | 
					                self.assert_image_equal(frame, firstFrame)
 | 
				
			||||||
            break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_palette_mmap(self):
 | 
					    def test_palette_mmap(self):
 | 
				
			||||||
        # Using mmap in ImageFile can require to reload the palette.
 | 
					        # Using mmap in ImageFile can require to reload the palette.
 | 
				
			||||||
        im = Image.open("Tests/images/multipage-mmap.tiff")
 | 
					        with Image.open("Tests/images/multipage-mmap.tiff") as im:
 | 
				
			||||||
        color1 = im.getpalette()[0:3]
 | 
					            color1 = im.getpalette()[0:3]
 | 
				
			||||||
        im.seek(0)
 | 
					            im.seek(0)
 | 
				
			||||||
        color2 = im.getpalette()[0:3]
 | 
					            color2 = im.getpalette()[0:3]
 | 
				
			||||||
        self.assertEqual(color1, color2)
 | 
					            self.assertEqual(color1, color2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_all_frames(self):
 | 
					    def test_all_frames(self):
 | 
				
			||||||
        # Test a single image
 | 
					        # Test a single image
 | 
				
			||||||
        im = Image.open("Tests/images/iss634.gif")
 | 
					        with Image.open("Tests/images/iss634.gif") as im:
 | 
				
			||||||
        ims = ImageSequence.all_frames(im)
 | 
					            ims = ImageSequence.all_frames(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(len(ims), 42)
 | 
					            self.assertEqual(len(ims), 42)
 | 
				
			||||||
        for i, im_frame in enumerate(ims):
 | 
					            for i, im_frame in enumerate(ims):
 | 
				
			||||||
            self.assertFalse(im_frame is im)
 | 
					                self.assertFalse(im_frame is im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            im.seek(i)
 | 
					                im.seek(i)
 | 
				
			||||||
            self.assert_image_equal(im, im_frame)
 | 
					                self.assert_image_equal(im, im_frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test a series of images
 | 
					            # Test a series of images
 | 
				
			||||||
        ims = ImageSequence.all_frames([im, hopper(), im])
 | 
					            ims = ImageSequence.all_frames([im, hopper(), im])
 | 
				
			||||||
        self.assertEqual(len(ims), 85)
 | 
					            self.assertEqual(len(ims), 85)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Test an operation
 | 
					            # Test an operation
 | 
				
			||||||
        ims = ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(90))
 | 
					            ims = ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(90))
 | 
				
			||||||
        for i, im_frame in enumerate(ims):
 | 
					            for i, im_frame in enumerate(ims):
 | 
				
			||||||
            im.seek(i)
 | 
					                im.seek(i)
 | 
				
			||||||
            self.assert_image_equal(im.rotate(90), im_frame)
 | 
					                self.assert_image_equal(im.rotate(90), im_frame)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,8 +27,8 @@ class TestImageShow(PillowTestCase):
 | 
				
			||||||
        ImageShow.register(viewer, -1)
 | 
					        ImageShow.register(viewer, -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for mode in ("1", "I;16", "LA", "RGB", "RGBA"):
 | 
					        for mode in ("1", "I;16", "LA", "RGB", "RGBA"):
 | 
				
			||||||
            im = hopper(mode)
 | 
					            with hopper() as im:
 | 
				
			||||||
            self.assertTrue(ImageShow.show(im))
 | 
					                self.assertTrue(ImageShow.show(im))
 | 
				
			||||||
            self.assertTrue(viewer.methodCalled)
 | 
					            self.assertTrue(viewer.methodCalled)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Restore original state
 | 
					        # Restore original state
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,13 +26,15 @@ path = "Tests/images/hopper.jpg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestLocale(PillowTestCase):
 | 
					class TestLocale(PillowTestCase):
 | 
				
			||||||
    def test_sanity(self):
 | 
					    def test_sanity(self):
 | 
				
			||||||
        Image.open(path)
 | 
					        with Image.open(path):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            locale.setlocale(locale.LC_ALL, "polish")
 | 
					            locale.setlocale(locale.LC_ALL, "polish")
 | 
				
			||||||
        except locale.Error:
 | 
					        except locale.Error:
 | 
				
			||||||
            unittest.skip("Polish locale not available")
 | 
					            unittest.skip("Polish locale not available")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            Image.open(path)
 | 
					            with Image.open(path):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
        finally:
 | 
					        finally:
 | 
				
			||||||
            locale.setlocale(locale.LC_ALL, (None, None))
 | 
					            locale.setlocale(locale.LC_ALL, (None, None))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,9 +23,9 @@ class TestMap(PillowTestCase):
 | 
				
			||||||
        Image.MAX_IMAGE_PIXELS = None
 | 
					        Image.MAX_IMAGE_PIXELS = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # This image hits the offset test.
 | 
					        # This image hits the offset test.
 | 
				
			||||||
        im = Image.open("Tests/images/l2rgb_read.bmp")
 | 
					        with Image.open("Tests/images/l2rgb_read.bmp") as im:
 | 
				
			||||||
        with self.assertRaises((ValueError, MemoryError, IOError)):
 | 
					            with self.assertRaises((ValueError, MemoryError, IOError)):
 | 
				
			||||||
            im.load()
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Image.MAX_IMAGE_PIXELS = max_pixels
 | 
					        Image.MAX_IMAGE_PIXELS = max_pixels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,10 +43,10 @@ class TestModeI16(PillowTestCase):
 | 
				
			||||||
            filename = self.tempfile("temp.im")
 | 
					            filename = self.tempfile("temp.im")
 | 
				
			||||||
            imIn.save(filename)
 | 
					            imIn.save(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            imOut = Image.open(filename)
 | 
					            with Image.open(filename) as imOut:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.verify(imIn)
 | 
					                self.verify(imIn)
 | 
				
			||||||
            self.verify(imOut)
 | 
					                self.verify(imOut)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            imOut = imIn.crop((0, 0, w, h))
 | 
					            imOut = imIn.crop((0, 0, w, h))
 | 
				
			||||||
            self.verify(imOut)
 | 
					            self.verify(imOut)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,8 @@ class TestShellInjection(PillowTestCase):
 | 
				
			||||||
            dest_file = self.tempfile(filename)
 | 
					            dest_file = self.tempfile(filename)
 | 
				
			||||||
            save_func(src_img, 0, dest_file)
 | 
					            save_func(src_img, 0, dest_file)
 | 
				
			||||||
            # If file can't be opened, shell injection probably occurred
 | 
					            # If file can't be opened, shell injection probably occurred
 | 
				
			||||||
            Image.open(dest_file).load()
 | 
					            with Image.open(dest_file) as im:
 | 
				
			||||||
 | 
					                im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(djpeg_available(), "djpeg not available")
 | 
					    @unittest.skipUnless(djpeg_available(), "djpeg not available")
 | 
				
			||||||
    def test_load_djpeg_filename(self):
 | 
					    def test_load_djpeg_filename(self):
 | 
				
			||||||
| 
						 | 
					@ -32,8 +33,8 @@ class TestShellInjection(PillowTestCase):
 | 
				
			||||||
            src_file = self.tempfile(filename)
 | 
					            src_file = self.tempfile(filename)
 | 
				
			||||||
            shutil.copy(TEST_JPG, src_file)
 | 
					            shutil.copy(TEST_JPG, src_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            im = Image.open(src_file)
 | 
					            with Image.open(src_file) as im:
 | 
				
			||||||
            im.load_djpeg()
 | 
					                im.load_djpeg()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(cjpeg_available(), "cjpeg not available")
 | 
					    @unittest.skipUnless(cjpeg_available(), "cjpeg not available")
 | 
				
			||||||
    def test_save_cjpeg_filename(self):
 | 
					    def test_save_cjpeg_filename(self):
 | 
				
			||||||
| 
						 | 
					@ -42,10 +43,12 @@ class TestShellInjection(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
					    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
				
			||||||
    def test_save_netpbm_filename_bmp_mode(self):
 | 
					    def test_save_netpbm_filename_bmp_mode(self):
 | 
				
			||||||
        im = Image.open(TEST_GIF).convert("RGB")
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        self.assert_save_filename_check(im, GifImagePlugin._save_netpbm)
 | 
					            im = im.convert("RGB")
 | 
				
			||||||
 | 
					            self.assert_save_filename_check(im, GifImagePlugin._save_netpbm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
					    @unittest.skipUnless(netpbm_available(), "netpbm not available")
 | 
				
			||||||
    def test_save_netpbm_filename_l_mode(self):
 | 
					    def test_save_netpbm_filename_l_mode(self):
 | 
				
			||||||
        im = Image.open(TEST_GIF).convert("L")
 | 
					        with Image.open(TEST_GIF) as im:
 | 
				
			||||||
        self.assert_save_filename_check(im, GifImagePlugin._save_netpbm)
 | 
					            im = im.convert("L")
 | 
				
			||||||
 | 
					            self.assert_save_filename_check(im, GifImagePlugin._save_netpbm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,5 +54,7 @@ class Test_IFDRational(PillowTestCase):
 | 
				
			||||||
            res = IFDRational(301, 1)
 | 
					            res = IFDRational(301, 1)
 | 
				
			||||||
            im.save(out, dpi=(res, res), compression="raw")
 | 
					            im.save(out, dpi=(res, res), compression="raw")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            reloaded = Image.open(out)
 | 
					            with Image.open(out) as reloaded:
 | 
				
			||||||
            self.assertEqual(float(IFDRational(301, 1)), float(reloaded.tag_v2[282]))
 | 
					                self.assertEqual(
 | 
				
			||||||
 | 
					                    float(IFDRational(301, 1)), float(reloaded.tag_v2[282])
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,9 +99,9 @@ Create JPEG thumbnails
 | 
				
			||||||
        outfile = os.path.splitext(infile)[0] + ".thumbnail"
 | 
					        outfile = os.path.splitext(infile)[0] + ".thumbnail"
 | 
				
			||||||
        if infile != outfile:
 | 
					        if infile != outfile:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                im = Image.open(infile)
 | 
					                with Image.open(infile) as im:
 | 
				
			||||||
                im.thumbnail(size)
 | 
					                    im.thumbnail(size)
 | 
				
			||||||
                im.save(outfile, "JPEG")
 | 
					                    im.save(outfile, "JPEG")
 | 
				
			||||||
            except IOError:
 | 
					            except IOError:
 | 
				
			||||||
                print("cannot create thumbnail for", infile)
 | 
					                print("cannot create thumbnail for", infile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,7 +267,8 @@ Converting between modes
 | 
				
			||||||
::
 | 
					::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
    im = Image.open("hopper.ppm").convert("L")
 | 
					    with Image.open("hopper.ppm") as im:
 | 
				
			||||||
 | 
					        im = im.convert("L")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The library supports transformations between each supported mode and the “L”
 | 
					The library supports transformations between each supported mode and the “L”
 | 
				
			||||||
and “RGB” modes. To convert between other modes, you may have to use an
 | 
					and “RGB” modes. To convert between other modes, you may have to use an
 | 
				
			||||||
| 
						 | 
					@ -383,15 +384,15 @@ Reading sequences
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    im = Image.open("animation.gif")
 | 
					    with Image.open("animation.gif") as im:
 | 
				
			||||||
    im.seek(1) # skip to the second frame
 | 
					        im.seek(1) # skip to the second frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try:
 | 
					        try:
 | 
				
			||||||
        while 1:
 | 
					            while 1:
 | 
				
			||||||
            im.seek(im.tell()+1)
 | 
					                im.seek(im.tell()+1)
 | 
				
			||||||
            # do something to im
 | 
					                # do something to im
 | 
				
			||||||
    except EOFError:
 | 
					        except EOFError:
 | 
				
			||||||
        pass # end of sequence
 | 
					            pass # end of sequence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As seen in this example, you’ll get an :py:exc:`EOFError` exception when the
 | 
					As seen in this example, you’ll get an :py:exc:`EOFError` exception when the
 | 
				
			||||||
sequence ends.
 | 
					sequence ends.
 | 
				
			||||||
| 
						 | 
					@ -422,32 +423,34 @@ Drawing Postscript
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
    from PIL import PSDraw
 | 
					    from PIL import PSDraw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    im = Image.open("hopper.ppm")
 | 
					    with Image.open("hopper.ppm") as im:
 | 
				
			||||||
    title = "hopper"
 | 
					        title = "hopper"
 | 
				
			||||||
    box = (1*72, 2*72, 7*72, 10*72) # in points
 | 
					        box = (1*72, 2*72, 7*72, 10*72) # in points
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ps = PSDraw.PSDraw() # default is sys.stdout
 | 
					        ps = PSDraw.PSDraw() # default is sys.stdout
 | 
				
			||||||
    ps.begin_document(title)
 | 
					        ps.begin_document(title)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # draw the image (75 dpi)
 | 
					        # draw the image (75 dpi)
 | 
				
			||||||
    ps.image(box, im, 75)
 | 
					        ps.image(box, im, 75)
 | 
				
			||||||
    ps.rectangle(box)
 | 
					        ps.rectangle(box)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # draw title
 | 
					        # draw title
 | 
				
			||||||
    ps.setfont("HelveticaNarrow-Bold", 36)
 | 
					        ps.setfont("HelveticaNarrow-Bold", 36)
 | 
				
			||||||
    ps.text((3*72, 4*72), title)
 | 
					        ps.text((3*72, 4*72), title)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ps.end_document()
 | 
					        ps.end_document()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
More on reading images
 | 
					More on reading images
 | 
				
			||||||
----------------------
 | 
					----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As described earlier, the :py:func:`~PIL.Image.open` function of the
 | 
					As described earlier, the :py:func:`~PIL.Image.open` function of the
 | 
				
			||||||
:py:mod:`~PIL.Image` module is used to open an image file. In most cases, you
 | 
					:py:mod:`~PIL.Image` module is used to open an image file. In most cases, you
 | 
				
			||||||
simply pass it the filename as an argument::
 | 
					simply pass it the filename as an argument. ``Image.open()`` can be used a
 | 
				
			||||||
 | 
					context manager::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
    im = Image.open("hopper.ppm")
 | 
					    with Image.open("hopper.ppm") as im:
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If everything goes well, the result is an :py:class:`PIL.Image.Image` object.
 | 
					If everything goes well, the result is an :py:class:`PIL.Image.Image` object.
 | 
				
			||||||
Otherwise, an :exc:`IOError` exception is raised.
 | 
					Otherwise, an :exc:`IOError` exception is raised.
 | 
				
			||||||
| 
						 | 
					@ -513,12 +516,12 @@ This is only available for JPEG and MPO files.
 | 
				
			||||||
::
 | 
					::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
    from __future__ import print_function
 | 
					 | 
				
			||||||
    im = Image.open(file)
 | 
					 | 
				
			||||||
    print("original =", im.mode, im.size)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    im.draft("L", (100, 100))
 | 
					    with Image.open(file) as im:
 | 
				
			||||||
    print("draft =", im.mode, im.size)
 | 
					        print("original =", im.mode, im.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        im.draft("L", (100, 100))
 | 
				
			||||||
 | 
					        print("draft =", im.mode, im.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This prints something like::
 | 
					This prints something like::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,27 +8,25 @@ object, or a file-like object. Pillow uses the filename or ``Path`` to open a
 | 
				
			||||||
file, so for the rest of this article, they will all be treated as a file-like
 | 
					file, so for the rest of this article, they will all be treated as a file-like
 | 
				
			||||||
object.
 | 
					object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The first four of these items are equivalent, the last is dangerous
 | 
					The following are all equivalent::
 | 
				
			||||||
and may fail::
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from PIL import Image
 | 
					    from PIL import Image
 | 
				
			||||||
    import io
 | 
					    import io
 | 
				
			||||||
    import pathlib
 | 
					    import pathlib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    im = Image.open('test.jpg')
 | 
					    with Image.open('test.jpg') as im:
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    im2 = Image.open(pathlib.Path('test.jpg'))
 | 
					    with Image.open(pathlib.Path('test.jpg')) as im2:
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    f = open('test.jpg', 'rb')
 | 
					    with open('test.jpg', 'rb') as f:
 | 
				
			||||||
    im3 = Image.open(f)
 | 
					        im3 = Image.open(f)
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with open('test.jpg', 'rb') as f:
 | 
					    with open('test.jpg', 'rb') as f:
 | 
				
			||||||
        im4 = Image.open(io.BytesIO(f.read()))
 | 
					        im4 = Image.open(io.BytesIO(f.read()))
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
    # Dangerous FAIL:
 | 
					 | 
				
			||||||
    with open('test.jpg', 'rb') as f:
 | 
					 | 
				
			||||||
        im5 = Image.open(f)
 | 
					 | 
				
			||||||
    im5.load() # FAILS, closed file
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
If a filename or a path-like object is passed to Pillow, then the resulting
 | 
					If a filename or a path-like object is passed to Pillow, then the resulting
 | 
				
			||||||
file object opened by Pillow may also be closed by Pillow after the
 | 
					file object opened by Pillow may also be closed by Pillow after the
 | 
				
			||||||
| 
						 | 
					@ -38,13 +36,6 @@ have multiple frames.
 | 
				
			||||||
Pillow cannot in general close and reopen a file, so any access to
 | 
					Pillow cannot in general close and reopen a file, so any access to
 | 
				
			||||||
that file needs to be prior to the close.
 | 
					that file needs to be prior to the close.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Issues
 | 
					 | 
				
			||||||
------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Using the file context manager to provide a file-like object to
 | 
					 | 
				
			||||||
  Pillow is dangerous unless the context of the image is limited to
 | 
					 | 
				
			||||||
  the context of the file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Image Lifecycle
 | 
					Image Lifecycle
 | 
				
			||||||
---------------
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,9 +61,9 @@ Image Lifecycle
 | 
				
			||||||
         ...  # image operations here.
 | 
					         ...  # image operations here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The lifecycle of a single-frame image is relatively simple. The file
 | 
					The lifecycle of a single-frame image is relatively simple. The file must
 | 
				
			||||||
must remain open until the ``load()`` or ``close()`` function is
 | 
					remain open until the ``load()`` or ``close()`` function is called or the
 | 
				
			||||||
called.
 | 
					context manager exits.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Multi-frame images are more complicated. The ``load()`` method is not
 | 
					Multi-frame images are more complicated. The ``load()`` method is not
 | 
				
			||||||
a terminal method, so it should not close the underlying file. In general,
 | 
					a terminal method, so it should not close the underlying file. In general,
 | 
				
			||||||
| 
						 | 
					@ -87,14 +78,16 @@ Complications
 | 
				
			||||||
  libtiff (if working on an actual file). Since libtiff closes the file
 | 
					  libtiff (if working on an actual file). Since libtiff closes the file
 | 
				
			||||||
  descriptor internally, it is duplicated prior to passing it into libtiff.
 | 
					  descriptor internally, it is duplicated prior to passing it into libtiff.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* I don't think that there's any way to make this safe without
 | 
					* After a file has been closed, operations that require file access will fail::
 | 
				
			||||||
  changing the lazy loading::
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Dangerous FAIL:
 | 
					 | 
				
			||||||
    with open('test.jpg', 'rb') as f:
 | 
					    with open('test.jpg', 'rb') as f:
 | 
				
			||||||
        im5 = Image.open(f)
 | 
					        im5 = Image.open(f)
 | 
				
			||||||
    im5.load() # FAILS, closed file
 | 
					    im5.load() # FAILS, closed file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with Image.open('test.jpg') as im6:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    im6.load() # FAILS, closed file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Proposed File Handling
 | 
					Proposed File Handling
 | 
				
			||||||
----------------------
 | 
					----------------------
 | 
				
			||||||
| 
						 | 
					@ -104,5 +97,6 @@ Proposed File Handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* ``Image.Image.seek()`` should never close the image file.
 | 
					* ``Image.Image.seek()`` should never close the image file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Users of the library should call ``Image.Image.close()`` on any
 | 
					* Users of the library should use a context manager or call
 | 
				
			||||||
  multi-frame image to ensure that the underlying file is closed.
 | 
					  ``Image.Image.close()`` on any image opened with a filename or ``Path``
 | 
				
			||||||
 | 
					  object to ensure that the underlying file is closed.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,8 +42,8 @@ def testimage():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Or open existing files:
 | 
					    Or open existing files:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> im = Image.open("Tests/images/hopper.gif")
 | 
					    >>> with Image.open("Tests/images/hopper.gif") as im:
 | 
				
			||||||
    >>> _info(im)
 | 
					    ...     _info(im)
 | 
				
			||||||
    ('GIF', 'P', (128, 128))
 | 
					    ('GIF', 'P', (128, 128))
 | 
				
			||||||
    >>> _info(Image.open("Tests/images/hopper.ppm"))
 | 
					    >>> _info(Image.open("Tests/images/hopper.ppm"))
 | 
				
			||||||
    ('PPM', 'RGB', (128, 128))
 | 
					    ('PPM', 'RGB', (128, 128))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -622,11 +622,6 @@ class Image(object):
 | 
				
			||||||
        # object is gone.
 | 
					        # object is gone.
 | 
				
			||||||
        self.im = deferred_error(ValueError("Operation on closed image"))
 | 
					        self.im = deferred_error(ValueError("Operation on closed image"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if sys.version_info.major >= 3:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __del__(self):
 | 
					 | 
				
			||||||
            self.__exit__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _copy(self):
 | 
					    def _copy(self):
 | 
				
			||||||
        self.load()
 | 
					        self.load()
 | 
				
			||||||
        self.im = self.im.copy()
 | 
					        self.im = self.im.copy()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,21 +103,24 @@ class ImageFile(Image.Image):
 | 
				
			||||||
            self._exclusive_fp = None
 | 
					            self._exclusive_fp = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self._open()
 | 
					            try:
 | 
				
			||||||
        except (
 | 
					                self._open()
 | 
				
			||||||
            IndexError,  # end of data
 | 
					            except (
 | 
				
			||||||
            TypeError,  # end of data (ord)
 | 
					                IndexError,  # end of data
 | 
				
			||||||
            KeyError,  # unsupported mode
 | 
					                TypeError,  # end of data (ord)
 | 
				
			||||||
            EOFError,  # got header but not the first frame
 | 
					                KeyError,  # unsupported mode
 | 
				
			||||||
            struct.error,
 | 
					                EOFError,  # got header but not the first frame
 | 
				
			||||||
        ) as v:
 | 
					                struct.error,
 | 
				
			||||||
 | 
					            ) as v:
 | 
				
			||||||
 | 
					                raise SyntaxError(v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if not self.mode or self.size[0] <= 0:
 | 
				
			||||||
 | 
					                raise SyntaxError("not identified by this driver")
 | 
				
			||||||
 | 
					        except BaseException:
 | 
				
			||||||
            # close the file only if we have opened it this constructor
 | 
					            # close the file only if we have opened it this constructor
 | 
				
			||||||
            if self._exclusive_fp:
 | 
					            if self._exclusive_fp:
 | 
				
			||||||
                self.fp.close()
 | 
					                self.fp.close()
 | 
				
			||||||
            raise SyntaxError(v)
 | 
					            raise
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.mode or self.size[0] <= 0:
 | 
					 | 
				
			||||||
            raise SyntaxError("not identified by this driver")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draft(self, mode, size):
 | 
					    def draft(self, mode, size):
 | 
				
			||||||
        """Set draft mode"""
 | 
					        """Set draft mode"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -219,7 +219,8 @@ def loadImageSeries(filelist=None):
 | 
				
			||||||
            print("unable to find %s" % img)
 | 
					            print("unable to find %s" % img)
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            im = Image.open(img).convert2byte()
 | 
					            with Image.open(img) as im:
 | 
				
			||||||
 | 
					                im = im.convert2byte()
 | 
				
			||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
            if not isSpiderImage(img):
 | 
					            if not isSpiderImage(img):
 | 
				
			||||||
                print(img + " is not a Spider image file")
 | 
					                print(img + " is not a Spider image file")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,6 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import io
 | 
					import io
 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from . import ContainerIO
 | 
					from . import ContainerIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,10 +63,5 @@ class TarIO(ContainerIO.ContainerIO):
 | 
				
			||||||
    def __exit__(self, *args):
 | 
					    def __exit__(self, *args):
 | 
				
			||||||
        self.close()
 | 
					        self.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if sys.version_info.major >= 3:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __del__(self):
 | 
					 | 
				
			||||||
            self.close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def close(self):
 | 
					    def close(self):
 | 
				
			||||||
        self.fh.close()
 | 
					        self.fh.close()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user