46 #include "config_auto.h"
51 static const int kMaxNumChunks = 64;
62 static int check_blob(
TBLOB *blob) {
66 for (outline = blob->
outlines; outline !=
nullptr; outline = outline->
next) {
67 edgept = outline->
loop;
69 if (edgept ==
nullptr)
71 edgept = edgept->
next;
73 while (edgept != outline->
loop);
74 if (edgept ==
nullptr)
89 length = seams.
size();
90 for (index = 0; index < length; index++)
100 static void preserve_outline(
EDGEPT *start) {
103 if (start ==
nullptr)
110 while (srcpt != start);
114 static void preserve_outline_tree(
TESSLINE *srcline) {
117 for (outline = srcline; outline !=
nullptr; outline = outline->
next) {
118 preserve_outline (outline->
loop);
131 if (start ==
nullptr)
135 if (srcpt->
flags[1] == 2)
139 while (srcpt != start);
147 while (srcpt != real_start);
151 static void restore_outline_tree(
TESSLINE *srcline) {
154 for (outline = srcline; outline !=
nullptr; outline = outline->
next) {
155 outline->
loop = restore_outline (outline->
loop);
166 static int16_t total_containment(
TBLOB *blob1,
TBLOB *blob2) {
174 static SEAM* CheckSeam(
int debug_level, int32_t blob_number,
TWERD* word,
177 if (seam ==
nullptr || blob->
outlines ==
nullptr || other_blob->
outlines ==
nullptr ||
178 total_containment(blob, other_blob) || check_blob(other_blob) ||
180 any_shared_split_points(seams, seam) ||
187 #ifndef GRAPHICS_DISABLED
191 tprintf(
"\n** seam being removed ** \n");
214 preserve_outline_tree (blob->
outlines);
219 SEAM *seam =
nullptr;
223 seam =
new SEAM(0.0f, location);
230 seam->
Print(
"Good seam picked=");
232 tprintf(
"\n** no seam picked *** \n");
235 seam->
ApplySeam(italic_blob, blob, other_blob);
238 seam = CheckSeam(
chop_debug, blob_number, word, blob, other_blob,
240 if (seam ==
nullptr) {
242 restore_outline_tree(blob->
outlines);
249 seam =
new SEAM(0.0f, location);
250 seam->
ApplySeam(italic_blob, blob, other_blob);
251 seam = CheckSeam(
chop_debug, blob_number, word, blob, other_blob,
256 if (seam !=
nullptr) {
273 bool italic_blob,
WERD_RES *word_res,
276 for (*blob_number = 0; *blob_number < word->
NumBlobs(); ++*blob_number) {
284 TPOINT original_topleft, original_botright;
288 TBOX original_box =
TBOX(original_topleft.
x, original_botright.
y,
289 original_botright.
x, original_topleft.
y);
291 bool almost_equal_box =
false;
293 for (
int i = 0; i < boxes.
size(); i++) {
297 almost_equal_box =
true;
302 (!almost_equal_box && num_overlap > 1)) {
328 bool split_next_to_fragment,
332 float rating_ceiling = FLT_MAX;
333 SEAM *seam =
nullptr;
337 bool split_point_from_dict = (*blob_number != -1);
338 if (split_point_from_dict) {
342 split_next_to_fragment);
345 if (*blob_number == -1)
353 if (blob_choices[*blob_number] ==
nullptr)
355 if (!split_point_from_dict) {
357 rating_ceiling = blob_choices[*blob_number]->rating();
392 if (word->
ratings ==
nullptr) {
397 for (
int b = 0; b < num_blobs; ++b) {
408 BLOB_CHOICE_LIST* choices = word->
ratings->
get(col, row);
409 if (choices !=
nullptr) {
410 BLOB_CHOICE_IT bc_it(choices);
411 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
412 bc_it.data()->set_matrix_cell(col, row);
435 if (word->
blamer_bundle !=
nullptr && this->fill_lattice_ !=
nullptr) {
440 tprintf(
"Final Ratings Matrix:\n");
455 BestChoiceBundle* best_choice_bundle,
457 LMPainPoints* pain_points,
465 for (
int i = 0; i < num_blobs; ++i) {
466 BLOB_CHOICE_LIST* choices = word->
ratings->
get(i, i);
467 if (choices ==
nullptr || choices->empty()) {
470 BLOB_CHOICE_IT bc_it(choices);
475 false,
false, word, &blob_number);
476 if (seam ==
nullptr)
break;
484 best_choice_bundle->beam.insert(
new LanguageModelState, blob_number);
486 best_choice_bundle->fixpt.clear();
488 pain_points->RemapForSplit(blob_number);
490 pending->
insert(SegSearchPending(), blob_number);
496 pain_points, blamer_bundle);
497 pain_point.col = blob_number + 1;
498 pain_point.row = blob_number + 1;
500 pain_points, blamer_bundle);
509 word, pain_points, best_choice_bundle, blamer_bundle);
521 bool valid_permuter = word->
best_choice !=
nullptr &&
539 float rating_ceiling,
bool split_next_to_fragment) {
542 float worst = -FLT_MAX;
543 int worst_index = -1;
544 float worst_near_fragment = -FLT_MAX;
545 int worst_index_near_fragment = -1;
549 if (rating_ceiling < FLT_MAX)
550 tprintf(
"rating_ceiling = %8.4f\n", rating_ceiling);
552 tprintf(
"rating_ceiling = No Limit\n");
555 if (split_next_to_fragment && blob_choices.
size() > 0) {
557 if (blob_choices[0] !=
nullptr) {
559 blob_choices[0]->unichar_id());
561 fragments[0] =
nullptr;
565 for (x = 0; x < blob_choices.
size(); ++x) {
566 if (blob_choices[x] ==
nullptr) {
570 blob_choice = blob_choices[x];
572 if (split_next_to_fragment && x+1 < blob_choices.
size()) {
573 if (blob_choices[x + 1] !=
nullptr) {
575 blob_choices[x + 1]->unichar_id());
577 fragments[x + 1] =
nullptr;
580 if (blob_choice->
rating() < rating_ceiling &&
583 if (blob_choice->
rating() > worst) {
585 worst = blob_choice->
rating();
587 if (split_next_to_fragment) {
589 bool expand_following_fragment =
590 (x + 1 < blob_choices.
size() &&
591 fragments[x+1] !=
nullptr && !fragments[x+1]->
is_beginning());
592 bool expand_preceding_fragment =
593 (x > 0 && fragments[x-1] !=
nullptr && !fragments[x-1]->
is_ending());
594 if ((expand_following_fragment || expand_preceding_fragment) &&
595 blob_choice->
rating() > worst_near_fragment) {
596 worst_index_near_fragment = x;
597 worst_near_fragment = blob_choice->
rating();
599 tprintf(
"worst_index_near_fragment=%d"
600 " expand_following_fragment=%d"
601 " expand_preceding_fragment=%d\n",
602 worst_index_near_fragment,
603 expand_following_fragment,
604 expand_preceding_fragment);
614 return worst_index_near_fragment != -1 ?
615 worst_index_near_fragment : worst_index;
628 for (
int i = 0; i < fixpt->
size(); i++) {
629 if ((*fixpt)[i].begin + 1 == (*fixpt)[i].end &&
630 (*fixpt)[i].dangerous &&
631 (*fixpt)[i].correct_is_ngram) {
632 return (*fixpt)[i].begin;