diff --git a/Tests/images/zero_dpi.jp2 b/Tests/images/zero_dpi.jp2 new file mode 100644 index 000000000..079271fc6 Binary files /dev/null and b/Tests/images/zero_dpi.jp2 differ diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 1af73a767..779d246e9 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -155,6 +155,9 @@ def test_load_dpi(): with Image.open("Tests/images/test-card-lossless.jp2") as im: assert im.info["dpi"] == (71.9836, 71.9836) + with Image.open("Tests/images/zero_dpi.jp2") as im: + assert "dpi" not in im.info + def test_layers_type(tmp_path): outfile = str(tmp_path / "temp_layers.jp2") diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index bbcfc0ef9..cb774595e 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -131,11 +131,8 @@ def _res_to_dpi(num, denom, exp): """Convert JPEG2000's (numerator, denominator, exponent-base-10) resolution, calculated as (num / denom) * 10^exp and stored in dots per meter, to floating-point dots per inch.""" - if num == 0 or denom == 0: - raise SyntaxError( - f"Invalid JP2 resolution information: ({num} / {denom}) * 10^{exp}" - ) - return (254 * num * (10 ** exp)) / (10000 * denom) + if denom != 0: + return num / denom * (10 ** exp) * 0.0254 def _parse_jp2_header(fp): @@ -217,7 +214,8 @@ def _parse_jp2_header(fp): vrcn, vrcd, hrcn, hrcd, vrce, hrce = res.read_fields(">HHHHBB") hres = _res_to_dpi(hrcn, hrcd, hrce) vres = _res_to_dpi(vrcn, vrcd, vrce) - dpi = (hres, vres) + if hres is not None and vres is not None: + dpi = (hres, vres) if size is None or mode is None: raise SyntaxError("Malformed JP2 header")