Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions
scanedg.cpp File Reference
`#include "mfcpch.h"`
`#include "edgloop.h"`
`#include "scanedg.h"`

Go to the source code of this file.

## Macros

#define | WHITE_PIX 1 /*thresholded colours */
#define | BLACK_PIX 0
#define | FLIP_COLOUR(pix) (1-(pix))

## Functions

void | block_edges (IMAGE *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 | whiteout_block (IMAGE *t_image, PDBLK *block)
void | line_edges (inT16 x, inT16 y, inT16 xext, uinT8 uppercolour, uinT8 *bwpos, CRACKEDGE **prevline, CRACKEDGE **free_cracks, C_OUTLINE_IT *outline_it)
CRACKEDGE * | h_edge (int sign, CRACKEDGE *join, CrackPos *pos)
CRACKEDGE * | v_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)

## Macro Definition Documentation

#define BLACK_PIX 0

Definition at line 25 of file scanedg.cpp.

#define FLIP_COLOUR | ( |  | pix | ) | (1-(pix))

Definition at line 27 of file scanedg.cpp.

#define WHITE_PIX 1 /*thresholded colours */

Definition at line 24 of file scanedg.cpp.

## Function Documentation

void block_edges | ( | IMAGE * | t_image,
|  | PDBLK * | block,
|  | C_OUTLINE_IT * | outline_it
| ) |  |

Definition at line 35 of file scanedg.cpp.

{
uinT8 margin; // margin colour
inT16 x; // line coords
inT16 y; // current line
ICOORD bleft; // bounding box
ICOORD tright;
ICOORD block_bleft; // bounding box
ICOORD block_tright;
int xindex; // index to pixel
BLOCK_LINE_IT line_it = block; // line iterator
IMAGELINE bwline; // thresholded line
// lines in progress
CRACKEDGE **ptrline = new CRACKEDGE*[t_image->get_xsize()+1];
CRACKEDGE *free_cracks = NULL;
block->bounding_box(bleft, tright); // block box
block_bleft = bleft;
block_tright = tright;
for (x = tright.x() - bleft.x(); x >= 0; x--)
ptrline[x] = NULL; //no lines in progress
bwline.init(t_image->get_xsize());
margin = WHITE_PIX;
for (y = tright.y() - 1; y >= bleft.y() - 1; y--) {
if (y >= block_bleft.y() && y < block_tright.y()) {
t_image->get_line(bleft.x(), y, tright.x() - bleft.x(), &bwline, 0);
make_margins(block, &line_it, bwline.pixels, margin, bleft.x(),
tright.x(), y);
} else {
x = tright.x() - bleft.x();
for (xindex = 0; xindex < x; xindex++)
bwline.pixels[xindex] = margin;
}
line_edges(bleft.x(), y, tright.x() - bleft.x(),
margin, bwline.pixels, ptrline, &free_cracks, outline_it);
}
free_crackedges(free_cracks); // really free them
delete[] ptrline;
}

void free_crackedges | ( | CRACKEDGE * | start | ) |

Definition at line 398 of file scanedg.cpp.

{
CRACKEDGE *current; // current edge to free
CRACKEDGE *next; // next one to free
for (current = start; current != NULL; current = next) {
next = current->next;
delete current; // delete them all
}
}

CRACKEDGE* h_edge | ( | int | sign,
|  | CRACKEDGE * | join,
|  | CrackPos * | pos
| ) |  |

Definition at line 262 of file scanedg.cpp.

