/******************************************************************
 * File:        docqual.cpp  (Formerly docqual.c)
 * Description: Document Quality Metrics
 * Author:		Phil Cheatle
 * Created:		Mon May  9 11:27:28 BST 1994
 *
 * (C) Copyright 1994, Hewlett-Packard Ltd.
 ** 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.
 *
 **********************************************************************/

#include "mfcpch.h"
#include          <ctype.h>
#include          "docqual.h"
#include          "tstruct.h"
#include          "tfacep.h"
#include          "reject.h"
#include          "tessvars.h"
#include          "genblob.h"
#include          "secname.h"
#include          "globals.h"
#include          "tesseractclass.h"

#define EXTERN

EXTERN STRING_VAR (outlines_odd, "%| ", "Non standard number of outlines");
EXTERN STRING_VAR (outlines_2, "ij!?%\":;",
"Non standard number of outlines");
EXTERN BOOL_VAR (docqual_excuse_outline_errs, FALSE,
"Allow outline errs in unrejection?");
EXTERN BOOL_VAR (tessedit_good_quality_unrej, TRUE,
"Reduce rejection on good docs");
EXTERN BOOL_VAR (tessedit_use_reject_spaces, TRUE, "Reject spaces?");
EXTERN double_VAR (tessedit_reject_doc_percent, 65.00,
"%rej allowed before rej whole doc");
EXTERN double_VAR (tessedit_reject_block_percent, 45.00,
"%rej allowed before rej whole block");
EXTERN double_VAR (tessedit_reject_row_percent, 40.00,
"%rej allowed before rej whole row");
EXTERN double_VAR (tessedit_whole_wd_rej_row_percent, 70.00,
"%of row rejects in whole word rejects which prevents whole row rejection");
EXTERN BOOL_VAR (tessedit_preserve_blk_rej_perfect_wds, TRUE,
"Only rej partially rejected words in block rejection");
EXTERN BOOL_VAR (tessedit_preserve_row_rej_perfect_wds, TRUE,
"Only rej partially rejected words in row rejection");
EXTERN BOOL_VAR (tessedit_dont_blkrej_good_wds, FALSE,
"Use word segmentation quality metric");
EXTERN BOOL_VAR (tessedit_dont_rowrej_good_wds, FALSE,
"Use word segmentation quality metric");
EXTERN INT_VAR (tessedit_preserve_min_wd_len, 2,
"Only preserve wds longer than this");
EXTERN BOOL_VAR (tessedit_row_rej_good_docs, TRUE,
"Apply row rejection to good docs");
EXTERN double_VAR (tessedit_good_doc_still_rowrej_wd, 1.1,
"rej good doc wd if more than this fraction rejected");
EXTERN BOOL_VAR (tessedit_reject_bad_qual_wds, TRUE,
"Reject all bad quality wds");
EXTERN BOOL_VAR (tessedit_debug_doc_rejection, FALSE, "Page stats");
EXTERN BOOL_VAR (tessedit_debug_quality_metrics, FALSE,
"Output data to debug file");
EXTERN BOOL_VAR (bland_unrej, FALSE, "unrej potential with no chekcs");
EXTERN double_VAR (quality_rowrej_pc, 1.1,
"good_quality_doc gte good char limit");

EXTERN BOOL_VAR (unlv_tilde_crunching, TRUE,
"Mark v.bad words for tilde crunch");
EXTERN BOOL_VAR (crunch_early_merge_tess_fails, TRUE, "Before word crunch?");
EXTERN BOOL_EVAR (crunch_early_convert_bad_unlv_chs, FALSE,
"Take out ~^ early?");

EXTERN double_VAR (crunch_terrible_rating, 80.0, "crunch rating lt this");
EXTERN BOOL_VAR (crunch_terrible_garbage, TRUE, "As it says");
EXTERN double_VAR (crunch_poor_garbage_cert, -9.0,
"crunch garbage cert lt this");
EXTERN double_VAR (crunch_poor_garbage_rate, 60,
"crunch garbage rating lt this");

EXTERN double_VAR (crunch_pot_poor_rate, 40,
"POTENTIAL crunch rating lt this");
EXTERN double_VAR (crunch_pot_poor_cert, -8.0,
"POTENTIAL crunch cert lt this");
EXTERN BOOL_VAR (crunch_pot_garbage, TRUE, "POTENTIAL crunch garbage");

EXTERN double_VAR (crunch_del_rating, 60, "POTENTIAL crunch rating lt this");
EXTERN double_VAR (crunch_del_cert, -10.0, "POTENTIAL crunch cert lt this");
EXTERN double_VAR (crunch_del_min_ht, 0.7, "Del if word ht lt xht x this");
EXTERN double_VAR (crunch_del_max_ht, 3.0, "Del if word ht gt xht x this");
EXTERN double_VAR (crunch_del_min_width, 3.0,
"Del if word width lt xht x this");
EXTERN double_VAR (crunch_del_high_word, 1.5,
"Del if word gt xht x this above bl");
EXTERN double_VAR (crunch_del_low_word, 0.5,
"Del if word gt xht x this below bl");
EXTERN double_VAR (crunch_small_outlines_size, 0.6, "Small if lt xht x this");

EXTERN INT_VAR (crunch_rating_max, 10, "For adj length in rating per ch");
EXTERN INT_VAR (crunch_pot_indicators, 1,
"How many potential indicators needed");

EXTERN BOOL_VAR (crunch_leave_ok_strings, TRUE,
"Dont touch sensible strings");
EXTERN BOOL_VAR (crunch_accept_ok, TRUE, "Use acceptability in okstring");
EXTERN BOOL_VAR (crunch_leave_accept_strings, FALSE,
"Dont pot crunch sensible strings");
EXTERN BOOL_VAR (crunch_include_numerals, FALSE, "Fiddle alpha figures");
EXTERN INT_VAR (crunch_leave_lc_strings, 4,
"Dont crunch words with long lower case strings");
EXTERN INT_VAR (crunch_leave_uc_strings, 4,
"Dont crunch words with long lower case strings");
EXTERN INT_VAR (crunch_long_repetitions, 3,
"Crunch words with long repetitions");

EXTERN INT_VAR (crunch_debug, 0, "As it says");

/*************************************************************************
 * word_blob_quality()
 * How many blobs in the outword are identical to those of the inword?
 * ASSUME blobs in both initial word and outword are in ascending order of
 * left hand blob edge.
 *************************************************************************/
