00001
00020 #include "mfcpch.h"
00021 #include "edgloop.h"
00022
00023 #include "scanedg.h"
00024
00025 #ifdef TEXT_VERBOSE
00026 #include "../cutil/callcpp.h"
00027 #endif
00028
00030 #define WHITE_PIX 1
00032 #define BLACK_PIX 0
00033
00034 #define FLIP_COLOUR(pix) (1-(pix))
00035
00036 #define EWSIZE 4
00038 #define XMARGIN 2
00040 #define YMARGIN 3
00041
00043 static CRACKEDGE *free_cracks = NULL;
00044
00055 DLLSYM void block_edges(
00056 IMAGE *t_image,
00057 PDBLK *block,
00058 ICOORD page_tr
00059 ) {
00060 UINT8 margin;
00061 INT16 x;
00062 INT16 y;
00063 ICOORD bleft;
00064 ICOORD tright;
00065 ICOORD block_bleft;
00066 ICOORD block_tright;
00067 int xindex;
00068 BLOCK_LINE_IT line_it = block;
00069 IMAGELINE bwline;
00070
00071 CRACKEDGE *ptrlinemem[MAXIMAGEWIDTH];
00072 CRACKEDGE **ptrline = ptrlinemem;
00073
00074 if (t_image->get_xsize()+1 > MAXIMAGEWIDTH) {
00075 ptrline = new CRACKEDGE*[t_image->get_xsize()+1];
00076 }
00077
00078
00079 block->bounding_box (bleft, tright);
00080 block_bleft = bleft;
00081 block_tright = tright;
00082 for (x = tright.x () - bleft.x (); x >= 0; x--)
00083 ptrline[x] = NULL;
00084
00085 bwline.init (t_image->get_xsize());
00086
00087 margin = WHITE;
00088
00089 for (y = tright.y () - 1; y >= bleft.y () - 1; y--) {
00090 if (y >= block_bleft.y () && y < block_tright.y ()) {
00091 t_image->get_line (bleft.x (), y, tright.x () - bleft.x (), &bwline,
00092 0);
00093 make_margins (block, &line_it, bwline.pixels, margin, bleft.x (),
00094 tright.x (), y);
00095 }
00096 else {
00097 x = tright.x () - bleft.x ();
00098 for (xindex = 0; xindex < x; xindex++)
00099 bwline.pixels[xindex] = margin;
00100 }
00101 line_edges (bleft.x (), y, tright.x () - bleft.x (),
00102 margin, bwline.pixels, ptrline);
00103 }
00104
00105 free_crackedges(free_cracks);
00106 free_cracks = NULL;
00107 if (ptrline != ptrlinemem) {
00108 delete [] ptrline;
00109 }
00110 }
00111
00112
00118 void make_margins(
00119 PDBLK *block,
00120 BLOCK_LINE_IT *line_it,
00121 UINT8 *pixels,
00122 UINT8 margin,
00123 INT16 left,
00124 INT16 right,
00125 INT16 y
00126 ) {
00127 PB_LINE_IT *lines;
00128 ICOORDELT_LIST *segments;
00129 ICOORDELT_IT seg_it;
00130 INT32 start;
00131 INT16 xext;
00132 int xindex;
00133
00134 if (block->poly_block () != NULL) {
00135 lines = new PB_LINE_IT (block->poly_block ());
00136 segments = lines->get_line (y);
00137 if (!segments->empty ()) {
00138 seg_it.set_to_list (segments);
00139 seg_it.mark_cycle_pt ();
00140 start = seg_it.data ()->x ();
00141 xext = seg_it.data ()->y ();
00142 for (xindex = left; xindex < right; xindex++) {
00143 if (xindex >= start && !seg_it.cycled_list ()) {
00144 xindex = start + xext - 1;
00145 seg_it.forward ();
00146 start = seg_it.data ()->x ();
00147 xext = seg_it.data ()->y ();
00148 }
00149 else
00150 pixels[xindex - left] = margin;
00151 }
00152 }
00153 else {
00154 for (xindex = left; xindex < right; xindex++)
00155 pixels[xindex - left] = margin;
00156 }
00157 delete segments;
00158 delete lines;
00159 }
00160 else {
00161 start = line_it->get_line (y, xext);
00162 for (xindex = left; xindex < start; xindex++)
00163 pixels[xindex - left] = margin;
00164 for (xindex = start + xext; xindex < right; xindex++)
00165 pixels[xindex - left] = margin;
00166 }
00167 }
00168
00169
00175 void whiteout_block(
00176 IMAGE *t_image,
00177 PDBLK *block
00178 ) {
00179 INT16 x;
00180 INT16 y;
00181 INT16 xext;
00182 int xindex;
00183 UINT8 *dest;
00184 BOX block_box;
00185 BLOCK_LINE_IT line_it = block;
00186 IMAGELINE bwline;
00187
00188 block_box = block->bounding_box ();
00189 for (y = block_box.bottom (); y < block_box.top (); y++) {
00190
00191 x = line_it.get_line (y, xext);
00192 t_image->get_line (x, y, xext, &bwline, 0);
00193 dest = bwline.pixels;
00194 for (xindex = 0; xindex < xext; xindex++)
00195 *dest++ = 1;
00196 t_image->put_line (x, y, xext, &bwline, 0);
00197 }
00198 }
00199
00200
00218 void line_edges (
00219 INT16 x,
00220 INT16 y,
00221 INT16 xext,
00222 UINT8 uppercolour,
00223 UINT8 * bwpos,
00224 CRACKEDGE ** prevline
00225 ) {
00226 int xpos;
00227 int xmax;
00228 int colour;
00229 int prevcolour;
00230 CRACKEDGE *current;
00231 CRACKEDGE *newcurrent;
00232
00233 #if defined(TEXT_VERBOSE)
00234 #if defined(TV_FOCUSE)
00235 cprintf("\n");
00236 #endif
00237 cprintf("e");
00238 #endif
00239 xmax = x + xext;
00240 prevcolour = uppercolour;
00241 current = NULL;
00242
00243
00244 for (xpos = x; xpos < xmax; xpos++, prevline++) {
00245 colour = *bwpos++;
00246 if (*prevline != NULL) {
00247
00248
00249 uppercolour = FLIP_COLOUR (uppercolour);
00250 if (colour == prevcolour) {
00251 if (colour == uppercolour) {
00252
00253 join_edges(current, *prevline);
00254 current = NULL;
00255 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00256 cprintf("C");
00257 #endif
00258 }
00259 else {
00260
00261 current = h_edge (xpos, y, uppercolour - colour, *prevline);
00262 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00263 cprintf("L");
00264 #endif
00265 }
00266 *prevline = NULL;
00267 }
00268 else {
00269 if (colour == uppercolour) {
00270 *prevline = v_edge (xpos, y, colour - prevcolour, *prevline);
00271 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00272 cprintf("K");
00273 #endif
00274 }
00275
00276 else if (colour == WHITE_PIX) {
00277 join_edges(current, *prevline);
00278 current = h_edge (xpos, y, uppercolour - colour, NULL);
00279 *prevline = v_edge (xpos, y, colour - prevcolour, current);
00280 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00281 cprintf("J");
00282 #endif
00283 }
00284 else {
00285 newcurrent = h_edge (xpos, y, uppercolour - colour, *prevline);
00286 *prevline = v_edge (xpos, y, colour - prevcolour, current);
00287 current = newcurrent;
00288 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00289 cprintf("H");
00290 #endif
00291 }
00292 prevcolour = colour;
00293 }
00294 }
00295 else {
00296 if (colour != prevcolour) {
00297 *prevline = current =
00298 v_edge (xpos, y, colour - prevcolour, current);
00299 prevcolour = colour;
00300 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00301 cprintf("D");
00302 #endif
00303 }
00304 if (colour != uppercolour) {
00305 current = h_edge (xpos, y, uppercolour - colour, current);
00306 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00307 cprintf("E");
00308 #endif
00309 }
00310 else {
00311 current = NULL;
00312 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00313 cprintf("=");
00314 #endif
00315 }
00316 }
00317 }
00318 if (current != NULL) {
00319
00320 if (*prevline != NULL) {
00321 join_edges(current, *prevline);
00322 *prevline = NULL;
00323 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00324 cprintf("M");
00325 #endif
00326 }
00327 else {
00328
00329 *prevline = v_edge (xpos, y, FLIP_COLOUR(prevcolour)-prevcolour, current);
00330 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00331 cprintf("N");
00332 #endif
00333 }
00334 }
00335 else if (*prevline != NULL) {
00336
00337 *prevline = v_edge (xpos, y, FLIP_COLOUR(prevcolour)-prevcolour, *prevline);
00338 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE)
00339 cprintf("O");
00340 #endif
00341 }
00342 }
00343
00344
00350 CRACKEDGE *
00351 h_edge (
00352 INT16 x,
00353 INT16 y,
00354 INT8 sign,
00355 CRACKEDGE * join
00356 ) {
00357 CRACKEDGE *newpt;
00358
00359
00360 if (free_cracks != NULL) {
00361 newpt = free_cracks;
00362 free_cracks = newpt->next;
00363 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00364 cprintf("a");
00365 #endif
00366 }
00367 else {
00368 newpt = new CRACKEDGE;
00369 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00370 cprintf("b");
00371 #endif
00372 }
00373 newpt->pos.set_y (y + 1);
00374 newpt->stepy = 0;
00375
00376 if (sign > 0) {
00377 newpt->pos.set_x (x + 1);
00378 newpt->stepx = -1;
00379 newpt->stepdir = 0;
00380 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00381 cprintf("c");
00382 #endif
00383 }
00384 else {
00385 newpt->pos.set_x (x);
00386 newpt->stepx = 1;
00387 newpt->stepdir = 2;
00388 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00389 cprintf("d");
00390 #endif
00391 }
00392
00393 if (join == NULL) {
00394 newpt->next = newpt;
00395 newpt->prev = newpt;
00396 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00397 cprintf("f");
00398 #endif
00399 }
00400 else {
00401 if (newpt->pos.x () + newpt->stepx == join->pos.x ()
00402 && newpt->pos.y () == join->pos.y ()) {
00403 newpt->prev = join->prev;
00404 newpt->prev->next = newpt;
00405 newpt->next = join;
00406 join->prev = newpt;
00407 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00408 cprintf("g");
00409 #endif
00410 }
00411 else {
00412 newpt->next = join->next;
00413 newpt->next->prev = newpt;
00414 newpt->prev = join;
00415 join->next = newpt;
00416 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC)
00417 cprintf("h");
00418 #endif
00419 }
00420 }
00421 return newpt;
00422 }
00423
00424
00430 CRACKEDGE *
00431 v_edge (
00432 INT16 x,
00433 INT16 y,
00434 INT8 sign,
00435 CRACKEDGE * join
00436 ) {
00437 CRACKEDGE *newpt;
00438
00439 if (free_cracks != NULL) {
00440 newpt = free_cracks;
00441 free_cracks = newpt->next;
00442 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00443 cprintf("j");
00444 #endif
00445 }
00446 else {
00447 newpt = new CRACKEDGE;
00448 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00449 cprintf("k");
00450 #endif
00451 }
00452 newpt->pos.set_x (x);
00453 newpt->stepx = 0;
00454
00455 if (sign > 0) {
00456 newpt->pos.set_y (y);
00457 newpt->stepy = 1;
00458 newpt->stepdir = 3;
00459 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00460 cprintf("l");
00461 #endif
00462 }
00463 else {
00464 newpt->pos.set_y (y + 1);
00465 newpt->stepy = -1;
00466 newpt->stepdir = 1;
00467 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00468 cprintf("m");
00469 #endif
00470 }
00471
00472 if (join == NULL) {
00473 newpt->next = newpt;
00474 newpt->prev = newpt;
00475 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00476 cprintf("n");
00477 #endif
00478 }
00479 else {
00480 if (newpt->pos.x () == join->pos.x ()
00481 && newpt->pos.y () + newpt->stepy == join->pos.y ()) {
00482 newpt->prev = join->prev;
00483 newpt->prev->next = newpt;
00484 newpt->next = join;
00485 join->prev = newpt;
00486 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00487 cprintf("o");
00488 #endif
00489 }
00490 else {
00491 newpt->next = join->next;
00492 newpt->next->prev = newpt;
00493 newpt->prev = join;
00494 join->next = newpt;
00495 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD)
00496 cprintf("p");
00497 #endif
00498 }
00499 }
00500 return newpt;
00501 }
00502
00503
00510 void join_edges(
00511 CRACKEDGE *edge1,
00512 CRACKEDGE *edge2
00513 ) {
00514 CRACKEDGE *tempedge;
00515
00516 if (edge1->pos.x () + edge1->stepx != edge2->pos.x ()
00517 || edge1->pos.y () + edge1->stepy != edge2->pos.y ()) {
00518 tempedge = edge1;
00519 edge1 = edge2;
00520 edge2 = tempedge;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 if (edge1->next == edge2) {
00530 #if defined(TEXT_VERBOSE) && !defined(TV_FOCUSE)
00531 cprintf("c");
00532 #endif
00533
00534 complete_edge(edge1);
00535
00536 edge1->prev->next = free_cracks;
00537 free_cracks = edge1;
00538 }
00539 else {
00540
00541 edge2->prev->next = edge1->next;
00542 edge1->next->prev = edge2->prev;
00543 edge1->next = edge2;
00544 edge2->prev = edge1;
00545 }
00546 }
00547
00548
00554 void free_crackedges(
00555 CRACKEDGE *start
00556 ) {
00557 CRACKEDGE *current;
00558 CRACKEDGE *next;
00559
00560 for (current = start; current != NULL; current = next) {
00561 next = current->next;
00562 delete current;
00563 }
00564 }