mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-14 05:36:48 +03:00
Reverted converting L with transparency to LA after first frame
This commit is contained in:
parent
ce8c682748
commit
c5efe60c37
Binary file not shown.
Before Width: | Height: | Size: 64 B After Width: | Height: | Size: 1.6 KiB |
|
@ -59,23 +59,15 @@ def test_invalid_file():
|
||||||
GifImagePlugin.GifImageFile(invalid_file)
|
GifImagePlugin.GifImageFile(invalid_file)
|
||||||
|
|
||||||
|
|
||||||
def test_l_mode_subsequent_frames():
|
def test_l_mode_transparency():
|
||||||
with Image.open("Tests/images/no_palette.gif") as im:
|
|
||||||
assert im.mode == "L"
|
|
||||||
assert im.load()[0, 0] == 0
|
|
||||||
|
|
||||||
im.seek(1)
|
|
||||||
assert im.mode == "L"
|
|
||||||
assert im.load()[0, 0] == 0
|
|
||||||
|
|
||||||
with Image.open("Tests/images/no_palette_with_transparency.gif") as im:
|
with Image.open("Tests/images/no_palette_with_transparency.gif") as im:
|
||||||
assert im.mode == "L"
|
assert im.mode == "L"
|
||||||
assert im.load()[0, 0] == 0
|
assert im.load()[0, 0] == 128
|
||||||
assert im.info["transparency"] == 255
|
assert im.info["transparency"] == 255
|
||||||
|
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
assert im.mode == "LA"
|
assert im.mode == "L"
|
||||||
assert im.load()[0, 0] == (0, 255)
|
assert im.load()[0, 0] == 128
|
||||||
|
|
||||||
|
|
||||||
def test_strategy():
|
def test_strategy():
|
||||||
|
@ -439,14 +431,6 @@ def test_dispose_background_transparency():
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"mode_strategy, expected_colors",
|
"mode_strategy, expected_colors",
|
||||||
(
|
(
|
||||||
(
|
|
||||||
GifImagePlugin.ModeStrategy.DIFFERENT_PALETTE_ONLY,
|
|
||||||
(
|
|
||||||
(2, 1, 2),
|
|
||||||
(0, 1, 0),
|
|
||||||
(2, 1, 2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
GifImagePlugin.ModeStrategy.AFTER_FIRST,
|
GifImagePlugin.ModeStrategy.AFTER_FIRST,
|
||||||
(
|
(
|
||||||
|
@ -455,16 +439,27 @@ def test_dispose_background_transparency():
|
||||||
((0, 0, 0, 0), (0, 0, 255, 255), (0, 0, 0, 0)),
|
((0, 0, 0, 0), (0, 0, 255, 255), (0, 0, 0, 0)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
GifImagePlugin.ModeStrategy.DIFFERENT_PALETTE_ONLY,
|
||||||
|
(
|
||||||
|
(2, 1, 2),
|
||||||
|
(0, 1, 0),
|
||||||
|
(2, 1, 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_transparent_dispose(mode_strategy, expected_colors):
|
def test_transparent_dispose(mode_strategy, expected_colors):
|
||||||
GifImagePlugin.PALETTE_TO_RGB = mode_strategy
|
GifImagePlugin.PALETTE_TO_RGB = mode_strategy
|
||||||
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
try:
|
||||||
for frame in range(3):
|
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
||||||
img.seek(frame)
|
for frame in range(3):
|
||||||
for x in range(3):
|
img.seek(frame)
|
||||||
color = img.getpixel((x, 0))
|
for x in range(3):
|
||||||
assert color == expected_colors[frame][x]
|
color = img.getpixel((x, 0))
|
||||||
|
assert color == expected_colors[frame][x]
|
||||||
|
finally:
|
||||||
|
GifImagePlugin.PALETTE_TO_RGB = GifImagePlugin.ModeStrategy.AFTER_FIRST
|
||||||
|
|
||||||
|
|
||||||
def test_dispose_previous():
|
def test_dispose_previous():
|
||||||
|
|
|
@ -107,8 +107,7 @@ are used or GIF89a is already in use.
|
||||||
|
|
||||||
GIF files are initially read as grayscale (``L``) or palette mode (``P``)
|
GIF files are initially read as grayscale (``L``) or palette mode (``P``)
|
||||||
images. Seeking to later frames in a ``P`` image will change the image to
|
images. Seeking to later frames in a ``P`` image will change the image to
|
||||||
``RGB`` (or ``RGBA`` if the first frame had transparency). ``L`` images will
|
``RGB`` (or ``RGBA`` if the first frame had transparency).
|
||||||
stay in ``L`` mode (or change to ``LA`` if the first frame had transparency).
|
|
||||||
|
|
||||||
``P`` mode images are changed to ``RGB`` because each frame of a GIF may
|
``P`` mode images are changed to ``RGB`` because each frame of a GIF may
|
||||||
introduce up to 256 colors. Because ``P`` can only have up to 256 colors, the
|
introduce up to 256 colors. Because ``P`` can only have up to 256 colors, the
|
||||||
|
|
|
@ -71,6 +71,12 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
return self.fp.read(s[0])
|
return self.fp.read(s[0])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _is_palette_needed(self, p):
|
||||||
|
for i in range(0, len(p), 3):
|
||||||
|
if not (i // 3 == p[i] == p[i + 1] == p[i + 2]):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
|
|
||||||
# Screen
|
# Screen
|
||||||
|
@ -89,11 +95,9 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.info["background"] = s[11]
|
self.info["background"] = s[11]
|
||||||
# check if palette contains colour indices
|
# check if palette contains colour indices
|
||||||
p = self.fp.read(3 << bits)
|
p = self.fp.read(3 << bits)
|
||||||
for i in range(0, len(p), 3):
|
if self._is_palette_needed(p):
|
||||||
if not (i // 3 == p[i] == p[i + 1] == p[i + 2]):
|
p = ImagePalette.raw("RGB", p)
|
||||||
p = ImagePalette.raw("RGB", p)
|
self.global_palette = self.palette = p
|
||||||
self.global_palette = self.palette = p
|
|
||||||
break
|
|
||||||
|
|
||||||
self.__fp = self.fp # FIXME: hack
|
self.__fp = self.fp # FIXME: hack
|
||||||
self.__rewind = self.fp.tell()
|
self.__rewind = self.fp.tell()
|
||||||
|
@ -259,7 +263,9 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
if flags & 128:
|
if flags & 128:
|
||||||
bits = (flags & 7) + 1
|
bits = (flags & 7) + 1
|
||||||
palette = ImagePalette.raw("RGB", self.fp.read(3 << bits))
|
p = self.fp.read(3 << bits)
|
||||||
|
if self._is_palette_needed(p):
|
||||||
|
palette = ImagePalette.raw("RGB", p)
|
||||||
|
|
||||||
# image data
|
# image data
|
||||||
bits = self.fp.read(1)[0]
|
bits = self.fp.read(1)[0]
|
||||||
|
@ -305,11 +311,6 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
else:
|
else:
|
||||||
self.mode = "RGB"
|
self.mode = "RGB"
|
||||||
self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG)
|
self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG)
|
||||||
elif self.mode == "L" and "transparency" in self.info:
|
|
||||||
self.pyaccess = None
|
|
||||||
self.im = self.im.convert_transparent("LA", self.info["transparency"])
|
|
||||||
self.mode = "LA"
|
|
||||||
del self.info["transparency"]
|
|
||||||
|
|
||||||
def _rgb(color):
|
def _rgb(color):
|
||||||
if self._frame_palette:
|
if self._frame_palette:
|
||||||
|
@ -369,7 +370,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
if frame_transparency is not None:
|
if frame_transparency is not None:
|
||||||
if frame == 0:
|
if frame == 0:
|
||||||
self.info["transparency"] = frame_transparency
|
self.info["transparency"] = frame_transparency
|
||||||
elif self.mode not in ("RGB", "RGBA", "LA"):
|
elif self.mode not in ("RGB", "RGBA"):
|
||||||
transparency = frame_transparency
|
transparency = frame_transparency
|
||||||
self.tile = [
|
self.tile = [
|
||||||
(
|
(
|
||||||
|
@ -394,7 +395,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.im = Image.core.fill(
|
self.im = Image.core.fill(
|
||||||
temp_mode, self.size, self.info["transparency"]
|
temp_mode, self.size, self.info["transparency"]
|
||||||
)
|
)
|
||||||
elif self.mode in ("RGB", "RGBA", "LA"):
|
elif self.mode in ("RGB", "RGBA"):
|
||||||
self._prev_im = self.im
|
self._prev_im = self.im
|
||||||
if self._frame_palette:
|
if self._frame_palette:
|
||||||
self.im = Image.core.fill("P", self.size, self._frame_transparency or 0)
|
self.im = Image.core.fill("P", self.size, self._frame_transparency or 0)
|
||||||
|
@ -418,8 +419,6 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
frame_im = self.im.convert("RGBA")
|
frame_im = self.im.convert("RGBA")
|
||||||
else:
|
else:
|
||||||
frame_im = self.im.convert("RGB")
|
frame_im = self.im.convert("RGB")
|
||||||
elif self.mode == "L" and self._frame_transparency is not None:
|
|
||||||
frame_im = self.im.convert_transparent("LA", self._frame_transparency)
|
|
||||||
else:
|
else:
|
||||||
if not self._prev_im:
|
if not self._prev_im:
|
||||||
return
|
return
|
||||||
|
@ -428,7 +427,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
self.im = self._prev_im
|
self.im = self._prev_im
|
||||||
self.mode = self.im.mode
|
self.mode = self.im.mode
|
||||||
if frame_im.mode in ("LA", "RGBA"):
|
if frame_im.mode == "RGBA":
|
||||||
self.im.paste(frame_im, self.dispose_extent, frame_im)
|
self.im.paste(frame_im, self.dispose_extent, frame_im)
|
||||||
else:
|
else:
|
||||||
self.im.paste(frame_im, self.dispose_extent)
|
self.im.paste(frame_im, self.dispose_extent)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user