diff --git a/AUTHORS b/AUTHORS index f46860f..5552139 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,6 +4,7 @@ Adam Langley Contributors: ============= +Dan Bloomberg Misty De Meo zdenop Steven Lee http://www.rubypdf.com diff --git a/src/jbig2.cc b/src/jbig2.cc index 79816d4..f84af70 100644 --- a/src/jbig2.cc +++ b/src/jbig2.cc @@ -49,7 +49,8 @@ #define JBIG2_WEIGHT_DEF 0.5f #define BW_THRESHOLD_MIN 0 #define BW_THRESHOLD_MAX 255 -#define BW_THRESHOLD_DEF 128 +#define BW_LOCAL_THRESHOLD_DEF 200 +#define BW_GLOBAL_THRESHOLD_DEF 128 static void usage(const char *argv0) { @@ -61,7 +62,9 @@ usage(const char *argv0) { fprintf(stderr, " -s --symbol-mode: use text region, not generic coder\n"); fprintf(stderr, " -t : set classification threshold for symbol coder (def: %0.2f)\n", JBIG2_THRESHOLD_DEF); fprintf(stderr, " -w : set classification weight for symbol coder (def: %0.2f)\n", JBIG2_WEIGHT_DEF); - fprintf(stderr, " -T : set 1 bpp threshold (def: %d)\n", BW_THRESHOLD_DEF); + fprintf(stderr, " -T : set 1 bpp threshold (def: %d)\n", BW_LOCAL_THRESHOLD_DEF); + fprintf(stderr, " -G --global: use global BW threshold on 8 bpp images;\n" + " the default is to use local (adaptive) thresholding\n"); fprintf(stderr, " -r --refine: use refinement (requires -s: lossless)\n"); fprintf(stderr, " -O : dump thresholded image as PNG\n"); fprintf(stderr, " -2: upsample 2x before thresholding\n"); @@ -213,13 +216,14 @@ int main(int argc, char **argv) { bool duplicate_line_removal = false; bool pdfmode = false; + bool globalmode = false; + int bw_threshold = BW_LOCAL_THRESHOLD_DEF; float threshold = JBIG2_THRESHOLD_DEF; float weight = JBIG2_WEIGHT_DEF; - int bw_threshold = BW_THRESHOLD_DEF; bool symbol_mode = false; bool refine = false; bool up2 = false, up4 = false; - const char *output_threshold = NULL; + const char *output_threshold_image = NULL; const char *basename = "output"; l_int32 img_fmt = IFF_PNG; const char *img_ext = "png"; @@ -294,7 +298,7 @@ main(int argc, char **argv) { } if (strcmp(argv[i], "-O") == 0) { - output_threshold = argv[i+1]; + output_threshold_image = argv[i+1]; i++; continue; } @@ -320,9 +324,11 @@ main(int argc, char **argv) { return 1; } - if ((threshold < JBIG2_THRESHOLD_MIN) || (threshold > JBIG2_THRESHOLD_MAX)) { + if ((threshold < JBIG2_THRESHOLD_MIN) || + (threshold > JBIG2_THRESHOLD_MAX)) { fprintf(stderr, "Invalid value for threshold\n"); - fprintf(stderr, "(must be between %0.2f and %0.2f)\n", JBIG2_THRESHOLD_MIN, JBIG2_THRESHOLD_MAX); + fprintf(stderr, "(must be between %0.2f and %0.2f)\n", + JBIG2_THRESHOLD_MIN, JBIG2_THRESHOLD_MAX); return 10; } i++; @@ -340,13 +346,24 @@ main(int argc, char **argv) { if ((weight < JBIG2_WEIGHT_MIN) || (weight > JBIG2_WEIGHT_MAX)) { fprintf(stderr, "Invalid value for weight\n"); - fprintf(stderr, "(must be between %0.2f and %0.2f)\n", JBIG2_WEIGHT_MIN, JBIG2_WEIGHT_MAX); + fprintf(stderr, "(must be between %0.2f and %0.2f)\n", + JBIG2_WEIGHT_MIN, JBIG2_WEIGHT_MAX); return 10; } i++; continue; } + // Local BW thresholding is the default. However, if global + // BW thresholding is requested, use its default threshold. + if (strcmp(argv[i], "-G") == 0 || + strcmp(argv[i], "--global") == 0) { + globalmode = true; + bw_threshold = BW_GLOBAL_THRESHOLD_DEF; + continue; + } + + // If a BW threshold value is requested, overwrite the default value. if (strcmp(argv[i], "-T") == 0) { char *endptr; bw_threshold = strtol(argv[i+1], &endptr, 10); @@ -356,7 +373,8 @@ main(int argc, char **argv) { return 1; } if (bw_threshold < BW_THRESHOLD_MIN || bw_threshold > BW_THRESHOLD_MAX) { - fprintf(stderr, "Invalid bw threshold: (%d..%d)\n", BW_THRESHOLD_MIN, BW_THRESHOLD_MAX); + fprintf(stderr, "Invalid bw threshold: (%d..%d)\n", + BW_THRESHOLD_MIN, BW_THRESHOLD_MAX); return 11; } i++; @@ -418,7 +436,8 @@ main(int argc, char **argv) { return 6; } - struct jbig2ctx *ctx = jbig2_init(threshold, weight, 0, 0, !pdfmode, refine ? 10 : -1); + struct jbig2ctx *ctx = jbig2_init(threshold, weight, 0, 0, + !pdfmode, refine ? 10 : -1); int pageno = -1; int numsubimages=0, subimage=0, num_pages = 0; @@ -456,7 +475,7 @@ main(int argc, char **argv) { if (verbose) pixInfo(source, "source image:"); - PIX *pixl, *gray, *pixt; + PIX *pixl, *gray, *adapt, *pixt; if ((pixl = pixRemoveColormap(source, REMOVE_CMAP_BASED_ON_SRC)) == NULL) { fprintf(stderr, "Failed to remove colormap from %s\n", argv[i]); return 1; @@ -474,7 +493,11 @@ main(int argc, char **argv) { fprintf(stderr, "Unsupported input image depth: %d\n", pixl->d); return 1; } - Pix *adapt = pixBackgroundNormSimple(gray, NULL, NULL); + if (!globalmode) { + adapt = pixCleanBackgroundToWhite(gray, NULL, NULL, 1.0, 90, 190); + } else { + adapt = pixClone(gray); + } pixDestroy(&gray); if (up2) { pixt = pixScaleGray2xLIThresh(adapt, bw_threshold); @@ -494,8 +517,8 @@ main(int argc, char **argv) { if (verbose) pixInfo(pixt, "thresholded image:"); - if (output_threshold) { - pixWrite(output_threshold, pixt, IFF_PNG); + if (output_threshold_image) { + pixWrite(output_threshold_image, pixt, IFF_PNG); } if (segment && pixl->d > 1) {