{
CRACKEDGE *newpt; // return value
if (*pos->free_cracks != NULL) {
newpt = *pos->free_cracks;
*pos->free_cracks = newpt->next; // get one fast
} else {
newpt = new CRACKEDGE;
}
newpt->pos.set_y(pos->y + 1); // coords of pt
newpt->stepy = 0; // edge is horizontal
if (sign > 0) {
newpt->pos.set_x(pos->x + 1); // start location
newpt->stepx = -1;
newpt->stepdir = 0;
} else {
newpt->pos.set_x(pos->x); // start location
newpt->stepx = 1;
newpt->stepdir = 2;
}
if (join == NULL) {
newpt->next = newpt; // ptrs to other ends
newpt->prev = newpt;
} else {
if (newpt->pos.x() + newpt->stepx == join->pos.x()
&& newpt->pos.y() == join->pos.y()) {
newpt->prev = join->prev; // update other ends
newpt->prev->next = newpt;
newpt->next = join; // join up
join->prev = newpt;
} else {
newpt->next = join->next; // update other ends
newpt->next->prev = newpt;
newpt->prev = join; // join up
join->next = newpt;
}
}
return newpt;
}

void join_edges | ( | CRACKEDGE * | edge1,
|  | CRACKEDGE * | edge2,
|  | CRACKEDGE ** | free_cracks,
|  | C_OUTLINE_IT * | outline_it
| ) |  |

Definition at line 365 of file scanedg.cpp.

{
if (edge1->pos.x() + edge1->stepx != edge2->pos.x()
|| edge1->pos.y() + edge1->stepy != edge2->pos.y()) {
CRACKEDGE *tempedge = edge1;
edge1 = edge2; // swap araound
edge2 = tempedge;
}
if (edge1->next == edge2) {
// already closed
complete_edge(edge1, outline_it);
// attach freelist to end
edge1->prev->next = *free_cracks;
*free_cracks = edge1; // and free list
} else {
// update opposite ends
edge2->prev->next = edge1->next;
edge1->next->prev = edge2->prev;
edge1->next = edge2; // make joins
edge2->prev = edge1;
}
}

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 178 of file scanedg.cpp.

{
CrackPos pos = {free_cracks, x, y };
int xmax; // max x coord
int colour; // of current pixel
int prevcolour; // of previous pixel
CRACKEDGE *current; // current h edge
CRACKEDGE *newcurrent; // new h edge
xmax = x + xext; // max allowable coord
prevcolour = uppercolour; // forced plain margin
current = NULL; // nothing yet
// do each pixel
for (; pos.x < xmax; pos.x++, prevline++) {
colour = *bwpos++; // current pixel
if (*prevline != NULL) {
// changed above
// change colour
uppercolour = FLIP_COLOUR(uppercolour);
if (colour == prevcolour) {
if (colour == uppercolour) {
// finish a line
join_edges(current, *prevline, free_cracks, outline_it);
current = NULL; // no edge now
} else {
// new horiz edge
current = h_edge(uppercolour - colour, *prevline, &pos);
}
*prevline = NULL; // no change this time
} else {
if (colour == uppercolour)
*prevline = v_edge(colour - prevcolour, *prevline, &pos);
// 8 vs 4 connection
else if (colour == WHITE_PIX) {
join_edges(current, *prevline, free_cracks, outline_it);
current = h_edge(uppercolour - colour, NULL, &pos);
*prevline = v_edge(colour - prevcolour, current, &pos);
} else {
newcurrent = h_edge(uppercolour - colour, *prevline, &pos);
*prevline = v_edge(colour - prevcolour, current, &pos);
current = newcurrent; // right going h edge
}
prevcolour = colour; // remember new colour
}
} else {
if (colour != prevcolour) {
*prevline = current = v_edge(colour - prevcolour, current, &pos);
prevcolour = colour;
}
if (colour != uppercolour)
current = h_edge(uppercolour - colour, current, &pos);
else
current = NULL; // no edge now
}
}
if (current != NULL) {
// out of block
if (*prevline != NULL) { // got one to join to?
join_edges(current, *prevline, free_cracks, outline_it);
*prevline = NULL; // tidy now
} else {
// fake vertical
*prevline = v_edge(FLIP_COLOUR(prevcolour)-prevcolour, current, &pos);
}
} else if (*prevline != NULL) {
//continue fake
*prevline = v_edge(FLIP_COLOUR(prevcolour)-prevcolour, *prevline, &pos);
}
}

