From 4f5802b6b17a3c463f734e3c5cc3484dca9b1d44 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 16 Mar 2026 23:45:22 +1100 Subject: [PATCH] Do not use palette from grayscale or bilevel colorspace --- Tests/test_file_jpeg2k.py | 7 +++++++ src/PIL/Jpeg2KImagePlugin.py | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 575d911def5..4f6376ed7e5 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -440,6 +440,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: diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index d6ec38d4310..b08c466e266 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -176,6 +176,7 @@ def _parse_jp2_header( nc = None dpi = None # 2-tuple of DPI info, or None palette = None + colr = None while header.has_next_box(): tbox = header.next_box_type() @@ -196,11 +197,17 @@ def _parse_jp2_header( mode = "RGB" elif nc == 4: mode = "RGBA" - elif tbox == b"colr" and nc == 4: + elif tbox == b"colr": meth, _, _, enumcs = header.read_fields(">BBBI") - if meth == 1 and enumcs == 12: - mode = "CMYK" - elif tbox == b"pclr" and mode in ("L", "LA"): + if meth == 1: + if enumcs in (0, 15): + colr = "1" + elif enumcs == 12: + 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)