• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*-C-*-
2  ********************************************************************************
3  *
4  * File:        blobs.c  (Formerly blobs.c)
5  * Description:  Blob definition
6  * Author:       Mark Seaman, OCR Technology
7  * Created:      Fri Oct 27 15:39:52 1989
8  * Modified:     Thu Mar 28 15:33:26 1991 (Mark Seaman) marks@hpgrlt
9  * Language:     C
10  * Package:      N/A
11  * Status:       Experimental (Do Not Distribute)
12  *
13  * (c) Copyright 1989, Hewlett-Packard Company.
14  ** Licensed under the Apache License, Version 2.0 (the "License");
15  ** you may not use this file except in compliance with the License.
16  ** You may obtain a copy of the License at
17  ** http://www.apache.org/licenses/LICENSE-2.0
18  ** Unless required by applicable law or agreed to in writing, software
19  ** distributed under the License is distributed on an "AS IS" BASIS,
20  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  ** See the License for the specific language governing permissions and
22  ** limitations under the License.
23  *
24  *********************************************************************************/
25 
26 /*----------------------------------------------------------------------
27               I n c l u d e s
28 ----------------------------------------------------------------------*/
29 #include "mfcpch.h"
30 #include "blobs.h"
31 #include "cutil.h"
32 #include "emalloc.h"
33 #include "structures.h"
34 
35 /*----------------------------------------------------------------------
36               F u n c t i o n s
37 ----------------------------------------------------------------------*/
38 /**********************************************************************
39  * blob_origin
40  *
41  * Compute the origin of a compound blob, define to be the centre
42  * of the bounding box.
43  **********************************************************************/
blob_origin(TBLOB * blob,TPOINT * origin)44 void blob_origin(TBLOB *blob,       /*blob to compute on */
45                  TPOINT *origin) {  /*return value */
46   TPOINT topleft;                /*bounding box */
47   TPOINT botright;
48 
49                                  /*find bounding box */
50   blob_bounding_box(blob, &topleft, &botright);
51                                  /*centre of box */
52   origin->x = (topleft.x + botright.x) / 2;
53   origin->y = (topleft.y + botright.y) / 2;
54 }
55 
56 
57 /**********************************************************************
58  * blob_bounding_box
59  *
60  * Compute the bounding_box of a compound blob, define to be the
61  * max coordinate value of the bounding boxes of all the top-level
62  * outlines in the box.
63  **********************************************************************/
blob_bounding_box(TBLOB * blob,register TPOINT * topleft,register TPOINT * botright)64 void blob_bounding_box(TBLOB *blob,               /*blob to compute on */
65                        register TPOINT *topleft,  /*bounding box */
66                        register TPOINT *botright) {
67   register TESSLINE *outline;    /*current outline */
68 
69   if (blob == NULL || blob->outlines == NULL) {
70     topleft->x = topleft->y = 0;
71     *botright = *topleft;        /*default value */
72   }
73   else {
74     outline = blob->outlines;
75     *topleft = outline->topleft;
76     *botright = outline->botright;
77     for (outline = outline->next; outline != NULL; outline = outline->next) {
78       if (outline->topleft.x < topleft->x)
79                                  /*find extremes */
80         topleft->x = outline->topleft.x;
81       if (outline->botright.x > botright->x)
82                                  /*find extremes */
83         botright->x = outline->botright.x;
84       if (outline->topleft.y > topleft->y)
85                                  /*find extremes */
86         topleft->y = outline->topleft.y;
87       if (outline->botright.y < botright->y)
88                                  /*find extremes */
89         botright->y = outline->botright.y;
90     }
91   }
92 }
93 
94 
95 /**********************************************************************
96  * blobs_bounding_box
97  *
98  * Return the smallest extreme point that contain this word.
99  **********************************************************************/
blobs_bounding_box(TBLOB * blobs,TPOINT * topleft,TPOINT * botright)100 void blobs_bounding_box(TBLOB *blobs, TPOINT *topleft, TPOINT *botright) {
101   TPOINT tl;
102   TPOINT br;
103   TBLOB *blob;
104   /* Start with first blob */
105   blob_bounding_box(blobs, topleft, botright);
106 
107   iterate_blobs(blob, blobs) {
108     blob_bounding_box(blob, &tl, &br);
109 
110     if (tl.x < topleft->x)
111       topleft->x = tl.x;
112     if (tl.y > topleft->y)
113       topleft->y = tl.y;
114     if (br.x > botright->x)
115       botright->x = br.x;
116     if (br.y < botright->y)
117       botright->y = br.y;
118   }
119 }
120 
121 
122 /**********************************************************************
123  * blobs_origin
124  *
125  * Compute the origin of a compound blob, define to be the centre
126  * of the bounding box.
127  **********************************************************************/
blobs_origin(TBLOB * blobs,TPOINT * origin)128 void blobs_origin(TBLOB *blobs,      /*blob to compute on */
129                   TPOINT *origin) {  /*return value */
130   TPOINT topleft;                /*bounding box */
131   TPOINT botright;
132 
133                                  /*find bounding box */
134   blobs_bounding_box(blobs, &topleft, &botright);
135                                  /*center of box */
136   origin->x = (topleft.x + botright.x) / 2;
137   origin->y = (topleft.y + botright.y) / 2;
138 }
139 
140 
141 /**********************************************************************
142  * blobs_widths
143  *
144  * Compute the widths of a list of blobs. Return an array of the widths
145  * and gaps.
146  **********************************************************************/
blobs_widths(TBLOB * blobs)147 WIDTH_RECORD *blobs_widths(TBLOB *blobs) {  /*blob to compute on */
148   WIDTH_RECORD *width_record;
149   TPOINT topleft;                /*bounding box */
150   TPOINT botright;
151   TBLOB *blob;                   /*blob to compute on */
152   int i = 0;
153   int blob_end;
154   int num_blobs = count_blobs (blobs);
155 
156   /* Get memory */
157   width_record = (WIDTH_RECORD *) memalloc (sizeof (int) * num_blobs * 2);
158   width_record->num_chars = num_blobs;
159 
160   blob_bounding_box(blobs, &topleft, &botright);
161   width_record->widths[i++] = botright.x - topleft.x;
162   /* First width */
163   blob_end = botright.x;
164 
165   iterate_blobs (blob, blobs->next) {
166     blob_bounding_box(blob, &topleft, &botright);
167     width_record->widths[i++] = topleft.x - blob_end;
168     width_record->widths[i++] = botright.x - topleft.x;
169     blob_end = botright.x;
170   }
171   return (width_record);
172 }
173 
174 
175 /**********************************************************************
176  * count_blobs
177  *
178  * Return a count of the number of blobs attached to this one.
179  **********************************************************************/
count_blobs(TBLOB * blobs)180 int count_blobs(TBLOB *blobs) {
181   TBLOB *b;
182   int x = 0;
183 
184   iterate_blobs (b, blobs) x++;
185   return (x);
186 }
187 
188 
189 /**********************************************************************
190  * delete_word
191  *
192  * Reclaim the memory taken by this word structure and all of its
193  * lower level structures.
194  **********************************************************************/
delete_word(TWERD * word)195 void delete_word(TWERD *word) {
196   TBLOB *blob;
197   TBLOB *nextblob;
198   TESSLINE *outline;
199   TESSLINE *nextoutline;
200   TESSLINE *child;
201   TESSLINE *nextchild;
202 
203   for (blob = word->blobs; blob; blob = nextblob) {
204     nextblob = blob->next;
205 
206     for (outline = blob->outlines; outline; outline = nextoutline) {
207       nextoutline = outline->next;
208 
209       delete_edgepts (outline->loop);
210 
211       for (child = outline->child; child; child = nextchild) {
212         nextchild = child->next;
213 
214         delete_edgepts (child->loop);
215 
216         oldoutline(child);
217       }
218       oldoutline(outline);
219     }
220     oldblob(blob);
221   }
222   if (word->correct != NULL)
223     strfree (word->correct);     /* Reclaim memory */
224   oldword(word);
225 }
226 
227 
228 /**********************************************************************
229  * delete_edgepts
230  *
231  * Delete a list of EDGEPT structures.
232  **********************************************************************/
delete_edgepts(register EDGEPT * edgepts)233 void delete_edgepts(register EDGEPT *edgepts) {
234   register EDGEPT *this_edge;
235   register EDGEPT *next_edge;
236 
237   if (edgepts == NULL)
238     return;
239 
240   this_edge = edgepts;
241   do {
242     next_edge = this_edge->next;
243     oldedgept(this_edge);
244     this_edge = next_edge;
245   }
246   while (this_edge != edgepts);
247 }
248