inT16 word_blob_quality(  //Blob seg changes
                        WERD_RES *word,
                        ROW *row) {
  WERD *bln_word;                //BL norm init word
  TWERD *tessword;               //tess format
  WERD *init_word;               //BL norm init word
  PBLOB_IT outword_it;
  PBLOB_IT initial_it;
  inT16 i;
  inT16 init_blobs_left;
  inT16 match_count = 0;
  BOOL8 matched;
  TBOX out_box;
  PBLOB *test_blob;
  DENORM denorm;
  float bln_xht;

  if (word->word->gblob_list ()->empty ())
    return 0;
                                 //xht used for blnorm
  bln_xht = bln_x_height / word->denorm.scale ();
  bln_word = make_bln_copy(word->word, row, NULL, bln_xht, &denorm);
  /*
    NOTE: Need to convert to tess format and back again to ensure that the
    same float -> int rounding of coords is done to source wd as out wd before
    comparison
  */
  tessword = make_tess_word(bln_word, NULL);  // Convert word.
  init_word = make_ed_word (tessword, bln_word);
  delete bln_word;
  delete_word(tessword);
  if (init_word == NULL) {
    // Conversion failed.
    return 0;
  }

  initial_it.set_to_list (init_word->blob_list ());
  init_blobs_left = initial_it.length ();
  outword_it.set_to_list (word->outword->blob_list ());

  for (outword_it.mark_cycle_pt ();
  !outword_it.cycled_list (); outword_it.forward ()) {
    out_box = outword_it.data ()->bounding_box ();

    // Skip any initial blobs LEFT of current outword blob.
    while (!initial_it.at_last () &&
    (initial_it.data ()->bounding_box ().left () < out_box.left ())) {
      initial_it.forward ();
      init_blobs_left--;
    }

    /* See if current outword blob matches any initial blob with the same left
      coord. (Normally only one but possibly more - in unknown order) */

    i = 0;
    matched = FALSE;
    do {
      test_blob = initial_it.data_relative (i++);
      matched = crude_match_blobs (test_blob, outword_it.data ());
      if (matched)
        match_count++;
    }
    while (!matched &&
      (init_blobs_left - i > 0) &&
      (i < 129) &&
      !initial_it.at_last () &&
      test_blob->bounding_box ().left () == out_box.left ());
  }
  delete init_word;
  return match_count;
}


/*************************************************************************
 * crude_match_blobs()
 * Check bounding boxes are the same and the number of outlines are the same.
 *************************************************************************/
BOOL8 crude_match_blobs(PBLOB *blob1, PBLOB *blob2) {
  TBOX box1 = blob1->bounding_box ();
  TBOX box2 = blob2->bounding_box ();

  if (box1.contains (box2) &&
    box2.contains (box1) &&
    (blob1->out_list ()->length () == blob1->out_list ()->length ()))
    return TRUE;
  else
    return FALSE;
}


inT16 word_outline_errs(WERD_RES *word) {
  PBLOB_IT outword_it;
  inT16 i = 0;
  inT16 err_count = 0;

  outword_it.set_to_list (word->outword->blob_list ());

  for (outword_it.mark_cycle_pt ();
  !outword_it.cycled_list (); outword_it.forward ()) {
    err_count += count_outline_errs (word->best_choice->unichar_string()[i],
                                    outword_it.data()->out_list()->length());
    i++;
  }
  return err_count;
}


/*************************************************************************
 * word_char_quality()
 * Combination of blob quality and outline quality - how many good chars are
 * there? - I.e chars which pass the blob AND outline tests.
 *************************************************************************/
void word_char_quality(WERD_RES *word,
                       ROW *row,
                       inT16 *match_count,
                       inT16 *accepted_match_count) {
  WERD *bln_word;                //BL norm init word
  TWERD *tessword;               //tess format
  WERD *init_word;               //BL norm init word
  PBLOB_IT outword_it;
  PBLOB_IT initial_it;
  inT16 i;
  inT16 init_blobs_left;
  BOOL8 matched;
  TBOX out_box;
  PBLOB *test_blob;
  DENORM denorm;
  float bln_xht;
  inT16 j = 0;

  *match_count = 0;
  *accepted_match_count = 0;
  if (word->word->gblob_list ()->empty ())
    return;

                                 //xht used for blnorm
  bln_xht = bln_x_height / word->denorm.scale ();
  bln_word = make_bln_copy(word->word, row, NULL, bln_xht, &denorm);
  /*
    NOTE: Need to convert to tess format and back again to ensure that the
    same float -> int rounding of coords is done to source wd as out wd before
    comparison
  */
  tessword = make_tess_word(bln_word, NULL);  // Convert word.
  init_word = make_ed_word (tessword, bln_word);
  delete bln_word;
  delete_word(tessword);
  if (init_word == NULL)
    return;

  initial_it.set_to_list (init_word->blob_list ());
  init_blobs_left = initial_it.length ();
  outword_it.set_to_list (word->outword->blob_list ());

  for (outword_it.mark_cycle_pt ();
  !outword_it.cycled_list (); outword_it.forward ()) {
    out_box = outword_it.data ()->bounding_box ();

    /* Skip any initial blobs LEFT of current outword blob */
    while (!initial_it.at_last () &&
    (initial_it.data ()->bounding_box ().left () < out_box.left ())) {
      initial_it.forward ();
      init_blobs_left--;
    }

    /* See if current outword blob matches any initial blob with the same left
      coord. (Normally only one but possibly more - in unknown order) */

    i = 0;
    matched = FALSE;
    do {
      test_blob = initial_it.data_relative (i++);
      matched = crude_match_blobs (test_blob, outword_it.data ());
      if (matched &&
        (count_outline_errs (word->best_choice->unichar_string()[j],
        outword_it.data ()->out_list ()->length ())
      == 0)) {
        (*match_count)++;
        if (word->reject_map[j].accepted ())
          (*accepted_match_count)++;
      }
    }
    while (!matched &&
      (init_blobs_left - i > 0) &&
      (i < 129) &&
      !initial_it.at_last () &&
      test_blob->bounding_box ().left () == out_box.left ());
    j++;
  }
  delete init_word;
}


/*************************************************************************
 * unrej_good_chs()
 * Unreject POTENTIAL rejects if the blob passes the blob and outline checks
 *************************************************************************/
