diff --git a/src/PIL/DcxImagePlugin.py b/src/PIL/DcxImagePlugin.py index 7d2aff325..a12d9195b 100644 --- a/src/PIL/DcxImagePlugin.py +++ b/src/PIL/DcxImagePlugin.py @@ -59,16 +59,10 @@ class DcxImageFile(PcxImageFile): self.__fp = self.fp self.frame = None + self.n_frames = len(self._offset) + self.is_animated = self.n_frames > 1 self.seek(0) - @property - def n_frames(self): - return len(self._offset) - - @property - def is_animated(self): - return len(self._offset) > 1 - def seek(self, frame): if not self._seek_check(frame): return diff --git a/src/PIL/FliImagePlugin.py b/src/PIL/FliImagePlugin.py index 9bf7d74d6..989094569 100644 --- a/src/PIL/FliImagePlugin.py +++ b/src/PIL/FliImagePlugin.py @@ -51,7 +51,8 @@ class FliImageFile(ImageFile.ImageFile): raise SyntaxError("not an FLI/FLC file") # frames - self.__framecount = i16(s[6:8]) + self.n_frames = i16(s[6:8]) + self.is_animated = self.n_frames > 1 # image characteristics self.mode = "P" @@ -110,14 +111,6 @@ class FliImageFile(ImageFile.ImageFile): palette[i] = (r, g, b) i += 1 - @property - def n_frames(self): - return self.__framecount - - @property - def is_animated(self): - return self.__framecount > 1 - def seek(self, frame): if not self._seek_check(frame): return diff --git a/src/PIL/MicImagePlugin.py b/src/PIL/MicImagePlugin.py index 8610988fc..1d7af7c7a 100644 --- a/src/PIL/MicImagePlugin.py +++ b/src/PIL/MicImagePlugin.py @@ -64,20 +64,14 @@ class MicImageFile(TiffImagePlugin.TiffImageFile): self.__fp = self.fp self.frame = None + self._n_frames = len(self.images) + self.is_animated = self._n_frames > 1 if len(self.images) > 1: self.category = Image.CONTAINER self.seek(0) - @property - def n_frames(self): - return len(self.images) - - @property - def is_animated(self): - return len(self.images) > 1 - def seek(self, frame): if not self._seek_check(frame): return diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py index e97176d57..575cc9c8e 100644 --- a/src/PIL/MpoImagePlugin.py +++ b/src/PIL/MpoImagePlugin.py @@ -48,15 +48,16 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile): def _after_jpeg_open(self, mpheader=None): self.mpinfo = mpheader if mpheader is not None else self._getmp() - self.__framecount = self.mpinfo[0xB001] + self.n_frames = self.mpinfo[0xB001] self.__mpoffsets = [ mpent["DataOffset"] + self.info["mpoffset"] for mpent in self.mpinfo[0xB002] ] self.__mpoffsets[0] = 0 # Note that the following assertion will only be invalid if something # gets broken within JpegImagePlugin. - assert self.__framecount == len(self.__mpoffsets) + assert self.n_frames == len(self.__mpoffsets) del self.info["mpoffset"] # no longer needed + self.is_animated = self.n_frames > 1 self.__fp = self.fp # FIXME: hack self.__fp.seek(self.__mpoffsets[0]) # get ready to read first frame self.__frame = 0 @@ -67,14 +68,6 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile): def load_seek(self, pos): self.__fp.seek(pos) - @property - def n_frames(self): - return self.__framecount - - @property - def is_animated(self): - return self.__framecount > 1 - def seek(self, frame): if not self._seek_check(frame): return diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py index cceb85c5b..044df443d 100644 --- a/src/PIL/PsdImagePlugin.py +++ b/src/PIL/PsdImagePlugin.py @@ -119,6 +119,8 @@ class PsdImageFile(ImageFile.ImageFile): if size: self.layers = _layerinfo(self.fp) self.fp.seek(end) + self.n_frames = len(self.layers) + self.is_animated = self.n_frames > 1 # # image descriptor @@ -130,14 +132,6 @@ class PsdImageFile(ImageFile.ImageFile): self.frame = 1 self._min_frame = 1 - @property - def n_frames(self): - return len(self.layers) - - @property - def is_animated(self): - return len(self.layers) > 1 - def seek(self, layer): if not self._seek_check(layer): return diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index e8d82ae46..ee2d57743 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1015,10 +1015,6 @@ class TiffImageFile(ImageFile.ImageFile): self.seek(current) return self._n_frames - @property - def is_animated(self): - return self._is_animated - def seek(self, frame): """Select a given frame as current image""" if not self._seek_check(frame): @@ -1052,7 +1048,7 @@ class TiffImageFile(ImageFile.ImageFile): if self.__next == 0: self._n_frames = frame + 1 if len(self._frame_pos) == 1: - self._is_animated = self.__next != 0 + self.is_animated = self.__next != 0 self.__frame += 1 self.fp.seek(self._frame_pos[frame]) self.tag_v2.load(self.fp) @@ -1087,7 +1083,7 @@ class TiffImageFile(ImageFile.ImageFile): # allow closing if we're on the first frame, there's no next # This is the ImageFile.load path only, libtiff specific below. - if not self._is_animated: + if not self.is_animated: self._close_exclusive_fp_after_loading = True def _load_libtiff(self): @@ -1138,7 +1134,7 @@ class TiffImageFile(ImageFile.ImageFile): except ValueError: raise OSError("Couldn't set the image") - close_self_fp = self._exclusive_fp and not self._is_animated + close_self_fp = self._exclusive_fp and not self.is_animated if hasattr(self.fp, "getvalue"): # We've got a stringio like thing passed in. Yay for all in memory. # The decoder needs the entire file in one shot, so there's not diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py index 77a02e4b9..fd8c02a2d 100644 --- a/src/PIL/WebPImagePlugin.py +++ b/src/PIL/WebPImagePlugin.py @@ -54,7 +54,8 @@ class WebPImageFile(ImageFile.ImageFile): self._size = width, height self.fp = BytesIO(data) self.tile = [("raw", (0, 0) + self.size, 0, self.mode)] - self._n_frames = 1 + self.n_frames = 1 + self.is_animated = False return # Use the newer AnimDecoder API to parse the (possibly) animated file, @@ -72,7 +73,8 @@ class WebPImageFile(ImageFile.ImageFile): bgcolor & 0xFF, ) self.info["background"] = (bg_r, bg_g, bg_b, bg_a) - self._n_frames = frame_count + self.n_frames = frame_count + self.is_animated = self.n_frames > 1 self.mode = "RGB" if mode == "RGBX" else mode self.rawmode = mode self.tile = [] @@ -97,14 +99,6 @@ class WebPImageFile(ImageFile.ImageFile): return None return dict(self.getexif()) - @property - def n_frames(self): - return self._n_frames - - @property - def is_animated(self): - return self._n_frames > 1 - def seek(self, frame): if not _webp.HAVE_WEBPANIM: return super().seek(frame)