Skip to content

Commit 1cc5111

Browse files
committed
Added extra Init that takes a memory buffer or a filereader function pointer to enable read of traineddata from memory or foreign file systems. Updated existing readers to use TFile API instead of FILE. This does not yet add big-endian capability to LSTM, but it is very easy from here.
1 parent 10e04ff commit 1cc5111

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+825
-1191
lines changed

api/baseapi.cpp

+65-39
Original file line numberDiff line numberDiff line change
@@ -108,26 +108,30 @@ const int kMinCredibleResolution = 70;
108108
const int kMaxCredibleResolution = 2400;
109109

110110
TessBaseAPI::TessBaseAPI()
111-
: tesseract_(NULL),
112-
osd_tesseract_(NULL),
113-
equ_detect_(NULL),
114-
// Thresholder is initialized to NULL here, but will be set before use by:
115-
// A constructor of a derived API, SetThresholder(), or
116-
// created implicitly when used in InternalSetImage.
117-
thresholder_(NULL),
118-
paragraph_models_(NULL),
119-
block_list_(NULL),
120-
page_res_(NULL),
121-
input_file_(NULL),
122-
output_file_(NULL),
123-
datapath_(NULL),
124-
language_(NULL),
125-
last_oem_requested_(OEM_DEFAULT),
126-
recognition_done_(false),
127-
truth_cb_(NULL),
128-
rect_left_(0), rect_top_(0), rect_width_(0), rect_height_(0),
129-
image_width_(0), image_height_(0) {
130-
}
111+
: tesseract_(nullptr),
112+
osd_tesseract_(nullptr),
113+
equ_detect_(nullptr),
114+
reader_(nullptr),
115+
// Thresholder is initialized to NULL here, but will be set before use by:
116+
// A constructor of a derived API, SetThresholder(), or
117+
// created implicitly when used in InternalSetImage.
118+
thresholder_(nullptr),
119+
paragraph_models_(nullptr),
120+
block_list_(nullptr),
121+
page_res_(nullptr),
122+
input_file_(nullptr),
123+
output_file_(nullptr),
124+
datapath_(nullptr),
125+
language_(nullptr),
126+
last_oem_requested_(OEM_DEFAULT),
127+
recognition_done_(false),
128+
truth_cb_(NULL),
129+
rect_left_(0),
130+
rect_top_(0),
131+
rect_width_(0),
132+
rect_height_(0),
133+
image_width_(0),
134+
image_height_(0) {}
131135

