/**********************************************************************
 * File:        applybox.cpp  (Formerly applybox.c)
 * Description: Re segment rows according to box file data
 * Author:      Phil Cheatle
 * Created:     Wed Nov 24 09:11:23 GMT 1993
 *
 * (C) Copyright 1993, 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 automatically generated configuration file if running autoconf.
#ifdef HAVE_CONFIG_H
#include "config_auto.h"
#endif

#ifdef HAVE_LIBLEPT
// Include leptonica library only if autoconf (or makefile etc) tell us to.
#include "allheaders.h"
#endif

#include "applybox.h"
#include <ctype.h>
#include <string.h>
#ifdef __UNIX__
#include <assert.h>
#include <errno.h>
#endif
#include "boxread.h"
#include "control.h"
#include "genblob.h"
#include "globals.h"
#include "fixxht.h"
#include "mainblk.h"
#include "matchdefs.h"
#include "secname.h"
#include "tessbox.h"
#include "unichar.h"
#include "unicharset.h"
#include "matchdefs.h"
#include "tesseractclass.h"

#define SECURE_NAMES
#ifndef SECURE_NAMES
#include          "wordstats.h"
#endif

#define EXTERN
EXTERN BOOL_VAR (applybox_rebalance, TRUE, "Drop dead");
EXTERN INT_VAR (applybox_debug, 5, "Debug level");
EXTERN INT_VAR (applybox_page, 0, "Page number to apply boxes from");
EXTERN STRING_VAR (applybox_test_exclusions, "",
                   "Chars ignored for testing");
EXTERN double_VAR (applybox_error_band, 0.15, "Err band as fract of xht");

EXTERN STRING_VAR(exposure_pattern, ".exp",
                  "Exposure value follows this pattern in the image"
                  " filename. The name of the image files are expected"
                  " to be in the form [lang].[fontname].exp[num].tif");

EXTERN BOOL_VAR(learn_chars_and_char_frags_mode, FALSE,
                "Learn both character fragments (as is done in the"
                " special low exposure mode) as well as unfragmented"
                " characters.");

extern IMAGE page_image;

// The unicharset used during box training
static UNICHARSET unicharset_boxes;

/*************************************************************************
 * The code re-assigns outlines to form words each with ONE labelled blob.
 * Noise is left in UNLABELLED words. The chars on the page are checked crudely
 * for sensible position relative to baseline and xht. Failed boxes are
 * compensated for by duplicating other believable instances of the character.
 *
 * The box file is assumed to contain box definitions, one per line, of the
 * following format:
 *   <Char> <left> <bottom> <right> <top> ... arbitrary trailing fields unused
 *
 * The approach taken is to search the WHOLE page for stuff overlapping each box.
 *  - This is not too inefficient and is SAFE.
 *    - We can detect overlapping blobs as we will be attempting to put a blob
 *      from a LABELLED word into the current word.
 *    - When all the boxes have been processed we can detect any stuff which is
 *      being ignored - it is the unlabelled words left on the page.
 *
 * A box should only overlap one row.
 *
 * A warning is given if the box is on the same row as the previous box, but NOT
 * on the same row as the previous blob.
 *
 * Any OUTLINE which overlaps the box is put into the new word.
 *
 * ascender chars must ascend above xht significantly
 * xht chars must not rise above row xht significantly
 * bl chars must not descend below baseline significantly
 * descender chars must descend below baseline significantly
 *
 * ?? Certain chars are DROPPED - to limit the training data.
 *
 *************************************************************************/
