aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIliyan Malchev <malchev@google.com>2008-10-07 09:09:46 -0700
committerIliyan Malchev <malchev@google.com>2008-10-09 14:27:54 -0700
commit4125145ec2a453fa13de515907294391a71c78b7 (patch)
treeea88d953f6d039a5dbd2666819a65082ba7d037e
parent4fcb47ad848430e96a08a2bae9b5042cf4ed5218 (diff)
downloadtesseract-4125145ec2a453fa13de515907294391a71c78b7.tar.gz
add more JNI bindings
Signed-off-by: Iliyan Malchev <malchev@google.com>
-rw-r--r--ccmain/jni.cpp208
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},
};
/*