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

Last change on this file since 424 was 424, checked in by Sam Hocevar, 18 years ago
  • authimage support
  • broadened scode to trencaspammers
  • Property svn:keywords set to Id
File size: 11.8 KB
Line 
1/*
2 * filters.c: various image filters
3 * $Id: filters.c 424 2005-01-05 17:08:50Z 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_dup(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    return dst;
71}
72
73struct image *filter_scale(struct image *img, float ratio)
74{
75    struct image *dst;
76    int w, h, x, y;
77    int r, g, b;
78
79    w = ratio * img->width;
80    h = ratio * img->height;
81
82    dst = image_new(w, h);
83
84    for(y = 0; y < h; y++)
85        for(x = 0; x < w; x++)
86        {
87            getpixel(img, x / ratio, y / ratio, &r, &g, &b);
88            setpixel(dst, x, y, r, g, b);
89        }
90
91    return dst;
92}
93
94struct image *filter_fill_holes(struct image *img)
95{
96    struct image *dst;
97    int x, y;
98    int r, g, b;
99
100    dst = image_new(img->width, img->height);
101
102    for(y = 0; y < img->height; y++)
103        for(x = 0; x < img->width; x++)
104        {
105            getpixel(img, x, y, &r, &g, &b);
106            setpixel(dst, x, y, r, g, b);
107        }
108
109    for(y = 0; y < dst->height; y++)
110        for(x = 2; x < dst->width - 2; x++)
111        {
112            int c1, c2, c3, c4, c5;
113            getpixel(img, x-2, y, &c1, &g, &b);
114            getpixel(img, x-1, y, &c2, &g, &b);
115            getpixel(img, x, y, &c3, &g, &b);
116            getpixel(img, x+1, y, &c4, &g, &b);
117            getpixel(img, x+2, y, &c5, &g, &b);
118            if(c1 < 127 && c2 < 127 && c3 > 128 && c4 < 127)
119                c3 = (c1 + c2 + c4) / 3;
120            else if(c2 < 127 && c3 > 128 && c4 < 127 && c5 < 127)
121                c3 = (c2 + c4 + c5) / 3;
122            setpixel(dst, x, y, c3, c3, c3);
123        }
124
125    for(x = 0; x < dst->width; x++)
126        for(y = 2; y < dst->height - 2; y++)
127        {
128            int c1, c2, c3, c4, c5;
129            getpixel(img, x, y-2, &c1, &g, &b);
130            getpixel(img, x, y-1, &c2, &g, &b);
131            getpixel(img, x, y, &c3, &g, &b);
132            getpixel(img, x, y+1, &c4, &g, &b);
133            getpixel(img, x, y+2, &c5, &g, &b);
134            if(c1 < 127 && c2 < 127 && c3 > 128 && c4 < 127)
135                c3 = (c1 + c2 + c4) / 3;
136            else if(c2 < 127 && c3 > 128 && c4 < 127 && c5 < 127)
137                c3 = (c2 + c4 + c5) / 3;
138            setpixel(dst, x, y, c3, c3, c3);
139        }
140
141    return dst;
142}
143
144struct image *filter_black_stuff(struct image *img)
145{
146    struct image *dst;
147    int x, y;
148    int r, ra, rb, g, b;
149
150    dst = image_new(img->width, img->height);
151
152    /* Remove vertical stuff */
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            setpixel(dst, x, y, r, g, b);
158            if(y > 0 && y < img->height - 1)
159            {
160                getpixel(img, x, y - 1, &ra, &g, &b);
161                getpixel(img, x, y + 1, &rb, &g, &b);
162                if(r < ra && (r - ra) * (r - rb) > 5000)
163                    setpixel(dst, x, y, ra, ra, ra);
164            }
165        }
166
167    /* Remove horizontal stuff */
168    for(y = 0; y < img->height; y++)
169        for(x = 0; x < img->width; x++)
170        {
171            getpixel(img, x, y, &r, &g, &b);
172            if(x > 0 && x < img->width - 1)
173            {
174                getpixel(dst, x - 1, y, &ra, &g, &b);
175                getpixel(dst, x + 1, y, &rb, &g, &b);
176                if(r < ra && (r - ra) * (r - rb) > 5000)
177                    setpixel(dst, x, y, ra, ra, ra);
178            }
179        }
180
181    return dst;
182}
183
184struct image *filter_detect_lines(struct image *img)
185{
186    struct image *dst;
187    int x, y;
188    int r, ra, rb, g, b;
189
190    dst = image_new(img->width, img->height);
191
192    /* Remove white lines */
193    for(y = 0; y < img->height; y++)
194        for(x = 0; x < img->width; x++)
195        {
196            getpixel(img, x, y, &r, &g, &b);
197            setpixel(dst, x, y, r, g, b);
198            if(y > 0 && y < img->height - 1)
199            {
200                getpixel(img, x, y - 1, &ra, &g, &b);
201                getpixel(img, x, y + 1, &rb, &g, &b);
202                if(r > ra && (r - ra) * (r - rb) > 5000)
203                    setpixel(dst, x, y, ra, ra, ra);
204            }
205        }
206
207    /* Remove black lines */
208    for(y = 0; y < img->height; y++)
209        for(x = 0; x < img->width; x++)
210        {
211            getpixel(dst, x, y, &r, &g, &b);
212            if(y > 0 && y < img->height - 1)
213            {
214                getpixel(img, x, y - 1, &ra, &g, &b);
215                getpixel(img, x, y + 1, &rb, &g, &b);
216                if(r < ra && (r - ra) * (r - rb) > 500)
217                    setpixel(dst, x, y, ra, ra, ra);
218            }
219        }
220
221    return dst;
222}
223
224struct image *filter_equalize(struct image *img, int threshold)
225{
226    struct image *dst;
227    int x, y;
228    int r, g, b;
229    int min = 0, max = 255;
230
231    dst = image_new(img->width, img->height);
232
233    if(threshold < 0)
234    {
235        min = 255;
236        max = 0;
237        threshold = -threshold;
238    }
239
240    threshold *= 3;
241
242    for(y = 0; y < img->height; y++)
243        for(x = 0; x < img->width; x++)
244        {
245            getpixel(img, x, y, &r, &g, &b);
246            if(r + g + b < threshold)
247                setpixel(dst, x, y, min, min, min);
248            else
249                setpixel(dst, x, y, max, max, max);
250        }
251
252    return dst;
253}
254
255struct image *filter_trick(struct image *img)
256{
257#define TSIZE 3
258    struct image *dst;
259    int x, y, i, j, val, m, more, l, less;
260    int r, g, b;
261
262    dst = image_new(img->width, img->height);
263
264    for(y = 0; y < img->height; y++)
265        for(x = 0; x < img->width; x++)
266            setpixel(dst, x, y, 255, 255, 255);
267
268    for(y = TSIZE/2; y < img->height - TSIZE/2; y++)
269        for(x = TSIZE/2; x < img->width - TSIZE/2; x++)
270        {
271            getpixel(img, x + TSIZE - TSIZE/2, y + TSIZE - TSIZE/2, &val, &g, &b);
272            m = more = l = less = 0;
273            for(i = 0; i < TSIZE; i++)
274                for(j = 0; j < TSIZE; j++)
275                {
276                    getpixel(img, x + j - TSIZE/2, y + i - TSIZE/2, &r, &g, &b);
277                    if(r > val)
278                    {
279                        more += r;
280                        m++;
281                    }
282                    else if(r < val)
283                    {
284                        less += r;
285                        l++;
286                    }
287                }
288
289            if(l >= 6)
290                i = less / l;
291            else if(m >= 6)
292                i = more / m;
293            else
294                i = val;
295            setpixel(dst, x, y, i, i, i);
296        }
297
298    return dst;
299}
300
301struct image *filter_smooth(struct image *img)
302{
303#define SSIZE 3
304    struct image *dst;
305    int x, y, i, j, val;
306    int r, g, b;
307
308    dst = image_new(img->width, img->height);
309
310    for(y = 0; y < img->height; y++)
311        for(x = 0; x < img->width; x++)
312            setpixel(dst, x, y, 255, 255, 255);
313
314    for(y = SSIZE/2; y < img->height - SSIZE/2; y++)
315        for(x = SSIZE/2; x < img->width - SSIZE/2; x++)
316        {
317            val = 0;
318            for(i = 0; i < SSIZE; i++)
319                for(j = 0; j < SSIZE; j++)
320                {
321                    getpixel(img, x + j - SSIZE/2, y + i - SSIZE/2, &r, &g, &b);
322                    val += r;
323                }
324
325            i = val / (SSIZE * SSIZE);
326            setpixel(dst, x, y, i, i, i);
327        }
328
329    return dst;
330}
331
332struct image *filter_median(struct image *img)
333{
334#define MSIZE 3
335    struct image *dst;
336    int x, y, i, j, val[MSIZE*MSIZE];
337    int r, g, b;
338
339    dst = image_new(img->width, img->height);
340
341    for(y = 0; y < img->height; y++)
342        for(x = 0; x < img->width; x++)
343            setpixel(dst, x, y, 255, 255, 255);
344
345    for(y = MSIZE/2; y < img->height - MSIZE/2; y++)
346        for(x = MSIZE/2; x < img->width - MSIZE/2; x++)
347        {
348            for(i = 0; i < MSIZE; i++)
349                for(j = 0; j < MSIZE; j++)
350                {
351                    getpixel(img, x + j - SSIZE/2, y + i - SSIZE/2, &r, &g, &b);
352                    val[i * MSIZE + j] = r;
353                }
354
355            /* Bubble sort power! */
356            for(i = 0; i < MSIZE * MSIZE / 2 + 1; i++)
357                for(j = i + 1; j < MSIZE * MSIZE; j++)
358                    if(val[i] > val[j])
359                    {
360                        register int k = val[i];
361                        val[i] = val[j];
362                        val[j] = k;
363                    }
364
365            i = val[MSIZE * MSIZE / 2];
366            setpixel(dst, x, y, i, i, i);
367        }
368
369    return dst;
370}
371
372struct image *filter_contrast(struct image *img)
373{
374    struct image *dst;
375    int histo[256];
376    int x, y, i, min = 255, max = 0;
377    int r, g, b;
378
379    dst = image_new(img->width, img->height);
380
381    for(y = 0; y < img->height; y++)
382        for(x = 0; x < img->width; x++)
383        {
384            getgray(img, x, y, &r);
385            if(r < min) min = r;
386            if(r > max) max = r;
387        }
388
389    if(min == max)
390        histo[min] = 127;
391    else
392        for(i = min; i < max; i++)
393            histo[i] = (i - min) * 255 / (max - min);
394
395    for(y = 0; y < img->height; y++)
396        for(x = 0; x < img->width; x++)
397        {
398            getgray(img, x, y, &r);
399            setpixel(dst, x, y, histo[r], histo[r], histo[r]);
400        }
401
402    return dst;
403}
404
405struct image *filter_crop(struct image *img,
406                          int xmin, int ymin, int xmax, int ymax)
407{
408    struct image *dst;
409    int x, y;
410    int r, g, b;
411
412    if(xmin < 0)
413        xmin = 0;
414    if(ymin < 0)
415        ymin = 0;
416    if(xmax >= img->width)
417        xmax = img->width - 1;
418    if(ymax >= img->height)
419        ymax = img->height - 1;
420
421    if(xmin >= xmax || ymin >= ymax)
422        return NULL;
423
424    dst = image_new(xmax - xmin, ymax - ymin);
425
426    for(y = 0; y < dst->height; y++)
427        for(x = 0; x < dst->width; x++)
428        {
429            getpixel(img, xmin + x, ymin + y, &r, &g, &b);
430            setpixel(dst, x, y, r, g, b);
431        }
432
433    return dst;
434}
435
436int filter_count(struct image *img)
437{
438    int histo[256];
439    int x, y, i, count = 0;
440    int r, g, b;
441
442    for(i = 0; i < 256; i++)
443        histo[i] = 0;
444
445    for(y = 0; y < img->height; y++)
446        for(x = 0; x < img->width; x++)
447        {
448            getgray(img, x, y, &r);
449            histo[r] = 1;
450        }
451
452    for(i = 0; i < 256; i++)
453        count += histo[i];
454
455    return count;
456}
457
Note: See TracBrowser for help on using the repository browser.