57 #include "config_auto.h" 62 static const int kMaxNumChunks = 64;
82 while (srcpt != start);
91 for (outline = srcline; outline !=
nullptr; outline = outline->
next) {
106 if (start ==
nullptr)
110 if (srcpt->
flags[1] == 2)
114 while (srcpt != start);
122 while (srcpt != real_start);
131 for (outline = srcline; outline !=
nullptr; outline = outline->
next) {
139 static SEAM* CheckSeam(
int debug_level, int32_t blob_number,
TWERD* word,
142 if (seam ==
nullptr || blob->
outlines ==
nullptr || other_blob->
outlines ==
nullptr ||
152 #ifndef GRAPHICS_DISABLED 156 tprintf(
"\n** seam being removed ** \n");
184 SEAM *seam =
nullptr;
188 seam =
new SEAM(0.0f, location);
195 seam->
Print(
"Good seam picked=");
197 tprintf(
"\n** no seam picked *** \n");
200 seam->
ApplySeam(italic_blob, blob, other_blob);
203 seam = CheckSeam(
chop_debug, blob_number, word, blob, other_blob,
205 if (seam ==
nullptr) {
214 seam =
new SEAM(0.0f, location);
215 seam->
ApplySeam(italic_blob, blob, other_blob);
216 seam = CheckSeam(
chop_debug, blob_number, word, blob, other_blob,
221 if (seam !=
nullptr) {
238 bool italic_blob,
WERD_RES *word_res,
241 for (*blob_number = 0; *blob_number < word->
NumBlobs(); ++*blob_number) {
249 TPOINT original_topleft, original_botright;
253 TBOX original_box =
TBOX(original_topleft.
x, original_botright.
y,
254 original_botright.
x, original_topleft.
y);
256 bool almost_equal_box =
false;
258 for (
int i = 0; i < boxes.
size(); i++) {
262 almost_equal_box =
true;
267 (!almost_equal_box && num_overlap > 1)) {
291 length = seams.
size();
292 for (index = 0; index < length; index++)
307 for (outline = blob->
outlines; outline !=
nullptr; outline = outline->
next) {
308 edgept = outline->
loop;
310 if (edgept ==
nullptr)
312 edgept = edgept->
next;
314 while (edgept != outline->
loop);
315 if (edgept ==
nullptr)
337 bool split_next_to_fragment,
341 float rating_ceiling = FLT_MAX;
342 SEAM *seam =
nullptr;
346 bool split_point_from_dict = (*blob_number != -1);
347 if (split_point_from_dict) {
351 split_next_to_fragment);
354 if (*blob_number == -1)
362 if (blob_choices[*blob_number] ==
nullptr)
364 if (!split_point_from_dict) {
366 rating_ceiling = blob_choices[*blob_number]->rating();
401 if (word->
ratings ==
nullptr) {
406 for (
int b = 0; b < num_blobs; ++b) {
417 BLOB_CHOICE_LIST* choices = word->
ratings->
get(col, row);
418 if (choices !=
nullptr) {
419 BLOB_CHOICE_IT bc_it(choices);
420 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
421 bc_it.data()->set_matrix_cell(col, row);
444 if (word->
blamer_bundle !=
nullptr && this->fill_lattice_ !=
nullptr) {
449 tprintf(
"Final Ratings Matrix:\n");
474 for (
int i = 0; i < num_blobs; ++i) {
475 BLOB_CHOICE_LIST* choices = word->
ratings->
get(i, i);
476 if (choices ==
nullptr || choices->empty()) {
479 BLOB_CHOICE_IT bc_it(choices);
484 false,
false, word, &blob_number);
485 if (seam ==
nullptr)
break;
505 pain_points, blamer_bundle);
506 pain_point.
col = blob_number + 1;
507 pain_point.
row = blob_number + 1;
509 pain_points, blamer_bundle);
518 word, pain_points, best_choice_bundle, blamer_bundle);
530 bool valid_permuter = word->
best_choice !=
nullptr &&
548 float rating_ceiling,
bool split_next_to_fragment) {
551 float worst = -FLT_MAX;
552 int worst_index = -1;
553 float worst_near_fragment = -FLT_MAX;
554 int worst_index_near_fragment = -1;
558 if (rating_ceiling < FLT_MAX)
559 tprintf(
"rating_ceiling = %8.4f\n", rating_ceiling);
561 tprintf(
"rating_ceiling = No Limit\n");
564 if (split_next_to_fragment && blob_choices.
size() > 0) {
566 if (blob_choices[0] !=
nullptr) {
568 blob_choices[0]->unichar_id());
570 fragments[0] =
nullptr;
574 for (x = 0; x < blob_choices.
size(); ++x) {
575 if (blob_choices[x] ==
nullptr) {
579 blob_choice = blob_choices[x];
581 if (split_next_to_fragment && x+1 < blob_choices.
size()) {
582 if (blob_choices[x + 1] !=
nullptr) {
584 blob_choices[x + 1]->unichar_id());
586 fragments[x + 1] =
nullptr;
589 if (blob_choice->
rating() < rating_ceiling &&
592 if (blob_choice->
rating() > worst) {
594 worst = blob_choice->
rating();
596 if (split_next_to_fragment) {
598 bool expand_following_fragment =
599 (x + 1 < blob_choices.
size() &&
600 fragments[x+1] !=
nullptr && !fragments[x+1]->
is_beginning());
601 bool expand_preceding_fragment =
602 (x > 0 && fragments[x-1] !=
nullptr && !fragments[x-1]->
is_ending());
603 if ((expand_following_fragment || expand_preceding_fragment) &&
604 blob_choice->
rating() > worst_near_fragment) {
605 worst_index_near_fragment = x;
606 worst_near_fragment = blob_choice->
rating();
608 tprintf(
"worst_index_near_fragment=%d" 609 " expand_following_fragment=%d" 610 " expand_preceding_fragment=%d\n",
611 worst_index_near_fragment,
612 expand_following_fragment,
613 expand_preceding_fragment);
623 return worst_index_near_fragment != -1 ?
624 worst_index_near_fragment : worst_index;
637 for (
int i = 0; i < fixpt->
size(); i++) {
638 if ((*fixpt)[i].begin + 1 == (*fixpt)[i].end &&
639 (*fixpt)[i].dangerous &&
640 (*fixpt)[i].correct_is_ngram) {
641 return (*fixpt)[i].begin;
int repair_unchopped_blobs
void print(const UNICHARSET &unicharset) const
bool is_beginning() const
WERD_CHOICE_LIST best_choices
void FakeWordFromRatings(PermuterType permuter)
int check_blob(TBLOB *blob)
void ProcessSegSearchPainPoint(float pain_point_priority, const MATRIX_COORD &pain_point, const char *pain_point_type, GenericVector< SegSearchPending > *pending, WERD_RES *word_res, LMPainPoints *pain_points, BlamerBundle *blamer_bundle)
bool almost_equal(const TBOX &box, int tolerance) const
int wordrec_max_join_chunks
void reset_hyphen_vars(bool last_word_on_line)
void InsertSeam(int blob_number, SEAM *seam)
void ApplySeam(bool italic_blob, TBLOB *blob, TBLOB *other_blob) const
SEAM * pick_good_seam(TBLOB *blob)
void CallFillLattice(const MATRIX &ratings, const WERD_CHOICE_LIST &best_choices, const UNICHARSET &unicharset, BlamerBundle *blamer_bundle)
Struct to store information maintained by various language model components.
void RemapForSplit(int index)
void remove_edgept(EDGEPT *point)
SEAM * improve_one_blob(const GenericVector< BLOB_CHOICE *> &blob_choices, DANGERR *fixpt, bool split_next_to_fragment, bool italic_blob, WERD_RES *word, int *blob_number)
int any_shared_split_points(const GenericVector< SEAM *> &seams, SEAM *seam)
void preserve_outline(EDGEPT *start)
bool divisible_blob(TBLOB *blob, bool italic_blob, TPOINT *location)
void ResetNGramSearch(WERD_RES *word_res, BestChoiceBundle *best_choice_bundle, GenericVector< SegSearchPending > *pending)
bool ChoiceIsCorrect(const WERD_CHOICE *word_choice) const
double overlap_fraction(const TBOX &box) const
bool PrepareToInsertSeam(const GenericVector< SEAM *> &seams, const GenericVector< TBLOB *> &blobs, int insert_index, bool modify)
PointerVector< LanguageModelState > beam
void Print(const char *label) const
void FilterWordChoices(int debug_level)
std::unique_ptr< LanguageModel > language_model_
void BlameClassifierOrLangModel(const WERD_RES *word, const UNICHARSET &unicharset, bool valid_permuter, bool debug)
bool flag(WERD_FLAGS mask) const
void insert(const T &t, int index)
void DenormTransform(const DENORM *last_denorm, const TPOINT &pt, TPOINT *original) const
int select_blob_to_split_from_fixpt(DANGERR *fixpt)
void chop_word_main(WERD_RES *word)
IncorrectResultReason incorrect_result_reason() const
bool SharesPosition(const SEAM &other) const
DLLSYM void tprintf(const char *format,...)
void display_blob(TBLOB *blob, C_COL color)
TBOX bounding_box() const
void preserve_outline_tree(TESSLINE *srcline)
void put(ICOORD pos, const T &thing)
DANGERR fixpt
Places to try to fix the word suggested by ambiguity checking.
void UpdateSegSearchNodes(float rating_cert_scale, int starting_col, GenericVector< SegSearchPending > *pending, WERD_RES *word_res, LMPainPoints *pain_points, BestChoiceBundle *best_choice_bundle, BlamerBundle *blamer_bundle)
GenericVector< SEAM * > seam_array
Bundle together all the things pertaining to the best choice/state.
double tessedit_certainty_threshold
GenericVector< TBLOB * > blobs
EDGEPT * restore_outline(EDGEPT *start)
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const
static TBLOB * ShallowCopy(const TBLOB &src)
bool contains(const FCOORD pt) const
const UNICHARSET * uch_set
SEAM * chop_overlapping_blob(const GenericVector< TBOX > &boxes, bool italic_blob, WERD_RES *word_res, int *blob_number)
BlamerBundle * blamer_bundle
void restore_outline_tree(TESSLINE *srcline)
const UNICHARSET & getUnicharset() const
bool ContainedByBlob(const TBLOB &blob) const
int select_blob_to_split(const GenericVector< BLOB_CHOICE *> &blob_choices, float rating_ceiling, bool split_next_to_fragment)
void UndoSeam(TBLOB *blob, TBLOB *other_blob) const
void improve_by_chopping(float rating_cert_scale, WERD_RES *word, BestChoiceBundle *best_choice_bundle, BlamerBundle *blamer_bundle, LMPainPoints *pain_points, GenericVector< SegSearchPending > *pending)
bool has_hyphen_end(UNICHAR_ID unichar_id, bool first_pos) const
Check whether the word has a hyphen at the end.
SEAM * attempt_blob_chop(TWERD *word, TBLOB *blob, int32_t blob_number, bool italic_blob, const GenericVector< SEAM *> &seams)
bool wordrec_debug_blamer
virtual BLOB_CHOICE_LIST * classify_piece(const GenericVector< SEAM *> &seams, int16_t start, int16_t end, const char *description, TWERD *word, BlamerBundle *blamer_bundle)
SEAM * chop_numbered_blob(TWERD *word, int32_t blob_number, bool italic_blob, const GenericVector< SEAM *> &seams)
SEAM * chop_one_blob(const GenericVector< TBOX > &boxes, const GenericVector< BLOB_CHOICE *> &blob_choices, WERD_RES *word_res, int *blob_number)
static bool valid_word_permuter(uint8_t perm, bool numbers_ok)
Check all the DAWGs to see if this word is in any of them.
int16_t total_containment(TBLOB *blob1, TBLOB *blob2)
void SegSearch(WERD_RES *word_res, BestChoiceBundle *best_choice_bundle, BlamerBundle *blamer_bundle)
WERD_CHOICE * best_choice