00001
00020 #include "mfcpch.h"
00021 #include "scanedg.h"
00022 #include "drawedg.h"
00023 #include "edgloop.h"
00024
00025 #ifdef TEXT_VERBOSE
00026 #include "../cutil/callcpp.h"
00027 #endif
00028
00030 #define MINEDGELENGTH 8
00031
00032 #define EXTERN
00033
00036 EXTERN double_VAR (edges_threshold_greyfraction, 0.07,
00037 "Min edge diff for grad vector");
00038 EXTERN BOOL_VAR (edges_show_paths, FALSE, "Draw raw outlines");
00039 EXTERN BOOL_VAR (edges_show_needles, FALSE, "Draw edge needles");
00040 EXTERN INT_VAR (edges_maxedgelength, 16000, "Max steps in any outline");
00043 #ifndef GRAPHICS_DISABLED
00045 static WINDOW edge_win;
00046 #endif
00048 static C_OUTLINE_IT *outline_it;
00050 static int short_edges;
00052 static int long_edges;
00053
00068 DLLSYM void get_outlines(
00069 #ifndef GRAPHICS_DISABLED
00070 WINDOW window,
00071 #endif
00072 IMAGE *image,
00073 IMAGE *t_image,
00074 ICOORD page_tr,
00075 PDBLK *block,
00076 C_OUTLINE_IT *out_it
00077 ) {
00078 #ifndef GRAPHICS_DISABLED
00079 edge_win = window;
00080 #endif
00081 outline_it = out_it;
00082 block_edges(t_image, block, page_tr);
00083 out_it->move_to_first ();
00084 #ifndef GRAPHICS_DISABLED
00085 if (window != NO_WINDOW)
00086 overlap_picture_ops(TRUE);
00087 #endif
00088 }
00089
00090
00099 void complete_edge(
00100 CRACKEDGE *start
00101 ) {
00102 COLOUR colour;
00103 INT16 looplength;
00104 ICOORD botleft;
00105 ICOORD topright;
00106 C_OUTLINE *outline;
00107
00108
00109 colour = check_path_legal (start);
00110 #ifndef GRAPHICS_DISABLED
00111 if (edges_show_paths) {
00112
00113 draw_raw_edge(edge_win, start, colour);
00114 }
00115 #endif
00116
00117 if (colour == RED || colour == BLUE) {
00118 looplength = loop_bounding_box (start, botleft, topright);
00119 outline = new C_OUTLINE (start, botleft, topright, looplength);
00120
00121 outline_it->add_after_then_move (outline);
00122 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00123 cprintf("Z");
00124 #endif
00125 }
00126 }
00127
00128
00197 COLOUR check_path_legal(
00198 CRACKEDGE *start
00199 ) {
00200 int lastchain;
00201 int chaindiff;
00202 INT32 length;
00203 INT32 chainsum;
00204 CRACKEDGE *edgept;
00205 const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes";
00206
00207 length = 0;
00208 chainsum = 0;
00209 edgept = start;
00210 lastchain = edgept->prev->stepdir;
00211
00212 int c = 0;
00213 do {
00214 length++;
00215 if (edgept->stepdir != lastchain) {
00216
00217 chaindiff = edgept->stepdir - lastchain;
00218 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00219 cprintf("1(%d,%d,%d)",edgept->stepdir,lastchain,chaindiff);
00220 #endif
00221 if (chaindiff > 2)
00222 chaindiff -= 4;
00223 else if (chaindiff < -2)
00224 chaindiff += 4;
00225 chainsum += chaindiff;
00226 lastchain = edgept->stepdir;
00227 }
00228 edgept = edgept->next;
00229 c++;
00230 }
00231 while (edgept != start && length < edges_maxedgelength);
00232
00233 if (chainsum != 4 && chainsum != -4
00234 || edgept != start || length < MINEDGELENGTH) {
00235 if (edgept != start) {
00236 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00237 cprintf("\n2(Y:%d,%d,iter=%d)",length,chainsum,c);
00238 #endif
00239 long_edges++;
00240 return YELLOW;
00241 }
00242 else if (length < MINEDGELENGTH) {
00243 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00244 cprintf("3(M:%d,%d,iter=%d)",length,chainsum,c);
00245 #endif
00246 short_edges++;
00247 return MAGENTA;
00248 }
00249 else {
00250 ED_ILLEGAL_SUM.error ("check_path_legal", LOG, "chainsum=%d",
00251 chainsum);
00252 return GREEN;
00253 }
00254 }
00255 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00256 cprintf("4(%s:%d,%d,iter=%d)",(chainsum < 0 ? "B" : "R"),
00257 length,chainsum,c);
00258 #endif
00259
00260 return chainsum < 0 ? BLUE : RED;
00261 }
00262
00274 INT16 loop_bounding_box(
00275 CRACKEDGE *&start,
00276 ICOORD &botleft,
00277 ICOORD &topright) {
00278 INT16 length;
00279 INT16 leftmost;
00280 CRACKEDGE *edgept;
00281 CRACKEDGE *realstart;
00282
00283 edgept = start;
00284 realstart = start;
00285 botleft = topright = ICOORD (edgept->pos.x (), edgept->pos.y ());
00286 leftmost = edgept->pos.x ();
00287 length = 0;
00288 do {
00289 edgept = edgept->next;
00290 if (edgept->pos.x () < botleft.x ())
00291
00292 botleft.set_x (edgept->pos.x ());
00293 else if (edgept->pos.x () > topright.x ())
00294 topright.set_x (edgept->pos.x ());
00295 if (edgept->pos.y () < botleft.y ())
00296
00297 botleft.set_y (edgept->pos.y ());
00298 else if (edgept->pos.y () > topright.y ()) {
00299 realstart = edgept;
00300 leftmost = edgept->pos.x ();
00301 topright.set_y (edgept->pos.y ());
00302 }
00303 else if (edgept->pos.y () == topright.y ()
00304 && edgept->pos.x () < leftmost) {
00305
00306 leftmost = edgept->pos.x ();
00307 realstart = edgept;
00308 }
00309 length++;
00310 }
00311 while (edgept != start);
00312 start = realstart;
00313 return length;
00314 }