All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
scanedg.h File Reference
#include "params.h"
#include "scrollview.h"
#include "pdblock.h"
#include "crakedge.h"

Go to the source code of this file.

Classes

struct  CrackPos
 

Functions

void block_edges (Pix *t_image, PDBLK *block, C_OUTLINE_IT *outline_it)
 
void make_margins (PDBLK *block, BLOCK_LINE_IT *line_it, uinT8 *pixels, uinT8 margin, inT16 left, inT16 right, inT16 y)
 
void line_edges (inT16 x, inT16 y, inT16 xext, uinT8 uppercolour, uinT8 *bwpos, CRACKEDGE **prevline, CRACKEDGE **free_cracks, C_OUTLINE_IT *outline_it)
 
CRACKEDGEh_edge (int sign, CRACKEDGE *join, CrackPos *pos)
 
CRACKEDGEv_edge (int sign, CRACKEDGE *join, CrackPos *pos)
 
void join_edges (CRACKEDGE *edge1, CRACKEDGE *edge2, CRACKEDGE **free_cracks, C_OUTLINE_IT *outline_it)
 
void free_crackedges (CRACKEDGE *start)
 

Function Documentation

void block_edges ( Pix *  t_image,
PDBLK block,
C_OUTLINE_IT *  outline_it 
)

Definition at line 36 of file scanedg.cpp.

38  {
39  ICOORD bleft; // bounding box
40  ICOORD tright;
41  BLOCK_LINE_IT line_it = block; // line iterator
42 
43  int width = pixGetWidth(t_pix);
44  int height = pixGetHeight(t_pix);
45  int wpl = pixGetWpl(t_pix);
46  // lines in progress
47  CRACKEDGE **ptrline = new CRACKEDGE*[width + 1];
48  CRACKEDGE *free_cracks = NULL;
49 
50  block->bounding_box(bleft, tright); // block box
51  int block_width = tright.x() - bleft.x();
52  for (int x = block_width; x >= 0; x--)
53  ptrline[x] = NULL; // no lines in progress
54 
55  uinT8* bwline = new uinT8[width];
56 
57  uinT8 margin = WHITE_PIX;
58 
59  for (int y = tright.y() - 1; y >= bleft.y() - 1; y--) {
60  if (y >= bleft.y() && y < tright.y()) {
61  // Get the binary pixels from the image.
62  l_uint32* line = pixGetData(t_pix) + wpl * (height - 1 - y);
63  for (int x = 0; x < block_width; ++x) {
64  bwline[x] = GET_DATA_BIT(line, x + bleft.x()) ^ 1;
65  }
66  make_margins(block, &line_it, bwline, margin, bleft.x(), tright.x(), y);
67  } else {
68  memset(bwline, margin, block_width * sizeof(bwline[0]));
69  }
70  line_edges(bleft.x(), y, block_width,
71  margin, bwline, ptrline, &free_cracks, outline_it);
72  }
73 
74  free_crackedges(free_cracks); // really free them
75  delete[] ptrline;
76  delete[] bwline;
77 }
rectangle iterator
Definition: pdblock.h:160
inT16 y() const
access_function
Definition: points.h:56
void free_crackedges(CRACKEDGE *start)
Definition: scanedg.cpp:364
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
Definition: pdblock.h:67
void line_edges(inT16 x, inT16 y, inT16 xext, uinT8 uppercolour, uinT8 *bwpos, CRACKEDGE **prevline, CRACKEDGE **free_cracks, C_OUTLINE_IT *outline_it)
Definition: scanedg.cpp:144
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
void make_margins(PDBLK *block, BLOCK_LINE_IT *line_it, uinT8 *pixels, uinT8 margin, inT16 left, inT16 right, inT16 y)
Definition: scanedg.cpp:86
#define NULL
Definition: host.h:144
#define WHITE_PIX
Definition: scanedg.cpp:25
unsigned char uinT8
Definition: host.h:99
void free_crackedges ( CRACKEDGE start)

Definition at line 364 of file scanedg.cpp.

