diff --git a/PIL/ImageOps.py b/PIL/ImageOps.py index fec77620a..30377dc62 100644 --- a/PIL/ImageOps.py +++ b/PIL/ImageOps.py @@ -446,14 +446,16 @@ usm = unsharp_mask def box_blur(image, radius): """ - Apply box blur to given image. Box blur is operation where - each pixel becomes the average value of pixels in given radius. - Supports float radius and very large ones. Fast implementation, - works in linear time relative to the radius. + Blur the image by setting each pixel to the average value of the pixels + in a square box extending radius pixels in each direction. + Supports float radius of arbitrary size. Uses an optimized implementation + which runs in linear time relative to the size of the image + for any radius value. :param image: The image to blur. :param radius: Size of the box in one direction. Radius 0 does not blur, - radius 1 takes 1 pixel in all directions, i.e. 9 pixels in total. + returns an identical image. Radius 1 takes 1 pixel + in each direction, i.e. 9 pixels in total. :return: An image. """ image.load() diff --git a/_imaging.c b/_imaging.c index 75a72465d..dfb0fd46e 100644 --- a/_imaging.c +++ b/_imaging.c @@ -872,7 +872,7 @@ _gaussian_blur(ImagingObject* self, PyObject* args) if (!imOut) return NULL; - if ( ! ImagingGaussianBlur(imOut, imIn, radius, passes)) + if (!ImagingGaussianBlur(imOut, imIn, radius, passes)) return NULL; return PyImagingNew(imOut); @@ -1797,7 +1797,7 @@ _unsharp_mask(ImagingObject* self, PyObject* args) if (!imOut) return NULL; - if ( ! ImagingUnsharpMask(imOut, imIn, radius, percent, threshold)) + if (!ImagingUnsharpMask(imOut, imIn, radius, percent, threshold)) return NULL; return PyImagingNew(imOut); diff --git a/libImaging/BoxBlur.c b/libImaging/BoxBlur.c index 64d4fd430..a85c5eadc 100644 --- a/libImaging/BoxBlur.c +++ b/libImaging/BoxBlur.c @@ -16,11 +16,11 @@ LineBoxBlur32(pixel *line, UINT32 *lineOut, int lastx, int radius, int edgeA, UINT32 acc[4]; UINT32 bulk[4]; - #define MOVE_ACC(acc, substract, add) \ - acc[0] += line[add][0] - line[substract][0]; \ - acc[1] += line[add][1] - line[substract][1]; \ - acc[2] += line[add][2] - line[substract][2]; \ - acc[3] += line[add][3] - line[substract][3]; + #define MOVE_ACC(acc, subtract, add) \ + acc[0] += line[add][0] - line[subtract][0]; \ + acc[1] += line[add][1] - line[subtract][1]; \ + acc[2] += line[add][2] - line[subtract][2]; \ + acc[3] += line[add][3] - line[subtract][3]; #define ADD_FAR(bulk, acc, left, right) \ bulk[0] = (acc[0] * ww) + (line[left][0] + line[right][0]) * fw; \ @@ -28,9 +28,9 @@ LineBoxBlur32(pixel *line, UINT32 *lineOut, int lastx, int radius, int edgeA, bulk[2] = (acc[2] * ww) + (line[left][2] + line[right][2]) * fw; \ bulk[3] = (acc[3] * ww) + (line[left][3] + line[right][3]) * fw; - #define SAVE(acc) \ - (UINT8)((acc[0] + (1 << 23)) >> 24) << 0 | (UINT8)((acc[1] + (1 << 23)) >> 24) << 8 | \ - (UINT8)((acc[2] + (1 << 23)) >> 24) << 16 | (UINT8)((acc[3] + (1 << 23)) >> 24) << 24 + #define SAVE(bulk) \ + (UINT8)((bulk[0] + (1 << 23)) >> 24) << 0 | (UINT8)((bulk[1] + (1 << 23)) >> 24) << 8 | \ + (UINT8)((bulk[2] + (1 << 23)) >> 24) << 16 | (UINT8)((bulk[3] + (1 << 23)) >> 24) << 24 /* Compute acc for -1 pixel (outside of image): From "-radius-1" to "-1" get first pixel, @@ -54,21 +54,21 @@ LineBoxBlur32(pixel *line, UINT32 *lineOut, int lastx, int radius, int edgeA, if (edgeA <= edgeB) { - /* Substract pixel from left ("0"). + /* Subtract pixel from left ("0"). Add pixels from radius. */ for (x = 0; x < edgeA; x++) { MOVE_ACC(acc, 0, x + radius); ADD_FAR(bulk, acc, 0, x + radius + 1); lineOut[x] = SAVE(bulk); } - /* Substract previous pixel from "-radius". + /* Subtract previous pixel from "-radius". Add pixels from radius. */ for (x = edgeA; x < edgeB; x++) { MOVE_ACC(acc, x - radius - 1, x + radius); ADD_FAR(bulk, acc, x - radius - 1, x + radius + 1); lineOut[x] = SAVE(bulk); } - /* Substract previous pixel from "-radius". + /* Subtract previous pixel from "-radius". Add last pixel. */ for (x = edgeB; x <= lastx; x++) { MOVE_ACC(acc, x - radius - 1, lastx); @@ -109,14 +109,14 @@ LineBoxBlur8(UINT8 *line, UINT8 *lineOut, int lastx, int radius, int edgeA, UINT32 acc; UINT32 bulk; - #define MOVE_ACC(acc, substract, add) \ - acc += line[add] - line[substract]; + #define MOVE_ACC(acc, subtract, add) \ + acc += line[add] - line[subtract]; #define ADD_FAR(bulk, acc, left, right) \ bulk = (acc * ww) + (line[left] + line[right]) * fw; - #define SAVE(acc) \ - (UINT8)((acc + (1 << 23)) >> 24) + #define SAVE(bulk) \ + (UINT8)((bulk + (1 << 23)) >> 24) acc = line[0] * (radius + 1); for (x = 0; x < edgeA - 1; x++) { @@ -252,17 +252,17 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n) if (imIn->type != IMAGING_TYPE_UINT8) return ImagingError_ModeError(); - if ( ! (strcmp(imIn->mode, "RGB") == 0 || - strcmp(imIn->mode, "RGBA") == 0 || - strcmp(imIn->mode, "RGBX") == 0 || - strcmp(imIn->mode, "CMYK") == 0 || - strcmp(imIn->mode, "L") == 0 || - strcmp(imIn->mode, "LA") == 0)) + if (!(strcmp(imIn->mode, "RGB") == 0 || + strcmp(imIn->mode, "RGBA") == 0 || + strcmp(imIn->mode, "RGBX") == 0 || + strcmp(imIn->mode, "CMYK") == 0 || + strcmp(imIn->mode, "L") == 0 || + strcmp(imIn->mode, "LA") == 0)) return ImagingError_ModeError(); /* Create transposed temp image (imIn->ysize x imIn->xsize). */ Imaging temp = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); - if ( ! temp) + if (!temp) return NULL; /* Apply one-dimensional blur.