2010-07-31 06:52:47 +04:00
|
|
|
/*
|
|
|
|
* The Python Imaging Library
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* 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];
|
|
|
|
|
2020-05-10 12:56:36 +03:00
|
|
|
if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) {
|
2017-08-17 03:23:13 +03:00
|
|
|
return (Imaging) ImagingError_ModeError();
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
|
2017-08-17 03:23:13 +03:00
|
|
|
imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize);
|
2020-05-10 12:56:36 +03:00
|
|
|
if (!imOut) {
|
2017-08-17 03:23:13 +03:00
|
|
|
return NULL;
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
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));
|
2020-05-10 12:56:36 +03:00
|
|
|
for (yy = y - size; yy <= y + size; yy++) {
|
2010-07-31 06:52:47 +04:00
|
|
|
if (yy >= 0 && yy < imOut->ysize) {
|
|
|
|
UINT8* in = &IMAGING_PIXEL_L(im, 0, yy);
|
2020-05-10 12:56:36 +03:00
|
|
|
for (xx = x - size; xx <= x + size; xx++) {
|
|
|
|
if (xx >= 0 && xx < imOut->xsize) {
|
2010-07-31 06:52:47 +04:00
|
|
|
histogram[in[xx]]++;
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
}
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* find most frequent pixel value in this region */
|
|
|
|
maxpixel = 0;
|
|
|
|
maxcount = histogram[maxpixel];
|
2020-05-10 12:56:36 +03:00
|
|
|
for (i = 1; i < 256; i++) {
|
2010-07-31 06:52:47 +04:00
|
|
|
if (histogram[i] > maxcount) {
|
|
|
|
maxcount = histogram[i];
|
|
|
|
maxpixel = (UINT8) i;
|
|
|
|
}
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
|
2020-05-10 12:56:36 +03:00
|
|
|
if (maxcount > 2) {
|
2010-07-31 06:52:47 +04:00
|
|
|
out[x] = maxpixel;
|
2020-05-10 12:56:36 +03:00
|
|
|
} else {
|
2010-07-31 06:52:47 +04:00
|
|
|
out[x] = IMAGING_PIXEL_L(im, x, y);
|
2020-05-10 12:56:36 +03:00
|
|
|
}
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
}
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
}
|
|
|
|
|
2017-09-19 20:42:13 +03:00
|
|
|
ImagingCopyPalette(imOut, im);
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
return imOut;
|
|
|
|
}
|