364  {
365  CRACKEDGE *current; // current edge to free
366  CRACKEDGE *next; // next one to free
367 
368  for (current = start; current != NULL; current = next) {
369  next = current->next;
370  delete current; // delete them all
371  }
372 }
#define NULL
Definition: host.h:144
CRACKEDGE * next
Definition: crakedge.h:35
CRACKEDGE* h_edge ( int  sign,
CRACKEDGE join,
CrackPos pos 
)

Definition at line 228 of file scanedg.cpp.

230  {
231  CRACKEDGE *newpt; // return value
232 
233  if (*pos->free_cracks != NULL) {
234  newpt = *pos->free_cracks;
235  *pos->free_cracks = newpt->next; // get one fast
236  } else {
237  newpt = new CRACKEDGE;
238  }
239  newpt->pos.set_y(pos->y + 1); // coords of pt
240  newpt->stepy = 0; // edge is horizontal
241 
242  if (sign > 0) {
243  newpt->pos.set_x(pos->x + 1); // start location
244  newpt->stepx = -1;
245  newpt->stepdir = 0;
246  } else {
247  newpt->pos.set_x(pos->x); // start location
248  newpt->stepx = 1;
249  newpt->stepdir = 2;
250  }
251 
252  if (join == NULL) {
253  newpt->next = newpt; // ptrs to other ends
254  newpt->prev = newpt;
255  } else {
256  if (newpt->pos.x() + newpt->stepx == join->pos.x()
257  && newpt->pos.y() == join->pos.y()) {
258  newpt->prev = join->prev; // update other ends
259  newpt->prev->next = newpt;
260  newpt->next = join; // join up
261  join->prev = newpt;
262  } else {
263  newpt->next = join->next; // update other ends
264  newpt->next->prev = newpt;
265  newpt->prev = join; // join up
266  join->next = newpt;
267  }
268  }
269  return newpt;
270 }
void set_x(inT16 xin)
rewrite function
Definition: points.h:61
ICOORD pos
Definition: crakedge.h:30
CRACKEDGE ** free_cracks
Definition: scanedg.h:31
LIST join(LIST list1, LIST list2)
Definition: oldlist.cpp:264
int y
Definition: scanedg.h:33
int x
Definition: scanedg.h:32
inT8 stepdir
Definition: crakedge.h:33
CRACKEDGE * prev
Definition: crakedge.h:34
inT16 y() const
access_function
Definition: points.h:56
inT8 stepx
Definition: crakedge.h:31
void set_y(inT16 yin)
rewrite function
Definition: points.h:65
inT16 x() const
access function
Definition: points.h:52
#define NULL
Definition: host.h:144
CRACKEDGE * next
Definition: crakedge.h:35
inT8 stepy
Definition: crakedge.h:32
void join_edges ( CRACKEDGE edge1,
CRACKEDGE edge2,
CRACKEDGE **  free_cracks,
C_OUTLINE_IT *  outline_it 
)

Definition at line 331 of file scanedg.cpp.

334  {
335  if (edge1->pos.x() + edge1->stepx != edge2->pos.x()
336  || edge1->pos.y() + edge1->stepy != edge2->pos.y()) {
337  CRACKEDGE *tempedge = edge1;
338  edge1 = edge2; // swap araound
339  edge2 = tempedge;
340  }
341 
342  if (edge1->next == edge2) {
343  // already closed
344  complete_edge(edge1, outline_it);
345  // attach freelist to end
346  edge1->prev->next = *free_cracks;
347  *free_cracks = edge1; // and free list
348  } else {
349  // update opposite ends
350  edge2->prev->next = edge1->next;
351  edge1->next->prev = edge2->prev;
352  edge1->next = edge2; // make joins
353  edge2->prev = edge1;
354  }
355 }
ICOORD pos
Definition: crakedge.h:30
void complete_edge(CRACKEDGE *start, C_OUTLINE_IT *outline_it)
Definition: edgloop.cpp:37
CRACKEDGE * prev
Definition: crakedge.h:34
inT16 y() const
access_function
Definition: points.h:56
inT8 stepx
Definition: crakedge.h:31
inT16 x() const
access function
Definition: points.h:52
CRACKEDGE * next
Definition: crakedge.h:35
inT8 stepy
Definition: crakedge.h:32
void line_edges ( inT16  x,
inT16  y,
inT16  xext,
uinT8  uppercolour,
uinT8 bwpos,
CRACKEDGE **  prevline,
CRACKEDGE **  free_cracks,
C_OUTLINE_IT *  outline_it 
)

