From 4e7f04179586ae241fd4b0b71146d58d0043fbf1 Mon Sep 17 00:00:00 2001 From: scaramallion Date: Sun, 16 May 2021 10:46:43 +1000 Subject: [PATCH] Rename parameter and add more tests --- Tests/test_file_jpeg2k.py | 65 +++++++++++++++++++++++----- docs/handbook/image-file-formats.rst | 15 ++++--- src/PIL/Jpeg2KImagePlugin.py | 4 +- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index faaf8e355..474ca1f00 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -209,41 +209,82 @@ def test_layers(): assert_image_similar(im, test_card, 0.4) -def test_use_jp2(): - out = BytesIO() - test_card.save(out, "JPEG2000", use_jp2=False) - out.seek(0) - assert out.read(2) == b"\xff\x4f" - +def test_no_jp2(): out = BytesIO() out.name = "foo.j2k" - test_card.save(out, "JPEG2000", use_jp2=False) + test_card.save(out, "JPEG2000") out.seek(0) assert out.read(2) == b"\xff\x4f" out = BytesIO() out.name = "foo.jp2" - test_card.save(out, "JPEG2000", use_jp2=False) + test_card.save(out, "JPEG2000") out.seek(4) - assert out.read(2) != b"jP" + assert out.read(2) == b"jP" + + out = BytesIO() + test_card.save(out, "JPEG2000", no_jp2=True) + out.seek(0) + assert out.read(2) == b"\xff\x4f" + + out = BytesIO() + test_card.save(out, "JPEG2000", no_jp2=True) + out.seek(0) + assert out.read(2) == b"\xff\x4f" + + out = BytesIO() + out.name = "foo.j2k" + test_card.save(out, "JPEG2000", no_jp2=True) + out.seek(0) + assert out.read(2) == b"\xff\x4f" + + out = BytesIO() + out.name = "foo.jp2" + test_card.save(out, "JPEG2000", no_jp2=True) + out.seek(0) + assert out.read(2) == b"\xff\x4f" + + # Use the filename extension to determine format + out = BytesIO() + out.name = "foo.j2k" + test_card.save(out, "JPEG2000", no_jp2=False) + out.seek(0) + assert out.read(2) == b"\xff\x4f" + + out = BytesIO() + out.name = "foo.jp2" + test_card.save(out, "JPEG2000", no_jp2=False) + out.seek(4) + assert out.read(2) == b"jP" + + # Default to JP2 if no filename + out = BytesIO() + test_card.save(out, "JPEG2000", no_jp2=False) + out.seek(4) + assert out.read(2) == b"jP" + + out = BytesIO() + test_card.save(out, "JPEG2000", no_jp2=False) + out.seek(4) + assert out.read(2) == b"jP" def test_mct(): # Three component for val in (0, 1): out = BytesIO() - test_card.save(out, "JPEG2000", mct=val, use_jp2=False) + test_card.save(out, "JPEG2000", mct=val, no_jp2=True) out.seek(0) with Image.open(out) as im: im.load() assert_image_similar(im, test_card, 1.0e-3) assert out.getvalue()[59] == val - # Single component + # Single component should have MCT disabled for val in (0, 1): out = BytesIO() with Image.open("Tests/images/16bit.cropped.jp2") as jp2: - jp2.save(out, "JPEG2000", mct=val, use_jp2=False) + jp2.save(out, "JPEG2000", mct=val, no_jp2=True) out.seek(0) with Image.open(out) as im: diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 3bb48115d..f76cc82b7 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -506,10 +506,10 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options: Defaults to ``False``, which uses the lossless DWT 5-3. **mct** - If ``0`` then don't use multiple component transformation when encoding, - otherwise use ``1`` to apply to components 0, 1 and 2. MCT works best - with a ``mode`` of ``RGB`` and is only available for 3 component image - data. + If ``1`` then apply multiple component transformation when encoding, + otherwise use ``0`` for no component transformation (default). MCT works + best with a ``mode`` of ``RGB`` and is only applied when the image data has + 3 components. **progression** Controls the progression order; must be one of ``"LRCP"``, ``"RLCP"``, @@ -529,9 +529,10 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options: for compliant 4K files, *at least one* of the dimensions must match 4096 x 2160. -**use_jp2** - If ``False`` then don't wrap the codestream in the JP2 file format when - saving. Defaults to ``True``. +**no_jp2** + If ``True`` then don't wrap the raw codestream in the JP2 file format when + saving, otherwise the extension of the filename will be used to determine + the format (default). .. note:: diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index 98e93fea5..fb5d70cee 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -293,10 +293,10 @@ def _save(im, fp, filename): # Get the keyword arguments info = im.encoderinfo - if filename.endswith(".j2k"): + if filename.endswith(".j2k") or info.get("no_jp2", False): kind = "j2k" else: - kind = "jp2" if info.get("use_jp2", True) else "j2k" + kind = "jp2" offset = info.get("offset", None) tile_offset = info.get("tile_offset", None)