Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions pypdf/generic/_image_xobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,15 @@ def _handle_flate(
# gray lookup does not work: it is converted to a similar RGB lookup
lookup = b"".join([bytes([b, b, b]) for b in lookup])
mode = "RGB"
# TODO: https://github.com/py-pdf/pypdf/pull/2039
# this is a work around until PIL is able to process CMYK images
elif mode == "CMYK":
# Pillow could not unpack CMYK palettes until 10.1.0
# (https://github.com/python-pillow/Pillow/issues/7309,
# fixed by https://github.com/python-pillow/Pillow/pull/7310).
# pypdf currently supports Pillow>=8.0.0, so this manual
# CMYK -> RGB conversion needs to stay until that floor is
# raised to 10.1.0. Note: this rounds slightly differently
# than Pillow's native unpacker (off-by-one on some channels),
# so output is not byte-identical between Pillow versions.
_rgb = []
for _c, _m, _y, _k in (
lookup[n : n + 4] for n in range(0, 4 * (len(lookup) // 4), 4)
Expand Down Expand Up @@ -536,18 +542,23 @@ def _apply_alpha(
obj_as_text,
)
elif lfilters in (FT.LZW_DECODE, FT.ASCII_85_DECODE):
# I'm not sure if the following logic is correct.
# There might not be any relationship between the filters and the
# extension
if lfilters == FT.LZW_DECODE:
image_format = "TIFF"
extension = ".tiff" # mime_type = "image/tiff"
else:
image_format = "PNG"
extension = ".png" # mime_type = "image/png"
# LZW-encoded image data is most commonly TIFF, and ASCII85-encoded
# image data is most commonly PNG, but the filter alone does not
# guarantee the underlying format. Try to open the data directly
# first and trust Pillow's own format detection; only fall back to
# guessing from the filter type if Pillow cannot identify the image
# (in which case it is interpreted as raw, undecoded pixel data).
try:
img = Image.open(BytesIO(data), formats=("TIFF", "PNG"))
image_format = cast(str, img.format)
extension = "." + image_format.lower()
except UnidentifiedImageError:
if lfilters == FT.LZW_DECODE:
image_format = "TIFF"
extension = ".tiff" # mime_type = "image/tiff"
else:
image_format = "PNG"
extension = ".png" # mime_type = "image/png"
img = _image_from_bytes(mode, size, data)
elif lfilters == FT.DCT_DECODE:
img, image_format, extension = Image.open(BytesIO(data)), "JPEG", ".jpg"
Expand Down
Loading