@luii/node-tesseract-ocr 2.0.13 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,20 +20,86 @@
20
20
  #include <cstddef>
21
21
  #include <cstdint>
22
22
  #include <cstring>
23
+ #include <iostream>
23
24
  #include <leptonica/allheaders.h>
24
25
  #include <string>
25
26
  #include <tesseract/publictypes.h>
26
27
 
27
28
  Napi::FunctionReference TesseractWrapper::constructor;
28
29
 
30
+ namespace {
31
+
32
+ Napi::Value RejectWithError(Napi::Env env, Napi::Error error, const char *code,
33
+ const std::string &message, const char *method) {
34
+ error.Set("code", Napi::String::New(env, code));
35
+ error.Set("method", Napi::String::New(env, method));
36
+
37
+ Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
38
+ deferred.Reject(error.Value());
39
+ return deferred.Promise();
40
+ }
41
+
42
+ Napi::Value RejectError(Napi::Env env, const std::string &message,
43
+ const char *method) {
44
+ return RejectWithError(env, Napi::Error::New(env, message),
45
+ "ERR_TESSERACT_RUNTIME", message, method);
46
+ }
47
+
48
+ Napi::Value RejectTypeError(Napi::Env env, const std::string &message,
49
+ const char *method) {
50
+ return RejectWithError(env, Napi::TypeError::New(env, message),
51
+ "ERR_INVALID_ARGUMENT", message, method);
52
+ }
53
+
54
+ Napi::Value RejectRangeError(Napi::Env env, const std::string &message,
55
+ const char *method) {
56
+ return RejectWithError(env, Napi::RangeError::New(env, message),
57
+ "ERR_OUT_OF_RANGE", message, method);
58
+ }
59
+
60
+ bool HasArg(const Napi::CallbackInfo &info, size_t index) {
61
+ return info.Length() > index && !info[index].IsUndefined();
62
+ }
63
+
64
+ } // namespace
65
+
29
66
  Napi::Object TesseractWrapper::InitAddon(Napi::Env env, Napi::Object exports) {
30
67
  Napi::Function func = DefineClass(
31
68
  env, "Tesseract",
32
69
  {
70
+ InstanceMethod("version", &TesseractWrapper::Version),
71
+ InstanceMethod("isInitialized", &TesseractWrapper::IsInitialized),
72
+ InstanceMethod("setInputName", &TesseractWrapper::SetInputName),
73
+ InstanceMethod("getInputName", &TesseractWrapper::GetInputName),
74
+ InstanceMethod("setInputImage", &TesseractWrapper::SetInputImage),
75
+ InstanceMethod("getInputImage", &TesseractWrapper::GetInputImage),
76
+ InstanceMethod("getSourceYResolution",
77
+ &TesseractWrapper::GetSourceYResolution),
78
+ InstanceMethod("getDataPath", &TesseractWrapper::GetDataPath),
79
+ InstanceMethod("setOutputName", &TesseractWrapper::SetOutputName),
80
+ InstanceMethod("clearPersistentCache",
81
+ &TesseractWrapper::ClearPersistentCache),
82
+ InstanceMethod("clearAdaptiveClassifier",
83
+ &TesseractWrapper::ClearAdaptiveClassifier),
84
+ InstanceMethod("getThresholdedImage",
85
+ &TesseractWrapper::GetThresholdedImage),
86
+ InstanceMethod("getThresholdedImageScaleFactor",
87
+ &TesseractWrapper::GetThresholdedImageScaleFactor),
33
88
  InstanceMethod("init", &TesseractWrapper::Init),
34
89
  InstanceMethod("initForAnalysePage",
35
90
  &TesseractWrapper::InitForAnalysePage),
36
- InstanceMethod("analysePage", &TesseractWrapper::AnalysePage),
91
+ InstanceMethod("analyseLayout", &TesseractWrapper::AnalyseLayout),
92
+ InstanceMethod("beginProcessPages",
93
+ &TesseractWrapper::BeginProcessPages),
94
+ InstanceMethod("addProcessPage", &TesseractWrapper::AddProcessPage),
95
+ InstanceMethod("finishProcessPages",
96
+ &TesseractWrapper::FinishProcessPages),
97
+ InstanceMethod("abortProcessPages",
98
+ &TesseractWrapper::AbortProcessPages),
99
+ InstanceMethod("getProcessPagesStatus",
100
+ &TesseractWrapper::GetProcessPagesStatus),
101
+ InstanceMethod("setDebugVariable",
102
+ &TesseractWrapper::SetDebugVariable),
37
103
  InstanceMethod("setVariable", &TesseractWrapper::SetVariable),
38
104
  InstanceMethod("getIntVariable", &TesseractWrapper::GetIntVariable),
39
105
  InstanceMethod("getBoolVariable", &TesseractWrapper::GetBoolVariable),
@@ -41,9 +107,9 @@ Napi::Object TesseractWrapper::InitAddon(Napi::Env env, Napi::Object exports) {
41
107
  &TesseractWrapper::GetDoubleVariable),
42
108
  InstanceMethod("getStringVariable",
43
109
  &TesseractWrapper::GetStringVariable),
110
+ InstanceMethod("setImage", &TesseractWrapper::SetImage),
44
111
  // InstanceMethod("printVariables",
45
112
  // &TesseractWrapper::PrintVariables),
46
- InstanceMethod("setImage", &TesseractWrapper::SetImage),
47
113
  InstanceMethod("setPageMode", &TesseractWrapper::SetPageMode),
48
114
  InstanceMethod("setRectangle", &TesseractWrapper::SetRectangle),
49
115
  InstanceMethod("setSourceResolution",
@@ -52,6 +118,14 @@ Napi::Object TesseractWrapper::InitAddon(Napi::Env env, Napi::Object exports) {
52
118
  InstanceMethod("detectOrientationScript",
53
119
  &TesseractWrapper::DetectOrientationScript),
54
120
  InstanceMethod("meanTextConf", &TesseractWrapper::MeanTextConf),
121
+ InstanceMethod("allWordConfidences",
122
+ &TesseractWrapper::AllWordConfidences),
123
+ InstanceMethod("getPAGEText", &TesseractWrapper::GetPAGEText),
124
+ InstanceMethod("getLSTMBoxText", &TesseractWrapper::GetLSTMBoxText),
125
+ InstanceMethod("getBoxText", &TesseractWrapper::GetBoxText),
126
+ InstanceMethod("getWordStrBoxText",
127
+ &TesseractWrapper::GetWordStrBoxText),
128
+ InstanceMethod("getOSDText", &TesseractWrapper::getOSDText),
55
129
  InstanceMethod("getUTF8Text", &TesseractWrapper::GetUTF8Text),
56
130
  InstanceMethod("getHOCRText", &TesseractWrapper::GetHOCRText),
57
131
  InstanceMethod("getTSVText", &TesseractWrapper::GetTSVText),
@@ -79,31 +153,210 @@ TesseractWrapper::TesseractWrapper(const Napi::CallbackInfo &info)
79
153
 
80
154
  TesseractWrapper::~TesseractWrapper() {}
81
155
 
156
+ Napi::Value TesseractWrapper::Version(const Napi::CallbackInfo &info) {
157
+ return _worker_thread.Enqueue(CommandVersion{});
158
+ }
159
+
160
+ Napi::Value TesseractWrapper::IsInitialized(const Napi::CallbackInfo &info) {
161
+ Napi::Env env = info.Env();
162
+
163
+ if (info.Length() > 0) {
164
+ return RejectTypeError(env, "isInitialized(): expected no arguments",
165
+ "isInitialized");
166
+ }
167
+
168
+ return _worker_thread.Enqueue(CommandIsInitialized{});
169
+ }
170
+
171
+ Napi::Value TesseractWrapper::SetInputName(const Napi::CallbackInfo &info) {
172
+ Napi::Env env = info.Env();
173
+
174
+ if (info.Length() > 1) {
175
+ return RejectTypeError(
176
+ env, "setInputName(inputName?): expected at most 1 argument",
177
+ "setInputName");
178
+ }
179
+
180
+ CommandSetInputName command{};
181
+ if (HasArg(info, 0)) {
182
+ if (!info[0].IsString()) {
183
+ return RejectTypeError(
184
+ env, "setInputName(inputName?): inputName must be a string",
185
+ "setInputName");
186
+ }
187
+
188
+ command.input_name = info[0].As<Napi::String>().Utf8Value();
189
+ }
190
+
191
+ return _worker_thread.Enqueue(command);
192
+ }
193
+
194
+ Napi::Value TesseractWrapper::GetInputName(const Napi::CallbackInfo &info) {
195
+ return _worker_thread.Enqueue(CommandGetInputName{});
196
+ }
197
+
198
+ Napi::Value TesseractWrapper::SetInputImage(const Napi::CallbackInfo &info) {
199
+ Napi::Env env = info.Env();
200
+
201
+ if (info.Length() > 1) {
202
+ return RejectTypeError(
203
+ env, "setInputImage(buffer?): expected at most 1 argument",
204
+ "setInputImage");
205
+ }
206
+
207
+ CommandSetInputImage command{};
208
+ if (HasArg(info, 0)) {
209
+ if (!info[0].IsBuffer()) {
210
+ return RejectTypeError(env,
211
+ "setInputImage(buffer?): buffer must be a Buffer",
212
+ "setInputImage");
213
+ }
214
+
215
+ Napi::Buffer<uint8_t> image_buffer = info[0].As<Napi::Buffer<uint8_t>>();
216
+ const uint8_t *data = image_buffer.Data();
217
+ const size_t length = image_buffer.Length();
218
+
219
+ if (length == 0) {
220
+ return RejectTypeError(env, "setInputImage(buffer?): buffer is empty",
221
+ "setInputImage");
222
+ }
223
+
224
+ command.bytes.assign(data, data + length);
225
+ }
226
+
227
+ return _worker_thread.Enqueue(command);
228
+ }
229
+
230
+ Napi::Value TesseractWrapper::GetInputImage(const Napi::CallbackInfo &info) {
231
+ Napi::Env env = info.Env();
232
+
233
+ if (info.Length() > 0) {
234
+ return RejectTypeError(env, "getInputImage(): expected no arguments",
235
+ "getInputImage");
236
+ }
237
+
238
+ return _worker_thread.Enqueue(CommandGetInputImage{});
239
+ }
240
+
241
+ Napi::Value
242
+ TesseractWrapper::GetSourceYResolution(const Napi::CallbackInfo &info) {
243
+ Napi::Env env = info.Env();
244
+
245
+ if (info.Length() > 0) {
246
+ return RejectTypeError(env, "getSourceYResolution(): expected no arguments",
247
+ "getSourceYResolution");
248
+ }
249
+
250
+ return _worker_thread.Enqueue(CommandGetSourceYResolution{});
251
+ }
252
+
253
+ Napi::Value TesseractWrapper::GetDataPath(const Napi::CallbackInfo &info) {
254
+ Napi::Env env = info.Env();
255
+
256
+ if (info.Length() > 0) {
257
+ return RejectTypeError(env, "getDataPath(): expected no arguments",
258
+ "getDataPath");
259
+ }
260
+
261
+ return _worker_thread.Enqueue(CommandGetDataPath{});
262
+ }
263
+
264
+ Napi::Value TesseractWrapper::SetOutputName(const Napi::CallbackInfo &info) {
265
+ Napi::Env env = info.Env();
266
+ CommandSetOutputName command{};
267
+
268
+ if (info.Length() != 1 || !info[0].IsString()) {
269
+ return RejectTypeError(
270
+ env, "setOutputName(outputName): outputName must be a string",
271
+ "setOutputName");
272
+ }
273
+
274
+ command.output_name = info[0].As<Napi::String>().Utf8Value();
275
+ return _worker_thread.Enqueue(command);
276
+ }
277
+
278
+ Napi::Value
279
+ TesseractWrapper::ClearPersistentCache(const Napi::CallbackInfo &info) {
280
+ Napi::Env env = info.Env();
281
+
282
+ if (info.Length() > 0) {
283
+ return RejectTypeError(env, "clearPersistentCache(): expected no arguments",
284
+ "clearPersistentCache");
285
+ }
286
+
287
+ return _worker_thread.Enqueue(CommandClearPersistentCache{});
288
+ }
289
+
290
+ Napi::Value
291
+ TesseractWrapper::ClearAdaptiveClassifier(const Napi::CallbackInfo &info) {
292
+ Napi::Env env = info.Env();
293
+
294
+ if (info.Length() > 0) {
295
+ return RejectTypeError(env,
296
+ "clearAdaptiveClassifier(): expected no arguments",
297
+ "clearAdaptiveClassifier");
298
+ }
299
+
300
+ return _worker_thread.Enqueue(CommandClearAdaptiveClassifier{});
301
+ }
302
+
303
+ Napi::Value
304
+ TesseractWrapper::GetThresholdedImage(const Napi::CallbackInfo &info) {
305
+ Napi::Env env = info.Env();
306
+
307
+ if (info.Length() > 0) {
308
+ return RejectTypeError(env, "getThresholdedImage(): expected no arguments",
309
+ "getThresholdedImage");
310
+ }
311
+
312
+ return _worker_thread.Enqueue(CommandGetThresholdedImage{});
313
+ }
314
+
315
+ Napi::Value TesseractWrapper::GetThresholdedImageScaleFactor(
316
+ const Napi::CallbackInfo &info) {
317
+ Napi::Env env = info.Env();
318
+
319
+ if (info.Length() > 0) {
320
+ return RejectTypeError(
321
+ env, "getThresholdedImageScaleFactor(): expected no arguments",
322
+ "getThresholdedImageScaleFactor");
323
+ }
324
+
325
+ return _worker_thread.Enqueue(CommandGetThresholdedImageScaleFactor{});
326
+ }
327
+
82
328
  Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
83
329
  Napi::Env env = info.Env();
84
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
85
330
 
86
331
  if (info.Length() != 1 || !info[0].IsObject()) {
87
- deferred.Reject(
88
- Napi::TypeError::New(
89
- env, "Expected required argument at index 0 to be of type object")
90
- .Value());
91
- return deferred.Promise();
332
+ return RejectTypeError(
333
+ env, "init(options): required argument at index 0 must be an object",
334
+ "init");
92
335
  }
93
336
 
94
337
  auto options = info[0].As<Napi::Object>();
95
338
  CommandInit command{};
96
339
 
97
- const Napi::Value langOption = options.Get("lang");
98
- if (!langOption.IsUndefined()) {
99
- if (!langOption.IsArray()) {
100
- deferred.Reject(
101
- Napi::TypeError::New(env, "Option 'lang' must be a array of strings")
102
- .Value());
103
- return deferred.Promise();
340
+ const Napi::Value dataPathOption = options.Get("dataPath");
341
+ if (!dataPathOption.IsUndefined()) {
342
+ if (!dataPathOption.IsString()) {
343
+ return RejectTypeError(
344
+ env, "init(options): options.dataPath must be a string", "init");
104
345
  }
105
346
 
106
- Napi::Array languages = langOption.As<Napi::Array>();
347
+ Napi::String dataPath = dataPathOption.As<Napi::String>();
348
+ command.data_path = dataPath.Utf8Value();
349
+ }
350
+
351
+ const Napi::Value langsOption = options.Get("langs");
352
+ if (!langsOption.IsUndefined()) {
353
+ if (!langsOption.IsArray()) {
354
+ return RejectTypeError(
355
+ env, "init(options): options.langs must be an array of strings",
356
+ "init");
357
+ }
358
+
359
+ Napi::Array languages = langsOption.As<Napi::Array>();
107
360
  std::string language;
108
361
 
109
362
  for (uint32_t i = 0; i < languages.Length(); ++i) {
@@ -120,18 +373,15 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
120
373
  const Napi::Value engineModeOption = options.Get("oem");
121
374
  if (!engineModeOption.IsUndefined()) {
122
375
  if (!engineModeOption.IsNumber()) {
123
- deferred.Reject(
124
- Napi::TypeError::New(env, "Option 'oem' must be of type number")
125
- .Value());
126
- return deferred.Promise();
376
+ return RejectTypeError(env, "init(options): options.oem must be a number",
377
+ "init");
127
378
  }
128
379
  tesseract::OcrEngineMode oem = static_cast<tesseract::OcrEngineMode>(
129
380
  engineModeOption.As<Napi::Number>().Int32Value());
130
381
 
131
382
  if (oem < 0 || oem >= tesseract::OEM_COUNT) {
132
- deferred.Reject(
133
- Napi::TypeError::New(env, "Unsupported OCR Engine Mode").Value());
134
- return deferred.Promise();
383
+ return RejectRangeError(
384
+ env, "init(options): options.oem is out of supported range", "init");
135
385
  }
136
386
 
137
387
  command.oem = oem;
@@ -141,11 +391,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
141
391
  options.Get("setOnlyNonDebugParams");
142
392
  if (!set_only_non_debug_params.IsUndefined()) {
143
393
  if (!set_only_non_debug_params.IsBoolean()) {
144
- deferred.Reject(
145
- Napi::TypeError::New(
146
- env, "Option 'setOnlyNonDebugParams' must be of type boolean")
147
- .Value());
148
- return deferred.Promise();
394
+ return RejectTypeError(
395
+ env, "init(options): options.setOnlyNonDebugParams must be a boolean",
396
+ "init");
149
397
  }
150
398
 
151
399
  command.set_only_non_debug_params =
@@ -155,10 +403,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
155
403
  const Napi::Value v = options.Get("configs");
156
404
  if (!v.IsUndefined()) {
157
405
  if (!v.IsArray()) {
158
- deferred.Reject(Napi::TypeError::New(
159
- env, "Option 'configs' must be an array of strings")
160
- .Value());
161
- return deferred.Promise();
406
+ return RejectTypeError(
407
+ env, "init(options): options.configs must be an array of strings",
408
+ "init");
162
409
  }
163
410
 
164
411
  Napi::Array arr = v.As<Napi::Array>();
@@ -170,10 +417,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
170
417
  for (uint32_t i = 0; i < len; ++i) {
171
418
  Napi::Value item = arr.Get(i);
172
419
  if (!item.IsString()) {
173
- deferred.Reject(Napi::TypeError::New(
174
- env, "Option 'configs' must contain only strings")
175
- .Value());
176
- return deferred.Promise();
420
+ return RejectTypeError(
421
+ env, "init(options): options.configs must contain only strings",
422
+ "init");
177
423
  }
178
424
  command.configs_storage.emplace_back(item.As<Napi::String>().Utf8Value());
179
425
  }
@@ -188,10 +434,8 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
188
434
 
189
435
  if (!varsOption.IsUndefined()) {
190
436
  if (!varsOption.IsObject()) {
191
- deferred.Reject(
192
- Napi::TypeError::New(env, "Options 'vars' must be of type object")
193
- .Value());
194
- return deferred.Promise();
437
+ return RejectTypeError(
438
+ env, "init(options): options.vars must be an object", "init");
195
439
  }
196
440
 
197
441
  // Napi::Array a = vars_vec.As<Napi::Array>();
@@ -206,10 +450,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
206
450
  for (uint32_t i = 0; i < length; ++i) {
207
451
  Napi::Value variable_value = vars.Get(variable_names.Get(i));
208
452
  if (!variable_names.Get(i).IsString() || !variable_value.IsString()) {
209
- deferred.Reject(
210
- Napi::TypeError::New(env, "'vars' must contain only strings")
211
- .Value());
212
- return deferred.Promise();
453
+ return RejectTypeError(
454
+ env, "init(options): options.vars must contain only strings",
455
+ "init");
213
456
  }
214
457
  command.vars_vec.emplace_back(
215
458
  variable_names.Get(i).As<Napi::String>().Utf8Value());
@@ -226,22 +469,22 @@ TesseractWrapper::InitForAnalysePage(const Napi::CallbackInfo &info) {
226
469
  return _worker_thread.Enqueue(CommandInitForAnalysePage{});
227
470
  }
228
471
 
229
- Napi::Value TesseractWrapper::AnalysePage(const Napi::CallbackInfo &info) {
472
+ Napi::Value TesseractWrapper::AnalyseLayout(const Napi::CallbackInfo &info) {
230
473
  Napi::Env env = info.Env();
231
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
232
474
  CommandAnalyseLayout command{};
233
475
 
234
476
  if (info.Length() > 1) {
235
- deferred.Reject(Napi::Error::New(env, "Too many arguments").Value());
236
- return deferred.Promise();
477
+ return RejectTypeError(
478
+ env, "analyseLayout(mergeSimilarWords?): expected at most 1 argument",
479
+ "analyseLayout");
237
480
  }
238
481
 
239
- if (!info[0].IsUndefined()) {
482
+ if (HasArg(info, 0)) {
240
483
  if (!info[0].IsBoolean()) {
241
- deferred.Reject(
242
- Napi::Error::New(env, "Expected argument to be of type boolean")
243
- .Value());
244
- return deferred.Promise();
484
+ return RejectTypeError(env,
485
+ "analyseLayout(mergeSimilarWords?): "
486
+ "mergeSimilarWords must be a boolean",
487
+ "analyseLayout");
245
488
  }
246
489
 
247
490
  command.merge_similar_words = info[0].As<Napi::Boolean>().Value();
@@ -250,38 +493,152 @@ Napi::Value TesseractWrapper::AnalysePage(const Napi::CallbackInfo &info) {
250
493
  return _worker_thread.Enqueue(command);
251
494
  }
252
495
 
253
- Napi::Value TesseractWrapper::SetPageMode(const Napi::CallbackInfo &info) {
496
+ Napi::Value
497
+ TesseractWrapper::BeginProcessPages(const Napi::CallbackInfo &info) {
254
498
  Napi::Env env = info.Env();
255
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
256
- CommandSetPageMode command{};
499
+ CommandBeginProcessPages command{};
257
500
 
258
- if (info.Length() > 1) {
259
- deferred.Reject(
260
- Napi::Error::New(env, "Expected only one parameter").Value());
261
- return deferred.Promise();
501
+ if (info.Length() != 1 || !info[0].IsObject()) {
502
+ return RejectTypeError(
503
+ env, "beginProcessPages(options): options must be an object",
504
+ "beginProcessPages");
262
505
  }
263
506
 
264
- if (!info[0].IsUndefined()) {
265
- if (!info[0].IsNumber()) {
266
- deferred.Reject(
267
- Napi::Error::New(
268
- env, "Expected page segmentation mode to be of type number")
269
- .Value());
270
- return deferred.Promise();
507
+ Napi::Object options = info[0].As<Napi::Object>();
508
+
509
+ Napi::Value output_base = options.Get("outputBase");
510
+ if (!output_base.IsUndefined()) {
511
+ if (!output_base.IsString()) {
512
+ return RejectTypeError(
513
+ env,
514
+ "beginProcessPages(options): options.outputBase must be a string",
515
+ "beginProcessPages");
271
516
  }
517
+ command.output_base = output_base.As<Napi::String>().Utf8Value();
518
+ }
272
519
 
273
- tesseract::PageSegMode psm = static_cast<tesseract::PageSegMode>(
274
- info[0].As<Napi::Number>().Int32Value());
520
+ Napi::Value title = options.Get("title");
521
+ if (title.IsUndefined() || !title.IsString()) {
522
+ return RejectTypeError(env,
523
+ "beginProcessPages(options): options.title is "
524
+ "required and must be a string",
525
+ "beginProcessPages");
526
+ }
527
+ command.title = title.As<Napi::String>().Utf8Value();
528
+
529
+ Napi::Value timeout = options.Get("timeout");
530
+ if (!timeout.IsUndefined()) {
531
+ if (!timeout.IsNumber()) {
532
+ return RejectTypeError(
533
+ env, "beginProcessPages(options): options.timeout must be a number",
534
+ "beginProcessPages");
535
+ }
536
+ command.timeout_millisec = timeout.As<Napi::Number>().Int32Value();
537
+ }
275
538
 
276
- if (psm < 0 || psm >= tesseract::PageSegMode::PSM_COUNT) {
277
- deferred.Reject(
278
- Napi::Error::New(env, "Page Segmentation Mode out of range").Value());
279
- return deferred.Promise();
539
+ Napi::Value textonly = options.Get("textonly");
540
+ if (!textonly.IsUndefined()) {
541
+ if (!textonly.IsBoolean()) {
542
+ return RejectTypeError(
543
+ env, "beginProcessPages(options): options.textonly must be a boolean",
544
+ "beginProcessPages");
280
545
  }
546
+ command.textonly = textonly.As<Napi::Boolean>().Value();
547
+ }
281
548
 
282
- command.psm = psm;
549
+ return _worker_thread.Enqueue(std::move(command));
550
+ }
551
+
552
+ Napi::Value TesseractWrapper::AddProcessPage(const Napi::CallbackInfo &info) {
553
+ Napi::Env env = info.Env();
554
+ CommandAddProcessPage command{};
555
+
556
+ if (info.Length() < 1 || info.Length() > 2) {
557
+ return RejectTypeError(
558
+ env, "addProcessPage(buffer, filename?): expected 1 or 2 arguments",
559
+ "addProcessPage");
283
560
  }
284
561
 
562
+ if (!info[0].IsBuffer()) {
563
+ return RejectTypeError(
564
+ env, "addProcessPage(buffer, filename?): buffer must be a Buffer",
565
+ "addProcessPage");
566
+ }
567
+
568
+ Napi::Buffer<uint8_t> page_buffer = info[0].As<Napi::Buffer<uint8_t>>();
569
+ const size_t length = page_buffer.Length();
570
+ if (length == 0) {
571
+ return RejectTypeError(env,
572
+ "addProcessPage(buffer, filename?): buffer is empty",
573
+ "addProcessPage");
574
+ }
575
+
576
+ if (HasArg(info, 1)) {
577
+ if (!info[1].IsString()) {
578
+ return RejectTypeError(
579
+ env, "addProcessPage(buffer, filename?): filename must be a string",
580
+ "addProcessPage");
581
+ }
582
+ command.filename = info[1].As<Napi::String>().Utf8Value();
583
+ }
584
+
585
+ command.page.bytes.resize(length);
586
+ std::memcpy(command.page.bytes.data(), page_buffer.Data(), length);
587
+
588
+ return _worker_thread.Enqueue(std::move(command));
589
+ }
590
+
591
+ Napi::Value
592
+ TesseractWrapper::FinishProcessPages(const Napi::CallbackInfo &info) {
593
+ return _worker_thread.Enqueue(CommandFinishProcessPages{});
594
+ }
595
+
596
+ Napi::Value
597
+ TesseractWrapper::AbortProcessPages(const Napi::CallbackInfo &info) {
598
+ CommandAbortProcessPages command{};
599
+ if (info.Length() > 0 && info[0].IsString()) {
600
+ command.reason = info[0].As<Napi::String>().Utf8Value();
601
+ }
602
+ return _worker_thread.Enqueue(std::move(command));
603
+ }
604
+
605
+ Napi::Value
606
+ TesseractWrapper::GetProcessPagesStatus(const Napi::CallbackInfo &info) {
607
+ Napi::Env env = info.Env();
608
+
609
+ if (info.Length() > 0) {
610
+ return RejectTypeError(env,
611
+ "getProcessPagesStatus(): expected no arguments",
612
+ "getProcessPagesStatus");
613
+ }
614
+
615
+ return _worker_thread.Enqueue(CommandGetProcessPagesStatus{});
616
+ }
617
+
618
+ Napi::Value TesseractWrapper::SetDebugVariable(const Napi::CallbackInfo &info) {
619
+ Napi::Env env = info.Env();
620
+ CommandSetDebugVariable command{};
621
+
622
+ if (info.Length() != 2) {
623
+ return RejectTypeError(
624
+ env, "setDebugVariable(name, value): expected exactly 2 arguments",
625
+ "setDebugVariable");
626
+ }
627
+
628
+ if (!info[0].IsString()) {
629
+ return RejectTypeError(
630
+ env, "setDebugVariable(name, value): name must be a string",
631
+ "setDebugVariable");
632
+ }
633
+ if (!info[1].IsString()) {
634
+ return RejectTypeError(
635
+ env, "setDebugVariable(name, value): value must be a string",
636
+ "setDebugVariable");
637
+ }
638
+
639
+ command.name = info[0].As<Napi::String>().Utf8Value();
640
+ command.value = info[1].As<Napi::String>().Utf8Value();
641
+
285
642
  return _worker_thread.Enqueue(command);
286
643
  }
287
644
 
@@ -289,23 +646,19 @@ Napi::Value TesseractWrapper::SetVariable(const Napi::CallbackInfo &info) {
289
646
  Napi::Env env = info.Env();
290
647
  CommandSetVariable command{};
291
648
 
292
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
293
-
294
649
  if (info.Length() != 2) {
295
- deferred.Reject(Napi::Error::New(env, "Expected two arguments").Value());
296
- return deferred.Promise();
650
+ return RejectTypeError(
651
+ env, "setVariable(name, value): expected exactly 2 arguments",
652
+ "setVariable");
297
653
  }
298
654
 
299
655
  if (!info[0].IsString()) {
300
- deferred.Reject(
301
- Napi::Error::New(env, "Expected variable name to be a string").Value());
302
- return deferred.Promise();
656
+ return RejectTypeError(
657
+ env, "setVariable(name, value): name must be a string", "setVariable");
303
658
  }
304
659
  if (!info[1].IsString()) {
305
- return deferred.Reject(
306
- Napi::Error::New(env, "Variable value must be a string")
307
- .Value()),
308
- deferred.Promise();
660
+ return RejectTypeError(
661
+ env, "setVariable(name, value): value must be a string", "setVariable");
309
662
  }
310
663
 
311
664
  const std::string variable_name = info[0].As<Napi::String>().Utf8Value();
@@ -319,22 +672,17 @@ Napi::Value TesseractWrapper::SetVariable(const Napi::CallbackInfo &info) {
319
672
 
320
673
  Napi::Value TesseractWrapper::GetIntVariable(const Napi::CallbackInfo &info) {
321
674
  Napi::Env env = info.Env();
322
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
323
675
  CommandGetIntVariable command{};
324
676
 
325
677
  if (info.Length() != 1) {
326
- deferred.Reject(
327
- Napi::Error::New(env,
328
- "GetIntVariable(name): exactly 1 argument required")
329
- .Value());
330
- return deferred.Promise();
678
+ return RejectTypeError(env,
679
+ "getIntVariable(name): expected exactly 1 argument",
680
+ "getIntVariable");
331
681
  }
332
682
 
333
683
  if (!info[0].IsString()) {
334
- deferred.Reject(
335
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
336
- .Value());
337
- return deferred.Promise();
684
+ return RejectTypeError(env, "getIntVariable(name): name must be a string",
685
+ "getIntVariable");
338
686
  }
339
687
 
340
688
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -345,22 +693,17 @@ Napi::Value TesseractWrapper::GetIntVariable(const Napi::CallbackInfo &info) {
345
693
 
346
694
  Napi::Value TesseractWrapper::GetBoolVariable(const Napi::CallbackInfo &info) {
347
695
  Napi::Env env = info.Env();
348
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
349
696
  CommandGetBoolVariable command{};
350
697
 
351
698
  if (info.Length() != 1) {
352
- deferred.Reject(
353
- Napi::Error::New(env,
354
- "GetIntVariable(name): exactly 1 argument required")
355
- .Value());
356
- return deferred.Promise();
699
+ return RejectTypeError(env,
700
+ "getBoolVariable(name): expected exactly 1 argument",
701
+ "getBoolVariable");
357
702
  }
358
703
 
359
704
  if (!info[0].IsString()) {
360
- deferred.Reject(
361
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
362
- .Value());
363
- return deferred.Promise();
705
+ return RejectTypeError(env, "getBoolVariable(name): name must be a string",
706
+ "getBoolVariable");
364
707
  }
365
708
 
366
709
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -372,22 +715,18 @@ Napi::Value TesseractWrapper::GetBoolVariable(const Napi::CallbackInfo &info) {
372
715
  Napi::Value
373
716
  TesseractWrapper::GetDoubleVariable(const Napi::CallbackInfo &info) {
374
717
  Napi::Env env = info.Env();
375
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
376
718
  CommandGetDoubleVariable command{};
377
719
 
378
720
  if (info.Length() != 1) {
379
- deferred.Reject(
380
- Napi::Error::New(env,
381
- "GetIntVariable(name): exactly 1 argument required")
382
- .Value());
383
- return deferred.Promise();
721
+ return RejectTypeError(
722
+ env, "getDoubleVariable(name): expected exactly 1 argument",
723
+ "getDoubleVariable");
384
724
  }
385
725
 
386
726
  if (!info[0].IsString()) {
387
- deferred.Reject(
388
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
389
- .Value());
390
- return deferred.Promise();
727
+ return RejectTypeError(env,
728
+ "getDoubleVariable(name): name must be a string",
729
+ "getDoubleVariable");
391
730
  }
392
731
 
393
732
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -399,22 +738,18 @@ TesseractWrapper::GetDoubleVariable(const Napi::CallbackInfo &info) {
399
738
  Napi::Value
400
739
  TesseractWrapper::GetStringVariable(const Napi::CallbackInfo &info) {
401
740
  Napi::Env env = info.Env();
402
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
403
741
  CommandGetStringVariable command{};
404
742
 
405
743
  if (info.Length() != 1) {
406
- deferred.Reject(
407
- Napi::Error::New(env,
408
- "GetIntVariable(name): exactly 1 argument required")
409
- .Value());
410
- return deferred.Promise();
744
+ return RejectTypeError(
745
+ env, "getStringVariable(name): expected exactly 1 argument",
746
+ "getStringVariable");
411
747
  }
412
748
 
413
749
  if (!info[0].IsString()) {
414
- deferred.Reject(
415
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
416
- .Value());
417
- return deferred.Promise();
750
+ return RejectTypeError(env,
751
+ "getStringVariable(name): name must be a string",
752
+ "getStringVariable");
418
753
  }
419
754
 
420
755
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -425,13 +760,11 @@ TesseractWrapper::GetStringVariable(const Napi::CallbackInfo &info) {
425
760
 
426
761
  Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
427
762
  Napi::Env env = info.Env();
428
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
429
763
  CommandSetImage command{};
430
764
 
431
765
  if (info.Length() < 1 || !info[0].IsBuffer()) {
432
- deferred.Reject(
433
- Napi::Error::New(env, "SetImage(buffer): buffer required").Value());
434
- return deferred.Promise();
766
+ return RejectTypeError(env, "setImage(buffer): buffer argument is required",
767
+ "setImage");
435
768
  }
436
769
 
437
770
  Napi::Buffer<uint8_t> image_buffer = info[0].As<Napi::Buffer<uint8_t>>();
@@ -439,16 +772,14 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
439
772
  const size_t length = image_buffer.Length();
440
773
 
441
774
  if (length == 0) {
442
- deferred.Reject(Napi::Error::New(env, "SetImage: buffer is empty").Value());
443
- return deferred.Promise();
775
+ return RejectTypeError(env, "setImage(buffer): buffer is empty",
776
+ "setImage");
444
777
  }
445
778
 
446
779
  Pix *pix = pixReadMem(data, length);
447
780
  if (!pix) {
448
- deferred.Reject(
449
- Napi::Error::New(env, "SetImage: failed to decode image buffer")
450
- .Value());
451
- return deferred.Promise();
781
+ return RejectError(env, "setImage(buffer): failed to decode image buffer",
782
+ "setImage");
452
783
  }
453
784
 
454
785
  Pix *normalized = pix;
@@ -486,9 +817,8 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
486
817
  pixDestroy(&normalized);
487
818
  }
488
819
  pixDestroy(&pix);
489
- deferred.Reject(
490
- Napi::Error::New(env, "SetImage: invalid decoded image data").Value());
491
- return deferred.Promise();
820
+ return RejectError(env, "setImage(buffer): invalid decoded image data",
821
+ "setImage");
492
822
  }
493
823
 
494
824
  command.width = width;
@@ -506,16 +836,43 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
506
836
  return _worker_thread.Enqueue(command);
507
837
  }
508
838
 
839
+ Napi::Value TesseractWrapper::SetPageMode(const Napi::CallbackInfo &info) {
840
+ Napi::Env env = info.Env();
841
+ CommandSetPageMode command{};
842
+
843
+ if (info.Length() > 1) {
844
+ return RejectTypeError(
845
+ env, "setPageMode(psm?): expected at most 1 argument", "setPageMode");
846
+ }
847
+
848
+ if (HasArg(info, 0)) {
849
+ if (!info[0].IsNumber()) {
850
+ return RejectTypeError(env, "setPageMode(psm?): psm must be a number",
851
+ "setPageMode");
852
+ }
853
+
854
+ tesseract::PageSegMode psm = static_cast<tesseract::PageSegMode>(
855
+ info[0].As<Napi::Number>().Int32Value());
856
+
857
+ if (psm < 0 || psm >= tesseract::PageSegMode::PSM_COUNT) {
858
+ return RejectRangeError(env, "setPageMode(psm?): psm is out of range",
859
+ "setPageMode");
860
+ }
861
+
862
+ command.psm = psm;
863
+ }
864
+
865
+ return _worker_thread.Enqueue(command);
866
+ }
867
+
509
868
  Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
510
869
  Napi::Env env = info.Env();
511
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
512
870
  CommandSetRectangle command{};
513
871
 
514
872
  if (info.Length() != 1 || !info[0].IsObject()) {
515
- deferred.Reject(
516
- Napi::Error::New(env, "Expected first argument to be a object")
517
- .Value());
518
- return deferred.Promise();
873
+ return RejectTypeError(
874
+ env, "setRectangle(rectangle): rectangle must be an object",
875
+ "setRectangle");
519
876
  }
520
877
 
521
878
  Napi::Object rectangle = info[0].As<Napi::Object>();
@@ -527,11 +884,10 @@ Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
527
884
 
528
885
  if (!maybe_left.IsNumber() || !maybe_top.IsNumber() ||
529
886
  !maybe_width.IsNumber() || !maybe_height.IsNumber()) {
530
- deferred.Reject(
531
- Napi::Error::New(env,
532
- "SetRectangle: missing property in rectangle object")
533
- .Value());
534
- return deferred.Promise();
887
+ return RejectTypeError(env,
888
+ "setRectangle(rectangle): "
889
+ "rectangle.left/top/width/height must be numbers",
890
+ "setRectangle");
535
891
  }
536
892
 
537
893
  int32_t left = maybe_left.As<Napi::Number>().Int32Value();
@@ -550,19 +906,18 @@ Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
550
906
  Napi::Value
551
907
  TesseractWrapper::SetSourceResolution(const Napi::CallbackInfo &info) {
552
908
  Napi::Env env = info.Env();
553
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
554
909
  CommandSetSourceResolution command{};
555
910
 
556
- if (info.Length() > 1) {
557
- deferred.Reject(
558
- Napi::Error::New(env, "Expected only one parameter").Value());
559
- return deferred.Promise();
911
+ if (info.Length() != 1) {
912
+ return RejectTypeError(
913
+ env, "setSourceResolution(ppi): expected exactly 1 argument",
914
+ "setSourceResolution");
560
915
  }
561
916
 
562
917
  if (!info[0].IsNumber()) {
563
- deferred.Reject(
564
- Napi::Error::New(env, "Expected ppi to be of type number").Value());
565
- return deferred.Promise();
918
+ return RejectTypeError(env,
919
+ "setSourceResolution(ppi): ppi must be a number",
920
+ "setSourceResolution");
566
921
  }
567
922
 
568
923
  int ppi = info[0].As<Napi::Number>().Int32Value();
@@ -574,16 +929,14 @@ TesseractWrapper::SetSourceResolution(const Napi::CallbackInfo &info) {
574
929
 
575
930
  Napi::Value TesseractWrapper::Recognize(const Napi::CallbackInfo &info) {
576
931
  Napi::Env env = info.Env();
577
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
578
932
  CommandRecognize command{};
579
933
 
580
- if (!info[0].IsUndefined()) {
934
+ if (HasArg(info, 0)) {
581
935
  if (!info[0].IsFunction()) {
582
- deferred.Reject(
583
- Napi::Error::New(env,
584
- "Expected progress callback to be of type function")
585
- .Value());
586
- return deferred.Promise();
936
+ return RejectTypeError(
937
+ env,
938
+ "recognize(progressCallback?): progressCallback must be a function",
939
+ "recognize");
587
940
  }
588
941
 
589
942
  Napi::Function progress_callback = info[0].As<Napi::Function>();
@@ -606,22 +959,129 @@ Napi::Value TesseractWrapper::MeanTextConf(const Napi::CallbackInfo &info) {
606
959
  return _worker_thread.Enqueue(CommandMeanTextConf{});
607
960
  }
608
961
 
962
+ Napi::Value
963
+ TesseractWrapper::AllWordConfidences(const Napi::CallbackInfo &info) {
964
+ return _worker_thread.Enqueue(CommandAllWordConfidences{});
965
+ }
966
+
967
+ Napi::Value TesseractWrapper::GetPAGEText(const Napi::CallbackInfo &info) {
968
+ Napi::Env env = info.Env();
969
+ CommandGetPAGEText command{};
970
+ command.page_number = 0;
971
+
972
+ if (HasArg(info, 0)) {
973
+ if (!info[0].IsFunction()) {
974
+ return RejectTypeError(env,
975
+ "getPAGEText(progressCallback?, pageNumber?): "
976
+ "progressCallback must be a function",
977
+ "getPAGEText");
978
+ }
979
+
980
+ Napi::Function progress_callback = info[0].As<Napi::Function>();
981
+ Napi::ThreadSafeFunction progress_tsfn = Napi::ThreadSafeFunction::New(
982
+ env, progress_callback, "tesseract_progress_callback", 0, 1);
983
+
984
+ command.monitor_context =
985
+ std::make_shared<MonitorContext>(std::move(progress_tsfn));
986
+ }
987
+
988
+ if (HasArg(info, 1)) {
989
+ if (!info[1].IsNumber()) {
990
+ return RejectTypeError(env,
991
+ "getPAGEText(progressCallback?, pageNumber?): "
992
+ "pageNumber must be a number",
993
+ "getPAGEText");
994
+ }
995
+
996
+ command.page_number = info[1].As<Napi::Number>().Int32Value();
997
+ }
998
+
999
+ return _worker_thread.Enqueue(command);
1000
+ }
1001
+
1002
+ Napi::Value TesseractWrapper::GetLSTMBoxText(const Napi::CallbackInfo &info) {
1003
+ Napi::Env env = info.Env();
1004
+ CommandGetLSTMBoxText command{};
1005
+ command.page_number = 0;
1006
+
1007
+ if (HasArg(info, 0)) {
1008
+ if (!info[0].IsNumber()) {
1009
+ return RejectTypeError(
1010
+ env, "getLSTMBoxText(pageNumber?): pageNumber must be a number",
1011
+ "getLSTMBoxText");
1012
+ }
1013
+ command.page_number = info[0].As<Napi::Number>().Int32Value();
1014
+ }
1015
+
1016
+ return _worker_thread.Enqueue(command);
1017
+ }
1018
+
1019
+ Napi::Value TesseractWrapper::GetBoxText(const Napi::CallbackInfo &info) {
1020
+ Napi::Env env = info.Env();
1021
+ CommandGetBoxText command{};
1022
+ command.page_number = 0;
1023
+
1024
+ if (HasArg(info, 0)) {
1025
+ if (!info[0].IsNumber()) {
1026
+ return RejectTypeError(
1027
+ env, "getBoxText(pageNumber?): pageNumber must be a number",
1028
+ "getBoxText");
1029
+ }
1030
+ command.page_number = info[0].As<Napi::Number>().Int32Value();
1031
+ }
1032
+
1033
+ return _worker_thread.Enqueue(command);
1034
+ }
1035
+
1036
+ Napi::Value
1037
+ TesseractWrapper::GetWordStrBoxText(const Napi::CallbackInfo &info) {
1038
+ Napi::Env env = info.Env();
1039
+ CommandGetWordStrBoxText command{};
1040
+ command.page_number = 0;
1041
+
1042
+ if (HasArg(info, 0)) {
1043
+ if (!info[0].IsNumber()) {
1044
+ return RejectTypeError(
1045
+ env, "getWordStrBoxText(pageNumber?): pageNumber must be a number",
1046
+ "getWordStrBoxText");
1047
+ }
1048
+ command.page_number = info[0].As<Napi::Number>().Int32Value();
1049
+ }
1050
+
1051
+ return _worker_thread.Enqueue(command);
1052
+ }
1053
+
1054
+ Napi::Value TesseractWrapper::getOSDText(const Napi::CallbackInfo &info) {
1055
+ Napi::Env env = info.Env();
1056
+ CommandGetOSDText command{};
1057
+ command.page_number = 0;
1058
+
1059
+ if (HasArg(info, 0)) {
1060
+ if (!info[0].IsNumber()) {
1061
+ return RejectTypeError(
1062
+ env, "getOSDText(pageNumber?): pageNumber must be a number",
1063
+ "getOSDText");
1064
+ }
1065
+ command.page_number = info[0].As<Napi::Number>().Int32Value();
1066
+ }
1067
+
1068
+ return _worker_thread.Enqueue(command);
1069
+ }
1070
+
609
1071
  Napi::Value TesseractWrapper::GetUTF8Text(const Napi::CallbackInfo &info) {
610
1072
  return _worker_thread.Enqueue(CommandGetUTF8Text{});
611
1073
  }
612
1074
 
613
1075
  Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
614
1076
  Napi::Env env = info.Env();
615
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
616
1077
  CommandGetHOCRText command{};
617
1078
 
618
- if (!info[0].IsUndefined()) {
1079
+ if (HasArg(info, 0)) {
619
1080
  if (!info[0].IsFunction()) {
620
- deferred.Reject(
621
- Napi::Error::New(env,
622
- "Expected progress callback to be of type function")
623
- .Value());
624
- return deferred.Promise();
1081
+ return RejectTypeError(env,
1082
+ "getHOCRText(progressCallback?, pageNumber?): "
1083
+ "progressCallback must be a function",
1084
+ "getHOCRText");
625
1085
  }
626
1086
 
627
1087
  Napi::Function progress_callback = info[0].As<Napi::Function>();
@@ -632,12 +1092,12 @@ Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
632
1092
  std::make_shared<MonitorContext>(std::move(progress_tsfn));
633
1093
  }
634
1094
 
635
- if (!info[1].IsUndefined()) {
1095
+ if (HasArg(info, 1)) {
636
1096
  if (!info[1].IsNumber()) {
637
- deferred.Reject(
638
- Napi::Error::New(env, "Expected page_number to be of type number")
639
- .Value());
640
- return deferred.Promise();
1097
+ return RejectTypeError(env,
1098
+ "getHOCRText(progressCallback?, pageNumber?): "
1099
+ "pageNumber must be a number",
1100
+ "getHOCRText");
641
1101
  }
642
1102
 
643
1103
  int32_t page_number = info[1].As<Napi::Number>().Int32Value();
@@ -649,15 +1109,13 @@ Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
649
1109
 
650
1110
  Napi::Value TesseractWrapper::GetTSVText(const Napi::CallbackInfo &info) {
651
1111
  Napi::Env env = info.Env();
652
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
653
1112
  CommandGetTSVText command{};
654
1113
 
655
- if (!info[0].IsUndefined()) {
1114
+ if (HasArg(info, 0)) {
656
1115
  if (!info[0].IsNumber()) {
657
- deferred.Reject(
658
- Napi::Error::New(env, "Expected page_number to be of type number")
659
- .Value());
660
- return deferred.Promise();
1116
+ return RejectTypeError(
1117
+ env, "getTSVText(pageNumber?): pageNumber must be a number",
1118
+ "getTSVText");
661
1119
  }
662
1120
 
663
1121
  int32_t page_number = info[0].As<Napi::Number>().Int32Value();
@@ -673,15 +1131,13 @@ Napi::Value TesseractWrapper::GetUNLVText(const Napi::CallbackInfo &info) {
673
1131
 
674
1132
  Napi::Value TesseractWrapper::GetALTOText(const Napi::CallbackInfo &info) {
675
1133
  Napi::Env env = info.Env();
676
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
677
1134
  CommandGetALTOText command{};
678
1135
 
679
- if (!info[0].IsUndefined()) {
1136
+ if (HasArg(info, 0)) {
680
1137
  if (!info[0].IsNumber()) {
681
- deferred.Reject(
682
- Napi::Error::New(env, "Expected page_number to be of type number")
683
- .Value());
684
- return deferred.Promise();
1138
+ return RejectTypeError(
1139
+ env, "getALTOText(pageNumber?): pageNumber must be a number",
1140
+ "getALTOText");
685
1141
  }
686
1142
 
687
1143
  int32_t page_number = info[0].As<Napi::Number>().Int32Value();