mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-20 12:14:46 +03:00
Optimized GifImagePlugin seek-related operations
- Add: Added `self.__prev_offset` to always hold the offset of the frame just before the current frame. - Add: Seeking beyond the last frame automatically computes `GifImagePlugin.n_frames`. - Change: Optimized `GifImagePlugin.seek()`, `GifImagePlugin.n_frames` and `GifImagePlugin.is_animated` when seeking back to the current frame before invoking the operation, after an `EOFError` is raised. - Change: Replaced all internal calls to `GifImagePlugin.tell()` with direct references to `self.__frame`.
This commit is contained in:
parent
b803b7c2a1
commit
5bdd0762f3
|
@ -94,13 +94,17 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
@property
|
@property
|
||||||
def n_frames(self):
|
def n_frames(self):
|
||||||
if self._n_frames is None:
|
if self._n_frames is None:
|
||||||
current = self.tell()
|
prev_offset = self.__prev_offset
|
||||||
|
current = self.__frame
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
self.seek(self.tell() + 1)
|
self._seek(self.__frame + 1)
|
||||||
except EOFError:
|
except EOFError:
|
||||||
self._n_frames = self.tell() + 1
|
self._n_frames = self.__frame
|
||||||
self.seek(current)
|
|
||||||
|
self.__offset = prev_offset
|
||||||
|
self.__frame = current - 1
|
||||||
|
self._seek(current)
|
||||||
return self._n_frames
|
return self._n_frames
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -109,7 +113,8 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
if self._n_frames is not None:
|
if self._n_frames is not None:
|
||||||
self._is_animated = self._n_frames != 1
|
self._is_animated = self._n_frames != 1
|
||||||
else:
|
else:
|
||||||
current = self.tell()
|
prev_offset = self.__prev_offset
|
||||||
|
current = self.__frame
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.seek(1)
|
self.seek(1)
|
||||||
|
@ -117,7 +122,9 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
except EOFError:
|
except EOFError:
|
||||||
self._is_animated = False
|
self._is_animated = False
|
||||||
|
|
||||||
self.seek(current)
|
self.__offset = prev_offset
|
||||||
|
self.__frame = current - 1
|
||||||
|
self._seek(current)
|
||||||
return self._is_animated
|
return self._is_animated
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame):
|
||||||
|
@ -127,12 +134,17 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.im = None
|
self.im = None
|
||||||
self._seek(0)
|
self._seek(0)
|
||||||
|
|
||||||
|
prev_offset = self.__prev_offset
|
||||||
last_frame = self.__frame
|
last_frame = self.__frame
|
||||||
for f in range(self.__frame + 1, frame + 1):
|
for f in range(self.__frame + 1, frame + 1):
|
||||||
try:
|
try:
|
||||||
self._seek(f)
|
self._seek(f)
|
||||||
except EOFError as e:
|
except EOFError as e:
|
||||||
self.seek(last_frame)
|
if not self._n_frames:
|
||||||
|
self._n_frames = f
|
||||||
|
self.__offset = prev_offset
|
||||||
|
self.__frame = last_frame - 1
|
||||||
|
self._seek(last_frame)
|
||||||
raise EOFError("no more images in GIF file") from e
|
raise EOFError("no more images in GIF file") from e
|
||||||
|
|
||||||
def _seek(self, frame):
|
def _seek(self, frame):
|
||||||
|
@ -157,6 +169,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.tile = []
|
self.tile = []
|
||||||
|
|
||||||
self.fp = self.__fp
|
self.fp = self.__fp
|
||||||
|
self.__prev_offset = self.__offset
|
||||||
if self.__offset:
|
if self.__offset:
|
||||||
# backup to last frame
|
# backup to last frame
|
||||||
self.fp.seek(self.__offset)
|
self.fp.seek(self.__offset)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user