Skip to content

Commit 905745a

Browse files
TST: Add test for retrieving P image with alpha mask (#3525)
1 parent bd433f7 commit 905745a

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

tests/test_xobject_image_helpers.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
from pathlib import Path
44

55
import pytest
6+
from PIL import Image
67

78
from pypdf import PdfReader
89
from pypdf._xobj_image_helpers import _extended_image_frombytes, _handle_flate
10+
from pypdf.constants import FilterTypes, ImageAttributes, StreamAttributes
911
from pypdf.errors import EmptyImageDataError, PdfReadError
10-
from pypdf.generic import ArrayObject, DecodedStreamObject, NameObject, NumberObject
12+
from pypdf.filters import _xobj_to_image
13+
from pypdf.generic import ArrayObject, DecodedStreamObject, NameObject, NumberObject, StreamObject, TextStringObject
1114

1215
from . import get_data_from_url
1316

@@ -171,3 +174,43 @@ def test_get_imagemode__empty_array():
171174

172175
with pytest.raises(expected_exception=PdfReadError, match=r"^ColorSpace field not found in .+"):
173176
page.images[0].image.load()
177+
178+
179+
def test_p_image_with_alpha_mask():
180+
# Generate the base image. Use TIFF as this is easy to do on the fly.
181+
image = Image.new(mode="P", size=(10, 10), color=0)
182+
image_data = BytesIO()
183+
image.save(image_data, format="tiff")
184+
185+
# Set the common values.
186+
x_object = StreamObject()
187+
mask_object = StreamObject()
188+
for obj in [x_object, mask_object]:
189+
obj[NameObject(ImageAttributes.WIDTH)] = NumberObject(image.width)
190+
obj[NameObject(ImageAttributes.HEIGHT)] = NumberObject(image.height)
191+
obj[NameObject(StreamAttributes.FILTER)] = NameObject(FilterTypes.CCITT_FAX_DECODE)
192+
193+
# Set the basic image data.
194+
x_object.set_data(image_data.getvalue())
195+
x_object[NameObject(ImageAttributes.COLOR_SPACE)] = TextStringObject("palette")
196+
197+
# Generate the mask image. Will be a diagonal white stripe.
198+
image = Image.new(mode="1", size=(image.width, image.height))
199+
[image.putpixel((i, i), 1) for i in range(10)]
200+
image_data = BytesIO()
201+
image.save(image_data, format="tiff")
202+
203+
# Set the mask data.
204+
mask_object.set_data(image_data.getvalue())
205+
mask_object[NameObject(ImageAttributes.COLOR_SPACE)] = TextStringObject("1bit")
206+
207+
# Add the mask to the image.
208+
x_object[NameObject("/SMask")] = mask_object
209+
210+
# Generate the output image and make sure that the diagonal stripe is present.
211+
extension, data, image = _xobj_to_image(x_object)
212+
assert extension == ".png"
213+
assert data.startswith(b"\x89PNG")
214+
for i in range(10):
215+
for j in range(10):
216+
assert image.getpixel((i, j)) == (0, 0, 0, 255 * (i == j))

0 commit comments

Comments
 (0)