From 08816f43ae621830cd4cf9dc1fecfbae63e5cc60 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 26 Dec 2022 15:46:14 +1100 Subject: [PATCH] Added support for I;16 modes in putdata() --- Tests/test_image_putdata.py | 5 +++-- src/_imaging.c | 28 ++++++++++++---------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Tests/test_image_putdata.py b/Tests/test_image_putdata.py index 3d60e52a294..0e6293349bc 100644 --- a/Tests/test_image_putdata.py +++ b/Tests/test_image_putdata.py @@ -55,10 +55,11 @@ def test_mode_with_L_with_float(): assert im.getpixel((0, 0)) == 2 -def test_mode_i(): +@pytest.mark.parametrize("mode", ("I", "I;16", "I;16L", "I;16B")) +def test_mode_i(mode): src = hopper("L") data = list(src.getdata()) - im = Image.new("I", src.size, 0) + im = Image.new(mode, src.size, 0) im.putdata(data, 2, 256) target = [2 * elt + 256 for elt in data] diff --git a/src/_imaging.c b/src/_imaging.c index 940b5fbb39d..05e1370f6e3 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -1531,25 +1531,21 @@ if (PySequence_Check(op)) { \ PyErr_SetString(PyExc_TypeError, must_be_sequence); return NULL; } + int endian = strncmp(image->mode, "I;16", 4) == 0 ? (strcmp(image->mode, "I;16B") == 0 ? 2 : 1) : 0; double value; - if (scale == 1.0 && offset == 0.0) { - /* Clipped data */ - for (i = x = y = 0; i < n; i++) { - set_value_to_item(seq, i); + for (i = x = y = 0; i < n; i++) { + set_value_to_item(seq, i); + if (scale != 1.0 || offset != 0.0) { + value = value * scale + offset; + } + if (endian == 0) { image->image8[y][x] = (UINT8)CLIP8(value); - if (++x >= (int)image->xsize) { - x = 0, y++; - } + } else { + image->image8[y][x * 2 + (endian == 2 ? 1 : 0)] = CLIP8((int)value % 256); + image->image8[y][x * 2 + (endian == 2 ? 0 : 1)] = CLIP8((int)value >> 8); } - - } else { - /* Scaled and clipped data */ - for (i = x = y = 0; i < n; i++) { - set_value_to_item(seq, i); - image->image8[y][x] = CLIP8(value * scale + offset); - if (++x >= (int)image->xsize) { - x = 0, y++; - } + if (++x >= (int)image->xsize) { + x = 0, y++; } } PyErr_Clear(); /* Avoid weird exceptions */