void unrej_good_chs(WERD_RES *word, ROW *row) {
  WERD *bln_word;                //BL norm init word
  TWERD *tessword;               //tess format
  WERD *init_word;               //BL norm init word
  PBLOB_IT outword_it;
  PBLOB_IT initial_it;
  inT16 i;
  inT16 init_blobs_left;
  BOOL8 matched;
  TBOX out_box;
  PBLOB *test_blob;
  DENORM denorm;
  float bln_xht;
  inT16 j = 0;

  if (word->word->gblob_list ()->empty ())
    return;

                                 //xht used for blnorm
  bln_xht = bln_x_height / word->denorm.scale ();
  bln_word = make_bln_copy(word->word, row, NULL, bln_xht, &denorm);
  /*
    NOTE: Need to convert to tess format and back again to ensure that the
    same float -> int rounding of coords is done to source wd as out wd before
    comparison
  */
  tessword = make_tess_word(bln_word, NULL);  // Convert word
  init_word = make_ed_word (tessword, bln_word);
  delete bln_word;
  delete_word(tessword);
  if (init_word == NULL)
    return;

  initial_it.set_to_list (init_word->blob_list ());
  init_blobs_left = initial_it.length ();
  outword_it.set_to_list (word->outword->blob_list ());

  for (outword_it.mark_cycle_pt ();
  !outword_it.cycled_list (); outword_it.forward ()) {
    out_box = outword_it.data ()->bounding_box ();

    /* Skip any initial blobs LEFT of current outword blob */
    while (!initial_it.at_last () &&
    (initial_it.data ()->bounding_box ().left () < out_box.left ())) {
      initial_it.forward ();
      init_blobs_left--;
    }

    /* See if current outword blob matches any initial blob with the same left
      coord. (Normally only one but possibly more - in unknown order) */

    i = 0;
    matched = FALSE;
    do {
      test_blob = initial_it.data_relative (i++);
      matched = crude_match_blobs (test_blob, outword_it.data ());
      if (matched &&
        (word->reject_map[j].accept_if_good_quality ()) &&
        (docqual_excuse_outline_errs ||
        (count_outline_errs (word->best_choice->unichar_string()[j],
        outword_it.data ()->out_list ()->
        length ()) == 0)))
        word->reject_map[j].setrej_quality_accept ();
    }
    while (!matched &&
      (init_blobs_left - i > 0) &&
      (i < 129) &&
      !initial_it.at_last () &&
      test_blob->bounding_box ().left () == out_box.left ());
    j++;
  }
  delete init_word;
}


void print_boxes(WERD *word) {
  PBLOB_IT it;
  TBOX box;

  it.set_to_list (word->blob_list ());
  for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
    box = it.data ()->bounding_box ();
    box.print ();
  }
}


inT16 count_outline_errs(char c, inT16 outline_count) {
  int expected_outline_count;

  if (STRING (outlines_odd).contains (c))
    return 0;                    //Dont use this char
  else if (STRING (outlines_2).contains (c))
    expected_outline_count = 2;
  else
    expected_outline_count = 1;
  return abs (outline_count - expected_outline_count);
}