namespace tesseract {
void Tesseract::apply_boxes(const STRING& fname,
                            BLOCK_LIST *block_list    //real blocks
                           ) {
  inT16 boxfile_lineno = 0;
  inT16 boxfile_charno = 0;
  TBOX box;                       //boxfile box
  UNICHAR_ID uch_id;             //correct ch from boxfile
  ROW *row;
  ROW *prev_row = NULL;
  inT16 prev_box_right = MAX_INT16;
  inT16 block_id;
  inT16 row_id;
  inT16 box_count = 0;
  inT16 box_failures = 0;
  inT16 labels_ok;
  inT16 rows_ok;
  inT16 bad_blobs;
  inT16 *tgt_char_counts = NULL; // No. of box samples
  inT16 i;
  inT16 rebalance_count = 0;
  UNICHAR_ID min_uch_id = INVALID_UNICHAR_ID;
  inT16 min_samples;
  inT16 final_labelled_blob_count;
  bool low_exposure = false;

  // Clean the unichar set
  unicharset_boxes.clear();
  // Space character needed to represent NIL classification
  unicharset_boxes.unichar_insert(" ");

  // Figure out whether this image file's exposure is less than 1, in which
  // case when learning we will only pay attention to character fragments.
  const char *ptr = strstr(imagefile.string(), exposure_pattern.string());
  if (ptr != NULL &&
      strtol(ptr += strlen(exposure_pattern.string()), NULL, 10) < 0) {
    low_exposure = true;
  }

  FILE* box_file;
  STRING filename = fname;
  const char *lastdot;           //of name

  lastdot = strrchr (filename.string (), '.');
  if (lastdot != NULL)
    filename[lastdot - filename.string()] = '\0';

  filename += ".box";
  if (!(box_file = fopen (filename.string(), "r"))) {
    CANTOPENFILE.error ("read_next_box", EXIT,
      "Cant open box file %s %d",
      filename.string(), errno);
  }

  tgt_char_counts = new inT16[MAX_NUM_CLASSES];
  for (i = 0; i < MAX_NUM_CLASSES; i++)
    tgt_char_counts[i] = 0;

  clear_any_old_text(block_list);
  while (read_next_box(applybox_page, box_file, &box, &uch_id)) {
    box_count++;
    if (!low_exposure || learn_chars_and_char_frags_mode) {
      tgt_char_counts[uch_id]++;
    }
    row = find_row_of_box (block_list, box, block_id, row_id);
    if (box.left () < prev_box_right) {
      boxfile_lineno++;
      boxfile_charno = 1;
    }
    else
      boxfile_charno++;

    if (row == NULL) {
      box_failures++;
      report_failed_box (boxfile_lineno, boxfile_charno, box,
                         unicharset_boxes.id_to_unichar(uch_id),
        "FAILURE! box overlaps no blobs or blobs in multiple rows");
    }
    else {
      if ((box.left () >= prev_box_right) && (row != prev_row))
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
          "WARNING! false row break");
      box_failures += resegment_box (row, box, uch_id, block_id, row_id,
        boxfile_lineno, boxfile_charno, tgt_char_counts, low_exposure, true);
      prev_row = row;
    }
    prev_box_right = box.right ();
  }
  tidy_up(block_list,
          labels_ok,
          rows_ok,
          bad_blobs,
          tgt_char_counts,
          rebalance_count,
          &min_uch_id,
          min_samples,
          final_labelled_blob_count,
          low_exposure,
          true);
  tprintf ("APPLY_BOXES:\n");
  tprintf ("   Boxes read from boxfile:  %6d\n", box_count);
  tprintf ("   Initially labelled blobs: %6d in %d rows\n",
    labels_ok, rows_ok);
  tprintf ("   Box failures detected:       %6d\n", box_failures);
  tprintf ("   Duped blobs for rebalance:%6d\n", rebalance_count);
  tprintf ("   \"%s\" has fewest samples:%6d\n",
           unicharset_boxes.id_to_unichar(min_uch_id), min_samples);
  tprintf ("                Total unlabelled words:   %6d\n",
    bad_blobs);
  tprintf ("                Final labelled words:     %6d\n",
    final_labelled_blob_count);

  // Clean up.
  delete[] tgt_char_counts;
}

int Tesseract::Boxes2BlockList(int box_cnt, TBOX *boxes,
                               BLOCK_LIST *block_list,
                               bool right2left) {
  inT16 boxfile_lineno = 0;
  inT16 boxfile_charno = 0;
  TBOX box;
  ROW *row;
  ROW *prev_row = NULL;
  inT16 prev_box_right = MAX_INT16;
  inT16 prev_box_left = 0;
  inT16 block_id;
  inT16 row_id;
  inT16 box_failures = 0;
  inT16 labels_ok;
  inT16 rows_ok;
  inT16 bad_blobs;
  inT16 rebalance_count = 0;
  UNICHAR_ID min_uch_id;
  inT16 min_samples;
  inT16 final_labelled_blob_count;

  clear_any_old_text(block_list);
  for (int box_idx = 0; box_idx < box_cnt; box_idx++) {
    box = boxes[box_idx];

    row = find_row_of_box(block_list, box, block_id, row_id);
    // check for a new row
    if ((right2left && box.right () > prev_box_left) ||
        (!right2left && box.left () < prev_box_right)) {
      boxfile_lineno++;
      boxfile_charno = 1;
    }
    else {
      boxfile_charno++;
    }

    if (row == NULL) {
      box_failures++;
    }
    else {
      box_failures += resegment_box(row, box, 0, block_id, row_id,
                                    boxfile_lineno, boxfile_charno,
                                    NULL, false, false);
      prev_row = row;
    }
    prev_box_right = box.right ();
    prev_box_left = box.left ();
  }

  tidy_up(block_list, labels_ok, rows_ok, bad_blobs, NULL,
          rebalance_count, &min_uch_id, min_samples, final_labelled_blob_count,
          false, false);

  return box_failures;
}

}  // namespace tesseract


