All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
edgloop.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * File: edgloop.c (Formerly edgeloop.c)
3  * Description: Functions to clean up an outline before approximation.
4  * Author: Ray Smith
5  * Created: Tue Mar 26 16:56:25 GMT 1991
6  *
7  * (C) Copyright 1991, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include "scanedg.h"
21 #include "drawedg.h"
22 #include "edgloop.h"
23 
24 // Include automatically generated configuration file if running autoconf.
25 #ifdef HAVE_CONFIG_H
26 #include "config_auto.h"
27 #endif
28 
29 #define MINEDGELENGTH 8 // min decent length
30 
31 /**********************************************************************
32  * complete_edge
33  *
34  * Complete the edge by cleaning it up.
35  **********************************************************************/
36 
37 void complete_edge(CRACKEDGE *start, //start of loop
38  C_OUTLINE_IT* outline_it) {
39  ScrollView::Color colour; //colour to draw in
40  inT16 looplength; //steps in loop
41  ICOORD botleft; //bounding box
42  ICOORD topright;
43  C_OUTLINE *outline; //new outline
44 
45  //check length etc.
46  colour = check_path_legal (start);
47 
48  if (colour == ScrollView::RED || colour == ScrollView::BLUE) {
49  looplength = loop_bounding_box (start, botleft, topright);
50  outline = new C_OUTLINE (start, botleft, topright, looplength);
51  //add to list
52  outline_it->add_after_then_move (outline);
53  }
54 }
55 
56 
57 /**********************************************************************
58  * check_path_legal
59  *
60  * Check that the outline is legal for length and for chaincode sum.
61  * The return value is RED for a normal black-inside outline,
62  * BLUE for a white-inside outline, MAGENTA if it is too short,
63  * YELLOW if it is too long, and GREEN if it is illegal.
64  * These colours are used to draw the raw outline.
65  **********************************************************************/
66 
68  CRACKEDGE *start //start of loop
69  ) {
70  int lastchain; //last chain code
71  int chaindiff; //chain code diff
72  inT32 length; //length of loop
73  inT32 chainsum; //sum of chain diffs
74  CRACKEDGE *edgept; //current point
75  const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes";
76 
77  length = 0;
78  chainsum = 0; //sum of chain codes
79  edgept = start;
80  lastchain = edgept->prev->stepdir; //previous chain code
81  do {
82  length++;
83  if (edgept->stepdir != lastchain) {
84  //chain code difference
85  chaindiff = edgept->stepdir - lastchain;
86  if (chaindiff > 2)
87  chaindiff -= 4;
88  else if (chaindiff < -2)
89  chaindiff += 4;
90  chainsum += chaindiff; //sum differences
91  lastchain = edgept->stepdir;
92  }
93  edgept = edgept->next;
94  }
95  while (edgept != start && length < C_OUTLINE::kMaxOutlineLength);
96 
97  if ((chainsum != 4 && chainsum != -4)
98  || edgept != start || length < MINEDGELENGTH) {
99  if (edgept != start) {
100  return ScrollView::YELLOW;
101  } else if (length < MINEDGELENGTH) {
102  return ScrollView::MAGENTA;
103  } else {
104  ED_ILLEGAL_SUM.error ("check_path_legal", TESSLOG, "chainsum=%d",
105  chainsum);
106  return ScrollView::GREEN;
107  }
108  }
109  //colour on inside
110  return chainsum < 0 ? ScrollView::BLUE : ScrollView::RED;
111 }
112 
113 /**********************************************************************
114  * loop_bounding_box
115  *
116  * Find the bounding box of the edge loop.
117  **********************************************************************/
118 
119 inT16 loop_bounding_box( //get bounding box
120  CRACKEDGE *&start, //edge loop
121  ICOORD &botleft, //bounding box
122  ICOORD &topright) {
123  inT16 length; //length of loop
124  inT16 leftmost; //on top row
125  CRACKEDGE *edgept; //current point
126  CRACKEDGE *realstart; //topleft start
127 
128  edgept = start;
129  realstart = start;
130  botleft = topright = ICOORD (edgept->pos.x (), edgept->pos.y ());
131  leftmost = edgept->pos.x ();
132  length = 0; //coutn length
133  do {
134  edgept = edgept->next;
135  if (edgept->pos.x () < botleft.x ())
136  //get bounding box
137  botleft.set_x (edgept->pos.x ());
138  else if (edgept->pos.x () > topright.x ())
139  topright.set_x (edgept->pos.x ());
140  if (edgept->pos.y () < botleft.y ())
141  //get bounding box
142  botleft.set_y (edgept->pos.y ());
143  else if (edgept->pos.y () > topright.y ()) {
144  realstart = edgept;
145  leftmost = edgept->pos.x ();
146  topright.set_y (edgept->pos.y ());
147  }
148  else if (edgept->pos.y () == topright.y ()
149  && edgept->pos.x () < leftmost) {
150  //leftmost on line
151  leftmost = edgept->pos.x ();
152  realstart = edgept;
153  }
154  length++; //count elements
155  }
156  while (edgept != start);
157  start = realstart; //shift it to topleft
158  return length;
159 }
void set_x(inT16 xin)
rewrite function
Definition: points.h:61
inT16 loop_bounding_box(CRACKEDGE *&start, ICOORD &botleft, ICOORD &topright)
Definition: edgloop.cpp:119
ICOORD pos
Definition: crakedge.h:30
ScrollView::Color check_path_legal(CRACKEDGE *start)
Definition: edgloop.cpp:67
void complete_edge(CRACKEDGE *start, C_OUTLINE_IT *outline_it)
Definition: edgloop.cpp:37
inT8 stepdir
Definition: crakedge.h:33
CRACKEDGE * prev
Definition: crakedge.h:34
inT16 y() const
access_function
Definition: points.h:56
class DLLSYM C_OUTLINE
Definition: coutln.h:65
void error(const char *caller, TessErrorLogCode action, const char *format,...) const
Definition: errcode.cpp:40
integer coordinate
Definition: points.h:30
static const int kMaxOutlineLength
Definition: coutln.h:271
void set_y(inT16 yin)
rewrite function
Definition: points.h:65
inT16 x() const
access function
Definition: points.h:52
#define MINEDGELENGTH
Definition: edgloop.cpp:29
CRACKEDGE * next
Definition: crakedge.h:35
short inT16
Definition: host.h:100
int inT32
Definition: host.h:102