Do not use palette from grayscale or bilevel colorspace when reading JPEG2000 images (#9468)

This commit is contained in:
Hugo van Kemenade 2026-03-26 15:33:18 +02:00 committed by GitHub
commit 43e4ebe037
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 6 deletions

View File

@ -456,6 +456,13 @@ def test_pclr() -> None:
assert len(im.palette.colors) == 256
assert im.palette.colors[(255, 255, 255)] == 0
for enumcs in (0, 15, 17):
with open(f"{EXTRA_DIR}/issue104_jpxstream.jp2", "rb") as fp:
data = bytearray(fp.read())
data[114:115] = bytes([enumcs])
with Image.open(BytesIO(data)) as im:
assert im.mode == "L"
with Image.open(
f"{EXTRA_DIR}/147af3f1083de4393666b7d99b01b58b_signal_sigsegv_130c531_6155_5136.jp2"
) as im:

View File

@ -176,7 +176,7 @@ def _parse_jp2_header(
nc = None
dpi = None # 2-tuple of DPI info, or None
palette = None
cmyk = False
colr = None
while header.has_next_box():
tbox = header.next_box_type()
@ -199,10 +199,16 @@ def _parse_jp2_header(
mode = "RGBA"
elif tbox == b"colr":
meth, _, _, enumcs = header.read_fields(">BBBI")
if cmyk := (meth == 1 and enumcs == 12):
if nc == 4:
mode = "CMYK"
elif tbox == b"pclr" and mode in ("L", "LA"):
if meth == 1:
if enumcs in (0, 15):
colr = "1"
elif enumcs == 12:
colr = "CMYK"
if nc == 4:
mode = "CMYK"
elif enumcs == 17:
colr = "L"
elif tbox == b"pclr" and mode in ("L", "LA") and colr not in ("1", "L"):
ne, npc = header.read_fields(">HB")
assert isinstance(ne, int)
assert isinstance(npc, int)
@ -213,7 +219,7 @@ def _parse_jp2_header(
max_bitdepth = bitdepth
if max_bitdepth <= 8:
if npc == 4:
palette_mode = "CMYK" if cmyk else "RGBA"
palette_mode = "CMYK" if colr == "CMYK" else "RGBA"
else:
palette_mode = "RGB"
palette = ImagePalette.ImagePalette(palette_mode)