* removed OLE code; it doesn't work and won't be needed. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/pwntcha/trunk@445 92316355-f0b4-4df1-b90c-862c8a59935fmaster
| @@ -19,16 +19,6 @@ pwntcha_CFLAGS = $(ADDITIONAL_CFLAGS) -Wall -O6 | |||||
| pwntcha_LDFLAGS = $(ADDITIONAL_LDFLAGS) | pwntcha_LDFLAGS = $(ADDITIONAL_LDFLAGS) | ||||
| pwntcha_LDADD = $(ADDITIONAL_LDADD) | pwntcha_LDADD = $(ADDITIONAL_LDADD) | ||||
| #if USE_DEVIL | |||||
| #ADDITIONAL_CFLAGS = | |||||
| #ADDITIONAL_LDFLAGS = | |||||
| #ADDITIONAL_LDADD = -lDevIL | |||||
| #else | |||||
| #if USE_OLE | |||||
| #ADDITIONAL_CFLAGS = | |||||
| #ADDITIONAL_LDFLAGS = | |||||
| #ADDITIONAL_LDADD = -luuid -loleaut32 -lole32 -lgdi32 | |||||
| #else | |||||
| if USE_SDL | if USE_SDL | ||||
| ADDITIONAL_CFLAGS = `sdl-config --cflags` | ADDITIONAL_CFLAGS = `sdl-config --cflags` | ||||
| ADDITIONAL_LDFLAGS = `sdl-config --libs` -lSDL_image | ADDITIONAL_LDFLAGS = `sdl-config --libs` -lSDL_image | ||||
| @@ -50,6 +40,4 @@ ADDITIONAL_LDADD = | |||||
| endif | endif | ||||
| endif | endif | ||||
| endif | endif | ||||
| #endif | |||||
| #endif | |||||
| @@ -26,7 +26,7 @@ char *decode_authimage(struct image *img) | |||||
| { | { | ||||
| char *all = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | char *all = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||||
| char *result; | char *result; | ||||
| struct image *tmp1, *tmp2, *tmp3; | |||||
| struct image *tmp; | |||||
| int x, y, r, g, b, i; | int x, y, r, g, b, i; | ||||
| if(!font) | if(!font) | ||||
| @@ -46,10 +46,11 @@ char *decode_authimage(struct image *img) | |||||
| memset(result, '\0', 7); | memset(result, '\0', 7); | ||||
| /* half the captchas are inverse video; we set them back to normal */ | /* half the captchas are inverse video; we set them back to normal */ | ||||
| tmp1 = filter_scale(img, 2.0); | |||||
| getpixel(img, 0, 0, &r, &g, &b); | |||||
| tmp2 = filter_equalize(tmp1, r * 3 / 4); | |||||
| tmp3 = filter_smooth(tmp2); | |||||
| 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); | |||||
| for(i = 0; i < 6; i++) | for(i = 0; i < 6; i++) | ||||
| { | { | ||||
| @@ -64,7 +65,7 @@ char *decode_authimage(struct image *img) | |||||
| int newx, newy, r2; | int newx, newy, r2; | ||||
| newx = 35.0 + (x + 6 * i) * 218.0 / 34.0 + y * 5.0 / 6.0 + 0.5; | 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; | newy = 33.0 - (x + 6 * i) * 18.0 / 34.0 + y * 42.0 / 6.0 + 0.5; | ||||
| getpixel(tmp3, newx, newy, &r, &g, &b); | |||||
| getpixel(tmp, newx, newy, &r, &g, &b); | |||||
| getpixel(font, x + 6 * ch, y, &r2, &g, &b); | getpixel(font, x + 6 * ch, y, &r2, &g, &b); | ||||
| r = (r < 220) ? 0 : 255; | r = (r < 220) ? 0 : 255; | ||||
| diff += (r - r2) * (r - r2); | diff += (r - r2) * (r - r2); | ||||
| @@ -79,9 +80,7 @@ char *decode_authimage(struct image *img) | |||||
| result[i] = all[minch]; | result[i] = all[minch]; | ||||
| } | } | ||||
| image_free(tmp3); | |||||
| image_free(tmp2); | |||||
| image_free(tmp1); | |||||
| image_free(tmp); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -17,7 +17,7 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "common.h" | #include "common.h" | ||||
| static struct image *find_glyphs(struct image *img); | |||||
| static void find_glyphs(struct image *img); | |||||
| /* Our macros */ | /* Our macros */ | ||||
| #define FONTNAME "font_clubic.png" | #define FONTNAME "font_clubic.png" | ||||
| @@ -27,7 +27,7 @@ char *result; | |||||
| /* Main function */ | /* Main function */ | ||||
| char *decode_clubic(struct image *img) | char *decode_clubic(struct image *img) | ||||
| { | { | ||||
| struct image *tmp1, *tmp2; | |||||
| struct image *tmp; | |||||
| if(!font) | if(!font) | ||||
| { | { | ||||
| @@ -45,16 +45,16 @@ char *decode_clubic(struct image *img) | |||||
| result = malloc(7 * sizeof(char)); | result = malloc(7 * sizeof(char)); | ||||
| strcpy(result, " "); | strcpy(result, " "); | ||||
| tmp1 = filter_equalize(img, 200); | |||||
| tmp2 = find_glyphs(tmp1); | |||||
| tmp = image_dup(img); | |||||
| filter_equalize(tmp, 200); | |||||
| find_glyphs(tmp); | |||||
| image_free(tmp1); | |||||
| image_free(tmp2); | |||||
| image_free(tmp); | |||||
| return result; | return result; | ||||
| } | } | ||||
| static struct image *find_glyphs(struct image *img) | |||||
| static void find_glyphs(struct image *img) | |||||
| { | { | ||||
| char all[] = "0123456789"; | char all[] = "0123456789"; | ||||
| struct | struct | ||||
| @@ -63,19 +63,19 @@ static struct image *find_glyphs(struct image *img) | |||||
| int count; | int count; | ||||
| } | } | ||||
| glyphs[10]; | glyphs[10]; | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| 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; | ||||
| int distmin, distx, disty, distch; | int distmin, distx, disty, distch; | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = 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++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, 255, g, 255); | |||||
| setpixel(tmp, x, y, 255, g, 255); | |||||
| } | } | ||||
| for(x = 0; x < font->width; x++) | for(x = 0; x < font->width; x++) | ||||
| @@ -168,13 +168,13 @@ static struct image *find_glyphs(struct image *img) | |||||
| { | { | ||||
| getpixel(font, xmin + x, ymin + y, &r, &g, &b); | getpixel(font, xmin + x, ymin + y, &r, &g, &b); | ||||
| if(r > 128) continue; | if(r > 128) continue; | ||||
| setpixel(dst, distx + x, disty + y, r, g, b); | |||||
| setpixel(tmp, distx + x, disty + y, r, g, b); | |||||
| } | } | ||||
| startx = distx + xmax - xmin; | startx = distx + xmax - xmin; | ||||
| result[cur++] = all[distch]; | result[cur++] = all[distch]; | ||||
| } | } | ||||
| return dst; | |||||
| image_free(tmp); | |||||
| } | } | ||||
| @@ -37,25 +37,25 @@ char *decode_test(struct image *img); | |||||
| /* image operations */ | /* image operations */ | ||||
| struct image *image_load(const char *name); | struct image *image_load(const char *name); | ||||
| struct image *image_new(int width, int height); | struct image *image_new(int width, int height); | ||||
| struct image *image_dup(struct image *img); | |||||
| void image_free(struct image *img); | void image_free(struct image *img); | ||||
| void image_save(struct image *img, const char *name); | void image_save(struct image *img, const char *name); | ||||
| void image_swap(struct image *img1, struct image *img2); | |||||
| 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 filter_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); | ||||
| struct image *filter_fill_holes(struct image *img); | |||||
| struct image *filter_dup(struct image *img); | |||||
| struct image *filter_scale(struct image *img, float ratio); | |||||
| struct image *filter_black_stuff(struct image *img); | |||||
| struct image *filter_detect_lines(struct image *img); | |||||
| struct image *filter_equalize(struct image *img, int threshold); | |||||
| struct image *filter_trick(struct image *img); | |||||
| struct image *filter_smooth(struct image *img); | |||||
| struct image *filter_median(struct image *img); | |||||
| struct image *filter_contrast(struct image *img); | |||||
| struct image *filter_crop(struct image *img, | |||||
| int xmin, int ymin, int xmax, int ymax); | |||||
| void filter_fill_holes(struct image *img); | |||||
| void filter_scale(struct image *img, float ratio); | |||||
| void filter_black_stuff(struct image *img); | |||||
| void filter_detect_lines(struct image *img); | |||||
| void filter_equalize(struct image *img, int threshold); | |||||
| void filter_trick(struct image *img); | |||||
| void filter_smooth(struct image *img); | |||||
| void filter_median(struct image *img); | |||||
| void filter_contrast(struct image *img); | |||||
| void filter_crop(struct image *img, int xmin, int ymin, int xmax, int ymax); | |||||
| int filter_count(struct image *img); | int filter_count(struct image *img); | ||||
| @@ -46,25 +46,7 @@ void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b) | |||||
| filter_flood_fill(img, x, y - 1, r, g, b); | filter_flood_fill(img, x, y - 1, r, g, b); | ||||
| } | } | ||||
| struct image *filter_dup(struct image *img) | |||||
| { | |||||
| struct image *dst; | |||||
| int x, y; | |||||
| int r, g, b; | |||||
| dst = 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(dst, x, y, r, g, b); | |||||
| } | |||||
| return dst; | |||||
| } | |||||
| struct image *filter_scale(struct image *img, float ratio) | |||||
| void filter_scale(struct image *img, float ratio) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int w, h, x, y; | int w, h, x, y; | ||||
| @@ -82,10 +64,11 @@ struct image *filter_scale(struct image *img, float ratio) | |||||
| setpixel(dst, x, y, r, g, b); | setpixel(dst, x, y, r, g, b); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_fill_holes(struct image *img) | |||||
| void filter_fill_holes(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| @@ -132,10 +115,11 @@ struct image *filter_fill_holes(struct image *img) | |||||
| setpixel(dst, x, y, c3, c3, c3); | setpixel(dst, x, y, c3, c3, c3); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_black_stuff(struct image *img) | |||||
| void filter_black_stuff(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| @@ -172,10 +156,11 @@ struct image *filter_black_stuff(struct image *img) | |||||
| } | } | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_detect_lines(struct image *img) | |||||
| void filter_detect_lines(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| @@ -212,10 +197,11 @@ struct image *filter_detect_lines(struct image *img) | |||||
| } | } | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_equalize(struct image *img, int threshold) | |||||
| void filter_equalize(struct image *img, int threshold) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| @@ -243,10 +229,11 @@ struct image *filter_equalize(struct image *img, int threshold) | |||||
| setpixel(dst, x, y, max, max, max); | setpixel(dst, x, y, max, max, max); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_trick(struct image *img) | |||||
| void filter_trick(struct image *img) | |||||
| { | { | ||||
| #define TSIZE 3 | #define TSIZE 3 | ||||
| struct image *dst; | struct image *dst; | ||||
| @@ -289,10 +276,11 @@ struct image *filter_trick(struct image *img) | |||||
| setpixel(dst, x, y, i, i, i); | setpixel(dst, x, y, i, i, i); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_smooth(struct image *img) | |||||
| void filter_smooth(struct image *img) | |||||
| { | { | ||||
| #define SSIZE 3 | #define SSIZE 3 | ||||
| struct image *dst; | struct image *dst; | ||||
| @@ -320,10 +308,11 @@ struct image *filter_smooth(struct image *img) | |||||
| setpixel(dst, x, y, i, i, i); | setpixel(dst, x, y, i, i, i); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_median(struct image *img) | |||||
| void filter_median(struct image *img) | |||||
| { | { | ||||
| #define MSIZE 3 | #define MSIZE 3 | ||||
| struct image *dst; | struct image *dst; | ||||
| @@ -360,10 +349,11 @@ struct image *filter_median(struct image *img) | |||||
| setpixel(dst, x, y, i, i, i); | setpixel(dst, x, y, i, i, i); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_contrast(struct image *img) | |||||
| void filter_contrast(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int histo[256]; | int histo[256]; | ||||
| @@ -393,11 +383,11 @@ struct image *filter_contrast(struct image *img) | |||||
| setpixel(dst, x, y, histo[r], histo[r], histo[r]); | setpixel(dst, x, y, histo[r], histo[r], histo[r]); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| struct image *filter_crop(struct image *img, | |||||
| int xmin, int ymin, int xmax, int ymax) | |||||
| void filter_crop(struct image *img, int xmin, int ymin, int xmax, int ymax) | |||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| @@ -413,7 +403,7 @@ struct image *filter_crop(struct image *img, | |||||
| ymax = img->height - 1; | ymax = img->height - 1; | ||||
| if(xmin >= xmax || ymin >= ymax) | if(xmin >= xmax || ymin >= ymax) | ||||
| return NULL; | |||||
| return; | |||||
| dst = image_new(xmax - xmin, ymax - ymin); | dst = image_new(xmax - xmin, ymax - ymin); | ||||
| @@ -424,7 +414,8 @@ struct image *filter_crop(struct image *img, | |||||
| setpixel(dst, x, y, r, g, b); | setpixel(dst, x, y, r, g, b); | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, dst); | |||||
| image_free(dst); | |||||
| } | } | ||||
| int filter_count(struct image *img) | int filter_count(struct image *img) | ||||
| @@ -11,23 +11,12 @@ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "common.h" | #include "common.h" | ||||
| #if defined(HAVE_IL_H) | |||||
| # error "DevIL routines not implemented yet" | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| # include <windows.h> | |||||
| # include <ocidl.h> | |||||
| # include <olectl.h> | |||||
| static BOOL oleload(LPCTSTR name, LPPICTURE* pic); | |||||
| struct priv | |||||
| { | |||||
| HBITMAP bitmap; | |||||
| BITMAPINFO info; | |||||
| }; | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| # include <SDL_image.h> | # include <SDL_image.h> | ||||
| #elif defined(HAVE_IMLIB2_H) | #elif defined(HAVE_IMLIB2_H) | ||||
| # include <Imlib2.h> | # include <Imlib2.h> | ||||
| @@ -41,15 +30,7 @@ struct priv | |||||
| struct image *image_load(const char *name) | struct image *image_load(const char *name) | ||||
| { | { | ||||
| struct image *img; | struct image *img; | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| struct priv *priv = malloc(sizeof(struct priv)); | |||||
| LPPICTURE pic = NULL; | |||||
| HDC dc; | |||||
| long scrwidth = 0, scrheight = 0; | |||||
| int width, height; | |||||
| void *data = NULL; | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| SDL_Surface *priv = IMG_Load(name); | SDL_Surface *priv = IMG_Load(name); | ||||
| #elif defined(HAVE_IMLIB2_H) | #elif defined(HAVE_IMLIB2_H) | ||||
| Imlib_Image priv = imlib_load_image(name); | Imlib_Image priv = imlib_load_image(name); | ||||
| @@ -60,57 +41,7 @@ struct image *image_load(const char *name) | |||||
| if(!priv) | if(!priv) | ||||
| return NULL; | return NULL; | ||||
| #if defined(HAVE_OLECTL_H) | |||||
| if(!oleload((LPCTSTR)name, &pic)) | |||||
| { | |||||
| free(priv); | |||||
| return NULL; | |||||
| } | |||||
| #if 0 | |||||
| for(i = 0; ; i++) | |||||
| { | |||||
| DEVMODE devMode; | |||||
| devMode.dmSize = sizeof(DEVMODE); | |||||
| if(EnumDisplaySettings(NULL, i, &devMode) != 1) | |||||
| break; | |||||
| printf("mode %i x %i - %i\n", (int)devMode.dmPelsWidth, | |||||
| (int)devMode.dmPelsHeight, (int)devMode.dmBitsPerPel); | |||||
| } | |||||
| #endif | |||||
| dc = CreateCompatibleDC(NULL); | |||||
| if(GetDeviceCaps(dc, BITSPIXEL) < 24) | |||||
| { | |||||
| fprintf(stderr, "%s: 24bpp screen depth or better required\n", argv0); | |||||
| DeleteDC(dc); | |||||
| free(priv); | |||||
| return NULL; | |||||
| } | |||||
| pic->lpVtbl->get_Width(pic, &scrwidth); | |||||
| pic->lpVtbl->get_Height(pic, &scrheight); | |||||
| width = (scrwidth * GetDeviceCaps(dc, LOGPIXELSX) + 2540 / 2) / 2540; | |||||
| height = (scrheight * GetDeviceCaps(dc, LOGPIXELSY) + 2540 / 2) / 2540; | |||||
| memset(&priv->info, 0, sizeof(BITMAPINFO)); | |||||
| priv->info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |||||
| priv->info.bmiHeader.biBitCount = 24; | |||||
| priv->info.bmiHeader.biWidth = width; | |||||
| priv->info.bmiHeader.biHeight = -height; | |||||
| priv->info.bmiHeader.biCompression = BI_RGB; | |||||
| priv->info.bmiHeader.biPlanes = 1; | |||||
| priv->bitmap = CreateDIBSection(dc, &priv->info, DIB_RGB_COLORS, &data, 0, 0); | |||||
| SelectObject(dc, priv->bitmap); | |||||
| pic->lpVtbl->Render(pic, dc, 0, 0, width, height, | |||||
| 0, scrheight, scrwidth, -scrheight, NULL); | |||||
| pic->lpVtbl->Release(pic); | |||||
| DeleteDC(dc); | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| if(priv->format->BytesPerPixel == 1) | if(priv->format->BytesPerPixel == 1) | ||||
| { | { | ||||
| img = image_new(priv->w, priv->h); | img = image_new(priv->w, priv->h); | ||||
| @@ -121,14 +52,7 @@ struct image *image_load(const char *name) | |||||
| #endif | #endif | ||||
| img = (struct image *)malloc(sizeof(struct image)); | img = (struct image *)malloc(sizeof(struct image)); | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| img->width = width; | |||||
| img->height = height; | |||||
| img->pitch = 3 * width; | |||||
| img->channels = 3; | |||||
| img->pixels = data; | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| img->width = priv->w; | img->width = priv->w; | ||||
| img->height = priv->h; | img->height = priv->h; | ||||
| img->pitch = priv->pitch; | img->pitch = priv->pitch; | ||||
| @@ -156,12 +80,7 @@ struct image *image_load(const char *name) | |||||
| struct image *image_new(int width, int height) | struct image *image_new(int width, int height) | ||||
| { | { | ||||
| struct image *img; | struct image *img; | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| struct priv *priv = malloc(sizeof(struct priv)); | |||||
| HDC dc; | |||||
| void *data = NULL; | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| SDL_Surface *priv; | SDL_Surface *priv; | ||||
| Uint32 rmask, gmask, bmask, amask; | Uint32 rmask, gmask, bmask, amask; | ||||
| # if SDL_BYTEORDER == SDL_BIG_ENDIAN | # if SDL_BYTEORDER == SDL_BIG_ENDIAN | ||||
| @@ -187,31 +106,7 @@ struct image *image_new(int width, int height) | |||||
| return NULL; | return NULL; | ||||
| img = (struct image *)malloc(sizeof(struct image)); | img = (struct image *)malloc(sizeof(struct image)); | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| dc = CreateCompatibleDC(NULL); | |||||
| if(GetDeviceCaps(dc, BITSPIXEL) < 24) | |||||
| { | |||||
| fprintf(stderr, "a screen depth of at least 24bpp is required\n"); | |||||
| DeleteDC(dc); | |||||
| free(priv); | |||||
| return NULL; | |||||
| } | |||||
| priv->info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |||||
| priv->info.bmiHeader.biWidth = width; | |||||
| priv->info.bmiHeader.biHeight = -height; | |||||
| priv->info.bmiHeader.biCompression = BI_RGB; | |||||
| priv->info.bmiHeader.biBitCount = 24; | |||||
| priv->info.bmiHeader.biPlanes = 1; | |||||
| priv->bitmap = CreateDIBSection(dc, &priv->info, | |||||
| DIB_RGB_COLORS, &data, 0, 0); | |||||
| DeleteDC(dc); | |||||
| img->width = width; | |||||
| img->height = height; | |||||
| img->pitch = 3 * width; | |||||
| img->channels = 3; | |||||
| img->pixels = data; | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| img->width = priv->w; | img->width = priv->w; | ||||
| img->height = priv->h; | img->height = priv->h; | ||||
| img->pitch = priv->pitch; | img->pitch = priv->pitch; | ||||
| @@ -236,14 +131,26 @@ struct image *image_new(int width, int height) | |||||
| return img; | return img; | ||||
| } | } | ||||
| struct image *image_dup(struct image *img) | |||||
| { | |||||
| struct image *dst; | |||||
| int x, y; | |||||
| dst = image_new(img->width, img->height); | |||||
| for(y = 0; y < img->height; y++) | |||||
| { | |||||
| for(x = 0; x < img->width; x++) | |||||
| { | |||||
| int r, g, b; | |||||
| getpixel(img, x, y, &r, &g, &b); | |||||
| setpixel(dst, x, y, r, g, b); | |||||
| } | |||||
| } | |||||
| return dst; | |||||
| } | |||||
| void image_free(struct image *img) | void image_free(struct image *img) | ||||
| { | { | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| struct priv *priv = img->priv; | |||||
| DeleteObject(priv->bitmap); | |||||
| free(img->priv); | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| SDL_FreeSurface(img->priv); | SDL_FreeSurface(img->priv); | ||||
| #elif defined(HAVE_IMLIB2_H) | #elif defined(HAVE_IMLIB2_H) | ||||
| imlib_context_set_image(img->priv); | imlib_context_set_image(img->priv); | ||||
| @@ -259,10 +166,7 @@ void image_free(struct image *img) | |||||
| void image_save(struct image *img, const char *name) | void image_save(struct image *img, const char *name) | ||||
| { | { | ||||
| #if defined(HAVE_IL_H) | |||||
| #elif defined(HAVE_OLECTL_H) | |||||
| #elif defined(HAVE_SDL_IMAGE_H) | |||||
| #if defined(HAVE_SDL_IMAGE_H) | |||||
| SDL_SaveBMP(img->priv, name); | SDL_SaveBMP(img->priv, name); | ||||
| #elif defined(HAVE_IMLIB2_H) | #elif defined(HAVE_IMLIB2_H) | ||||
| imlib_context_set_image(img->priv); | imlib_context_set_image(img->priv); | ||||
| @@ -272,6 +176,14 @@ void image_save(struct image *img, const char *name) | |||||
| #endif | #endif | ||||
| } | } | ||||
| void image_swap(struct image *img1, struct image *img2) | |||||
| { | |||||
| struct image tmp; | |||||
| memcpy(&tmp, img1, sizeof(tmp)); | |||||
| memcpy(img1, img2, sizeof(tmp)); | |||||
| memcpy(img2, &tmp, sizeof(tmp)); | |||||
| } | |||||
| int getgray(struct image *img, int x, int y, int *g) | int getgray(struct image *img, int x, int y, int *g) | ||||
| { | { | ||||
| if(x < 0 || y < 0 || x >= img->width || y >= img->height) | if(x < 0 || y < 0 || x >= img->width || y >= img->height) | ||||
| @@ -314,73 +226,3 @@ int setpixel(struct image *img, int x, int y, int r, int g, int b) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #if defined(HAVE_OLECTL_H) | |||||
| static BOOL oleload(LPCTSTR name, LPPICTURE* pic) | |||||
| { | |||||
| HRESULT ret; | |||||
| HANDLE h; | |||||
| DWORD size, read = 0; | |||||
| LPVOID data; | |||||
| HGLOBAL buffer; | |||||
| LPSTREAM stream = NULL; | |||||
| h = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); | |||||
| if (h == INVALID_HANDLE_VALUE) | |||||
| return FALSE; | |||||
| size = GetFileSize(h, NULL); | |||||
| if(size == (DWORD)-1) | |||||
| { | |||||
| CloseHandle(h); | |||||
| return FALSE; | |||||
| } | |||||
| buffer = GlobalAlloc(GMEM_MOVEABLE, size); | |||||
| if(!buffer) | |||||
| { | |||||
| CloseHandle(h); | |||||
| return FALSE; | |||||
| } | |||||
| data = GlobalLock(buffer); | |||||
| if(!data) | |||||
| { | |||||
| GlobalUnlock(buffer); | |||||
| CloseHandle(h); | |||||
| return FALSE; | |||||
| } | |||||
| ret = ReadFile(h, data, size, &read, NULL); | |||||
| GlobalUnlock(buffer); | |||||
| CloseHandle(h); | |||||
| if(!ret) | |||||
| return FALSE; | |||||
| ret = CreateStreamOnHGlobal(buffer, TRUE, &stream); | |||||
| if(!SUCCEEDED(ret)) | |||||
| { | |||||
| if(stream) | |||||
| stream->lpVtbl->Release(stream); | |||||
| return FALSE; | |||||
| } | |||||
| if(!stream) | |||||
| return FALSE; | |||||
| if(*pic) | |||||
| (*pic)->lpVtbl->Release(*pic); | |||||
| ret = OleLoadPicture(stream, size, FALSE, &IID_IPicture, (PVOID *)pic); | |||||
| stream->lpVtbl->Release(stream); | |||||
| if(!SUCCEEDED(ret)) | |||||
| return FALSE; | |||||
| if(!*pic) | |||||
| return FALSE; | |||||
| return TRUE; | |||||
| } | |||||
| #endif | |||||
| @@ -47,12 +47,13 @@ char *decode_linuxfr(struct image *img) | |||||
| result = malloc(8 * sizeof(char)); | result = malloc(8 * sizeof(char)); | ||||
| memset(result, '\0', 8); | memset(result, '\0', 8); | ||||
| tmp = filter_equalize(img, 150); | |||||
| tmp = image_dup(img); | |||||
| filter_equalize(tmp, 150); | |||||
| for(y = 0; y < img->height; y++) | |||||
| for(y = 0; y < tmp->height; y++) | |||||
| { | { | ||||
| int count = 0; | int count = 0; | ||||
| for(x = 0; x < img->width; x++) | |||||
| for(x = 0; x < tmp->width; x++) | |||||
| { | { | ||||
| getpixel(tmp, x, y, &r, &g, &b); | getpixel(tmp, x, y, &r, &g, &b); | ||||
| if(r == 0) | if(r == 0) | ||||
| @@ -63,7 +64,7 @@ char *decode_linuxfr(struct image *img) | |||||
| /* Find 7 consecutive lines that have at least 14 pixels; they're | /* Find 7 consecutive lines that have at least 14 pixels; they're | ||||
| * baseline candidates */ | * baseline candidates */ | ||||
| for(y = 0; y < img->height - 11; y++) | |||||
| for(y = 0; y < tmp->height - 11; y++) | |||||
| { | { | ||||
| int ycan = 1; | int ycan = 1; | ||||
| for(j = 3; j < 10; j++) | for(j = 3; j < 10; j++) | ||||
| @@ -80,7 +81,7 @@ char *decode_linuxfr(struct image *img) | |||||
| /* Find 7 consecutive cells that have at least 2 pixels on | /* Find 7 consecutive cells that have at least 2 pixels on | ||||
| * each line; they're base column candidates */ | * each line; they're base column candidates */ | ||||
| for(x = 0; x < img->width - 9 * 7 + 1; x++) | |||||
| for(x = 0; x < tmp->width - 9 * 7 + 1; x++) | |||||
| { | { | ||||
| int goodx = 1; | int goodx = 1; | ||||
| for(c = 0; c < 7 && goodx; c++) | for(c = 0; c < 7 && goodx; c++) | ||||
| @@ -26,7 +26,7 @@ char *decode_phpbb(struct image *img) | |||||
| { | { | ||||
| char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; | char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; | ||||
| char *result; | char *result; | ||||
| struct image *tmp1, *tmp2, *tmp3; | |||||
| struct image *tmp1, *tmp2; | |||||
| int x, y, i = 0; | int x, y, i = 0; | ||||
| int r, g, b; | int r, g, b; | ||||
| int xmin, xmax, ymin, ymax, cur, offset = -1; | int xmin, xmax, ymin, ymax, cur, offset = -1; | ||||
| @@ -48,18 +48,20 @@ char *decode_phpbb(struct image *img) | |||||
| result = malloc(7 * sizeof(char)); | result = malloc(7 * sizeof(char)); | ||||
| strcpy(result, " "); | strcpy(result, " "); | ||||
| tmp1 = filter_smooth(img); | |||||
| tmp2 = filter_equalize(tmp1, 128); | |||||
| tmp3 = image_new(img->width, img->height); | |||||
| tmp1 = image_dup(img); | |||||
| tmp2 = image_new(img->width, img->height); | |||||
| filter_smooth(tmp1); | |||||
| filter_equalize(tmp1, 128); | |||||
| for(x = 0; x < img->width; x++) | for(x = 0; x < img->width; x++) | ||||
| for(y = 0; y < img->height; y++) | for(y = 0; y < img->height; y++) | ||||
| { | { | ||||
| getpixel(tmp2, x, y, &r, &g, &b); | |||||
| getpixel(tmp1, x, y, &r, &g, &b); | |||||
| if(r == 0 && offset == -1) | if(r == 0 && offset == -1) | ||||
| offset = x; | offset = x; | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(tmp3, x, y, 255, g, 255); | |||||
| setpixel(tmp2, x, y, 255, g, 255); | |||||
| } | } | ||||
| for(cur = 0; cur < 6; cur++) | for(cur = 0; cur < 6; cur++) | ||||
| @@ -89,7 +91,7 @@ char *decode_phpbb(struct image *img) | |||||
| { | { | ||||
| int r2; | int r2; | ||||
| getgray(font, xmin + z, ymin + t, &r); | getgray(font, xmin + z, ymin + t, &r); | ||||
| getgray(tmp2, x + z, y + t, &r2); | |||||
| getgray(tmp1, x + z, y + t, &r2); | |||||
| if(r > r2) | if(r > r2) | ||||
| dist += r - r2; | dist += r - r2; | ||||
| else | else | ||||
| @@ -123,8 +125,8 @@ char *decode_phpbb(struct image *img) | |||||
| int r2; | int r2; | ||||
| getpixel(font, xmin + x, ymin + y, &r2, &g, &b); | getpixel(font, xmin + x, ymin + y, &r2, &g, &b); | ||||
| if(r2 > 128) continue; | if(r2 > 128) continue; | ||||
| getpixel(tmp3, distx + x, disty + y, &r, &g, &b); | |||||
| setpixel(tmp3, distx + x, disty + y, r2, g, b); | |||||
| getpixel(tmp2, distx + x, disty + y, &r, &g, &b); | |||||
| setpixel(tmp2, distx + x, disty + y, r2, g, b); | |||||
| } | } | ||||
| offset = distx + xmax - xmin; | offset = distx + xmax - xmin; | ||||
| @@ -133,7 +135,6 @@ char *decode_phpbb(struct image *img) | |||||
| image_free(tmp1); | image_free(tmp1); | ||||
| image_free(tmp2); | image_free(tmp2); | ||||
| image_free(tmp3); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -30,7 +30,7 @@ char *decode_scode(struct image *img) | |||||
| /* allocate enough place */ | /* allocate enough place */ | ||||
| result = malloc(1024 * sizeof(char)); | result = malloc(1024 * sizeof(char)); | ||||
| tmp1 = filter_dup(img); | |||||
| tmp1 = image_dup(img); | |||||
| /* Remove border */ | /* Remove border */ | ||||
| getpixel(img, 1, 1, &r, &g, &b); | getpixel(img, 1, 1, &r, &g, &b); | ||||
| @@ -18,10 +18,10 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "common.h" | #include "common.h" | ||||
| static struct image *count_objects(struct image *img); | |||||
| static struct image *rotate(struct image *img); | |||||
| static struct image *cut_cells(struct image *img); | |||||
| static struct image *find_glyphs(struct image *img); | |||||
| 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 */ | /* Our macros */ | ||||
| #define FACTOR 1 | #define FACTOR 1 | ||||
| @@ -38,7 +38,7 @@ char *result; | |||||
| /* Main function */ | /* Main function */ | ||||
| char *decode_slashdot(struct image *img) | char *decode_slashdot(struct image *img) | ||||
| { | { | ||||
| struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; | |||||
| struct image *tmp1, *tmp2; | |||||
| /* Initialise local data */ | /* Initialise local data */ | ||||
| objects = 0; | objects = 0; | ||||
| @@ -50,27 +50,24 @@ char *decode_slashdot(struct image *img) | |||||
| strcpy(result, " "); | strcpy(result, " "); | ||||
| /* Clean image a bit */ | /* Clean image a bit */ | ||||
| tmp1 = filter_detect_lines(img); | |||||
| tmp2 = filter_fill_holes(tmp1); | |||||
| tmp1 = image_dup(img); | |||||
| filter_detect_lines(tmp1); | |||||
| filter_fill_holes(tmp1); | |||||
| /* Detect small objects to guess image orientation */ | /* Detect small objects to guess image orientation */ | ||||
| tmp3 = filter_median(tmp2); | |||||
| tmp4 = filter_equalize(tmp3, 200); | |||||
| count_objects(tmp4); | |||||
| tmp2 = image_dup(tmp1); | |||||
| filter_median(tmp2); | |||||
| filter_equalize(tmp2, 200); | |||||
| count_objects(tmp2); | |||||
| /* Invert rotation and find glyphs */ | /* Invert rotation and find glyphs */ | ||||
| tmp5 = rotate(tmp2); | |||||
| tmp6 = filter_median(tmp5); | |||||
| tmp7 = find_glyphs(tmp6); | |||||
| rotate(tmp1); | |||||
| filter_median(tmp1); | |||||
| find_glyphs(tmp1); | |||||
| /* Clean up our mess */ | /* Clean up our mess */ | ||||
| image_free(tmp1); | image_free(tmp1); | ||||
| image_free(tmp2); | image_free(tmp2); | ||||
| image_free(tmp3); | |||||
| image_free(tmp4); | |||||
| image_free(tmp5); | |||||
| image_free(tmp6); | |||||
| image_free(tmp7); | |||||
| /* aaaaaaa means decoding failed */ | /* aaaaaaa means decoding failed */ | ||||
| if(!strcmp(result, "aaaaaaa")) | if(!strcmp(result, "aaaaaaa")) | ||||
| @@ -81,33 +78,33 @@ char *decode_slashdot(struct image *img) | |||||
| /* The following functions are local */ | /* The following functions are local */ | ||||
| static struct image *count_objects(struct image *img) | |||||
| static void count_objects(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| int gotblack = 1; | int gotblack = 1; | ||||
| int x, y, i; | int x, y, i; | ||||
| int r, g, b; | int r, g, b; | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = 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++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, r, g, b); | |||||
| setpixel(tmp, x, y, r, g, b); | |||||
| } | } | ||||
| while(gotblack) | while(gotblack) | ||||
| { | { | ||||
| gotblack = 0; | gotblack = 0; | ||||
| for(y = 0; y < dst->height; y++) | |||||
| for(x = 0; x < dst->width; x++) | |||||
| for(y = 0; y < tmp->height; y++) | |||||
| for(x = 0; x < tmp->width; x++) | |||||
| { | { | ||||
| getpixel(dst, x, y, &r, &g, &b); | |||||
| getpixel(tmp, x, y, &r, &g, &b); | |||||
| if(r == 0 && g == 0 && b == 0) | if(r == 0 && g == 0 && b == 0) | ||||
| { | { | ||||
| gotblack = 1; | gotblack = 1; | ||||
| filter_flood_fill(dst, x, y, 254 - objects, 0, 0); | |||||
| filter_flood_fill(tmp, x, y, 254 - objects, 0, 0); | |||||
| objects++; | objects++; | ||||
| } | } | ||||
| } | } | ||||
| @@ -117,13 +114,13 @@ static struct image *count_objects(struct image *img) | |||||
| for(i = 0; i < objects; i++) | for(i = 0; i < objects; i++) | ||||
| { | { | ||||
| objlist[i].ymin = dst->height; | |||||
| objlist[i].ymin = tmp->height; | |||||
| objlist[i].ymax = 0; | objlist[i].ymax = 0; | ||||
| for(y = 0; y < dst->height; y++) | |||||
| for(x = 0; x < dst->width; x++) | |||||
| for(y = 0; y < tmp->height; y++) | |||||
| for(x = 0; x < tmp->width; x++) | |||||
| { | { | ||||
| getpixel(dst, x, y, &r, &g, &b); | |||||
| getpixel(tmp, x, y, &r, &g, &b); | |||||
| if(r == 255 - i && g == 0 && b == 0) | if(r == 255 - i && g == 0 && b == 0) | ||||
| { | { | ||||
| if(y < objlist[i].ymin) { objlist[i].ymin = y; objlist[i].xmin = x; } | if(y < objlist[i].ymin) { objlist[i].ymin = y; objlist[i].xmin = x; } | ||||
| @@ -136,7 +133,7 @@ static struct image *count_objects(struct image *img) | |||||
| if(first == -1) | if(first == -1) | ||||
| first = i; | first = i; | ||||
| last = i; | last = i; | ||||
| filter_flood_fill(dst, objlist[i].xmin, objlist[i].ymin, 0, 0, 255); | |||||
| filter_flood_fill(tmp, objlist[i].xmin, objlist[i].ymin, 0, 0, 255); | |||||
| } | } | ||||
| } | } | ||||
| @@ -146,16 +143,17 @@ static struct image *count_objects(struct image *img) | |||||
| A.y = (objlist[first].ymin + objlist[first].ymax) / 2; | A.y = (objlist[first].ymin + objlist[first].ymax) / 2; | ||||
| B.x = (objlist[last].xmin + objlist[last].xmax) / 2; | B.x = (objlist[last].xmin + objlist[last].xmax) / 2; | ||||
| B.y = (objlist[last].ymin + objlist[last].ymax) / 2; | B.y = (objlist[last].ymin + objlist[last].ymax) / 2; | ||||
| cvLine(dst, A, B, 0, 2.0, 0); | |||||
| cvLine(tmp, A, B, 0, 2.0, 0); | |||||
| } | } | ||||
| #endif | #endif | ||||
| return dst; | |||||
| image_swap(img, tmp); | |||||
| image_free(tmp); | |||||
| } | } | ||||
| static struct image *rotate(struct image *img) | |||||
| static void rotate(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| int x, y, xdest, ydest; | int x, y, xdest, ydest; | ||||
| int r, g, b; | int r, g, b; | ||||
| //int R, G, B; | //int R, G, B; | ||||
| @@ -170,7 +168,7 @@ static struct image *rotate(struct image *img) | |||||
| cosa = -cosa; | cosa = -cosa; | ||||
| } | } | ||||
| dst = image_new(img->width * FACTOR, img->height * FACTOR); | |||||
| tmp = 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++) | ||||
| @@ -191,44 +189,46 @@ static struct image *rotate(struct image *img) | |||||
| //r = R / 4; g = G / 4; b = B / 4; | //r = R / 4; g = G / 4; b = B / 4; | ||||
| if(r == 255 && g == 0 && b == 255) | if(r == 255 && g == 0 && b == 255) | ||||
| g = 255; | g = 255; | ||||
| setpixel(dst, x, y, r, g, b); | |||||
| setpixel(tmp, x, y, r, g, b); | |||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, tmp); | |||||
| image_free(tmp); | |||||
| } | } | ||||
| static struct image *cut_cells(struct image *img) | |||||
| static void cut_cells(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| int x, y; | int x, y; | ||||
| int r, g, b; | int r, g, b; | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = 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++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, r, g, b); | |||||
| setpixel(tmp, x, y, r, g, b); | |||||
| } | } | ||||
| for(x = 0; x < img->width; x++) | for(x = 0; x < img->width; x++) | ||||
| { | { | ||||
| setpixel(dst, x, 0, 255, 255, 255); | |||||
| setpixel(dst, x, img->height - 1, 255, 255, 255); | |||||
| setpixel(tmp, x, 0, 255, 255, 255); | |||||
| setpixel(tmp, x, img->height - 1, 255, 255, 255); | |||||
| } | } | ||||
| for(y = 0; y < img->height; y++) | for(y = 0; y < img->height; y++) | ||||
| for(x = 0; x < 7; x++) | for(x = 0; x < 7; x++) | ||||
| { | { | ||||
| setpixel(dst, x * img->width / 7, y, 255, 255, 255); | |||||
| setpixel(dst, (x + 1) * img->width / 7 - 1, y, 255, 255, 255); | |||||
| setpixel(tmp, x * img->width / 7, y, 255, 255, 255); | |||||
| setpixel(tmp, (x + 1) * img->width / 7 - 1, y, 255, 255, 255); | |||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, tmp); | |||||
| image_free(tmp); | |||||
| } | } | ||||
| static struct image *find_glyphs(struct image *img) | |||||
| static void find_glyphs(struct image *img) | |||||
| { | { | ||||
| char all[] = "abcdefgijkmnpqrstvwxyz"; | char all[] = "abcdefgijkmnpqrstvwxyz"; | ||||
| struct | struct | ||||
| @@ -237,7 +237,7 @@ static struct image *find_glyphs(struct image *img) | |||||
| int count; | int count; | ||||
| } | } | ||||
| glyphs[22]; | glyphs[22]; | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| 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; | ||||
| @@ -255,13 +255,13 @@ static struct image *find_glyphs(struct image *img) | |||||
| } | } | ||||
| } | } | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = 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++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, 255, g, 255); | |||||
| setpixel(tmp, x, y, 255, g, 255); | |||||
| } | } | ||||
| for(x = 0; x < font->width; x++) | for(x = 0; x < font->width; x++) | ||||
| @@ -386,13 +386,14 @@ static struct image *find_glyphs(struct image *img) | |||||
| { | { | ||||
| getpixel(font, xmin + x, ymin + y, &r, &g, &b); | getpixel(font, xmin + x, ymin + y, &r, &g, &b); | ||||
| if(r > 128) continue; | if(r > 128) continue; | ||||
| setpixel(dst, distx + x, disty + y, r, g, b); | |||||
| setpixel(tmp, distx + x, disty + y, r, g, b); | |||||
| } | } | ||||
| startx = distx + xmax - xmin; | startx = distx + xmax - xmin; | ||||
| result[cur++] = all[distch]; | result[cur++] = all[distch]; | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, tmp); | |||||
| image_free(tmp); | |||||
| } | } | ||||
| @@ -21,7 +21,7 @@ | |||||
| /* Our macros */ | /* Our macros */ | ||||
| #define FONTNAME "font_phpbb.png" | #define FONTNAME "font_phpbb.png" | ||||
| static struct image *find_glyphs(struct image *img); | |||||
| static void find_glyphs(struct image *img); | |||||
| /* Global stuff */ | /* Global stuff */ | ||||
| struct { int xmin, ymin, xmax, ymax; } objlist[100]; | struct { int xmin, ymin, xmax, ymax; } objlist[100]; | ||||
| @@ -31,7 +31,7 @@ char *result; | |||||
| /* Main function */ | /* Main function */ | ||||
| char *decode_test(struct image *img) | char *decode_test(struct image *img) | ||||
| { | { | ||||
| struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; | |||||
| struct image *tmp; | |||||
| /* Initialise local data */ | /* Initialise local data */ | ||||
| objects = 0; | objects = 0; | ||||
| @@ -41,30 +41,27 @@ char *decode_test(struct image *img) | |||||
| /* phpBB captchas have 6 characters */ | /* phpBB captchas have 6 characters */ | ||||
| result = malloc(7 * sizeof(char)); | result = malloc(7 * sizeof(char)); | ||||
| tmp1 = filter_smooth(img); | |||||
| tmp2 = filter_median(tmp1); | |||||
| tmp3 = filter_equalize(tmp2, 130); | |||||
| tmp4 = filter_median(tmp3); | |||||
| tmp5 = find_glyphs(tmp3); | |||||
| tmp = image_dup(img); | |||||
| filter_smooth(tmp); | |||||
| filter_median(tmp); | |||||
| filter_equalize(tmp, 130); | |||||
| filter_median(tmp); | |||||
| find_glyphs(tmp); | |||||
| image_free(tmp1); | |||||
| image_free(tmp2); | |||||
| image_free(tmp3); | |||||
| image_free(tmp4); | |||||
| image_free(tmp5); | |||||
| image_free(tmp); | |||||
| return result; | return result; | ||||
| } | } | ||||
| /* The following functions are local */ | /* The following functions are local */ | ||||
| static struct image *find_glyphs(struct image *img) | |||||
| static void find_glyphs(struct image *img) | |||||
| { | { | ||||
| char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; | char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; | ||||
| struct image *dst, *font; | |||||
| struct image *tmp, *font; | |||||
| 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, cur = 0, offset = -1; | |||||
| int xmin, xmax, ymin, ymax, cur = 0, offset = -1; | |||||
| int distmin, distx, disty, distch; | int distmin, distx, disty, distch; | ||||
| if(!font) | if(!font) | ||||
| @@ -79,13 +76,13 @@ static struct image *find_glyphs(struct image *img) | |||||
| } | } | ||||
| } | } | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = image_new(img->width, img->height); | |||||
| for(x = 0; x < img->width; x++) | for(x = 0; x < img->width; x++) | ||||
| for(y = 0; y < img->height; y++) | for(y = 0; y < img->height; y++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, 255, g, 255); | |||||
| setpixel(tmp, x, y, 255, g, 255); | |||||
| if(r == 0 && offset == -1) | if(r == 0 && offset == -1) | ||||
| offset = x; | offset = x; | ||||
| } | } | ||||
| @@ -149,13 +146,14 @@ static struct image *find_glyphs(struct image *img) | |||||
| { | { | ||||
| getpixel(font, xmin + x, ymin + y, &r, &g, &b); | getpixel(font, xmin + x, ymin + y, &r, &g, &b); | ||||
| if(r > 128) continue; | if(r > 128) continue; | ||||
| setpixel(dst, distx + x, disty + y, r, g, b); | |||||
| setpixel(tmp, distx + x, disty + y, r, g, b); | |||||
| } | } | ||||
| offset = distx + xmax - xmin; | offset = distx + xmax - xmin; | ||||
| result[cur++] = all[distch]; | result[cur++] = all[distch]; | ||||
| } | } | ||||
| return dst; | |||||
| image_swap(img, tmp); | |||||
| image_free(tmp); | |||||
| } | } | ||||
| @@ -25,7 +25,7 @@ char *decode_vbulletin(struct image *img) | |||||
| { | { | ||||
| char all[] = "2346789ABCDEFGHJKLMNPRTWXYZ"; | char all[] = "2346789ABCDEFGHJKLMNPRTWXYZ"; | ||||
| char *result; | char *result; | ||||
| struct image *tmp1, *tmp2, *tmp3; | |||||
| struct image *tmp; | |||||
| int limits[6] = { 26, 53, 80, 107, 134, 160 }; | int limits[6] = { 26, 53, 80, 107, 134, 160 }; | ||||
| int x, y, r, g, b, i, j; | int x, y, r, g, b, i, j; | ||||
| @@ -46,76 +46,77 @@ char *decode_vbulletin(struct image *img) | |||||
| strcpy(result, " "); | strcpy(result, " "); | ||||
| /* half the captchas are inverse video; we set them back to normal */ | /* half the captchas are inverse video; we set them back to normal */ | ||||
| getpixel(img, 0, 0, &r, &g, &b); | |||||
| tmp = image_dup(img); | |||||
| getpixel(tmp, 0, 0, &r, &g, &b); | |||||
| if(r < 50) | if(r < 50) | ||||
| tmp1 = filter_equalize(img, 128); | |||||
| filter_equalize(tmp, 128); | |||||
| else | else | ||||
| tmp1 = filter_equalize(img, -128); | |||||
| filter_equalize(tmp, -128); | |||||
| /* Remove garbage around the cells */ | /* Remove garbage around the cells */ | ||||
| for(x = 0; x < img->width; x++) | |||||
| for(x = 0; x < tmp->width; x++) | |||||
| { | { | ||||
| for(y = 0; y < 15; y++) | for(y = 0; y < 15; y++) | ||||
| setpixel(tmp1, x, y, 255, 255, 255); | |||||
| for(y = 45; y < img->height; y++) | |||||
| setpixel(tmp1, x, y, 255, 255, 255); | |||||
| setpixel(tmp, x, y, 255, 255, 255); | |||||
| for(y = 45; y < tmp->height; y++) | |||||
| setpixel(tmp, x, y, 255, 255, 255); | |||||
| } | } | ||||
| for(x = 0; x < img->width; x++) | |||||
| for(x = 0; x < tmp->width; x++) | |||||
| { | { | ||||
| for(i = 0; i < 6; i++) | for(i = 0; i < 6; i++) | ||||
| if(x == limits[i]) | if(x == limits[i]) | ||||
| break; | break; | ||||
| if(i == 6) | if(i == 6) | ||||
| for(y = 15; y < 45; y++) | for(y = 15; y < 45; y++) | ||||
| setpixel(tmp1, x, y, 255, 255, 255); | |||||
| setpixel(tmp, x, y, 255, 255, 255); | |||||
| else | else | ||||
| x += 11; | x += 11; | ||||
| } | } | ||||
| tmp2 = filter_black_stuff(tmp1); | |||||
| tmp3 = filter_black_stuff(tmp2); | |||||
| filter_black_stuff(tmp); | |||||
| filter_black_stuff(tmp); | |||||
| /* Fill letters in gray */ | /* Fill letters in gray */ | ||||
| for(x = 26; x < 172; x++) | for(x = 26; x < 172; x++) | ||||
| { | { | ||||
| getpixel(tmp3, x, 15, &r, &g, &b); | |||||
| getpixel(tmp, x, 15, &r, &g, &b); | |||||
| if(r == 0) | if(r == 0) | ||||
| filter_flood_fill(tmp3, x, 15, 127, 0, 255); | |||||
| filter_flood_fill(tmp, x, 15, 127, 0, 255); | |||||
| } | } | ||||
| /* Find remaining black parts and remove them */ | /* Find remaining black parts and remove them */ | ||||
| for(x = 26; x < 172; x++) | for(x = 26; x < 172; x++) | ||||
| for(y = 15; y < 45; y++) | for(y = 15; y < 45; y++) | ||||
| { | { | ||||
| getpixel(tmp3, x, y, &r, &g, &b); | |||||
| getpixel(tmp, x, y, &r, &g, &b); | |||||
| if(r == 0) | if(r == 0) | ||||
| filter_flood_fill(tmp3, x, y, 255, 255, 255); | |||||
| filter_flood_fill(tmp, x, y, 255, 255, 255); | |||||
| } | } | ||||
| /* Fill letters in black */ | /* Fill letters in black */ | ||||
| for(x = 26; x < 172; x++) | for(x = 26; x < 172; x++) | ||||
| { | { | ||||
| getpixel(tmp3, x, 44, &r, &g, &b); | |||||
| getpixel(tmp, x, 44, &r, &g, &b); | |||||
| if(r == 127) | if(r == 127) | ||||
| filter_flood_fill(tmp3, x, 44, 0, 0, 0); | |||||
| filter_flood_fill(tmp, x, 44, 0, 0, 0); | |||||
| } | } | ||||
| /* Find remaining gray parts and remove them */ | /* Find remaining gray parts and remove them */ | ||||
| for(x = 26; x < 172; x++) | for(x = 26; x < 172; x++) | ||||
| for(y = 15; y < 45; y++) | for(y = 15; y < 45; y++) | ||||
| { | { | ||||
| getpixel(tmp3, x, y, &r, &g, &b); | |||||
| getpixel(tmp, x, y, &r, &g, &b); | |||||
| if(r == 127) | if(r == 127) | ||||
| filter_flood_fill(tmp3, x, y, 255, 255, 255); | |||||
| filter_flood_fill(tmp, x, y, 255, 255, 255); | |||||
| } | } | ||||
| /* Guess all glyphs */ | /* Guess all glyphs */ | ||||
| for(i = 0; i < 6; i++) | for(i = 0; i < 6; i++) | ||||
| { | { | ||||
| struct image *new; | |||||
| struct image *new = image_dup(tmp); | |||||
| int mindist = INT_MAX, min = -1; | int mindist = INT_MAX, min = -1; | ||||
| new = filter_crop(tmp3, limits[i], 15, limits[i] + 11, 45); | |||||
| filter_crop(new, limits[i], 15, limits[i] + 11, 45); | |||||
| for(j = 0; j < 27; j++) | for(j = 0; j < 27; j++) | ||||
| { | { | ||||
| int dist = 0; | int dist = 0; | ||||
| @@ -137,9 +138,7 @@ char *decode_vbulletin(struct image *img) | |||||
| result[i] = all[min]; | result[i] = all[min]; | ||||
| } | } | ||||
| image_free(tmp1); | |||||
| image_free(tmp2); | |||||
| image_free(tmp3); | |||||
| image_free(tmp); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -18,10 +18,7 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "common.h" | #include "common.h" | ||||
| static struct image *fill_white_holes(struct image *img); | |||||
| static struct image *rotate(struct image *img); | |||||
| static struct image *cut_cells(struct image *img); | |||||
| static struct image *find_glyphs(struct image *img); | |||||
| static void fill_white_holes(struct image *img); | |||||
| /* Our macros */ | /* Our macros */ | ||||
| #define FACTOR 1 | #define FACTOR 1 | ||||
| @@ -38,7 +35,7 @@ char *result; | |||||
| /* Main function */ | /* Main function */ | ||||
| char *decode_xanga(struct image *img) | char *decode_xanga(struct image *img) | ||||
| { | { | ||||
| struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; | |||||
| struct image *tmp; | |||||
| /* Initialise local data */ | /* Initialise local data */ | ||||
| objects = 0; | objects = 0; | ||||
| @@ -49,38 +46,33 @@ char *decode_xanga(struct image *img) | |||||
| result = malloc(8 * sizeof(char)); | result = malloc(8 * sizeof(char)); | ||||
| strcpy(result, " "); | strcpy(result, " "); | ||||
| image_save(img, "xanga1.bmp"); | |||||
| tmp = image_dup(img); | |||||
| image_save(tmp, "xanga1.bmp"); | |||||
| /* Clean image a bit */ | /* Clean image a bit */ | ||||
| // tmp1 = filter_equalize(img, 200); | |||||
| tmp1 = filter_contrast(img); | |||||
| //tmp1 = filter_detect_lines(img); | |||||
| image_save(tmp1, "xanga2.bmp"); | |||||
| tmp2 = fill_white_holes(tmp1); | |||||
| // tmp2 = filter_fill_holes(tmp1); | |||||
| image_save(tmp2, "xanga3.bmp"); | |||||
| //tmp3 = filter_detect_lines(tmp2); | |||||
| // tmp3 = filter_median(tmp2); | |||||
| //image_save(tmp3, "xanga4.bmp"); | |||||
| tmp3 = filter_equalize(tmp2, 128); | |||||
| image_save(tmp3, "xanga4.bmp"); | |||||
| // filter_equalize(tmp, 200); | |||||
| filter_contrast(tmp); | |||||
| //filter_detect_lines(tmp); | |||||
| image_save(tmp, "xanga2.bmp"); | |||||
| fill_white_holes(tmp); | |||||
| // filter_fill_holes(tmp); | |||||
| image_save(tmp, "xanga3.bmp"); | |||||
| //filter_detect_lines(tmp); | |||||
| // filter_median(tmp); | |||||
| //image_save(tmp, "xanga4.bmp"); | |||||
| filter_equalize(tmp, 128); | |||||
| image_save(tmp, "xanga4.bmp"); | |||||
| return NULL; | return NULL; | ||||
| /* Detect small objects to guess image orientation */ | /* Detect small objects to guess image orientation */ | ||||
| tmp3 = filter_median(tmp2); | |||||
| tmp4 = filter_equalize(tmp3, 200); | |||||
| filter_median(tmp); | |||||
| filter_equalize(tmp, 200); | |||||
| /* Invert rotation and find glyphs */ | /* Invert rotation and find glyphs */ | ||||
| tmp5 = rotate(tmp2); | |||||
| tmp6 = filter_median(tmp5); | |||||
| rotate(tmp); | |||||
| filter_median(tmp); | |||||
| /* Clean up our mess */ | /* Clean up our mess */ | ||||
| image_free(tmp1); | |||||
| image_free(tmp2); | |||||
| image_free(tmp3); | |||||
| image_free(tmp4); | |||||
| image_free(tmp5); | |||||
| image_free(tmp6); | |||||
| image_free(tmp7); | |||||
| image_free(tmp); | |||||
| /* aaaaaaa means decoding failed */ | /* aaaaaaa means decoding failed */ | ||||
| if(!strcmp(result, "aaaaaaa")) | if(!strcmp(result, "aaaaaaa")) | ||||
| @@ -91,19 +83,19 @@ return NULL; | |||||
| /* The following functions are local */ | /* The following functions are local */ | ||||
| static struct image *fill_white_holes(struct image *img) | |||||
| static void fill_white_holes(struct image *img) | |||||
| { | { | ||||
| struct image *dst; | |||||
| struct image *tmp; | |||||
| int x, y, i; | int x, y, i; | ||||
| int r, g, b; | int r, g, b; | ||||
| dst = image_new(img->width, img->height); | |||||
| tmp = 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++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | getpixel(img, x, y, &r, &g, &b); | ||||
| setpixel(dst, x, y, r, g, b); | |||||
| setpixel(tmp, x, y, r, g, b); | |||||
| } | } | ||||
| for(y = 1; y < img->height - 1; y++) | for(y = 1; y < img->height - 1; y++) | ||||
| @@ -123,9 +115,10 @@ static struct image *fill_white_holes(struct image *img) | |||||
| count += r; | count += r; | ||||
| if(count > 600) | if(count > 600) | ||||
| continue; | continue; | ||||
| setpixel(dst, x, y, count / 5, count / 5, count / 5); | |||||
| setpixel(tmp, x, y, count / 5, count / 5, count / 5); | |||||
| } | } | ||||
| return dst; | |||||
| image_swap(tmp, img); | |||||
| image_free(tmp); | |||||
| } | } | ||||