tessbaseapi.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /*
  2. * Copyright 2011, Google Inc.
  3. * Copyright 2011, Robert Theis
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <stdio.h>
  18. #include <malloc.h>
  19. #include "android/bitmap.h"
  20. #include "common.h"
  21. #include "baseapi.h"
  22. #include "ocrclass.h"
  23. #include "allheaders.h"
  24. #include "renderer.h"
  25. static jmethodID method_onProgressValues;
  26. struct native_data_t {
  27. tesseract::TessBaseAPI api;
  28. PIX *pix;
  29. void *data;
  30. bool debug;
  31. Box* currentTextBox = NULL;
  32. l_int32 lastProgress;
  33. bool cancel_ocr;
  34. JNIEnv *cachedEnv;
  35. jobject* cachedObject;
  36. bool isStateValid() {
  37. if (cancel_ocr == false && cachedEnv != NULL && cachedObject != NULL) {
  38. return true;
  39. } else {
  40. LOGI("state is cancelled");
  41. return false;
  42. }
  43. }
  44. void setTextBoundaries(l_uint32 x, l_uint32 y, l_uint32 width, l_uint32 height) {
  45. boxSetGeometry(currentTextBox, x, y, width, height);
  46. }
  47. void initStateVariables(JNIEnv* env, jobject *object) {
  48. cancel_ocr = false;
  49. cachedEnv = env;
  50. cachedObject = object;
  51. lastProgress = 0;
  52. }
  53. void resetStateVariables() {
  54. cancel_ocr = false;
  55. cachedEnv = NULL;
  56. cachedObject = NULL;
  57. lastProgress = 0;
  58. boxSetGeometry(currentTextBox, 0, 0, 0, 0);
  59. }
  60. native_data_t() {
  61. currentTextBox = boxCreate(0, 0, 0, 0);
  62. lastProgress = 0;
  63. pix = NULL;
  64. data = NULL;
  65. debug = false;
  66. cachedEnv = NULL;
  67. cachedObject = NULL;
  68. cancel_ocr = false;
  69. }
  70. ~native_data_t() {
  71. boxDestroy(&currentTextBox);
  72. }
  73. };
  74. /**
  75. * Callback for Tesseract's monitor to cancel recognition.
  76. */
  77. bool cancelFunc(void* cancel_this, int words) {
  78. native_data_t *nat = (native_data_t*)cancel_this;
  79. return nat->cancel_ocr;
  80. }
  81. /**
  82. * Callback for Tesseract's monitor to update progress.
  83. */
  84. bool progressJavaCallback(void* progress_this, int progress, int left, int right,
  85. int top, int bottom) {
  86. native_data_t *nat = (native_data_t*)progress_this;
  87. if (nat->isStateValid() && nat->currentTextBox != NULL) {
  88. if (progress > nat->lastProgress || left != 0 || right != 0 || top != 0 || bottom != 0) {
  89. int x, y, width, height;
  90. boxGetGeometry(nat->currentTextBox, &x, &y, &width, &height);
  91. nat->cachedEnv->CallVoidMethod(*(nat->cachedObject), method_onProgressValues, progress,
  92. (jint) left, (jint) right, (jint) top, (jint) bottom,
  93. (jint) x, (jint) (x + width), (jint) (y + height), (jint) y);
  94. nat->lastProgress = progress;
  95. }
  96. }
  97. return true;
  98. }
  99. #ifdef __cplusplus
  100. extern "C" {
  101. #endif
  102. jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  103. JNIEnv *env;
  104. if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
  105. LOGE("Failed to get the environment using GetEnv()");
  106. return -1;
  107. }
  108. return JNI_VERSION_1_6;
  109. }
  110. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeClassInit(JNIEnv* env,
  111. jclass clazz) {
  112. method_onProgressValues = env->GetMethodID(clazz, "onProgressValues", "(IIIIIIIII)V");
  113. }
  114. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeConstruct(JNIEnv* env,
  115. jobject object) {
  116. native_data_t *nat = new native_data_t;
  117. if (nat == NULL) {
  118. LOGE("%s: out of memory!", __FUNCTION__);
  119. return 0;
  120. }
  121. return (jlong) nat;
  122. }
  123. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeInit(JNIEnv *env,
  124. jobject thiz,
  125. jlong mNativeData,
  126. jstring dir,
  127. jstring lang) {
  128. native_data_t *nat = (native_data_t*) mNativeData;
  129. const char *c_dir = env->GetStringUTFChars(dir, NULL);
  130. const char *c_lang = env->GetStringUTFChars(lang, NULL);
  131. jboolean res = JNI_TRUE;
  132. if (nat->api.Init(c_dir, c_lang)) {
  133. LOGE("Could not initialize Tesseract API with language=%s!", c_lang);
  134. res = JNI_FALSE;
  135. } else {
  136. LOGI("Initialized Tesseract API with language=%s", c_lang);
  137. }
  138. env->ReleaseStringUTFChars(dir, c_dir);
  139. env->ReleaseStringUTFChars(lang, c_lang);
  140. return res;
  141. }
  142. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeInitOem(JNIEnv *env,
  143. jobject thiz,
  144. jlong mNativeData,
  145. jstring dir,
  146. jstring lang,
  147. jint mode) {
  148. native_data_t *nat = (native_data_t*) mNativeData;
  149. const char *c_dir = env->GetStringUTFChars(dir, NULL);
  150. const char *c_lang = env->GetStringUTFChars(lang, NULL);
  151. jboolean res = JNI_TRUE;
  152. if (nat->api.Init(c_dir, c_lang, (tesseract::OcrEngineMode) mode)) {
  153. LOGE("Could not initialize Tesseract API with language=%s!", c_lang);
  154. res = JNI_FALSE;
  155. } else {
  156. LOGI("Initialized Tesseract API with language=%s", c_lang);
  157. }
  158. env->ReleaseStringUTFChars(dir, c_dir);
  159. env->ReleaseStringUTFChars(lang, c_lang);
  160. return res;
  161. }
  162. jstring Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetInitLanguagesAsString(JNIEnv *env,
  163. jobject thiz,
  164. jlong mNativeData) {
  165. native_data_t *nat = (native_data_t*) mNativeData;
  166. const char *text = nat->api.GetInitLanguagesAsString();
  167. jstring result = env->NewStringUTF(text);
  168. return result;
  169. }
  170. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetImageBytes(JNIEnv *env,
  171. jobject thiz,
  172. jlong mNativeData,
  173. jbyteArray data,
  174. jint width,
  175. jint height,
  176. jint bpp,
  177. jint bpl) {
  178. jbyte *data_array = env->GetByteArrayElements(data, NULL);
  179. int count = env->GetArrayLength(data);
  180. unsigned char* imagedata = (unsigned char *) malloc(count * sizeof(unsigned char));
  181. // This is painfully slow, but necessary because we don't know
  182. // how many bits the JVM might be using to represent a byte
  183. for (int i = 0; i < count; i++) {
  184. imagedata[i] = (unsigned char) data_array[i];
  185. }
  186. env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
  187. native_data_t *nat = (native_data_t*) mNativeData;
  188. nat->api.SetImage(imagedata, (int) width, (int) height, (int) bpp, (int) bpl);
  189. // Since Tesseract doesn't take ownership of the memory, we keep a pointer in the native
  190. // code struct. We need to free that pointer when we release our instance of Tesseract or
  191. // attempt to set a new image using one of the nativeSet* methods.
  192. if (nat->data != NULL)
  193. free(nat->data);
  194. else if (nat->pix != NULL)
  195. pixDestroy(&nat->pix);
  196. nat->data = imagedata;
  197. nat->pix = NULL;
  198. }
  199. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetImagePix(JNIEnv *env,
  200. jobject thiz,
  201. jlong mNativeData,
  202. jlong nativePix) {
  203. PIX *pixs = (PIX *) nativePix;
  204. PIX *pixd = pixClone(pixs);
  205. native_data_t *nat = (native_data_t*) mNativeData;
  206. if (pixd) {
  207. l_int32 width = pixGetWidth(pixd);
  208. l_int32 height = pixGetHeight(pixd);
  209. nat->setTextBoundaries(0, 0, width, height);
  210. }
  211. nat->api.SetImage(pixd);
  212. // Since Tesseract doesn't take ownership of the memory, we keep a pointer in the native
  213. // code struct. We need to free that pointer when we release our instance of Tesseract or
  214. // attempt to set a new image using one of the nativeSet* methods.
  215. if (nat->data != NULL)
  216. free(nat->data);
  217. else if (nat->pix != NULL)
  218. pixDestroy(&nat->pix);
  219. nat->data = NULL;
  220. nat->pix = pixd;
  221. }
  222. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetRectangle(JNIEnv *env,
  223. jobject thiz,
  224. jlong mNativeData,
  225. jint left,
  226. jint top,
  227. jint width,
  228. jint height) {
  229. native_data_t *nat = (native_data_t*) mNativeData;
  230. nat->setTextBoundaries(left, top, width, height);
  231. nat->api.SetRectangle(left, top, width, height);
  232. }
  233. jstring Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetUTF8Text(JNIEnv *env,
  234. jobject thiz,
  235. jlong mNativeData) {
  236. native_data_t *nat = (native_data_t*) mNativeData;
  237. nat->initStateVariables(env, &thiz);
  238. ETEXT_DESC monitor;
  239. monitor.progress_callback = progressJavaCallback;
  240. monitor.cancel = cancelFunc;
  241. monitor.cancel_this = nat;
  242. monitor.progress_this = nat;
  243. char *text = nat->api.GetUTF8Text();
  244. jstring result = env->NewStringUTF(text);
  245. free(text);
  246. nat->resetStateVariables();
  247. return result;
  248. }
  249. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeStop(JNIEnv *env,
  250. jobject thiz,
  251. jlong mNativeData) {
  252. native_data_t *nat = (native_data_t*) mNativeData;
  253. // Stop by setting a flag that's used by the monitor
  254. nat->resetStateVariables();
  255. nat->cancel_ocr = true;
  256. }
  257. jint Java_com_googlecode_tesseract_android_TessBaseAPI_nativeMeanConfidence(JNIEnv *env,
  258. jobject thiz,
  259. jlong mNativeData) {
  260. native_data_t *nat = (native_data_t*) mNativeData;
  261. return (jint) nat->api.MeanTextConf();
  262. }
  263. jintArray Java_com_googlecode_tesseract_android_TessBaseAPI_nativeWordConfidences(JNIEnv *env,
  264. jobject thiz,
  265. jlong mNativeData) {
  266. native_data_t *nat = (native_data_t*) mNativeData;
  267. int *confs = nat->api.AllWordConfidences();
  268. if (confs == NULL) {
  269. LOGE("Could not get word-confidence values!");
  270. return NULL;
  271. }
  272. int len, *trav;
  273. for (len = 0, trav = confs; *trav != -1; trav++, len++)
  274. ;
  275. LOG_ASSERT((confs != NULL), "Confidence array has %d elements", len);
  276. jintArray ret = env->NewIntArray(len);
  277. LOG_ASSERT((ret != NULL), "Could not create Java confidence array!");
  278. env->SetIntArrayRegion(ret, 0, len, confs);
  279. delete[] confs;
  280. return ret;
  281. }
  282. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetVariable(JNIEnv *env,
  283. jobject thiz,
  284. jlong mNativeData,
  285. jstring var,
  286. jstring value) {
  287. native_data_t *nat = (native_data_t*) mNativeData;
  288. const char *c_var = env->GetStringUTFChars(var, NULL);
  289. const char *c_value = env->GetStringUTFChars(value, NULL);
  290. jboolean set = nat->api.SetVariable(c_var, c_value) ? JNI_TRUE : JNI_FALSE;
  291. env->ReleaseStringUTFChars(var, c_var);
  292. env->ReleaseStringUTFChars(value, c_value);
  293. return set;
  294. }
  295. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeClear(JNIEnv *env,
  296. jobject thiz,
  297. jlong mNativeData) {
  298. native_data_t *nat = (native_data_t*) mNativeData;
  299. nat->api.Clear();
  300. // Call between pages or documents etc to free up memory and forget adaptive data.
  301. nat->api.ClearAdaptiveClassifier();
  302. // Since Tesseract doesn't take ownership of the memory, we keep a pointer in the native
  303. // code struct. We need to free that pointer when we release our instance of Tesseract or
  304. // attempt to set a new image using one of the nativeSet* methods.
  305. if (nat->data != NULL)
  306. free(nat->data);
  307. else if (nat->pix != NULL)
  308. pixDestroy(&nat->pix);
  309. nat->data = NULL;
  310. nat->pix = NULL;
  311. }
  312. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeEnd(JNIEnv *env,
  313. jobject thiz,
  314. jlong mNativeData) {
  315. native_data_t *nat = (native_data_t*) mNativeData;
  316. nat->api.End();
  317. // Since Tesseract doesn't take ownership of the memory, we keep a pointer in the native
  318. // code struct. We need to free that pointer when we release our instance of Tesseract or
  319. // attempt to set a new image using one of the nativeSet* methods.
  320. if (nat->data != NULL)
  321. free(nat->data);
  322. else if (nat->pix != NULL)
  323. pixDestroy(&nat->pix);
  324. nat->data = NULL;
  325. nat->pix = NULL;
  326. }
  327. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetDebug(JNIEnv *env,
  328. jobject thiz,
  329. jlong mNativeData,
  330. jboolean debug) {
  331. native_data_t *nat = (native_data_t*) mNativeData;
  332. nat->debug = (debug == JNI_TRUE) ? TRUE : FALSE;
  333. }
  334. jint Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetPageSegMode(JNIEnv *env,
  335. jobject thiz,
  336. jlong mNativeData) {
  337. native_data_t *nat = (native_data_t*) mNativeData;
  338. return nat->api.GetPageSegMode();
  339. }
  340. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetPageSegMode(JNIEnv *env,
  341. jobject thiz,
  342. jlong mNativeData,
  343. jint mode) {
  344. native_data_t *nat = (native_data_t*) mNativeData;
  345. nat->api.SetPageSegMode((tesseract::PageSegMode) mode);
  346. }
  347. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetThresholdedImage(JNIEnv *env,
  348. jobject thiz,
  349. jlong mNativeData) {
  350. native_data_t *nat = (native_data_t*) mNativeData;
  351. PIX *pix = nat->api.GetThresholdedImage();
  352. return (jlong) pix;
  353. }
  354. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetRegions(JNIEnv *env,
  355. jobject thiz,
  356. jlong mNativeData) {
  357. native_data_t *nat = (native_data_t*) mNativeData;
  358. PIXA *pixa = NULL;
  359. BOXA *boxa;
  360. boxa = nat->api.GetRegions(&pixa);
  361. boxaDestroy(&boxa);
  362. return reinterpret_cast<jlong>(pixa);
  363. }
  364. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetTextlines(JNIEnv *env,
  365. jobject thiz,
  366. jlong mNativeData) {
  367. native_data_t *nat = (native_data_t*) mNativeData;
  368. PIXA *pixa = NULL;
  369. BOXA *boxa;
  370. boxa = nat->api.GetTextlines(&pixa, NULL);
  371. boxaDestroy(&boxa);
  372. return reinterpret_cast<jlong>(pixa);
  373. }
  374. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetStrips(JNIEnv *env,
  375. jobject thiz,
  376. jlong mNativeData) {
  377. native_data_t *nat = (native_data_t*) mNativeData;
  378. PIXA *pixa = NULL;
  379. BOXA *boxa;
  380. boxa = nat->api.GetStrips(&pixa, NULL);
  381. boxaDestroy(&boxa);
  382. return reinterpret_cast<jlong>(pixa);
  383. }
  384. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetWords(JNIEnv *env,
  385. jobject thiz,
  386. jlong mNativeData) {
  387. native_data_t *nat = (native_data_t*) mNativeData;
  388. PIXA *pixa = NULL;
  389. BOXA *boxa;
  390. boxa = nat->api.GetWords(&pixa);
  391. boxaDestroy(&boxa);
  392. return reinterpret_cast<jlong>(pixa);
  393. }
  394. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetConnectedComponents(JNIEnv *env,
  395. jobject thiz,
  396. jlong mNativeData) {
  397. native_data_t *nat = (native_data_t*) mNativeData;
  398. PIXA *pixa = NULL;
  399. BOXA *boxa;
  400. boxa = nat->api.GetConnectedComponents(&pixa);
  401. boxaDestroy(&boxa);
  402. return reinterpret_cast<jlong>(pixa);
  403. }
  404. jlong Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetResultIterator(JNIEnv *env,
  405. jobject thiz,
  406. jlong mNativeData) {
  407. native_data_t *nat = (native_data_t*) mNativeData;
  408. return (jlong) nat->api.GetIterator();
  409. }
  410. jstring Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetHOCRText(JNIEnv *env,
  411. jobject thiz,
  412. jlong mNativeData,
  413. jint page) {
  414. native_data_t *nat = (native_data_t*) mNativeData;
  415. nat->initStateVariables(env, &thiz);
  416. ETEXT_DESC monitor;
  417. monitor.progress_callback = progressJavaCallback;
  418. monitor.cancel = cancelFunc;
  419. monitor.cancel_this = nat;
  420. monitor.progress_this = nat;
  421. char *text = nat->api.GetHOCRText(&monitor, page);
  422. jstring result = env->NewStringUTF(text);
  423. free(text);
  424. nat->resetStateVariables();
  425. return result;
  426. }
  427. jstring Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetBoxText(JNIEnv *env,
  428. jobject thiz,
  429. jlong mNativeData,
  430. jint page) {
  431. native_data_t *nat = (native_data_t*) mNativeData;
  432. char *text = nat->api.GetBoxText(page);
  433. jstring result = env->NewStringUTF(text);
  434. free(text);
  435. return result;
  436. }
  437. jstring Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetVersion(JNIEnv *env,
  438. jobject thiz,
  439. jlong mNativeData) {
  440. native_data_t *nat = (native_data_t*) mNativeData;
  441. const char *text = nat->api.Version();
  442. jstring result = env->NewStringUTF(text);
  443. return result;
  444. }
  445. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetInputName(JNIEnv *env,
  446. jobject thiz,
  447. jlong mNativeData,
  448. jstring name) {
  449. native_data_t *nat = (native_data_t*) mNativeData;
  450. const char *c_name = env->GetStringUTFChars(name, NULL);
  451. nat->api.SetInputName(c_name);
  452. env->ReleaseStringUTFChars(name, c_name);
  453. }
  454. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeSetOutputName(JNIEnv *env,
  455. jobject thiz,
  456. jlong mNativeData,
  457. jstring name) {
  458. native_data_t *nat = (native_data_t*) mNativeData;
  459. const char *c_name = env->GetStringUTFChars(name, NULL);
  460. nat->api.SetOutputName(c_name);
  461. env->ReleaseStringUTFChars(name, c_name);
  462. }
  463. void Java_com_googlecode_tesseract_android_TessBaseAPI_nativeReadConfigFile(JNIEnv *env,
  464. jobject thiz,
  465. jlong mNativeData,
  466. jstring fileName) {
  467. native_data_t *nat = (native_data_t*) mNativeData;
  468. const char *c_file_name = env->GetStringUTFChars(fileName, NULL);
  469. nat->api.ReadConfigFile(c_file_name);
  470. env->ReleaseStringUTFChars(fileName, c_file_name);
  471. }
  472. jlong Java_com_googlecode_tesseract_android_TessPdfRenderer_nativeCreate(JNIEnv *env,
  473. jobject thiz,
  474. jlong jTessBaseApi,
  475. jstring outputPath) {
  476. native_data_t *nat = (native_data_t*) jTessBaseApi;
  477. const char *c_output_path = env->GetStringUTFChars(outputPath, NULL);
  478. tesseract::TessPDFRenderer* result = new tesseract::TessPDFRenderer(c_output_path, nat->api.GetDatapath());
  479. env->ReleaseStringUTFChars(outputPath, c_output_path);
  480. return (jlong) result;
  481. }
  482. void Java_com_googlecode_tesseract_android_TessPdfRenderer_nativeRecycle(JNIEnv *env,
  483. jobject thiz,
  484. jlong jPointer) {
  485. tesseract::TessPDFRenderer* renderer = (tesseract::TessPDFRenderer*) jPointer;
  486. delete renderer;
  487. }
  488. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeBeginDocument(JNIEnv *env,
  489. jobject thiz,
  490. jlong jRenderer,
  491. jstring title) {
  492. const char *c_title = env->GetStringUTFChars(title, NULL);
  493. tesseract::TessPDFRenderer* pdfRenderer = (tesseract::TessPDFRenderer*) jRenderer;
  494. jboolean res = JNI_TRUE;
  495. if (pdfRenderer->BeginDocument(c_title)) {
  496. res = JNI_FALSE;
  497. }
  498. env->ReleaseStringUTFChars(title, c_title);
  499. return res;
  500. }
  501. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeEndDocument(JNIEnv *env,
  502. jobject thiz,
  503. jlong jRenderer) {
  504. tesseract::TessPDFRenderer* pdfRenderer = (tesseract::TessPDFRenderer*) jRenderer;
  505. return pdfRenderer->EndDocument();
  506. }
  507. jboolean Java_com_googlecode_tesseract_android_TessBaseAPI_nativeAddPageToDocument(JNIEnv *env,
  508. jobject thiz,
  509. jlong mNativeData,
  510. jlong jPix,
  511. jstring jPath,
  512. jlong jRenderer) {
  513. tesseract::TessPDFRenderer* pdfRenderer = (tesseract::TessPDFRenderer*) jRenderer;
  514. native_data_t *nat = (native_data_t*) mNativeData;
  515. PIX* pix = (PIX*) jPix;
  516. const char *inputImage = env->GetStringUTFChars(jPath, NULL);
  517. nat->api.ProcessPage(pix, 0, inputImage, NULL, 0, pdfRenderer);
  518. env->ReleaseStringUTFChars(jPath, inputImage);
  519. return true;
  520. }
  521. #ifdef __cplusplus
  522. }
  523. #endif