void make_margins | ( | PDBLK * | block,
|  | BLOCK_LINE_IT * | line_it,
|  | uinT8 * | pixels,
|  | uinT8 | margin,
|  | inT16 | left,
|  | inT16 | right,
|  | inT16 | y
| ) |  |

Definition at line 87 of file scanedg.cpp.

{
PB_LINE_IT *lines;
ICOORDELT_LIST *segments; //bits of a line
ICOORDELT_IT seg_it;
inT32 start; //of segment
inT16 xext; //of segment
int xindex; //index to pixel
if (block->poly_block () != NULL) {
lines = new PB_LINE_IT (block->poly_block ());
segments = lines->get_line (y);
if (!segments->empty ()) {
seg_it.set_to_list (segments);
seg_it.mark_cycle_pt ();
start = seg_it.data ()->x ();
xext = seg_it.data ()->y ();
for (xindex = left; xindex < right; xindex++) {
if (xindex >= start && !seg_it.cycled_list ()) {
xindex = start + xext - 1;
seg_it.forward ();
start = seg_it.data ()->x ();
xext = seg_it.data ()->y ();
}
else
pixels[xindex - left] = margin;
}
}
else {
for (xindex = left; xindex < right; xindex++)
pixels[xindex - left] = margin;
}
delete segments;
delete lines;
}
else {
start = line_it->get_line (y, xext);
for (xindex = left; xindex < start; xindex++)
pixels[xindex - left] = margin;
for (xindex = start + xext; xindex < right; xindex++)
pixels[xindex - left] = margin;
}
}

CRACKEDGE* v_edge | ( | int | sign,
|  | CRACKEDGE * | join,
|  | CrackPos * | pos
| ) |  |

Definition at line 313 of file scanedg.cpp.

{
CRACKEDGE *newpt; // return value
if (*pos->free_cracks != NULL) {
newpt = *pos->free_cracks;
*pos->free_cracks = newpt->next; // get one fast
} else {
newpt = new CRACKEDGE;
}
newpt->pos.set_x(pos->x); // coords of pt
newpt->stepx = 0; // edge is vertical
if (sign > 0) {
newpt->pos.set_y(pos->y); // start location
newpt->stepy = 1;
newpt->stepdir = 3;
} else {
newpt->pos.set_y(pos->y + 1); // start location
newpt->stepy = -1;
newpt->stepdir = 1;
}
if (join == NULL) {
newpt->next = newpt; //ptrs to other ends
newpt->prev = newpt;
} else {
if (newpt->pos.x() == join->pos.x()
&& newpt->pos.y() + newpt->stepy == join->pos.y()) {
newpt->prev = join->prev; // update other ends
newpt->prev->next = newpt;
newpt->next = join; // join up
join->prev = newpt;
} else {
newpt->next = join->next; // update other ends
newpt->next->prev = newpt;
newpt->prev = join; // join up
join->next = newpt;
}
}
return newpt;
}

void whiteout_block | ( | IMAGE * | t_image,
|  | PDBLK * | block
| ) |  |

Definition at line 145 of file scanedg.cpp.

{
inT16 x; //line coords
inT16 y; //current line
inT16 xext; //line width
int xindex; //index to pixel
uinT8 *dest; //destination pixel
TBOX block_box; //bounding box
BLOCK_LINE_IT line_it = block; //line iterator
IMAGELINE bwline; //thresholded line
block_box = block->bounding_box ();
for (y = block_box.bottom (); y < block_box.top (); y++) {
//find line limits
x = line_it.get_line (y, xext);
t_image->get_line (x, y, xext, &bwline, 0);
dest = bwline.pixels; //destination pixel
for (xindex = 0; xindex < xext; xindex++)
*dest++ = 1;
t_image->put_line (x, y, xext, &bwline, 0);
}
}