diff --git a/Tests/test_box_blur.py b/Tests/test_box_blur.py index 391e00a23..841aefcef 100644 --- a/Tests/test_box_blur.py +++ b/Tests/test_box_blur.py @@ -119,3 +119,42 @@ class TestBoxBlur(PillowTestCase): ], delta=1, ) + + def test_radius_bigger_then_half(self): + self.assertImage( + box_blur(sample, 3), + [ + [144, 145, 142, 128, 114, 115, 117], + [148, 145, 137, 122, 109, 111, 112], + [152, 145, 131, 117, 103, 107, 108], + [156, 144, 126, 111, 97, 102, 103], + [160, 144, 121, 106, 92, 98, 99 ], + ], + delta=1, + ) + + def test_radius_bigger_then_width(self): + self.assertImage( + box_blur(sample, 10), + [ + [158, 153, 147, 141, 135, 129, 123], + [159, 153, 147, 141, 136, 130, 124], + [159, 154, 148, 142, 136, 130, 124], + [160, 154, 148, 142, 137, 131, 125], + [160, 155, 149, 143, 137, 131, 125], + ], + delta=0, + ) + + def test_exteme_large_radius(self): + self.assertImage( + box_blur(sample, 600), + [ + [162, 162, 162, 162, 162, 162, 162], + [162, 162, 162, 162, 162, 162, 162], + [162, 162, 162, 162, 162, 162, 162], + [162, 162, 162, 162, 162, 162, 162], + [162, 162, 162, 162, 162, 162, 162], + ], + delta=1, + ) diff --git a/libImaging/BoxBlur.c b/libImaging/BoxBlur.c index 7a3909adb..29b89dc9e 100644 --- a/libImaging/BoxBlur.c +++ b/libImaging/BoxBlur.c @@ -57,12 +57,18 @@ HorizontalBoxBlur32(Imaging im, Imaging imOut, float floatRadius) acc[1] = line[0][1] * (radius + 1); acc[2] = line[0][2] * (radius + 1); acc[3] = line[0][3] * (radius + 1); - for (pix = 0; pix < radius; pix++) { + /* As radius can be bigger than xsize, iterate to edgeA -1. */ + for (pix = 0; pix < edgeA - 1; pix++) { acc[0] += line[pix][0]; acc[1] += line[pix][1]; acc[2] += line[pix][2]; acc[3] += line[pix][3]; } + /* Then multiply remainder to last x. */ + acc[0] += line[lastx][0] * (radius - edgeA + 1); + acc[1] += line[lastx][1] * (radius - edgeA + 1); + acc[2] += line[lastx][2] * (radius - edgeA + 1); + acc[3] += line[lastx][3] * (radius - edgeA + 1); if (edgeA <= edgeB) { @@ -140,9 +146,10 @@ HorizontalBoxBlur8(Imaging im, Imaging imOut, float floatRadius) line = im->image8[y]; acc = line[0] * (radius + 1); - for (pix = 0; pix < radius; pix++) { + for (pix = 0; pix < edgeA - 1; pix++) { acc += line[pix]; } + acc += line[lastx] * (radius - edgeA + 1); if (edgeA <= edgeB) {