From 598d97daffe27d1fdc20a79dbac7ff3fa353cfc1 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Thu, 19 Dec 2013 21:38:31 -0800 Subject: [PATCH 1/3] Reorg+add test for #452 --- Tests/test_image_getpixel.py | 72 +++++++++++++++++------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/Tests/test_image_getpixel.py b/Tests/test_image_getpixel.py index 6c5e8b084..104b67097 100644 --- a/Tests/test_image_getpixel.py +++ b/Tests/test_image_getpixel.py @@ -9,49 +9,43 @@ def color(mode): else: return tuple(range(1, bands+1)) -def test_pixel(): - def pixel(mode): + +def check(mode, c=None): + if not c: c = color(mode) - im = Image.new(mode, (1, 1), None) - im.putpixel((0, 0), c) - return im.getpixel((0, 0)) + + #check putpixel + im = Image.new(mode, (1, 1), None) + im.putpixel((0, 0), c) + assert_equal(im.getpixel((0, 0)), c, + "put/getpixel roundtrip failed for mode %s, color %s" % + (mode, c)) + + # check inital color + im = Image.new(mode, (1, 1), c) + assert_equal(im.getpixel((0, 0)), c, + "initial color failed for mode %s, color %s " % + (mode, color)) - assert_equal(pixel("1"), 1) - assert_equal(pixel("L"), 1) - assert_equal(pixel("LA"), (1, 2)) - assert_equal(pixel("I"), 1) - assert_equal(pixel("I;16"), 1) - assert_equal(pixel("I;16B"), 1) - assert_equal(pixel("F"), 1.0) - assert_equal(pixel("P"), 1) - assert_equal(pixel("PA"), (1, 2)) - assert_equal(pixel("RGB"), (1, 2, 3)) - assert_equal(pixel("RGBA"), (1, 2, 3, 4)) - assert_equal(pixel("RGBX"), (1, 2, 3, 4)) - assert_equal(pixel("CMYK"), (1, 2, 3, 4)) - assert_equal(pixel("YCbCr"), (1, 2, 3)) +def test_basic(): + for mode in ("1", "L", "LA", "I", "I;16", "I;16B", "F", + "P", "PA", "RGB", "RGBA", "RGBX", "CMYK","YCbCr"): + check(mode) -def test_image(): - - def pixel(mode): - im = Image.new(mode, (1, 1), color(mode)) - return im.getpixel((0, 0)) - - assert_equal(pixel("1"), 1) - assert_equal(pixel("L"), 1) - assert_equal(pixel("LA"), (1, 2)) - assert_equal(pixel("I"), 1) - assert_equal(pixel("I;16"), 1) - assert_equal(pixel("I;16B"), 1) - assert_equal(pixel("F"), 1.0) - assert_equal(pixel("P"), 1) - assert_equal(pixel("PA"), (1, 2)) - assert_equal(pixel("RGB"), (1, 2, 3)) - assert_equal(pixel("RGBA"), (1, 2, 3, 4)) - assert_equal(pixel("RGBX"), (1, 2, 3, 4)) - assert_equal(pixel("CMYK"), (1, 2, 3, 4)) - assert_equal(pixel("YCbCr"), (1, 2, 3)) +def test_signedness(): + # see https://github.com/python-imaging/Pillow/issues/452 + # pixelaccess is using signed int* instead of uint* + for mode in ("I;16", "I;16B"): + check(mode, 2**15-1) + check(mode, 2**15) + check(mode, 2**15+1) + check(mode, 2**16-1) + check("I", 2**31-1) + check("I", 2**31) + check("I", 2**31+1) + check("I", 2**32-1) + From 77c36d6edcf9c24280e978fffb899a29e04f0dd0 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Thu, 19 Dec 2013 21:39:18 -0800 Subject: [PATCH 2/3] Using uint* for pixel access in mode I;16 and I;32, fixes #452 --- _imaging.c | 8 ++++---- libImaging/Access.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_imaging.c b/_imaging.c index dcb063081..0cce74ce0 100644 --- a/_imaging.c +++ b/_imaging.c @@ -463,14 +463,14 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) { union { UINT8 b[4]; - INT16 h; - INT32 i; + UINT16 h; + UINT32 i; FLOAT32 f; } pixel; if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return NULL; + PyErr_SetString(PyExc_IndexError, outside_image); + return NULL; } access->get_pixel(im, x, y, &pixel); diff --git a/libImaging/Access.c b/libImaging/Access.c index 70eb1af4c..82a4d5297 100644 --- a/libImaging/Access.c +++ b/libImaging/Access.c @@ -94,11 +94,11 @@ static void get_pixel_16L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x+x]; - INT16* out = color; + UINT16* out = color; #ifdef WORDS_BIGENDIAN out[0] = in[0] + (in[1]<<8); #else - out[0] = *(INT16*) in; + out[0] = *(UINT16*) in; #endif } @@ -106,9 +106,9 @@ static void get_pixel_16B(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x+x]; - INT16* out = color; + UINT16* out = color; #ifdef WORDS_BIGENDIAN - out[0] = *(INT16*) in; + out[0] = *(UINT16*) in; #else out[0] = in[1] + (in[0]<<8); #endif @@ -125,11 +125,11 @@ static void get_pixel_32L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; + UINT32* out = color; #ifdef WORDS_BIGENDIAN out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); #else - out[0] = *(INT32*) in; + out[0] = *(UINT32*) in; #endif } @@ -137,9 +137,9 @@ static void get_pixel_32B(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; + UINT32* out = color; #ifdef WORDS_BIGENDIAN - out[0] = *(INT32*) in; + out[0] = *(UINT32*) in; #else out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); #endif From 1dd80b26250206b8d5f00e91b3e24bda2570b745 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Mon, 30 Dec 2013 21:00:32 -0800 Subject: [PATCH 3/3] reverted int32 changes --- Tests/test_image_getpixel.py | 4 ---- _imaging.c | 2 +- libImaging/Access.c | 8 ++++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Tests/test_image_getpixel.py b/Tests/test_image_getpixel.py index 104b67097..0acfd6698 100644 --- a/Tests/test_image_getpixel.py +++ b/Tests/test_image_getpixel.py @@ -42,10 +42,6 @@ def test_signedness(): check(mode, 2**15+1) check(mode, 2**16-1) - check("I", 2**31-1) - check("I", 2**31) - check("I", 2**31+1) - check("I", 2**32-1) diff --git a/_imaging.c b/_imaging.c index 0cce74ce0..3511de4cf 100644 --- a/_imaging.c +++ b/_imaging.c @@ -464,7 +464,7 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) union { UINT8 b[4]; UINT16 h; - UINT32 i; + INT32 i; FLOAT32 f; } pixel; diff --git a/libImaging/Access.c b/libImaging/Access.c index 82a4d5297..62c97f3a3 100644 --- a/libImaging/Access.c +++ b/libImaging/Access.c @@ -125,11 +125,11 @@ static void get_pixel_32L(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - UINT32* out = color; + INT32* out = color; #ifdef WORDS_BIGENDIAN out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); #else - out[0] = *(UINT32*) in; + out[0] = *(INT32*) in; #endif } @@ -137,9 +137,9 @@ static void get_pixel_32B(Imaging im, int x, int y, void* color) { UINT8* in = (UINT8*) &im->image[y][x*4]; - UINT32* out = color; + INT32* out = color; #ifdef WORDS_BIGENDIAN - out[0] = *(UINT32*) in; + out[0] = *(INT32*) in; #else out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); #endif