void clear_any_old_text(                        //remove correct text
                        BLOCK_LIST *block_list  //real blocks
                       ) {
  BLOCK_IT block_it(block_list);
  ROW_IT row_it;
  WERD_IT word_it;

  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    row_it.set_to_list (block_it.data ()->row_list ());
    for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
      word_it.set_to_list (row_it.data ()->word_list ());
      for (word_it.mark_cycle_pt ();
      !word_it.cycled_list (); word_it.forward ()) {
        word_it.data ()->set_text ("");
      }
    }
  }
}

UNICHAR_ID register_char(const char *uch) {
  if (!unicharset_boxes.contains_unichar(uch)) {
    unicharset_boxes.unichar_insert(uch);
    if (unicharset_boxes.size() > MAX_NUM_CLASSES) {
      tprintf("Error: Size of unicharset of boxes is "
              "greater than MAX_NUM_CLASSES (%d)\n", MAX_NUM_CLASSES);
      exit(1);
    }
  }
  return unicharset_boxes.unichar_to_id(uch);
}

BOOL8 read_next_box(int page,
                    FILE* box_file,
                    TBOX *box,
                    UNICHAR_ID *uch_id) {
  int x_min;
  int y_min;
  int x_max;
  int y_max;
  char uch[kBoxReadBufSize];

  if (read_next_box(page, box_file, uch, &x_min, &y_min, &x_max, &y_max)) {
    *uch_id = register_char(uch);
    *box = TBOX (ICOORD (x_min, y_min), ICOORD (x_max, y_max));
    return TRUE;  // read a box ok
  } else {
    return FALSE;  // EOF
  }
}


