Merge pull request #6709 from radarhere/signed

Added signed option when saving JPEG2000 images
This commit is contained in:
Hugo van Kemenade 2022-12-29 11:59:33 +02:00 committed by GitHub
commit f452f9a3f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 2 deletions

View File

@ -252,6 +252,20 @@ def test_mct():
assert_image_similar(im, jp2, 1.0e-3) assert_image_similar(im, jp2, 1.0e-3)
def test_sgnd(tmp_path):
outfile = str(tmp_path / "temp.jp2")
im = Image.new("L", (1, 1))
im.save(outfile)
with Image.open(outfile) as reloaded:
assert reloaded.getpixel((0, 0)) == 0
im = Image.new("L", (1, 1))
im.save(outfile, signed=True)
with Image.open(outfile) as reloaded_signed:
assert reloaded_signed.getpixel((0, 0)) == 128
def test_rgba(): def test_rgba():
# Arrange # Arrange
with Image.open("Tests/images/rgb_trns_ycbc.j2k") as j2k: with Image.open("Tests/images/rgb_trns_ycbc.j2k") as j2k:

View File

@ -568,6 +568,11 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
encoded using RLCP mode will have increasing resolutions decoded as they encoded using RLCP mode will have increasing resolutions decoded as they
arrive, and so on. arrive, and so on.
**signed**
If true, then tell the encoder to save the image as signed.
.. versionadded:: 9.4.0
**cinema_mode** **cinema_mode**
Set the encoder to produce output compliant with the digital cinema Set the encoder to produce output compliant with the digital cinema
specifications. The options here are ``"no"`` (the default), specifications. The options here are ``"no"`` (the default),

View File

@ -45,6 +45,12 @@ removes the hidden RGB values for better compression by default in libwebp 0.5
or later. By setting this option to ``True``, the encoder will keep the hidden or later. By setting this option to ``True``, the encoder will keep the hidden
RGB values. RGB values.
Added ``signed`` option when saving JPEG2000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the ``signed`` keyword argument is present and true when saving JPEG2000
images, then tell the encoder to save the image as signed.
Added IFD, Interop and LightSource ExifTags enums Added IFD, Interop and LightSource ExifTags enums
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -321,6 +321,7 @@ def _save(im, fp, filename):
progression = info.get("progression", "LRCP") progression = info.get("progression", "LRCP")
cinema_mode = info.get("cinema_mode", "no") cinema_mode = info.get("cinema_mode", "no")
mct = info.get("mct", 0) mct = info.get("mct", 0)
signed = info.get("signed", False)
fd = -1 fd = -1
if hasattr(fp, "fileno"): if hasattr(fp, "fileno"):
@ -342,6 +343,7 @@ def _save(im, fp, filename):
progression, progression,
cinema_mode, cinema_mode,
mct, mct,
signed,
fd, fd,
) )

View File

@ -1212,11 +1212,12 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
char *cinema_mode = "no"; char *cinema_mode = "no";
OPJ_CINEMA_MODE cine_mode; OPJ_CINEMA_MODE cine_mode;
char mct = 0; char mct = 0;
int sgnd = 0;
Py_ssize_t fd = -1; Py_ssize_t fd = -1;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, args,
"ss|OOOsOnOOOssbn", "ss|OOOsOnOOOssbbn",
&mode, &mode,
&format, &format,
&offset, &offset,
@ -1231,6 +1232,7 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
&progression, &progression,
&cinema_mode, &cinema_mode,
&mct, &mct,
&sgnd,
&fd)) { &fd)) {
return NULL; return NULL;
} }
@ -1329,6 +1331,7 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
context->progression = prog_order; context->progression = prog_order;
context->cinema_mode = cine_mode; context->cinema_mode = cine_mode;
context->mct = mct; context->mct = mct;
context->sgnd = sgnd;
return (PyObject *)encoder; return (PyObject *)encoder;
} }

View File

@ -85,6 +85,9 @@ typedef struct {
/* Set multiple component transformation */ /* Set multiple component transformation */
char mct; char mct;
/* Signed */
int sgnd;
/* Progression order (LRCP/RLCP/RPCL/PCRL/CPRL) */ /* Progression order (LRCP/RLCP/RPCL/PCRL/CPRL) */
OPJ_PROG_ORDER progression; OPJ_PROG_ORDER progression;

View File

@ -343,7 +343,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state) {
image_params[n].x0 = image_params[n].y0 = 0; image_params[n].x0 = image_params[n].y0 = 0;
image_params[n].prec = prec; image_params[n].prec = prec;
image_params[n].bpp = bpp; image_params[n].bpp = bpp;
image_params[n].sgnd = 0; image_params[n].sgnd = context->sgnd == 0 ? 0 : 1;
} }
image = opj_image_create(components, image_params, color_space); image = opj_image_create(components, image_params, color_space);