Definition at line 144 of file scanedg.cpp.

151  {
152  CrackPos pos = {free_cracks, x, y };
153  int xmax; // max x coord
154  int colour; // of current pixel
155  int prevcolour; // of previous pixel
156  CRACKEDGE *current; // current h edge
157  CRACKEDGE *newcurrent; // new h edge
158 
159  xmax = x + xext; // max allowable coord
160  prevcolour = uppercolour; // forced plain margin
161  current = NULL; // nothing yet
162 
163  // do each pixel
164  for (; pos.x < xmax; pos.x++, prevline++) {
165  colour = *bwpos++; // current pixel
166  if (*prevline != NULL) {
167  // changed above
168  // change colour
169  uppercolour = FLIP_COLOUR(uppercolour);
170  if (colour == prevcolour) {
171  if (colour == uppercolour) {
172  // finish a line
173  join_edges(current, *prevline, free_cracks, outline_it);
174  current = NULL; // no edge now
175  } else {
176  // new horiz edge
177  current = h_edge(uppercolour - colour, *prevline, &pos);
178  }
179  *prevline = NULL; // no change this time
180  } else {
181  if (colour == uppercolour)
182  *prevline = v_edge(colour - prevcolour, *prevline, &pos);
183  // 8 vs 4 connection
184  else if (colour == WHITE_PIX) {
185  join_edges(current, *prevline, free_cracks, outline_it);
186  current = h_edge(uppercolour - colour, NULL, &pos);
187  *prevline = v_edge(colour - prevcolour, current, &pos);
188  } else {
189  newcurrent = h_edge(uppercolour - colour, *prevline, &pos);
190  *prevline = v_edge(colour - prevcolour, current, &pos);
191  current = newcurrent; // right going h edge
192  }
193  prevcolour = colour; // remember new colour
194  }
195  } else {
196  if (colour != prevcolour) {
197  *prevline = current = v_edge(colour - prevcolour, current, &pos);
198  prevcolour = colour;
199  }
200  if (colour != uppercolour)
201  current = h_edge(uppercolour - colour, current, &pos);
202  else
203  current = NULL; // no edge now
204  }
205  }
206  if (current != NULL) {
207  // out of block
208  if (*prevline != NULL) { // got one to join to?
209  join_edges(current, *prevline, free_cracks, outline_it);
210  *prevline = NULL; // tidy now
211  } else {
212  // fake vertical
213  *prevline = v_edge(FLIP_COLOUR(prevcolour)-prevcolour, current, &pos);
214  }
215  } else if (*prevline != NULL) {
216  //continue fake
217  *prevline = v_edge(FLIP_COLOUR(prevcolour)-prevcolour, *prevline, &pos);
218  }
219 }
int x
Definition: scanedg.h:32
void join_edges(CRACKEDGE *edge1, CRACKEDGE *edge2, CRACKEDGE **free_cracks, C_OUTLINE_IT *outline_it)
Definition: scanedg.cpp:331
CRACKEDGE * v_edge(int sign, CRACKEDGE *join, CrackPos *pos)
Definition: scanedg.cpp:279
#define FLIP_COLOUR(pix)
Definition: scanedg.cpp:28
#define NULL
Definition: host.h:144
CRACKEDGE * h_edge(int sign, CRACKEDGE *join, CrackPos *pos)
Definition: scanedg.cpp:228
#define WHITE_PIX
Definition: scanedg.cpp:25
void make_margins ( PDBLK block,
BLOCK_LINE_IT line_it,
uinT8 pixels,
uinT8  margin,
inT16  left,
inT16  right,
inT16  y 
)

Definition at line 86 of file scanedg.cpp.

