Skip to content

Commit

Permalink
add lobal BW threshold on 8 bpp images
Browse files Browse the repository at this point in the history
  • Loading branch information
DanBloomberg authored and zdenop committed Dec 23, 2024
1 parent 0625330 commit 528a5f4
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Adam Langley <agl@imperialviolet.org>

Contributors:
=============
Dan Bloomberg <dan.bloomberg@gmail.com>
Misty De Meo <mistydemeo@gmail.com>
zdenop <zdenop@gmail.com>
Steven Lee http://www.rubypdf.com
Expand Down
51 changes: 37 additions & 14 deletions src/jbig2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -61,7 +62,9 @@ usage(const char *argv0) {
fprintf(stderr, " -s --symbol-mode: use text region, not generic coder\n");
fprintf(stderr, " -t <threshold>: set classification threshold for symbol coder (def: %0.2f)\n", JBIG2_THRESHOLD_DEF);
fprintf(stderr, " -w <weight>: set classification weight for symbol coder (def: %0.2f)\n", JBIG2_WEIGHT_DEF);
fprintf(stderr, " -T <bw threshold>: set 1 bpp threshold (def: %d)\n", BW_THRESHOLD_DEF);
fprintf(stderr, " -T <bw threshold>: 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 <outfile>: dump thresholded image as PNG\n");
fprintf(stderr, " -2: upsample 2x before thresholding\n");
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
Expand All @@ -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++;
Expand All @@ -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);
Expand All @@ -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++;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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) {
Expand Down

0 comments on commit 528a5f4

Please sign in to comment.