diff options
Diffstat (limited to 'Imaging/libImaging/ModeFilter.c')
-rw-r--r-- | Imaging/libImaging/ModeFilter.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/Imaging/libImaging/ModeFilter.c b/Imaging/libImaging/ModeFilter.c new file mode 100644 index 0000000..b3a9045 --- /dev/null +++ b/Imaging/libImaging/ModeFilter.c @@ -0,0 +1,78 @@ +/* + * The Python Imaging Library + * $Id: ModeFilter.c 2134 2004-10-06 08:55:20Z fredrik $ + * + * mode filter + * + * history: + * 2002-06-08 fl Created (based on code from IFUNC95) + * 2004-10-05 fl Rewritten; use a simpler brute-force algorithm + * + * Copyright (c) Secret Labs AB 2002-2004. All rights reserved. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +Imaging +ImagingModeFilter(Imaging im, int size) +{ + Imaging imOut; + int x, y, i; + int xx, yy; + int maxcount; + UINT8 maxpixel; + int histogram[256]; + + if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) + return (Imaging) ImagingError_ModeError(); + + imOut = ImagingNew(im->mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + size = size / 2; + + for (y = 0; y < imOut->ysize; y++) { + UINT8* out = &IMAGING_PIXEL_L(imOut, 0, y); + for (x = 0; x < imOut->xsize; x++) { + + /* calculate histogram over current area */ + + /* FIXME: brute force! to improve, update the histogram + incrementally. may also add a "frequent list", like in + the old implementation, but I'm not sure that's worth + the added complexity... */ + + memset(histogram, 0, sizeof(histogram)); + for (yy = y - size; yy <= y + size; yy++) + if (yy >= 0 && yy < imOut->ysize) { + UINT8* in = &IMAGING_PIXEL_L(im, 0, yy); + for (xx = x - size; xx <= x + size; xx++) + if (xx >= 0 && xx < imOut->xsize) + histogram[in[xx]]++; + } + + /* find most frequent pixel value in this region */ + maxpixel = 0; + maxcount = histogram[maxpixel]; + for (i = 1; i < 256; i++) + if (histogram[i] > maxcount) { + maxcount = histogram[i]; + maxpixel = (UINT8) i; + } + + if (maxcount > 2) + out[x] = maxpixel; + else + out[x] = IMAGING_PIXEL_L(im, x, y); + + } + + } + + ImagingCopyInfo(imOut, im); + + return imOut; +} |