diff --git a/Tests/test_image_resample.py b/Tests/test_image_resample.py index 3c8afd8ea..bd763addb 100644 --- a/Tests/test_image_resample.py +++ b/Tests/test_image_resample.py @@ -336,6 +336,17 @@ class CoreResampleCoefficientsTest(PillowTestCase): self.assertEqual(test_color // 2, px[2, 0]) # print '\r>', size, test_color // 2, px[2, 0] + def test_nonzero_coefficients(self): + # regression test for the wrong coefficients calculation + # due to bug https://github.com/python-pillow/Pillow/issues/2161 + im = Image.new('RGBA', (1280, 1280), (0x20, 0x40, 0x60, 0xff)) + histogram = im.resize((256, 256), Image.BICUBIC).histogram() + + self.assertEqual(histogram[0x100 * 0 + 0x20], 0x10000) # first channel + self.assertEqual(histogram[0x100 * 1 + 0x40], 0x10000) # second channel + self.assertEqual(histogram[0x100 * 2 + 0x60], 0x10000) # third channel + self.assertEqual(histogram[0x100 * 3 + 0xff], 0x10000) # fourth channel + if __name__ == '__main__': unittest.main() diff --git a/libImaging/Resample.c b/libImaging/Resample.c index 5f202bc3f..770f5f611 100644 --- a/libImaging/Resample.c +++ b/libImaging/Resample.c @@ -176,18 +176,23 @@ precompute_coeffs(int inSize, int outSize, struct filter *filterp, k = &kk[xx * kmax]; for (x = 0; x < xmax; x++) { double w = filterp->filter((x + xmin - center + 0.5) * ss); + k[x] = w; + ww += w; + + // We can skip extreme coefficients if they are zeroes. if (w == 0) { + // Skip from the start. if (x == 0) { + // At next loop `x` will be 0. x -= 1; + // But `w` will not be 0, because it based on `xmin`. xmin += 1; xmax -= 1; } else if (x == xmax - 1) { + // Truncate the last coefficient for current `xx`. xmax -= 1; } - continue; } - k[x] = w; - ww += w; } for (x = 0; x < xmax; x++) { if (ww != 0.0)