Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Determine JPEG2000 mode purely from ihdr header box #5654

Merged
merged 1 commit into from Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added Tests/images/balloon_eciRGBv2_aware.jp2
Binary file not shown.
10 changes: 10 additions & 0 deletions Tests/test_file_jpeg2k.py
Expand Up @@ -159,6 +159,16 @@ def test_load_dpi():
assert "dpi" not in im.info


def test_restricted_icc_profile():
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
# JPEG2000 image with a restricted ICC profile and a known colorspace
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
assert im.mode == "RGB"
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False


def test_header_errors():
for path in (
"Tests/images/invalid_header_length.jp2",
Expand Down
49 changes: 11 additions & 38 deletions src/PIL/Jpeg2KImagePlugin.py
Expand Up @@ -159,50 +159,23 @@ def _parse_jp2_header(fp):
bpc = None
nc = None
dpi = None # 2-tuple of DPI info, or None
unkc = 0 # Colorspace information unknown

while header.has_next_box():
tbox = header.next_box_type()

if tbox == b"ihdr":
height, width, nc, bpc, c, unkc, ipr = header.read_fields(">IIHBBBB")
height, width, nc, bpc = header.read_fields(">IIHB")
size = (width, height)
if unkc:
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 2:
mode = "LA"
elif nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
elif tbox == b"colr":
meth, prec, approx = header.read_fields(">BBB")
if meth == 1 and unkc == 0:
cs = header.read_fields(">I")[0]
if cs == 16: # sRGB
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
elif cs == 17: # grayscale
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 2:
mode = "LA"
elif cs == 18: # sYCC
if nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 2:
mode = "LA"
elif nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
elif tbox == b"res ":
res = header.read_boxes()
while res.has_next_box():
Expand Down