wordrec/seam.cpp File Reference

#include "seam.h"
#include "callcpp.h"
#include "structures.h"
#include "makechop.h"

Go to the source code of this file.

Defines

Functions


Define Documentation

#define NUM_STARTING_SEAMS   20

Note:
File: seam.cpp (Formerly seam.c)
Splitting seams
Author:
Mark Seaman, OCR Technology
Date:
Fri Oct 16 14:37:00 1987 Fri May 17 16:30:13 1991 (Mark Seaman) marks
 * (c) Copyright 1987, 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.

Definition at line 35 of file seam.cpp.

Referenced by new_seam_list().

#define SEAMBLOCK   100

Cells per block

Definition at line 38 of file seam.cpp.


Function Documentation

int account_splits_left ( SEAM seam,
TBLOB blob,
TBLOB end_blob 
)

Account for all the splits by looking to the LEFT in the blob list.

Definition at line 283 of file seam.cpp.

References account_splits_left(), find_split_in_blob(), blobstruct::next, NULL, seam_record::split1, seam_record::split2, and seam_record::split3.

Referenced by account_splits_left(), insert_seam(), and test_insert_seam().

00283                                                                   {
00284   static INT32 depth = 0;
00285   static INT8 width;
00286   static INT8 found_em[3];
00287 
00288   if (blob != end_blob) {
00289     depth++;
00290     account_splits_left (seam, blob->next, end_blob);
00291     depth--;
00292   }
00293   else {
00294     found_em[0] = seam->split1 == NULL;
00295     found_em[1] = seam->split2 == NULL;
00296     found_em[2] = seam->split3 == NULL;
00297     width = 0;
00298   }
00299   if (!found_em[0])
00300     found_em[0] = find_split_in_blob (seam->split1, blob);
00301   if (!found_em[1])
00302     found_em[1] = find_split_in_blob (seam->split2, blob);
00303   if (!found_em[2])
00304     found_em[2] = find_split_in_blob (seam->split3, blob);
00305   if (!found_em[0] || !found_em[1] || !found_em[2]) {
00306     width++;
00307     if (depth == 0) {
00308       width = -1;
00309     }
00310   }
00311   return width;
00312 }

int account_splits_right ( SEAM seam,
TBLOB blob 
)

Account for all the splits by looking to the RIGHT in the blob list.

Definition at line 250 of file seam.cpp.

References find_split_in_blob(), blobstruct::next, NULL, seam_record::split1, seam_record::split2, and seam_record::split3.

Referenced by insert_seam(), and test_insert_seam().

00250                                                   {
00251   INT8 found_em[3];
00252   INT8 width;
00253 
00254   found_em[0] = seam->split1 == NULL;
00255   found_em[1] = seam->split2 == NULL;
00256   found_em[2] = seam->split3 == NULL;
00257   if (found_em[0] && found_em[1] && found_em[2])
00258     return 0;
00259   width = 0;
00260   do {
00261     if (!found_em[0])
00262       found_em[0] = find_split_in_blob (seam->split1, blob);
00263     if (!found_em[1])
00264       found_em[1] = find_split_in_blob (seam->split2, blob);
00265     if (!found_em[2])
00266       found_em[2] = find_split_in_blob (seam->split3, blob);
00267     if (found_em[0] && found_em[1] && found_em[2]) {
00268       return width;
00269     }
00270     width++;
00271     blob = blob->next;
00272   }
00273   while (blob != NULL);
00274   return -1;
00275 }

SEAMS add_seam ( SEAMS  seam_list,
SEAM seam 
)

Add another seam to a collection of seams.

Definition at line 83 of file seam.cpp.

References array_push().

Referenced by start_seam_list().

00083                                             {
00084   return (array_push (seam_list, seam));
00085 }

void combine_seams ( SEAM dest_seam,
SEAM source_seam 
)

Combine two seam records into a single seam.

Move the split references from the second seam to the first one. The argument convention is patterned after strcpy.

Definition at line 95 of file seam.cpp.

References cprintf(), seam_record::location, seam_record::priority, seam_record::split1, seam_record::split2, and seam_record::split3.

Referenced by join_two_seams().