namespace tesseract {
void Tesseract::quality_based_rejection(PAGE_RES_IT &page_res_it,
                                        BOOL8 good_quality_doc) {
  if ((tessedit_good_quality_unrej && good_quality_doc))
    unrej_good_quality_words(page_res_it);
  doc_and_block_rejection(page_res_it, good_quality_doc);

  page_res_it.restart_page ();
  while (page_res_it.word () != NULL) {
    insert_rej_cblobs(page_res_it.word());
    page_res_it.forward();
  }

  if (unlv_tilde_crunching) {
    tilde_crunch(page_res_it);
    tilde_delete(page_res_it);
  }
}


/*************************************************************************
 * unrej_good_quality_words()
 * Accept potential rejects in words which pass the following checks:
 *    - Contains a potential reject
 *    - Word looks like a sensible alpha word.
 *    - Word segmentation is the same as the original image
 *		- All characters have the expected number of outlines
 * NOTE - the rejection counts are recalculated after unrejection
 *      - CANT do it in a single pass without a bit of fiddling
 *		- keep it simple but inefficient
 *************************************************************************/
void Tesseract::unrej_good_quality_words(  //unreject potential
                                         PAGE_RES_IT &page_res_it) {
  WERD_RES *word;
  ROW_RES *current_row;
  BLOCK_RES *current_block;
  int i;

  page_res_it.restart_page ();
  while (page_res_it.word () != NULL) {
    check_debug_pt (page_res_it.word (), 100);
    if (bland_unrej) {
      word = page_res_it.word ();
      for (i = 0; i < word->reject_map.length (); i++) {
        if (word->reject_map[i].accept_if_good_quality ())
          word->reject_map[i].setrej_quality_accept ();
      }
      page_res_it.forward ();
    }
    else if ((page_res_it.row ()->char_count > 0) &&
      ((page_res_it.row ()->rej_count /
      (float) page_res_it.row ()->char_count) <=
    quality_rowrej_pc)) {
      word = page_res_it.word ();
      if (word->reject_map.quality_recoverable_rejects () &&
        (tessedit_unrej_any_wd ||
        acceptable_word_string (word->best_choice->unichar_string().string(),
                                word->best_choice->unichar_lengths().string())
      != AC_UNACCEPTABLE)) {
        unrej_good_chs (word, page_res_it.row ()->row);
      }
      page_res_it.forward ();
    }
    else {
      /* Skip to end of dodgy row */
      current_row = page_res_it.row ();
      while ((page_res_it.word () != NULL) &&
        (page_res_it.row () == current_row))
        page_res_it.forward ();
    }
    check_debug_pt (page_res_it.word (), 110);
  }
  page_res_it.restart_page ();
  page_res_it.page_res->char_count = 0;
  page_res_it.page_res->rej_count = 0;
  current_block = NULL;
  current_row = NULL;
  while (page_res_it.word () != NULL) {
    if (current_block != page_res_it.block ()) {
      current_block = page_res_it.block ();
      current_block->char_count = 0;
      current_block->rej_count = 0;
    }
    if (current_row != page_res_it.row ()) {
      current_row = page_res_it.row ();
      current_row->char_count = 0;
      current_row->rej_count = 0;
      current_row->whole_word_rej_count = 0;
    }
    page_res_it.rej_stat_word ();
    page_res_it.forward ();
  }
}


/*************************************************************************
 * doc_and_block_rejection()
 *
 * If the page has too many rejects - reject all of it.
 * If any block has too many rejects - reject all words in the block
 *************************************************************************/

void Tesseract::doc_and_block_rejection(  //reject big chunks
                                        PAGE_RES_IT &page_res_it,
                                        BOOL8 good_quality_doc) {
  inT16 block_no = 0;
  inT16 row_no = 0;
  BLOCK_RES *current_block;
  ROW_RES *current_row;

  BOOL8 rej_word;
  BOOL8 prev_word_rejected;
  inT16 char_quality;
  inT16 accepted_char_quality;

  if ((page_res_it.page_res->rej_count * 100.0 /
  page_res_it.page_res->char_count) > tessedit_reject_doc_percent) {
    reject_whole_page(page_res_it);
    #ifndef SECURE_NAMES
    if (tessedit_debug_doc_rejection) {
      tprintf ("REJECT ALL #chars: %d #Rejects: %d; \n",
        page_res_it.page_res->char_count,
        page_res_it.page_res->rej_count);
    }
    #endif
  }
  else {
    #ifndef SECURE_NAMES
    if (tessedit_debug_doc_rejection)
      tprintf ("NO PAGE REJECTION #chars: %d  # Rejects: %d; \n",
        page_res_it.page_res->char_count,
        page_res_it.page_res->rej_count);
    #endif

    /* Walk blocks testing for block rejection */

    page_res_it.restart_page ();
    while (page_res_it.word () != NULL) {
      current_block = page_res_it.block ();
      block_no = current_block->block->index();
      if ((page_res_it.block ()->char_count > 0) &&
        ((page_res_it.block ()->rej_count * 100.0 /
        page_res_it.block ()->char_count) >
      tessedit_reject_block_percent)) {
        #ifndef SECURE_NAMES
        if (tessedit_debug_block_rejection)
          tprintf ("REJECTING BLOCK %d  #chars: %d;  #Rejects: %d\n",
            block_no,
            page_res_it.block ()->char_count,
            page_res_it.block ()->rej_count);
        #endif
        prev_word_rejected = FALSE;
        while ((page_res_it.word () != NULL) &&
        (page_res_it.block () == current_block)) {
          if (tessedit_preserve_blk_rej_perfect_wds) {
            rej_word =
              (page_res_it.word ()->reject_map.reject_count () > 0)
              || (page_res_it.word ()->reject_map.length () <
              tessedit_preserve_min_wd_len);
            if (rej_word && tessedit_dont_blkrej_good_wds
              && !(page_res_it.word ()->reject_map.length () <
              tessedit_preserve_min_wd_len)
              &&
              (acceptable_word_string
               (page_res_it.word()->best_choice->unichar_string().string(),
               page_res_it.word ()->best_choice->unichar_lengths().string()) !=
               AC_UNACCEPTABLE)) {
              word_char_quality (page_res_it.word (),
                page_res_it.row ()->row,
                &char_quality,
                &accepted_char_quality);
              rej_word = char_quality !=
                page_res_it.word ()->reject_map.length ();
            }
          }
          else
            rej_word = TRUE;
          if (rej_word) {
            /*
              Reject spacing if both current and prev words are rejected.
              NOTE - this is NOT restricted to FUZZY spaces. - When tried this
              generated more space errors.
            */
            if (tessedit_use_reject_spaces &&
              prev_word_rejected &&
              (page_res_it.prev_row () == page_res_it.row ()) &&
              (page_res_it.word ()->word->space () == 1))
              page_res_it.word ()->reject_spaces = TRUE;
            page_res_it.word ()->reject_map.rej_word_block_rej ();
          }
          prev_word_rejected = rej_word;
          page_res_it.forward ();
        }
      }
      else {
        #ifndef SECURE_NAMES
        if (tessedit_debug_block_rejection)
          tprintf
            ("NOT REJECTING BLOCK %d #chars: %d  # Rejects: %d; \n",
            block_no, page_res_it.block ()->char_count,
            page_res_it.block ()->rej_count);
        #endif

        /* Walk rows in block testing for row rejection */
        row_no = 0;
        while ((page_res_it.word () != NULL) &&
        (page_res_it.block () == current_block)) {
          current_row = page_res_it.row ();
          row_no++;
          /* Reject whole row if:
            fraction of chars on row which are rejected exceed a limit AND
            fraction rejects which occur in WHOLE WERD rejects is LESS THAN a
            limit
          */
          if ((page_res_it.row ()->char_count > 0) &&
            ((page_res_it.row ()->rej_count * 100.0 /
            page_res_it.row ()->char_count) >
            tessedit_reject_row_percent) &&
            ((page_res_it.row ()->whole_word_rej_count * 100.0 /
            page_res_it.row ()->rej_count) <
          tessedit_whole_wd_rej_row_percent)) {
            #ifndef SECURE_NAMES
            if (tessedit_debug_block_rejection)
              tprintf
                ("REJECTING ROW %d  #chars: %d;  #Rejects: %d\n",
                row_no, page_res_it.row ()->char_count,
                page_res_it.row ()->rej_count);
            #endif
            prev_word_rejected = FALSE;
            while ((page_res_it.word () != NULL) &&
            (page_res_it.row () == current_row)) {
              /* Preserve words on good docs unless they are mostly rejected*/
              if (!tessedit_row_rej_good_docs && good_quality_doc) {
                rej_word =
                  page_res_it.word ()->reject_map.
                  reject_count () /
                  (float) page_res_it.word ()->reject_map.
                  length () > tessedit_good_doc_still_rowrej_wd;
              }

              /* Preserve perfect words anyway */
              else if (tessedit_preserve_row_rej_perfect_wds) {
                rej_word =
                  (page_res_it.word ()->reject_map.
                  reject_count () > 0)
                  || (page_res_it.word ()->reject_map.
                  length () < tessedit_preserve_min_wd_len);
                if (rej_word && tessedit_dont_rowrej_good_wds
                  && !(page_res_it.word ()->reject_map.
                  length () <
                  tessedit_preserve_min_wd_len)
                  &&
                  (acceptable_word_string
                   (page_res_it.word ()->best_choice->
                    unichar_string().string(),
                    page_res_it.word ()->best_choice->
                    unichar_lengths().string()) != AC_UNACCEPTABLE)) {
                  word_char_quality (page_res_it.word (),
                    page_res_it.row ()->row,
                    &char_quality,
                    &accepted_char_quality);
                  rej_word = char_quality !=
                    page_res_it.word ()->reject_map.length ();
                }
              }
              else
                rej_word = TRUE;
              if (rej_word) {
                /*
                  Reject spacing if both current and prev words are rejected.
                  NOTE - this is NOT restricted to FUZZY spaces. - When tried
                  this generated more space errors.
                */
                if (tessedit_use_reject_spaces &&
                  prev_word_rejected &&
                  (page_res_it.prev_row () ==
                  page_res_it.row ())
                  && (page_res_it.word ()->word->space () ==
                  1))
                  page_res_it.word ()->reject_spaces = TRUE;
                page_res_it.word ()->reject_map.
                  rej_word_row_rej();
              }
              prev_word_rejected = rej_word;
              page_res_it.forward ();
            }
          }
          else {
            #ifndef SECURE_NAMES
            if (tessedit_debug_block_rejection)
              tprintf
                ("NOT REJECTING ROW %d #chars: %d  # Rejects: %d; \n",
                row_no, page_res_it.row ()->char_count,
                page_res_it.row ()->rej_count);
            #endif
            while ((page_res_it.word () != NULL) &&
              (page_res_it.row () == current_row))
              page_res_it.forward ();
          }
        }
      }
    }
  }
}
}  // namespace tesseract


