tesseract  5.0.0-alpha-619-ge9db
baseapi.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * File: baseapi.cpp
3  * Description: Simple API for calling tesseract.
4  * Author: Ray Smith
5  *
6  * (C) Copyright 2006, Google Inc.
7  ** Licensed under the Apache License, Version 2.0 (the "License");
8  ** you may not use this file except in compliance with the License.
9  ** You may obtain a copy of the License at
10  ** http://www.apache.org/licenses/LICENSE-2.0
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  *
17  **********************************************************************/
18 
19 #define _USE_MATH_DEFINES // for M_PI
20 
21 // Include automatically generated configuration file if running autoconf.
22 #ifdef HAVE_CONFIG_H
23 #include "config_auto.h"
24 #endif
25 
26 #include <tesseract/baseapi.h>
27 #ifdef __linux__
28 #include <csignal> // for sigaction, SA_RESETHAND, SIGBUS, SIGFPE
29 #endif
30 
31 #if defined(_WIN32)
32 #include <fcntl.h>
33 #include <io.h>
34 #else
35 #include <dirent.h> // for closedir, opendir, readdir, DIR, dirent
36 #include <libgen.h>
37 #include <sys/types.h>
38 #include <sys/stat.h> // for stat, S_IFDIR
39 #include <unistd.h>
40 #endif // _WIN32
41 
42 #include <cmath> // for round, M_PI
43 #include <cstdint> // for int32_t
44 #include <cstring> // for strcmp, strcpy
45 #include <fstream> // for size_t
46 #include <iostream> // for std::cin
47 #include <locale> // for std::locale::classic
48 #include <memory> // for std::unique_ptr
49 #include <set> // for std::pair
50 #include <sstream> // for std::stringstream
51 #include <vector> // for std::vector
52 #ifdef HAVE_LIBCURL
53 #include <curl/curl.h>
54 #endif
55 #include "allheaders.h" // for pixDestroy, boxCreate, boxaAddBox, box...
56 #ifndef DISABLED_LEGACY_ENGINE
57 #include "blobclass.h" // for ExtractFontName
58 #endif
59 #include "boxword.h" // for BoxWord
60 #include "config_auto.h" // for PACKAGE_VERSION
61 #include "coutln.h" // for C_OUTLINE_IT, C_OUTLINE_LIST
62 #include "dawg_cache.h" // for DawgCache
63 #include "dict.h" // for Dict
64 #include "edgblob.h" // for extract_edges
65 #include "elst.h" // for ELIST_ITERATOR, ELISTIZE, ELISTIZEH
66 #include "environ.h" // for l_uint8
67 #include "equationdetect.h" // for EquationDetect
68 #include "errcode.h" // for ASSERT_HOST
69 #include <tesseract/helpers.h> // for IntCastRounded, chomp_string
70 #include "imageio.h" // for IFF_TIFF_G4, IFF_TIFF, IFF_TIFF_G3, ...
71 #ifndef DISABLED_LEGACY_ENGINE
72 #include "intfx.h" // for INT_FX_RESULT_STRUCT
73 #endif
74 #include "mutableiterator.h" // for MutableIterator
75 #include "normalis.h" // for kBlnBaselineOffset, kBlnXHeight
76 #include <tesseract/ocrclass.h> // for ETEXT_DESC
77 #if defined(USE_OPENCL)
78 #include "openclwrapper.h" // for OpenclDevice
79 #endif
80 #include <tesseract/osdetect.h> // for OSResults, OSBestResult, OrientationId...
81 #include "pageres.h" // for PAGE_RES_IT, WERD_RES, PAGE_RES, CR_DE...
82 #include "paragraphs.h" // for DetectParagraphs
83 #include "params.h" // for BoolParam, IntParam, DoubleParam, Stri...
84 #include "pdblock.h" // for PDBLK
85 #include "points.h" // for FCOORD
86 #include "polyblk.h" // for POLY_BLOCK
87 #include "rect.h" // for TBOX
88 #include <tesseract/renderer.h> // for TessResultRenderer
89 #include <tesseract/resultiterator.h> // for ResultIterator
90 #include "stepblob.h" // for C_BLOB_IT, C_BLOB, C_BLOB_LIST
91 #include <tesseract/strngs.h> // for STRING
92 #include "tessdatamanager.h" // for TessdataManager, kTrainedDataSuffix
93 #include "tesseractclass.h" // for Tesseract
94 #include <tesseract/thresholder.h> // for ImageThresholder
95 #include "tprintf.h" // for tprintf
96 #include "werd.h" // for WERD, WERD_IT, W_FUZZY_NON, W_FUZZY_SP
97 
98 static BOOL_VAR(stream_filelist, false, "Stream a filelist from stdin");
99 static STRING_VAR(document_title, "", "Title of output document (used for hOCR and PDF output)");
100 
101 namespace tesseract {
102 
104 const int kMinRectSize = 10;
106 const char kTesseractReject = '~';
108 const char kUNLVReject = '~';
110 const char kUNLVSuspect = '^';
115 static const char* kInputFile = "noname.tif";
119 static const char* kOldVarsFile = "failed_vars.txt";
121 const int kMaxIntSize = 22;
122 
123 /* Add all available languages recursively.
124 */
125 static void addAvailableLanguages(const STRING &datadir, const STRING &base,
126  GenericVector<STRING>* langs)
127 {
128  const STRING base2 = (base.c_str()[0] == '\0') ? base : base + "/";
129  const size_t extlen = sizeof(kTrainedDataSuffix);
130 #ifdef _WIN32
131  WIN32_FIND_DATA data;
132  HANDLE handle = FindFirstFile((datadir + base2 + "*").c_str(), &data);
133  if (handle != INVALID_HANDLE_VALUE) {
134  BOOL result = TRUE;
135  for (; result;) {
136  char *name = data.cFileName;
137  // Skip '.', '..', and hidden files
138  if (name[0] != '.') {
139  if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
140  FILE_ATTRIBUTE_DIRECTORY) {
141  addAvailableLanguages(datadir, base2 + name, langs);
142  } else {
143  size_t len = strlen(name);
144  if (len > extlen && name[len - extlen] == '.' &&
145  strcmp(&name[len - extlen + 1], kTrainedDataSuffix) == 0) {
146  name[len - extlen] = '\0';
147  langs->push_back(base2 + name);
148  }
149  }
150  }
151  result = FindNextFile(handle, &data);
152  }
153  FindClose(handle);
154  }
155 #else // _WIN32
156  DIR* dir = opendir((datadir + base).c_str());
157  if (dir != nullptr) {
158  dirent *de;
159  while ((de = readdir(dir))) {
160  char *name = de->d_name;
161  // Skip '.', '..', and hidden files
162  if (name[0] != '.') {
163  struct stat st;
164  if (stat((datadir + base2 + name).c_str(), &st) == 0 &&
165  (st.st_mode & S_IFDIR) == S_IFDIR) {
166  addAvailableLanguages(datadir, base2 + name, langs);
167  } else {
168  size_t len = strlen(name);
169  if (len > extlen && name[len - extlen] == '.' &&
170  strcmp(&name[len - extlen + 1], kTrainedDataSuffix) == 0) {
171  name[len - extlen] = '\0';
172  langs->push_back(base2 + name);
173  }
174  }
175  }
176  }
177  closedir(dir);
178  }
179 #endif
180 }
181 
182 // Compare two STRING values (used for sorting).
183 static int CompareSTRING(const void* p1, const void* p2) {
184  const auto* s1 = static_cast<const STRING*>(p1);
185  const auto* s2 = static_cast<const STRING*>(p2);
186  return strcmp(s1->c_str(), s2->c_str());
187 }
188 
190  : tesseract_(nullptr),
191  osd_tesseract_(nullptr),
192  equ_detect_(nullptr),
193  reader_(nullptr),
194  // Thresholder is initialized to nullptr here, but will be set before use by:
195  // A constructor of a derived API, SetThresholder(), or
196  // created implicitly when used in InternalSetImage.
197  thresholder_(nullptr),
198  paragraph_models_(nullptr),
199  block_list_(nullptr),
200  page_res_(nullptr),
201  input_file_(nullptr),
202  output_file_(nullptr),
203  datapath_(nullptr),
204  language_(nullptr),
205  last_oem_requested_(OEM_DEFAULT),
206  recognition_done_(false),
207  truth_cb_(nullptr),
208  rect_left_(0),
209  rect_top_(0),
210  rect_width_(0),
211  rect_height_(0),
212  image_width_(0),
213  image_height_(0) {
214 #if defined(DEBUG)
215  // The Tesseract executables would use the "C" locale by default,
216  // but other software which is linked against the Tesseract library
217  // typically uses the locale from the user's environment.
218  // Here the default is overridden to allow debugging of potential
219  // problems caused by the locale settings.
220 
221  // Use the current locale if building debug code.
222  std::locale::global(std::locale(""));
223 #endif
224 }
225 
227  End();
228 }
229 
233 const char* TessBaseAPI::Version() {
234  return PACKAGE_VERSION;
235 }
236 
244 size_t TessBaseAPI::getOpenCLDevice(void **data) {
245 #ifdef USE_OPENCL
246  ds_device device = OpenclDevice::getDeviceSelection();
247  if (device.type == DS_DEVICE_OPENCL_DEVICE) {
248  *data = new cl_device_id;
249  memcpy(*data, &device.oclDeviceID, sizeof(cl_device_id));
250  return sizeof(cl_device_id);
251  }
252 #endif
253 
254  *data = nullptr;
255  return 0;
256 }
257 
262 void TessBaseAPI::SetInputName(const char* name) {
263  if (input_file_ == nullptr)
264  input_file_ = new STRING(name);
265  else
266  *input_file_ = name;
267 }
268 
270 void TessBaseAPI::SetOutputName(const char* name) {
271  if (output_file_ == nullptr)
272  output_file_ = new STRING(name);
273  else
274  *output_file_ = name;
275 }
276 
277 bool TessBaseAPI::SetVariable(const char* name, const char* value) {
278  if (tesseract_ == nullptr) tesseract_ = new Tesseract;
280  tesseract_->params());
281 }
282 
283 bool TessBaseAPI::SetDebugVariable(const char* name, const char* value) {
284  if (tesseract_ == nullptr) tesseract_ = new Tesseract;
286  tesseract_->params());
287 }
288 
289 bool TessBaseAPI::GetIntVariable(const char *name, int *value) const {
290  auto *p = ParamUtils::FindParam<IntParam>(
291  name, GlobalParams()->int_params, tesseract_->params()->int_params);
292  if (p == nullptr) return false;
293  *value = (int32_t)(*p);
294  return true;
295 }
296 
297 bool TessBaseAPI::GetBoolVariable(const char *name, bool *value) const {
298  auto *p = ParamUtils::FindParam<BoolParam>(
299  name, GlobalParams()->bool_params, tesseract_->params()->bool_params);
300  if (p == nullptr) return false;
301  *value = bool(*p);
302  return true;
303 }
304 
305 const char *TessBaseAPI::GetStringVariable(const char *name) const {
306  auto *p = ParamUtils::FindParam<StringParam>(
307  name, GlobalParams()->string_params, tesseract_->params()->string_params);
308  return (p != nullptr) ? p->c_str() : nullptr;
309 }
310 
311 bool TessBaseAPI::GetDoubleVariable(const char *name, double *value) const {
312  auto *p = ParamUtils::FindParam<DoubleParam>(
313  name, GlobalParams()->double_params, tesseract_->params()->double_params);
314  if (p == nullptr) return false;
315  *value = (double)(*p);
316  return true;
317 }
318 
320 bool TessBaseAPI::GetVariableAsString(const char *name, STRING *val) {
321  return ParamUtils::GetParamAsString(name, tesseract_->params(), val);
322 }
323 
325 void TessBaseAPI::PrintVariables(FILE *fp) const {
327 }
328 
337 int TessBaseAPI::Init(const char* datapath, const char* language,
338  OcrEngineMode oem, char **configs, int configs_size,
339  const GenericVector<STRING> *vars_vec,
340  const GenericVector<STRING> *vars_values,
341  bool set_only_non_debug_params) {
342  return Init(datapath, 0, language, oem, configs, configs_size, vars_vec,
343  vars_values, set_only_non_debug_params, nullptr);
344 }
345 
346 // In-memory version reads the traineddata file directly from the given
347 // data[data_size] array. Also implements the version with a datapath in data,
348 // flagged by data_size = 0.
349 int TessBaseAPI::Init(const char* data, int data_size, const char* language,
350  OcrEngineMode oem, char** configs, int configs_size,
351  const GenericVector<STRING>* vars_vec,
352  const GenericVector<STRING>* vars_values,
353  bool set_only_non_debug_params, FileReader reader) {
354  // Default language is "eng".
355  if (language == nullptr) language = "eng";
356  STRING datapath = data_size == 0 ? data : language;
357  // If the datapath, OcrEngineMode or the language have changed - start again.
358  // Note that the language_ field stores the last requested language that was
359  // initialized successfully, while tesseract_->lang stores the language
360  // actually used. They differ only if the requested language was nullptr, in
361  // which case tesseract_->lang is set to the Tesseract default ("eng").
362  if (tesseract_ != nullptr &&
363  (datapath_ == nullptr || language_ == nullptr || *datapath_ != datapath ||
365  (*language_ != language && tesseract_->lang != language))) {
366  delete tesseract_;
367  tesseract_ = nullptr;
368  }
369 #ifdef USE_OPENCL
370  OpenclDevice od;
371  od.InitEnv();
372 #endif
373  bool reset_classifier = true;
374  if (tesseract_ == nullptr) {
375  reset_classifier = false;
376  tesseract_ = new Tesseract;
377  if (reader != nullptr) reader_ = reader;
379  if (data_size != 0) {
380  mgr.LoadMemBuffer(language, data, data_size);
381  }
383  datapath.c_str(),
384  output_file_ != nullptr ? output_file_->c_str() : nullptr,
385  language, oem, configs, configs_size, vars_vec, vars_values,
386  set_only_non_debug_params, &mgr) != 0) {
387  return -1;
388  }
389  }
390 
391  // Update datapath and language requested for the last valid initialization.
392  if (datapath_ == nullptr)
393  datapath_ = new STRING(datapath);
394  else
395  *datapath_ = datapath;
396  if ((strcmp(datapath_->c_str(), "") == 0) &&
397  (strcmp(tesseract_->datadir.c_str(), "") != 0))
399 
400  if (language_ == nullptr)
401  language_ = new STRING(language);
402  else
403  *language_ = language;
405 
406 #ifndef DISABLED_LEGACY_ENGINE
407  // For same language and datapath, just reset the adaptive classifier.
408  if (reset_classifier) {
410  }
411 #endif // ndef DISABLED_LEGACY_ENGINE
412  return 0;
413 }
414 
424  return (language_ == nullptr || language_->c_str() == nullptr) ?
425  "" : language_->c_str();
426 }
427 
434  GenericVector<STRING>* langs) const {
435  langs->clear();
436  if (tesseract_ != nullptr) {
437  langs->push_back(tesseract_->lang);
438  int num_subs = tesseract_->num_sub_langs();
439  for (int i = 0; i < num_subs; ++i)
440  langs->push_back(tesseract_->get_sub_lang(i)->lang);
441  }
442 }
443 
448  GenericVector<STRING>* langs) const {
449  langs->clear();
450  if (tesseract_ != nullptr) {
451  addAvailableLanguages(tesseract_->datadir, "", langs);
452  langs->sort(CompareSTRING);
453  }
454 }
455 
456 //TODO(amit): Adapt to lstm
457 #ifndef DISABLED_LEGACY_ENGINE
458 
464 int TessBaseAPI::InitLangMod(const char* datapath, const char* language) {
465  if (tesseract_ == nullptr)
466  tesseract_ = new Tesseract;
467  else
469  TessdataManager mgr;
470  return tesseract_->init_tesseract_lm(datapath, nullptr, language, &mgr);
471 }
472 #endif // ndef DISABLED_LEGACY_ENGINE
473 
479  if (tesseract_ == nullptr) {
480  tesseract_ = new Tesseract;
481  #ifndef DISABLED_LEGACY_ENGINE
483  #endif
484  }
485 }
486 
492 void TessBaseAPI::ReadConfigFile(const char* filename) {
494 }
495 
497 void TessBaseAPI::ReadDebugConfigFile(const char* filename) {
499 }
500 
507  if (tesseract_ == nullptr)
508  tesseract_ = new Tesseract;
509  tesseract_->tessedit_pageseg_mode.set_value(mode);
510 }
511 
514  if (tesseract_ == nullptr)
515  return PSM_SINGLE_BLOCK;
516  return static_cast<PageSegMode>(
517  static_cast<int>(tesseract_->tessedit_pageseg_mode));
518 }
519 
533 char* TessBaseAPI::TesseractRect(const unsigned char* imagedata,
534  int bytes_per_pixel,
535  int bytes_per_line,
536  int left, int top,
537  int width, int height) {
538  if (tesseract_ == nullptr || width < kMinRectSize || height < kMinRectSize)
539  return nullptr; // Nothing worth doing.
540 
541  // Since this original api didn't give the exact size of the image,
542  // we have to invent a reasonable value.
543  int bits_per_pixel = bytes_per_pixel == 0 ? 1 : bytes_per_pixel * 8;
544  SetImage(imagedata, bytes_per_line * 8 / bits_per_pixel, height + top,
545  bytes_per_pixel, bytes_per_line);
546  SetRectangle(left, top, width, height);
547 
548  return GetUTF8Text();
549 }
550 
551 #ifndef DISABLED_LEGACY_ENGINE
552 
557  if (tesseract_ == nullptr)
558  return;
561 }
562 #endif // ndef DISABLED_LEGACY_ENGINE
563 
571 void TessBaseAPI::SetImage(const unsigned char* imagedata,
572  int width, int height,
573  int bytes_per_pixel, int bytes_per_line) {
574  if (InternalSetImage()) {
575  thresholder_->SetImage(imagedata, width, height,
576  bytes_per_pixel, bytes_per_line);
578  }
579 }
580 
582  if (thresholder_)
584  else
585  tprintf("Please call SetImage before SetSourceResolution.\n");
586 }
587 
596 void TessBaseAPI::SetImage(Pix* pix) {
597  if (InternalSetImage()) {
598  if (pixGetSpp(pix) == 4 && pixGetInputFormat(pix) == IFF_PNG) {
599  // remove alpha channel from png
600  Pix* p1 = pixRemoveAlpha(pix);
601  pixSetSpp(p1, 3);
602  (void)pixCopy(pix, p1);
603  pixDestroy(&p1);
604  }
605  thresholder_->SetImage(pix);
607  }
608 }
609 
615 void TessBaseAPI::SetRectangle(int left, int top, int width, int height) {
616  if (thresholder_ == nullptr)
617  return;
618  thresholder_->SetRectangle(left, top, width, height);
619  ClearResults();
620 }
621 
627  if (tesseract_ == nullptr || thresholder_ == nullptr) return nullptr;
628  if (tesseract_->pix_binary() == nullptr &&
630  return nullptr;
631  }
632  return pixClone(tesseract_->pix_binary());
633 }
634 
640 Boxa* TessBaseAPI::GetRegions(Pixa** pixa) {
641  return GetComponentImages(RIL_BLOCK, false, pixa, nullptr);
642 }
643 
652 Boxa* TessBaseAPI::GetTextlines(const bool raw_image, const int raw_padding,
653  Pixa** pixa, int** blockids, int** paraids) {
654  return GetComponentImages(RIL_TEXTLINE, true, raw_image, raw_padding,
655  pixa, blockids, paraids);
656 }
657 
666 Boxa* TessBaseAPI::GetStrips(Pixa** pixa, int** blockids) {
667  return GetComponentImages(RIL_TEXTLINE, false, pixa, blockids);
668 }
669 
675 Boxa* TessBaseAPI::GetWords(Pixa** pixa) {
676  return GetComponentImages(RIL_WORD, true, pixa, nullptr);
677 }
678 
686  return GetComponentImages(RIL_SYMBOL, true, pixa, nullptr);
687 }
688 
698  bool text_only, bool raw_image,
699  const int raw_padding,
700  Pixa** pixa, int** blockids,
701  int** paraids) {
702  PageIterator* page_it = GetIterator();
703  if (page_it == nullptr)
704  page_it = AnalyseLayout();
705  if (page_it == nullptr)
706  return nullptr; // Failed.
707 
708  // Count the components to get a size for the arrays.
709  int component_count = 0;
710  int left, top, right, bottom;
711 
712  if (raw_image) {
713  // Get bounding box in original raw image with padding.
714  do {
715  if (page_it->BoundingBox(level, raw_padding,
716  &left, &top, &right, &bottom) &&
717  (!text_only || PTIsTextType(page_it->BlockType())))
718  ++component_count;
719  } while (page_it->Next(level));
720  } else {
721  // Get bounding box from binarized imaged. Note that this could be
722  // differently scaled from the original image.
723  do {
724  if (page_it->BoundingBoxInternal(level, &left, &top, &right, &bottom) &&
725  (!text_only || PTIsTextType(page_it->BlockType())))
726  ++component_count;
727  } while (page_it->Next(level));
728  }
729 
730  Boxa* boxa = boxaCreate(component_count);
731  if (pixa != nullptr)
732  *pixa = pixaCreate(component_count);
733  if (blockids != nullptr)
734  *blockids = new int[component_count];
735  if (paraids != nullptr)
736  *paraids = new int[component_count];
737 
738  int blockid = 0;
739  int paraid = 0;
740  int component_index = 0;
741  page_it->Begin();
742  do {
743  bool got_bounding_box;
744  if (raw_image) {
745  got_bounding_box =
746  page_it->BoundingBox(level, raw_padding, &left, &top, &right, &bottom);
747  } else {
748  got_bounding_box =
749  page_it->BoundingBoxInternal(level, &left, &top, &right, &bottom);
750  }
751  if (got_bounding_box &&
752  (!text_only || PTIsTextType(page_it->BlockType()))) {
753  Box* lbox = boxCreate(left, top, right - left, bottom - top);
754  boxaAddBox(boxa, lbox, L_INSERT);
755  if (pixa != nullptr) {
756  Pix* pix = nullptr;
757  if (raw_image) {
758  pix = page_it->GetImage(level, raw_padding, GetInputImage(), &left,
759  &top);
760  } else {
761  pix = page_it->GetBinaryImage(level);
762  }
763  pixaAddPix(*pixa, pix, L_INSERT);
764  pixaAddBox(*pixa, lbox, L_CLONE);
765  }
766  if (paraids != nullptr) {
767  (*paraids)[component_index] = paraid;
768  if (page_it->IsAtFinalElement(RIL_PARA, level))
769  ++paraid;
770  }
771  if (blockids != nullptr) {
772  (*blockids)[component_index] = blockid;
773  if (page_it->IsAtFinalElement(RIL_BLOCK, level)) {
774  ++blockid;
775  paraid = 0;
776  }
777  }
778  ++component_index;
779  }
780  } while (page_it->Next(level));
781  delete page_it;
782  return boxa;
783 }
784 
786  if (thresholder_ == nullptr) {
787  return 0;
788  }
789  return thresholder_->GetScaleFactor();
790 }
791 
808 
809 PageIterator* TessBaseAPI::AnalyseLayout(bool merge_similar_words) {
810  if (FindLines() == 0) {
811  if (block_list_->empty())
812  return nullptr; // The page was empty.
813  page_res_ = new PAGE_RES(merge_similar_words, block_list_, nullptr);
814  DetectParagraphs(false);
815  return new PageIterator(
819  }
820  return nullptr;
821 }
822 
828  if (tesseract_ == nullptr)
829  return -1;
830  if (FindLines() != 0)
831  return -1;
832  delete page_res_;
833  if (block_list_->empty()) {
834  page_res_ = new PAGE_RES(false, block_list_,
836  return 0; // Empty page.
837  }
838 
840  recognition_done_ = true;
841 #ifndef DISABLED_LEGACY_ENGINE
846  } else
847 #endif // ndef DISABLED_LEGACY_ENGINE
848  {
851  }
852 
853  if (page_res_ == nullptr) {
854  return -1;
855  }
856 
859  return -1;
860  }
862  return 0;
863  }
864 #ifndef DISABLED_LEGACY_ENGINE
867  return 0;
868  }
869 #endif // ndef DISABLED_LEGACY_ENGINE
870 
871  if (truth_cb_ != nullptr) {
872  tesseract_->wordrec_run_blamer.set_value(true);
873  auto *page_it = new PageIterator(
878  image_height_, page_it, this->tesseract()->pix_grey());
879  delete page_it;
880  }
881 
882  int result = 0;
884  #ifndef GRAPHICS_DISABLED
886  #endif // GRAPHICS_DISABLED
887  // The page_res is invalid after an interactive session, so cleanup
888  // in a way that lets us continue to the next page without crashing.
889  delete page_res_;
890  page_res_ = nullptr;
891  return -1;
892  #ifndef DISABLED_LEGACY_ENGINE
894  STRING fontname;
895  ExtractFontName(*output_file_, &fontname);
897  } else if (tesseract_->tessedit_ambigs_training) {
898  FILE *training_output_file = tesseract_->init_recog_training(*input_file_);
899  // OCR the page segmented into words by tesseract.
901  *input_file_, page_res_, monitor, training_output_file);
902  fclose(training_output_file);
903  #endif // ndef DISABLED_LEGACY_ENGINE
904  } else {
905  // Now run the main recognition.
906  bool wait_for_text = true;
907  GetBoolVariable("paragraph_text_based", &wait_for_text);
908  if (!wait_for_text) DetectParagraphs(false);
909  if (tesseract_->recog_all_words(page_res_, monitor, nullptr, nullptr, 0)) {
910  if (wait_for_text) DetectParagraphs(true);
911  } else {
912  result = -1;
913  }
914  }
915  return result;
916 }
917 
918 #ifndef DISABLED_LEGACY_ENGINE
919 
921  if (tesseract_ == nullptr)
922  return -1;
923  if (thresholder_ == nullptr || thresholder_->IsEmpty()) {
924  tprintf("Please call SetImage before attempting recognition.\n");
925  return -1;
926  }
927  if (page_res_ != nullptr)
928  ClearResults();
929  if (FindLines() != 0)
930  return -1;
931  // Additional conditions under which chopper test cannot be run
932  if (tesseract_->interactive_display_mode) return -1;
933 
934  recognition_done_ = true;
935 
936  page_res_ = new PAGE_RES(false, block_list_,
938 
939  PAGE_RES_IT page_res_it(page_res_);
940 
941  while (page_res_it.word() != nullptr) {
942  WERD_RES *word_res = page_res_it.word();
943  GenericVector<TBOX> boxes;
944  tesseract_->MaximallyChopWord(boxes, page_res_it.block()->block,
945  page_res_it.row()->row, word_res);
946  page_res_it.forward();
947  }
948  return 0;
949 }
950 #endif // ndef DISABLED_LEGACY_ENGINE
951 
952 // Takes ownership of the input pix.
954 
956 
958  if (input_file_)
959  return input_file_->c_str();
960  return nullptr;
961 }
962 
963 const char * TessBaseAPI::GetDatapath() {
964  return tesseract_->datadir.c_str();
965 }
966 
969 }
970 
971 // If flist exists, get data from there. Otherwise get data from buf.
972 // Seems convoluted, but is the easiest way I know of to meet multiple
973 // goals. Support streaming from stdin, and also work on platforms
974 // lacking fmemopen.
975 bool TessBaseAPI::ProcessPagesFileList(FILE *flist,
976  STRING *buf,
977  const char* retry_config,
978  int timeout_millisec,
979  TessResultRenderer* renderer,
980  int tessedit_page_number) {
981  if (!flist && !buf) return false;
982  int page = (tessedit_page_number >= 0) ? tessedit_page_number : 0;
983  char pagename[MAX_PATH];
984 
985  GenericVector<STRING> lines;
986  if (!flist) {
987  buf->split('\n', &lines);
988  if (lines.empty()) return false;
989  }
990 
991  // Skip to the requested page number.
992  for (int i = 0; i < page; i++) {
993  if (flist) {
994  if (fgets(pagename, sizeof(pagename), flist) == nullptr) break;
995  }
996  }
997 
998  // Begin producing output
999  if (renderer && !renderer->BeginDocument(document_title.c_str())) {
1000  return false;
1001  }
1002 
1003  // Loop over all pages - or just the requested one
1004  while (true) {
1005  if (flist) {
1006  if (fgets(pagename, sizeof(pagename), flist) == nullptr) break;
1007  } else {
1008  if (page >= lines.size()) break;
1009  snprintf(pagename, sizeof(pagename), "%s", lines[page].c_str());
1010  }
1011  chomp_string(pagename);
1012  Pix *pix = pixRead(pagename);
1013  if (pix == nullptr) {
1014  tprintf("Image file %s cannot be read!\n", pagename);
1015  return false;
1016  }
1017  tprintf("Page %d : %s\n", page, pagename);
1018  bool r = ProcessPage(pix, page, pagename, retry_config,
1019  timeout_millisec, renderer);
1020  pixDestroy(&pix);
1021  if (!r) return false;
1022  if (tessedit_page_number >= 0) break;
1023  ++page;
1024  }
1025 
1026  // Finish producing output
1027  if (renderer && !renderer->EndDocument()) {
1028  return false;
1029  }
1030  return true;
1031 }
1032 
1033 bool TessBaseAPI::ProcessPagesMultipageTiff(const l_uint8 *data,
1034  size_t size,
1035  const char* filename,
1036  const char* retry_config,
1037  int timeout_millisec,
1038  TessResultRenderer* renderer,
1039  int tessedit_page_number) {
1040 #ifndef ANDROID_BUILD
1041  Pix *pix = nullptr;
1042  int page = (tessedit_page_number >= 0) ? tessedit_page_number : 0;
1043  size_t offset = 0;
1044  for (; ; ++page) {
1045  if (tessedit_page_number >= 0) {
1046  page = tessedit_page_number;
1047  pix = (data) ? pixReadMemTiff(data, size, page)
1048  : pixReadTiff(filename, page);
1049  } else {
1050  pix = (data) ? pixReadMemFromMultipageTiff(data, size, &offset)
1051  : pixReadFromMultipageTiff(filename, &offset);
1052  }
1053  if (pix == nullptr) break;
1054  tprintf("Page %d\n", page + 1);
1055  char page_str[kMaxIntSize];
1056  snprintf(page_str, kMaxIntSize - 1, "%d", page);
1057  SetVariable("applybox_page", page_str);
1058  bool r = ProcessPage(pix, page, filename, retry_config,
1059  timeout_millisec, renderer);
1060  pixDestroy(&pix);
1061  if (!r) return false;
1062  if (tessedit_page_number >= 0) break;
1063  if (!offset) break;
1064  }
1065  return true;
1066 #else
1067  return false;
1068 #endif
1069 }
1070 
1071 // Master ProcessPages calls ProcessPagesInternal and then does any post-
1072 // processing required due to being in a training mode.
1073 bool TessBaseAPI::ProcessPages(const char* filename, const char* retry_config,
1074  int timeout_millisec,
1075  TessResultRenderer* renderer) {
1076  bool result =
1077  ProcessPagesInternal(filename, retry_config, timeout_millisec, renderer);
1078  #ifndef DISABLED_LEGACY_ENGINE
1079  if (result) {
1082  tprintf("Write of TR file failed: %s\n", output_file_->c_str());
1083  return false;
1084  }
1085  }
1086  #endif // ndef DISABLED_LEGACY_ENGINE
1087  return result;
1088 }
1089 
1090 static size_t
1091 WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
1092 {
1093  size = size * nmemb;
1094  std::string* buf = reinterpret_cast<std::string*>(userp);
1095  buf->append(reinterpret_cast<const char*>(contents), size);
1096  return size;
1097 }
1098 
1099 // In the ideal scenario, Tesseract will start working on data as soon
1100 // as it can. For example, if you stream a filelist through stdin, we
1101 // should start the OCR process as soon as the first filename is
1102 // available. This is particularly useful when hooking Tesseract up to
1103 // slow hardware such as a book scanning machine.
1104 //
1105 // Unfortunately there are tradeoffs. You can't seek on stdin. That
1106 // makes automatic detection of datatype (TIFF? filelist? PNG?)
1107 // impractical. So we support a command line flag to explicitly
1108 // identify the scenario that really matters: filelists on
1109 // stdin. We'll still do our best if the user likes pipes.
1110 bool TessBaseAPI::ProcessPagesInternal(const char* filename,
1111  const char* retry_config,
1112  int timeout_millisec,
1113  TessResultRenderer* renderer) {
1114  bool stdInput = !strcmp(filename, "stdin") || !strcmp(filename, "-");
1115  if (stdInput) {
1116 #ifdef WIN32
1117  if (_setmode(_fileno(stdin), _O_BINARY) == -1)
1118  tprintf("ERROR: cin to binary: %s", strerror(errno));
1119 #endif // WIN32
1120  }
1121 
1122  if (stream_filelist) {
1123  return ProcessPagesFileList(stdin, nullptr, retry_config,
1124  timeout_millisec, renderer,
1126  }
1127 
1128  // At this point we are officially in autodection territory.
1129  // That means any data in stdin must be buffered, to make it
1130  // seekable.
1131  std::string buf;
1132  const l_uint8 *data = nullptr;
1133  if (stdInput) {
1134  buf.assign((std::istreambuf_iterator<char>(std::cin)),
1135  (std::istreambuf_iterator<char>()));
1136  data = reinterpret_cast<const l_uint8 *>(buf.data());
1137  } else if (strncmp(filename, "http:", 5) == 0 ||
1138  strncmp(filename, "https:", 6) == 0 ) {
1139  // Get image or image list by URL.
1140 #ifdef HAVE_LIBCURL
1141  CURL* curl = curl_easy_init();
1142  if (curl == nullptr) {
1143  fprintf(stderr, "Error, curl_easy_init failed\n");
1144  return false;
1145  } else {
1146  CURLcode curlcode;
1147  curlcode = curl_easy_setopt(curl, CURLOPT_URL, filename);
1148  ASSERT_HOST(curlcode == CURLE_OK);
1149  curlcode = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
1150  ASSERT_HOST(curlcode == CURLE_OK);
1151  curlcode = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf);
1152  ASSERT_HOST(curlcode == CURLE_OK);
1153  curlcode = curl_easy_perform(curl);
1154  ASSERT_HOST(curlcode == CURLE_OK);
1155  curl_easy_cleanup(curl);
1156  data = reinterpret_cast<const l_uint8 *>(buf.data());
1157  }
1158 #else
1159  fprintf(stderr, "Error, this tesseract has no URL support\n");
1160  return false;
1161 #endif
1162  } else {
1163  // Check whether the input file can be read.
1164  if (FILE* file = fopen(filename, "rb")) {
1165  fclose(file);
1166  } else {
1167  fprintf(stderr, "Error, cannot read input file %s: %s\n",
1168  filename, strerror(errno));
1169  return false;
1170  }
1171  }
1172 
1173  // Here is our autodetection
1174  int format;
1175  int r = (data != nullptr) ?
1176  findFileFormatBuffer(data, &format) :
1177  findFileFormat(filename, &format);
1178 
1179  // Maybe we have a filelist
1180  if (r != 0 || format == IFF_UNKNOWN) {
1181  STRING s;
1182  if (data != nullptr) {
1183  s = buf.c_str();
1184  } else {
1185  std::ifstream t(filename);
1186  std::string u((std::istreambuf_iterator<char>(t)),
1187  std::istreambuf_iterator<char>());
1188  s = u.c_str();
1189  }
1190  return ProcessPagesFileList(nullptr, &s, retry_config,
1191  timeout_millisec, renderer,
1193  }
1194 
1195  // Maybe we have a TIFF which is potentially multipage
1196  bool tiff = (format == IFF_TIFF || format == IFF_TIFF_PACKBITS ||
1197  format == IFF_TIFF_RLE || format == IFF_TIFF_G3 ||
1198  format == IFF_TIFF_G4 || format == IFF_TIFF_LZW ||
1199 #if LIBLEPT_MAJOR_VERSION > 1 || LIBLEPT_MINOR_VERSION > 76
1200  format == IFF_TIFF_JPEG ||
1201 #endif
1202  format == IFF_TIFF_ZIP);
1203 
1204  // Fail early if we can, before producing any output
1205  Pix *pix = nullptr;
1206  if (!tiff) {
1207  pix = (data != nullptr) ? pixReadMem(data, buf.size()) : pixRead(filename);
1208  if (pix == nullptr) {
1209  return false;
1210  }
1211  }
1212 
1213  // Begin the output
1214  if (renderer && !renderer->BeginDocument(document_title.c_str())) {
1215  pixDestroy(&pix);
1216  return false;
1217  }
1218 
1219  // Produce output
1220  r = (tiff) ?
1221  ProcessPagesMultipageTiff(data, buf.size(), filename, retry_config,
1222  timeout_millisec, renderer,
1224  ProcessPage(pix, 0, filename, retry_config,
1225  timeout_millisec, renderer);
1226 
1227  // Clean up memory as needed
1228  pixDestroy(&pix);
1229 
1230  // End the output
1231  if (!r || (renderer && !renderer->EndDocument())) {
1232  return false;
1233  }
1234  return true;
1235 }
1236 
1237 bool TessBaseAPI::ProcessPage(Pix* pix, int page_index, const char* filename,
1238  const char* retry_config, int timeout_millisec,
1239  TessResultRenderer* renderer) {
1240  SetInputName(filename);
1241  SetImage(pix);
1242  bool failed = false;
1243 
1245  // Disabled character recognition
1246  PageIterator* it = AnalyseLayout();
1247 
1248  if (it == nullptr) {
1249  failed = true;
1250  } else {
1251  delete it;
1252  }
1254  failed = FindLines() != 0;
1255  } else if (timeout_millisec > 0) {
1256  // Running with a timeout.
1257  ETEXT_DESC monitor;
1258  monitor.cancel = nullptr;
1259  monitor.cancel_this = nullptr;
1260  monitor.set_deadline_msecs(timeout_millisec);
1261 
1262  // Now run the main recognition.
1263  failed = Recognize(&monitor) < 0;
1264  } else {
1265  // Normal layout and character recognition with no timeout.
1266  failed = Recognize(nullptr) < 0;
1267  }
1268 
1270 #ifndef ANDROID_BUILD
1271  Pix* page_pix = GetThresholdedImage();
1272  pixWrite("tessinput.tif", page_pix, IFF_TIFF_G4);
1273 #endif // ANDROID_BUILD
1274  }
1275 
1276  if (failed && retry_config != nullptr && retry_config[0] != '\0') {
1277  // Save current config variables before switching modes.
1278  FILE* fp = fopen(kOldVarsFile, "wb");
1279  if (fp == nullptr) {
1280  tprintf("Error, failed to open file \"%s\"\n", kOldVarsFile);
1281  } else {
1282  PrintVariables(fp);
1283  fclose(fp);
1284  }
1285  // Switch to alternate mode for retry.
1286  ReadConfigFile(retry_config);
1287  SetImage(pix);
1288  Recognize(nullptr);
1289  // Restore saved config variables.
1290  ReadConfigFile(kOldVarsFile);
1291  }
1292 
1293  if (renderer && !failed) {
1294  failed = !renderer->AddImage(this);
1295  }
1296 
1297  return !failed;
1298 }
1299 
1305  if (tesseract_ == nullptr || page_res_ == nullptr)
1306  return nullptr;
1307  return new LTRResultIterator(
1311 }
1312 
1322  if (tesseract_ == nullptr || page_res_ == nullptr)
1323  return nullptr;
1328 }
1329 
1339  if (tesseract_ == nullptr || page_res_ == nullptr)
1340  return nullptr;
1341  return new MutableIterator(page_res_, tesseract_,
1345 }
1346 
1349  if (tesseract_ == nullptr ||
1350  (!recognition_done_ && Recognize(nullptr) < 0))
1351  return nullptr;
1352  STRING text("");
1353  ResultIterator *it = GetIterator();
1354  do {
1355  if (it->Empty(RIL_PARA)) continue;
1356  const std::unique_ptr<const char[]> para_text(it->GetUTF8Text(RIL_PARA));
1357  text += para_text.get();
1358  } while (it->Next(RIL_PARA));
1359  char* result = new char[text.length() + 1];
1360  strncpy(result, text.c_str(), text.length() + 1);
1361  delete it;
1362  return result;
1363 }
1364 
1365 static void AddBoxToTSV(const PageIterator* it, PageIteratorLevel level,
1366  STRING* text) {
1367  int left, top, right, bottom;
1368  it->BoundingBox(level, &left, &top, &right, &bottom);
1369  text->add_str_int("\t", left);
1370  text->add_str_int("\t", top);
1371  text->add_str_int("\t", right - left);
1372  text->add_str_int("\t", bottom - top);
1373 }
1374 
1380 char* TessBaseAPI::GetTSVText(int page_number) {
1381  if (tesseract_ == nullptr || (page_res_ == nullptr && Recognize(nullptr) < 0))
1382  return nullptr;
1383 
1384  int lcnt = 1, bcnt = 1, pcnt = 1, wcnt = 1;
1385  int page_id = page_number + 1; // we use 1-based page numbers.
1386 
1387  STRING tsv_str("");
1388 
1389  int page_num = page_id;
1390  int block_num = 0;
1391  int par_num = 0;
1392  int line_num = 0;
1393  int word_num = 0;
1394 
1395  tsv_str.add_str_int("1\t", page_num); // level 1 - page
1396  tsv_str.add_str_int("\t", block_num);
1397  tsv_str.add_str_int("\t", par_num);
1398  tsv_str.add_str_int("\t", line_num);
1399  tsv_str.add_str_int("\t", word_num);
1400  tsv_str.add_str_int("\t", rect_left_);
1401  tsv_str.add_str_int("\t", rect_top_);
1402  tsv_str.add_str_int("\t", rect_width_);
1403  tsv_str.add_str_int("\t", rect_height_);
1404  tsv_str += "\t-1\t\n";
1405 
1406  ResultIterator* res_it = GetIterator();
1407  while (!res_it->Empty(RIL_BLOCK)) {
1408  if (res_it->Empty(RIL_WORD)) {
1409  res_it->Next(RIL_WORD);
1410  continue;
1411  }
1412 
1413  // Add rows for any new block/paragraph/textline.
1414  if (res_it->IsAtBeginningOf(RIL_BLOCK)) {
1415  block_num++;
1416  par_num = 0;
1417  line_num = 0;
1418  word_num = 0;
1419  tsv_str.add_str_int("2\t", page_num); // level 2 - block
1420  tsv_str.add_str_int("\t", block_num);
1421  tsv_str.add_str_int("\t", par_num);
1422  tsv_str.add_str_int("\t", line_num);
1423  tsv_str.add_str_int("\t", word_num);
1424  AddBoxToTSV(res_it, RIL_BLOCK, &tsv_str);
1425  tsv_str += "\t-1\t\n"; // end of row for block
1426  }
1427  if (res_it->IsAtBeginningOf(RIL_PARA)) {
1428  par_num++;
1429  line_num = 0;
1430  word_num = 0;
1431  tsv_str.add_str_int("3\t", page_num); // level 3 - paragraph
1432  tsv_str.add_str_int("\t", block_num);
1433  tsv_str.add_str_int("\t", par_num);
1434  tsv_str.add_str_int("\t", line_num);
1435  tsv_str.add_str_int("\t", word_num);
1436  AddBoxToTSV(res_it, RIL_PARA, &tsv_str);
1437  tsv_str += "\t-1\t\n"; // end of row for para
1438  }
1439  if (res_it->IsAtBeginningOf(RIL_TEXTLINE)) {
1440  line_num++;
1441  word_num = 0;
1442  tsv_str.add_str_int("4\t", page_num); // level 4 - line
1443  tsv_str.add_str_int("\t", block_num);
1444  tsv_str.add_str_int("\t", par_num);
1445  tsv_str.add_str_int("\t", line_num);
1446  tsv_str.add_str_int("\t", word_num);
1447  AddBoxToTSV(res_it, RIL_TEXTLINE, &tsv_str);
1448  tsv_str += "\t-1\t\n"; // end of row for line
1449  }
1450 
1451  // Now, process the word...
1452  int left, top, right, bottom;
1453  res_it->BoundingBox(RIL_WORD, &left, &top, &right, &bottom);
1454  word_num++;
1455  tsv_str.add_str_int("5\t", page_num); // level 5 - word
1456  tsv_str.add_str_int("\t", block_num);
1457  tsv_str.add_str_int("\t", par_num);
1458  tsv_str.add_str_int("\t", line_num);
1459  tsv_str.add_str_int("\t", word_num);
1460  tsv_str.add_str_int("\t", left);
1461  tsv_str.add_str_int("\t", top);
1462  tsv_str.add_str_int("\t", right - left);
1463  tsv_str.add_str_int("\t", bottom - top);
1464  tsv_str.add_str_int("\t", res_it->Confidence(RIL_WORD));
1465  tsv_str += "\t";
1466 
1467  // Increment counts if at end of block/paragraph/textline.
1468  if (res_it->IsAtFinalElement(RIL_TEXTLINE, RIL_WORD)) lcnt++;
1469  if (res_it->IsAtFinalElement(RIL_PARA, RIL_WORD)) pcnt++;
1470  if (res_it->IsAtFinalElement(RIL_BLOCK, RIL_WORD)) bcnt++;
1471 
1472  do {
1473  tsv_str +=
1474  std::unique_ptr<const char[]>(res_it->GetUTF8Text(RIL_SYMBOL)).get();
1475  res_it->Next(RIL_SYMBOL);
1476  } while (!res_it->Empty(RIL_BLOCK) && !res_it->IsAtBeginningOf(RIL_WORD));
1477  tsv_str += "\n"; // end of row
1478  wcnt++;
1479  }
1480 
1481  char* ret = new char[tsv_str.length() + 1];
1482  strcpy(ret, tsv_str.c_str());
1483  delete res_it;
1484  return ret;
1485 }
1486 
1488 const int kNumbersPerBlob = 5;
1493 const int kBytesPerNumber = 5;
1501 const int kBytesPer64BitNumber = 20;
1509  UNICHAR_LEN;
1510 
1517 char* TessBaseAPI::GetBoxText(int page_number) {
1518  if (tesseract_ == nullptr ||
1519  (!recognition_done_ && Recognize(nullptr) < 0))
1520  return nullptr;
1521  int blob_count;
1522  int utf8_length = TextLength(&blob_count);
1523  int total_length = blob_count * kBytesPerBoxFileLine + utf8_length +
1525  char* result = new char[total_length];
1526  result[0] = '\0';
1527  int output_length = 0;
1529  do {
1530  int left, top, right, bottom;
1531  if (it->BoundingBox(RIL_SYMBOL, &left, &top, &right, &bottom)) {
1532  const std::unique_ptr</*non-const*/ char[]> text(
1533  it->GetUTF8Text(RIL_SYMBOL));
1534  // Tesseract uses space for recognition failure. Fix to a reject
1535  // character, kTesseractReject so we don't create illegal box files.
1536  for (int i = 0; text[i] != '\0'; ++i) {
1537  if (text[i] == ' ')
1538  text[i] = kTesseractReject;
1539  }
1540  snprintf(result + output_length, total_length - output_length,
1541  "%s %d %d %d %d %d\n", text.get(), left, image_height_ - bottom,
1542  right, image_height_ - top, page_number);
1543  output_length += strlen(result + output_length);
1544  // Just in case...
1545  if (output_length + kMaxBytesPerLine > total_length)
1546  break;
1547  }
1548  } while (it->Next(RIL_SYMBOL));
1549  delete it;
1550  return result;
1551 }
1552 
1558 const int kUniChs[] = {
1559  0x20ac, 0x201c, 0x201d, 0x2018, 0x2019, 0x2022, 0x2014, 0
1560 };
1562 const int kLatinChs[] = {
1563  0x00a2, 0x0022, 0x0022, 0x0027, 0x0027, 0x00b7, 0x002d, 0
1564 };
1565 
1572  if (tesseract_ == nullptr ||
1573  (!recognition_done_ && Recognize(nullptr) < 0))
1574  return nullptr;
1575  bool tilde_crunch_written = false;
1576  bool last_char_was_newline = true;
1577  bool last_char_was_tilde = false;
1578 
1579  int total_length = TextLength(nullptr);
1580  PAGE_RES_IT page_res_it(page_res_);
1581  char* result = new char[total_length];
1582  char* ptr = result;
1583  for (page_res_it.restart_page(); page_res_it.word () != nullptr;
1584  page_res_it.forward()) {
1585  WERD_RES *word = page_res_it.word();
1586  // Process the current word.
1587  if (word->unlv_crunch_mode != CR_NONE) {
1588  if (word->unlv_crunch_mode != CR_DELETE &&
1589  (!tilde_crunch_written ||
1590  (word->unlv_crunch_mode == CR_KEEP_SPACE &&
1591  word->word->space() > 0 &&
1592  !word->word->flag(W_FUZZY_NON) &&
1593  !word->word->flag(W_FUZZY_SP)))) {
1594  if (!word->word->flag(W_BOL) &&
1595  word->word->space() > 0 &&
1596  !word->word->flag(W_FUZZY_NON) &&
1597  !word->word->flag(W_FUZZY_SP)) {
1598  /* Write a space to separate from preceding good text */
1599  *ptr++ = ' ';
1600  last_char_was_tilde = false;
1601  }
1602  if (!last_char_was_tilde) {
1603  // Write a reject char.
1604  last_char_was_tilde = true;
1605  *ptr++ = kUNLVReject;
1606  tilde_crunch_written = true;
1607  last_char_was_newline = false;
1608  }
1609  }
1610  } else {
1611  // NORMAL PROCESSING of non tilde crunched words.
1612  tilde_crunch_written = false;
1614  const char* wordstr = word->best_choice->unichar_string().c_str();
1615  const STRING& lengths = word->best_choice->unichar_lengths();
1616  int length = lengths.length();
1617  int i = 0;
1618  int offset = 0;
1619 
1620  if (last_char_was_tilde &&
1621  word->word->space() == 0 && wordstr[offset] == ' ') {
1622  // Prevent adjacent tilde across words - we know that adjacent tildes
1623  // within words have been removed.
1624  // Skip the first character.
1625  offset = lengths[i++];
1626  }
1627  if (i < length && wordstr[offset] != 0) {
1628  if (!last_char_was_newline)
1629  *ptr++ = ' ';
1630  else
1631  last_char_was_newline = false;
1632  for (; i < length; offset += lengths[i++]) {
1633  if (wordstr[offset] == ' ' ||
1634  wordstr[offset] == kTesseractReject) {
1635  *ptr++ = kUNLVReject;
1636  last_char_was_tilde = true;
1637  } else {
1638  if (word->reject_map[i].rejected())
1639  *ptr++ = kUNLVSuspect;
1640  UNICHAR ch(wordstr + offset, lengths[i]);
1641  int uni_ch = ch.first_uni();
1642  for (int j = 0; kUniChs[j] != 0; ++j) {
1643  if (kUniChs[j] == uni_ch) {
1644  uni_ch = kLatinChs[j];
1645  break;
1646  }
1647  }
1648  if (uni_ch <= 0xff) {
1649  *ptr++ = static_cast<char>(uni_ch);
1650  last_char_was_tilde = false;
1651  } else {
1652  *ptr++ = kUNLVReject;
1653  last_char_was_tilde = true;
1654  }
1655  }
1656  }
1657  }
1658  }
1659  if (word->word->flag(W_EOL) && !last_char_was_newline) {
1660  /* Add a new line output */
1661  *ptr++ = '\n';
1662  tilde_crunch_written = false;
1663  last_char_was_newline = true;
1664  last_char_was_tilde = false;
1665  }
1666  }
1667  *ptr++ = '\n';
1668  *ptr = '\0';
1669  return result;
1670 }
1671 
1672 #ifndef DISABLED_LEGACY_ENGINE
1673 
1683 bool TessBaseAPI::DetectOrientationScript(int* orient_deg, float* orient_conf,
1684  const char** script_name,
1685  float* script_conf) {
1686  OSResults osr;
1687 
1688  bool osd = DetectOS(&osr);
1689  if (!osd) {
1690  return false;
1691  }
1692 
1693  int orient_id = osr.best_result.orientation_id;
1694  int script_id = osr.get_best_script(orient_id);
1695  if (orient_conf) *orient_conf = osr.best_result.oconfidence;
1696  if (orient_deg) *orient_deg = orient_id * 90; // convert quadrant to degrees
1697 
1698  if (script_name) {
1699  const char* script = osr.unicharset->get_script_from_script_id(script_id);
1700 
1701  *script_name = script;
1702  }
1703 
1704  if (script_conf) *script_conf = osr.best_result.sconfidence;
1705 
1706  return true;
1707 }
1708 
1714 char* TessBaseAPI::GetOsdText(int page_number) {
1715  int orient_deg;
1716  float orient_conf;
1717  const char* script_name;
1718  float script_conf;
1719 
1720  if (!DetectOrientationScript(&orient_deg, &orient_conf, &script_name,
1721  &script_conf))
1722  return nullptr;
1723 
1724  // clockwise rotation needed to make the page upright
1725  int rotate = OrientationIdToValue(orient_deg / 90);
1726 
1727  std::stringstream stream;
1728  // Use "C" locale (needed for float values orient_conf and script_conf).
1729  stream.imbue(std::locale::classic());
1730  // Use fixed notation with 2 digits after the decimal point for float values.
1731  stream.precision(2);
1732  stream
1733  << std::fixed
1734  << "Page number: " << page_number << "\n"
1735  << "Orientation in degrees: " << orient_deg << "\n"
1736  << "Rotate: " << rotate << "\n"
1737  << "Orientation confidence: " << orient_conf << "\n"
1738  << "Script: " << script_name << "\n"
1739  << "Script confidence: " << script_conf << "\n";
1740  const std::string& text = stream.str();
1741  char* result = new char[text.length() + 1];
1742  strcpy(result, text.c_str());
1743  return result;
1744 }
1745 
1746 #endif // ndef DISABLED_LEGACY_ENGINE
1747 
1750  int* conf = AllWordConfidences();
1751  if (!conf) return 0;
1752  int sum = 0;
1753  int *pt = conf;
1754  while (*pt >= 0) sum += *pt++;
1755  if (pt != conf) sum /= pt - conf;
1756  delete [] conf;
1757  return sum;
1758 }
1759 
1762  if (tesseract_ == nullptr ||
1763  (!recognition_done_ && Recognize(nullptr) < 0))
1764  return nullptr;
1765  int n_word = 0;
1766  PAGE_RES_IT res_it(page_res_);
1767  for (res_it.restart_page(); res_it.word() != nullptr; res_it.forward())
1768  n_word++;
1769 
1770  int* conf = new int[n_word+1];
1771  n_word = 0;
1772  for (res_it.restart_page(); res_it.word() != nullptr; res_it.forward()) {
1773  WERD_RES *word = res_it.word();
1774  WERD_CHOICE* choice = word->best_choice;
1775  int w_conf = static_cast<int>(100 + 5 * choice->certainty());
1776  // This is the eq for converting Tesseract confidence to 1..100
1777  if (w_conf < 0) w_conf = 0;
1778  if (w_conf > 100) w_conf = 100;
1779  conf[n_word++] = w_conf;
1780  }
1781  conf[n_word] = -1;
1782  return conf;
1783 }
1784 
1785 #ifndef DISABLED_LEGACY_ENGINE
1786 
1796 bool TessBaseAPI::AdaptToWordStr(PageSegMode mode, const char* wordstr) {
1797  int debug = 0;
1798  GetIntVariable("applybox_debug", &debug);
1799  bool success = true;
1800  PageSegMode current_psm = GetPageSegMode();
1801  SetPageSegMode(mode);
1802  SetVariable("classify_enable_learning", "0");
1803  const std::unique_ptr<const char[]> text(GetUTF8Text());
1804  if (debug) {
1805  tprintf("Trying to adapt \"%s\" to \"%s\"\n", text.get(), wordstr);
1806  }
1807  if (text != nullptr) {
1808  PAGE_RES_IT it(page_res_);
1809  WERD_RES* word_res = it.word();
1810  if (word_res != nullptr) {
1811  word_res->word->set_text(wordstr);
1812  // Check to see if text matches wordstr.
1813  int w = 0;
1814  int t;
1815  for (t = 0; text[t] != '\0'; ++t) {
1816  if (text[t] == '\n' || text[t] == ' ')
1817  continue;
1818  while (wordstr[w] == ' ') ++w;
1819  if (text[t] != wordstr[w])
1820  break;
1821  ++w;
1822  }
1823  if (text[t] != '\0' || wordstr[w] != '\0') {
1824  // No match.
1825  delete page_res_;
1826  GenericVector<TBOX> boxes;
1830  PAGE_RES_IT pr_it(page_res_);
1831  if (pr_it.word() == nullptr)
1832  success = false;
1833  else
1834  word_res = pr_it.word();
1835  } else {
1836  word_res->BestChoiceToCorrectText();
1837  }
1838  if (success) {
1839  tesseract_->EnableLearning = true;
1840  tesseract_->LearnWord(nullptr, word_res);
1841  }
1842  } else {
1843  success = false;
1844  }
1845  } else {
1846  success = false;
1847  }
1848  SetPageSegMode(current_psm);
1849  return success;
1850 }
1851 #endif // ndef DISABLED_LEGACY_ENGINE
1852 
1860  if (thresholder_ != nullptr)
1861  thresholder_->Clear();
1862  ClearResults();
1863  if (tesseract_ != nullptr) SetInputImage(nullptr);
1864 }
1865 
1873  Clear();
1874  delete thresholder_;
1875  thresholder_ = nullptr;
1876  delete page_res_;
1877  page_res_ = nullptr;
1878  delete block_list_;
1879  block_list_ = nullptr;
1880  if (paragraph_models_ != nullptr) {
1882  delete paragraph_models_;
1883  paragraph_models_ = nullptr;
1884  }
1885  if (osd_tesseract_ == tesseract_) osd_tesseract_ = nullptr;
1886  delete tesseract_;
1887  tesseract_ = nullptr;
1888  delete osd_tesseract_;
1889  osd_tesseract_ = nullptr;
1890  delete equ_detect_;
1891  equ_detect_ = nullptr;
1892  delete input_file_;
1893  input_file_ = nullptr;
1894  delete output_file_;
1895  output_file_ = nullptr;
1896  delete datapath_;
1897  datapath_ = nullptr;
1898  delete language_;
1899  language_ = nullptr;
1900 }
1901 
1902 // Clear any library-level memory caches.
1903 // There are a variety of expensive-to-load constant data structures (mostly
1904 // language dictionaries) that are cached globally -- surviving the Init()
1905 // and End() of individual TessBaseAPI's. This function allows the clearing
1906 // of these caches.
1909 }
1910 
1915 int TessBaseAPI::IsValidWord(const char *word) {
1916  return tesseract_->getDict().valid_word(word);
1917 }
1918 // Returns true if utf8_character is defined in the UniCharset.
1919 bool TessBaseAPI::IsValidCharacter(const char *utf8_character) {
1920  return tesseract_->unicharset.contains_unichar(utf8_character);
1921 }
1922 
1923 
1924 // TODO(rays) Obsolete this function and replace with a more aptly named
1925 // function that returns image coordinates rather than tesseract coordinates.
1926 bool TessBaseAPI::GetTextDirection(int* out_offset, float* out_slope) {
1927  PageIterator* it = AnalyseLayout();
1928  if (it == nullptr) {
1929  return false;
1930  }
1931  int x1, x2, y1, y2;
1932  it->Baseline(RIL_TEXTLINE, &x1, &y1, &x2, &y2);
1933  // Calculate offset and slope (NOTE: Kind of ugly)
1934  if (x2 <= x1) x2 = x1 + 1;
1935  // Convert the point pair to slope/offset of the baseline (in image coords.)
1936  *out_slope = static_cast<float>(y2 - y1) / (x2 - x1);
1937  *out_offset = static_cast<int>(y1 - *out_slope * x1);
1938  // Get the y-coord of the baseline at the left and right edges of the
1939  // textline's bounding box.
1940  int left, top, right, bottom;
1941  if (!it->BoundingBox(RIL_TEXTLINE, &left, &top, &right, &bottom)) {
1942  delete it;
1943  return false;
1944  }
1945  int left_y = IntCastRounded(*out_slope * left + *out_offset);
1946  int right_y = IntCastRounded(*out_slope * right + *out_offset);
1947  // Shift the baseline down so it passes through the nearest bottom-corner
1948  // of the textline's bounding box. This is the difference between the y
1949  // at the lowest (max) edge of the box and the actual box bottom.
1950  *out_offset += bottom - std::max(left_y, right_y);
1951  // Switch back to bottom-up tesseract coordinates. Requires negation of
1952  // the slope and height - offset for the offset.
1953  *out_slope = -*out_slope;
1954  *out_offset = rect_height_ - *out_offset;
1955  delete it;
1956 
1957  return true;
1958 }
1959 
1962  if (tesseract_ != nullptr) {
1964  }
1965 }
1966 
1976  if (tesseract_ != nullptr) {
1978  // Set it for the sublangs too.
1979  int num_subs = tesseract_->num_sub_langs();
1980  for (int i = 0; i < num_subs; ++i) {
1982  }
1983  }
1984 }
1985 
1986 #ifndef DISABLED_LEGACY_ENGINE
1987 
1989  if (tesseract_ != nullptr) tesseract_->fill_lattice_ = f;
1990 }
1991 #endif // ndef DISABLED_LEGACY_ENGINE
1992 
1995  if (tesseract_ == nullptr) {
1996  tprintf("Please call Init before attempting to set an image.\n");
1997  return false;
1998  }
1999  if (thresholder_ == nullptr)
2001  ClearResults();
2002  return true;
2003 }
2004 
2011 bool TessBaseAPI::Threshold(Pix** pix) {
2012  ASSERT_HOST(pix != nullptr);
2013  if (*pix != nullptr)
2014  pixDestroy(pix);
2015  // Zero resolution messes up the algorithms, so make sure it is credible.
2016  int user_dpi = 0;
2017  GetIntVariable("user_defined_dpi", &user_dpi);
2018  int y_res = thresholder_->GetScaledYResolution();
2019  if (user_dpi && (user_dpi < kMinCredibleResolution ||
2020  user_dpi > kMaxCredibleResolution)) {
2021  tprintf("Warning: User defined image dpi is outside of expected range "
2022  "(%d - %d)!\n",
2024  }
2025  // Always use user defined dpi
2026  if (user_dpi) {
2028  } else if (y_res < kMinCredibleResolution ||
2029  y_res > kMaxCredibleResolution) {
2030  tprintf("Warning: Invalid resolution %d dpi. Using %d instead.\n",
2031  y_res, kMinCredibleResolution);
2033  }
2034  auto pageseg_mode =
2035  static_cast<PageSegMode>(
2036  static_cast<int>(tesseract_->tessedit_pageseg_mode));
2037  if (!thresholder_->ThresholdToPix(pageseg_mode, pix)) return false;
2041  if (!thresholder_->IsBinary()) {
2044  } else {
2045  tesseract_->set_pix_thresholds(nullptr);
2046  tesseract_->set_pix_grey(nullptr);
2047  }
2048  // Set the internal resolution that is used for layout parameters from the
2049  // estimated resolution, rather than the image resolution, which may be
2050  // fabricated, but we will use the image resolution, if there is one, to
2051  // report output point sizes.
2052  int estimated_res = ClipToRange(thresholder_->GetScaledEstimatedResolution(),
2055  if (estimated_res != thresholder_->GetScaledEstimatedResolution()) {
2056  tprintf("Estimated internal resolution %d out of range! "
2057  "Corrected to %d.\n",
2058  thresholder_->GetScaledEstimatedResolution(), estimated_res);
2059  }
2060  tesseract_->set_source_resolution(estimated_res);
2061  return true;
2062 }
2063 
2066  if (thresholder_ == nullptr || thresholder_->IsEmpty()) {
2067  tprintf("Please call SetImage before attempting recognition.\n");
2068  return -1;
2069  }
2070  if (recognition_done_)
2071  ClearResults();
2072  if (!block_list_->empty()) {
2073  return 0;
2074  }
2075  if (tesseract_ == nullptr) {
2076  tesseract_ = new Tesseract;
2077  #ifndef DISABLED_LEGACY_ENGINE
2079  #endif
2080  }
2081  if (tesseract_->pix_binary() == nullptr &&
2083  return -1;
2084  }
2085 
2087 
2088 #ifndef DISABLED_LEGACY_ENGINE
2090  if (equ_detect_ == nullptr && datapath_ != nullptr) {
2091  equ_detect_ = new EquationDetect(datapath_->c_str(), nullptr);
2092  }
2093  if (equ_detect_ == nullptr) {
2094  tprintf("Warning: Could not set equation detector\n");
2095  } else {
2097  }
2098  }
2099 #endif // ndef DISABLED_LEGACY_ENGINE
2100 
2101  Tesseract* osd_tess = osd_tesseract_;
2102  OSResults osr;
2104  osd_tess == nullptr) {
2105  if (strcmp(language_->c_str(), "osd") == 0) {
2106  osd_tess = tesseract_;
2107  } else {
2108  osd_tesseract_ = new Tesseract;
2109  TessdataManager mgr(reader_);
2110  if (datapath_ == nullptr) {
2111  tprintf("Warning: Auto orientation and script detection requested,"
2112  " but data path is undefined\n");
2113  delete osd_tesseract_;
2114  osd_tesseract_ = nullptr;
2115  } else if (osd_tesseract_->init_tesseract(datapath_->c_str(), nullptr,
2116  "osd", OEM_TESSERACT_ONLY,
2117  nullptr, 0, nullptr, nullptr,
2118  false, &mgr) == 0) {
2119  osd_tess = osd_tesseract_;
2122  } else {
2123  tprintf("Warning: Auto orientation and script detection requested,"
2124  " but osd language failed to load\n");
2125  delete osd_tesseract_;
2126  osd_tesseract_ = nullptr;
2127  }
2128  }
2129  }
2130 
2131  if (tesseract_->SegmentPage(input_file_, block_list_, osd_tess, &osr) < 0)
2132  return -1;
2133 
2134  // If Devanagari is being recognized, we use different images for page seg
2135  // and for OCR.
2136  tesseract_->PrepareForTessOCR(block_list_, osd_tess, &osr);
2137  return 0;
2138 }
2139 
2142  if (tesseract_ != nullptr) {
2143  tesseract_->Clear();
2144  }
2145  delete page_res_;
2146  page_res_ = nullptr;
2147  recognition_done_ = false;
2148  if (block_list_ == nullptr)
2149  block_list_ = new BLOCK_LIST;
2150  else
2151  block_list_->clear();
2152  if (paragraph_models_ != nullptr) {
2154  delete paragraph_models_;
2155  paragraph_models_ = nullptr;
2156  }
2157 }
2158 
2166 int TessBaseAPI::TextLength(int* blob_count) {
2167  if (tesseract_ == nullptr || page_res_ == nullptr)
2168  return 0;
2169 
2170  PAGE_RES_IT page_res_it(page_res_);
2171  int total_length = 2;
2172  int total_blobs = 0;
2173  // Iterate over the data structures to extract the recognition result.
2174  for (page_res_it.restart_page(); page_res_it.word () != nullptr;
2175  page_res_it.forward()) {
2176  WERD_RES *word = page_res_it.word();
2177  WERD_CHOICE* choice = word->best_choice;
2178  if (choice != nullptr) {
2179  total_blobs += choice->length() + 2;
2180  total_length += choice->unichar_string().length() + 2;
2181  for (int i = 0; i < word->reject_map.length(); ++i) {
2182  if (word->reject_map[i].rejected())
2183  ++total_length;
2184  }
2185  }
2186  }
2187  if (blob_count != nullptr)
2188  *blob_count = total_blobs;
2189  return total_length;
2190 }
2191 
2192 #ifndef DISABLED_LEGACY_ENGINE
2193 
2198  if (tesseract_ == nullptr)
2199  return false;
2200  ClearResults();
2201  if (tesseract_->pix_binary() == nullptr &&
2203  return false;
2204  }
2205 
2206  if (input_file_ == nullptr)
2207  input_file_ = new STRING(kInputFile);
2209 }
2210 #endif // ndef DISABLED_LEGACY_ENGINE
2211 
2213  tesseract_->min_orientation_margin.set_value(margin);
2214 }
2215 
2230 void TessBaseAPI::GetBlockTextOrientations(int** block_orientation,
2231  bool** vertical_writing) {
2232  delete[] *block_orientation;
2233  *block_orientation = nullptr;
2234  delete[] *vertical_writing;
2235  *vertical_writing = nullptr;
2236  BLOCK_IT block_it(block_list_);
2237 
2238  block_it.move_to_first();
2239  int num_blocks = 0;
2240  for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
2241  if (!block_it.data()->pdblk.poly_block()->IsText()) {
2242  continue;
2243  }
2244  ++num_blocks;
2245  }
2246  if (!num_blocks) {
2247  tprintf("WARNING: Found no blocks\n");
2248  return;
2249  }
2250  *block_orientation = new int[num_blocks];
2251  *vertical_writing = new bool[num_blocks];
2252  block_it.move_to_first();
2253  int i = 0;
2254  for (block_it.mark_cycle_pt(); !block_it.cycled_list();
2255  block_it.forward()) {
2256  if (!block_it.data()->pdblk.poly_block()->IsText()) {
2257  continue;
2258  }
2259  FCOORD re_rotation = block_it.data()->re_rotation();
2260  float re_theta = re_rotation.angle();
2261  FCOORD classify_rotation = block_it.data()->classify_rotation();
2262  float classify_theta = classify_rotation.angle();
2263  double rot_theta = - (re_theta - classify_theta) * 2.0 / M_PI;
2264  if (rot_theta < 0) rot_theta += 4;
2265  int num_rotations = static_cast<int>(rot_theta + 0.5);
2266  (*block_orientation)[i] = num_rotations;
2267  // The classify_rotation is non-zero only if the text has vertical
2268  // writing direction.
2269  (*vertical_writing)[i] = classify_rotation.y() != 0.0f;
2270  ++i;
2271  }
2272 }
2273 
2274 
2275 void TessBaseAPI::DetectParagraphs(bool after_text_recognition) {
2276  int debug_level = 0;
2277  GetIntVariable("paragraph_debug_level", &debug_level);
2278  if (paragraph_models_ == nullptr)
2280  MutableIterator *result_it = GetMutableIterator();
2281  do { // Detect paragraphs for this block
2283  ::tesseract::DetectParagraphs(debug_level, after_text_recognition,
2284  result_it, &models);
2285  *paragraph_models_ += models;
2286  } while (result_it->Next(RIL_BLOCK));
2287  delete result_it;
2288 }
2289 
2291 const char* TessBaseAPI::GetUnichar(int unichar_id) {
2292  return tesseract_->unicharset.id_to_unichar(unichar_id);
2293 }
2294 
2296 const Dawg *TessBaseAPI::GetDawg(int i) const {
2297  if (tesseract_ == nullptr || i >= NumDawgs()) return nullptr;
2298  return tesseract_->getDict().GetDawg(i);
2299 }
2300 
2303  return tesseract_ == nullptr ? 0 : tesseract_->getDict().NumDawgs();
2304 }
2305 
2307 STRING HOcrEscape(const char* text) {
2308  STRING ret;
2309  const char *ptr;
2310  for (ptr = text; *ptr; ptr++) {
2311  switch (*ptr) {
2312  case '<': ret += "&lt;"; break;
2313  case '>': ret += "&gt;"; break;
2314  case '&': ret += "&amp;"; break;
2315  case '"': ret += "&quot;"; break;
2316  case '\'': ret += "&#39;"; break;
2317  default: ret += *ptr;
2318  }
2319  }
2320  return ret;
2321 }
2322 
2323 
2324 #ifndef DISABLED_LEGACY_ENGINE
2325 
2326 
2327 // ____________________________________________________________________________
2328 // Ocropus add-ons.
2329 
2332  ASSERT_HOST(FindLines() == 0);
2333  BLOCK_LIST* result = block_list_;
2334  block_list_ = nullptr;
2335  return result;
2336 }
2337 
2343 void TessBaseAPI::DeleteBlockList(BLOCK_LIST *block_list) {
2344  delete block_list;
2345 }
2346 
2347 
2349  float xheight,
2350  float descender,
2351  float ascender) {
2352  int32_t xstarts[] = {-32000};
2353  double quad_coeffs[] = {0, 0, baseline};
2354  return new ROW(1,
2355  xstarts,
2356  quad_coeffs,
2357  xheight,
2358  ascender - (baseline + xheight),
2359  descender - baseline,
2360  0,
2361  0);
2362 }
2363 
2366  int width = pixGetWidth(pix);
2367  int height = pixGetHeight(pix);
2368  BLOCK block("a character", true, 0, 0, 0, 0, width, height);
2369 
2370  // Create C_BLOBs from the page
2371  extract_edges(pix, &block);
2372 
2373  // Merge all C_BLOBs
2374  C_BLOB_LIST *list = block.blob_list();
2375  C_BLOB_IT c_blob_it(list);
2376  if (c_blob_it.empty())
2377  return nullptr;
2378  // Move all the outlines to the first blob.
2379  C_OUTLINE_IT ol_it(c_blob_it.data()->out_list());
2380  for (c_blob_it.forward();
2381  !c_blob_it.at_first();
2382  c_blob_it.forward()) {
2383  C_BLOB *c_blob = c_blob_it.data();
2384  ol_it.add_list_after(c_blob->out_list());
2385  }
2386  // Convert the first blob to the output TBLOB.
2387  return TBLOB::PolygonalCopy(false, c_blob_it.data());
2388 }
2389 
2395 void TessBaseAPI::NormalizeTBLOB(TBLOB *tblob, ROW *row, bool numeric_mode) {
2396  TBOX box = tblob->bounding_box();
2397  float x_center = (box.left() + box.right()) / 2.0f;
2398  float baseline = row->base_line(x_center);
2399  float scale = kBlnXHeight / row->x_height();
2400  tblob->Normalize(nullptr, nullptr, nullptr, x_center, baseline, scale, scale,
2401  0.0f, static_cast<float>(kBlnBaselineOffset), false, nullptr);
2402 }
2403 
2408 static TBLOB *make_tesseract_blob(float baseline, float xheight,
2409  float descender, float ascender,
2410  bool numeric_mode, Pix* pix) {
2411  TBLOB *tblob = TessBaseAPI::MakeTBLOB(pix);
2412 
2413  // Normalize TBLOB
2414  ROW *row =
2415  TessBaseAPI::MakeTessOCRRow(baseline, xheight, descender, ascender);
2416  TessBaseAPI::NormalizeTBLOB(tblob, row, numeric_mode);
2417  delete row;
2418  return tblob;
2419 }
2420 
2426 void TessBaseAPI::AdaptToCharacter(const char *unichar_repr,
2427  int length,
2428  float baseline,
2429  float xheight,
2430  float descender,
2431  float ascender) {
2432  UNICHAR_ID id = tesseract_->unicharset.unichar_to_id(unichar_repr, length);
2433  TBLOB *blob = make_tesseract_blob(baseline, xheight, descender, ascender,
2435  tesseract_->pix_binary());
2436  float threshold;
2437  float best_rating = -100;
2438 
2439 
2440  // Classify to get a raw choice.
2441  BLOB_CHOICE_LIST choices;
2442  tesseract_->AdaptiveClassifier(blob, &choices);
2443  BLOB_CHOICE_IT choice_it;
2444  choice_it.set_to_list(&choices);
2445  for (choice_it.mark_cycle_pt(); !choice_it.cycled_list();
2446  choice_it.forward()) {
2447  if (choice_it.data()->rating() > best_rating) {
2448  best_rating = choice_it.data()->rating();
2449  }
2450  }
2451 
2452  threshold = tesseract_->matcher_good_threshold;
2453 
2454  if (blob->outlines)
2455  tesseract_->AdaptToChar(blob, id, kUnknownFontinfoId, threshold,
2457  delete blob;
2458 }
2459 
2460 
2461 PAGE_RES* TessBaseAPI::RecognitionPass1(BLOCK_LIST* block_list) {
2462  auto *page_res = new PAGE_RES(false, block_list,
2464  tesseract_->recog_all_words(page_res, nullptr, nullptr, nullptr, 1);
2465  return page_res;
2466 }
2467 
2468 PAGE_RES* TessBaseAPI::RecognitionPass2(BLOCK_LIST* block_list,
2469  PAGE_RES* pass1_result) {
2470  if (!pass1_result)
2471  pass1_result = new PAGE_RES(false, block_list,
2473  tesseract_->recog_all_words(pass1_result, nullptr, nullptr, nullptr, 2);
2474  return pass1_result;
2475 }
2476 
2479  int length; // of unicode_repr
2480  float cost;
2482 
2483  TESS_CHAR(float _cost, const char *repr, int len = -1) : cost(_cost) {
2484  length = (len == -1 ? strlen(repr) : len);
2485  unicode_repr = new char[length + 1];
2486  strncpy(unicode_repr, repr, length);
2487  }
2488 
2490  : unicode_repr(nullptr),
2491  length(0),
2492  cost(0.0f)
2493  { // Satisfies ELISTIZE.
2494  }
2496  delete [] unicode_repr;
2497  }
2498 };
2499 
2500 ELISTIZEH(TESS_CHAR)
2501 ELISTIZE(TESS_CHAR)
2502 
2503 static void add_space(TESS_CHAR_IT* it) {
2504  auto *t = new TESS_CHAR(0, " ");
2505  it->add_after_then_move(t);
2506 }
2507 
2508 
2509 static float rating_to_cost(float rating) {
2510  rating = 100 + rating;
2511  // cuddled that to save from coverage profiler
2512  // (I have never seen ratings worse than -100,
2513  // but the check won't hurt)
2514  if (rating < 0) rating = 0;
2515  return rating;
2516 }
2517 
2522 static void extract_result(TESS_CHAR_IT* out,
2523  PAGE_RES* page_res) {
2524  PAGE_RES_IT page_res_it(page_res);
2525  int word_count = 0;
2526  while (page_res_it.word() != nullptr) {
2527  WERD_RES *word = page_res_it.word();
2528  const char *str = word->best_choice->unichar_string().c_str();
2529  const char *len = word->best_choice->unichar_lengths().c_str();
2530  TBOX real_rect = word->word->bounding_box();
2531 
2532  if (word_count)
2533  add_space(out);
2534  int n = strlen(len);
2535  for (int i = 0; i < n; i++) {
2536  auto *tc = new TESS_CHAR(rating_to_cost(word->best_choice->rating()),
2537  str, *len);
2538  tc->box = real_rect.intersection(word->box_word->BlobBox(i));
2539  out->add_after_then_move(tc);
2540  str += *len;
2541  len++;
2542  }
2543  page_res_it.forward();
2544  word_count++;
2545  }
2546 }
2547 
2553  int** lengths,
2554  float** costs,
2555  int** x0,
2556  int** y0,
2557  int** x1,
2558  int** y1,
2559  PAGE_RES* page_res) {
2560  TESS_CHAR_LIST tess_chars;
2561  TESS_CHAR_IT tess_chars_it(&tess_chars);
2562  extract_result(&tess_chars_it, page_res);
2563  tess_chars_it.move_to_first();
2564  int n = tess_chars.length();
2565  int text_len = 0;
2566  *lengths = new int[n];
2567  *costs = new float[n];
2568  *x0 = new int[n];
2569  *y0 = new int[n];
2570  *x1 = new int[n];
2571  *y1 = new int[n];
2572  int i = 0;
2573  for (tess_chars_it.mark_cycle_pt();
2574  !tess_chars_it.cycled_list();
2575  tess_chars_it.forward(), i++) {
2576  TESS_CHAR *tc = tess_chars_it.data();
2577  text_len += (*lengths)[i] = tc->length;
2578  (*costs)[i] = tc->cost;
2579  (*x0)[i] = tc->box.left();
2580  (*y0)[i] = tc->box.bottom();
2581  (*x1)[i] = tc->box.right();
2582  (*y1)[i] = tc->box.top();
2583  }
2584  char *p = *text = new char[text_len];
2585 
2586  tess_chars_it.move_to_first();
2587  for (tess_chars_it.mark_cycle_pt();
2588  !tess_chars_it.cycled_list();
2589  tess_chars_it.forward()) {
2590  TESS_CHAR *tc = tess_chars_it.data();
2591  strncpy(p, tc->unicode_repr, tc->length);
2592  p += tc->length;
2593  }
2594  return n;
2595 }
2596 
2598 // The resulting features are returned in int_features, which must be
2599 // of size MAX_NUM_INT_FEATURES. The number of features is returned in
2600 // num_features (or 0 if there was a failure).
2601 // On return feature_outline_index is filled with an index of the outline
2602 // corresponding to each feature in int_features.
2603 // TODO(rays) Fix the caller to out outline_counts instead.
2605  INT_FEATURE_STRUCT* int_features,
2606  int* num_features,
2607  int* feature_outline_index) {
2608  GenericVector<int> outline_counts;
2611  INT_FX_RESULT_STRUCT fx_info;
2612  tesseract_->ExtractFeatures(*blob, false, &bl_features,
2613  &cn_features, &fx_info, &outline_counts);
2614  if (cn_features.empty() || cn_features.size() > MAX_NUM_INT_FEATURES) {
2615  *num_features = 0;
2616  return; // Feature extraction failed.
2617  }
2618  *num_features = cn_features.size();
2619  memcpy(int_features, &cn_features[0], *num_features * sizeof(cn_features[0]));
2620  // TODO(rays) Pass outline_counts back and simplify the calling code.
2621  if (feature_outline_index != nullptr) {
2622  int f = 0;
2623  for (int i = 0; i < outline_counts.size(); ++i) {
2624  while (f < outline_counts[i])
2625  feature_outline_index[f++] = i;
2626  }
2627  }
2628 }
2629 
2630 // This method returns the row to which a box of specified dimensions would
2631 // belong. If no good match is found, it returns nullptr.
2632 ROW* TessBaseAPI::FindRowForBox(BLOCK_LIST* blocks,
2633  int left, int top, int right, int bottom) {
2634  TBOX box(left, bottom, right, top);
2635  BLOCK_IT b_it(blocks);
2636  for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) {
2637  BLOCK* block = b_it.data();
2638  if (!box.major_overlap(block->pdblk.bounding_box()))
2639  continue;
2640  ROW_IT r_it(block->row_list());
2641  for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
2642  ROW* row = r_it.data();
2643  if (!box.major_overlap(row->bounding_box()))
2644  continue;
2645  WERD_IT w_it(row->word_list());
2646  for (w_it.mark_cycle_pt(); !w_it.cycled_list(); w_it.forward()) {
2647  WERD* word = w_it.data();
2648  if (box.major_overlap(word->bounding_box()))
2649  return row;
2650  }
2651  }
2652  }
2653  return nullptr;
2654 }
2655 
2658  int num_max_matches,
2659  int* unichar_ids,
2660  float* ratings,
2661  int* num_matches_returned) {
2662  auto* choices = new BLOB_CHOICE_LIST;
2663  tesseract_->AdaptiveClassifier(blob, choices);
2664  BLOB_CHOICE_IT choices_it(choices);
2665  int& index = *num_matches_returned;
2666  index = 0;
2667  for (choices_it.mark_cycle_pt();
2668  !choices_it.cycled_list() && index < num_max_matches;
2669  choices_it.forward()) {
2670  BLOB_CHOICE* choice = choices_it.data();
2671  unichar_ids[index] = choice->unichar_id();
2672  ratings[index] = choice->rating();
2673  ++index;
2674  }
2675  *num_matches_returned = index;
2676  delete choices;
2677 }
2678 #endif // ndef DISABLED_LEGACY_ENGINE
2679 
2680 } // namespace tesseract.
tesseract::TessBaseAPI::DetectOrientationScript
bool DetectOrientationScript(int *orient_deg, float *orient_conf, const char **script_name, float *script_conf)
Definition: baseapi.cpp:1683
string
std::string string
Definition: equationdetect_test.cc:21
WERD_CHOICE::unichar_string
const STRING & unichar_string() const
Definition: ratngs.h:529
GenericVector::delete_data_pointers
void delete_data_pointers()
Definition: genericvector.h:872
tesseract::ImageThresholder::GetImageSizes
virtual void GetImageSizes(int *left, int *top, int *width, int *height, int *imagewidth, int *imageheight)
Definition: thresholder.cpp:134
ClipToRange
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:106
tesseract::TessBaseAPI::GetLoadedLanguagesAsVector
void GetLoadedLanguagesAsVector(GenericVector< STRING > *langs) const
Definition: baseapi.cpp:433
tesseract::TessBaseAPI::GetMutableIterator
MutableIterator * GetMutableIterator()
Definition: baseapi.cpp:1338
elst.h
tesseract::TessResultRenderer::EndDocument
bool EndDocument()
Definition: renderer.cpp:92
strngs.h
tesseract::Dict::NumDawgs
int NumDawgs() const
Return the number of dawgs in the dawgs_ vector.
Definition: dict.h:430
normalis.h
tesseract::Tesseract::init_tesseract
int init_tesseract(const char *arg0, const char *textbase, const char *language, OcrEngineMode oem, char **configs, int configs_size, const GenericVector< STRING > *vars_vec, const GenericVector< STRING > *vars_values, bool set_only_init_params, TessdataManager *mgr)
Definition: tessedit.cpp:302
tesseract::CCUtil::datadir
STRING datadir
Definition: ccutil.h:53
tesseract::TessBaseAPI::ClearPersistentCache
static void ClearPersistentCache()
Definition: baseapi.cpp:1907
pdblock.h
tesseract::Tesseract::PrepareForTessOCR
void PrepareForTessOCR(BLOCK_LIST *block_list, Tesseract *osd_tess, OSResults *osr)
Definition: tesseractclass.cpp:672
tesseract::ResultIterator::IsAtFinalElement
bool IsAtFinalElement(PageIteratorLevel level, PageIteratorLevel element) const override
Definition: resultiterator.cpp:570
tesseract::PSM_OSD_ENABLED
bool PSM_OSD_ENABLED(int pageseg_mode)
Definition: publictypes.h:188
OSResults::best_result
OSBestResult best_result
Definition: osdetect.h:81
intfx.h
PAGE_RES_IT::forward
WERD_RES * forward()
Definition: pageres.h:728
tesseract::RIL_WORD
Definition: publictypes.h:220
WERD_RES::box_word
tesseract::BoxWord * box_word
Definition: pageres.h:266
FCOORD::angle
float angle() const
find angle
Definition: points.h:246
tesseract::Tesseract::tessedit_train_from_boxes
bool tessedit_train_from_boxes
Definition: tesseractclass.h:787
tesseract::TESS_CHAR::unicode_repr
char * unicode_repr
Definition: baseapi.cpp:2478
tesseract::Tesseract::pix_grey
Pix * pix_grey() const
Definition: tesseractclass.h:203
tesseract::TessBaseAPI::Threshold
virtual TESS_LOCAL bool Threshold(Pix **pix)
Definition: baseapi.cpp:2011
pageres.h
tesseract::TESS_CHAR::~TESS_CHAR
~TESS_CHAR()
Definition: baseapi.cpp:2495
tesseract::Tesseract::ResetDocumentDictionary
void ResetDocumentDictionary()
Definition: tesseractclass.cpp:607
TBOX::intersection
TBOX intersection(const TBOX &box) const
Definition: rect.cpp:83
CR_DELETE
Definition: pageres.h:156
STRING::add_str_int
void add_str_int(const char *str, int number)
Definition: strngs.cpp:370
ROW::base_line
float base_line(float xpos) const
Definition: ocrrow.h:58
tesseract::TessBaseAPI::page_res_
PAGE_RES * page_res_
The page-level data.
Definition: baseapi.h:893
tesseract::TessBaseAPI::last_oem_requested_
OcrEngineMode last_oem_requested_
Last ocr language mode requested.
Definition: baseapi.h:898
WERD::flag
bool flag(WERD_FLAGS mask) const
Definition: werd.h:116
tesseract::TessBaseAPI::GetConnectedComponents
Boxa * GetConnectedComponents(Pixa **cc)
Definition: baseapi.cpp:685
dict.h
C_BLOB::out_list
C_OUTLINE_LIST * out_list()
Definition: stepblob.h:69
OrientationIdToValue
TESS_API int OrientationIdToValue(const int &id)
Definition: osdetect.cpp:566
kBlnXHeight
const int kBlnXHeight
Definition: normalis.h:23
tesseract::TessBaseAPI::GetStrips
Boxa * GetStrips(Pixa **pixa, int **blockids)
Definition: baseapi.cpp:666
PDBLK::bounding_box
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
Definition: pdblock.h:58
WERD_RES::BestChoiceToCorrectText
void BestChoiceToCorrectText()
Definition: pageres.cpp:920
tesseract::EquationDetect
Definition: equationdetect.h:38
tesseract::DictFunc
int(Dict::*)(void *, const UNICHARSET &, UNICHAR_ID, bool) const DictFunc
Definition: baseapi.h:80
tesseract::TessBaseAPI::RecognitionPass2
TESS_LOCAL PAGE_RES * RecognitionPass2(BLOCK_LIST *block_list, PAGE_RES *pass1_result)
Definition: baseapi.cpp:2468
tesseract::Dict::probability_in_context_
double(Dict::* probability_in_context_)(const char *lang, const char *context, int context_bytes, const char *character, int character_bytes)
Probability in context function used by the ngram permuter.
Definition: dict.h:384
tesseract::SET_PARAM_CONSTRAINT_NON_INIT_ONLY
Definition: params.h:53
tesseract::TessBaseAPI::image_height_
int image_height_
Definition: baseapi.h:912
tesseract::TessdataManager
Definition: tessdatamanager.h:126
tesseract::ImageThresholder::IsBinary
bool IsBinary() const
Returns true if the source image is binary.
Definition: thresholder.h:74
WERD_CHOICE
Definition: ratngs.h:261
tesseract::Tesseract::recog_training_segmented
void recog_training_segmented(const STRING &fname, PAGE_RES *page_res, volatile ETEXT_DESC *monitor, FILE *output_file)
Definition: recogtraining.cpp:84
tesseract::kUniChs
const int kUniChs[]
Definition: baseapi.cpp:1558
tesseract::TessBaseAPI::TextLength
TESS_LOCAL int TextLength(int *blob_count)
Definition: baseapi.cpp:2166
tesseractclass.h
tesseract::ImageThresholder::GetPixRectThresholds
virtual Pix * GetPixRectThresholds()
Definition: thresholder.cpp:209
dawg_cache.h
ASSERT_HOST
#define ASSERT_HOST(x)
Definition: errcode.h:87
tesseract::TessBaseAPI::paragraph_models_
GenericVector< ParagraphModel * > * paragraph_models_
Definition: baseapi.h:891
tesseract::TessBaseAPI::Clear
void Clear()
Definition: baseapi.cpp:1859
tesseract::TessBaseAPI::NumDawgs
int NumDawgs() const
Definition: baseapi.cpp:2302
WERD::bounding_box
TBOX bounding_box() const
Definition: werd.cpp:147
TBLOB::outlines
TESSLINE * outlines
Definition: blobs.h:398
BLOCK::row_list
ROW_LIST * row_list()
get rows
Definition: ocrblock.h:115
tesseract::TessBaseAPI::InitForAnalysePage
void InitForAnalysePage()
Definition: baseapi.cpp:478
tesseract::TessBaseAPI::AnalyseLayout
PageIterator * AnalyseLayout()
Definition: baseapi.cpp:807
baseline
Definition: mfoutline.h:62
INT_FX_RESULT_STRUCT
Definition: intfx.h:34
tesseract::Classify::EnableLearning
bool EnableLearning
Definition: classify.h:577
tesseract::RIL_BLOCK
Definition: publictypes.h:217
tesseract::Tesseract::SetEquationDetect
void SetEquationDetect(EquationDetect *detector)
Definition: tesseractclass.cpp:591
ETEXT_DESC::set_deadline_msecs
void set_deadline_msecs(int32_t deadline_msecs)
Definition: ocrclass.h:121
PAGE_RES_IT::block
BLOCK_RES * block() const
Definition: pageres.h:754
params.h
FCOORD::y
float y() const
Definition: points.h:209
PAGE_RES_IT::row
ROW_RES * row() const
Definition: pageres.h:751
WERD_RES::unlv_crunch_mode
CRUNCH_MODE unlv_crunch_mode
Definition: pageres.h:309
tesseract::Tesseract
Definition: tesseractclass.h:172
kMaxCredibleResolution
constexpr int kMaxCredibleResolution
Definition: publictypes.h:39
tesseract::Tesseract::min_orientation_margin
double min_orientation_margin
Definition: tesseractclass.h:1057
tesseract::TessBaseAPI::DetectOS
bool DetectOS(OSResults *)
Definition: baseapi.cpp:2197
tesseract::PageIterator
Definition: pageiterator.h:52
CR_NONE
Definition: pageres.h:153
tesseract::kBytesPerBoxFileLine
const int kBytesPerBoxFileLine
Definition: baseapi.cpp:1499
tesseract::kUNLVReject
const char kUNLVReject
Definition: baseapi.cpp:108
tesseract::TessBaseAPI::GetComponentImages
Boxa * GetComponentImages(PageIteratorLevel level, bool text_only, bool raw_image, int raw_padding, Pixa **pixa, int **blockids, int **paraids)
Definition: baseapi.cpp:697
tesseract::Classify::matcher_good_threshold
double matcher_good_threshold
Definition: classify.h:456
tesseract::TessBaseAPI::GetTextlines
Boxa * GetTextlines(bool raw_image, int raw_padding, Pixa **pixa, int **blockids, int **paraids)
Definition: baseapi.cpp:652
PAGE_RES_IT::restart_page
WERD_RES * restart_page()
Definition: pageres.h:695
WERD_CHOICE::certainty
float certainty() const
Definition: ratngs.h:318
TBOX::top
int16_t top() const
Definition: rect.h:57
OSResults
Definition: osdetect.h:50
tesseract::Tesseract::set_unlv_suspects
void set_unlv_suspects(WERD_RES *word)
Definition: output.cpp:272
tesseract::ImageThresholder::SetSourceYResolution
void SetSourceYResolution(int ppi)
Definition: thresholder.h:85
tesseract::TessBaseAPI::block_list_
BLOCK_LIST * block_list_
The page layout.
Definition: baseapi.h:892
tesseract::ResultIterator::IsAtBeginningOf
bool IsAtBeginningOf(PageIteratorLevel level) const override
Definition: resultiterator.cpp:527
STRING
Definition: strngs.h:45
tesseract::TessBaseAPI::GetTextDirection
bool GetTextDirection(int *out_offset, float *out_slope)
Definition: baseapi.cpp:1926
UNICHARSET::get_script_from_script_id
const char * get_script_from_script_id(int id) const
Definition: unicharset.h:844
tesseract::Classify::ExtractFeatures
static void ExtractFeatures(const TBLOB &blob, bool nonlinear_norm, GenericVector< INT_FEATURE_STRUCT > *bl_features, GenericVector< INT_FEATURE_STRUCT > *cn_features, INT_FX_RESULT_STRUCT *results, GenericVector< int > *outline_cn_counts)
Definition: intfx.cpp:440
tesseract::ParamsVectors::int_params
GenericVector< IntParam * > int_params
Definition: params.h:57
tesseract::TessBaseAPI::GetIntVariable
bool GetIntVariable(const char *name, int *value) const
Definition: baseapi.cpp:289
tesseract::TessBaseAPI::rect_top_
int rect_top_
Definition: baseapi.h:908
polyblk.h
tesseract::Wordrec::prev_word_best_choice_
WERD_CHOICE * prev_word_best_choice_
Definition: wordrec.h:476
WERD_RES
Definition: pageres.h:160
tesseract::TessBaseAPI::~TessBaseAPI
virtual ~TessBaseAPI()
Definition: baseapi.cpp:226
STRING_VAR
#define STRING_VAR(name, val, comment)
Definition: params.h:306
tesseract::ParamUtils::PrintParams
static void PrintParams(FILE *fp, const ParamsVectors *member_params)
Definition: params.cpp:168
tesseract::FileReader
bool(*)(const char *filename, GenericVector< char > *data) FileReader
Definition: serialis.h:47
tesseract::Tesseract::tessedit_train_line_recognizer
bool tessedit_train_line_recognizer
Definition: tesseractclass.h:791
tesseract::TESS_CHAR::box
TBOX box
Definition: baseapi.cpp:2481
DIR
#define DIR
Definition: polyaprx.cpp:39
tesseract::Tesseract::read_config_file
void read_config_file(const char *filename, SetParamConstraint constraint)
Definition: tessedit.cpp:64
tesseract::PSM_SINGLE_BLOCK
Assume a single uniform block of text. (Default.)
Definition: publictypes.h:168
tesseract::Classify::LearnWord
void LearnWord(const char *fontname, WERD_RES *word)
Definition: adaptmatch.cpp:250
tesseract::TessBaseAPI::GetStringVariable
const char * GetStringVariable(const char *name) const
Definition: baseapi.cpp:305
IntCastRounded
int IntCastRounded(double x)
Definition: helpers.h:173
tesseract::TessBaseAPI::TesseractRect
char * TesseractRect(const unsigned char *imagedata, int bytes_per_pixel, int bytes_per_line, int left, int top, int width, int height)
Definition: baseapi.cpp:533
tesseract::DawgCache::DeleteUnusedDawgs
void DeleteUnusedDawgs()
Definition: dawg_cache.h:43
tesseract::TESS_CHAR::cost
float cost
Definition: baseapi.cpp:2480
tesseract::Tesseract::tessedit_pageseg_mode
int tessedit_pageseg_mode
Definition: tesseractclass.h:799
tesseract::TessBaseAPI::MeanTextConf
int MeanTextConf()
Definition: baseapi.cpp:1749
OSResults::unicharset
UNICHARSET * unicharset
Definition: osdetect.h:80
tesseract::Tesseract::SegmentPage
int SegmentPage(const STRING *input_file, BLOCK_LIST *blocks, Tesseract *osd_tess, OSResults *osr)
Definition: pagesegmain.cpp:113
OSResults::get_best_script
TESS_API int get_best_script(int orientation_id) const
Definition: osdetect.cpp:112
tesseract::ProbabilityInContextFunc
double(Dict::*)(const char *, const char *, int, const char *, int) ProbabilityInContextFunc
Definition: baseapi.h:82
tesseract::TessBaseAPI::GetDatapath
const char * GetDatapath()
Definition: baseapi.cpp:963
tesseract::Dict::GlobalDawgCache
static TESS_API DawgCache * GlobalDawgCache()
Definition: dict.cpp:184
tesseract::TessBaseAPI::rect_height_
int rect_height_
Definition: baseapi.h:910
tesseract::TessBaseAPI::NormalizeTBLOB
static void NormalizeTBLOB(TBLOB *tblob, ROW *row, bool numeric_mode)
Definition: baseapi.cpp:2395
rect.h
ETEXT_DESC
Definition: ocrclass.h:95
FCOORD
Definition: points.h:187
BLOB_CHOICE::unichar_id
UNICHAR_ID unichar_id() const
Definition: ratngs.h:75
tesseract::TessBaseAPI::AllWordConfidences
int * AllWordConfidences()
Definition: baseapi.cpp:1761
tesseract::LTRResultIterator
Definition: ltrresultiterator.h:47
tesseract::TessBaseAPI::Init
int Init(const char *datapath, const char *language, OcrEngineMode mode, char **configs, int configs_size, const GenericVector< STRING > *vars_vec, const GenericVector< STRING > *vars_values, bool set_only_non_debug_params)
Definition: baseapi.cpp:337
ELISTIZEH
#define ELISTIZEH(CLASSNAME)
Definition: elst.h:907
tesseract::Tesseract::get_sub_lang
Tesseract * get_sub_lang(int index) const
Definition: tesseractclass.h:279
tesseract::ImageThresholder::GetSourceYResolution
int GetSourceYResolution() const
Definition: thresholder.h:89
C_BLOB
Definition: stepblob.h:36
tesseract::UNICHAR
Definition: unichar.h:59
tesseract::CCUtil::unicharset
UNICHARSET unicharset
Definition: ccutil.h:57
tesseract::SET_PARAM_CONSTRAINT_DEBUG_ONLY
Definition: params.h:51
tesseract::TessBaseAPI::SetDebugVariable
bool SetDebugVariable(const char *name, const char *value)
Definition: baseapi.cpp:283
tesseract::TessBaseAPI::End
void End()
Definition: baseapi.cpp:1872
resultiterator.h
tesseract::PageIterator::BoundingBoxInternal
bool BoundingBoxInternal(PageIteratorLevel level, int *left, int *top, int *right, int *bottom) const
Definition: pageiterator.cpp:265
tesseract::ParamsVectors::double_params
GenericVector< DoubleParam * > double_params
Definition: params.h:60
tesseract::Tesseract::pgeditor_main
void pgeditor_main(int width, int height, PAGE_RES *page_res)
Definition: pgedit.cpp:378
werd.h
tesseract::TessResultRenderer::AddImage
bool AddImage(TessBaseAPI *api)
Definition: renderer.cpp:82
tesseract::ExtractFontName
void ExtractFontName(const STRING &filename, STRING *fontname)
Definition: blobclass.cpp:45
tesseract::RIL_SYMBOL
Definition: publictypes.h:221
tesseract::TessBaseAPI::GetThresholdedImage
Pix * GetThresholdedImage()
Definition: baseapi.cpp:626
tesseract::TessBaseAPI::SetSourceResolution
void SetSourceResolution(int ppi)
Definition: baseapi.cpp:581
tesseract::TessBaseAPI::FindLinesCreateBlockList
BLOCK_LIST * FindLinesCreateBlockList()
Definition: baseapi.cpp:2331
tesseract::OcrEngineMode
OcrEngineMode
Definition: publictypes.h:265
mutableiterator.h
tesseract::Tesseract::init_tesseract_lm
int init_tesseract_lm(const char *arg0, const char *textbase, const char *language, TessdataManager *mgr)
Definition: tessedit.cpp:469
tesseract::kLatinChs
const int kLatinChs[]
Definition: baseapi.cpp:1562
tesseract::Tesseract::tessedit_resegment_from_line_boxes
bool tessedit_resegment_from_line_boxes
Definition: tesseractclass.h:785
tesseract::Tesseract::tessedit_make_boxes_from_boxes
bool tessedit_make_boxes_from_boxes
Definition: tesseractclass.h:789
tesseract::Tesseract::ApplyBoxTraining
void ApplyBoxTraining(const STRING &fontname, PAGE_RES *page_res)
tesseract::PageIterator::GetImage
Pix * GetImage(PageIteratorLevel level, int padding, Pix *original_img, int *left, int *top) const
Definition: pageiterator.cpp:452
OSBestResult::orientation_id
int orientation_id
Definition: osdetect.h:44
tesseract::TessBaseAPI::GetFeaturesForBlob
void GetFeaturesForBlob(TBLOB *blob, INT_FEATURE_STRUCT *int_features, int *num_features, int *feature_outline_index)
Definition: baseapi.cpp:2604
tesseract::ImageThresholder::Clear
virtual void Clear()
Destroy the Pix if there is one, freeing memory.
Definition: thresholder.cpp:48
tesseract::LTRResultIterator::Confidence
float Confidence(PageIteratorLevel level) const
Definition: ltrresultiterator.cpp:96
tesseract::TessBaseAPI::set_min_orientation_margin
void set_min_orientation_margin(double margin)
Definition: baseapi.cpp:2212
tesseract::Tesseract::set_pix_grey
void set_pix_grey(Pix *grey_pix)
Definition: tesseractclass.h:206
extract_edges
void extract_edges(Pix *pix, BLOCK *block)
Definition: edgblob.cpp:329
GenericVector::push_back
int push_back(T object)
Definition: genericvector.h:799
BLOCK
Definition: ocrblock.h:28
tesseract::TessBaseAPI::truth_cb_
TruthCallback truth_cb_
fxn for setting truth_* in WERD_RES
Definition: baseapi.h:900
openclwrapper.h
BLOCK::pdblk
PDBLK pdblk
Page Description Block.
Definition: ocrblock.h:189
tesseract::TessBaseAPI::ClearAdaptiveClassifier
void ClearAdaptiveClassifier()
Definition: baseapi.cpp:556
tesseract::TESS_CHAR::TESS_CHAR
TESS_CHAR()
Definition: baseapi.cpp:2489
tesseract::TessBaseAPI::rect_width_
int rect_width_
Definition: baseapi.h:909
tesseract::Tesseract::TidyUp
void TidyUp(PAGE_RES *page_res)
tesseract::ParamsVectors::string_params
GenericVector< StringParam * > string_params
Definition: params.h:59
ETEXT_DESC::cancel_this
void * cancel_this
monitor-aware progress callback
Definition: ocrclass.h:109
REJMAP::length
int32_t length() const
Definition: rejctmap.h:222
W_FUZZY_NON
fuzzy nonspace
Definition: werd.h:54
ROW::x_height
float x_height() const
Definition: ocrrow.h:63
tesseract::Tesseract::interactive_display_mode
bool interactive_display_mode
Definition: tesseractclass.h:1047
tesseract::TessBaseAPI::SetVariable
bool SetVariable(const char *name, const char *value)
Definition: baseapi.cpp:277
tesseract::BoxWord::BlobBox
const TBOX & BlobBox(int index) const
Definition: boxword.h:83
baseapi.h
WERD_RES::best_choice
WERD_CHOICE * best_choice
Definition: pageres.h:235
WERD::space
uint8_t space()
Definition: werd.h:98
tesseract::Tesseract::tessedit_resegment_from_boxes
bool tessedit_resegment_from_boxes
Definition: tesseractclass.h:783
tesseract::PageIterator::Empty
bool Empty(PageIteratorLevel level) const
Definition: pageiterator.cpp:349
STRING::c_str
const char * c_str() const
Definition: strngs.cpp:192
tesseract::PageIterator::Next
virtual bool Next(PageIteratorLevel level)
Definition: pageiterator.cpp:147
tesseract::Tesseract::ApplyBoxes
PAGE_RES * ApplyBoxes(const STRING &fname, bool find_segmentation, BLOCK_LIST *block_list)
Definition: applybox.cpp:108
tesseract::kBytesPerNumber
const int kBytesPerNumber
Definition: baseapi.cpp:1493
file
Definition: include_gunit.h:22
BOOL
#define BOOL
Definition: capi.h:43
tesseract::TessBaseAPI::GetWords
Boxa * GetWords(Pixa **pixa)
Definition: baseapi.cpp:675
OSBestResult::oconfidence
float oconfidence
Definition: osdetect.h:47
chomp_string
void chomp_string(char *str)
Definition: helpers.h:75
ROW_RES::row
ROW * row
Definition: pageres.h:136
tesseract::TessBaseAPI::equ_detect_
EquationDetect * equ_detect_
The equation detector.
Definition: baseapi.h:888
edgblob.h
tesseract::TessBaseAPI::osd_tesseract_
Tesseract * osd_tesseract_
For orientation & script detection.
Definition: baseapi.h:887
tesseract::TessBaseAPI::AdaptToCharacter
TESS_LOCAL void AdaptToCharacter(const char *unichar_repr, int length, float baseline, float xheight, float descender, float ascender)
Definition: baseapi.cpp:2426
tesseract::PageIterator::IsAtFinalElement
virtual bool IsAtFinalElement(PageIteratorLevel level, PageIteratorLevel element) const
Definition: pageiterator.cpp:209
tesseract::PageIterator::BlockType
PolyBlockType BlockType() const
Definition: pageiterator.cpp:358
equationdetect.h
UNICHARSET::unichar_to_id
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:209
tesseract::ResultIterator::StartOfParagraph
static ResultIterator * StartOfParagraph(const LTRResultIterator &resit)
Definition: resultiterator.cpp:50
tesseract::PageIterator::GetBinaryImage
Pix * GetBinaryImage(PageIteratorLevel level) const
Definition: pageiterator.cpp:416
W_EOL
end of line
Definition: werd.h:47
tesseract::TessBaseAPI::GetInitLanguagesAsString
const char * GetInitLanguagesAsString() const
Definition: baseapi.cpp:423
tesseract::OEM_DEFAULT
Definition: publictypes.h:271
tesseract::TessBaseAPI::tesseract_
Tesseract * tesseract_
The underlying data object.
Definition: baseapi.h:886
tesseract::Classify::AdaptiveClassifier
void AdaptiveClassifier(TBLOB *Blob, BLOB_CHOICE_LIST *Choices)
Definition: adaptmatch.cpp:191
tesseract::TessBaseAPI::GetIterator
ResultIterator * GetIterator()
Definition: baseapi.cpp:1321
tesseract::TessBaseAPI::IsValidCharacter
bool IsValidCharacter(const char *utf8_character)
Definition: baseapi.cpp:1919
tesseract::Wordrec::wordrec_run_blamer
bool wordrec_run_blamer
Definition: wordrec.h:232
tesseract::UNICHAR::first_uni
int first_uni() const
Definition: unichar.cpp:98
tesseract::TessBaseAPI::GetThresholdedImageScaleFactor
int GetThresholdedImageScaleFactor() const
Definition: baseapi.cpp:785
tesseract::TessBaseAPI::input_file_
STRING * input_file_
Name used by training code.
Definition: baseapi.h:894
stepblob.h
tesseract::Wordrec::fill_lattice_
void(Wordrec::* fill_lattice_)(const MATRIX &ratings, const WERD_CHOICE_LIST &best_choices, const UNICHARSET &unicharset, BlamerBundle *blamer_bundle)
Definition: wordrec.h:480
kMinCredibleResolution
constexpr int kMinCredibleResolution
Definition: publictypes.h:37
tesseract::TessdataManager::LoadMemBuffer
bool LoadMemBuffer(const char *name, const char *data, int size)
Definition: tessdatamanager.cpp:111
tesseract::Tesseract::PrepareForPageseg
void PrepareForPageseg()
Definition: tesseractclass.cpp:641
tesseract::TessBaseAPI::GetUNLVText
char * GetUNLVText()
Definition: baseapi.cpp:1571
MAX_NUM_INT_FEATURES
#define MAX_NUM_INT_FEATURES
Definition: intproto.h:128
GenericVector::empty
bool empty() const
Definition: genericvector.h:86
BOOL_VAR
#define BOOL_VAR(name, val, comment)
Definition: params.h:303
tesseract::Tesseract::getDict
Dict & getDict() override
Definition: tesseractclass.cpp:564
tesseract::TessBaseAPI::SetPageSegMode
void SetPageSegMode(PageSegMode mode)
Definition: baseapi.cpp:506
tesseract::Tesseract::tessedit_ambigs_training
bool tessedit_ambigs_training
Definition: tesseractclass.h:809
tesseract::TESS_CHAR::TESS_CHAR
TESS_CHAR(float _cost, const char *repr, int len=-1)
Definition: baseapi.cpp:2483
tesseract::TessBaseAPI::recognition_done_
bool recognition_done_
page_res_ contains recognition data.
Definition: baseapi.h:899
TBOX::bottom
int16_t bottom() const
Definition: rect.h:64
tesseract::TessBaseAPI::ReadDebugConfigFile
void ReadDebugConfigFile(const char *filename)
Definition: baseapi.cpp:497
tesseract::ParamUtils::GetParamAsString
static bool GetParamAsString(const char *name, const ParamsVectors *member_params, STRING *value)
Definition: params.cpp:129
TBLOB::PolygonalCopy
static TBLOB * PolygonalCopy(bool allow_detailed_fx, C_BLOB *src)
Definition: blobs.cpp:326
GlobalParams
tesseract::ParamsVectors * GlobalParams()
Definition: params.cpp:32
tesseract::kBytesPer64BitNumber
const int kBytesPer64BitNumber
Definition: baseapi.cpp:1501
tesseract::Classify::AdaptedTemplates
ADAPT_TEMPLATES AdaptedTemplates
Definition: classify.h:515
tesseract::PageIteratorLevel
PageIteratorLevel
Definition: publictypes.h:216
tesseract::kMaxIntSize
const int kMaxIntSize
Definition: baseapi.cpp:121
coutln.h
tesseract::TessBaseAPI::GetBoxText
char * GetBoxText(int page_number)
Definition: baseapi.cpp:1517
ROW::bounding_box
TBOX bounding_box() const
Definition: ocrrow.h:87
tesseract::CCUtil::lang
STRING lang
Definition: ccutil.h:55
TBLOB::Normalize
void Normalize(const BLOCK *block, const FCOORD *rotation, const DENORM *predecessor, float x_origin, float y_origin, float x_scale, float y_scale, float final_xshift, float final_yshift, bool inverse, Pix *pix)
Definition: blobs.cpp:396
tesseract::Tesseract::SetBlackAndWhitelist
void SetBlackAndWhitelist()
Definition: tesseractclass.cpp:614
tesseract::TessBaseAPI::Version
static const char * Version()
Definition: baseapi.cpp:233
WERD_RES::reject_map
REJMAP reject_map
Definition: pageres.h:288
helpers.h
tesseract::Classify::InitAdaptiveClassifier
void InitAdaptiveClassifier(TessdataManager *mgr)
Definition: adaptmatch.cpp:527
tesseract
Definition: baseapi.h:65
tesseract::kTesseractReject
const char kTesseractReject
Definition: baseapi.cpp:106
WERD::set_text
void set_text(const char *new_text)
Definition: werd.h:114
tesseract::Tesseract::AnyLSTMLang
bool AnyLSTMLang() const
Definition: tesseractclass.h:293
tesseract::Tesseract::mutable_pix_binary
Pix ** mutable_pix_binary()
Definition: tesseractclass.h:196
tesseract::kMaxBytesPerLine
const int kMaxBytesPerLine
Definition: baseapi.cpp:1508
PAGE_RES_IT::word
WERD_RES * word() const
Definition: pageres.h:748
tesseract::TessBaseAPI::SetInputName
void SetInputName(const char *name)
Definition: baseapi.cpp:262
tesseract::CCUtil::params
ParamsVectors * params()
Definition: ccutil.h:51
tesseract::TessBaseAPI::GetUnichar
const char * GetUnichar(int unichar_id)
Definition: baseapi.cpp:2291
PAGE_RES
Definition: pageres.h:73
tesseract::Tesseract::MaximallyChopWord
void MaximallyChopWord(const GenericVector< TBOX > &boxes, BLOCK *block, ROW *row, WERD_RES *word_res)
Definition: applybox.cpp:242
tesseract::TessBaseAPI::GetBlockTextOrientations
void GetBlockTextOrientations(int **block_orientation, bool **vertical_writing)
Definition: baseapi.cpp:2230
tesseract::Tesseract::tessedit_page_number
int tessedit_page_number
Definition: tesseractclass.h:1045
tprintf.h
BLOB_CHOICE::rating
float rating() const
Definition: ratngs.h:78
tesseract::TessBaseAPI::SetInputImage
void SetInputImage(Pix *pix)
Definition: baseapi.cpp:953
tesseract::RIL_TEXTLINE
Definition: publictypes.h:219
paragraphs.h
UNICHAR_ID
int UNICHAR_ID
Definition: unichar.h:36
tesseract::Tesseract::tessedit_write_images
bool tessedit_write_images
Definition: tesseractclass.h:1046
tesseract::TessBaseAPI::GetAvailableLanguagesAsVector
void GetAvailableLanguagesAsVector(GenericVector< STRING > *langs) const
Definition: baseapi.cpp:447
tesseract::TessBaseAPI::GetTSVText
char * GetTSVText(int page_number)
Definition: baseapi.cpp:1380
TBLOB::bounding_box
TBOX bounding_box() const
Definition: blobs.cpp:466
tesseract::ResultIterator::Next
bool Next(PageIteratorLevel level) override
Definition: resultiterator.cpp:449
tesseract::kMinRectSize
const int kMinRectSize
Definition: baseapi.cpp:104
tesseract::ImageThresholder::GetScaledEstimatedResolution
int GetScaledEstimatedResolution() const
Definition: thresholder.h:105
GenericVector< STRING >
tesseract::ImageThresholder::GetPixRectGrey
virtual Pix * GetPixRectGrey()
Definition: thresholder.cpp:253
tesseract::TessBaseAPI::GetLTRIterator
TESS_LOCAL LTRResultIterator * GetLTRIterator()
Definition: baseapi.cpp:1304
tesseract::Tesseract::num_sub_langs
int num_sub_langs() const
Definition: tesseractclass.h:276
PAGE_RES_IT
Definition: pageres.h:668
tesseract::TessBaseAPI::SetOutputName
void SetOutputName(const char *name)
Definition: baseapi.cpp:270
tesseract::TessBaseAPI::thresholder_
ImageThresholder * thresholder_
Image thresholding module.
Definition: baseapi.h:890
tesseract::ImageThresholder::IsEmpty
bool IsEmpty() const
Return true if no image has been set.
Definition: thresholder.cpp:53
tesseract::Classify::WriteTRFile
bool WriteTRFile(const STRING &filename)
Definition: blobclass.cpp:98
tesseract::ResultIterator
Definition: resultiterator.h:44
tesseract::TessBaseAPI::rect_left_
int rect_left_
Definition: baseapi.h:907
tesseract::TessBaseAPI::GetBoolVariable
bool GetBoolVariable(const char *name, bool *value) const
Definition: baseapi.cpp:297
tesseract::Tesseract::Clear
void Clear()
Definition: tesseractclass.cpp:574
tesseract::PageIterator::Begin
virtual void Begin()
Definition: pageiterator.cpp:105
orientation_and_script_detection
int orientation_and_script_detection(STRING &filename, OSResults *, tesseract::Tesseract *)
Definition: osdetect.cpp:190
tesseract::TessBaseAPI::MakeTBLOB
static TBLOB * MakeTBLOB(Pix *pix)
Definition: baseapi.cpp:2365
tesseract::PSM_AUTO_ONLY
Automatic page segmentation, but no OSD, or OCR.
Definition: publictypes.h:163
tesseract::TessBaseAPI::GetRegions
Boxa * GetRegions(Pixa **pixa)
Definition: baseapi.cpp:640
tesseract::PageIterator::BoundingBox
bool BoundingBox(PageIteratorLevel level, int *left, int *top, int *right, int *bottom) const
Definition: pageiterator.cpp:325
thresholder.h
tesseract::TessBaseAPI::GetInputImage
Pix * GetInputImage()
Definition: baseapi.cpp:955
tesseract::TessBaseAPI::GetPageSegMode
PageSegMode GetPageSegMode() const
Definition: baseapi.cpp:513
tesseract::Tesseract::SetupApplyBoxes
PAGE_RES * SetupApplyBoxes(const GenericVector< TBOX > &boxes, BLOCK_LIST *block_list)
Definition: applybox.cpp:206
tesseract::TessBaseAPI::SetProbabilityInContextFunc
void SetProbabilityInContextFunc(ProbabilityInContextFunc f)
Definition: baseapi.cpp:1975
tesseract::TESS_CHAR::length
int length
Definition: baseapi.cpp:2479
tesseract::Tesseract::TrainLineRecognizer
bool TrainLineRecognizer(const STRING &input_imagename, const STRING &output_basename, BLOCK_LIST *block_list)
Definition: linerec.cpp:43
tesseract::TessBaseAPI::reader_
FileReader reader_
Reads files from any filesystem.
Definition: baseapi.h:889
tesseract::TessBaseAPI::IsValidWord
int IsValidWord(const char *word)
Definition: baseapi.cpp:1915
UNICHAR_LEN
#define UNICHAR_LEN
Definition: unichar.h:32
STRING::length
int32_t length() const
Definition: strngs.cpp:187
tesseract::TessResultRenderer::BeginDocument
bool BeginDocument(const char *title)
Definition: renderer.cpp:71
renderer.h
tesseract::Tesseract::set_pix_original
void set_pix_original(Pix *original_pix)
Definition: tesseractclass.h:214
WERD_CHOICE::length
int length() const
Definition: ratngs.h:291
tesseract::TessResultRenderer
Definition: renderer.h:49
tesseract::Dawg
Definition: dawg.h:113
INT_FEATURE_STRUCT
Definition: intproto.h:131
blobclass.h
W_FUZZY_SP
fuzzy space
Definition: werd.h:53
ocrclass.h
tesseract::ImageThresholder::SetImage
void SetImage(const unsigned char *imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line)
Definition: thresholder.cpp:65
BLOB_CHOICE
Definition: ratngs.h:49
tesseract::TessBaseAPI::MakeTessOCRRow
static ROW * MakeTessOCRRow(float baseline, float xheight, float descender, float ascender)
Definition: baseapi.cpp:2348
tesseract::TessBaseAPI::GetInputName
const char * GetInputName()
Definition: baseapi.cpp:957
TBLOB
Definition: blobs.h:282
tesseract::TessBaseAPI::ProcessPage
bool ProcessPage(Pix *pix, int page_index, const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
Definition: baseapi.cpp:1237
tesseract::TessBaseAPI::ProcessPagesInternal
bool ProcessPagesInternal(const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
Definition: baseapi.cpp:1110
tesseract::PageSegMode
PageSegMode
Definition: publictypes.h:159
PTIsTextType
bool PTIsTextType(PolyBlockType type)
Definition: publictypes.h:81
TBOX::major_overlap
bool major_overlap(const TBOX &box) const
Definition: rect.h:362
WERD
Definition: werd.h:55
BLOCK_RES::block
BLOCK * block
Definition: pageres.h:113
tesseract::TessBaseAPI::GetVariableAsString
bool GetVariableAsString(const char *name, STRING *val)
Definition: baseapi.cpp:320
tesseract::TessBaseAPI::DeleteBlockList
static void DeleteBlockList(BLOCK_LIST *block_list)
Definition: baseapi.cpp:2343
tesseract::Tesseract::pix_binary
Pix * pix_binary() const
Definition: tesseractclass.h:200
TBOX::left
int16_t left() const
Definition: rect.h:71
tesseract::TessBaseAPI::SetFillLatticeFunc
void SetFillLatticeFunc(FillLatticeFunc f)
Definition: baseapi.cpp:1988
ROW
Definition: ocrrow.h:35
UNICHARSET::contains_unichar
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:670
tesseract::TessBaseAPI::TesseractExtractResult
static TESS_LOCAL int TesseractExtractResult(char **text, int **lengths, float **costs, int **x0, int **y0, int **x1, int **y1, PAGE_RES *page_res)
Definition: baseapi.cpp:2552
tesseract::ImageThresholder::ThresholdToPix
virtual bool ThresholdToPix(PageSegMode pageseg_mode, Pix **pix)
Returns false on error.
Definition: thresholder.cpp:185
tesseract::ImageThresholder::GetPixRect
Pix * GetPixRect()
Definition: thresholder.cpp:236
tesseract::TessBaseAPI::FindRowForBox
static ROW * FindRowForBox(BLOCK_LIST *blocks, int left, int top, int right, int bottom)
Definition: baseapi.cpp:2632
tesseract::TessBaseAPI::SetDictFunc
void SetDictFunc(DictFunc f)
Definition: baseapi.cpp:1961
ETEXT_DESC::cancel
CANCEL_FUNC cancel
for errcode use
Definition: ocrclass.h:105
tesseract::Tesseract::ReSegmentByClassification
void ReSegmentByClassification(PAGE_RES *page_res)
BLOCK::blob_list
C_BLOB_LIST * blob_list()
get blobs
Definition: ocrblock.h:127
tesseract::TessBaseAPI::InitLangMod
int InitLangMod(const char *datapath, const char *language)
Definition: baseapi.cpp:464
GenericVector::clear
void clear()
Definition: genericvector.h:857
tesseract::TessBaseAPI::GetDawg
const Dawg * GetDawg(int i) const
Definition: baseapi.cpp:2296
tesseract::TessBaseAPI::TessBaseAPI
TessBaseAPI()
Definition: baseapi.cpp:189
tesseract::ImageThresholder::GetScaleFactor
int GetScaleFactor() const
Definition: thresholder.h:78
TRUE
#define TRUE
Definition: capi.h:44
TBOX::right
int16_t right() const
Definition: rect.h:78
tesseract::Tesseract::CorrectClassifyWords
void CorrectClassifyWords(PAGE_RES *page_res)
tesseract::ResultIterator::GetUTF8Text
virtual char * GetUTF8Text(PageIteratorLevel level) const
Definition: resultiterator.cpp:603
tesseract::Tesseract::set_source_resolution
void set_source_resolution(int ppi)
Definition: tesseractclass.h:247
tesseract::LTRResultIterator::GetUTF8Text
char * GetUTF8Text(PageIteratorLevel level) const
Definition: ltrresultiterator.cpp:45
tesseract::MutableIterator
Definition: mutableiterator.h:44
tprintf
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:34
tesseract::PSM_OSD_ONLY
Orientation and script detection only.
Definition: publictypes.h:160
OSBestResult::sconfidence
float sconfidence
Definition: osdetect.h:46
tesseract::TessBaseAPI::RunAdaptiveClassifier
void RunAdaptiveClassifier(TBLOB *blob, int num_max_matches, int *unichar_ids, float *ratings, int *num_matches_returned)
Definition: baseapi.cpp:2657
tesseract::Dict::getUnicharset
const UNICHARSET & getUnicharset() const
Definition: dict.h:101
tesseract::Dict::GetDawg
const Dawg * GetDawg(int index) const
Return i-th dawg pointer recorded in the dawgs_ vector.
Definition: dict.h:432
errcode.h
tesseract::Tesseract::set_pix_thresholds
void set_pix_thresholds(Pix *thresholds)
Definition: tesseractclass.h:240
tesseract::Tesseract::recog_all_words
bool recog_all_words(PAGE_RES *page_res, ETEXT_DESC *monitor, const TBOX *target_word_box, const char *word_config, int dopasses)
Definition: control.cpp:302
tesseract::Tesseract::textord_equation_detect
bool textord_equation_detect
Definition: tesseractclass.h:1065
tesseract::DetectParagraphs
void DetectParagraphs(int debug_level, GenericVector< RowInfo > *row_infos, GenericVector< PARA * > *row_owners, PARA_LIST *paragraphs, GenericVector< ParagraphModel * > *models)
Definition: paragraphs.cpp:2284
ELIST_LINK
Definition: elst.h:74
tesseract::ParamUtils::SetParam
static bool SetParam(const char *name, const char *value, SetParamConstraint constraint, ParamsVectors *member_params)
Definition: params.cpp:79
tesseract::TessBaseAPI::GetDoubleVariable
bool GetDoubleVariable(const char *name, double *value) const
Definition: baseapi.cpp:311
MAX_PATH
#define MAX_PATH
Definition: platform.h:29
tesseract::Dict::valid_word
int valid_word(const WERD_CHOICE &word, bool numbers_ok) const
Definition: dict.cpp:778
tesseract::kUNLVSuspect
const char kUNLVSuspect
Definition: baseapi.cpp:110
tesseract::TessBaseAPI::FindLines
TESS_LOCAL int FindLines()
Definition: baseapi.cpp:2065
WERD_RES::word
WERD * word
Definition: pageres.h:180
tesseract::Tesseract::init_recog_training
FILE * init_recog_training(const STRING &fname)
Definition: recogtraining.cpp:36
WERD_CHOICE::rating
float rating() const
Definition: ratngs.h:315
tesseract::TessBaseAPI::ClearResults
void ClearResults()
Definition: baseapi.cpp:2141
tesseract::TessBaseAPI::AdaptToWordStr
bool AdaptToWordStr(PageSegMode mode, const char *wordstr)
Definition: baseapi.cpp:1796
tesseract::TessBaseAPI::RecognizeForChopTest
int RecognizeForChopTest(ETEXT_DESC *monitor)
Definition: baseapi.cpp:920
UNICHARSET::id_to_unichar
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:290
tesseract::TessBaseAPI::RecognitionPass1
TESS_LOCAL PAGE_RES * RecognitionPass1(BLOCK_LIST *block_list)
Definition: baseapi.cpp:2461
tesseract::ImageThresholder::SetRectangle
void SetRectangle(int left, int top, int width, int height)
Definition: thresholder.cpp:123
tesseract::kNumbersPerBlob
const int kNumbersPerBlob
Definition: baseapi.cpp:1488
tesseract::TessBaseAPI::datapath_
STRING * datapath_
Current location of tessdata.
Definition: baseapi.h:896
tesseract::Tesseract::ResetAdaptiveClassifier
void ResetAdaptiveClassifier()
Definition: tesseractclass.cpp:597
tesseract::TessBaseAPI::GetUTF8Text
char * GetUTF8Text()
Definition: baseapi.cpp:1348
tesseract::Classify::classify_bln_numeric_mode
bool classify_bln_numeric_mode
Definition: classify.h:508
tesseract::TessBaseAPI::tesseract
Tesseract * tesseract() const
Definition: baseapi.h:798
GenericVector::sort
void sort()
Definition: genericvector.h:1102
CR_KEEP_SPACE
Definition: pageres.h:154
tesseract::TessBaseAPI::getOpenCLDevice
static size_t getOpenCLDevice(void **device)
Definition: baseapi.cpp:244
tesseract::TESS_CHAR
Definition: baseapi.cpp:2477
GenericVector::size
int size() const
Definition: genericvector.h:71
tesseract::OEM_TESSERACT_ONLY
Definition: publictypes.h:266
osdetect.h
ROW::word_list
WERD_LIST * word_list()
Definition: ocrrow.h:54
tesseract::ImageThresholder
Definition: thresholder.h:35
tesseract::Classify::AdaptToChar
void AdaptToChar(TBLOB *Blob, CLASS_ID ClassId, int FontinfoId, float Threshold, ADAPT_TEMPLATES adaptive_templates)
Definition: adaptmatch.cpp:853
tesseract::TessBaseAPI::InternalSetImage
TESS_LOCAL bool InternalSetImage()
Definition: baseapi.cpp:1994
TessResultRenderer
struct TessResultRenderer TessResultRenderer
Definition: capi.h:71
tesseract::TessBaseAPI::oem
OcrEngineMode oem() const
Definition: baseapi.h:802
WERD_CHOICE::unichar_lengths
const STRING & unichar_lengths() const
Definition: ratngs.h:536
boxword.h
tesseract::RIL_PARA
Definition: publictypes.h:218
tesseract::FillLatticeFunc
void(Wordrec::*)(const MATRIX &, const WERD_CHOICE_LIST &, const UNICHARSET &, BlamerBundle *) FillLatticeFunc
Definition: baseapi.h:86
tesseract::TessBaseAPI::GetSourceYResolution
int GetSourceYResolution()
Definition: baseapi.cpp:967
tessdatamanager.h
tesseract::ImageThresholder::GetScaledYResolution
int GetScaledYResolution() const
Definition: thresholder.h:92
tesseract::TessBaseAPI::ReadConfigFile
void ReadConfigFile(const char *filename)
Definition: baseapi.cpp:492
tesseract::TessBaseAPI::image_width_
int image_width_
Definition: baseapi.h:911
tesseract::TessBaseAPI::SetImage
void SetImage(const unsigned char *imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line)
Definition: baseapi.cpp:571
tesseract::TessBaseAPI::Recognize
int Recognize(ETEXT_DESC *monitor)
Definition: baseapi.cpp:827
kBlnBaselineOffset
const int kBlnBaselineOffset
Definition: normalis.h:24
tesseract::TessBaseAPI::output_file_
STRING * output_file_
Name used by debug code.
Definition: baseapi.h:895
tesseract::TessBaseAPI::DetectParagraphs
TESS_LOCAL void DetectParagraphs(bool after_text_recognition)
Definition: baseapi.cpp:2275
ELISTIZE
#define ELISTIZE(CLASSNAME)
Definition: elst.h:919
tesseract::TessBaseAPI::language_
STRING * language_
Last initialized language.
Definition: baseapi.h:897
tesseract::TessBaseAPI::PrintVariables
void PrintVariables(FILE *fp) const
Definition: baseapi.cpp:325
tesseract::HOcrEscape
STRING HOcrEscape(const char *text)
Definition: baseapi.cpp:2307
tesseract::Tesseract::pix_original
Pix * pix_original() const
Definition: tesseractclass.h:210
W_BOL
start of line
Definition: werd.h:46
STRING::split
void split(char c, GenericVector< STRING > *splited)
Definition: strngs.cpp:275
tesseract::ParamUtils::ResetToDefaults
static void ResetToDefaults(ParamsVectors *member_params)
Definition: params.cpp:199
tesseract::PageIterator::Baseline
bool Baseline(PageIteratorLevel level, int *x1, int *y1, int *x2, int *y2) const
Definition: pageiterator.cpp:496
tesseract::ParamsVectors::bool_params
GenericVector< BoolParam * > bool_params
Definition: params.h:58
tesseract::TessBaseAPI::GetOsdText
char * GetOsdText(int page_number)
Definition: baseapi.cpp:1714
points.h
TBOX
Definition: rect.h:33
tesseract::TessBaseAPI::ProcessPages
bool ProcessPages(const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
Definition: baseapi.cpp:1073
tesseract::TessBaseAPI::SetRectangle
void SetRectangle(int left, int top, int width, int height)
Definition: baseapi.cpp:615
tesseract::Dict::letter_is_okay_
int(Dict::* letter_is_okay_)(void *void_dawg_args, const UNICHARSET &unicharset, UNICHAR_ID unichar_id, bool word_end) const
Definition: dict.h:372