From 18ad4c867ff8a53a6c40d6fdf954799b976ab7f0 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 31 Jan 2023 21:49:12 +1100 Subject: [PATCH 1/4] Use skip_unless_feature_version --- Tests/test_file_jpeg2k.py | 50 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index ccc18772a..5669af7ab 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -12,6 +12,7 @@ from .helper import ( assert_image_similar, assert_image_similar_tofile, skip_unless_feature, + skip_unless_feature_version, ) EXTRA_DIR = "Tests/images/jpeg2000" @@ -384,34 +385,31 @@ def test_custom_comment(): assert bytes(unique_comment, "utf-8") in data +@skip_unless_feature_version("jpg_2000", "2.4.0") def test_plt_marker(): # Search the start of the codesteam for the PLT box (id 0xFF58) - opj_version = re.search(r"(\d+\.\d+)\.\d+$", features.version_codec("jpg_2000")) - assert opj_version is not None + out = BytesIO() + test_card.save(out, "JPEG2000", no_jp2=True, add_plt=True) + out.seek(0) + while True: + box_bytes = out.read(2) + if len(box_bytes) == 0: + # End of steam encountered and no PLT or SOD + break + jp2_boxid = struct.unpack(">H", box_bytes)[0] - if float(opj_version[1]) >= 2.4: - out = BytesIO() - test_card.save(out, "JPEG2000", no_jp2=True, add_plt=True) - out.seek(0) - while True: - box_bytes = out.read(2) - if len(box_bytes) == 0: - # End of steam encountered and no PLT or SOD - break - jp2_boxid = struct.unpack(">H", box_bytes)[0] + if jp2_boxid == 0xFF4F: + # No length specifier for main header + continue + elif jp2_boxid == 0xFF58: + # This is the PLT box we're looking for + return + elif jp2_boxid == 0xFF93: + break + # SOD box encountered and no PLT, so it wasn't found - if jp2_boxid == 0xFF4F: - # No length specifier for main header - continue - elif jp2_boxid == 0xFF58: - # This is the PLT box we're looking for - return - elif jp2_boxid == 0xFF93: - break - # SOD box encountered and no PLT, so it wasn't found + jp2_boxlength = struct.unpack(">H", out.read(2))[0] + out.seek(jp2_boxlength - 2, os.SEEK_CUR) - jp2_boxlength = struct.unpack(">H", out.read(2))[0] - out.seek(jp2_boxlength - 2, os.SEEK_CUR) - - # The PLT box wasn't found - raise ValueError + # The PLT box wasn't found + raise ValueError From ca97e2a3a51fcad8eab4d5466b944e512b82dadd Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 31 Jan 2023 22:31:52 +1100 Subject: [PATCH 2/4] Use _binary --- Tests/test_file_jpeg2k.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 5669af7ab..56d8a7974 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -1,11 +1,17 @@ import os import re -import struct from io import BytesIO import pytest -from PIL import Image, ImageFile, Jpeg2KImagePlugin, UnidentifiedImageError, features +from PIL import ( + Image, + ImageFile, + Jpeg2KImagePlugin, + UnidentifiedImageError, + _binary, + features, +) from .helper import ( assert_image_equal, @@ -393,11 +399,11 @@ def test_plt_marker(): out.seek(0) while True: box_bytes = out.read(2) - if len(box_bytes) == 0: + if not box_bytes: # End of steam encountered and no PLT or SOD break - jp2_boxid = struct.unpack(">H", box_bytes)[0] + jp2_boxid = _binary.i16be(box_bytes) if jp2_boxid == 0xFF4F: # No length specifier for main header continue @@ -405,10 +411,10 @@ def test_plt_marker(): # This is the PLT box we're looking for return elif jp2_boxid == 0xFF93: - break # SOD box encountered and no PLT, so it wasn't found + break - jp2_boxlength = struct.unpack(">H", out.read(2))[0] + jp2_boxlength = _binary.i16be(out.read(2)) out.seek(jp2_boxlength - 2, os.SEEK_CUR) # The PLT box wasn't found From 4bb50b1fa7fe5ef4323b9cb0c819bfba2b608f7f Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 31 Jan 2023 22:24:47 +1100 Subject: [PATCH 3/4] Test comment too long --- Tests/test_file_jpeg2k.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 56d8a7974..a0fb75016 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -390,6 +390,10 @@ def test_custom_comment(): # Lazy method to determine if the comment is in the image generated assert bytes(unique_comment, "utf-8") in data + too_long_comment = " " * 65532 + with pytest.raises(ValueError): + test_card.save(output_stream, "JPEG2000", comment=too_long_comment) + @skip_unless_feature_version("jpg_2000", "2.4.0") def test_plt_marker(): From 04e8a9b3e723a867f220124c26489ace5d2187e0 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 31 Jan 2023 22:24:52 +1100 Subject: [PATCH 4/4] Removed unnecessary code --- src/encode.c | 6 ++---- src/libImaging/Jpeg2K.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/encode.c b/src/encode.c index 33a2a37a7..e8946dbae 100644 --- a/src/encode.c +++ b/src/encode.c @@ -1214,7 +1214,7 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) { char mct = 0; int sgnd = 0; Py_ssize_t fd = -1; - char * comment = NULL; + char *comment = NULL; int add_plt = 0; if (!PyArg_ParseTuple( @@ -1326,7 +1326,7 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) { PyExc_ValueError, "JPEG 2000 comment is too long"); Py_DECREF(encoder); - return NULL; + return NULL; } context->comment = strdup(comment); @@ -1338,8 +1338,6 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) { Py_DECREF(encoder); return NULL; } - } else { - context->comment = NULL; } if (quality_layers && PySequence_Check(quality_layers)) { diff --git a/src/libImaging/Jpeg2K.h b/src/libImaging/Jpeg2K.h index 65728be5d..7bf8b4b0a 100644 --- a/src/libImaging/Jpeg2K.h +++ b/src/libImaging/Jpeg2K.h @@ -98,7 +98,7 @@ typedef struct { const char *error_msg; /* Custom comment */ - char * comment; + char *comment; /* Include PLT marker segment */ int add_plt;