ROW *find_row_of_box(                         //
                     BLOCK_LIST *block_list,  //real blocks
                     const TBOX &box,                 //from boxfile
                     inT16 &block_id,
                     inT16 &row_id_to_process) {
  BLOCK_IT block_it(block_list);
  BLOCK *block;
  ROW_IT row_it;
  ROW *row;
  ROW *row_to_process = NULL;
  inT16 row_id;
  WERD_IT word_it;
  WERD *word;
  BOOL8 polyg;
  PBLOB_IT blob_it;
  PBLOB *blob;
  OUTLINE_IT outline_it;
  OUTLINE *outline;

  /*
    Find row to process - error if box REALLY overlaps more than one row. (I.e
    it overlaps blobs in the row - not just overlaps the bounding box of the
    whole row.)
  */

  block_id = 0;
  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    block_id++;
    row_id = 0;
    block = block_it.data ();
    if (block->bounding_box ().overlap (box)) {
      row_it.set_to_list (block->row_list ());
      for (row_it.mark_cycle_pt ();
      !row_it.cycled_list (); row_it.forward ()) {
        row_id++;
        row = row_it.data ();
        if (row->bounding_box ().overlap (box)) {
          word_it.set_to_list (row->word_list ());
          for (word_it.mark_cycle_pt ();
          !word_it.cycled_list (); word_it.forward ()) {
            word = word_it.data ();
            polyg = word->flag (W_POLYGON);
            if (word->bounding_box ().overlap (box)) {
              blob_it.set_to_list (word->gblob_list ());
              for (blob_it.mark_cycle_pt ();
              !blob_it.cycled_list (); blob_it.forward ()) {
                blob = blob_it.data ();
                if (gblob_bounding_box (blob, polyg).
                overlap (box)) {
                  outline_it.
                    set_to_list (gblob_out_list
                    (blob, polyg));
                  for (outline_it.mark_cycle_pt ();
                    !outline_it.cycled_list ();
                  outline_it.forward ()) {
                    outline = outline_it.data ();
                    if (goutline_bounding_box
                    (outline, polyg).major_overlap (box)) {
                      if ((row_to_process == NULL) ||
                      (row_to_process == row)) {
                        row_to_process = row;
                        row_id_to_process = row_id;
                      }
                      else
                        /* RETURN ERROR Box overlaps blobs in more than one row  */
                        return NULL;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return row_to_process;
}


inT16 resegment_box(  //
                    ROW *row,
                    TBOX &box,
                    UNICHAR_ID uch_id,
                    inT16 block_id,
                    inT16 row_id,
                    inT16 boxfile_lineno,
                    inT16 boxfile_charno,
                    inT16 *tgt_char_counts,
                    bool learn_char_fragments,
                    bool learning) {
  WERD_LIST new_word_list;
  WERD_IT word_it;
  WERD_IT new_word_it(&new_word_list);
  WERD *word = NULL;
  WERD *new_word = NULL;
  BOOL8 polyg = false;
  PBLOB_IT blob_it;
  PBLOB_IT new_blob_it;
  PBLOB *blob;
  PBLOB *new_blob;
  OUTLINE_IT outline_it;
  OUTLINE_LIST dummy;  // Just to initialize new_outline_it.
  OUTLINE_IT new_outline_it = &dummy;
  OUTLINE *outline;
  TBOX new_word_box;
  TBOX curr_outline_box;
  TBOX prev_outline_box;
  float word_x_centre;
  float baseline;
  inT16 error_count = 0;         //number of chars lost
  STRING label;
  UNICHAR_ID fragment_uch_id;
  int fragment_index;
  int new_word_it_len;

  if (learning && applybox_debug > 6) {
    tprintf("\nAPPLY_BOX: in resegment_box() for %s(%d)\n",
            unicharset_boxes.id_to_unichar(uch_id), uch_id);
  }
  word_it.set_to_list (row->word_list ());
  for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
    word = word_it.data ();
    polyg = word->flag (W_POLYGON);
    if (word->bounding_box ().overlap (box)) {
      blob_it.set_to_list (word->gblob_list ());
      prev_outline_box = TBOX();  // clear prev_outline_box
      curr_outline_box = TBOX();  // clear curr_outline_box
      for (blob_it.mark_cycle_pt ();
      !blob_it.cycled_list (); blob_it.forward ()) {
        blob = blob_it.data ();
        if (gblob_bounding_box (blob, polyg).overlap (box)) {
          outline_it.set_to_list (gblob_out_list (blob, polyg));
          for (outline_it.mark_cycle_pt ();
          !outline_it.cycled_list (); outline_it.forward ()) {
            outline = outline_it.data ();
            prev_outline_box += curr_outline_box;
            curr_outline_box = goutline_bounding_box(outline, polyg);
            if (curr_outline_box.major_overlap (box)) {
              if (strlen (word->text ()) > 0) {
                if (error_count == 0) {
                  error_count = 1;
                  if (learning && applybox_debug > 4)
                    report_failed_box (boxfile_lineno,
                      boxfile_charno,
                      box, unicharset_boxes.id_to_unichar(uch_id),
                      "FAILURE! box overlaps blob in labelled word");
                }
                if (learning && applybox_debug > 4)
                  tprintf ("APPLY_BOXES: ALSO ignoring corrupted char"
                           " blk:%d row:%d \"%s\"\n",
                           block_id, row_id, word_it.data()->text());
                word_it.data ()->set_text ("");  // UN label it
                error_count++;
              }
              // Do not learn from fragments of characters that are broken
              // into very small pieces to avoid picking up noise.
              if ((learn_char_fragments || learn_chars_and_char_frags_mode) &&
                  ((C_OUTLINE *)outline)->area() < kMinFragmentOutlineArea) {
                if (applybox_debug > 6) {
                  tprintf("APPLY_BOX: fragment outline area %d is too small"
                          " - not recording fragments of this character\n",
                          ((C_OUTLINE *)outline)->area());
                }
                error_count++;
              }

              if (error_count == 0) {
                if (applybox_debug > 6 ) {
                  tprintf("APPLY_BOX: Previous ");
                  prev_outline_box.print();
                  tprintf("APPLY_BOX: Current area: %d ",
                          ((C_OUTLINE *)outline)->area());
                  curr_outline_box.print();
                }
                // When learning character fragments is enabled, we put
                // outlines that do not overlap on x axis in separate WERDs.
                bool start_new_word =
                    (learn_char_fragments || learn_chars_and_char_frags_mode) &&
                  !curr_outline_box.major_x_overlap(prev_outline_box);
                if (new_word == NULL || start_new_word) {
                  if (new_word != NULL) {  // add prev new_word to new_word_list
                    new_word_it.add_to_end(new_word);
                  }
                  // Make a new word with a single blob.
                  new_word = word->shallow_copy();
                  new_word->set_flag(W_FUZZY_NON, false);
                  new_word->set_flag(W_FUZZY_SP, false);
                  if (polyg){
                    new_blob = new PBLOB;
                  } else {
                    new_blob = (PBLOB *) new C_BLOB;
                  }
                  new_blob_it.set_to_list(new_word->gblob_list());
                  new_blob_it.add_to_end(new_blob);
                  new_outline_it.set_to_list(
                      gblob_out_list(new_blob, polyg));
                }
                new_outline_it.add_to_end(outline_it.extract());  // move blob
              }
            }
          }
          if (outline_it.empty())      // no outlines in blob
            delete blob_it.extract();  // so delete blob
        }
      }
      if (blob_it.empty())         // no blobs in word
        delete word_it.extract();  // so delete word
    }
  }
  if (new_word != NULL) {  // add prev new_word to new_word_list
    new_word_it.add_to_end(new_word);
  }
  new_word_it_len = new_word_it.length();

  // Check for failures.
  if (error_count > 0)
    return error_count;
  if (learning && new_word_it_len <= 0) {
    report_failed_box(boxfile_lineno, boxfile_charno, box,
                      unicharset_boxes.id_to_unichar(uch_id),
                      "FAILURE! Couldn't find any blobs");
    return 1;  // failure
  }

  if (learning && new_word_it_len > CHAR_FRAGMENT::kMaxChunks) {
    tprintf("APPLY_BOXES: too many fragments (%d) for char %s\n",
            new_word_it_len, unicharset_boxes.id_to_unichar(uch_id));
    return 1;  // failure
  }

  // Add labelled character or character fragments to the word list.
  fragment_index = 0;
  new_word_it.move_to_first();
  for (new_word_it.mark_cycle_pt(); !new_word_it.cycled_list();
       new_word_it.forward()) {
    new_word = new_word_it.extract();
    if (new_word_it_len > 1) {  // deal with a fragment
      if (learning) {
      label = CHAR_FRAGMENT::to_string(unicharset_boxes.id_to_unichar(uch_id),
                                       fragment_index, new_word_it_len);
      fragment_uch_id = register_char(label.string());
      new_word->set_text(label.string());
      ++fragment_index;
      // For now we cheat by setting the expected number of char fragments
      // to the number of char fragments actually parsed and labelled.
      // TODO(daria): find out whether this can be improved.
      tgt_char_counts[fragment_uch_id]++;
      } else {
        // No learning involved, Just stick a place-holder string
        new_word->set_text("*");
      }
      if (applybox_debug > 5) {
        tprintf("APPLY_BOX: adding char fragment %s\n", label.string());
      }
    } else {  // deal with a regular character
      if (learning) {
        if (!learn_char_fragments || learn_chars_and_char_frags_mode) {
        new_word->set_text(unicharset_boxes.id_to_unichar(uch_id));
        } else {
          // not interested in non-fragmented chars if learning fragments, so
          // unlabel it.
          new_word->set_text("");
        }
      } else {
        // No learning involved here. Just stick a place holder string
        new_word->set_text("*");
      }
    }
    gblob_sort_list(new_word->gblob_list(), polyg);
    word_it.add_to_end(new_word);
    new_word_box = new_word->bounding_box();
    word_x_centre = (new_word_box.left() + new_word_box.right()) / 2.0f;
    baseline = row->base_line(word_x_centre);
  }

  // All done. Now check if the EOL, BOL flags are set correctly.
  word_it.move_to_first();
  for (word_it.mark_cycle_pt(); !word_it.cycled_list(); word_it.forward()) {
    word = word_it.data();
    word->set_flag(W_BOL, false);
    word->set_flag(W_EOL, false);
  }
  word->set_flag(W_EOL, true);
  word_it.move_to_first();
  word_it.data()->set_flag(W_BOL, true);
  return 0;  //success

#if 0
    if (strlen(unicharset_boxes.id_to_unichar(uch_id)) == 1) {
      if (STRING (chs_caps_ht).contains (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          (new_word_box.top () <
           baseline + (1 + applybox_error_band) * row->x_height ())) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
                           "FAILURE! caps-ht char didn't ascend");
        new_word->set_text ("");
        return 1;
      }
      if (STRING (chs_odd_top).contains (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          (new_word_box.top () <
           baseline + (1 - applybox_error_band) * row->x_height ())) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
                           "FAILURE! Odd top char below xht");
        new_word->set_text ("");
        return 1;
      }
      if (STRING (chs_x_ht).contains (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          ((new_word_box.top () >
            baseline + (1 + applybox_error_band) * row->x_height ()) ||
           (new_word_box.top () <
            baseline + (1 - applybox_error_band) * row->x_height ()))) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
                           "FAILURE! x-ht char didn't have top near xht");
        new_word->set_text ("");
        return 1;
      }
      if (STRING (chs_non_ambig_bl).contains
          (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          ((new_word_box.bottom () <
            baseline - applybox_error_band * row->x_height ()) ||
           (new_word_box.bottom () >
            baseline + applybox_error_band * row->x_height ()))) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
                           "FAILURE! non ambig BL char didnt have bottom near baseline");
        new_word->set_text ("");
        return 1;
      }
      if (STRING (chs_odd_bot).contains (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          (new_word_box.bottom () >
           baseline + applybox_error_band * row->x_height ())) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
                           "FAILURE! Odd bottom char above baseline");
        new_word->set_text ("");
        return 1;
      }
      if (STRING (chs_desc).contains (unicharset_boxes.id_to_unichar(uch_id)[0]) &&
          (new_word_box.bottom () >
           baseline - applybox_error_band * row->x_height ())) {
        report_failed_box (boxfile_lineno, boxfile_charno, box,
                           unicharset_boxes.id_to_unichar(uch_id),
        "FAILURE! Descender doesn't descend");
        new_word->set_text ("");
        return 1;
      }
    }
#endif
}


/*************************************************************************
 * tidy_up()
 *   - report >1 block
 *   - sort the words in each row.
 *   - report any rows with no labelled words.
 *   - report any remaining unlabelled words
 *   - report total labelled words
 *
 *************************************************************************/
void tidy_up(                         //
             BLOCK_LIST *block_list,  //real blocks
             inT16 &ok_char_count,
             inT16 &ok_row_count,
             inT16 &unlabelled_words,
             inT16 *tgt_char_counts,
             inT16 &rebalance_count,
             UNICHAR_ID *min_uch_id,
             inT16 &min_samples,
             inT16 &final_labelled_blob_count,
             bool learn_character_fragments,
             bool learning) {
  BLOCK_IT block_it(block_list);
  ROW_IT row_it;
  ROW *row;
  WERD_IT word_it;
  WERD *word;
  WERD *duplicate_word;
  inT16 block_idx = 0;
  inT16 row_idx;
  inT16 all_row_idx = 0;
  BOOL8 row_ok;
  BOOL8 rebalance_needed = FALSE;
  inT16 *labelled_char_counts = NULL;  // num unique labelled samples
  inT16 i;
  UNICHAR_ID uch_id;
  UNICHAR_ID prev_uch_id = -1;
  BOOL8 at_dupe_of_prev_word;
  ROW *prev_row = NULL;
  inT16 left;
  inT16 prev_left = -1;

  labelled_char_counts = new inT16[MAX_NUM_CLASSES];
  for (i = 0; i < MAX_NUM_CLASSES; i++)
    labelled_char_counts[i] = 0;

  ok_char_count = 0;
  ok_row_count = 0;
  unlabelled_words = 0;
  if (learning && (applybox_debug > 4) && (block_it.length () != 1)) {
    if (block_it.length() > 1) {
    tprintf ("APPLY_BOXES: More than one block??\n");
    } else {
      tprintf("APPLY_BOXES: No blocks identified.\n");
    }
  }

  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    block_idx++;
    row_idx = 0;
    row_ok = FALSE;
    row_it.set_to_list (block_it.data ()->row_list ());
    for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
      row_idx++;
      all_row_idx++;
      row = row_it.data ();
      word_it.set_to_list (row->word_list ());
      word_it.sort (word_comparator);
      for (word_it.mark_cycle_pt ();
      !word_it.cycled_list (); word_it.forward ()) {
        word = word_it.data ();
        if (strlen (word->text ()) == 0 ||
            unicharset_boxes.unichar_to_id(word->text()) < 0) {
          unlabelled_words++;
          if (learning && applybox_debug > 4 && !learn_character_fragments) {
            tprintf ("APPLY_BOXES: Unlabelled word blk:%d row:%d allrows:%d\n",
                     block_idx, row_idx, all_row_idx);
          }
        } else {
          if (word->gblob_list ()->length () != 1)
            tprintf ("APPLY_BOXES: FATALITY - MULTIBLOB Labelled word blk:%d"
                     " row:%d allrows:%d\n", block_idx, row_idx, all_row_idx);

          ok_char_count++;
          ++labelled_char_counts[unicharset_boxes.unichar_to_id(word->text())];
          row_ok = TRUE;
        }
      }
      if ((applybox_debug > 6) && (!row_ok)) {
        tprintf("APPLY_BOXES: Row with no labelled words blk:%d row:%d"
                " allrows:%d\n", block_idx, row_idx, all_row_idx);
      }
      else
        ok_row_count++;
    }
  }

  min_samples = 9999;
  for (i = 0; i < unicharset_boxes.size(); i++) {
    if (tgt_char_counts[i] > labelled_char_counts[i]) {
      if (labelled_char_counts[i] <= 1) {
        tprintf("APPLY_BOXES: FATALITY - %d labelled samples of \"%s\" -"
                " target is %d:\n",
                labelled_char_counts[i], unicharset_boxes.debug_str(i).string(),
                tgt_char_counts[i]);
      }
      else {
        rebalance_needed = TRUE;
        if (applybox_debug > 0)
          tprintf("APPLY_BOXES: REBALANCE REQD \"%s\" - target of"
                  " %d from %d labelled samples\n",
                  unicharset_boxes.debug_str(i).string(), tgt_char_counts[i],
                  labelled_char_counts[i]);
      }
    }
    if ((min_samples > labelled_char_counts[i]) && (tgt_char_counts[i] > 0)) {
      min_samples = labelled_char_counts[i];
      *min_uch_id = i;
    }
  }

  while (applybox_rebalance && rebalance_needed) {
    block_it.set_to_list (block_list);
    for (block_it.mark_cycle_pt ();
    !block_it.cycled_list (); block_it.forward ()) {
      row_it.set_to_list (block_it.data ()->row_list ());
      for (row_it.mark_cycle_pt ();
      !row_it.cycled_list (); row_it.forward ()) {
        row = row_it.data ();
        word_it.set_to_list (row->word_list ());
        for (word_it.mark_cycle_pt ();
        !word_it.cycled_list (); word_it.forward ()) {
          word = word_it.data ();
          left = word->bounding_box ().left ();
          if (*word->text () != '\0')
            uch_id = unicharset_boxes.unichar_to_id(word->text ());
          else
            uch_id = -1;
          at_dupe_of_prev_word = ((row == prev_row) &&
            (left = prev_left) &&
            (uch_id == prev_uch_id));
          if ((uch_id != -1) &&
            (labelled_char_counts[uch_id] > 1) &&
            (tgt_char_counts[uch_id] > labelled_char_counts[uch_id]) &&
          (!at_dupe_of_prev_word)) {
            /* Duplicate the word to rebalance the labelled samples */
            if (applybox_debug > 9) {
              tprintf ("Duping \"%s\" from ", unicharset_boxes.id_to_unichar(uch_id));
              word->bounding_box ().print ();
            }
            duplicate_word = new WERD;
            *duplicate_word = *word;
            word_it.add_after_then_move (duplicate_word);
            rebalance_count++;
            labelled_char_counts[uch_id]++;
          }
          prev_row = row;
          prev_left = left;
          prev_uch_id = uch_id;
        }
      }
    }
    rebalance_needed = FALSE;
    for (i = 0; i < unicharset_boxes.size(); i++) {
      if ((tgt_char_counts[i] > labelled_char_counts[i]) &&
      (labelled_char_counts[i] > 1)) {
        rebalance_needed = TRUE;
        break;
      }
    }
  }

  /* Now final check - count labeled blobs */
  final_labelled_blob_count = 0;
  block_it.set_to_list (block_list);
  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    row_it.set_to_list (block_it.data ()->row_list ());
    for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
      row = row_it.data ();
      word_it.set_to_list (row->word_list ());
      word_it.sort (word_comparator);
      for (word_it.mark_cycle_pt ();
      !word_it.cycled_list (); word_it.forward ()) {
        word = word_it.data ();
        if ((strlen (word->text ()) > 0) &&
            (word->gblob_list()->length() == 1)) {
          final_labelled_blob_count++;
        } else {
          delete word_it.extract();
        }
      }
      // delete the row if empty
      if (row->word_list()->empty()) {
        delete row_it.extract();
    }
  }
}

  // Clean up.
  delete[] labelled_char_counts;
}


