mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
Merge pull request #4552 from radarhere/animation
Simplified animation code
This commit is contained in:
commit
f83f19788b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
@ -1133,7 +1129,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
|
||||
|
|
|
@ -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 = []
|
||||
|
@ -90,30 +92,15 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
|
||||
# Initialize seek state
|
||||
self._reset(reset=False)
|
||||
self.seek(0)
|
||||
|
||||
def _getexif(self):
|
||||
if "exif" not in self.info:
|
||||
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)
|
||||
|
||||
# Perform some simple checks first
|
||||
if frame >= self._n_frames:
|
||||
raise EOFError("attempted to seek beyond end of sequence")
|
||||
if frame < 0:
|
||||
raise EOFError("negative frame index is not valid")
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
||||
# Set logical frame to requested position
|
||||
self.__logical_frame = frame
|
||||
|
|
Loading…
Reference in New Issue
Block a user