/*************************************************************************
 * reject_whole_page()
 * Dont believe any of it - set the reject map to 00..00 in all words
 *
 *************************************************************************/

void reject_whole_page(PAGE_RES_IT &page_res_it) {
  page_res_it.restart_page ();
  while (page_res_it.word () != NULL) {
    page_res_it.word ()->reject_map.rej_word_doc_rej ();
    page_res_it.forward ();
  }
                                 //whole page is rejected
  page_res_it.page_res->rejected = TRUE;
}

namespace tesseract {
void Tesseract::tilde_crunch(PAGE_RES_IT &page_res_it) {
  WERD_RES *word;
  GARBAGE_LEVEL garbage_level;
  PAGE_RES_IT copy_it;
  BOOL8 prev_potential_marked = FALSE;
  BOOL8 found_terrible_word = FALSE;
  BOOL8 ok_dict_word;

  page_res_it.restart_page ();
  while (page_res_it.word () != NULL) {
    word = page_res_it.word ();

    if (crunch_early_convert_bad_unlv_chs)
      convert_bad_unlv_chs(word);

    if (crunch_early_merge_tess_fails)
      merge_tess_fails(word);

    if (word->reject_map.accept_count () != 0) {
      found_terrible_word = FALSE;
                                 //Forget earlier potential crunches
      prev_potential_marked = FALSE;
    }
    else {
      ok_dict_word = safe_dict_word(*(word->best_choice));
      garbage_level = garbage_word (word, ok_dict_word);

      if ((garbage_level != G_NEVER_CRUNCH) &&
      (terrible_word_crunch (word, garbage_level))) {
        if (crunch_debug > 0) {
          tprintf ("T CRUNCHING: \"%s\"\n",
            word->best_choice->unichar_string().string());
        }
        word->unlv_crunch_mode = CR_KEEP_SPACE;
        if (prev_potential_marked) {
          while (copy_it.word () != word) {
            if (crunch_debug > 0) {
              tprintf ("P1 CRUNCHING: \"%s\"\n",
                copy_it.word()->best_choice->unichar_string().string());
            }
            copy_it.word ()->unlv_crunch_mode = CR_KEEP_SPACE;
            copy_it.forward ();
          }
          prev_potential_marked = FALSE;
        }
        found_terrible_word = TRUE;
      }
      else if ((garbage_level != G_NEVER_CRUNCH) &&
        (potential_word_crunch (word,
      garbage_level, ok_dict_word))) {
        if (found_terrible_word) {
          if (crunch_debug > 0) {
            tprintf ("P2 CRUNCHING: \"%s\"\n",
              word->best_choice->unichar_string().string());
          }
          word->unlv_crunch_mode = CR_KEEP_SPACE;
        }
        else if (!prev_potential_marked) {
          copy_it = page_res_it;
          prev_potential_marked = TRUE;
          if (crunch_debug > 1) {
            tprintf ("P3 CRUNCHING: \"%s\"\n",
              word->best_choice->unichar_string().string());
          }
        }
      }
      else {
        found_terrible_word = FALSE;
                                 //Forget earlier potential crunches
        prev_potential_marked = FALSE;
        if (crunch_debug > 2) {
          tprintf ("NO CRUNCH: \"%s\"\n",
            word->best_choice->unichar_string().string());
        }
      }
    }
    page_res_it.forward ();
  }
}
}  // namespace tesseract


BOOL8 terrible_word_crunch(WERD_RES *word, GARBAGE_LEVEL garbage_level) {
  float rating_per_ch;
  int adjusted_len;
  int crunch_mode = 0;

  if ((word->best_choice->unichar_string().length () == 0) ||
    (strspn (word->best_choice->unichar_string().string(), " ") ==
    word->best_choice->unichar_string().length ()))
    crunch_mode = 1;
  else {
    adjusted_len = word->reject_map.length ();
    if (adjusted_len > crunch_rating_max)
      adjusted_len = crunch_rating_max;
    rating_per_ch = word->best_choice->rating () / adjusted_len;

    if (rating_per_ch > crunch_terrible_rating)
      crunch_mode = 2;
    else if (crunch_terrible_garbage && (garbage_level == G_TERRIBLE))
      crunch_mode = 3;
    else if ((word->best_choice->certainty () < crunch_poor_garbage_cert) &&
      (garbage_level != G_OK))
      crunch_mode = 4;
    else if ((rating_per_ch > crunch_poor_garbage_rate) &&
      (garbage_level != G_OK))
      crunch_mode = 5;
  }
  if (crunch_mode > 0) {
    if (crunch_debug > 2) {
      tprintf ("Terrible_word_crunch (%d) on \"%s\"\n",
        crunch_mode, word->best_choice->unichar_string().string());
    }
    return TRUE;
  }
  else
    return FALSE;
}

namespace tesseract {
BOOL8 Tesseract::potential_word_crunch(WERD_RES *word,
                                       GARBAGE_LEVEL garbage_level,
                                       BOOL8 ok_dict_word) {
  float rating_per_ch;
  int adjusted_len;
  const char *str = word->best_choice->unichar_string().string();
  const char *lengths = word->best_choice->unichar_lengths().string();
  BOOL8 word_crunchable;
  int poor_indicator_count = 0;

  word_crunchable =
    !crunch_leave_accept_strings ||
    (word->reject_map.length () < 3) ||
    ((acceptable_word_string (str, lengths) == AC_UNACCEPTABLE) &&
     !ok_dict_word);

  adjusted_len = word->reject_map.length ();
  if (adjusted_len > 10)
    adjusted_len = 10;
  rating_per_ch = word->best_choice->rating () / adjusted_len;

  if (rating_per_ch > crunch_pot_poor_rate) {
    if (crunch_debug > 2) {
      tprintf ("Potential poor rating on \"%s\"\n",
        word->best_choice->unichar_string().string());
    }
    poor_indicator_count++;
  }

  if (word_crunchable &&
  (word->best_choice->certainty () < crunch_pot_poor_cert)) {
    if (crunch_debug > 2) {
      tprintf ("Potential poor cert on \"%s\"\n",
        word->best_choice->unichar_string().string());
    }
    poor_indicator_count++;
  }

  if (garbage_level != G_OK) {
    if (crunch_debug > 2) {
      tprintf ("Potential garbage on \"%s\"\n",
        word->best_choice->unichar_string().string());
    }
    poor_indicator_count++;
  }
  return (poor_indicator_count >= crunch_pot_indicators);
}
}  // namespace tesseract