132136
TessBaseAPI::~TessBaseAPI() {
133137
End();
@@ -275,20 +279,33 @@ int TessBaseAPI::Init(const char* datapath, const char* language,
275279
const GenericVector<STRING> *vars_vec,
276280
const GenericVector<STRING> *vars_values,
277281
bool set_only_non_debug_params) {
282+
return Init(datapath, 0, language, oem, configs, configs_size, vars_vec,
283+
vars_values, set_only_non_debug_params, nullptr);
284+
}
285+
286+
// In-memory version reads the traineddata file directly from the given
287+
// data[data_size] array. Also implements the version with a datapath in data,
288+
// flagged by data_size = 0.
289+
int TessBaseAPI::Init(const char* data, int data_size, const char* language,
290+
OcrEngineMode oem, char** configs, int configs_size,
291+
const GenericVector<STRING>* vars_vec,
292+
const GenericVector<STRING>* vars_values,
293+
bool set_only_non_debug_params, FileReader reader) {
278294
PERF_COUNT_START("TessBaseAPI::Init")
279295
// Default language is "eng".
280-
if (language == NULL) language = "eng";
296+
if (language == nullptr) language = "eng";
297+
STRING datapath = data_size == 0 ? data : language;
281298
// If the datapath, OcrEngineMode or the language have changed - start again.
282299
// Note that the language_ field stores the last requested language that was
283300
// initialized successfully, while tesseract_->lang stores the language
284301
// actually used. They differ only if the requested language was NULL, in
285302
// which case tesseract_->lang is set to the Tesseract default ("eng").
286-
if (tesseract_ != NULL &&
287-
(datapath_ == NULL || language_ == NULL ||
288-
*datapath_ != datapath || last_oem_requested_ != oem ||
303+
if (tesseract_ != nullptr &&
304+
(datapath_ == nullptr || language_ == nullptr || *datapath_ != datapath ||
305+
last_oem_requested_ != oem ||
289306
(*language_ != language && tesseract_->lang != language))) {
290307
delete tesseract_;
291-
tesseract_ = NULL;
308+
tesseract_ = nullptr;
292309
}
293310
// PERF_COUNT_SUB("delete tesseract_")
294311
#ifdef USE_OPENCL
@@ -297,27 +314,33 @@ int TessBaseAPI::Init(const char* datapath, const char* language,
297314
#endif
298315
PERF_COUNT_SUB("OD::InitEnv()")
299316
bool reset_classifier = true;
300-
if (tesseract_ == NULL) {
317+
if (tesseract_ == nullptr) {
301318
reset_classifier = false;
302319
tesseract_ = new Tesseract;
320+
if (reader != nullptr) reader_ = reader;
321+
TessdataManager mgr(reader_);
322+
if (data_size != 0) {
323+
mgr.LoadMemBuffer(language, data, data_size);
324+
}
303325
if (tesseract_->init_tesseract(
304-
datapath, output_file_ != NULL ? output_file_->string() : NULL,
305-
language, oem, configs, configs_size, vars_vec, vars_values,
306-
set_only_non_debug_params) != 0) {
326+
datapath.string(),
327+
output_file_ != nullptr ? output_file_->string() : nullptr,
328+
language, oem, configs, configs_size, vars_vec, vars_values,
329+
set_only_non_debug_params, &mgr) != 0) {
307330
return -1;
308331
}
309332
}
310333
PERF_COUNT_SUB("update tesseract_")
311334
// Update datapath and language requested for the last valid initialization.
312-
if (datapath_ == NULL)
335+
if (datapath_ == nullptr)
313336
datapath_ = new STRING(datapath);
314337
else
315338
*datapath_ = datapath;
316339
if ((strcmp(datapath_->string(), "") == 0) &&
317340
(strcmp(tesseract_->datadir.string(), "") != 0))
318341
*datapath_ = tesseract_->datadir;
319342

320-
if (language_ == NULL)
343+
if (language_ == nullptr)
321344
language_ = new STRING(language);
322345
else
323346
*language_ = language;
@@ -421,7 +444,8 @@ int TessBaseAPI::InitLangMod(const char* datapath, const char* language) {
421444
tesseract_ = new Tesseract;
422445
else
423446
ParamUtils::ResetToDefaults(tesseract_->params());
424-
return tesseract_->init_tesseract_lm(datapath, NULL, language);
447+
TessdataManager mgr;
448+
return tesseract_->init_tesseract_lm(datapath, NULL, language, &mgr);
425449
}
426450

427451
/**
@@ -431,7 +455,7 @@ int TessBaseAPI::InitLangMod(const char* datapath, const char* language) {
431455
void TessBaseAPI::InitForAnalysePage() {
432456
if (tesseract_ == NULL) {
433457
tesseract_ = new Tesseract;
434-
tesseract_->InitAdaptiveClassifier(false);
458+
tesseract_->InitAdaptiveClassifier(nullptr);
435459
}
436460
}
437461

@@ -2239,7 +2263,7 @@ int TessBaseAPI::FindLines() {
22392263
}
22402264
if (tesseract_ == NULL) {
22412265
tesseract_ = new Tesseract;
2242-
tesseract_->InitAdaptiveClassifier(false);
2266+
tesseract_->InitAdaptiveClassifier(nullptr);
22432267
}
22442268
if (tesseract_->pix_binary() == NULL)
22452269
Threshold(tesseract_->mutable_pix_binary());
@@ -2261,22 +2285,24 @@ int TessBaseAPI::FindLines() {
22612285

22622286
Tesseract* osd_tess = osd_tesseract_;
22632287
OSResults osr;
2264-
if (PSM_OSD_ENABLED(tesseract_->tessedit_pageseg_mode) && osd_tess == NULL) {
2288+
if (PSM_OSD_ENABLED(tesseract_->tessedit_pageseg_mode) &&
2289+
osd_tess == nullptr) {
22652290
if (strcmp(language_->string(), "osd") == 0) {
22662291
osd_tess = tesseract_;
22672292
} else {
22682293
osd_tesseract_ = new Tesseract;
2269-
if (osd_tesseract_->init_tesseract(
2270-
datapath_->string(), NULL, "osd", OEM_TESSERACT_ONLY,
2271-
NULL, 0, NULL, NULL, false) == 0) {
2294+
TessdataManager mgr(reader_);
2295+
if (osd_tesseract_->init_tesseract(datapath_->string(), nullptr, "osd",
2296+
OEM_TESSERACT_ONLY, nullptr, 0,
2297+
nullptr, nullptr, false, &mgr) == 0) {
22722298
osd_tess = osd_tesseract_;
22732299
osd_tesseract_->set_source_resolution(
22742300
thresholder_->GetSourceYResolution());
22752301
} else {
22762302
tprintf("Warning: Auto orientation and script detection requested,"
22772303
" but osd language failed to load\n");
22782304
delete osd_tesseract_;
2279-
osd_tesseract_ = NULL;
2305+
osd_tesseract_ = nullptr;
22802306
}
22812307
}
22822308
}

api/baseapi.h

+14-5
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@
2929
// To avoid collision with other typenames include the ABSOLUTE MINIMUM
3030
// complexity of includes here. Use forward declarations wherever possible
3131
// and hide includes of complex types in baseapi.cpp.
32-
#include "platform.h"
3332
#include "apitypes.h"
34-
#include "thresholder.h"
35-
#include "unichar.h"
36-
#include "tesscallback.h"
37-
#include "publictypes.h"
3833
#include "pageiterator.h"
34+
#include "platform.h"
35+
#include "publictypes.h"
3936
#include "resultiterator.h"
37+
#include "serialis.h"
38+
#include "tesscallback.h"
39+
#include "thresholder.h"
40+
#include "unichar.h"
4041

4142
template <typename T> class GenericVector;
4243
class PAGE_RES;
@@ -237,6 +238,13 @@ class TESS_API TessBaseAPI {
237238
int Init(const char* datapath, const char* language) {
238239
return Init(datapath, language, OEM_DEFAULT, NULL, 0, NULL, NULL, false);
239240
}
241+
// In-memory version reads the traineddata file directly from the given
242+
// data[data_size] array, and/or reads data via a FileReader.
243+
int Init(const char* data, int data_size, const char* language,
244+
OcrEngineMode mode, char** configs, int configs_size,
245+
const GenericVector<STRING>* vars_vec,
246+
const GenericVector<STRING>* vars_values,
247+
bool set_only_non_debug_params, FileReader reader);
240248

241249
/**
242250
* Returns the languages string used in the last valid initialization.
@@ -859,6 +867,7 @@ class TESS_API TessBaseAPI {
859867
Tesseract* tesseract_; ///< The underlying data object.
860868
Tesseract* osd_tesseract_; ///< For orientation & script detection.
861869
EquationDetect* equ_detect_; ///<The equation detector.
870+
FileReader reader_; ///< Reads files from any filesystem.
862871
ImageThresholder* thresholder_; ///< Image thresholding module.
863872
GenericVector<ParagraphModel *>* paragraph_models_;
864873
BLOCK_LIST* block_list_; ///< The page layout.

0 commit comments

Comments
 (0)