From 3230270aa772ba7f7d6c3c763fc4a556e089a2bd Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 26 Jul 2023 12:25:54 +1000 Subject: [PATCH] Added BGR;15, BGR;16 and BGR;24 access --- Tests/test_image_access.py | 10 +++++++++ src/_imaging.c | 6 ++++-- src/libImaging/Access.c | 42 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index c9db3aee730..0851681ffa2 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -130,9 +130,16 @@ def color(mode): bands = Image.getmodebands(mode) if bands == 1: return 1 + if mode in ("BGR;15", "BGR;16"): + # These modes have less than 8 bits per band + # So (1, 2, 3) cannot be roundtripped + return (16, 32, 49) return tuple(range(1, bands + 1)) def check(self, mode, expected_color=None): + if self._need_cffi_access and mode.startswith("BGR;"): + pytest.skip("Support not added to deprecated module for BGR;* modes") + if not expected_color: expected_color = self.color(mode) @@ -203,6 +210,9 @@ def check(self, mode, expected_color=None): "F", "P", "PA", + "BGR;15", + "BGR;16", + "BGR;24", "RGB", "RGBA", "RGBX", diff --git a/src/_imaging.c b/src/_imaging.c index e15cb89fcea..c331669a74a 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -475,8 +475,10 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) { case IMAGING_TYPE_FLOAT32: return PyFloat_FromDouble(pixel.f); case IMAGING_TYPE_SPECIAL: - if (strncmp(im->mode, "I;16", 4) == 0) { + if (im->bands == 1) { return PyLong_FromLong(pixel.h); + } else { + return Py_BuildValue("BBB", pixel.b[0], pixel.b[1], pixel.b[2]); } break; } @@ -599,7 +601,7 @@ getink(PyObject *color, Imaging im, char *ink) { } else if (tupleSize != 3) { PyErr_SetString(PyExc_TypeError, "color must be int, or tuple of one or three elements"); return NULL; - } else if (!PyArg_ParseTuple(color, "Lii", &r, &g, &b)) { + } else if (!PyArg_ParseTuple(color, "iiL", &b, &g, &r)) { return NULL; } if (!strcmp(im->mode, "BGR;15")) { diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c index dd0418696fe..091c84e18fa 100644 --- a/src/libImaging/Access.c +++ b/src/libImaging/Access.c @@ -12,8 +12,8 @@ #include "Imaging.h" /* use make_hash.py from the pillow-scripts repository to calculate these values */ -#define ACCESS_TABLE_SIZE 27 -#define ACCESS_TABLE_HASH 33051 +#define ACCESS_TABLE_SIZE 35 +#define ACCESS_TABLE_HASH 8940 static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE]; @@ -87,6 +87,31 @@ get_pixel_16(Imaging im, int x, int y, void *color) { memcpy(color, in, sizeof(UINT16)); } +static void +get_pixel_BGR15(Imaging im, int x, int y, void *color) { + UINT8 *in = (UINT8 *)&im->image8[y][x * 2]; + UINT16 pixel = in[0] + (in[1] << 8); + char *out = color; + out[0] = (pixel & 31) * 255 / 31; + out[1] = ((pixel >> 5) & 31) * 255 / 31; + out[2] = ((pixel >> 10) & 31) * 255 / 31; +} + +static void +get_pixel_BGR16(Imaging im, int x, int y, void *color) { + UINT8 *in = (UINT8 *)&im->image8[y][x * 2]; + UINT16 pixel = in[0] + (in[1] << 8); + char *out = color; + out[0] = (pixel & 31) * 255 / 31; + out[1] = ((pixel >> 5) & 63) * 255 / 63; + out[2] = ((pixel >> 11) & 31) * 255 / 31; +} + +static void +get_pixel_BGR24(Imaging im, int x, int y, void *color) { + memcpy(color, &im->image8[y][x * 3], sizeof(UINT8) * 3); +} + static void get_pixel_32(Imaging im, int x, int y, void *color) { memcpy(color, &im->image32[y][x], sizeof(INT32)); @@ -134,6 +159,16 @@ put_pixel_16B(Imaging im, int x, int y, const void *color) { out[1] = in[0]; } +static void +put_pixel_BGR1516(Imaging im, int x, int y, const void *color) { + memcpy(&im->image8[y][x * 2], color, 2); +} + +static void +put_pixel_BGR24(Imaging im, int x, int y, const void *color) { + memcpy(&im->image8[y][x * 3], color, 3); +} + static void put_pixel_32L(Imaging im, int x, int y, const void *color) { memcpy(&im->image8[y][x * 4], color, 4); @@ -178,6 +213,9 @@ ImagingAccessInit() { ADD("F", get_pixel_32, put_pixel_32); ADD("P", get_pixel_8, put_pixel_8); ADD("PA", get_pixel_32_2bands, put_pixel_32); + ADD("BGR;15", get_pixel_BGR15, put_pixel_BGR1516); + ADD("BGR;16", get_pixel_BGR16, put_pixel_BGR1516); + ADD("BGR;24", get_pixel_BGR24, put_pixel_BGR24); ADD("RGB", get_pixel_32, put_pixel_32); ADD("RGBA", get_pixel_32, put_pixel_32); ADD("RGBa", get_pixel_32, put_pixel_32);