00095                                                        {
00096   dest_seam->priority += source_seam->priority;
00097   dest_seam->location += source_seam->location;
00098   dest_seam->location /= 2;
00099 
00100   if (source_seam->split1) {
00101     if (!dest_seam->split1)
00102       dest_seam->split1 = source_seam->split1;
00103     else if (!dest_seam->split2)
00104       dest_seam->split2 = source_seam->split1;
00105     else if (!dest_seam->split3)
00106       dest_seam->split3 = source_seam->split1;
00107     else
00108       cprintf ("combine_seam: Seam is too crowded, can't be combined !\n");
00109   }
00110   if (source_seam->split2) {
00111     if (!dest_seam->split2)
00112       dest_seam->split2 = source_seam->split2;
00113     else if (!dest_seam->split3)
00114       dest_seam->split3 = source_seam->split2;
00115     else
00116       cprintf ("combine_seam: Seam is too crowded, can't be combined !\n");
00117   }
00118   if (source_seam->split3) {
00119     if (!dest_seam->split3)
00120       dest_seam->split3 = source_seam->split3;
00121     else
00122       cprintf ("combine_seam: Seam is too crowded, can't be combined !\n");
00123   }
00124   free_seam(source_seam);
00125 }

void delete_seam ( void *  arg  ) 

Free this seam record and the splits that are attached to it.

Definition at line 132 of file seam.cpp.

References delete_split().

Referenced by attempt_blob_chop(), choose_best_seam(), delete_seam_pile(), free_seam_list(), junk_worst_seam(), and pick_good_seam().

00132                             {  //SEAM  *seam)
00133   SEAM *seam = (SEAM *) arg;
00134 
00135   if (seam) {
00136     if (seam->split1)
00137       delete_split (seam->split1);
00138     if (seam->split2)
00139       delete_split (seam->split2);
00140     if (seam->split3)
00141       delete_split (seam->split3);
00142     free_seam(seam);
00143   }
00144 }

bool find_split_in_blob ( SPLIT split,
TBLOB blob 
)

Return TRUE if the split is somewhere in this blob.

Definition at line 319 of file seam.cpp.

References FALSE, is_split_outline, olinestruct::next, NULL, blobstruct::outlines, split_record::point1, split_record::point2, point_in_outline, and TRUE.

Referenced by account_splits_left(), and account_splits_right().

00319                                                    {
00320   TESSLINE *outline;
00321 
00322 #if 0
00323   for (outline = blob->outlines; outline != NULL; outline = outline->next)
00324     if (is_split_outline (outline, split))
00325       return TRUE;
00326   return FALSE;
00327 #endif
00328   for (outline = blob->outlines; outline != NULL; outline = outline->next)
00329     if (point_in_outline(split->point1, outline))
00330       break;
00331   if (outline == NULL)
00332     return FALSE;
00333   for (outline = blob->outlines; outline != NULL; outline = outline->next)
00334     if (point_in_outline(split->point2, outline))
00335       return TRUE;
00336   return FALSE;
00337 }

void free_seam_list ( SEAMS  seam_list  ) 

Free all the seams that have been allocated in this list.

Reclaim the memory for each of the splits as well.

Definition at line 153 of file seam.cpp.

References array_free, array_loop, array_value, and delete_seam().

Referenced by chop_word_main().

00153                                      {
00154   int x;
00155 
00156   array_loop (seam_list, x) delete_seam (array_value (seam_list, x));
00157   array_free(seam_list);
00158 }

SEAMS insert_seam ( SEAMS  seam_list,
int  index,
SEAM seam,
TBLOB left_blob,
TBLOB first_blob 
)

Add seam.

Add another seam to a collection of seams at a particular location in the seam array.

Definition at line 200 of file seam.cpp.

References account_splits_left(), account_splits_right(), array_count, array_insert(), array_value, cprintf(), blobstruct::next, print_seam(), seam_record::widthn, and seam_record::widthp.

Referenced by improve_one_blob().

