mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-12 18:26:17 +03:00
Skip truncated mask if LOAD_TRUNCATED_IMAGES is enabled
This commit is contained in:
parent
585bd6ad48
commit
d3f343bb9b
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import IcoImagePlugin, Image, ImageDraw
|
||||
from PIL import IcoImagePlugin, Image, ImageDraw, ImageFile
|
||||
|
||||
from .helper import assert_image_equal, assert_image_equal_tofile, hopper
|
||||
|
||||
|
@ -241,3 +241,29 @@ def test_draw_reloaded(tmp_path: Path) -> None:
|
|||
|
||||
with Image.open(outfile) as im:
|
||||
assert_image_equal_tofile(im, "Tests/images/hopper_draw.ico")
|
||||
|
||||
|
||||
def test_truncated_mask() -> None:
|
||||
# 1 bpp
|
||||
with open("Tests/images/hopper_mask.ico", "rb") as fp:
|
||||
data = fp.read()
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
data = data[:-3]
|
||||
|
||||
try:
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
with Image.open("Tests/images/hopper_mask.png") as expected:
|
||||
assert im.mode == "1"
|
||||
|
||||
# 32 bpp
|
||||
output = io.BytesIO()
|
||||
expected = hopper("RGBA")
|
||||
expected.save(output, "ico", bitmap_format="bmp")
|
||||
|
||||
data = output.getvalue()[:-1]
|
||||
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
assert im.mode == "RGB"
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
|
|
@ -235,13 +235,19 @@ class IcoFile:
|
|||
alpha_bytes = self.buf.read(im.size[0] * im.size[1] * 4)[3::4]
|
||||
|
||||
# convert to an 8bpp grayscale image
|
||||
mask = Image.frombuffer(
|
||||
"L", # 8bpp
|
||||
im.size, # (w, h)
|
||||
alpha_bytes, # source chars
|
||||
"raw", # raw decoder
|
||||
("L", 0, -1), # 8bpp inverted, unpadded, reversed
|
||||
)
|
||||
try:
|
||||
mask = Image.frombuffer(
|
||||
"L", # 8bpp
|
||||
im.size, # (w, h)
|
||||
alpha_bytes, # source chars
|
||||
"raw", # raw decoder
|
||||
("L", 0, -1), # 8bpp inverted, unpadded, reversed
|
||||
)
|
||||
except ValueError:
|
||||
if ImageFile.LOAD_TRUNCATED_IMAGES:
|
||||
mask = None
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
# get AND image from end of bitmap
|
||||
w = im.size[0]
|
||||
|
@ -259,19 +265,26 @@ class IcoFile:
|
|||
mask_data = self.buf.read(total_bytes)
|
||||
|
||||
# convert raw data to image
|
||||
mask = Image.frombuffer(
|
||||
"1", # 1 bpp
|
||||
im.size, # (w, h)
|
||||
mask_data, # source chars
|
||||
"raw", # raw decoder
|
||||
("1;I", int(w / 8), -1), # 1bpp inverted, padded, reversed
|
||||
)
|
||||
try:
|
||||
mask = Image.frombuffer(
|
||||
"1", # 1 bpp
|
||||
im.size, # (w, h)
|
||||
mask_data, # source chars
|
||||
"raw", # raw decoder
|
||||
("1;I", int(w / 8), -1), # 1bpp inverted, padded, reversed
|
||||
)
|
||||
except ValueError:
|
||||
if ImageFile.LOAD_TRUNCATED_IMAGES:
|
||||
mask = None
|
||||
else:
|
||||
raise
|
||||
|
||||
# now we have two images, im is XOR image and mask is AND image
|
||||
|
||||
# apply mask image as alpha channel
|
||||
im = im.convert("RGBA")
|
||||
im.putalpha(mask)
|
||||
if mask:
|
||||
im = im.convert("RGBA")
|
||||
im.putalpha(mask)
|
||||
|
||||
return im
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user