From d84fd20f0c1b23e64fba9c19a38b517a762f46f8 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 13 Mar 2019 20:44:58 +1100 Subject: [PATCH 1/3] Simplified is_animated --- Tests/test_file_tiff.py | 5 ----- src/PIL/TiffImagePlugin.py | 25 ++++++------------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 34911ed50..47a1f71b1 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -229,11 +229,6 @@ class TestFileTiff(PillowTestCase): ['Tests/images/multipage-lastframe.tif', 1], ['Tests/images/multipage.tiff', 3] ]: - # Test is_animated before n_frames - im = Image.open(path) - self.assertEqual(im.is_animated, n_frames != 1) - - # Test is_animated after n_frames im = Image.open(path) self.assertEqual(im.n_frames, n_frames) self.assertEqual(im.is_animated, n_frames != 1) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 34c6f39de..5f4ed8af2 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -985,7 +985,6 @@ class TiffImageFile(ImageFile.ImageFile): self.__fp = self.fp self._frame_pos = [] self._n_frames = None - self._is_animated = None if DEBUG: print("*** TiffImageFile._open ***") @@ -1009,19 +1008,6 @@ class TiffImageFile(ImageFile.ImageFile): @property def is_animated(self): - if self._is_animated is None: - if self._n_frames is not None: - self._is_animated = self._n_frames != 1 - else: - current = self.tell() - - try: - self.seek(1) - self._is_animated = True - except EOFError: - self._is_animated = False - - self.seek(current) return self._is_animated def seek(self, frame): @@ -1053,6 +1039,8 @@ class TiffImageFile(ImageFile.ImageFile): print("Loading tags, location: %s" % self.fp.tell()) self.tag_v2.load(self.fp) self.__next = self.tag_v2.next + if len(self._frame_pos) == 1: + self._is_animated = self.__next != 0 self.__frame += 1 self.fp.seek(self._frame_pos[frame]) self.tag_v2.load(self.fp) @@ -1086,7 +1074,7 @@ class TiffImageFile(ImageFile.ImageFile): def load_end(self): # allow closing if we're on the first frame, there's no next # This is the ImageFile.load path only, libtiff specific below. - if len(self._frame_pos) == 1 and not self.__next: + if not self._is_animated: self._close_exclusive_fp_after_loading = True def _load_libtiff(self): @@ -1166,10 +1154,9 @@ class TiffImageFile(ImageFile.ImageFile): self.tile = [] self.readonly = 0 # libtiff closed the fp in a, we need to close self.fp, if possible - if self._exclusive_fp: - if len(self._frame_pos) == 1 and not self.__next: - self.fp.close() - self.fp = None # might be shared + if self._exclusive_fp and not self._is_animated: + self.fp.close() + self.fp = None # might be shared if err < 0: raise IOError(err) From be80b083e5a501e0a66364cd9b8e389bdf5ffd41 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 13 Mar 2019 18:28:17 +1100 Subject: [PATCH 2/3] Automatically populate _n_frames if seeking to the last frame --- src/PIL/TiffImagePlugin.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 5f4ed8af2..6ebc05ec1 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -998,11 +998,8 @@ class TiffImageFile(ImageFile.ImageFile): def n_frames(self): if self._n_frames is None: current = self.tell() - try: - while True: - self._seek(self.tell() + 1) - except EOFError: - self._n_frames = self.tell() + 1 + while self._n_frames is None: + self._seek(self.tell() + 1) self.seek(current) return self._n_frames @@ -1039,6 +1036,8 @@ class TiffImageFile(ImageFile.ImageFile): print("Loading tags, location: %s" % self.fp.tell()) self.tag_v2.load(self.fp) self.__next = self.tag_v2.next + if self.__next == 0: + self._n_frames = frame + 1 if len(self._frame_pos) == 1: self._is_animated = self.__next != 0 self.__frame += 1 From 0a877a527d0cc4c8df177c2945e64e636209a953 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 13 Mar 2019 19:07:55 +1100 Subject: [PATCH 3/3] Speed up n_frames by skipping past the last frame already seeked --- src/PIL/TiffImagePlugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 6ebc05ec1..3fced8a21 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -998,6 +998,7 @@ class TiffImageFile(ImageFile.ImageFile): def n_frames(self): if self._n_frames is None: current = self.tell() + self._seek(len(self._frame_pos)) while self._n_frames is None: self._seek(self.tell() + 1) self.seek(current)