namespace tesseract {
void Tesseract::tilde_delete(PAGE_RES_IT &page_res_it) {
  WERD_RES *word;
  PAGE_RES_IT copy_it;
  BOOL8 deleting_from_bol = FALSE;
  BOOL8 marked_delete_point = FALSE;
  inT16 debug_delete_mode;
  CRUNCH_MODE delete_mode;
  inT16 x_debug_delete_mode;
  CRUNCH_MODE x_delete_mode;

  page_res_it.restart_page ();
  while (page_res_it.word () != NULL) {
    word = page_res_it.word ();

    delete_mode = word_deletable (word, debug_delete_mode);
    if (delete_mode != CR_NONE) {
      if (word->word->flag (W_BOL) || deleting_from_bol) {
        if (crunch_debug > 0) {
          tprintf ("BOL CRUNCH DELETING(%d): \"%s\"\n",
            debug_delete_mode,
            word->best_choice->unichar_string().string());
        }
        word->unlv_crunch_mode = delete_mode;
        deleting_from_bol = TRUE;
      }
      else if (word->word->flag (W_EOL)) {
        if (marked_delete_point) {
          while (copy_it.word () != word) {
            x_delete_mode = word_deletable (copy_it.word (),
              x_debug_delete_mode);
            if (crunch_debug > 0) {
              tprintf ("EOL CRUNCH DELETING(%d): \"%s\"\n",
                x_debug_delete_mode,
                copy_it.word()->best_choice->unichar_string().string());
            }
            copy_it.word ()->unlv_crunch_mode = x_delete_mode;
            copy_it.forward ();
          }
        }
        if (crunch_debug > 0) {
          tprintf ("EOL CRUNCH DELETING(%d): \"%s\"\n",
            debug_delete_mode,
            word->best_choice->unichar_string().string());
        }
        word->unlv_crunch_mode = delete_mode;
        deleting_from_bol = FALSE;
        marked_delete_point = FALSE;
      }
      else {
        if (!marked_delete_point) {
          copy_it = page_res_it;
          marked_delete_point = TRUE;
        }
      }
    }
    else {
      deleting_from_bol = FALSE;
                                 //Forget earlier potential crunches
      marked_delete_point = FALSE;
    }
    /*
      The following step has been left till now as the tess fails are used to
      determine if the word is deletable.
    */
    if (!crunch_early_merge_tess_fails)
      merge_tess_fails(word);
    page_res_it.forward ();
  }
}


void Tesseract::convert_bad_unlv_chs(WERD_RES *word_res) {
  int i;
  UNICHAR_ID unichar_dash = unicharset.unichar_to_id("-");
  UNICHAR_ID unichar_space = unicharset.unichar_to_id(" ");
  UNICHAR_ID unichar_tilde = unicharset.unichar_to_id("~");
  UNICHAR_ID unichar_pow = unicharset.unichar_to_id("^");
  bool modified = false;
  for (i = 0; i < word_res->reject_map.length(); ++i) {
    if (word_res->best_choice->unichar_id(i) == unichar_tilde) {
      word_res->best_choice->set_unichar_id(unichar_dash, i);
      modified = true;
      if (word_res->reject_map[i].accepted ())
        word_res->reject_map[i].setrej_unlv_rej ();
    }
    if (word_res->best_choice->unichar_id(i) == unichar_pow) {
      word_res->best_choice->set_unichar_id(unichar_space, i);
      modified = true;
      if (word_res->reject_map[i].accepted ())
        word_res->reject_map[i].setrej_unlv_rej ();
    }
  }
  if (modified) {
    word_res->best_choice->populate_unichars(unicharset);
  }
}

// Change pairs of tess failures to a single one
void Tesseract::merge_tess_fails(WERD_RES *word_res) {
  PBLOB_IT blob_it;              //blobs
  int len = word_res->best_choice->length();
  bool modified = false;

  ASSERT_HOST (word_res->reject_map.length () == len);
  ASSERT_HOST (word_res->outword->blob_list ()->length () == len);

  UNICHAR_ID unichar_space = unicharset.unichar_to_id(" ");
  blob_it = word_res->outword->blob_list ();
  int i = 0;
  while (i < word_res->best_choice->length()-1) {
    if ((word_res->best_choice->unichar_id(i) == unichar_space) &&
        (word_res->best_choice->unichar_id(i+1) == unichar_space)) {
      modified = true;
      word_res->best_choice->remove_unichar_id(i);
      word_res->reject_map.remove_pos (i);
      merge_blobs (blob_it.data_relative (1), blob_it.data ());
      delete blob_it.extract (); //get rid of spare
    } else {
      i++;
    }
    blob_it.forward ();
  }
  len = word_res->best_choice->length();
  ASSERT_HOST (word_res->reject_map.length () == len);
  ASSERT_HOST (word_res->outword->blob_list ()->length () == len);
  if (modified) {
    word_res->best_choice->populate_unichars(unicharset);
  }
}

GARBAGE_LEVEL Tesseract::garbage_word(WERD_RES *word, BOOL8 ok_dict_word) {
  enum STATES
  {
    JUNK,
    FIRST_UPPER,
    FIRST_LOWER,
    FIRST_NUM,
    SUBSEQUENT_UPPER,
    SUBSEQUENT_LOWER,
    SUBSEQUENT_NUM
  };
  const char *str = word->best_choice->unichar_string().string();
  const char *lengths = word->best_choice->unichar_lengths().string();
  STATES state = JUNK;
  int len = 0;
  int isolated_digits = 0;
  int isolated_alphas = 0;
  int bad_char_count = 0;
  int tess_rejs = 0;
  int dodgy_chars = 0;
  int ok_chars;
  UNICHAR_ID last_char = -1;
  int alpha_repetition_count = 0;
  int longest_alpha_repetition_count = 0;
  int longest_lower_run_len = 0;
  int lower_string_count = 0;
  int longest_upper_run_len = 0;
  int upper_string_count = 0;
  int total_alpha_count = 0;
  int total_digit_count = 0;

  for (; *str != '\0'; str += *(lengths++)) {
    len++;
    if (unicharset.get_isupper (str, *lengths)) {
      total_alpha_count++;
      switch (state) {
        case SUBSEQUENT_UPPER:
        case FIRST_UPPER:
          state = SUBSEQUENT_UPPER;
          upper_string_count++;
          if (longest_upper_run_len < upper_string_count)
            longest_upper_run_len = upper_string_count;
          if (last_char == unicharset.unichar_to_id(str, *lengths)) {
            alpha_repetition_count++;
            if (longest_alpha_repetition_count < alpha_repetition_count) {
              longest_alpha_repetition_count = alpha_repetition_count;
            }
          }
          else {
            last_char = unicharset.unichar_to_id(str, *lengths);
            alpha_repetition_count = 1;
          }
          break;
        case FIRST_NUM:
          isolated_digits++;
        default:
          state = FIRST_UPPER;
          last_char = unicharset.unichar_to_id(str, *lengths);
          alpha_repetition_count = 1;
          upper_string_count = 1;
          break;
      }
    }
    else if (unicharset.get_islower (str, *lengths)) {
      total_alpha_count++;
      switch (state) {
        case SUBSEQUENT_LOWER:
        case FIRST_LOWER:
          state = SUBSEQUENT_LOWER;
          lower_string_count++;
          if (longest_lower_run_len < lower_string_count)
            longest_lower_run_len = lower_string_count;
          if (last_char == unicharset.unichar_to_id(str, *lengths)) {
            alpha_repetition_count++;
            if (longest_alpha_repetition_count < alpha_repetition_count) {
              longest_alpha_repetition_count = alpha_repetition_count;
            }
          }
          else {
            last_char = unicharset.unichar_to_id(str, *lengths);
            alpha_repetition_count = 1;
          }
          break;
        case FIRST_NUM:
          isolated_digits++;
        default:
          state = FIRST_LOWER;
          last_char = unicharset.unichar_to_id(str, *lengths);
          alpha_repetition_count = 1;
          lower_string_count = 1;
          break;
      }
    }
    else if (unicharset.get_isdigit (str, *lengths)) {
      total_digit_count++;
      switch (state) {
        case FIRST_NUM:
          state = SUBSEQUENT_NUM;
        case SUBSEQUENT_NUM:
          break;
        case FIRST_UPPER:
        case FIRST_LOWER:
          isolated_alphas++;
        default:
          state = FIRST_NUM;
          break;
      }
    }
    else {
      if (*lengths == 1 && *str == ' ')
        tess_rejs++;
      else
        bad_char_count++;
      switch (state) {
        case FIRST_NUM:
          isolated_digits++;
          break;
        case FIRST_UPPER:
        case FIRST_LOWER:
          isolated_alphas++;
        default:
          break;
      }
      state = JUNK;
    }
  }

  switch (state) {
    case FIRST_NUM:
      isolated_digits++;
      break;
    case FIRST_UPPER:
    case FIRST_LOWER:
      isolated_alphas++;
    default:
      break;
  }

  if (crunch_include_numerals) {
    total_alpha_count += total_digit_count - isolated_digits;
  }

  if (crunch_leave_ok_strings &&
    (len >= 4) &&
    (2 * (total_alpha_count - isolated_alphas) > len) &&
  (longest_alpha_repetition_count < crunch_long_repetitions)) {
    if ((crunch_accept_ok &&
      (acceptable_word_string (str, lengths) != AC_UNACCEPTABLE)) ||
      (longest_lower_run_len > crunch_leave_lc_strings) ||
      (longest_upper_run_len > crunch_leave_uc_strings))
      return G_NEVER_CRUNCH;
  }
  if ((word->reject_map.length () > 1) &&
    (strpbrk (str, " ") == NULL) &&
    ((word->best_choice->permuter () == SYSTEM_DAWG_PERM) ||
    (word->best_choice->permuter () == FREQ_DAWG_PERM) ||
    (word->best_choice->permuter () == USER_DAWG_PERM) ||
    (word->best_choice->permuter () == NUMBER_PERM) ||
    (acceptable_word_string (str, lengths) != AC_UNACCEPTABLE) || ok_dict_word))
    return G_OK;

  ok_chars = len - bad_char_count - isolated_digits -
    isolated_alphas - tess_rejs;

  if (crunch_debug > 3) {
    tprintf ("garbage_word: \"%s\"\n",
      word->best_choice->unichar_string().string());
    tprintf ("LEN: %d  bad: %d  iso_N: %d  iso_A: %d  rej: %d\n",
      len,
      bad_char_count, isolated_digits, isolated_alphas, tess_rejs);
  }
  if ((bad_char_count == 0) &&
    (tess_rejs == 0) &&
    ((len > isolated_digits + isolated_alphas) || (len <= 2)))
    return G_OK;

  if ((tess_rejs > ok_chars) ||
    ((tess_rejs > 0) && ((bad_char_count + tess_rejs) * 2 > len)))
    return G_TERRIBLE;

  if (len > 4) {
    dodgy_chars = 2 * tess_rejs + bad_char_count +
      isolated_digits + isolated_alphas;
    if ((dodgy_chars > 5) || ((dodgy_chars / (float) len) > 0.5))
      return G_DODGY;
    else
      return G_OK;
  }
  else {
    dodgy_chars = 2 * tess_rejs + bad_char_count;
    if (((len == 4) && (dodgy_chars > 2)) ||
      ((len == 3) && (dodgy_chars > 2)) || (dodgy_chars >= len))
      return G_DODGY;
    else
      return G_OK;
  }
}
}  // namespace tesseract


