diff --git a/PIL/FliImagePlugin.py b/PIL/FliImagePlugin.py index df6a4eb8e..772140076 100644 --- a/PIL/FliImagePlugin.py +++ b/PIL/FliImagePlugin.py @@ -127,8 +127,14 @@ class FliImageFile(ImageFile.ImageFile): return if frame < self.__frame: self._seek(0) + + last_frame = self.__frame for f in range(self.__frame + 1, frame + 1): - self._seek(f) + try: + self._seek(f) + except EOFError: + self.seek(last_frame) + raise EOFError("no more images in FLI file") def _seek(self, frame): if frame == 0: diff --git a/PIL/GifImagePlugin.py b/PIL/GifImagePlugin.py index bd974b651..35fb95164 100644 --- a/PIL/GifImagePlugin.py +++ b/PIL/GifImagePlugin.py @@ -107,8 +107,14 @@ class GifImageFile(ImageFile.ImageFile): return if frame < self.__frame: self._seek(0) + + last_frame = self.__frame for f in range(self.__frame + 1, frame + 1): - self._seek(f) + try: + self._seek(f) + except EOFError: + self.seek(last_frame) + raise EOFError("no more images in GIF file") def _seek(self, frame): @@ -241,7 +247,7 @@ class GifImageFile(ImageFile.ImageFile): if not self.tile: # self.__fp = None - raise EOFError("no more images in GIF file") + raise EOFError self.mode = "L" if self.palette: diff --git a/Tests/test_file_dcx.py b/Tests/test_file_dcx.py index 7d2ae32d8..d59a5a785 100644 --- a/Tests/test_file_dcx.py +++ b/Tests/test_file_dcx.py @@ -34,6 +34,18 @@ class TestFileDcx(PillowTestCase): im = Image.open(TEST_FILE) self.assertEqual(im.n_frames, 1) + def test_eoferror(self): + im = Image.open(TEST_FILE) + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) + def test_seek_too_far(self): # Arrange im = Image.open(TEST_FILE) diff --git a/Tests/test_file_fli.py b/Tests/test_file_fli.py index 04c2006c9..1b95f793f 100644 --- a/Tests/test_file_fli.py +++ b/Tests/test_file_fli.py @@ -20,7 +20,19 @@ class TestFileFli(PillowTestCase): def test_n_frames(self): im = Image.open(test_file) - self.assertEqual(im.n_frames, 2) + self.assertEqual(im.n_frames, 1) + + def test_eoferror(self): + im = Image.open(test_file) + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) if __name__ == '__main__': diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index b15d32097..a38c360c9 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -135,8 +135,23 @@ class TestFileGif(PillowTestCase): self.assertEqual(framecount, 5) def test_n_frames(self): + im = Image.open(TEST_GIF) + self.assertEqual(im.n_frames, 1) + im = Image.open("Tests/images/iss634.gif") - self.assertEqual(im.n_frames, 43) + self.assertEqual(im.n_frames, 42) + + def test_eoferror(self): + im = Image.open(TEST_GIF) + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) def test_dispose_none(self): img = Image.open("Tests/images/dispose_none.gif") diff --git a/Tests/test_file_im.py b/Tests/test_file_im.py index 24e00b2f0..76bf250a0 100644 --- a/Tests/test_file_im.py +++ b/Tests/test_file_im.py @@ -19,6 +19,18 @@ class TestFileIm(PillowTestCase): im = Image.open(TEST_IM) self.assertEqual(im.n_frames, 1) + def test_eoferror(self): + im = Image.open(TEST_IM) + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) + def test_roundtrip(self): out = self.tempfile('temp.im') im = hopper() diff --git a/Tests/test_file_mpo.py b/Tests/test_file_mpo.py index 1a0ebc453..c5562097d 100644 --- a/Tests/test_file_mpo.py +++ b/Tests/test_file_mpo.py @@ -99,6 +99,18 @@ class TestFileMpo(PillowTestCase): im = Image.open("Tests/images/sugarshack.mpo") self.assertEqual(im.n_frames, 2) + def test_eoferror(self): + im = Image.open("Tests/images/sugarshack.mpo") + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) + def test_image_grab(self): for test_file in test_files: im = Image.open(test_file) diff --git a/Tests/test_file_psd.py b/Tests/test_file_psd.py index dca3601b2..ea3856fce 100644 --- a/Tests/test_file_psd.py +++ b/Tests/test_file_psd.py @@ -23,6 +23,19 @@ class TestImagePsd(PillowTestCase): im = Image.open(test_file) self.assertEqual(im.n_frames, 2) + def test_eoferror(self): + im = Image.open(test_file) + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + # PSD seek index starts at 1 rather than 0 + im.seek(n_frames+1) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) + if __name__ == '__main__': unittest.main() diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 02a63586c..a88b49d7f 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -157,6 +157,18 @@ class TestFileTiff(PillowTestCase): im = Image.open('Tests/images/multipage.tiff') self.assertEqual(im.n_frames, 3) + def test_eoferror(self): + im = Image.open('Tests/images/multipage-lastframe.tif') + + n_frames = im.n_frames + while True: + n_frames -= 1 + try: + im.seek(n_frames) + break + except EOFError: + self.assertTrue(im.tell() < n_frames) + def test_multipage(self): # issue #862 im = Image.open('Tests/images/multipage.tiff')