Fix dispose calculations

- use correct dispose mode
- only apply the dispose on extent of the previous frame
This commit is contained in:
Lars Jørgen Solberg 2014-07-02 21:27:52 +02:00
parent bd9c555905
commit 08a9bdbcd6

View File

@ -96,6 +96,7 @@ class GifImageFile(ImageFile.ImageFile):
# rewind # rewind
self.__offset = 0 self.__offset = 0
self.dispose = None self.dispose = None
self.dispose_extent = [0, 0, 0, 0] #x0, y0, x1, y1
self.__frame = -1 self.__frame = -1
self.__fp.seek(self.__rewind) self.__fp.seek(self.__rewind)
@ -114,12 +115,12 @@ class GifImageFile(ImageFile.ImageFile):
self.__offset = 0 self.__offset = 0
if self.dispose: if self.dispose:
self.im = self.dispose self.im.paste(self.dispose, self.dispose_extent)
self.dispose = None
from copy import copy from copy import copy
self.palette = copy(self.global_palette) self.palette = copy(self.global_palette)
disposal_method = 0
while True: while True:
s = self.fp.read(1) s = self.fp.read(1)
@ -140,17 +141,10 @@ class GifImageFile(ImageFile.ImageFile):
if flags & 1: if flags & 1:
self.info["transparency"] = i8(block[3]) self.info["transparency"] = i8(block[3])
self.info["duration"] = i16(block[1:3]) * 10 self.info["duration"] = i16(block[1:3]) * 10
try:
# disposal methods # disposal method - find the value of bits 4 - 6
if flags & 8: disposal_method = 0b00011100 & flags
# replace with background colour disposal_method = disposal_method >> 2
self.dispose = Image.core.fill("P", self.size,
self.info["background"])
elif flags & 16:
# replace with previous contents
self.dispose = self.im.copy()
except (AttributeError, KeyError):
pass
elif i8(s) == 255: elif i8(s) == 255:
# #
# application extension # application extension
@ -172,6 +166,7 @@ class GifImageFile(ImageFile.ImageFile):
# extent # extent
x0, y0 = i16(s[0:]), i16(s[2:]) x0, y0 = i16(s[0:]), i16(s[2:])
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:]) x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:])
self.dispose_extent = x0, y0, x1, y1
flags = i8(s[8]) flags = i8(s[8])
interlace = (flags & 64) != 0 interlace = (flags & 64) != 0
@ -194,6 +189,26 @@ class GifImageFile(ImageFile.ImageFile):
pass pass
# raise IOError, "illegal GIF tag `%x`" % i8(s) # raise IOError, "illegal GIF tag `%x`" % i8(s)
try:
if disposal_method < 2:
# do not dispose or none specified
self.dispose = None
elif disposal_method == 2:
# replace with background colour
self.dispose = Image.core.fill("P", self.size,
self.info["background"])
else:
# replace with previous contents
if self.im:
self.dispose = self.im.copy()
# only dispose the extent in this frame
if self.dispose:
self.dispose = self.dispose.crop(self.dispose_extent)
except (AttributeError, KeyError):
pass
if not self.tile: if not self.tile:
# self.__fp = None # self.__fp = None
raise EOFError("no more images in GIF file") raise EOFError("no more images in GIF file")