/*************************************************************************
 * word_deletable()
 *     DELETE WERDS AT ENDS OF ROWS IF
 *        Word is crunched &&
 *        ( string length = 0                                          OR
 *          > 50% of chars are "|" (before merging)                    OR
 *          certainty < -10                                            OR
 *          rating /char > 60                                          OR
 *          TOP of word is more than 0.5 xht BELOW baseline            OR
 *          BOTTOM of word is more than 0.5 xht ABOVE xht              OR
 *          length of word < 3xht                                      OR
 *          height of word < 0.7 xht                                   OR
 *          height of word > 3.0 xht                                   OR
 *          >75% of the outline BBs have longest dimension < 0.5xht
 *************************************************************************/

CRUNCH_MODE word_deletable(WERD_RES *word, inT16 &delete_mode) {
  int word_len = word->reject_map.length ();
  float rating_per_ch;
  TBOX box;                       //BB of word

  if (word->unlv_crunch_mode == CR_NONE) {
    delete_mode = 0;
    return CR_NONE;
  }

  if (word_len == 0) {
    delete_mode = 1;
    return CR_DELETE;
  }

  box = word->outword->bounding_box ();
  if (box.height () < crunch_del_min_ht * bln_x_height) {
    delete_mode = 4;
    return CR_DELETE;
  }

  if (noise_outlines (word->outword)) {
    delete_mode = 5;
    return CR_DELETE;
  }

  if ((failure_count (word) * 1.5) > word_len) {
    delete_mode = 2;
    return CR_LOOSE_SPACE;
  }

  if (word->best_choice->certainty () < crunch_del_cert) {
    delete_mode = 7;
    return CR_LOOSE_SPACE;
  }

  rating_per_ch = word->best_choice->rating () / word_len;

  if (rating_per_ch > crunch_del_rating) {
    delete_mode = 8;
    return CR_LOOSE_SPACE;
  }

  if (box.top () < bln_baseline_offset - crunch_del_low_word * bln_x_height) {
    delete_mode = 9;
    return CR_LOOSE_SPACE;
  }

  if (box.bottom () >
  bln_baseline_offset + crunch_del_high_word * bln_x_height) {
    delete_mode = 10;
    return CR_LOOSE_SPACE;
  }

  if (box.height () > crunch_del_max_ht * bln_x_height) {
    delete_mode = 11;
    return CR_LOOSE_SPACE;
  }

  if (box.width () < crunch_del_min_width * bln_x_height) {
    delete_mode = 3;
    return CR_LOOSE_SPACE;
  }

  delete_mode = 0;
  return CR_NONE;
}

