source: pwntcha/trunk/src/filters.c @ 392

Last change on this file since 392 was 389, checked in by Sam Hocevar, 18 years ago
  • use OpenCV rather than Imlib2 if both are available.
  • cleaned up the slashdot code.
  • decode phpBB captchas.
  • added filter_contrast.
  • Property svn:keywords set to Id
File size: 8.6 KB
Line 
1/*
2 * filters.c: various image filters
3 * $Id: filters.c 389 2005-01-03 21:48:54Z sam $
4 *
5 * Copyright: (c) 2004 Sam Hocevar <sam@zoy.org>
6 *   This program is free software; you can redistribute it and/or
7 *   modify it under the terms of the Do What The Fuck You Want To
8 *   Public License as published by Banlu Kemiyatorn. See
9 *   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <math.h>
16
17#include "config.h"
18#include "common.h"
19
20/* Our macros */
21#define FACTOR 1
22//#define FONTNAME "share/font.png" // use with FACTOR = 2
23//#define FONTNAME "share/font_dilated.png" // use with FACTOR = 2
24#define FONTNAME "share/font_dilated_half.png" // use with FACTOR = 1
25
26/* Functions */
27void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b)
28{
29    int oldr, oldg, oldb;
30    int nextr, nextg, nextb;
31
32    if(x < 0 || y < 0 || x >= img->width || y >= img->height)
33        return;
34
35    getpixel(img, x, y, &oldr, &oldg, &oldb);
36    setpixel(img, x, y, r, g, b);
37
38    getpixel(img, x + 1, y, &nextr, &nextg, &nextb);
39    if(nextr == oldr && nextg == oldg && nextb == oldb)
40        filter_flood_fill(img, x + 1, y, r, g, b);
41
42    getpixel(img, x - 1, y, &nextr, &nextg, &nextb);
43    if(nextr == oldr && nextg == oldg && nextb == oldb)
44        filter_flood_fill(img, x - 1, y, r, g, b);
45
46    getpixel(img, x, y + 1, &nextr, &nextg, &nextb);
47    if(nextr == oldr && nextg == oldg && nextb == oldb)
48        filter_flood_fill(img, x, y + 1, r, g, b);
49
50    getpixel(img, x, y - 1, &nextr, &nextg, &nextb);
51    if(nextr == oldr && nextg == oldg && nextb == oldb)
52        filter_flood_fill(img, x, y - 1, r, g, b);
53}
54
55struct image *filter_fill_holes(struct image *img)
56{
57    struct image *dst;
58    int x, y;
59    int r, g, b;
60
61    dst = image_new(img->width, img->height);
62
63    for(y = 0; y < img->height; y++)
64        for(x = 0; x < img->width; x++)
65        {
66            getpixel(img, x, y, &r, &g, &b);
67            setpixel(dst, x, y, r, g, b);
68        }
69
70    for(y = 0; y < dst->height; y++)
71        for(x = 2; x < dst->width - 2; x++)
72        {
73            int c1, c2, c3, c4, c5;
74            getpixel(img, x-2, y, &c1, &g, &b);
75            getpixel(img, x-1, y, &c2, &g, &b);
76            getpixel(img, x, y, &c3, &g, &b);
77            getpixel(img, x+1, y, &c4, &g, &b);
78            getpixel(img, x+2, y, &c5, &g, &b);
79            if(c1 < 127 && c2 < 127 && c3 > 128 && c4 < 127)
80                c3 = (c1 + c2 + c4) / 3;
81            else if(c2 < 127 && c3 > 128 && c4 < 127 && c5 < 127)
82                c3 = (c2 + c4 + c5) / 3;
83            setpixel(dst, x, y, c3, c3, c3);
84        }
85
86    for(x = 0; x < dst->width; x++)
87        for(y = 2; y < dst->height - 2; y++)
88        {
89            int c1, c2, c3, c4, c5;
90            getpixel(img, x, y-2, &c1, &g, &b);
91            getpixel(img, x, y-1, &c2, &g, &b);
92            getpixel(img, x, y, &c3, &g, &b);
93            getpixel(img, x, y+1, &c4, &g, &b);
94            getpixel(img, x, y+2, &c5, &g, &b);
95            if(c1 < 127 && c2 < 127 && c3 > 128 && c4 < 127)
96                c3 = (c1 + c2 + c4) / 3;
97            else if(c2 < 127 && c3 > 128 && c4 < 127 && c5 < 127)
98                c3 = (c2 + c4 + c5) / 3;
99            setpixel(dst, x, y, c3, c3, c3);
100        }
101
102    return dst;
103}
104
105struct image *filter_detect_lines(struct image *img)
106{
107    struct image *dst;
108    int x, y;
109    int r, ra, rb, g, b;
110
111    dst = image_new(img->width, img->height);
112
113    /* Remove white lines */
114    for(y = 0; y < img->height; y++)
115        for(x = 0; x < img->width; x++)
116        {
117            getpixel(img, x, y, &r, &g, &b);
118            setpixel(dst, x, y, r, g, b);
119            if(y > 0 && y < img->height - 1)
120            {
121                getpixel(img, x, y - 1, &ra, &g, &b);
122                getpixel(img, x, y + 1, &rb, &g, &b);
123                if(r > ra && (r - ra) * (r - rb) > 5000)
124                    setpixel(dst, x, y, ra, ra, ra);
125            }
126        }
127
128    /* Remove black lines */
129    for(y = 0; y < img->height; y++)
130        for(x = 0; x < img->width; x++)
131        {
132            getpixel(dst, x, y, &r, &g, &b);
133            if(y > 0 && y < img->height - 1)
134            {
135                getpixel(img, x, y - 1, &ra, &g, &b);
136                getpixel(img, x, y + 1, &rb, &g, &b);
137                if(r < ra && (r - ra) * (r - rb) > 500)
138                    setpixel(dst, x, y, ra, ra, ra);
139            }
140        }
141
142    return dst;
143}
144
145struct image *filter_equalize(struct image *img, int threshold)
146{
147    struct image *dst;
148    int x, y;
149    int r, g, b;
150
151    dst = image_new(img->width, img->height);
152
153    for(y = 0; y < img->height; y++)
154        for(x = 0; x < img->width; x++)
155        {
156            getpixel(img, x, y, &r, &g, &b);
157            if(r < threshold) r = 0; else r = 255;
158            setpixel(dst, x, y, r, r, r);
159        }
160
161    return dst;
162}
163
164struct image *filter_trick(struct image *img)
165{
166#define TSIZE 3
167    struct image *dst;
168    int x, y, i, j, val, m, more, l, less;
169    int r, g, b;
170
171    dst = image_new(img->width, img->height);
172
173    for(y = 0; y < img->height; y++)
174        for(x = 0; x < img->width; x++)
175            setpixel(dst, x, y, 255, 255, 255);
176
177    for(y = TSIZE/2; y < img->height - TSIZE/2; y++)
178        for(x = TSIZE/2; x < img->width - TSIZE/2; x++)
179        {
180            getpixel(img, x + TSIZE - TSIZE/2, y + TSIZE - TSIZE/2, &val, &g, &b);
181            m = more = l = less = 0;
182            for(i = 0; i < TSIZE; i++)
183                for(j = 0; j < TSIZE; j++)
184                {
185                    getpixel(img, x + j - TSIZE/2, y + i - TSIZE/2, &r, &g, &b);
186                    if(r > val)
187                    {
188                        more += r;
189                        m++;
190                    }
191                    else if(r < val)
192                    {
193                        less += r;
194                        l++;
195                    }
196                }
197
198            if(l >= 6)
199                i = less / l;
200            else if(m >= 6)
201                i = more / m;
202            else
203                i = val;
204            setpixel(dst, x, y, i, i, i);
205        }
206
207    return dst;
208}
209
210struct image *filter_smooth(struct image *img)
211{
212#define SSIZE 3
213    struct image *dst;
214    int x, y, i, j, val;
215    int r, g, b;
216
217    dst = image_new(img->width, img->height);
218
219    for(y = 0; y < img->height; y++)
220        for(x = 0; x < img->width; x++)
221            setpixel(dst, x, y, 255, 255, 255);
222
223    for(y = SSIZE/2; y < img->height - SSIZE/2; y++)
224        for(x = SSIZE/2; x < img->width - SSIZE/2; x++)
225        {
226            val = 0;
227            for(i = 0; i < SSIZE; i++)
228                for(j = 0; j < SSIZE; j++)
229                {
230                    getpixel(img, x + j - SSIZE/2, y + i - SSIZE/2, &r, &g, &b);
231                    val += r;
232                }
233
234            i = val / (SSIZE * SSIZE);
235            setpixel(dst, x, y, i, i, i);
236        }
237
238    return dst;
239}
240
241struct image *filter_median(struct image *img)
242{
243#define MSIZE 3
244    struct image *dst;
245    int x, y, i, j, val[MSIZE*MSIZE];
246    int r, g, b;
247
248    dst = image_new(img->width, img->height);
249
250    for(y = 0; y < img->height; y++)
251        for(x = 0; x < img->width; x++)
252            setpixel(dst, x, y, 255, 255, 255);
253
254    for(y = MSIZE/2; y < img->height - MSIZE/2; y++)
255        for(x = MSIZE/2; x < img->width - MSIZE/2; x++)
256        {
257            for(i = 0; i < MSIZE; i++)
258                for(j = 0; j < MSIZE; j++)
259                {
260                    getpixel(img, x + j - SSIZE/2, y + i - SSIZE/2, &r, &g, &b);
261                    val[i * MSIZE + j] = r;
262                }
263
264            /* Bubble sort power! */
265            for(i = 0; i < MSIZE * MSIZE / 2 + 1; i++)
266                for(j = i + 1; j < MSIZE * MSIZE; j++)
267                    if(val[i] > val[j])
268                    {
269                        register int k = val[i];
270                        val[i] = val[j];
271                        val[j] = k;
272                    }
273
274            i = val[MSIZE * MSIZE / 2];
275            setpixel(dst, x, y, i, i, i);
276        }
277
278    return dst;
279}
280
281struct image *filter_contrast(struct image *img)
282{
283    struct image *dst;
284    int histo[256];
285    int x, y, i, min = 255, max = 0;
286    int r, g, b;
287
288    dst = image_new(img->width, img->height);
289
290    for(y = 0; y < img->height; y++)
291        for(x = 0; x < img->width; x++)
292        {
293            getgray(img, x, y, &r);
294            if(r < min) min = r;
295            if(r > max) max = r;
296        }
297
298    if(min == max)
299        histo[min] = 127;
300    else
301        for(i = min; i < max; i++)
302            histo[i] = (i - min) * 255 / (max - min);
303
304    for(y = 0; y < img->height; y++)
305        for(x = 0; x < img->width; x++)
306        {
307            getgray(img, x, y, &r);
308            setpixel(dst, x, y, histo[r], histo[r], histo[r]);
309        }
310
311    return dst;
312}
313
Note: See TracBrowser for help on using the repository browser.