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

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