inT16 failure_count(WERD_RES *word) {
  const char *str = word->best_choice->unichar_string().string();
  int tess_rejs = 0;

  for (; *str != '\0'; str++) {
    if (*str == ' ')
      tess_rejs++;
  }
  return tess_rejs;
}


BOOL8 noise_outlines(WERD *word) {
  PBLOB_IT blob_it;
  OUTLINE_IT outline_it;
  TBOX box;                       //BB of outline
  inT16 outline_count = 0;
  inT16 small_outline_count = 0;
  inT16 max_dimension;
  float small_limit = bln_x_height * crunch_small_outlines_size;

  blob_it.set_to_list (word->blob_list ());
  for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
    outline_it.set_to_list (blob_it.data ()->out_list ());
    for (outline_it.mark_cycle_pt ();
    !outline_it.cycled_list (); outline_it.forward ()) {
      outline_count++;
      box = outline_it.data ()->bounding_box ();
      if (box.height () > box.width ())
        max_dimension = box.height ();
      else
        max_dimension = box.width ();
      if (max_dimension < small_limit)
        small_outline_count++;
    }
  }
  return (small_outline_count >= outline_count);
}


/*************************************************************************
 * insert_rej_cblobs()
 * Put rejected word blobs back into the outword.
 * NOTE!!! AFTER THIS THE CHOICES LIST WILL NOT HAVE THE CORRECT NUMBER
 * OF ELEMENTS.
 *************************************************************************/
namespace tesseract {
void Tesseract::insert_rej_cblobs(WERD_RES *word) {
  PBLOB_IT blob_it;              //blob iterator
  PBLOB_IT rej_blob_it;
  const STRING *word_str;
  const STRING *word_lengths;
  int old_len;
  int rej_len;
  char new_str[512 * UNICHAR_LEN];
  char new_lengths[512];
  REJMAP new_map;
  int i = 0;                     //new_str index
  int j = 0;                     //old_str index
  int i_offset = 0;              //new_str offset
  int j_offset = 0;              //old_str offset
  int new_len;

  gblob_sort_list (word->outword->rej_blob_list (), TRUE);
  rej_blob_it.set_to_list (word->outword->rej_blob_list ());
  if (rej_blob_it.empty ())
    return;
  rej_len = rej_blob_it.length ();
  blob_it.set_to_list (word->outword->blob_list ());
  word_str = &(word->best_choice->unichar_string());
  word_lengths = &(word->best_choice->unichar_lengths());
  old_len = word->best_choice->length();
  ASSERT_HOST (word->reject_map.length () == old_len);
  ASSERT_HOST (blob_it.length () == old_len);
  if ((old_len + rej_len) > 511)
    return;                      //Word is garbage anyway prevent abort
  new_map.initialise (old_len + rej_len);

  while (!rej_blob_it.empty ()) {
    if ((j >= old_len) ||
      (rej_blob_it.data ()->bounding_box ().left () <=
    blob_it.data ()->bounding_box ().left ())) {
      /* Insert reject blob */
      if (j >= old_len)
        blob_it.add_to_end (rej_blob_it.extract ());
      else
        blob_it.add_before_stay_put (rej_blob_it.extract ());
      if (!rej_blob_it.empty ())
        rej_blob_it.forward ();
      new_str[i_offset] = ' ';
      new_lengths[i] = 1;
      new_map[i].setrej_rej_cblob ();
      i_offset += new_lengths[i++];
    }
    else {
      strncpy(new_str + i_offset, &(*word_str)[j_offset],
              (*word_lengths)[j]);
      new_lengths[i] = (*word_lengths)[j];
      new_map[i] = word->reject_map[j];
      i_offset += new_lengths[i++];
      j_offset += (*word_lengths)[j++];
      blob_it.forward ();
    }
  }
  /* Add any extra normal blobs to strings */
  while (j < word_lengths->length ()) {
    strncpy(new_str + i_offset, &(*word_str)[j_offset],
            (*word_lengths)[j]);
    new_lengths[i] = (*word_lengths)[j];
    new_map[i] = word->reject_map[j];
    i_offset += new_lengths[i++];
    j_offset += (*word_lengths)[j++];
  }
  new_str[i_offset] = '\0';
  new_lengths[i] = 0;
  /*
    tprintf(
          "\nOld len %d; New len %d; New str \"%s\"; New map \"%s\"\n",
          old_len, i, new_str, new_map );
  */
  ASSERT_HOST (i == blob_it.length ());
  ASSERT_HOST (i == old_len + rej_len);
  word->reject_map = new_map;

  // Update word->best_choice if needed.
  if (strcmp(new_str, word->best_choice->unichar_string().string()) != 0 ||
      strcmp(new_lengths, word->best_choice->unichar_lengths().string()) != 0) {
    WERD_CHOICE *new_choice =
      new WERD_CHOICE(new_str, new_lengths,
                      word->best_choice->rating(),
                      word->best_choice->certainty(),
                      word->best_choice->permuter(),
                      getDict().getUnicharset());
   new_choice->populate_unichars(getDict().getUnicharset());
   delete word->best_choice;
   word->best_choice = new_choice;
  }
  new_len = word->best_choice->length();
  ASSERT_HOST (word->reject_map.length () == new_len);
  ASSERT_HOST (word->outword->blob_list ()->length () == new_len);

}
}  // namespace tesseract
