Tesseract
3.02
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: makechop.c (Formerly makechop.c) 00005 * Description: 00006 * Author: Mark Seaman, OCR Technology 00007 * Created: Fri Oct 16 14:37:00 1987 00008 * Modified: Mon Jul 29 15:50:42 1991 (Mark Seaman) marks@hpgrlt 00009 * Language: C 00010 * Package: N/A 00011 * Status: Reusable Software Component 00012 * 00013 * (c) Copyright 1987, Hewlett-Packard Company. 00014 ** Licensed under the Apache License, Version 2.0 (the "License"); 00015 ** you may not use this file except in compliance with the License. 00016 ** You may obtain a copy of the License at 00017 ** http://www.apache.org/licenses/LICENSE-2.0 00018 ** Unless required by applicable law or agreed to in writing, software 00019 ** distributed under the License is distributed on an "AS IS" BASIS, 00020 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 ** See the License for the specific language governing permissions and 00022 ** limitations under the License. 00023 * 00024 *********************************************************************************/ 00025 /*---------------------------------------------------------------------- 00026 I n c l u d e s 00027 ----------------------------------------------------------------------*/ 00028 00029 #include "makechop.h" 00030 #include "blobs.h" 00031 #include "render.h" 00032 #include "structures.h" 00033 #ifdef __UNIX__ 00034 #include <assert.h> 00035 #include <unistd.h> 00036 #endif 00037 00038 // Include automatically generated configuration file if running autoconf. 00039 #ifdef HAVE_CONFIG_H 00040 #include "config_auto.h" 00041 #endif 00042 00043 /*---------------------------------------------------------------------- 00044 Public Function Code 00045 ----------------------------------------------------------------------*/ 00046 /********************************************************************** 00047 * apply_seam 00048 * 00049 * Split this blob into two blobs by applying the splits included in 00050 * the seam description. 00051 **********************************************************************/ 00052 void apply_seam(TBLOB *blob, TBLOB *other_blob, bool italic_blob, SEAM *seam) { 00053 if (seam->split1 == NULL) { 00054 divide_blobs(blob, other_blob, italic_blob, seam->location); 00055 } 00056 else if (seam->split2 == NULL) { 00057 make_split_blobs(blob, other_blob, italic_blob, seam); 00058 } 00059 else if (seam->split3 == NULL) { 00060 make_double_split(blob, other_blob, italic_blob, seam); 00061 } 00062 else { 00063 make_triple_split(blob, other_blob, italic_blob, seam); 00064 } 00065 } 00066 00067 00068 /********************************************************************** 00069 * form_two_blobs 00070 * 00071 * Group the outlines from the first blob into both of them. Do so 00072 * according to the information about the split. 00073 **********************************************************************/ 00074 void form_two_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob, 00075 const TPOINT& location) { 00076 setup_blob_outlines(blob); 00077 00078 divide_blobs(blob, other_blob, italic_blob, location); 00079 00080 eliminate_duplicate_outlines(blob); 00081 eliminate_duplicate_outlines(other_blob); 00082 00083 correct_blob_order(blob, other_blob); 00084 } 00085 00086 00087 /********************************************************************** 00088 * make_double_split 00089 * 00090 * Create two blobs out of one by splitting the original one in half. 00091 * Return the resultant blobs for classification. 00092 **********************************************************************/ 00093 void make_double_split(TBLOB *blob, TBLOB *other_blob, bool italic_blob, 00094 SEAM *seam) { 00095 make_single_split(blob->outlines, seam->split1); 00096 make_single_split(blob->outlines, seam->split2); 00097 form_two_blobs(blob, other_blob, italic_blob, seam->location); 00098 } 00099 00100 00101 /********************************************************************** 00102 * make_single_split 00103 * 00104 * Create two outlines out of one by splitting the original one in half. 00105 * Return the resultant outlines. 00106 **********************************************************************/ 00107 void make_single_split(TESSLINE *outlines, SPLIT *split) { 00108 assert (outlines != NULL); 00109 00110 split_outline (split->point1, split->point2); 00111 00112 while (outlines->next != NULL) 00113 outlines = outlines->next; 00114 00115 outlines->next = new TESSLINE; 00116 outlines->next->loop = split->point1; 00117 outlines->next->ComputeBoundingBox(); 00118 00119 outlines = outlines->next; 00120 00121 outlines->next = new TESSLINE; 00122 outlines->next->loop = split->point2; 00123 outlines->next->ComputeBoundingBox(); 00124 00125 outlines->next->next = NULL; 00126 } 00127 00128 00129 /********************************************************************** 00130 * make_split_blobs 00131 * 00132 * Create two blobs out of one by splitting the original one in half. 00133 * Return the resultant blobs for classification. 00134 **********************************************************************/ 00135 void make_split_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob, 00136 SEAM *seam) { 00137 make_single_split(blob->outlines, seam->split1); 00138 00139 form_two_blobs (blob, other_blob, italic_blob, seam->location); 00140 } 00141 00142 00143 /********************************************************************** 00144 * make_triple_split 00145 * 00146 * Create two blobs out of one by splitting the original one in half. 00147 * This splitting is accomplished by applying three separate splits on 00148 * the outlines. Three of the starting outlines will produce two ending 00149 * outlines. Return the resultant blobs for classification. 00150 **********************************************************************/ 00151 void make_triple_split(TBLOB *blob, TBLOB *other_blob, bool italic_blob, 00152 SEAM *seam) { 00153 make_single_split(blob->outlines, seam->split1); 00154 make_single_split(blob->outlines, seam->split2); 00155 make_single_split(blob->outlines, seam->split3); 00156 00157 form_two_blobs(blob, other_blob, italic_blob, seam->location); 00158 } 00159 00160 00161 /********************************************************************** 00162 * undo_seam 00163 * 00164 * Remove the seam between these two blobs. Produce one blob as a 00165 * result. The seam may consist of one, two, or three splits. Each 00166 * of these split must be removed from the outlines. 00167 **********************************************************************/ 00168 void undo_seam(TBLOB *blob, TBLOB *other_blob, SEAM *seam) { 00169 TESSLINE *outline; 00170 00171 if (!seam) 00172 return; /* Append other blob outlines */ 00173 if (blob->outlines == NULL) { 00174 blob->outlines = other_blob->outlines; 00175 other_blob->outlines = NULL; 00176 } 00177 00178 outline = blob->outlines; 00179 while (outline->next) 00180 outline = outline->next; 00181 outline->next = other_blob->outlines; 00182 other_blob->outlines = NULL; 00183 delete other_blob; 00184 00185 if (seam->split1 == NULL) { 00186 } 00187 else if (seam->split2 == NULL) { 00188 undo_single_split (blob, seam->split1); 00189 } 00190 else if (seam->split3 == NULL) { 00191 undo_single_split (blob, seam->split1); 00192 undo_single_split (blob, seam->split2); 00193 } 00194 else { 00195 undo_single_split (blob, seam->split3); 00196 undo_single_split (blob, seam->split2); 00197 undo_single_split (blob, seam->split1); 00198 } 00199 00200 setup_blob_outlines(blob); 00201 eliminate_duplicate_outlines(blob); 00202 } 00203 00204 00205 /********************************************************************** 00206 * undo_single_split 00207 * 00208 * Undo a seam that is made by a single split. Perform the correct 00209 * magic to reconstruct the appropriate set of outline data structures. 00210 **********************************************************************/ 00211 void undo_single_split(TBLOB *blob, SPLIT *split) { 00212 TESSLINE *outline1; 00213 TESSLINE *outline2; 00214 /* Modify edge points */ 00215 unsplit_outlines (split->point1, split->point2); 00216 00217 outline1 = new TESSLINE; 00218 outline1->next = blob->outlines; 00219 blob->outlines = outline1; 00220 outline1->loop = split->point1; 00221 00222 outline2 = new TESSLINE; 00223 outline2->next = blob->outlines; 00224 blob->outlines = outline2; 00225 outline2->loop = split->point2; 00226 }