void report_failed_box(inT16 boxfile_lineno,
                       inT16 boxfile_charno,
                       TBOX box,
                       const char *box_ch,
                       const char *err_msg) {
  if (applybox_debug > 4)
    tprintf ("APPLY_BOXES: boxfile %1d/%1d/%s ((%1d,%1d),(%1d,%1d)): %s\n",
      boxfile_lineno,
      boxfile_charno,
      box_ch,
      box.left (), box.bottom (), box.right (), box.top (), err_msg);
}


void apply_box_training(const STRING& filename, BLOCK_LIST *block_list) {
  BLOCK_IT block_it(block_list);
  ROW_IT row_it;
  ROW *row;
  WERD_IT word_it;
  WERD *word;
  WERD *bln_word;
  WERD copy_outword;             // copy to denorm
  PBLOB_IT blob_it;
  DENORM denorm;
  inT16 count = 0;
  char unichar[UNICHAR_LEN + 1];

  unichar[UNICHAR_LEN] = '\0';
  tprintf ("Generating training data\n");
  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    row_it.set_to_list (block_it.data ()->row_list ());
    for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
      row = row_it.data ();
      word_it.set_to_list (row->word_list ());
      for (word_it.mark_cycle_pt ();
      !word_it.cycled_list (); word_it.forward ()) {
        word = word_it.data ();
        if ((strlen (word->text ()) > 0) &&
        (word->gblob_list ()->length () == 1)) {
          // Here is a word with a single unichar label and a single blob so train on it.
          bln_word = make_bln_copy(word, row, NULL, row->x_height (), &denorm);
          blob_it.set_to_list (bln_word->blob_list ());
          strncpy(unichar, word->text (), UNICHAR_LEN);
          tess_training_tester (filename,
            blob_it.data (),     //single blob
            &denorm, TRUE,       //correct
            unichar,             //correct character
            strlen(unichar),     //character length
            NULL);
          copy_outword = *(bln_word);
          copy_outword.baseline_denormalise (&denorm);
          blob_it.set_to_list (copy_outword.blob_list ());
          delete bln_word;
          count++;
        }
      }
    }
  }
  tprintf ("Generated training data for %d blobs\n", count);
}

