@luii/node-tesseract-ocr 2.1.0 → 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,16 +153,185 @@ 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>();
@@ -97,10 +340,8 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
97
340
  const Napi::Value dataPathOption = options.Get("dataPath");
98
341
  if (!dataPathOption.IsUndefined()) {
99
342
  if (!dataPathOption.IsString()) {
100
- deferred.Reject(
101
- Napi::TypeError::New(env, "Option 'dataPath' must be a string")
102
- .Value());
103
- return deferred.Promise();
343
+ return RejectTypeError(
344
+ env, "init(options): options.dataPath must be a string", "init");
104
345
  }
105
346
 
106
347
  Napi::String dataPath = dataPathOption.As<Napi::String>();
@@ -110,10 +351,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
110
351
  const Napi::Value langsOption = options.Get("langs");
111
352
  if (!langsOption.IsUndefined()) {
112
353
  if (!langsOption.IsArray()) {
113
- deferred.Reject(
114
- Napi::TypeError::New(env, "Option 'langs' must be a array of strings")
115
- .Value());
116
- return deferred.Promise();
354
+ return RejectTypeError(
355
+ env, "init(options): options.langs must be an array of strings",
356
+ "init");
117
357
  }
118
358
 
119
359
  Napi::Array languages = langsOption.As<Napi::Array>();
@@ -133,18 +373,15 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
133
373
  const Napi::Value engineModeOption = options.Get("oem");
134
374
  if (!engineModeOption.IsUndefined()) {
135
375
  if (!engineModeOption.IsNumber()) {
136
- deferred.Reject(
137
- Napi::TypeError::New(env, "Option 'oem' must be of type number")
138
- .Value());
139
- return deferred.Promise();
376
+ return RejectTypeError(env, "init(options): options.oem must be a number",
377
+ "init");
140
378
  }
141
379
  tesseract::OcrEngineMode oem = static_cast<tesseract::OcrEngineMode>(
142
380
  engineModeOption.As<Napi::Number>().Int32Value());
143
381
 
144
382
  if (oem < 0 || oem >= tesseract::OEM_COUNT) {
145
- deferred.Reject(
146
- Napi::TypeError::New(env, "Unsupported OCR Engine Mode").Value());
147
- return deferred.Promise();
383
+ return RejectRangeError(
384
+ env, "init(options): options.oem is out of supported range", "init");
148
385
  }
149
386
 
150
387
  command.oem = oem;
@@ -154,11 +391,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
154
391
  options.Get("setOnlyNonDebugParams");
155
392
  if (!set_only_non_debug_params.IsUndefined()) {
156
393
  if (!set_only_non_debug_params.IsBoolean()) {
157
- deferred.Reject(
158
- Napi::TypeError::New(
159
- env, "Option 'setOnlyNonDebugParams' must be of type boolean")
160
- .Value());
161
- return deferred.Promise();
394
+ return RejectTypeError(
395
+ env, "init(options): options.setOnlyNonDebugParams must be a boolean",
396
+ "init");
162
397
  }
163
398
 
164
399
  command.set_only_non_debug_params =
@@ -168,10 +403,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
168
403
  const Napi::Value v = options.Get("configs");
169
404
  if (!v.IsUndefined()) {
170
405
  if (!v.IsArray()) {
171
- deferred.Reject(Napi::TypeError::New(
172
- env, "Option 'configs' must be an array of strings")
173
- .Value());
174
- return deferred.Promise();
406
+ return RejectTypeError(
407
+ env, "init(options): options.configs must be an array of strings",
408
+ "init");
175
409
  }
176
410
 
177
411
  Napi::Array arr = v.As<Napi::Array>();
@@ -183,10 +417,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
183
417
  for (uint32_t i = 0; i < len; ++i) {
184
418
  Napi::Value item = arr.Get(i);
185
419
  if (!item.IsString()) {
186
- deferred.Reject(Napi::TypeError::New(
187
- env, "Option 'configs' must contain only strings")
188
- .Value());
189
- return deferred.Promise();
420
+ return RejectTypeError(
421
+ env, "init(options): options.configs must contain only strings",
422
+ "init");
190
423
  }
191
424
  command.configs_storage.emplace_back(item.As<Napi::String>().Utf8Value());
192
425
  }
@@ -201,10 +434,8 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
201
434
 
202
435
  if (!varsOption.IsUndefined()) {
203
436
  if (!varsOption.IsObject()) {
204
- deferred.Reject(
205
- Napi::TypeError::New(env, "Options 'vars' must be of type object")
206
- .Value());
207
- return deferred.Promise();
437
+ return RejectTypeError(
438
+ env, "init(options): options.vars must be an object", "init");
208
439
  }
209
440
 
210
441
  // Napi::Array a = vars_vec.As<Napi::Array>();
@@ -219,10 +450,9 @@ Napi::Value TesseractWrapper::Init(const Napi::CallbackInfo &info) {
219
450
  for (uint32_t i = 0; i < length; ++i) {
220
451
  Napi::Value variable_value = vars.Get(variable_names.Get(i));
221
452
  if (!variable_names.Get(i).IsString() || !variable_value.IsString()) {
222
- deferred.Reject(
223
- Napi::TypeError::New(env, "'vars' must contain only strings")
224
- .Value());
225
- return deferred.Promise();
453
+ return RejectTypeError(
454
+ env, "init(options): options.vars must contain only strings",
455
+ "init");
226
456
  }
227
457
  command.vars_vec.emplace_back(
228
458
  variable_names.Get(i).As<Napi::String>().Utf8Value());
@@ -239,22 +469,22 @@ TesseractWrapper::InitForAnalysePage(const Napi::CallbackInfo &info) {
239
469
  return _worker_thread.Enqueue(CommandInitForAnalysePage{});
240
470
  }
241
471
 
242
- Napi::Value TesseractWrapper::AnalysePage(const Napi::CallbackInfo &info) {
472
+ Napi::Value TesseractWrapper::AnalyseLayout(const Napi::CallbackInfo &info) {
243
473
  Napi::Env env = info.Env();
244
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
245
474
  CommandAnalyseLayout command{};
246
475
 
247
476
  if (info.Length() > 1) {
248
- deferred.Reject(Napi::Error::New(env, "Too many arguments").Value());
249
- return deferred.Promise();
477
+ return RejectTypeError(
478
+ env, "analyseLayout(mergeSimilarWords?): expected at most 1 argument",
479
+ "analyseLayout");
250
480
  }
251
481
 
252
- if (!info[0].IsUndefined()) {
482
+ if (HasArg(info, 0)) {
253
483
  if (!info[0].IsBoolean()) {
254
- deferred.Reject(
255
- Napi::Error::New(env, "Expected argument to be of type boolean")
256
- .Value());
257
- return deferred.Promise();
484
+ return RejectTypeError(env,
485
+ "analyseLayout(mergeSimilarWords?): "
486
+ "mergeSimilarWords must be a boolean",
487
+ "analyseLayout");
258
488
  }
259
489
 
260
490
  command.merge_similar_words = info[0].As<Napi::Boolean>().Value();
@@ -263,38 +493,152 @@ Napi::Value TesseractWrapper::AnalysePage(const Napi::CallbackInfo &info) {
263
493
  return _worker_thread.Enqueue(command);
264
494
  }
265
495
 
266
- Napi::Value TesseractWrapper::SetPageMode(const Napi::CallbackInfo &info) {
496
+ Napi::Value
497
+ TesseractWrapper::BeginProcessPages(const Napi::CallbackInfo &info) {
267
498
  Napi::Env env = info.Env();
268
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
269
- CommandSetPageMode command{};
499
+ CommandBeginProcessPages command{};
270
500
 
271
- if (info.Length() > 1) {
272
- deferred.Reject(
273
- Napi::Error::New(env, "Expected only one parameter").Value());
274
- 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");
275
505
  }
276
506
 
277
- if (!info[0].IsUndefined()) {
278
- if (!info[0].IsNumber()) {
279
- deferred.Reject(
280
- Napi::Error::New(
281
- env, "Expected page segmentation mode to be of type number")
282
- .Value());
283
- 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");
284
516
  }
517
+ command.output_base = output_base.As<Napi::String>().Utf8Value();
518
+ }
285
519
 
286
- tesseract::PageSegMode psm = static_cast<tesseract::PageSegMode>(
287
- 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
+ }
288
538
 
289
- if (psm < 0 || psm >= tesseract::PageSegMode::PSM_COUNT) {
290
- deferred.Reject(
291
- Napi::Error::New(env, "Page Segmentation Mode out of range").Value());
292
- 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");
293
545
  }
546
+ command.textonly = textonly.As<Napi::Boolean>().Value();
547
+ }
294
548
 
295
- 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");
560
+ }
561
+
562
+ if (!info[0].IsBuffer()) {
563
+ return RejectTypeError(
564
+ env, "addProcessPage(buffer, filename?): buffer must be a Buffer",
565
+ "addProcessPage");
296
566
  }
297
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
+
298
642
  return _worker_thread.Enqueue(command);
299
643
  }
300
644
 
@@ -302,23 +646,19 @@ Napi::Value TesseractWrapper::SetVariable(const Napi::CallbackInfo &info) {
302
646
  Napi::Env env = info.Env();
303
647
  CommandSetVariable command{};
304
648
 
305
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
306
-
307
649
  if (info.Length() != 2) {
308
- deferred.Reject(Napi::Error::New(env, "Expected two arguments").Value());
309
- return deferred.Promise();
650
+ return RejectTypeError(
651
+ env, "setVariable(name, value): expected exactly 2 arguments",
652
+ "setVariable");
310
653
  }
311
654
 
312
655
  if (!info[0].IsString()) {
313
- deferred.Reject(
314
- Napi::Error::New(env, "Expected variable name to be a string").Value());
315
- return deferred.Promise();
656
+ return RejectTypeError(
657
+ env, "setVariable(name, value): name must be a string", "setVariable");
316
658
  }
317
659
  if (!info[1].IsString()) {
318
- return deferred.Reject(
319
- Napi::Error::New(env, "Variable value must be a string")
320
- .Value()),
321
- deferred.Promise();
660
+ return RejectTypeError(
661
+ env, "setVariable(name, value): value must be a string", "setVariable");
322
662
  }
323
663
 
324
664
  const std::string variable_name = info[0].As<Napi::String>().Utf8Value();
@@ -332,22 +672,17 @@ Napi::Value TesseractWrapper::SetVariable(const Napi::CallbackInfo &info) {
332
672
 
333
673
  Napi::Value TesseractWrapper::GetIntVariable(const Napi::CallbackInfo &info) {
334
674
  Napi::Env env = info.Env();
335
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
336
675
  CommandGetIntVariable command{};
337
676
 
338
677
  if (info.Length() != 1) {
339
- deferred.Reject(
340
- Napi::Error::New(env,
341
- "GetIntVariable(name): exactly 1 argument required")
342
- .Value());
343
- return deferred.Promise();
678
+ return RejectTypeError(env,
679
+ "getIntVariable(name): expected exactly 1 argument",
680
+ "getIntVariable");
344
681
  }
345
682
 
346
683
  if (!info[0].IsString()) {
347
- deferred.Reject(
348
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
349
- .Value());
350
- return deferred.Promise();
684
+ return RejectTypeError(env, "getIntVariable(name): name must be a string",
685
+ "getIntVariable");
351
686
  }
352
687
 
353
688
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -358,22 +693,17 @@ Napi::Value TesseractWrapper::GetIntVariable(const Napi::CallbackInfo &info) {
358
693
 
359
694
  Napi::Value TesseractWrapper::GetBoolVariable(const Napi::CallbackInfo &info) {
360
695
  Napi::Env env = info.Env();
361
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
362
696
  CommandGetBoolVariable command{};
363
697
 
364
698
  if (info.Length() != 1) {
365
- deferred.Reject(
366
- Napi::Error::New(env,
367
- "GetIntVariable(name): exactly 1 argument required")
368
- .Value());
369
- return deferred.Promise();
699
+ return RejectTypeError(env,
700
+ "getBoolVariable(name): expected exactly 1 argument",
701
+ "getBoolVariable");
370
702
  }
371
703
 
372
704
  if (!info[0].IsString()) {
373
- deferred.Reject(
374
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
375
- .Value());
376
- return deferred.Promise();
705
+ return RejectTypeError(env, "getBoolVariable(name): name must be a string",
706
+ "getBoolVariable");
377
707
  }
378
708
 
379
709
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -385,22 +715,18 @@ Napi::Value TesseractWrapper::GetBoolVariable(const Napi::CallbackInfo &info) {
385
715
  Napi::Value
386
716
  TesseractWrapper::GetDoubleVariable(const Napi::CallbackInfo &info) {
387
717
  Napi::Env env = info.Env();
388
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
389
718
  CommandGetDoubleVariable command{};
390
719
 
391
720
  if (info.Length() != 1) {
392
- deferred.Reject(
393
- Napi::Error::New(env,
394
- "GetIntVariable(name): exactly 1 argument required")
395
- .Value());
396
- return deferred.Promise();
721
+ return RejectTypeError(
722
+ env, "getDoubleVariable(name): expected exactly 1 argument",
723
+ "getDoubleVariable");
397
724
  }
398
725
 
399
726
  if (!info[0].IsString()) {
400
- deferred.Reject(
401
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
402
- .Value());
403
- return deferred.Promise();
727
+ return RejectTypeError(env,
728
+ "getDoubleVariable(name): name must be a string",
729
+ "getDoubleVariable");
404
730
  }
405
731
 
406
732
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -412,22 +738,18 @@ TesseractWrapper::GetDoubleVariable(const Napi::CallbackInfo &info) {
412
738
  Napi::Value
413
739
  TesseractWrapper::GetStringVariable(const Napi::CallbackInfo &info) {
414
740
  Napi::Env env = info.Env();
415
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
416
741
  CommandGetStringVariable command{};
417
742
 
418
743
  if (info.Length() != 1) {
419
- deferred.Reject(
420
- Napi::Error::New(env,
421
- "GetIntVariable(name): exactly 1 argument required")
422
- .Value());
423
- return deferred.Promise();
744
+ return RejectTypeError(
745
+ env, "getStringVariable(name): expected exactly 1 argument",
746
+ "getStringVariable");
424
747
  }
425
748
 
426
749
  if (!info[0].IsString()) {
427
- deferred.Reject(
428
- Napi::Error::New(env, "GetIntVariable(name): name must be a string")
429
- .Value());
430
- return deferred.Promise();
750
+ return RejectTypeError(env,
751
+ "getStringVariable(name): name must be a string",
752
+ "getStringVariable");
431
753
  }
432
754
 
433
755
  std::string name = info[0].As<Napi::String>().Utf8Value();
@@ -438,13 +760,11 @@ TesseractWrapper::GetStringVariable(const Napi::CallbackInfo &info) {
438
760
 
439
761
  Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
440
762
  Napi::Env env = info.Env();
441
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
442
763
  CommandSetImage command{};
443
764
 
444
765
  if (info.Length() < 1 || !info[0].IsBuffer()) {
445
- deferred.Reject(
446
- Napi::Error::New(env, "SetImage(buffer): buffer required").Value());
447
- return deferred.Promise();
766
+ return RejectTypeError(env, "setImage(buffer): buffer argument is required",
767
+ "setImage");
448
768
  }
449
769
 
450
770
  Napi::Buffer<uint8_t> image_buffer = info[0].As<Napi::Buffer<uint8_t>>();
@@ -452,16 +772,14 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
452
772
  const size_t length = image_buffer.Length();
453
773
 
454
774
  if (length == 0) {
455
- deferred.Reject(Napi::Error::New(env, "SetImage: buffer is empty").Value());
456
- return deferred.Promise();
775
+ return RejectTypeError(env, "setImage(buffer): buffer is empty",
776
+ "setImage");
457
777
  }
458
778
 
459
779
  Pix *pix = pixReadMem(data, length);
460
780
  if (!pix) {
461
- deferred.Reject(
462
- Napi::Error::New(env, "SetImage: failed to decode image buffer")
463
- .Value());
464
- return deferred.Promise();
781
+ return RejectError(env, "setImage(buffer): failed to decode image buffer",
782
+ "setImage");
465
783
  }
466
784
 
467
785
  Pix *normalized = pix;
@@ -499,9 +817,8 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
499
817
  pixDestroy(&normalized);
500
818
  }
501
819
  pixDestroy(&pix);
502
- deferred.Reject(
503
- Napi::Error::New(env, "SetImage: invalid decoded image data").Value());
504
- return deferred.Promise();
820
+ return RejectError(env, "setImage(buffer): invalid decoded image data",
821
+ "setImage");
505
822
  }
506
823
 
507
824
  command.width = width;
@@ -519,16 +836,43 @@ Napi::Value TesseractWrapper::SetImage(const Napi::CallbackInfo &info) {
519
836
  return _worker_thread.Enqueue(command);
520
837
  }
521
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
+
522
868
  Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
523
869
  Napi::Env env = info.Env();
524
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
525
870
  CommandSetRectangle command{};
526
871
 
527
872
  if (info.Length() != 1 || !info[0].IsObject()) {
528
- deferred.Reject(
529
- Napi::Error::New(env, "Expected first argument to be a object")
530
- .Value());
531
- return deferred.Promise();
873
+ return RejectTypeError(
874
+ env, "setRectangle(rectangle): rectangle must be an object",
875
+ "setRectangle");
532
876
  }
533
877
 
534
878
  Napi::Object rectangle = info[0].As<Napi::Object>();
@@ -540,11 +884,10 @@ Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
540
884
 
541
885
  if (!maybe_left.IsNumber() || !maybe_top.IsNumber() ||
542
886
  !maybe_width.IsNumber() || !maybe_height.IsNumber()) {
543
- deferred.Reject(
544
- Napi::Error::New(env,
545
- "SetRectangle: missing property in rectangle object")
546
- .Value());
547
- return deferred.Promise();
887
+ return RejectTypeError(env,
888
+ "setRectangle(rectangle): "
889
+ "rectangle.left/top/width/height must be numbers",
890
+ "setRectangle");
548
891
  }
549
892
 
550
893
  int32_t left = maybe_left.As<Napi::Number>().Int32Value();
@@ -563,19 +906,18 @@ Napi::Value TesseractWrapper::SetRectangle(const Napi::CallbackInfo &info) {
563
906
  Napi::Value
564
907
  TesseractWrapper::SetSourceResolution(const Napi::CallbackInfo &info) {
565
908
  Napi::Env env = info.Env();
566
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
567
909
  CommandSetSourceResolution command{};
568
910
 
569
- if (info.Length() > 1) {
570
- deferred.Reject(
571
- Napi::Error::New(env, "Expected only one parameter").Value());
572
- return deferred.Promise();
911
+ if (info.Length() != 1) {
912
+ return RejectTypeError(
913
+ env, "setSourceResolution(ppi): expected exactly 1 argument",
914
+ "setSourceResolution");
573
915
  }
574
916
 
575
917
  if (!info[0].IsNumber()) {
576
- deferred.Reject(
577
- Napi::Error::New(env, "Expected ppi to be of type number").Value());
578
- return deferred.Promise();
918
+ return RejectTypeError(env,
919
+ "setSourceResolution(ppi): ppi must be a number",
920
+ "setSourceResolution");
579
921
  }
580
922
 
581
923
  int ppi = info[0].As<Napi::Number>().Int32Value();
@@ -587,16 +929,14 @@ TesseractWrapper::SetSourceResolution(const Napi::CallbackInfo &info) {
587
929
 
588
930
  Napi::Value TesseractWrapper::Recognize(const Napi::CallbackInfo &info) {
589
931
  Napi::Env env = info.Env();
590
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
591
932
  CommandRecognize command{};
592
933
 
593
- if (!info[0].IsUndefined()) {
934
+ if (HasArg(info, 0)) {
594
935
  if (!info[0].IsFunction()) {
595
- deferred.Reject(
596
- Napi::Error::New(env,
597
- "Expected progress callback to be of type function")
598
- .Value());
599
- return deferred.Promise();
936
+ return RejectTypeError(
937
+ env,
938
+ "recognize(progressCallback?): progressCallback must be a function",
939
+ "recognize");
600
940
  }
601
941
 
602
942
  Napi::Function progress_callback = info[0].As<Napi::Function>();
@@ -619,22 +959,129 @@ Napi::Value TesseractWrapper::MeanTextConf(const Napi::CallbackInfo &info) {
619
959
  return _worker_thread.Enqueue(CommandMeanTextConf{});
620
960
  }
621
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
+
622
1071
  Napi::Value TesseractWrapper::GetUTF8Text(const Napi::CallbackInfo &info) {
623
1072
  return _worker_thread.Enqueue(CommandGetUTF8Text{});
624
1073
  }
625
1074
 
626
1075
  Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
627
1076
  Napi::Env env = info.Env();
628
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
629
1077
  CommandGetHOCRText command{};
630
1078
 
631
- if (!info[0].IsUndefined()) {
1079
+ if (HasArg(info, 0)) {
632
1080
  if (!info[0].IsFunction()) {
633
- deferred.Reject(
634
- Napi::Error::New(env,
635
- "Expected progress callback to be of type function")
636
- .Value());
637
- return deferred.Promise();
1081
+ return RejectTypeError(env,
1082
+ "getHOCRText(progressCallback?, pageNumber?): "
1083
+ "progressCallback must be a function",
1084
+ "getHOCRText");
638
1085
  }
639
1086
 
640
1087
  Napi::Function progress_callback = info[0].As<Napi::Function>();
@@ -645,12 +1092,12 @@ Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
645
1092
  std::make_shared<MonitorContext>(std::move(progress_tsfn));
646
1093
  }
647
1094
 
648
- if (!info[1].IsUndefined()) {
1095
+ if (HasArg(info, 1)) {
649
1096
  if (!info[1].IsNumber()) {
650
- deferred.Reject(
651
- Napi::Error::New(env, "Expected page_number to be of type number")
652
- .Value());
653
- return deferred.Promise();
1097
+ return RejectTypeError(env,
1098
+ "getHOCRText(progressCallback?, pageNumber?): "
1099
+ "pageNumber must be a number",
1100
+ "getHOCRText");
654
1101
  }
655
1102
 
656
1103
  int32_t page_number = info[1].As<Napi::Number>().Int32Value();
@@ -662,15 +1109,13 @@ Napi::Value TesseractWrapper::GetHOCRText(const Napi::CallbackInfo &info) {
662
1109
 
663
1110
  Napi::Value TesseractWrapper::GetTSVText(const Napi::CallbackInfo &info) {
664
1111
  Napi::Env env = info.Env();
665
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
666
1112
  CommandGetTSVText command{};
667
1113
 
668
- if (!info[0].IsUndefined()) {
1114
+ if (HasArg(info, 0)) {
669
1115
  if (!info[0].IsNumber()) {
670
- deferred.Reject(
671
- Napi::Error::New(env, "Expected page_number to be of type number")
672
- .Value());
673
- return deferred.Promise();
1116
+ return RejectTypeError(
1117
+ env, "getTSVText(pageNumber?): pageNumber must be a number",
1118
+ "getTSVText");
674
1119
  }
675
1120
 
676
1121
  int32_t page_number = info[0].As<Napi::Number>().Int32Value();
@@ -686,15 +1131,13 @@ Napi::Value TesseractWrapper::GetUNLVText(const Napi::CallbackInfo &info) {
686
1131
 
687
1132
  Napi::Value TesseractWrapper::GetALTOText(const Napi::CallbackInfo &info) {
688
1133
  Napi::Env env = info.Env();
689
- Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
690
1134
  CommandGetALTOText command{};
691
1135
 
692
- if (!info[0].IsUndefined()) {
1136
+ if (HasArg(info, 0)) {
693
1137
  if (!info[0].IsNumber()) {
694
- deferred.Reject(
695
- Napi::Error::New(env, "Expected page_number to be of type number")
696
- .Value());
697
- return deferred.Promise();
1138
+ return RejectTypeError(
1139
+ env, "getALTOText(pageNumber?): pageNumber must be a number",
1140
+ "getALTOText");
698
1141
  }
699
1142
 
700
1143
  int32_t page_number = info[0].As<Napi::Number>().Int32Value();