git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/pwntcha/trunk@387 92316355-f0b4-4df1-b90c-862c8a59935fmaster
@@ -18,21 +18,21 @@ struct image | |||
}; | |||
/* available CAPTCHA decoders */ | |||
char * slashdot_decode(char *image); | |||
char * decode_slashdot(struct image *img); | |||
/* image operations */ | |||
struct image * load_image(char *name); | |||
struct image * new_image(int width, int height); | |||
struct image * image_load(char *name); | |||
struct image * image_new(int width, int height); | |||
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); | |||
/* image filters */ | |||
void flood_fill(struct image *img, int x, int y, int r, int g, int b); | |||
struct image *fill_holes(struct image *img); | |||
struct image *detect_lines(struct image *img); | |||
struct image *equalize(struct image *img); | |||
struct image *trick(struct image *img); | |||
struct image *smooth(struct image *img); | |||
struct image *median(struct image *img); | |||
void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b); | |||
struct image *filter_fill_holes(struct image *img); | |||
struct image *filter_detect_lines(struct image *img); | |||
struct image *filter_equalize(struct image *img); | |||
struct image *filter_trick(struct image *img); | |||
struct image *filter_smooth(struct image *img); | |||
struct image *filter_median(struct image *img); | |||
@@ -24,7 +24,7 @@ | |||
#define FONTNAME "share/font_dilated_half.png" // use with FACTOR = 1 | |||
/* Functions */ | |||
void flood_fill(struct image *img, int x, int y, int r, int g, int b) | |||
void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b) | |||
{ | |||
int oldr, oldg, oldb; | |||
int nextr, nextg, nextb; | |||
@@ -37,28 +37,28 @@ void flood_fill(struct image *img, int x, int y, int r, int g, int b) | |||
getpixel(img, x + 1, y, &nextr, &nextg, &nextb); | |||
if(nextr == oldr && nextg == oldg && nextb == oldb) | |||
flood_fill(img, x + 1, y, r, g, b); | |||
filter_flood_fill(img, x + 1, y, r, g, b); | |||
getpixel(img, x - 1, y, &nextr, &nextg, &nextb); | |||
if(nextr == oldr && nextg == oldg && nextb == oldb) | |||
flood_fill(img, x - 1, y, r, g, b); | |||
filter_flood_fill(img, x - 1, y, r, g, b); | |||
getpixel(img, x, y + 1, &nextr, &nextg, &nextb); | |||
if(nextr == oldr && nextg == oldg && nextb == oldb) | |||
flood_fill(img, x, y + 1, r, g, b); | |||
filter_flood_fill(img, x, y + 1, r, g, b); | |||
getpixel(img, x, y - 1, &nextr, &nextg, &nextb); | |||
if(nextr == oldr && nextg == oldg && nextb == oldb) | |||
flood_fill(img, x, y - 1, r, g, b); | |||
filter_flood_fill(img, x, y - 1, r, g, b); | |||
} | |||
struct image *fill_holes(struct image *img) | |||
struct image *filter_fill_holes(struct image *img) | |||
{ | |||
struct image *dst; | |||
int x, y; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -102,13 +102,13 @@ struct image *fill_holes(struct image *img) | |||
return dst; | |||
} | |||
struct image *detect_lines(struct image *img) | |||
struct image *filter_detect_lines(struct image *img) | |||
{ | |||
struct image *dst; | |||
int x, y; | |||
int r, ra, rb, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
/* Remove white lines */ | |||
for(y = 0; y < img->height; y++) | |||
@@ -142,13 +142,13 @@ struct image *detect_lines(struct image *img) | |||
return dst; | |||
} | |||
struct image *equalize(struct image *img) | |||
struct image *filter_equalize(struct image *img) | |||
{ | |||
struct image *dst; | |||
int x, y; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -161,14 +161,14 @@ struct image *equalize(struct image *img) | |||
return dst; | |||
} | |||
struct image *trick(struct image *img) | |||
struct image *filter_trick(struct image *img) | |||
{ | |||
#define TSIZE 3 | |||
struct image *dst; | |||
int x, y, i, j, val, m, more, l, less; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -207,14 +207,14 @@ struct image *trick(struct image *img) | |||
return dst; | |||
} | |||
struct image *smooth(struct image *img) | |||
struct image *filter_smooth(struct image *img) | |||
{ | |||
#define SSIZE 3 | |||
struct image *dst; | |||
int x, y, i, j, val; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -238,14 +238,14 @@ struct image *smooth(struct image *img) | |||
return dst; | |||
} | |||
struct image *median(struct image *img) | |||
struct image *filter_median(struct image *img) | |||
{ | |||
#define MSIZE 4 | |||
struct image *dst; | |||
int x, y, i, j, val[MSIZE*MSIZE]; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -24,7 +24,7 @@ | |||
# error "No imaging library" | |||
#endif | |||
struct image * load_image(char *name) | |||
struct image * image_load(char *name) | |||
{ | |||
struct image * img; | |||
#if defined(HAVE_IMLIB2_H) | |||
@@ -56,7 +56,7 @@ struct image * load_image(char *name) | |||
return img; | |||
} | |||
struct image * new_image(int width, int height) | |||
struct image * image_new(int width, int height) | |||
{ | |||
struct image * img; | |||
#if defined(HAVE_IMLIB2_H) | |||
@@ -130,7 +130,7 @@ int setpixel(struct image *img, int x, int y, int r, int g, int b) | |||
return 0; | |||
} | |||
void display_image(struct image *img) | |||
void image_display(struct image *img) | |||
{ | |||
#if defined(HAVE_IMLIB2_H) | |||
//char name[BUFSIZ]; | |||
@@ -17,6 +17,7 @@ | |||
int main(int argc, char *argv[]) | |||
{ | |||
struct image *img; | |||
char *result; | |||
if(argc != 2) | |||
@@ -25,9 +26,19 @@ int main(int argc, char *argv[]) | |||
return -1; | |||
} | |||
result = slashdot_decode(argv[1]); | |||
img = image_load(argv[1]); | |||
if(!img) | |||
{ | |||
fprintf(stderr, "cannot load %s\n", argv[1]); | |||
return -1; | |||
} | |||
result = decode_slashdot(img); | |||
if(!result) | |||
{ | |||
fprintf(stderr, "sorry, decoding failed\n"); | |||
return -1; | |||
} | |||
printf("%s\n", result); | |||
@@ -34,29 +34,25 @@ int objects = 0, first = -1, last = -1; | |||
char *result; | |||
/* Main function */ | |||
char * slashdot_decode(char *image) | |||
char * decode_slashdot(struct image *img) | |||
{ | |||
struct image *img, *tmp, *tmp2; | |||
img = load_image(image); | |||
if(img == NULL) | |||
return NULL; | |||
struct image *tmp, *tmp2; | |||
/* Slashdot captchas have 7 characters */ | |||
result = malloc(8 * sizeof(char)); | |||
/* Clean image a bit */ | |||
tmp = detect_lines(img); | |||
tmp = fill_holes(tmp); | |||
tmp = filter_detect_lines(img); | |||
tmp = filter_fill_holes(tmp); | |||
/* Detect small objects to guess image orientation */ | |||
tmp2 = median(tmp); | |||
tmp2 = equalize(tmp2); | |||
tmp2 = filter_median(tmp); | |||
tmp2 = filter_equalize(tmp2); | |||
count_objects(tmp2); | |||
/* Invert rotation and find glyphs */ | |||
tmp = rotate(tmp); | |||
tmp = median(tmp); | |||
tmp = filter_median(tmp); | |||
tmp = find_glyphs(tmp); | |||
return result; | |||
@@ -71,7 +67,7 @@ static struct image *count_objects(struct image *img) | |||
int x, y, i; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -90,7 +86,7 @@ static struct image *count_objects(struct image *img) | |||
if(r == 50 && g == 50 && b == 50) | |||
{ | |||
gotblack = 1; | |||
flood_fill(dst, x, y, 255 - objects, 0, 0); | |||
filter_flood_fill(dst, x, y, 255 - objects, 0, 0); | |||
objects++; | |||
} | |||
} | |||
@@ -119,7 +115,7 @@ static struct image *count_objects(struct image *img) | |||
if(first == -1) | |||
first = i; | |||
last = i; | |||
flood_fill(dst, objlist[i].xmin, objlist[i].ymin, 0, 0, 255); | |||
filter_flood_fill(dst, objlist[i].xmin, objlist[i].ymin, 0, 0, 255); | |||
} | |||
} | |||
@@ -153,7 +149,7 @@ static struct image *rotate(struct image *img) | |||
cosa = -cosa; | |||
} | |||
dst = new_image(img->width * FACTOR, img->height * FACTOR); | |||
dst = image_new(img->width * FACTOR, img->height * FACTOR); | |||
for(y = 0; y < img->height * FACTOR; y++) | |||
for(x = 0; x < img->width * FACTOR; x++) | |||
@@ -186,7 +182,7 @@ static struct image *cut_cells(struct image *img) | |||
int x, y; | |||
int r, g, b; | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
@@ -221,7 +217,7 @@ static struct image *find_glyphs(struct image *img) | |||
} | |||
glyphs[22]; | |||
struct image *dst; | |||
struct image *font = load_image(FONTNAME); | |||
struct image *font = image_load(FONTNAME); | |||
int x, y, i = 0; | |||
int r, g, b; | |||
int xmin, xmax, ymin, ymax, incell = 0, count = 0, startx = 0, cur = 0; | |||
@@ -233,7 +229,7 @@ static struct image *find_glyphs(struct image *img) | |||
exit(-1); | |||
} | |||
dst = new_image(img->width, img->height); | |||
dst = image_new(img->width, img->height); | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||