namespace tesseract {
void Tesseract::apply_box_testing(BLOCK_LIST *block_list) {
  BLOCK_IT block_it(block_list);
  ROW_IT row_it;
  ROW *row;
  inT16 row_count = 0;
  WERD_IT word_it;
  WERD *word;
  WERD *bln_word;
  inT16 word_count = 0;
  PBLOB_IT blob_it;
  DENORM denorm;
  inT16 count = 0;
  char ch[2];
  WERD *outword;                 //bln best choice
  //segmentation
  WERD_CHOICE *best_choice;      //tess output
  WERD_CHOICE *raw_choice;       //top choice permuter
                                 //detailed results
  BLOB_CHOICE_LIST_CLIST blob_choices;
  inT16 char_count = 0;
  inT16 correct_count = 0;
  inT16 err_count = 0;
  inT16 rej_count = 0;
  #ifndef SECURE_NAMES
  WERDSTATS wordstats;           //As from newdiff
  #endif
  char tess_rej_str[3];
  char tess_long_str[3];

  ch[1] = '\0';
  strcpy (tess_rej_str, "|A");
  strcpy (tess_long_str, "|B");

  for (block_it.mark_cycle_pt ();
  !block_it.cycled_list (); block_it.forward ()) {
    row_it.set_to_list (block_it.data ()->row_list ());
    for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
      row = row_it.data ();
      row_count++;
      word_count = 0;
      word_it.set_to_list (row->word_list ());
      for (word_it.mark_cycle_pt ();
      !word_it.cycled_list (); word_it.forward ()) {
        word = word_it.data ();
        word_count++;
        if ((strlen (word->text ()) == 1) &&
          !STRING (applybox_test_exclusions).contains (*word->text ())
        && (word->gblob_list ()->length () == 1)) {
          // Here is a word with a single char label and a single blob so test it.
          bln_word = make_bln_copy(word, row, NULL, row->x_height (), &denorm);
          blob_it.set_to_list (bln_word->blob_list ());
          ch[0] = *word->text ();
          char_count++;
          best_choice = tess_segment_pass1 (bln_word,
            &denorm,
            &Tesseract::tess_default_matcher,
            raw_choice,
            &blob_choices, outword);

          /*
            Test for TESS screw up on word. Recog_word has already ensured that the
            choice list, outword blob lists and best_choice string are the same
            length. A TESS screw up is indicated by a blank filled or 0 length string.
          */
          if ((best_choice->length() == 0) ||
            (strspn(best_choice->unichar_string().string(), " ") ==
             best_choice->unichar_string().length())) {
            rej_count++;
            tprintf ("%d:%d: \"%s\" -> TESS FAILED\n",
              row_count, word_count, ch);
            #ifndef SECURE_NAMES
            wordstats.word (tess_rej_str, 2, ch, 1);
            #endif
          }
          else {
            if ((best_choice->length() != outword->blob_list()->length()) ||
                (best_choice->length() != blob_choices.length())) {
              tprintf
                ("ASSERT FAIL String:\"%s\"; Strlen=%d; #Blobs=%d; #Choices=%d\n",
                best_choice->unichar_string().string(),
                best_choice->length(),
                outword->blob_list ()->length(),
                blob_choices.length());
            }
            ASSERT_HOST(best_choice->length() ==
                        outword->blob_list()->length());
            ASSERT_HOST(best_choice->length() == blob_choices.length());
            fix_quotes (best_choice,
                                 //turn to double
              outword, &blob_choices);
            if (strcmp (best_choice->unichar_string().string(), ch) != 0) {
              err_count++;
              tprintf ("%d:%d: \"%s\" -> \"%s\"\n",
                row_count, word_count, ch,
                best_choice->unichar_string().string());
            }
            else
              correct_count++;
            #ifndef SECURE_NAMES
            if (best_choice->unichar_string().length() > 2)
              wordstats.word(tess_long_str, 2, ch, 1);
            else
              wordstats.word(best_choice->unichar_string().string(),
                             best_choice->unichar_string().length(),
                             ch, 1);
            #endif
          }
          delete bln_word;
          delete outword;
          delete best_choice;
          delete raw_choice;
          blob_choices.deep_clear ();
          count++;
        }
      }
    }
  }
  #ifndef SECURE_NAMES
  wordstats.print (1, 100.0);
  wordstats.conf_matrix ();
  tprintf ("Tested %d chars: %d correct; %d rejected by tess; %d errs\n",
    char_count, correct_count, rej_count, err_count);
  #endif
}

}  // namespace tesseract
