source: pwntcha/trunk/src/clubic.c @ 426

Last change on this file since 426 was 426, checked in by Sam Hocevar, 17 years ago
  • clubic captchas support.
  • Property svn:keywords set to Id
File size: 4.4 KB
Line 
1/*
2 * clubic.c: decode clubic captchas
3 * $Id: clubic.c 426 2005-01-05 21:16:40Z sam $
4 *
5 * Copyright: (c) 2005 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 <limits.h>
16
17#include "config.h"
18#include "common.h"
19
20static struct image *find_glyphs(struct image *img);
21
22/* Our macros */
23#define FONTNAME "share/font_clubic.png"
24static struct image *font = NULL;
25char *result;
26
27/* Main function */
28char *decode_clubic(struct image *img)
29{
30    struct image *tmp1, *tmp2;
31
32    if(!font)
33    {
34        font = image_load(FONTNAME);
35        if(!font)
36        {
37            fprintf(stderr, "cannot load font %s\n", FONTNAME);
38            exit(-1);
39        }
40    }
41
42    /* clubic captchas have 6 characters */
43    result = malloc(7 * sizeof(char));
44    strcpy(result, "      ");
45
46    tmp1 = filter_equalize(img, 200);
47    tmp2 = find_glyphs(tmp1);
48
49    image_free(tmp1);
50    image_free(tmp2);
51
52    return result;
53}
54
55static struct image *find_glyphs(struct image *img)
56{
57    char all[] = "0123456789";
58    struct
59    {
60        int xmin, xmax, ymin, ymax;
61        int count;
62    }
63    glyphs[10];
64    struct image *dst;
65    int x, y, i = 0;
66    int r, g, b;
67    int xmin, xmax, ymin, ymax, incell = 0, count = 0, startx = 0, cur = 0;
68    int distmin, distx, disty, distch;
69
70    dst = image_new(img->width, img->height);
71
72    for(y = 0; y < img->height; y++)
73        for(x = 0; x < img->width; x++)
74        {
75            getpixel(img, x, y, &r, &g, &b);
76            setpixel(dst, x, y, 255, g, 255);
77        }
78
79    for(x = 0; x < font->width; x++)
80    {
81        int found = 0;
82        for(y = 0; y < font->height; y++)
83        {
84            getpixel(font, x, y, &r, &g, &b);
85            if(r < 128)
86            {
87                found = 1;
88                count += (255 - r);
89            }
90        }
91        if(found && !incell)
92        {
93            incell = 1;
94            xmin = x;
95        }
96        else if(!found && incell)
97        {
98            incell = 0;
99            xmax = x;
100            ymin = 0;
101            ymax = font->height;
102            glyphs[i].xmin = xmin;
103            glyphs[i].xmax = xmax;
104            glyphs[i].ymin = ymin;
105            glyphs[i].ymax = ymax;
106            glyphs[i].count = count;
107            count = 0;
108            i++;
109        }
110    }
111
112    if(i != 10)
113    {
114        printf("error: could not find 10 glyphs in font\n");
115        exit(-1);
116    }
117
118    while(cur < 6)
119    {
120        /* Try to find 1st letter */
121        distmin = INT_MAX;
122        for(i = 0; i < 10; i++)
123        {
124            int localmin = INT_MAX, localx, localy;
125            xmin = glyphs[i].xmin;
126            ymin = glyphs[i].ymin;
127            xmax = glyphs[i].xmax;
128            ymax = glyphs[i].ymax;
129            for(y = -4; y < 4; y++)
130                for(x = startx; x < startx + 4; x++)
131                {
132                    int z, t, dist;
133                    dist = 0;
134                    for(t = 0; t < ymax - ymin; t++)
135                        for(z = 0; z < xmax - xmin; z++)
136                        {
137                            int r2;
138                            getgray(font, xmin + z, ymin + t, &r);
139                            getgray(img, x + z, y + t, &r2);
140                            dist += abs(r - r2);
141                        }
142                    dist = dist * 128 / glyphs[i].count;
143                    if(dist < localmin)
144                    {
145                        localmin = dist;
146                        localx = x;
147                        localy = y;
148                    }
149                }
150            if(localmin < distmin)
151            {
152                distmin = localmin;
153                distx = localx;
154                disty = localy;
155                distch = i;
156            }
157        }
158
159        /* Print min glyph */
160        xmin = glyphs[distch].xmin;
161        ymin = glyphs[distch].ymin;
162        xmax = glyphs[distch].xmax;
163        ymax = glyphs[distch].ymax;
164        for(y = 0; y < ymax - ymin; y++)
165            for(x = 0; x < xmax - xmin; x++)
166            {
167                getpixel(font, xmin + x, ymin + y, &r, &g, &b);
168                if(r > 128) continue;
169                setpixel(dst, distx + x, disty + y, r, g, b);
170            }
171
172        startx = distx + xmax - xmin;
173        result[cur++] = all[distch];
174    }
175
176    return dst;
177}
178
Note: See TracBrowser for help on using the repository browser.