void scale_image( //scale an image IMAGE &image, //source image IMAGE &target_image //target image ) { inT32 xsize, ysize, new_xsize, new_ysize; IMAGELINE line, new_line; int *hires, *lores, *oldhires, *oldlores; int i, j, n, oldn, row, col; int offset = 0; //not used here float factor; uinT8 curr_colour, new_colour; int dummy = -1; IMAGE image2; //horiz scaled image xsize = image.get_xsize (); ysize = image.get_ysize (); new_xsize = target_image.get_xsize (); new_ysize = target_image.get_ysize (); if (new_ysize > new_xsize) new_line.init (new_ysize); else new_line.init (new_xsize); factor = (float) xsize / (float) new_xsize; hires = (int *) calloc (xsize, sizeof (int)); lores = (int *) calloc (new_xsize, sizeof (int)); oldhires = (int *) calloc (xsize, sizeof (int)); oldlores = (int *) calloc (new_xsize, sizeof (int)); if ((hires == NULL) || (lores == NULL) || (oldhires == NULL) || (oldlores == NULL)) { fprintf (stderr, "Calloc error in scale_image\n"); err_exit(); } image2.create (new_xsize, ysize, image.get_bpp ()); oldn = 0; /* do first row separately because hires[col-1] doesn't make sense here */ image.fast_get_line (0, 0, xsize, &line); /* each line nominally begins with white */ curr_colour = 1; n = 0; for (i = 0; i < xsize; i++) { new_colour = *(line.pixels + i); if (new_colour != curr_colour) { hires[n] = i; n++; curr_colour = new_colour; } } if (offset != 0) for (i = 0; i < n; i++) hires[i] += offset; if (n > new_xsize) { tprintf ("Too many transitions (%d) on line 0\n", n); scale_image_cop_out(image, target_image, factor, hires, lores, oldhires, oldlores); return; } else if (n > 0) dyn_prog (n, hires, lores, new_xsize, &dummy, &dummy, 0, factor); else lores[0] = new_xsize; curr_colour = 1; j = 0; for (i = 0; i < new_xsize; i++) { if (lores[j] == i) { curr_colour = 1 - curr_colour; j++; } *(new_line.pixels + i) = curr_colour; } image2.put_line (0, 0, new_xsize, &new_line, 0); for (i = 0; i < n; i++) { oldhires[i] = hires[i]; oldlores[i] = lores[i]; } for (i = n; i < oldn; i++) { oldhires[i] = 0; oldlores[i] = 0; } oldn = n; for (row = 1; row < ysize; row++) { image.fast_get_line (0, row, xsize, &line); /* each line nominally begins with white */ curr_colour = 1; n = 0; for (i = 0; i < xsize; i++) { new_colour = *(line.pixels + i); if (new_colour != curr_colour) { hires[n] = i; n++; curr_colour = new_colour; } } for (i = n; i < oldn; i++) { hires[i] = 0; lores[i] = 0; } if (offset != 0) for (i = 0; i < n; i++) hires[i] += offset; if (n > new_xsize) { tprintf ("Too many transitions (%d) on line %d\n", n, row); scale_image_cop_out(image, target_image, factor, hires, lores, oldhires, oldlores); return; } else if (n > 0) dyn_prog(n, hires, lores, new_xsize, oldhires, oldlores, oldn, factor); else lores[0] = new_xsize; curr_colour = 1; j = 0; for (i = 0; i < new_xsize; i++) { if (lores[j] == i) { curr_colour = 1 - curr_colour; j++; } *(new_line.pixels + i) = curr_colour; } image2.put_line (0, row, new_xsize, &new_line, 0); for (i = 0; i < n; i++) { oldhires[i] = hires[i]; oldlores[i] = lores[i]; } for (i = n; i < oldn; i++) { oldhires[i] = 0; oldlores[i] = 0; } oldn = n; } free(hires); free(lores); free(oldhires); free(oldlores); /* NOW DO THE VERTICAL SCALING from image2 to target_image*/ xsize = new_xsize; factor = (float) ysize / (float) new_ysize; offset = 0; hires = (int *) calloc (ysize, sizeof (int)); lores = (int *) calloc (new_ysize, sizeof (int)); oldhires = (int *) calloc (ysize, sizeof (int)); oldlores = (int *) calloc (new_ysize, sizeof (int)); if ((hires == NULL) || (lores == NULL) || (oldhires == NULL) || (oldlores == NULL)) { fprintf (stderr, "Calloc error in scale_image (vert)\n"); err_exit(); } oldn = 0; /* do first col separately because hires[col-1] doesn't make sense here */ image2.get_column (0, 0, ysize, &line, 0); /* each line nominally begins with white */ curr_colour = 1; n = 0; for (i = 0; i < ysize; i++) { new_colour = *(line.pixels + i); if (new_colour != curr_colour) { hires[n] = i; n++; curr_colour = new_colour; } } if (offset != 0) for (i = 0; i < n; i++) hires[i] += offset; if (n > new_ysize) { tprintf ("Too many transitions (%d) on column 0\n", n); scale_image_cop_out(image, target_image, factor, hires, lores, oldhires, oldlores); return; } else if (n > 0) dyn_prog (n, hires, lores, new_ysize, &dummy, &dummy, 0, factor); else lores[0] = new_ysize; curr_colour = 1; j = 0; for (i = 0; i < new_ysize; i++) { if (lores[j] == i) { curr_colour = 1 - curr_colour; j++; } *(new_line.pixels + i) = curr_colour; } target_image.put_column (0, 0, new_ysize, &new_line, 0); for (i = 0; i < n; i++) { oldhires[i] = hires[i]; oldlores[i] = lores[i]; } for (i = n; i < oldn; i++) { oldhires[i] = 0; oldlores[i] = 0; } oldn = n; for (col = 1; col < xsize; col++) { image2.get_column (col, 0, ysize, &line, 0); /* each line nominally begins with white */ curr_colour = 1; n = 0; for (i = 0; i < ysize; i++) { new_colour = *(line.pixels + i); if (new_colour != curr_colour) { hires[n] = i; n++; curr_colour = new_colour; } } for (i = n; i < oldn; i++) { hires[i] = 0; lores[i] = 0; } if (offset != 0) for (i = 0; i < n; i++) hires[i] += offset; if (n > new_ysize) { tprintf ("Too many transitions (%d) on column %d\n", n, col); scale_image_cop_out(image, target_image, factor, hires, lores, oldhires, oldlores); return; } else if (n > 0) dyn_prog(n, hires, lores, new_ysize, oldhires, oldlores, oldn, factor); else lores[0] = new_ysize; curr_colour = 1; j = 0; for (i = 0; i < new_ysize; i++) { if (lores[j] == i) { curr_colour = 1 - curr_colour; j++; } *(new_line.pixels + i) = curr_colour; } target_image.put_column (col, 0, new_ysize, &new_line, 0); for (i = 0; i < n; i++) { oldhires[i] = hires[i]; oldlores[i] = lores[i]; } for (i = n; i < oldn; i++) { oldhires[i] = 0; oldlores[i] = 0; } oldn = n; } free(hires); free(lores); free(oldhires); free(oldlores); }
void edges_and_textord( //read .pb file const char *filename, //.pb file BLOCK_LIST *blocks) { BLOCK *block; //current block char *lastdot; //of name STRING name = filename; //truncated name ICOORD page_tr; BOX page_box; //bounding_box PDBLK_CLIST pd_blocks; //copy of list BLOCK_IT block_it = blocks; //iterator PDBLK_C_IT pd_it = &pd_blocks; //iterator //different orientations TO_BLOCK_LIST land_blocks, port_blocks; IMAGE thresh_image; //thresholded lastdot = strrchr (name.string (), '.'); if (lastdot != NULL) *lastdot = '\0'; if (page_image.get_bpp () == 0) { name += tessedit_image_ext; if (page_image.read_header (name.string ())) CANTOPENFILE.error ("edges_and_textord", EXIT, name.string ()); if (page_image.read (0)) READFAILED.error ("edges_and_textord", EXIT, name.string ()); name = filename; lastdot = strrchr (name.string (), '.'); if (lastdot != NULL) *lastdot = '\0'; } page_tr = ICOORD (page_image.get_xsize (), page_image.get_ysize ()); read_pd_file (name, page_image.get_xsize (), page_image.get_ysize (), blocks); block_it.set_to_list (blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; if (page_image.get_bpp () > 1) { set_global_loc_code(LOC_ADAPTIVE); for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); pd_it.add_after_then_move (block); } // adaptive_threshold(&page_image,&pd_blocks,&thresh_image); set_global_loc_code(LOC_EDGE_PROG); #ifndef EMBEDDED previous_cpu = clock (); #endif for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); if (!polygon_tess_approximation) invert_image(&page_image); #ifndef GRAPHICS_DISABLED extract_edges(NO_WINDOW, &page_image, &thresh_image, page_tr, block); #else extract_edges(&page_image, &thresh_image, page_tr, block); #endif page_box += block->bounding_box (); } page_image = thresh_image; //everyone else gets it } else { set_global_loc_code(LOC_EDGE_PROG); if (!page_image.white_high ()) invert_image(&page_image); #ifndef EMBEDDED previous_cpu = clock (); #endif for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); #ifndef GRAPHICS_DISABLED extract_edges(NO_WINDOW, &page_image, &page_image, page_tr, block); #else extract_edges(&page_image, &page_image, page_tr, block); #endif page_box += block->bounding_box (); } } if (global_monitor != NULL) { global_monitor->ocr_alive = TRUE; global_monitor->progress = 10; } assign_blobs_to_blocks2(blocks, &land_blocks, &port_blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; filter_blobs (page_box.topright (), &land_blocks, textord_test_landscape); #ifndef EMBEDDED previous_cpu = clock (); #endif filter_blobs (page_box.topright (), &port_blocks, !textord_test_landscape); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; textord_page (page_box.topright (), blocks, &land_blocks, &port_blocks); }