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