diff --git a/src/Makefile.am b/src/Makefile.am index fa14046..ccf1f92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,9 @@ NULL = bin_PROGRAMS = pwntcha pwntcha_SOURCES = \ main.c \ + filter.c \ + font.c \ image.c \ - filters.c \ common.h \ authimage.c \ clubic.c \ diff --git a/src/authimage.c b/src/authimage.c index 1411e3d..e3f3bc9 100644 --- a/src/authimage.c +++ b/src/authimage.c @@ -18,44 +18,38 @@ #include "config.h" #include "common.h" -#define FONTNAME "font_authimage.png" -static struct image *font = NULL; - /* Main function */ char *decode_authimage(struct image *img) { - char *all = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + static struct font *font = NULL; char *result; struct image *tmp; int x, y, r, g, b, i; if(!font) { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); + font = font_load_fixed("font_authimage.png", + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); exit(-1); - } } /* authimage captchas have 6 characters */ result = malloc(7 * sizeof(char)); memset(result, '\0', 7); - /* half the captchas are inverse video; we set them back to normal */ + /* double the captcha size for better accuracy in the rotation */ tmp = image_dup(img); filter_scale(tmp, 2.0); getpixel(tmp, 0, 0, &r, &g, &b); filter_equalize(tmp, r * 3 / 4); filter_smooth(tmp); + filter_equalize(tmp, 220); for(i = 0; i < 6; i++) { int mindiff = INT_MAX, minch = -1, ch; - for(ch = 0; ch < 36; ch++) + for(ch = 0; ch < font->size; ch++) { int diff = 0; for(y = 0; y < 7; y++) @@ -66,8 +60,7 @@ char *decode_authimage(struct image *img) newx = 35.0 + (x + 6 * i) * 218.0 / 34.0 + y * 5.0 / 6.0 + 0.5; newy = 33.0 - (x + 6 * i) * 18.0 / 34.0 + y * 42.0 / 6.0 + 0.5; getpixel(tmp, newx, newy, &r, &g, &b); - getpixel(font, x + 6 * ch, y, &r2, &g, &b); - r = (r < 220) ? 0 : 255; + getpixel(font->img, x + 6 * ch, y, &r2, &g, &b); diff += (r - r2) * (r - r2); } } @@ -77,7 +70,7 @@ char *decode_authimage(struct image *img) minch = ch; } } - result[i] = all[minch]; + result[i] = font->glyphs[minch].c; } image_free(tmp); diff --git a/src/clubic.c b/src/clubic.c index 47749fa..cb3a4f5 100644 --- a/src/clubic.c +++ b/src/clubic.c @@ -20,8 +20,6 @@ static void find_glyphs(struct image *img); /* Our macros */ -#define FONTNAME "font_clubic.png" -static struct image *font = NULL; char *result; /* Main function */ @@ -29,18 +27,6 @@ char *decode_clubic(struct image *img) { struct image *tmp; - if(!font) - { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); - if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); - exit(-1); - } - } - /* clubic captchas have 6 characters */ result = malloc(7 * sizeof(char)); strcpy(result, " "); @@ -56,19 +42,20 @@ char *decode_clubic(struct image *img) static void find_glyphs(struct image *img) { - char all[] = "0123456789"; - struct - { - int xmin, xmax, ymin, ymax; - int count; - } - glyphs[10]; + static struct font *font = NULL; struct image *tmp; int x, y, i = 0; int r, g, b; - int xmin, xmax, ymin, ymax, incell = 0, count = 0, startx = 0, cur = 0; + int xmin, xmax, ymin, ymax, startx = 0, cur = 0; int distmin, distx, disty, distch; + if(!font) + { + font = font_load_variable("font_clubic.png", "0123456789"); + if(!font) + exit(1); + } + tmp = image_new(img->width, img->height); for(y = 0; y < img->height; y++) @@ -78,56 +65,17 @@ static void find_glyphs(struct image *img) setpixel(tmp, x, y, 255, g, 255); } - for(x = 0; x < font->width; x++) - { - int found = 0; - for(y = 0; y < font->height; y++) - { - getpixel(font, x, y, &r, &g, &b); - if(r < 128) - { - found = 1; - count += (255 - r); - } - } - if(found && !incell) - { - incell = 1; - xmin = x; - } - else if(!found && incell) - { - incell = 0; - xmax = x; - ymin = 0; - ymax = font->height; - glyphs[i].xmin = xmin; - glyphs[i].xmax = xmax; - glyphs[i].ymin = ymin; - glyphs[i].ymax = ymax; - glyphs[i].count = count; - count = 0; - i++; - } - } - - if(i != 10) - { - printf("error: could not find 10 glyphs in font\n"); - exit(-1); - } - while(cur < 6) { /* Try to find 1st letter */ distmin = INT_MAX; - for(i = 0; i < 10; i++) + for(i = 0; i < font->size; i++) { int localmin = INT_MAX, localx, localy; - xmin = glyphs[i].xmin; - ymin = glyphs[i].ymin; - xmax = glyphs[i].xmax; - ymax = glyphs[i].ymax; + xmin = font->glyphs[i].xmin; + ymin = font->glyphs[i].ymin; + xmax = font->glyphs[i].xmax; + ymax = font->glyphs[i].ymax; for(y = -4; y < 4; y++) for(x = startx; x < startx + 4; x++) { @@ -137,11 +85,11 @@ static void find_glyphs(struct image *img) for(z = 0; z < xmax - xmin; z++) { int r2; - getgray(font, xmin + z, ymin + t, &r); + getgray(font->img, xmin + z, ymin + t, &r); getgray(img, x + z, y + t, &r2); dist += abs(r - r2); } - dist = dist * 128 / glyphs[i].count; + dist = dist * 128 / font->glyphs[i].count; if(dist < localmin) { localmin = dist; @@ -159,20 +107,21 @@ static void find_glyphs(struct image *img) } /* Print min glyph */ - xmin = glyphs[distch].xmin; - ymin = glyphs[distch].ymin; - xmax = glyphs[distch].xmax; - ymax = glyphs[distch].ymax; + xmin = font->glyphs[distch].xmin; + ymin = font->glyphs[distch].ymin; + xmax = font->glyphs[distch].xmax; + ymax = font->glyphs[distch].ymax; for(y = 0; y < ymax - ymin; y++) for(x = 0; x < xmax - xmin; x++) { - getpixel(font, xmin + x, ymin + y, &r, &g, &b); - if(r > 128) continue; + getpixel(font->img, xmin + x, ymin + y, &r, &g, &b); + if(r > 128) + continue; setpixel(tmp, distx + x, disty + y, r, g, b); } startx = distx + xmax - xmin; - result[cur++] = all[distch]; + result[cur++] = font->glyphs[distch].c; } image_free(tmp); diff --git a/src/common.h b/src/common.h index 024aaeb..2e37701 100644 --- a/src/common.h +++ b/src/common.h @@ -25,7 +25,9 @@ struct font { int xmin, xmax, ymin, ymax; int count; /* Black pixel count */ + char c; } *glyphs; + int size; }; /* global variables */ @@ -57,6 +59,11 @@ int getgray(struct image *img, int x, int y, int *g); int getpixel(struct image *img, int x, int y, int *r, int *g, int *b); int setpixel(struct image *img, int x, int y, int r, int g, int b); +/* font operations */ +struct font *font_load_fixed(char *file, char *chars); +struct font *font_load_variable(char *file, char *chars); +void font_free(struct font *font); + /* image filters */ void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b); void filter_fill_holes(struct image *img); diff --git a/src/filters.c b/src/filter.c similarity index 100% rename from src/filters.c rename to src/filter.c diff --git a/src/font.c b/src/font.c new file mode 100644 index 0000000..5a35603 --- /dev/null +++ b/src/font.c @@ -0,0 +1,150 @@ +/* + * font.c: font handling + * $Id$ + * + * Copyright: (c) 2005 Sam Hocevar + * This program is free software; you can redistribute it and/or + * modify it under the terms of the Do What The Fuck You Want To + * Public License as published by Banlu Kemiyatorn. See + * http://sam.zoy.org/projects/COPYING.WTFPL for more details. + */ + +#include +#include +#include + +#include "config.h" +#include "common.h" + +struct font *font_load_fixed(char *file, char *chars) +{ + char fontname[BUFSIZ]; + struct font *font; + struct image *img; + int i; + + sprintf(fontname, "%s/%s", share, file); + img = image_load(fontname); + if(!img) + { + fprintf(stderr, "%s: cannot load font %s\n", argv0, fontname); + return NULL; + } + + font = malloc(sizeof(struct font)); + font->img = img; + font->size = strlen(chars); + font->glyphs = malloc(font->size * sizeof(struct glyph)); + + for(i = 0; i < font->size; i++) + { + font->glyphs[i].xmin = i * font->img->width / font->size; + font->glyphs[i].xmax = (i + 1) * font->img->width / font->size; + font->glyphs[i].ymin = 0; + font->glyphs[i].ymax = font->img->height; + font->glyphs[i].count = 0; /* They all have the same width anyway */ + font->glyphs[i].c = chars[i]; + } + + return font; +} + +struct font *font_load_variable(char *file, char *chars) +{ + char fontname[BUFSIZ]; + struct font *font; + struct image *img; + int count = 0, incell = 0, xmin, xmax, ymin, ymax; + int x, y, i; + int r, g, b; + + sprintf(fontname, "%s/%s", share, file); + img = image_load(fontname); + if(!img) + { + fprintf(stderr, "%s: cannot load font %s\n", argv0, fontname); + return NULL; + } + + font = malloc(sizeof(struct font)); + font->img = img; + font->size = strlen(chars); + font->glyphs = malloc(font->size * sizeof(struct glyph)); + + for(x = 0, i = 0, xmin = 0; x < font->img->width && i < font->size; x++) + { + int found = 0; + for(y = 0; y < font->img->height; y++) + { + getpixel(font->img, x, y, &r, &g, &b); + if(r < 128) + { + found = 1; + count += (255 - r); + } + } + if(found && !incell) + { + incell = 1; + xmin = x; + } + else if(!found && incell) + { + incell = 0; + xmax = x; +#if 0 + ymin = font->img->height; + ymax = 0; + for(y = 0; y < font->img->height; y++) + { + int newx; + int gotit = 0; + for(newx = xmin; newx < xmax; newx++) + { + getpixel(font->img, newx, y, &r, &g, &b); + if(r < 128) + { + gotit = 1; + break; + } + } + if(gotit) + { + if(ymin > y) ymin = y; + if(ymax <= y) ymax = y + 1; + } + } +#else + ymin = 0; + ymax = font->img->height; +#endif + font->glyphs[i].xmin = xmin; + font->glyphs[i].xmax = xmax; + font->glyphs[i].ymin = ymin; + font->glyphs[i].ymax = ymax; + font->glyphs[i].count = count; + font->glyphs[i].c = chars[i]; + count = 0; + i++; + } + } + + if(i != font->size) + { + printf("%s: could not find %i glyphs in font\n", argv0, font->size); + image_free(font->img); + free(font->glyphs); + free(font); + return NULL; + } + + return font; +} + +void font_free(struct font *font) +{ + image_free(font->img); + free(font->glyphs); + free(font); +} + diff --git a/src/linuxfr.c b/src/linuxfr.c index 9514ea2..dca8717 100644 --- a/src/linuxfr.c +++ b/src/linuxfr.c @@ -17,36 +17,31 @@ #include "config.h" #include "common.h" -#define FONTNAME "font_linuxfr.png" -static struct image *font = NULL; - /* Main function */ char *decode_linuxfr(struct image *img) { - char all[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; + static struct font *font = NULL; char *result; struct image *tmp; int x, y, r, g, b, i, j, c; - int *stats = malloc(img->height * sizeof(int)); + int *stats; if(!font) { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); + font = font_load_fixed("font_linuxfr.png", + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"); if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); exit(-1); - } } /* linuxfr captchas have 7 characters */ result = malloc(8 * sizeof(char)); memset(result, '\0', 8); + stats = malloc(img->height * sizeof(int)); + tmp = image_dup(img); filter_equalize(tmp, 150); @@ -114,14 +109,14 @@ char *decode_linuxfr(struct image *img) { int r2, g2, b2, ch; int minerror = INT_MAX; - for(ch = 0; ch < 62; ch++) + for(ch = 0; ch < font->size; ch++) { int error = 0, goodch = 1; for(j = 0; j < 12 && goodch; j++) for(i = 0; i < 8; i++) { getpixel(tmp, x + c * 9 + i, y + j, &r, &g, &b); - getpixel(font, ch * 9 + i, j, &r2, &g2, &b2); + getpixel(font->img, ch * 9 + i, j, &r2, &g2, &b2); /* Only die if font is black and image is white */ if(r > r2) { @@ -134,7 +129,7 @@ char *decode_linuxfr(struct image *img) if(goodch && error < minerror) { minerror = error; - result[c] = all[ch]; + result[c] = font->glyphs[ch].c; result[c+1] = '\0'; } } diff --git a/src/main.c b/src/main.c index 44043b5..6f75246 100644 --- a/src/main.c +++ b/src/main.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) switch(c) { case 'h': /* --help */ - printf("Usage: %s [OPTION]... FILE...\n", argv[0]); + printf("Usage: %s [OPTION]... IMAGE...\n", argv[0]); #ifdef HAVE_GETOPT_LONG printf(" -m, --mode force operating mode\n"); printf(" -s, --share specify shared dir\n"); diff --git a/src/phpbb.c b/src/phpbb.c index 10a3488..101d674 100644 --- a/src/phpbb.c +++ b/src/phpbb.c @@ -17,14 +17,10 @@ #include "config.h" #include "common.h" -/* Our macros */ -#define FONTNAME "font_phpbb.png" -static struct image *font = NULL; - /* Main function */ char *decode_phpbb(struct image *img) { - char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; + static struct font *font = NULL; char *result; struct image *tmp1, *tmp2; int x, y, i = 0; @@ -34,14 +30,10 @@ char *decode_phpbb(struct image *img) if(!font) { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); + font = font_load_fixed("font_phpbb.png", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"); if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); exit(-1); - } } /* phpBB captchas have 6 characters */ @@ -68,14 +60,14 @@ char *decode_phpbb(struct image *img) { /* Try to find 1st letter */ distmin = INT_MAX; - for(i = 0; i < 35; i++) + for(i = 0; i < font->size; i++) { int localmin = INT_MAX, localx, localy; - xmin = i * 40; - ymin = 0; - xmax = i * 40 + 40; - ymax = 40; - for(y = 0; y < img->height - 40; y++) + xmin = font->glyphs[i].xmin; + ymin = font->glyphs[i].ymin; + xmax = font->glyphs[i].xmax; + ymax = font->glyphs[i].ymax; + for(y = 0; y < img->height - (ymax - ymin); y++) { x = offset - 3; if(cur == 0) @@ -90,7 +82,7 @@ char *decode_phpbb(struct image *img) for(z = 0; z < xmax - xmin; z++) { int r2; - getgray(font, xmin + z, ymin + t, &r); + getgray(font->img, xmin + z, ymin + t, &r); getgray(tmp1, x + z, y + t, &r2); if(r > r2) dist += r - r2; @@ -115,22 +107,23 @@ char *decode_phpbb(struct image *img) } /* Print min glyph (debug) */ - xmin = distch * 40; - ymin = 0; - xmax = distch * 40 + 40; - ymax = 40; + xmin = font->glyphs[distch].xmin; + ymin = font->glyphs[distch].ymin; + xmax = font->glyphs[distch].xmax; + ymax = font->glyphs[distch].ymax; for(y = 0; y < ymax - ymin; y++) for(x = 0; x < xmax - xmin; x++) { int r2; - getpixel(font, xmin + x, ymin + y, &r2, &g, &b); - if(r2 > 128) continue; + getpixel(font->img, xmin + x, ymin + y, &r2, &g, &b); + if(r2 > 128) + continue; getpixel(tmp2, distx + x, disty + y, &r, &g, &b); setpixel(tmp2, distx + x, disty + y, r2, g, b); } offset = distx + xmax - xmin; - result[cur] = all[distch]; + result[cur] = font->glyphs[distch].c; } image_free(tmp1); diff --git a/src/slashdot.c b/src/slashdot.c index 6edc850..e1e84c5 100644 --- a/src/slashdot.c +++ b/src/slashdot.c @@ -20,15 +20,8 @@ static void count_objects(struct image *img); static void rotate(struct image *img); -static void cut_cells(struct image *img); static void find_glyphs(struct image *img); -/* Our macros */ -#define FONTNAME "font_slashdot.png" - -struct font font; -struct glyph glyphs[22]; - /* Global stuff */ struct { int xmin, ymin, xmax, ymax; } objlist[100]; int objects, first, last; @@ -136,16 +129,6 @@ static void count_objects(struct image *img) } } -#if 0 - { CvPoint A, B; - A.x = (objlist[first].xmin + objlist[first].xmax) / 2; - A.y = (objlist[first].ymin + objlist[first].ymax) / 2; - B.x = (objlist[last].xmin + objlist[last].xmax) / 2; - B.y = (objlist[last].ymin + objlist[last].ymax) / 2; - cvLine(tmp, A, B, 0, 2.0, 0); - } -#endif - image_swap(img, tmp); image_free(tmp); } @@ -195,58 +178,20 @@ static void rotate(struct image *img) image_free(tmp); } -static void cut_cells(struct image *img) -{ - struct image *tmp; - int x, y; - int r, g, b; - - tmp = image_new(img->width, img->height); - - for(y = 0; y < img->height; y++) - for(x = 0; x < img->width; x++) - { - getpixel(img, x, y, &r, &g, &b); - setpixel(tmp, x, y, r, g, b); - } - - for(x = 0; x < img->width; x++) - { - setpixel(tmp, x, 0, 255, 255, 255); - setpixel(tmp, x, img->height - 1, 255, 255, 255); - } - - for(y = 0; y < img->height; y++) - for(x = 0; x < 7; x++) - { - setpixel(tmp, x * img->width / 7, y, 255, 255, 255); - setpixel(tmp, (x + 1) * img->width / 7 - 1, y, 255, 255, 255); - } - - image_swap(img, tmp); - image_free(tmp); -} - static void find_glyphs(struct image *img) { - char all[] = "abcdefgijkmnpqrstvwxyz"; + static struct font *font = NULL; struct image *tmp; int x, y, i = 0; int r, g, b; - int xmin, xmax, ymin, ymax, incell = 0, count = 0, startx = 0, cur = 0; + int xmin, xmax, ymin, ymax, startx = 0, cur = 0; int distmin, distx, disty, distch; - if(!font.img) + if(!font) { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font.img = image_load(fontname); - if(!font.img) - { - fprintf(stderr, "cannot load font %s\n", fontname); - exit(-1); - } - font.glyphs = glyphs; + font = font_load_variable("font_slashdot.png", "abcdefgijkmnpqrstvwxyz"); + if(!font) + exit(1); } tmp = image_new(img->width, img->height); @@ -258,82 +203,17 @@ static void find_glyphs(struct image *img) setpixel(tmp, x, y, 255, g, 255); } - for(x = 0; x < font.img->width; x++) - { - int found = 0; - for(y = 0; y < font.img->height; y++) - { - getpixel(font.img, x, y, &r, &g, &b); - if(r < 128) - { - found = 1; - count += (255 - r); - } - } - if(found && !incell) - { - incell = 1; - xmin = x; - } - else if(!found && incell) - { - incell = 0; - xmax = x; -#if 0 - ymin = font.img->height; - ymax = 0; - for(y = 0; y < font.img->height; y++) - { - int newx; - int gotit = 0; - for(newx = xmin; newx < xmax; newx++) - { - getpixel(font.img, newx, y, &r, &g, &b); - if(r < 128) - { - gotit = 1; - break; - } - } - if(gotit) - { - if(ymin > y) ymin = y; - if(ymax <= y) ymax = y + 1; - } - } -#else - ymin = 0; - ymax = font.img->height; -#endif - font.glyphs[i].xmin = xmin; - font.glyphs[i].xmax = xmax; - font.glyphs[i].ymin = ymin; - font.glyphs[i].ymax = ymax; - font.glyphs[i].count = count; - count = 0; - i++; - } - } - - if(i != 22) - { - printf("error: could not find 22 glyphs in font\n"); - exit(-1); - } - while(cur < 7) { /* Try to find 1st letter */ distmin = INT_MAX; - for(i = 0; i < 22; i++) + for(i = 0; i < font->size; i++) { int localmin = INT_MAX, localx, localy; -//if(all[i] == 'i') continue; - xmin = font.glyphs[i].xmin; - ymin = font.glyphs[i].ymin; - xmax = font.glyphs[i].xmax; - ymax = font.glyphs[i].ymax; - //printf("trying to find %c (%i×%i) - ", all[i], xmax - xmin, ymax - ymin); + xmin = font->glyphs[i].xmin; + ymin = font->glyphs[i].ymin; + xmax = font->glyphs[i].xmax; + ymax = font->glyphs[i].ymax; for(y = -5; y < 5; y++) for(x = startx - 5; x < startx + 5; x++) { @@ -343,13 +223,13 @@ static void find_glyphs(struct image *img) for(z = 0; z < xmax - xmin; z++) { int r2; - getgray(font.img, xmin + z, ymin + t, &r); + getgray(font->img, xmin + z, ymin + t, &r); getgray(img, x + z, y + t, &r2); dist += abs(r - r2); } // printf("%i %i -> %i\n", x, y, dist); //dist /= sqrt(xmax - xmin); - dist = dist * 128 / font.glyphs[i].count; + dist = dist * 128 / font->glyphs[i].count; if(dist < localmin) { localmin = dist; @@ -367,24 +247,21 @@ static void find_glyphs(struct image *img) } } - //fprintf(stderr, "%i (%i,%i)\n", distmin, distx - startx, disty); - //printf("min diff: %c - %i (%i, %i)\n", all[distch], distmin, distx, disty); - - /* Print min glyph */ - xmin = font.glyphs[distch].xmin; - ymin = font.glyphs[distch].ymin; - xmax = font.glyphs[distch].xmax; - ymax = font.glyphs[distch].ymax; + /* Draw best glyph in picture (debugging purposes) */ + xmin = font->glyphs[distch].xmin; + ymin = font->glyphs[distch].ymin; + xmax = font->glyphs[distch].xmax; + ymax = font->glyphs[distch].ymax; for(y = 0; y < ymax - ymin; y++) for(x = 0; x < xmax - xmin; x++) { - getpixel(font.img, xmin + x, ymin + y, &r, &g, &b); + getpixel(font->img, xmin + x, ymin + y, &r, &g, &b); if(r > 128) continue; setpixel(tmp, distx + x, disty + y, r, g, b); } startx = distx + xmax - xmin; - result[cur++] = all[distch]; + result[cur++] = font->glyphs[distch].c; } image_swap(img, tmp); diff --git a/src/test.c b/src/test.c index a4fdb83..8ef75ba 100644 --- a/src/test.c +++ b/src/test.c @@ -18,35 +18,21 @@ #include "config.h" #include "common.h" -/* Our macros */ -#define FONTNAME "font_phpbb.png" - -static void find_glyphs(struct image *img); - -/* Global stuff */ -struct { int xmin, ymin, xmax, ymax; } objlist[100]; -int objects, first, last; -char *result; - /* Main function */ char *decode_test(struct image *img) { + char *result; struct image *tmp; - /* Initialise local data */ - objects = 0; - first = -1; - last = -1; - /* phpBB captchas have 6 characters */ result = malloc(7 * sizeof(char)); + result[0] = 0; tmp = image_dup(img); filter_smooth(tmp); filter_median(tmp); filter_equalize(tmp, 130); filter_median(tmp); - find_glyphs(tmp); image_free(tmp); @@ -55,105 +41,3 @@ char *decode_test(struct image *img) /* The following functions are local */ -static void find_glyphs(struct image *img) -{ - char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; - struct image *tmp, *font; - int x, y, i = 0; - int r, g, b; - int xmin, xmax, ymin, ymax, cur = 0, offset = -1; - int distmin, distx, disty, distch; - - if(!font) - { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); - if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); - exit(-1); - } - } - - tmp = image_new(img->width, img->height); - - for(x = 0; x < img->width; x++) - for(y = 0; y < img->height; y++) - { - getpixel(img, x, y, &r, &g, &b); - setpixel(tmp, x, y, 255, g, 255); - if(r == 0 && offset == -1) - offset = x; - } - - strcpy(result, " "); - - while(cur < 6) - { - /* Try to find 1st letter */ - distmin = INT_MAX; - for(i = 0; i < 35; i++) - { - int localmin = INT_MAX, localx, localy; - xmin = i * 40; - ymin = 0; - xmax = i * 40 + 40; - ymax = 40; - for(y = 0; y < img->height - 40; y++) - { - x = offset - 5; - if(cur == 0) - x -= 15; - if(x < 0) - x = 0; - for(; x < offset + 10; x++) - { - int z, t, dist; - dist = 0; - for(t = 0; t < ymax - ymin; t++) - for(z = 0; z < xmax - xmin; z++) - { - int r2; - getgray(font, xmin + z, ymin + t, &r); - getgray(img, x + z, y + t, &r2); - dist += abs(r - r2); - } - if(dist < localmin) - { - localmin = dist; - localx = x; - localy = y; - } - } - } - if(localmin < distmin) - { - distmin = localmin; - distx = localx; - disty = localy; - distch = i; - } - } - - /* Print min glyph (debug) */ - xmin = distch * 40; - ymin = 0; - xmax = distch * 40 + 40; - ymax = 40; - for(y = 0; y < ymax - ymin; y++) - for(x = 0; x < xmax - xmin; x++) - { - getpixel(font, xmin + x, ymin + y, &r, &g, &b); - if(r > 128) continue; - setpixel(tmp, distx + x, disty + y, r, g, b); - } - - offset = distx + xmax - xmin; - result[cur++] = all[distch]; - } - - image_swap(img, tmp); - image_free(tmp); -} - diff --git a/src/vbulletin.c b/src/vbulletin.c index 89be4fb..db69491 100644 --- a/src/vbulletin.c +++ b/src/vbulletin.c @@ -17,13 +17,10 @@ #include "config.h" #include "common.h" -#define FONTNAME "font_vbulletin.png" -static struct image *font = NULL; - /* Main function */ char *decode_vbulletin(struct image *img) { - char all[] = "2346789ABCDEFGHJKLMNPRTWXYZ"; + static struct font *font = NULL; char *result; struct image *tmp; int limits[6] = { 26, 53, 80, 107, 134, 160 }; @@ -31,14 +28,10 @@ char *decode_vbulletin(struct image *img) if(!font) { - char fontname[BUFSIZ]; - sprintf(fontname, "%s/%s", share, FONTNAME); - font = image_load(fontname); + font = font_load_fixed("font_vbulletin.png", + "2346789ABCDEFGHJKLMNPRTWXYZ"); if(!font) - { - fprintf(stderr, "cannot load font %s\n", fontname); exit(-1); - } } /* vBulletin captchas have 6 characters */ @@ -114,18 +107,16 @@ char *decode_vbulletin(struct image *img) /* Guess all glyphs */ for(i = 0; i < 6; i++) { - struct image *new = image_dup(tmp); int mindist = INT_MAX, min = -1; - filter_crop(new, limits[i], 15, limits[i] + 11, 45); - for(j = 0; j < 27; j++) + for(j = 0; j < font->size; j++) { int dist = 0; - for(y = 0; y < new->height; y++) - for(x = 0; x < new->width; x++) + for(y = 0; y < 11; y++) + for(x = 0; x < 30; x++) { int r2, g2, b2; - getpixel(font, 12 * j + x, y, &r, &g, &b); - getpixel(new, x, y, &r2, &g2, &b2); + getpixel(font->img, 12 * j + x, y, &r, &g, &b); + getpixel(tmp, limits[i] + x, 15 + y, &r2, &g2, &b2); dist += (r - r2) * (r - r2); } if(dist < mindist) @@ -134,8 +125,7 @@ char *decode_vbulletin(struct image *img) min = j; } } - image_free(new); - result[i] = all[min]; + result[i] = font->glyphs[min].c; } image_free(tmp); diff --git a/src/xanga.c b/src/xanga.c index 68a59ea..cd3ced2 100644 --- a/src/xanga.c +++ b/src/xanga.c @@ -20,27 +20,36 @@ static void fill_white_holes(struct image *img); -/* Our macros */ -#define FACTOR 1 -#define FONTNAME "font_xanga.png" // use with FACTOR = 1 -//#define FONTNAME "font.png" // use with FACTOR = 2 -//#define FONTNAME "font_dilated.png" // use with FACTOR = 2 -static struct image *font = NULL; - -/* Global stuff */ -struct { int xmin, ymin, xmax, ymax; } objlist[100]; -int objects, first, last; -char *result; - /* Main function */ char *decode_xanga(struct image *img) { + static struct font *font1 = NULL, *font2 = NULL, *font3 = NULL; struct image *tmp; - - /* Initialise local data */ - objects = 0; - first = -1; - last = -1; + char *result; + + if(!font1) + { + font1 = font_load_variable("font_freemonobold_32_az.bmp", + "abcdefghijklmnopqrstuvwxyz"); + if(!font1) + exit(1); + } + + if(!font2) + { + font2 = font_load_variable("font_freemonobold_32_az.bmp", + "abcdefghijklmnopqrstuvwxyz"); + if(!font2) + exit(1); + } + + if(!font3) + { + font3 = font_load_variable("font_freemonobold_32_az.bmp", + "abcdefghijklmnopqrstuvwxyz"); + if(!font3) + exit(1); + } /* Xanga captchas have 7 characters */ result = malloc(8 * sizeof(char)); @@ -68,7 +77,6 @@ return NULL; filter_equalize(tmp, 200); /* Invert rotation and find glyphs */ - rotate(tmp); filter_median(tmp); /* Clean up our mess */ @@ -86,7 +94,7 @@ return NULL; static void fill_white_holes(struct image *img) { struct image *tmp; - int x, y, i; + int x, y; int r, g, b; tmp = image_new(img->width, img->height);