blob: 73fd09e11b4f2420f0458ad07f8e57977068e1ff [file] [log] [blame]
/* -*-C-*-
********************************************************************************
*
* File: blobs.c (Formerly blobs.c)
* Description: Blob definition
* Author: Mark Seaman, OCR Technology
* Created: Fri Oct 27 15:39:52 1989
* Modified: Thu Mar 28 15:33:26 1991 (Mark Seaman) marks@hpgrlt
* Language: C
* Package: N/A
* Status: Experimental (Do Not Distribute)
*
* (c) Copyright 1989, Hewlett-Packard Company.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
*********************************************************************************/
/*----------------------------------------------------------------------
I n c l u d e s
----------------------------------------------------------------------*/
#include "mfcpch.h"
#include "blobs.h"
#include "cutil.h"
#include "emalloc.h"
#include "structures.h"
/*----------------------------------------------------------------------
F u n c t i o n s
----------------------------------------------------------------------*/
/**********************************************************************
* blob_origin
*
* Compute the origin of a compound blob, define to be the centre
* of the bounding box.
**********************************************************************/
void blob_origin(TBLOB *blob, /*blob to compute on */
TPOINT *origin) { /*return value */
TPOINT topleft; /*bounding box */
TPOINT botright;
/*find bounding box */
blob_bounding_box(blob, &topleft, &botright);
/*centre of box */
origin->x = (topleft.x + botright.x) / 2;
origin->y = (topleft.y + botright.y) / 2;
}
/**********************************************************************
* blob_bounding_box
*
* Compute the bounding_box of a compound blob, define to be the
* max coordinate value of the bounding boxes of all the top-level
* outlines in the box.
**********************************************************************/
void blob_bounding_box(TBLOB *blob, /*blob to compute on */
register TPOINT *topleft, /*bounding box */
register TPOINT *botright) {
register TESSLINE *outline; /*current outline */
if (blob == NULL || blob->outlines == NULL) {
topleft->x = topleft->y = 0;
*botright = *topleft; /*default value */
}
else {
outline = blob->outlines;
*topleft = outline->topleft;
*botright = outline->botright;
for (outline = outline->next; outline != NULL; outline = outline->next) {
if (outline->topleft.x < topleft->x)
/*find extremes */
topleft->x = outline->topleft.x;
if (outline->botright.x > botright->x)
/*find extremes */
botright->x = outline->botright.x;
if (outline->topleft.y > topleft->y)
/*find extremes */
topleft->y = outline->topleft.y;
if (outline->botright.y < botright->y)
/*find extremes */
botright->y = outline->botright.y;
}
}
}
/**********************************************************************
* blobs_bounding_box
*
* Return the smallest extreme point that contain this word.
**********************************************************************/
void blobs_bounding_box(TBLOB *blobs, TPOINT *topleft, TPOINT *botright) {
TPOINT tl;
TPOINT br;
TBLOB *blob;
/* Start with first blob */
blob_bounding_box(blobs, topleft, botright);
iterate_blobs(blob, blobs) {
blob_bounding_box(blob, &tl, &br);
if (tl.x < topleft->x)
topleft->x = tl.x;
if (tl.y > topleft->y)
topleft->y = tl.y;
if (br.x > botright->x)
botright->x = br.x;
if (br.y < botright->y)
botright->y = br.y;
}
}
/**********************************************************************
* blobs_origin
*
* Compute the origin of a compound blob, define to be the centre
* of the bounding box.
**********************************************************************/
void blobs_origin(TBLOB *blobs, /*blob to compute on */
TPOINT *origin) { /*return value */
TPOINT topleft; /*bounding box */
TPOINT botright;
/*find bounding box */
blobs_bounding_box(blobs, &topleft, &botright);
/*center of box */
origin->x = (topleft.x + botright.x) / 2;
origin->y = (topleft.y + botright.y) / 2;
}
/**********************************************************************
* blobs_widths
*
* Compute the widths of a list of blobs. Return an array of the widths
* and gaps.
**********************************************************************/
WIDTH_RECORD *blobs_widths(TBLOB *blobs) { /*blob to compute on */
WIDTH_RECORD *width_record;
TPOINT topleft; /*bounding box */
TPOINT botright;
TBLOB *blob; /*blob to compute on */
int i = 0;
int blob_end;
int num_blobs = count_blobs (blobs);
/* Get memory */
width_record = (WIDTH_RECORD *) memalloc (sizeof (int) * num_blobs * 2);
width_record->num_chars = num_blobs;
blob_bounding_box(blobs, &topleft, &botright);
width_record->widths[i++] = botright.x - topleft.x;
/* First width */
blob_end = botright.x;
iterate_blobs (blob, blobs->next) {
blob_bounding_box(blob, &topleft, &botright);
width_record->widths[i++] = topleft.x - blob_end;
width_record->widths[i++] = botright.x - topleft.x;
blob_end = botright.x;
}
return (width_record);
}
/**********************************************************************
* count_blobs
*
* Return a count of the number of blobs attached to this one.
**********************************************************************/
int count_blobs(TBLOB *blobs) {
TBLOB *b;
int x = 0;
iterate_blobs (b, blobs) x++;
return (x);
}
/**********************************************************************
* delete_word
*
* Reclaim the memory taken by this word structure and all of its
* lower level structures.
**********************************************************************/
void delete_word(TWERD *word) {
TBLOB *blob;
TBLOB *nextblob;
TESSLINE *outline;
TESSLINE *nextoutline;
TESSLINE *child;
TESSLINE *nextchild;
for (blob = word->blobs; blob; blob = nextblob) {
nextblob = blob->next;
for (outline = blob->outlines; outline; outline = nextoutline) {
nextoutline = outline->next;
delete_edgepts (outline->loop);
for (child = outline->child; child; child = nextchild) {
nextchild = child->next;
delete_edgepts (child->loop);
oldoutline(child);
}
oldoutline(outline);
}
oldblob(blob);
}
if (word->correct != NULL)
strfree (word->correct); /* Reclaim memory */
oldword(word);
}
/**********************************************************************
* delete_edgepts
*
* Delete a list of EDGEPT structures.
**********************************************************************/
void delete_edgepts(register EDGEPT *edgepts) {
register EDGEPT *this_edge;
register EDGEPT *next_edge;
if (edgepts == NULL)
return;
this_edge = edgepts;
do {
next_edge = this_edge->next;
oldedgept(this_edge);
this_edge = next_edge;
}
while (this_edge != edgepts);
}