#include "split.h"
#include "tessarray.h"
Go to the source code of this file.
#define clone_seam | ( | dest, | |||
source | ) |
Value:
if (source) { \ (dest) = newseam (); \ (dest)->location = (source)->location; \ (dest)->widthp = (source)->widthp; \ (dest)->widthn = (source)->widthn; \ (dest)->priority = (source)->priority; \ clone_split ((dest)->split1, (source)->split1); \ clone_split ((dest)->split2, (source)->split2); \ clone_split ((dest)->split3, (source)->split3); \ } \ else { \ (dest) = (SEAM*) NULL; \ } \
Definition at line 72 of file seam.h.
Referenced by choose_best_seam(), and join_two_seams().
#define exact_point | ( | p1, | |||
p2 | ) | (! ((p1->pos.x - p2->pos.x) || (p1->pos.y - p2->pos.y))) |
Return TRUE if the point positions are the exactly the same.
The parameters must be of type (EDGEPT*).
Definition at line 94 of file seam.h.
Referenced by hide_edge_pair(), point_in_split(), and reveal_edge_pair().
Type of seam_record, info on one seam.
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 }
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 }
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 }
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 }
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 }
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 }
SEAM* newseam | ( | ) |
Referenced by new_seam().
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 }
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 }
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 }
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 }