diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index 4079d935800..027af5d56fa 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -275,15 +275,10 @@ def test_get_vs_c(self): # self._test_get_access(hopper('PA')) # PA -- how do I make a PA image? self._test_get_access(hopper("F")) - im = Image.new("I;16", (10, 10), 40000) - self._test_get_access(im) - im = Image.new("I;16L", (10, 10), 40000) - self._test_get_access(im) - im = Image.new("I;16B", (10, 10), 40000) - self._test_get_access(im) - - im = Image.new("I", (10, 10), 40000) - self._test_get_access(im) + for mode in ("I;16", "I;16L", "I;16B", "I;16N", "I"): + im = Image.new(mode, (10, 10), 40000) + self._test_get_access(im) + # These don't actually appear to be modes that I can actually make, # as unpack sets them directly into the I mode. # im = Image.new('I;32L', (10, 10), -2**10) @@ -322,15 +317,10 @@ def test_set_vs_c(self): # self._test_set_access(i, (128, 128)) #PA -- undone how to make self._test_set_access(hopper("F"), 1024.0) - im = Image.new("I;16", (10, 10), 40000) - self._test_set_access(im, 45000) - im = Image.new("I;16L", (10, 10), 40000) - self._test_set_access(im, 45000) - im = Image.new("I;16B", (10, 10), 40000) - self._test_set_access(im, 45000) + for mode in ("I;16", "I;16L", "I;16B", "I;16N", "I"): + im = Image.new(mode, (10, 10), 40000) + self._test_set_access(im, 45000) - im = Image.new("I", (10, 10), 40000) - self._test_set_access(im, 45000) # im = Image.new('I;32L', (10, 10), -(2**10)) # self._test_set_access(im, -(2**13)+1) # im = Image.new('I;32B', (10, 10), 2**10) diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py index 979806cae99..de3e7d1569b 100644 --- a/Tests/test_lib_pack.py +++ b/Tests/test_lib_pack.py @@ -207,6 +207,9 @@ def test_I(self): 0x01000083, ) + def test_I16(self): + self.assert_pack("I;16N", "I;16N", 2, 0x0201, 0x0403, 0x0605) + def test_F_float(self): self.assert_pack("F", "F;32F", 4, 1.539989614439558e-36, 4.063216068939723e-34) @@ -761,10 +764,12 @@ def test_I16(self): self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605) + self.assert_unpack("I;16N", "I;16N", 2, 0x0201, 0x0403, 0x0605) else: self.assert_unpack("I;16", "I;16N", 2, 0x0102, 0x0304, 0x0506) self.assert_unpack("I;16B", "I;16N", 2, 0x0102, 0x0304, 0x0506) self.assert_unpack("I;16L", "I;16N", 2, 0x0102, 0x0304, 0x0506) + self.assert_unpack("I;16N", "I;16N", 2, 0x0102, 0x0304, 0x0506) def test_CMYK16(self): self.assert_unpack("CMYK", "CMYK;16L", 8, (2, 4, 6, 8), (10, 12, 14, 16)) diff --git a/Tests/test_mode_i16.py b/Tests/test_mode_i16.py index dcdee3d416d..1786dba3847 100644 --- a/Tests/test_mode_i16.py +++ b/Tests/test_mode_i16.py @@ -88,10 +88,7 @@ def tobytes(mode): def test_convert(): im = original.copy() - verify(im.convert("I;16")) - verify(im.convert("I;16").convert("L")) - verify(im.convert("I;16").convert("I")) - - verify(im.convert("I;16B")) - verify(im.convert("I;16B").convert("L")) - verify(im.convert("I;16B").convert("I")) + for mode in ("I;16", "I;16B", "I;16N"): + verify(im.convert(mode)) + verify(im.convert(mode).convert("L")) + verify(im.convert(mode).convert("I")) diff --git a/docs/releasenotes/9.5.0.rst b/docs/releasenotes/9.5.0.rst index bd6e586932a..13c99313a22 100644 --- a/docs/releasenotes/9.5.0.rst +++ b/docs/releasenotes/9.5.0.rst @@ -63,3 +63,10 @@ Added support for saving PDFs in RGBA mode ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Using the JPXDecode filter, PDFs can now be saved in RGBA mode. + + +Improved I;16N support +^^^^^^^^^^^^^^^^^^^^^^ + +Support has been added for I;16N access, packing and unpacking. Conversion to +and from L mode has also been added. diff --git a/src/PIL/PyAccess.py b/src/PIL/PyAccess.py index e9cb34ceda1..39747b4f311 100644 --- a/src/PIL/PyAccess.py +++ b/src/PIL/PyAccess.py @@ -320,6 +320,7 @@ def set_pixel(self, x, y, color): "1": _PyAccess8, "L": _PyAccess8, "P": _PyAccess8, + "I;16N": _PyAccessI16_N, "LA": _PyAccess32_2, "La": _PyAccess32_2, "PA": _PyAccess32_2, diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c index 83860c38a7e..f00939da0b3 100644 --- a/src/libImaging/Access.c +++ b/src/libImaging/Access.c @@ -13,7 +13,7 @@ /* use make_hash.py from the pillow-scripts repository to calculate these values */ #define ACCESS_TABLE_SIZE 27 -#define ACCESS_TABLE_HASH 3078 +#define ACCESS_TABLE_HASH 33051 static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE]; @@ -92,6 +92,12 @@ get_pixel_16B(Imaging im, int x, int y, void *color) { #endif } +static void +get_pixel_16(Imaging im, int x, int y, void *color) { + UINT8 *in = (UINT8 *)&im->image[y][x + x]; + memcpy(color, in, sizeof(UINT16)); +} + static void get_pixel_32(Imaging im, int x, int y, void *color) { memcpy(color, &im->image32[y][x], sizeof(INT32)); @@ -186,6 +192,7 @@ ImagingAccessInit() { ADD("I;16", get_pixel_16L, put_pixel_16L); ADD("I;16L", get_pixel_16L, put_pixel_16L); ADD("I;16B", get_pixel_16B, put_pixel_16B); + ADD("I;16N", get_pixel_16, put_pixel_16L); ADD("I;32L", get_pixel_32L, put_pixel_32L); ADD("I;32B", get_pixel_32B, put_pixel_32B); ADD("F", get_pixel_32, put_pixel_32); diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index b03bd02af2b..7fe24a63939 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -990,6 +990,13 @@ static struct { {"I;16L", "L", I16L_L}, {"L", "I;16B", L_I16B}, {"I;16B", "L", I16B_L}, +#ifdef WORDS_BIGENDIAN + {"L", "I;16N", L_I16B}, + {"I;16N", "L", I16B_L}, +#else + {"L", "I;16N", L_I16L}, + {"I;16N", "L", I16L_L}, +#endif {"I;16", "F", I16L_F}, {"I;16L", "F", I16L_F}, diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c index 01760e742be..14c8f1461aa 100644 --- a/src/libImaging/Pack.c +++ b/src/libImaging/Pack.c @@ -664,6 +664,7 @@ static struct { #endif {"I;16B", "I;16B", 16, copy2}, {"I;16L", "I;16L", 16, copy2}, + {"I;16N", "I;16N", 16, copy2}, {"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian. {"I;16L", "I;16N", 16, packI16N_I16}, {"I;16B", "I;16N", 16, packI16N_I16B}, diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c index e426ed74fce..7eeadf944ea 100644 --- a/src/libImaging/Unpack.c +++ b/src/libImaging/Unpack.c @@ -1762,6 +1762,7 @@ static struct { {"I;16", "I;16", 16, copy2}, {"I;16B", "I;16B", 16, copy2}, {"I;16L", "I;16L", 16, copy2}, + {"I;16N", "I;16N", 16, copy2}, {"I;16", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian. {"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.