Tesseract  3.02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
makechop.cpp
Go to the documentation of this file.
1 /* -*-C-*-
2  ********************************************************************************
3  *
4  * File: makechop.c (Formerly makechop.c)
5  * Description:
6  * Author: Mark Seaman, OCR Technology
7  * Created: Fri Oct 16 14:37:00 1987
8  * Modified: Mon Jul 29 15:50:42 1991 (Mark Seaman) marks@hpgrlt
9  * Language: C
10  * Package: N/A
11  * Status: Reusable Software Component
12  *
13  * (c) Copyright 1987, 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  I n c l u d e s
27 ----------------------------------------------------------------------*/
28 
29 #include "makechop.h"
30 #include "blobs.h"
31 #include "render.h"
32 #include "structures.h"
33 #ifdef __UNIX__
34 #include <assert.h>
35 #include <unistd.h>
36 #endif
37 
38 // Include automatically generated configuration file if running autoconf.
39 #ifdef HAVE_CONFIG_H
40 #include "config_auto.h"
41 #endif
42 
43 /*----------------------------------------------------------------------
44  Public Function Code
45 ----------------------------------------------------------------------*/
46 /**********************************************************************
47  * apply_seam
48  *
49  * Split this blob into two blobs by applying the splits included in
50  * the seam description.
51  **********************************************************************/
52 void apply_seam(TBLOB *blob, TBLOB *other_blob, bool italic_blob, SEAM *seam) {
53  if (seam->split1 == NULL) {
54  divide_blobs(blob, other_blob, italic_blob, seam->location);
55  }
56  else if (seam->split2 == NULL) {
57  make_split_blobs(blob, other_blob, italic_blob, seam);
58  }
59  else if (seam->split3 == NULL) {
60  make_double_split(blob, other_blob, italic_blob, seam);
61  }
62  else {
63  make_triple_split(blob, other_blob, italic_blob, seam);
64  }
65 }
66 
67 
68 /**********************************************************************
69  * form_two_blobs
70  *
71  * Group the outlines from the first blob into both of them. Do so
72  * according to the information about the split.
73  **********************************************************************/
74 void form_two_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob,
75  const TPOINT& location) {
76  setup_blob_outlines(blob);
77 
78  divide_blobs(blob, other_blob, italic_blob, location);
79 
81  eliminate_duplicate_outlines(other_blob);
82 
83  correct_blob_order(blob, other_blob);
84 }
85 
86 
87 /**********************************************************************
88  * make_double_split
89  *
90  * Create two blobs out of one by splitting the original one in half.
91  * Return the resultant blobs for classification.
92  **********************************************************************/
93 void make_double_split(TBLOB *blob, TBLOB *other_blob, bool italic_blob,
94  SEAM *seam) {
95  make_single_split(blob->outlines, seam->split1);
96  make_single_split(blob->outlines, seam->split2);
97  form_two_blobs(blob, other_blob, italic_blob, seam->location);
98 }
99 
100 
101 /**********************************************************************
102  * make_single_split
103  *
104  * Create two outlines out of one by splitting the original one in half.
105  * Return the resultant outlines.
106  **********************************************************************/
107 void make_single_split(TESSLINE *outlines, SPLIT *split) {
108  assert (outlines != NULL);
109 
110  split_outline (split->point1, split->point2);
111 
112  while (outlines->next != NULL)
113  outlines = outlines->next;
114 
115  outlines->next = new TESSLINE;
116  outlines->next->loop = split->point1;
117  outlines->next->ComputeBoundingBox();
118 
119  outlines = outlines->next;
120 
121  outlines->next = new TESSLINE;
122  outlines->next->loop = split->point2;
123  outlines->next->ComputeBoundingBox();
124 
125  outlines->next->next = NULL;
126 }
127 
128 
129 /**********************************************************************
130  * make_split_blobs
131  *
132  * Create two blobs out of one by splitting the original one in half.
133  * Return the resultant blobs for classification.
134  **********************************************************************/
135 void make_split_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob,
136  SEAM *seam) {
137  make_single_split(blob->outlines, seam->split1);
138 
139  form_two_blobs (blob, other_blob, italic_blob, seam->location);
140 }
141 
142 
143 /**********************************************************************
144  * make_triple_split
145  *
146  * Create two blobs out of one by splitting the original one in half.
147  * This splitting is accomplished by applying three separate splits on
148  * the outlines. Three of the starting outlines will produce two ending
149  * outlines. Return the resultant blobs for classification.
150  **********************************************************************/
151 void make_triple_split(TBLOB *blob, TBLOB *other_blob, bool italic_blob,
152  SEAM *seam) {
153  make_single_split(blob->outlines, seam->split1);
154  make_single_split(blob->outlines, seam->split2);
155  make_single_split(blob->outlines, seam->split3);
156 
157  form_two_blobs(blob, other_blob, italic_blob, seam->location);
158 }
159 
160 
161 /**********************************************************************
162  * undo_seam
163  *
164  * Remove the seam between these two blobs. Produce one blob as a
165  * result. The seam may consist of one, two, or three splits. Each
166  * of these split must be removed from the outlines.
167  **********************************************************************/
168 void undo_seam(TBLOB *blob, TBLOB *other_blob, SEAM *seam) {
169  TESSLINE *outline;
170 
171  if (!seam)
172  return; /* Append other blob outlines */
173  if (blob->outlines == NULL) {
174  blob->outlines = other_blob->outlines;
175  other_blob->outlines = NULL;
176  }
177 
178  outline = blob->outlines;
179  while (outline->next)
180  outline = outline->next;
181  outline->next = other_blob->outlines;
182  other_blob->outlines = NULL;
183  delete other_blob;
184 
185  if (seam->split1 == NULL) {
186  }
187  else if (seam->split2 == NULL) {
188  undo_single_split (blob, seam->split1);
189  }
190  else if (seam->split3 == NULL) {
191  undo_single_split (blob, seam->split1);
192  undo_single_split (blob, seam->split2);
193  }
194  else {
195  undo_single_split (blob, seam->split3);
196  undo_single_split (blob, seam->split2);
197  undo_single_split (blob, seam->split1);
198  }
199 
200  setup_blob_outlines(blob);
202 }
203 
204 
205 /**********************************************************************
206  * undo_single_split
207  *
208  * Undo a seam that is made by a single split. Perform the correct
209  * magic to reconstruct the appropriate set of outline data structures.
210  **********************************************************************/
211 void undo_single_split(TBLOB *blob, SPLIT *split) {
212  TESSLINE *outline1;
213  TESSLINE *outline2;
214  /* Modify edge points */
215  unsplit_outlines (split->point1, split->point2);
216 
217  outline1 = new TESSLINE;
218  outline1->next = blob->outlines;
219  blob->outlines = outline1;
220  outline1->loop = split->point1;
221 
222  outline2 = new TESSLINE;
223  outline2->next = blob->outlines;
224  blob->outlines = outline2;
225  outline2->loop = split->point2;
226 }