/* Main function */ char *decode_authimage(struct image *img) { static struct font *font = NULL; char *result; struct image *tmp; int x, y, r, g, b, i; if(!font) { font = font_load_fixed(DECODER, "font.png", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); if(!font) exit(-1); } /* authimage captchas have 6 characters */ result = malloc(7 * sizeof(char)); memset(result, '\0', 7); /* 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_threshold(tmp, r * 3 / 4); filter_smooth(tmp); filter_threshold(tmp, 220); for(i = 0; i < 6; i++) { int mindiff = INT_MAX, minch = -1, ch; for(ch = 0; ch < font->size; ch++) { int diff = 0; for(y = 0; y < 7; y++) { for(x = 0; x < 5; x++) { int newx, newy, r2; 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->img, x + 6 * ch, y, &r2, &g, &b); diff += (r - r2) * (r - r2); } } if(diff < mindiff) { mindiff = diff; minch = ch; } } result[i] = font->glyphs[minch].c; } image_free(tmp); return result; }
/* Main function */ char *decode_lmt(struct image *img) { struct image *tmp; /* lmt captchas have 3 characters */ result = malloc(4 * sizeof(char)); strcpy(result, " "); tmp = image_dup(img); filter_contrast(tmp); filter_black_stuff(tmp); filter_smooth(tmp); filter_median(tmp); find_glyphs(tmp); image_free(tmp); return result; }
static void find_glyphs(struct image *img) { #define DELTA 2 static struct font *font; int x, y, i = 0; int r, g, b; int xmin, xmax, ymin, ymax, startx = 0, cur = 0; int bestdist, bestx, besty, bestch; if(!font) { font = font_load_variable(DECODER, "freesans_24_09AZ.bmp", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); filter_smooth(font->img); if(!font) exit(1); } while(cur < 3) { /* Try to find 1st letter */ bestdist = INT_MAX; for(i = 0; i < font->size; i++) { int localmin = INT_MAX, localx, localy; xmin = font->glyphs[i].xmin - DELTA; ymin = font->glyphs[i].ymin; xmax = font->glyphs[i].xmax + DELTA; ymax = font->glyphs[i].ymax; for(y = -5; y < 5; y++) { for(x = startx; x < startx + 15; 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->img, xmin + z, ymin + t, &r); getgray(img, x + z, y + t, &r2); dist += (r - r2) * (r - r2); } dist = dist / (xmax - xmin - 2 * DELTA); if(dist < localmin) { localmin = dist; localx = x; localy = y; } } } if(localmin < bestdist) { bestdist = localmin; bestx = localx; besty = localy; bestch = i; } } /* Print min glyph */ #if 0 xmin = font->glyphs[bestch].xmin - DELTA; ymin = font->glyphs[bestch].ymin; xmax = font->glyphs[bestch].xmax + DELTA; ymax = font->glyphs[bestch].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); if(r > 128) { getpixel(img, bestx + x, besty + y, &r, &g, &b); r = 255; } setpixel(img, bestx + x, besty + y, r, g, b); } #endif startx = bestx + font->glyphs[bestch].xmax - font->glyphs[bestch].xmin; result[cur++] = font->glyphs[bestch].c; } }