00204                                      {
00205   SEAM *test_seam;
00206   TBLOB *blob;
00207   int test_index;
00208   int list_length;
00209 
00210   list_length = array_count (seam_list);
00211   for (test_index = 0, blob = first_blob->next;
00212   test_index < index; test_index++, blob = blob->next) {
00213     test_seam = (SEAM *) array_value (seam_list, test_index);
00214     if (test_index + test_seam->widthp >= index) {
00215       test_seam->widthp++;       /*got in the way */
00216     }
00217     else if (test_seam->widthp + test_index == index - 1) {
00218       test_seam->widthp = account_splits_right(test_seam, blob);
00219       if (test_seam->widthp < 0) {
00220         cprintf ("Failed to find any right blob for a split!\n");
00221         print_seam("New dud seam", seam);
00222         print_seam("Failed seam", test_seam);
00223       }
00224     }
00225   }
00226   for (test_index = index, blob = left_blob->next;
00227   test_index < list_length; test_index++, blob = blob->next) {
00228     test_seam = (SEAM *) array_value (seam_list, test_index);
00229     if (test_index - test_seam->widthn < index) {
00230       test_seam->widthn++;       /*got in the way */
00231     }
00232     else if (test_index - test_seam->widthn == index) {
00233       test_seam->widthn = account_splits_left(test_seam, first_blob, blob);
00234       if (test_seam->widthn < 0) {
00235         cprintf ("Failed to find any left blob for a split!\n");
00236         print_seam("New dud seam", seam);
00237         print_seam("Failed seam", test_seam);
00238       }
00239     }
00240   }
00241   return (array_insert (seam_list, index, seam));
00242 }

SEAM* join_two_seams ( SEAM seam1,
SEAM seam2 
)

Merge these two seams into a new seam.

Duplicate the split records in both of the input seams. Return the resultant seam.

Definition at line 347 of file seam.cpp.

References assert(), clone_seam, combine_seams(), NULL, shared_split_points(), seam_record::split1, seam_record::split2, and seam_record::split3.

Referenced by combine_seam().

00347                                                { 
00348   SEAM *result = NULL;
00349   SEAM *temp;
00350 
00351   assert(seam1 &&seam2);
00352 
00353   if ((seam1->split3 == NULL && seam2->split2 == NULL ||
00354     seam1->split2 == NULL && seam2->split3 == NULL ||
00355     seam1->split1 == NULL ||
00356   seam2->split1 == NULL) && (!shared_split_points (seam1, seam2))) {
00357     clone_seam(result, seam1);
00358     clone_seam(temp, seam2);
00359     combine_seams(result, temp);
00360   }
00361   return (result);
00362 }

SEAM* new_seam ( PRIORITY  priority,
int  x_location,
SPLIT split1,
SPLIT split2,
SPLIT split3 
)

Create a structure for a "seam" between two blobs.

This data structure may actually hold up to three different splits. Initailization of this record is done by this routine.

Definition at line 372 of file seam.cpp.

References seam_record::location, newseam(), seam_record::priority, seam_record::split1, seam_record::split2, seam_record::split3, seam_record::widthn, and seam_record::widthp.

Referenced by choose_best_seam(), junk_worst_seam(), and start_seam_list().

00376                               {
00377   SEAM *seam;
00378 
00379   seam = newseam ();
00380 
00381   seam->priority = priority;
00382   seam->location = x_location;
00383   seam->widthp = 0;
00384   seam->widthn = 0;
00385   seam->split1 = split1;
00386   seam->split2 = split2;
00387   seam->split3 = split3;
00388 
00389   return (seam);
00390 }

SEAMS new_seam_list (  ) 

Create a collection of seam records in an array.

Definition at line 397 of file seam.cpp.

References array_new(), and NUM_STARTING_SEAMS.

Referenced by start_seam_list().

00397                       {
00398   return (array_new (NUM_STARTING_SEAMS));
00399 }

bool point_in_seam ( SEAM seam,
SPLIT split 
)

Check to see if either of these points are present in the current seam.

Return TRUE if one of them is.

Definition at line 72 of file seam.cpp.

References split_record::point1, split_record::point2, point_in_split(), seam_record::split1, seam_record::split2, and seam_record::split3.

Referenced by shared_split_points().

00072                                              { 
00073   return (point_in_split (seam->split1, split->point1, split->point2) ||
00074     point_in_split (seam->split2, split->point1, split->point2) ||
00075     point_in_split (seam->split3, split->point1, split->point2));
00076 }

bool point_in_split ( SPLIT split,
EDGEPT point1,
EDGEPT point2 
)

Check to see if either of these points are present in the current split.

Return TRUE if one of them is.

Definition at line 56 of file seam.cpp.

References exact_point, FALSE, split_record::point1, split_record::point2, and TRUE.

Referenced by point_in_seam().

00056                                                                   { 
00057   return ((split) ?
00058     ((exact_point (split->point1, point1) ||
00059     exact_point (split->point1, point2) ||
00060     exact_point (split->point2, point1) ||
00061     exact_point (split->point2, point2)) ? TRUE : FALSE) : FALSE);
00062 }

