diff options
author | Iliyan Malchev <malchev@google.com> | 2008-10-07 09:09:46 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2008-10-09 14:27:54 -0700 |
commit | 4125145ec2a453fa13de515907294391a71c78b7 (patch) | |
tree | ea88d953f6d039a5dbd2666819a65082ba7d037e | |
parent | 4fcb47ad848430e96a08a2bae9b5042cf4ed5218 (diff) | |
download | tesseract-4125145ec2a453fa13de515907294391a71c78b7.tar.gz |
add more JNI bindings
Signed-off-by: Iliyan Malchev <malchev@google.com>
-rw-r--r-- | ccmain/jni.cpp | 208 |
1 files changed, 183 insertions, 25 deletions
diff --git a/ccmain/jni.cpp b/ccmain/jni.cpp index 294bf66..37a2403 100644 --- a/ccmain/jni.cpp +++ b/ccmain/jni.cpp @@ -17,7 +17,6 @@ #include <nativehelper/jni.h> #include <assert.h> -#include <stdio.h> // debug #include "baseapi.h" #include "varable.h" @@ -26,6 +25,7 @@ #define DEBUG 1 #if DEBUG +#include <stdio.h> BOOL_VAR (tessedit_write_images, TRUE, "Capture the image from the IPE"); #endif @@ -34,6 +34,8 @@ BOOL_VAR (tessedit_write_images, TRUE, #include <utils/Log.h> static tesseract::TessBaseAPI api; +static jbyteArray image_obj; +static jbyte* image_buffer; jboolean ocr_open(JNIEnv *env, jobject thiz, jstring lang) @@ -56,28 +58,54 @@ ocr_open(JNIEnv *env, jobject thiz, jstring lang) LOGE("could not initialize tesseract!"); res = JNI_FALSE; } +#if DEBUG else if (!api.ReadConfigFile("/sdcard/tessdata/ratings")) { LOGE("could not read config file, using defaults!"); // This is not a fatal error. } - LOGI("lang %s initialization complete\n", c_lang); +#endif + else + LOGI("lang %s initialization complete\n", c_lang); env->ReleaseStringUTFChars(lang, c_lang); LOGI("successfully initialized tesseract!"); return res; } +#if DEBUG +static void dump_debug_data(char *text) +{ + if (tessedit_write_images) { + page_image.write("/data/tessinput.tif"); + } + + if (text) { + const char *outfile = "/data/out.txt"; + LOGI("write to output %s\n", outfile); + FILE* fp = fopen(outfile, "w"); + if (fp != NULL) { + fwrite(text, strlen(text), 1, fp); + fclose(fp); + } + } +} +#else +static void dump_debug_data(char *text __attribute__((unused))) +{ +} +#endif + jstring -ocr_recognize(JNIEnv *env, jobject thiz, - jbyteArray image, - jint width, jint height, - jint bpp, - jint rowWidth) +ocr_recognize_image(JNIEnv *env, jobject thiz, + jbyteArray image, + jint width, jint height, + jint bpp, + jint rowWidth) { LOGI("recognize image x=%d, y=%d, rw=%d\n", width, height, rowWidth); if (env->GetArrayLength(image) < width * height) { - LOGE("image length = %ld is less than width * height = %ld!", + LOGE("image length = %d is less than width * height = %d!", env->GetArrayLength(image), width * height); } @@ -88,36 +116,166 @@ ocr_recognize(JNIEnv *env, jobject thiz, char * text = api.GetUTF8Text(); env->ReleaseByteArrayElements(image, buffer, JNI_ABORT); -#if DEBUG - if (tessedit_write_images) { - page_image.write("/data/tessinput.tif"); - } + dump_debug_data(text); - if (text) { - const char *outfile = "/data/out.txt"; - LOGI("write to output %s\n", outfile); - FILE* fp = fopen(outfile, "w"); - if (fp != NULL) { - fwrite(text, strlen(text), 1, fp); - fclose(fp); - } - } -#endif + // Will that work on a NULL? + return env->NewStringUTF(text); +} + +void +ocr_set_image(JNIEnv *env, jobject thiz, + jbyteArray image, + jint width, jint height, + jint bpp, + jint rowWidth) +{ + LOG_ASSERT(image_obj == NULL && image_buffer == NULL, + "image and/or image_buffer are not NULL!"); + image_obj = (jbyteArray)env->NewGlobalRef(image); + image_buffer = env->GetByteArrayElements(image_obj, NULL); + api.SetImage((const unsigned char *)image_buffer, + width, height, bpp, rowWidth); +} + +void +ocr_set_rectangle(JNIEnv *env, jobject thiz, + jint left, jint top, + jint width, jint height) +{ + // Restrict recognition to a sub-rectangle of the image. Call after SetImage. + // Each SetRectangle clears the recogntion results so multiple rectangles + // can be recognized with the same image. + LOG_ASSERT(image_obj != NULL && image_buffer != NULL, + "image and/or image_buffer are NULL!"); + api.SetRectangle(left, top, width, height); +} + +jstring +ocr_recognize(JNIEnv *env, jobject thiz, + jint width, jint height, + jint bpp, + jint rowWidth) +{ + LOG_ASSERT(image_obj != NULL && image_buffer != NULL, + "image and/or image_buffer are NULL!"); + + char * text = api.GetUTF8Text(); + + dump_debug_data(text); // Will that work on a NULL? return env->NewStringUTF(text); } +static jint +ocr_mean_confidence(JNIEnv *env, jobject thiz) +{ + // Returns the (average) confidence value between 0 and 100. + return api.MeanTextConf(); +} + +static jintArray +ocr_word_confidences(JNIEnv *env, jobject thiz) +{ + // Returns all word confidences (between 0 and 100) in an array, terminated + // by -1. The calling function must delete [] after use. + // The number of confidences should correspond to the number of space- + // delimited words in GetUTF8Text. + int* confs = api.AllWordConfidences(); + LOG_ASSERT(confs != NULL, "Could not get word-confidence values!"); + + int len, *trav; + for (len = 0, trav = confs; *trav != -1; trav++, len++); + + LOG_ASSERT(confs != NULL, "Confidence array has %d elements", + len); + + jintArray ret = env->NewIntArray(len); + LOG_ASSERT(ret != NULL, + "Could not create Java confidence array!"); + + env->SetIntArrayRegion(ret, 0, len, confs); + delete [] confs; + return ret; +} + +static void +ocr_set_variable(JNIEnv *env, jobject thiz, + jstring var, jstring value) +{ + // Set the value of an internal "variable" (of either old or new types). + // Supply the name of the variable and the value as a string, just as + // you would in a config file. + // Returns false if the name lookup failed. + // Eg SetVariable("tessedit_char_blacklist", "xyz"); to ignore x, y and z. + // Or SetVariable("bln_numericmode", "1"); to set numeric-only mode. + // SetVariable may be used before Init, but settings will revert to + // defaults on End(). + + const char *c_var = env->GetStringUTFChars(var, NULL); + const char *c_value = env->GetStringUTFChars(value, NULL); + + api.SetVariable(c_var, c_value); + + env->ReleaseStringUTFChars(var, c_var); + env->ReleaseStringUTFChars(value, c_value); +} + +static void +ocr_clear_results(JNIEnv *env, jobject thiz) +{ + // Free up recognition results and any stored image data, without actually + // freeing any recognition data that would be time-consuming to reload. + // Afterwards, you must call SetImage or TesseractRect before doing + // any Recognize or Get* operation. + LOGI("releasing all memory"); + api.Clear(); + + // Call between pages or documents etc to free up memory and forget + // adaptive data. + LOGI("clearing adaptive classifier"); + api.ClearAdaptiveClassifier(); + + if (image_buffer != NULL) { + LOGI("releasing image buffer"); + env->ReleaseByteArrayElements(image_obj, image_buffer, JNI_ABORT); + env->DeleteGlobalRef(image_obj); + image_obj = NULL; + image_buffer = NULL; + } +} + static void ocr_close(JNIEnv *env, jobject thiz) { LOGI("quit"); + + // Close down tesseract and free up all memory. End() is equivalent to + // destructing and reconstructing your TessBaseAPI. Once End() has been + // used, none of the other API functions may be used other than Init and + // anything declared above it in the class definition. +// api.End(); --> causes a crash +} + +static void +ocr_set_page_seg_mode(JNIEnv *env, jobject thiz, jint mode) +{ + // Set the current page segmentation mode. Defaults to PSM_AUTO. + api.SetPageSegMode((tesseract::PageSegMode)mode); } static JNINativeMethod methods[] = { - {"open", "(Ljava/lang/String;)Z", (void*)ocr_open}, - {"recognize", "([BIIII)Ljava/lang/String;", (void*)ocr_recognize}, - {"close", "()V", (void*)ocr_close}, + {"openNative", "(Ljava/lang/String;)Z", (void*)ocr_open}, + {"setImageNative", "([BIIII)V", (void*)ocr_set_image}, + {"setRectangleNative", "(IIII)V", (void*)ocr_set_rectangle}, + {"recognizeNative", "()Ljava/lang/String;", (void*)ocr_recognize}, + {"recognizeNative", "([BIIII)Ljava/lang/String;", (void*)ocr_recognize_image}, + {"clearResultsNative", "()V", (void*)ocr_clear_results}, + {"closeNative", "()V", (void*)ocr_close}, + {"meanConfidenceNative", "()I", (void*)ocr_mean_confidence}, + {"wordConfidencesNative", "()[I", (void*)ocr_word_confidences}, + {"setVariableNative", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)ocr_set_variable}, + {"setPageSegModeNative", "(I)V", (void*)ocr_set_page_seg_mode}, }; /* |