94  {
95  PB_LINE_IT *lines;
96  ICOORDELT_LIST *segments; //bits of a line
97  ICOORDELT_IT seg_it;
98  inT32 start; //of segment
99  inT16 xext; //of segment
100  int xindex; //index to pixel
101 
102  if (block->poly_block () != NULL) {
103  lines = new PB_LINE_IT (block->poly_block ());
104  segments = lines->get_line (y);
105  if (!segments->empty ()) {
106  seg_it.set_to_list (segments);
107  seg_it.mark_cycle_pt ();
108  start = seg_it.data ()->x ();
109  xext = seg_it.data ()->y ();
110  for (xindex = left; xindex < right; xindex++) {
111  if (xindex >= start && !seg_it.cycled_list ()) {
112  xindex = start + xext - 1;
113  seg_it.forward ();
114  start = seg_it.data ()->x ();
115  xext = seg_it.data ()->y ();
116  }
117  else
118  pixels[xindex - left] = margin;
119  }
120  }
121  else {
122  for (xindex = left; xindex < right; xindex++)
123  pixels[xindex - left] = margin;
124  }
125  delete segments;
126  delete lines;
127  }
128  else {
129  start = line_it->get_line (y, xext);
130  for (xindex = left; xindex < start; xindex++)
131  pixels[xindex - left] = margin;
132  for (xindex = start + xext; xindex < right; xindex++)
133  pixels[xindex - left] = margin;
134  }
135 }
ICOORDELT_LIST * get_line(inT16 y)
Definition: polyblk.cpp:341
inT16 get_line(inT16 y, inT16 &xext)
Definition: pdblock.cpp:344
#define NULL
Definition: host.h:144
POLY_BLOCK * poly_block() const
Definition: pdblock.h:59
short inT16
Definition: host.h:100
int inT32
Definition: host.h:102
CRACKEDGE* v_edge ( int  sign,
CRACKEDGE join,
CrackPos pos 
)

Definition at line 279 of file scanedg.cpp.

281  {
282  CRACKEDGE *newpt; // return value
283 
284  if (*pos->free_cracks != NULL) {
285  newpt = *pos->free_cracks;
286  *pos->free_cracks = newpt->next; // get one fast
287  } else {
288  newpt = new CRACKEDGE;
289  }
290  newpt->pos.set_x(pos->x); // coords of pt
291  newpt->stepx = 0; // edge is vertical
292 
293  if (sign > 0) {
294  newpt->pos.set_y(pos->y); // start location
295  newpt->stepy = 1;
296  newpt->stepdir = 3;
297  } else {
298  newpt->pos.set_y(pos->y + 1); // start location
299  newpt->stepy = -1;
300  newpt->stepdir = 1;
301  }
302 
303  if (join == NULL) {
304  newpt->next = newpt; //ptrs to other ends
305  newpt->prev = newpt;
306  } else {
307  if (newpt->pos.x() == join->pos.x()
308  && newpt->pos.y() + newpt->stepy == join->pos.y()) {
309  newpt->prev = join->prev; // update other ends
310  newpt->prev->next = newpt;
311  newpt->next = join; // join up
312  join->prev = newpt;
313  } else {
314  newpt->next = join->next; // update other ends
315  newpt->next->prev = newpt;
316  newpt->prev = join; // join up
317  join->next = newpt;
318  }
319  }
320  return newpt;
321 }
void set_x(inT16 xin)
rewrite function
Definition: points.h:61
ICOORD pos
Definition: crakedge.h:30
CRACKEDGE ** free_cracks
Definition: scanedg.h:31
LIST join(LIST list1, LIST list2)
Definition: oldlist.cpp:264
int y
Definition: scanedg.h:33
int x
Definition: scanedg.h:32
inT8 stepdir
Definition: crakedge.h:33
CRACKEDGE * prev
Definition: crakedge.h:34
inT16 y() const
access_function
Definition: points.h:56
inT8 stepx
Definition: crakedge.h:31
void set_y(inT16 yin)
rewrite function
Definition: points.h:65
inT16 x() const
access function
Definition: points.h:52
#define NULL
Definition: host.h:144
CRACKEDGE * next
Definition: crakedge.h:35
inT8 stepy
Definition: crakedge.h:32