diff --git a/ssocr.c b/ssocr.c index a2bc56a..8fb3878 100644 --- a/ssocr.c +++ b/ssocr.c @@ -40,7 +40,6 @@ /* global variables */ int ssocr_foreground = SSOCR_BLACK; int ssocr_background = SSOCR_WHITE; -int debug_output=0; /* print debug output? */ /* functions */ @@ -530,25 +529,24 @@ Imlib_Image rgb_threshold(Imlib_Image *source_image, double thresh, /* adapt threshold to image values values */ double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt, int x, - int y, int w, int h, int absolute_threshold, - int do_iterative_thresh, int verbose) + int y, int w, int h, int flags) { double t = thresh; - if(!absolute_threshold) { - if(debug_output) + if(!(flags & ABSOLUTE_THRESHOLD)) { + if(flags & DEBUG_OUTPUT) fprintf(stderr, "adjusting threshold to image: %f ->", t); t = get_threshold(image, thresh/100.0, lt, x, y, w, h); - if(debug_output) + if(flags & DEBUG_OUTPUT) fprintf(stderr, " %f\n", t); - if(do_iterative_thresh) { - if(debug_output) + if(flags & DO_ITERATIVE_THRESHOLD) { + if(flags & DEBUG_OUTPUT) fprintf(stderr, "doing iterative_thresholding: %f ->", t); t = iterative_threshold(image, t, lt, x, y, w, h); - if(debug_output) + if(flags & DEBUG_OUTPUT) fprintf(stderr, " %f\n", t); } } - if(verbose || debug_output) { + if((flags & VERBOSE) || (flags & DEBUG_OUTPUT)) { fprintf(stderr, "using threshold %.2f\n", t); } return t; @@ -1092,7 +1090,7 @@ int clip(int value, int min, int max) /* save image to file */ void save_image(const char *image_type, Imlib_Image *image, const char *fmt, - const char *filename, int verbose) + const char *filename, int flags) { const char *tmp; Imlib_Image *current_image; @@ -1109,12 +1107,12 @@ void save_image(const char *image_type, Imlib_Image *image, const char *fmt, tmp++; } if(tmp) { - if(verbose) + if(flags & VERBOSE) fprintf(stderr, "saving %s image in %s format to file %s\n", image_type, tmp, filename); imlib_image_set_format(tmp); } else { /* use png as default */ - if(verbose) + if(flags & VERBOSE) fprintf(stderr, "saving image in png format to file %s\n", filename); imlib_image_set_format("png"); @@ -1292,16 +1290,10 @@ int main(int argc, char **argv) double thresh=THRESHOLD; /* border between light and dark */ int offset; /* offset for shear */ double theta; /* rotation angle */ - int absolute_threshold=0; /* absolute threshold given? */ - int do_iterative_thresh=0; /* iterative threshold given? */ - int verbose=0; /* be verbose? */ char *output_file=NULL; /* wrie processed image to file */ char *output_fmt=NULL; /* use this format */ - int use_debug_image=0; /* write a debug image... */ char *debug_image_file=NULL; /* ...to this file */ - int process_only=0; /* image processing only (no OCR)? */ - int print_info=0; /* print image info? */ - int adjust_grey=0; /* use T1 and T2 as percentages of used luminance values*/ + int flags=0; /* set by options, see #defines on .h file */ luminance_t lt=DEFAULT_LUM_FORMULA; /* luminance function */ /* if we provided no arguments to the program exit */ @@ -1349,34 +1341,32 @@ int main(int argc, char **argv) exit (42); break; case 'v': - verbose=1; - if(debug_output) { - fprintf(stderr, "verbose=%d\n", verbose); + flags |= VERBOSE; + if(flags & DEBUG_OUTPUT) { + fprintf(stderr, "flags & VERBOSE=%d\n", flags & VERBOSE); } break; case 't': if(optarg) { thresh = atof(optarg); - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "thresh = %f (default: %f)\n", thresh, THRESHOLD); } if(thresh < 0.0 || 100.0 < thresh) { thresh = THRESHOLD; - if(verbose) { + if(flags & VERBOSE) { fprintf(stderr, "ignoring --treshold=%s\n", optarg); } } - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "thresh = %f (default: %f)\n", thresh, THRESHOLD); } } break; case 'a': - absolute_threshold=1; - break; + flags |= ABSOLUTE_THRESHOLD; break; case 'T': - do_iterative_thresh=1; - break; + flags |= DO_ITERATIVE_THRESHOLD; break; case 'n': if(optarg) { need_pixels = atoi(optarg); @@ -1415,7 +1405,7 @@ int main(int argc, char **argv) } break; case 'D': - use_debug_image = 1; + flags |= USE_DEBUG_IMAGE; if(optarg) { debug_image_file = strdup(optarg); } else { @@ -1423,11 +1413,9 @@ int main(int argc, char **argv) } break; case 'p': - process_only = 1; - break; + flags |= PROCESS_ONLY; break; case 'P': - debug_output = 1; - break; + flags |= DEBUG_OUTPUT; break; case 'f': if(optarg) { if(strcasecmp(optarg, "black") == 0) { @@ -1459,15 +1447,15 @@ int main(int argc, char **argv) } break; case 'I': - print_info=1; - if(debug_output) { - fprintf(stderr, "print_info=%d\n", print_info); + flags |= PRINT_INFO; + if(flags & DEBUG_OUTPUT) { + fprintf(stderr, "flags & PRINT_INFO=%d\n", flags & PRINT_INFO); } break; case 'g': - adjust_grey=1; - if(debug_output) { - fprintf(stderr, "adjust_grey=%d\n", adjust_grey); + flags |= ADJUST_GREY; + if(flags & DEBUG_OUTPUT) { + fprintf(stderr, "flags & ADJUST_GREY=%d\n", flags & ADJUST_GREY); } break; case 'l': @@ -1492,12 +1480,14 @@ int main(int argc, char **argv) exit(99); } } - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "================================================================================\n"); - fprintf(stderr, "verbose=%d\nthresh=%f\n", verbose, thresh); - fprintf(stderr, "print_info=%d\nadjust_grey=%d\n", print_info, adjust_grey); - fprintf(stderr, "absolute_threshold=%d\n", absolute_threshold); - fprintf(stderr, "do_iterative_thresh=%d\n", do_iterative_thresh); + fprintf(stderr, "flags & VERBOSE=%d\nthresh=%f\n", flags & VERBOSE, thresh); + fprintf(stderr, "flags & PRINT_INFO=%d\nflags & ADJUST_GREY=%d\n", + flags & PRINT_INFO, flags & ADJUST_GREY); + fprintf(stderr, "flags & ABSOLUTE_THRESHOLD=%d\n",flags&ABSOLUTE_THRESHOLD); + fprintf(stderr, "flags & DO_ITERATIVE_THRESHOLD=%d\n", + flags & DO_ITERATIVE_THRESHOLD); fprintf(stderr, "need_pixels = %d\n", need_pixels); fprintf(stderr, "ignore_pixels = %d\n", ignore_pixels); fprintf(stderr, "number_of_digits = %d\n", number_of_digits); @@ -1517,12 +1507,12 @@ int main(int argc, char **argv) usage(argv[0], stderr); exit(99); } - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "argv[argc-1]=%s used as image file name\n", argv[argc-1]); } /* load the image */ - if(verbose) { + if(flags & VERBOSE) { fprintf(stderr, "loading image %s\n", argv[argc-1]); } image = imlib_load_image_immediately_without_cache(argv[argc-1]); @@ -1557,23 +1547,22 @@ int main(int argc, char **argv) /* get image parameters */ w = imlib_image_get_width(); h = imlib_image_get_height(); - if(debug_output || print_info) { + if((flags & DEBUG_OUTPUT) || (flags & PRINT_INFO)) { fprintf(stderr, "image width: %d\nimage height: %d\n",w,h); } /* get minimum and maximum "value" values */ - if(debug_output || print_info) { + if((flags & DEBUG_OUTPUT) || (flags & PRINT_INFO)) { fprintf(stderr, "%.2f <= lum <= %.2f (lum should be in [0,255])\n", get_minval(&image, 0, 0, -1, -1, lt), get_maxval(&image, 0, 0, -1, -1, lt)); } /* adapt threshold to image */ - thresh = adapt_threshold(&image, thresh, lt, 0, 0, -1, -1, - absolute_threshold, do_iterative_thresh, verbose); + thresh = adapt_threshold(&image, thresh, lt, 0, 0, -1, -1, flags); /* process commands */ - if(verbose) /* then print found commands */ { + if(flags & VERBOSE) /* then print found commands */ { if(optind >= argc-1) { fprintf(stderr, "no commands given, using image %s unmodified\n", argv[argc-1]); @@ -1581,7 +1570,7 @@ int main(int argc, char **argv) fprintf(stderr, "got commands"); for(i=optind; i0) && (i+10) && (i+10) && (i+1=number_of_digits) { fprintf(stderr, "found too many digits (%d)\n", d+1); imlib_free_image_and_decache(); - if(use_debug_image) { - save_image("debug", debug_image, output_fmt, debug_image_file, - verbose); + if(flags & USE_DEBUG_IMAGE) { + save_image("debug", debug_image, output_fmt,debug_image_file,flags); imlib_context_set_image(debug_image); imlib_free_image_and_decache(); } @@ -1947,7 +1933,7 @@ int main(int argc, char **argv) } digits[d].x1 = i; digits[d].y1 = 0; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(255,0,0,255);/* red line for start of digit */ imlib_image_draw_line(i,0,i,h-1,0); @@ -1961,7 +1947,7 @@ int main(int argc, char **argv) digits[d].x2 = i; digits[d].y2 = h-1; d++; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(0,0,255,255); /* blue line for end of digit */ imlib_image_draw_line(i,0,i,h-1,0); @@ -1984,8 +1970,8 @@ int main(int argc, char **argv) if(d != number_of_digits) { fprintf(stderr, "found only %d of %d digits\n", d, number_of_digits); imlib_free_image_and_decache(); - if(use_debug_image) { - save_image("debug", debug_image, output_fmt, debug_image_file, verbose); + if(flags & USE_DEBUG_IMAGE) { + save_image("debug", debug_image, output_fmt, debug_image_file, flags); imlib_context_set_image(debug_image); imlib_free_image_and_decache(); } @@ -1993,7 +1979,7 @@ int main(int argc, char **argv) } dig_w = digits[number_of_digits-1].x2 - digits[0].x1; - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "found %d digits\n", d); for(d=0; d (%d,%d), width: %d (%f%%)\n", d, @@ -2021,7 +2007,7 @@ int main(int argc, char **argv) * (1/3 is arbitarily chosen -- normally seven segment displays use * digits that are 2 times as high as wide) */ if((digits[i].y2 - digits[i].y1) / (digits[i].x2 - digits[i].x1) > 2) { - if(debug_output) { + if(flags & DEBUG_OUTPUT) { fprintf(stderr, "digit %d is a 1 (height/width = %d/%d = (int) %d)\n", i, digits[i].y2 - digits[i].y1, digits[i].x2 - digits[i].x1, (digits[i].y2 - digits[i].y1) / (digits[i].x2 - digits[i].x1)); @@ -2059,7 +2045,7 @@ int main(int argc, char **argv) if(found_top) /* then we are searching for the bottom */ { digits[d].y2 = j; state = (ssocr_foreground == SSOCR_BLACK) ? FIND_LIGHT : FIND_DARK; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(0,255,0,255); /* green line */ imlib_image_draw_line(digits[d].x1,digits[d].y2, @@ -2070,7 +2056,7 @@ int main(int argc, char **argv) digits[d].y1 = j; found_top = 1; state = (ssocr_foreground == SSOCR_BLACK) ? FIND_LIGHT : FIND_DARK; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(0,255,0,255); /* green line */ imlib_image_draw_line(digits[d].x1,digits[d].y1, @@ -2085,7 +2071,7 @@ int main(int argc, char **argv) * dark */ digits[d].y2 = j; state = (ssocr_foreground == SSOCR_BLACK) ? FIND_DARK : FIND_LIGHT; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(0,255,0,255); /* green line */ imlib_image_draw_line(digits[d].x1,digits[d].y2, @@ -2098,7 +2084,7 @@ int main(int argc, char **argv) if(state == ((ssocr_foreground == SSOCR_BLACK) ? FIND_LIGHT : FIND_DARK)){ digits[d].y2 = h-1; state = (ssocr_foreground == SSOCR_BLACK) ? FIND_DARK : FIND_LIGHT; - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); imlib_context_set_color(0,255,0,255); /* green line */ imlib_image_draw_line(digits[d].x1,digits[d].y2, @@ -2107,7 +2093,7 @@ int main(int argc, char **argv) } } } - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { /* draw rectangles around digits */ imlib_context_set_image(debug_image); imlib_context_set_color(128,128,128,255); /* grey line */ @@ -2137,7 +2123,7 @@ int main(int argc, char **argv) imlib_image_query_pixel(middle, j, &color); lum = get_lum(&color, lt); if(is_pixel_set(lum, thresh)) /* dark i.e. pixel is set */ { - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { imlib_context_set_image(debug_image); if(third == 1) { imlib_context_set_color(255,0,0,255); @@ -2179,7 +2165,7 @@ int main(int argc, char **argv) imlib_image_query_pixel(i, quarter, &color); lum = get_lum(&color, lt); if(is_pixel_set(lum, thresh)) /* dark i.e. pixel is set */ { - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { if(half == 1) { imlib_context_set_color(255,0,0,255); } else if(half == 2) { @@ -2211,7 +2197,7 @@ int main(int argc, char **argv) imlib_image_query_pixel(i, three_quarters, &color); lum = get_lum(&color, lt); if(is_pixel_set(lum, thresh)) /* dark i.e. pixel is set */ { - if(use_debug_image) { + if(flags & USE_DEBUG_IMAGE) { if(half == 1) { imlib_context_set_color(255,0,0,255); } else if(half == 2) { @@ -2259,8 +2245,8 @@ int main(int argc, char **argv) /* clean up... */ imlib_free_image_and_decache(); - if(use_debug_image) { - save_image("debug", debug_image, output_fmt, debug_image_file, verbose); + if(flags & USE_DEBUG_IMAGE) { + save_image("debug", debug_image, output_fmt, debug_image_file, flags); imlib_context_set_image(debug_image); imlib_free_image_and_decache(); } diff --git a/ssocr.h b/ssocr.h index 280e828..712dd30 100644 --- a/ssocr.h +++ b/ssocr.h @@ -82,6 +82,16 @@ /* doubles are assumed equal when they differ less than EPSILON */ #define EPSILON 0.0000001 +/* flags set by options */ +#define ABSOLUTE_THRESHOLD 1 +#define DO_ITERATIVE_THRESHOLD (1<<1) +#define VERBOSE (1<<2) +#define USE_DEBUG_IMAGE (1<<3) +#define PROCESS_ONLY (1<<4) +#define PRINT_INFO (1<<5) +#define ADJUST_GREY (1<<6) +#define DEBUG_OUTPUT (1<<7) + /* types */ typedef struct { @@ -221,8 +231,7 @@ Imlib_Image crop(Imlib_Image *source_image, int x, int y, int w, int h); /* adapt threshold to image values values */ double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt, int x, - int y, int w, int h, int absolute_threshold, - int iterative_threshold, int verbose); + int y, int w, int h, int flags); /* compute dynamic threshold value from the rectangle (x,y),(x+w,y+h) of * source_image */ @@ -276,6 +285,6 @@ void print_info(Imlib_Image *source_image); /* save image to file */ void save_image(const char *image_type, Imlib_Image *image, const char *fmt, - const char *filename, int verbose); + const char *filename, int flags); #endif /* SSOCR2_H */