Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/ModeFilter.c
blob: b3a904513068fac181dbc9dd8f1d3c02490725af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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;
}