void print_seam ( const char *  label,
SEAM seam 
)

Print a list of splits.

Show the coordinates of both points in each split.

Definition at line 408 of file seam.cpp.

References cprintf(), seam_record::location, print_split(), seam_record::priority, seam_record::split1, seam_record::split2, seam_record::split3, seam_record::widthn, and seam_record::widthp.

Referenced by attempt_blob_chop(), choose_best_seam(), combine_seam(), insert_seam(), and print_seams().

00408                                                {
00409   if (seam) {
00410     cprintf(label);
00411     cprintf (" %6.2f @ %5d, p=%d, n=%d ",
00412       seam->priority, seam->location, seam->widthp, seam->widthn);
00413 
00414     print_split (seam->split1);
00415 
00416     if (seam->split2) {
00417       cprintf (",   ");
00418       print_split (seam->split2);
00419 
00420       if (seam->split3) {
00421         cprintf (",   ");
00422         print_split (seam->split3);
00423       }
00424     }
00425     cprintf ("\n");
00426   }
00427 }

void print_seams ( const char *  label,
SEAMS  seams 
)

Print a list of splits.

Show the coordinates of both points in each split.

Definition at line 436 of file seam.cpp.

References array_loop, array_value, CHARS_PER_LINE, cprintf(), and print_seam().

Referenced by chop_word_main().

00436                                                  {
00437   int x;
00438   char number[CHARS_PER_LINE];
00439 
00440   if (seams) {
00441     cprintf ("%s\n", label);
00442     array_loop(seams, x) {
00443       sprintf (number, "%2d:   ", x);
00444       print_seam (number, (SEAM *) array_value (seams, x));
00445     }
00446     cprintf ("\n");
00447   }
00448 }

int shared_split_points ( SEAM seam1,
SEAM seam2 
)

Check these two seams to make sure that neither of them have two points in common.

Return TRUE if any of the same points are present in any of the splits of both seams.

Definition at line 459 of file seam.cpp.

References FALSE, NULL, point_in_seam(), seam_record::split1, seam_record::split2, seam_record::split3, and TRUE.

Referenced by any_shared_split_points(), and join_two_seams().

00459                                                   {
00460   if (seam1 == NULL || seam2 == NULL)
00461     return (FALSE);
00462 
00463   if (seam2->split1 == NULL)
00464     return (FALSE);
00465   if (point_in_seam (seam1, seam2->split1))
00466     return (TRUE);
00467 
00468   if (seam2->split2 == NULL)
00469     return (FALSE);
00470   if (point_in_seam (seam1, seam2->split2))
00471     return (TRUE);
00472 
00473   if (seam2->split3 == NULL)
00474     return (FALSE);
00475   if (point_in_seam (seam1, seam2->split3))
00476     return (TRUE);
00477 
00478   return (FALSE);
00479 }

bool test_insert_seam ( SEAMS  seam_list,
int  index,
TBLOB left_blob,
TBLOB first_blob 
)

Return true if insert_seam will succeed.

Definition at line 165 of file seam.cpp.

References account_splits_left(), account_splits_right(), array_count, array_value, blobstruct::next, seam_record::widthn, and seam_record::widthp.

Referenced by attempt_blob_chop().

00168                                          {
00169   SEAM *test_seam;
00170   TBLOB *blob;
00171   int test_index;
00172   int list_length;
00173 
00174   list_length = array_count (seam_list);
00175   for (test_index = 0, blob = first_blob->next;
00176   test_index < index; test_index++, blob = blob->next) {
00177     test_seam = (SEAM *) array_value (seam_list, test_index);
00178     if (test_index + test_seam->widthp < index &&
00179         test_seam->widthp + test_index == index - 1 &&
00180         account_splits_right(test_seam, blob) < 0)
00181       return false;
00182   }
00183   for (test_index = index, blob = left_blob->next;
00184   test_index < list_length; test_index++, blob = blob->next) {
00185     test_seam = (SEAM *) array_value (seam_list, test_index);
00186     if (test_index - test_seam->widthn >= index &&
00187         test_index - test_seam->widthn == index &&
00188         account_splits_left(test_seam, first_blob, blob) < 0)
00189       return false;
00190   }
00191   return true;
00192 }


Generated on Wed Feb 28 19:49:29 2007 for Tesseract by  doxygen 1.5.1