Tesseract  3.02
tesseract-ocr/wordrec/makechop.cpp
Go to the documentation of this file.
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 }