diff --git a/Tests/test_color_lut.py b/Tests/test_color_lut.py index 30b8de279..3bfb05f02 100644 --- a/Tests/test_color_lut.py +++ b/Tests/test_color_lut.py @@ -198,7 +198,24 @@ class TestColorLut3DCoreAPI(PillowTestCase): -1, -1, 2, 2, -1, 2, -1, 2, 2, 2, 2, 2, ])).load() + self.assertEqual(transformed[0, 0], (0, 0, 255)) + self.assertEqual(transformed[50, 50], (0, 0, 255)) + self.assertEqual(transformed[255, 0], (0, 255, 255)) + self.assertEqual(transformed[205, 50], (0, 255, 255)) + self.assertEqual(transformed[0, 255], (255, 0, 0)) + self.assertEqual(transformed[50, 205], (255, 0, 0)) + self.assertEqual(transformed[255, 255], (255, 255, 0)) + self.assertEqual(transformed[205, 205], (255, 255, 0)) + transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR, + 3, 2, 2, 2, + [ + -3, -3, -3, 5, -3, -3, + -3, 5, -3, 5, 5, -3, + + -3, -3, 5, 5, -3, 5, + -3, 5, 5, 5, 5, 5, + ])).load() self.assertEqual(transformed[0, 0], (0, 0, 255)) self.assertEqual(transformed[50, 50], (0, 0, 255)) self.assertEqual(transformed[255, 0], (0, 255, 255)) @@ -257,6 +274,11 @@ class TestColorLut3DFilter(PillowTestCase): 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.5, 0.0, 0.0, 0.75, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.25, 0.25, 0.0, 0.5, 0.25, 0.0]) + g = Image.linear_gradient('L') + im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), + g.transpose(Image.ROTATE_180)]) + self.assertEqual(im, im.filter(flt)) + flt = ImageFilter.Color3DLUT.generate(5, channels=4, callback=lambda r, g, b: (b, r, g, (r+g+b) / 2)) self.assertEqual(tuple(flt.size), (5, 5, 5)) diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c index 29a6cce1d..6fae2081d 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -83,7 +83,16 @@ static struct filter LANCZOS = { lanczos_filter, 3.0 }; #define PRECISION_BITS (32 - 8 - 2) -UINT8 _clip8_lookups[1024] = { +/* Handles values form -640 to 639. */ +UINT8 _clip8_lookups[1280] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -147,10 +156,18 @@ UINT8 _clip8_lookups[1024] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }; -UINT8 *clip8_lookups = &_clip8_lookups[512]; +UINT8 *clip8_lookups = &_clip8_lookups[640]; static inline UINT8 clip8(int in) {