├── .gitignore ├── README.md ├── tesseract-android-tools-test ├── .classpath ├── .project ├── AndroidManifest.xml ├── README ├── build.xml ├── proguard-project.txt ├── project.properties ├── res │ └── values │ │ └── strings.xml └── src │ └── com │ └── googlecode │ ├── leptonica │ └── android │ │ └── test │ │ ├── AdaptiveMapTest.java │ │ ├── BinarizeTest.java │ │ ├── BoxTest.java │ │ ├── ConvertTest.java │ │ ├── EnhanceTest.java │ │ ├── JpegIOTest.java │ │ ├── PixTest.java │ │ ├── PixaTest.java │ │ ├── ReadFileTest.java │ │ ├── RotateTest.java │ │ ├── ScaleTest.java │ │ ├── SkewTest.java │ │ ├── TestUtils.java │ │ └── WriteFileTest.java │ └── tesseract │ └── android │ └── test │ ├── AllTests.java │ └── TessBaseAPITest.java └── tesseract-android-tools ├── .classpath ├── .gitignore ├── .project ├── AndroidManifest.xml ├── COPYING ├── README.md ├── build.xml ├── dependencies.sh ├── jni ├── Android.mk ├── Application.mk ├── com_googlecode_leptonica_android │ ├── .gitignore │ ├── Android.mk │ ├── box.cpp │ ├── common.h │ ├── config_auto.h │ ├── jni.cpp │ ├── pix.cpp │ ├── pixa.cpp │ ├── readfile.cpp │ ├── stdio │ │ ├── extrastdio.h │ │ ├── fmemopen.c │ │ ├── fopencookie.c │ │ └── open_memstream.c │ ├── utilities.cpp │ └── writefile.cpp └── com_googlecode_tesseract_android │ ├── .gitignore │ ├── Android.mk │ ├── common.h │ ├── glibc │ ├── glob.c │ └── glob.h │ ├── pageiterator.cpp │ ├── resultiterator.cpp │ └── tessbaseapi.cpp ├── languages.sh ├── proguard-project.txt ├── project.properties ├── res └── .stub └── src └── com └── googlecode ├── leptonica └── android │ ├── AdaptiveMap.java │ ├── Binarize.java │ ├── Box.java │ ├── Constants.java │ ├── Convert.java │ ├── Enhance.java │ ├── JpegIO.java │ ├── Pix.java │ ├── Pixa.java │ ├── ReadFile.java │ ├── Rotate.java │ ├── Scale.java │ ├── Skew.java │ └── WriteFile.java └── tesseract └── android ├── PageIterator.java ├── ResultIterator.java └── TessBaseAPI.java /.gitignore: -------------------------------------------------------------------------------- 1 | */bin 2 | */gen 3 | local.properties 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Tools for Tesseract OCR Library 2 | 3 | This project is a clone of [https://code.google.com/p/tesseract-android-tools/](http://https://code.google.com/p/tesseract-android-tools/). -------------------------------------------------------------------------------- /tesseract-android-tools-test/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tesseract-android-tools-test 4 | 5 | 6 | tesseract-android-tools 7 | 8 | 9 | 10 | com.android.ide.eclipse.adt.ResourceManagerBuilder 11 | 12 | 13 | 14 | 15 | com.android.ide.eclipse.adt.PreCompilerBuilder 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javabuilder 21 | 22 | 23 | 24 | 25 | com.android.ide.eclipse.adt.ApkBuilder 26 | 27 | 28 | 29 | 30 | 31 | com.android.ide.eclipse.adt.AndroidNature 32 | org.eclipse.jdt.core.javanature 33 | 34 | 35 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 23 | 26 | 27 | 28 | 29 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/README: -------------------------------------------------------------------------------- 1 | This project contains tests for the Tesseract and Leptonica libraries for use 2 | on the Android platform. See ../tesseract-android-tools/README for information 3 | on working with the libraries themselves. 4 | 5 | You must install language data before attempting to run the tests. To download 6 | the English language files for Tesseract and copy them to your device's 7 | external storage, run the following commands in the terminal: 8 | 9 | cd 10 | curl -O http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.01.eng.tar.gz 11 | tar -zxvf tesseract-ocr-3.01.eng.tar.gz 12 | rm -f tesseract-ocr-3.01.eng.tar.gz 13 | mkdir data 14 | mv tesseract-ocr data/tesseract 15 | adb push data/ /sdcard/ 16 | adb shell sync 17 | 18 | To build and test this project, run the following commands in the terminal: 19 | 20 | cd 21 | android update project --path . 22 | ant debug 23 | adb install -r -s bin/tesseract-android-tools-test-debug.apk 24 | adb shell am instrument -w -e class com.googlecode.tesseract.android.test.AllTests \ 25 | com.googlecode.tesseract.android.test/android.test.InstrumentationTestRunner 26 | 27 | If you receive an INSTALL_FAILED_INSUFFICIENT_STORAGE failure, try installing 28 | to internal storage by removing the -s flag from "adb install -r -s ..." 29 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | android.library.reference.1=../tesseract-android-tools 11 | # Project target. 12 | target=android-8 13 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tesseract Test 4 | 5 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/AdaptiveMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | 21 | public class AdaptiveMapTest extends TestCase { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/BinarizeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | 21 | public class BinarizeTest extends TestCase { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/BoxTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | import android.test.suitebuilder.annotation.SmallTest; 21 | 22 | import com.googlecode.leptonica.android.Box; 23 | 24 | public class BoxTest extends TestCase { 25 | @SmallTest 26 | public void testBoxCreate() { 27 | testBoxCreate(10, 10, 10, 10); 28 | testBoxCreate(0, 0, 1, 1); 29 | } 30 | 31 | private void testBoxCreate(int x, int y, int w, int h) { 32 | Box box = new Box(x, y, w, h); 33 | 34 | assertEquals(x, box.getX()); 35 | assertEquals(y, box.getY()); 36 | assertEquals(w, box.getWidth()); 37 | assertEquals(h, box.getHeight()); 38 | 39 | box.recycle(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/ConvertTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Color; 20 | import android.test.suitebuilder.annotation.SmallTest; 21 | 22 | import com.googlecode.leptonica.android.Convert; 23 | import com.googlecode.leptonica.android.Pix; 24 | 25 | import junit.framework.TestCase; 26 | 27 | public class ConvertTest extends TestCase { 28 | @SmallTest 29 | public void testConvertTo8() { 30 | Pix pixs = new Pix(640, 480, 32); 31 | pixs.setPixel(0, 0, Color.RED); 32 | pixs.setPixel(1, 0, Color.GREEN); 33 | pixs.setPixel(2, 0, Color.BLUE); 34 | pixs.setPixel(3, 0, Color.WHITE); 35 | pixs.setPixel(4, 0, Color.BLACK); 36 | 37 | Pix pixd = Convert.convertTo8(pixs); 38 | 39 | assertNotSame(Color.RED, pixd.getPixel(0, 0)); 40 | assertNotSame(Color.GREEN, pixd.getPixel(1, 0)); 41 | assertNotSame(Color.BLUE, pixd.getPixel(2, 0)); 42 | assertEquals(Color.WHITE, pixd.getPixel(3, 0)); 43 | assertEquals(Color.BLACK, pixd.getPixel(4, 0)); 44 | 45 | pixs.recycle(); 46 | pixd.recycle(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/EnhanceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | 21 | public class EnhanceTest extends TestCase { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/JpegIOTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | import android.test.suitebuilder.annotation.SmallTest; 22 | 23 | import com.googlecode.leptonica.android.JpegIO; 24 | import com.googlecode.leptonica.android.Pix; 25 | import com.googlecode.leptonica.android.ReadFile; 26 | 27 | import junit.framework.TestCase; 28 | 29 | public class JpegIOTest extends TestCase { 30 | @SmallTest 31 | public void testCompressToJpeg() { 32 | testCompressToJpeg(640, 480, 85, true); 33 | testCompressToJpeg(640, 480, 85, false); 34 | } 35 | 36 | private void testCompressToJpeg(int width, int height, int quality, boolean progressive) { 37 | Bitmap bmps = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 38 | Pix pixs = ReadFile.readBitmap(bmps); 39 | byte[] encodedBytes = JpegIO.compressToJpeg(pixs, quality, progressive); 40 | Bitmap bmpd = BitmapFactory.decodeByteArray(encodedBytes, 0, encodedBytes.length); 41 | 42 | assertEquals(bmps.getWidth(), bmpd.getWidth()); 43 | assertEquals(bmps.getHeight(), bmpd.getHeight()); 44 | 45 | bmps.recycle(); 46 | pixs.recycle(); 47 | encodedBytes = null; 48 | bmpd.recycle(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/PixTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | import android.graphics.Color; 21 | import android.test.suitebuilder.annotation.SmallTest; 22 | 23 | import com.googlecode.leptonica.android.Pix; 24 | 25 | public class PixTest extends TestCase { 26 | @SmallTest 27 | public void testPixCreate() { 28 | testPixCreate(1, 1, 1); 29 | testPixCreate(640, 480, 32); 30 | } 31 | 32 | private void testPixCreate(int w, int h, int d) { 33 | Pix pix = new Pix(w, h, d); 34 | 35 | // Make sure the dimensions were set correctly. 36 | assertEquals(w, pix.getWidth()); 37 | assertEquals(h, pix.getHeight()); 38 | assertEquals(d, pix.getDepth()); 39 | 40 | // Make sure we can recycle the Pix. 41 | pix.recycle(); 42 | } 43 | 44 | @SmallTest 45 | public void testPixPixelOps() { 46 | Pix pix = new Pix(640, 480, 32); 47 | 48 | // Set various pixel colors. 49 | pix.setPixel(0, 0, Color.RED); 50 | pix.setPixel(1, 0, Color.BLUE); 51 | pix.setPixel(2, 0, Color.GREEN); 52 | pix.setPixel(3, 0, Color.BLACK); 53 | pix.setPixel(4, 0, Color.WHITE); 54 | 55 | // Make sure the pixel was set and retrieved correctly. 56 | assertEquals(Color.RED, pix.getPixel(0, 0)); 57 | assertEquals(Color.BLUE, pix.getPixel(1, 0)); 58 | assertEquals(Color.GREEN, pix.getPixel(2, 0)); 59 | assertEquals(Color.BLACK, pix.getPixel(3, 0)); 60 | assertEquals(Color.WHITE, pix.getPixel(4, 0)); 61 | 62 | pix.recycle(); 63 | } 64 | 65 | @SmallTest 66 | public void testPixClone() { 67 | Pix pix = new Pix(640, 480, 32); 68 | Pix pixCopy = pix.clone(); 69 | 70 | // The clone should not have the same native pointer. 71 | assertNotSame(pix.getNativePix(), pixCopy.getNativePix()); 72 | 73 | // The clone should share the same backing data. 74 | pix.setPixel(0, 0, Color.RED); 75 | assertEquals(Color.RED, pixCopy.getPixel(0, 0)); 76 | 77 | // Finally, we should be able to recycle both Pix. 78 | pix.recycle(); 79 | pixCopy.recycle(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/PixaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.test.suitebuilder.annotation.SmallTest; 20 | 21 | import com.googlecode.leptonica.android.Box; 22 | import com.googlecode.leptonica.android.Constants; 23 | import com.googlecode.leptonica.android.Pix; 24 | import com.googlecode.leptonica.android.Pixa; 25 | 26 | import junit.framework.TestCase; 27 | 28 | public class PixaTest extends TestCase { 29 | @SmallTest 30 | public void testPixaCreate() { 31 | internalTestPixaCreate(0, 0, 0); 32 | internalTestPixaCreate(1, 0, 0); 33 | internalTestPixaCreate(0, 640, 480); 34 | internalTestPixaCreate(5, 640, 480); 35 | } 36 | 37 | private void internalTestPixaCreate(int initialCapacity, int width, int height) { 38 | Pixa pixa = Pixa.createPixa(initialCapacity, width, height); 39 | 40 | // Make sure the dimensions were set correctly. 41 | assertEquals(0, pixa.size()); 42 | assertEquals(width, pixa.getWidth()); 43 | assertEquals(height, pixa.getHeight()); 44 | 45 | // Fill the Pixa to capacity. 46 | for (int i = 0; i < initialCapacity; i++) { 47 | addBlockToPixa(pixa, 0, 0, 640, 480, 8); 48 | } 49 | 50 | // Make sure the size is reflected correctly. 51 | assertEquals(initialCapacity, pixa.size()); 52 | 53 | // Make sure we can recycle the Pixa. 54 | pixa.recycle(); 55 | } 56 | 57 | @SmallTest 58 | public void testPixaCopy() { 59 | internalTestPixaCopy(0, 0, 0); 60 | internalTestPixaCopy(5, 0, 0); 61 | internalTestPixaCopy(0, 640, 480); 62 | internalTestPixaCopy(5, 640, 480); 63 | } 64 | 65 | private void internalTestPixaCopy(int initialCapacity, int width, int height) { 66 | Pixa pixa = Pixa.createPixa(initialCapacity, width, height); 67 | 68 | // Fill the Pixa to capacity. 69 | for (int i = 0; i < initialCapacity; i++) { 70 | addBlockToPixa(pixa, 0, 0, 640, 640, 8); 71 | } 72 | 73 | // Create a shallow copy of the Pixa. 74 | Pixa pixaCopy = pixa.copy(); 75 | 76 | // Add a new Pix to the copy. 77 | addBlockToPixa(pixaCopy, 0, 0, 640, 640, 8); 78 | 79 | // Ensure that both copies changed size. 80 | assertEquals(initialCapacity + 1, pixaCopy.size()); 81 | assertEquals(pixaCopy.size(), pixa.size()); 82 | 83 | // Finally, we should be able to recycle both Pixa. 84 | pixa.recycle(); 85 | pixaCopy.recycle(); 86 | } 87 | 88 | @SmallTest 89 | public void testPixaSort() { 90 | Pixa pixa = Pixa.createPixa(0); 91 | 92 | // Add contained Pix in arbitrary order. 93 | addBlockToPixa(pixa, 0, 0, 640, 640, 8); 94 | addBlockToPixa(pixa, 160, 160, 64, 64, 8); 95 | addBlockToPixa(pixa, 32, 32, 320, 320, 8); 96 | addBlockToPixa(pixa, 64, 64, 160, 160, 8); 97 | addBlockToPixa(pixa, 320, 320, 32, 32, 8); 98 | 99 | // Sort by increasing height. 100 | Pixa pixaSorted = pixa.sort(Constants.L_SORT_BY_HEIGHT, Constants.L_SORT_INCREASING); 101 | 102 | // Ensure sort was successful. 103 | int[] currentDimensions = new int[4]; 104 | int previousHeight = -1; 105 | 106 | for (int i = 0; i < pixa.size(); i++) { 107 | assertTrue(pixaSorted.getBoxGeometry(i, currentDimensions)); 108 | int currentHeight = currentDimensions[Box.INDEX_H]; 109 | assertTrue(currentHeight > previousHeight); 110 | previousHeight = currentHeight; 111 | } 112 | 113 | pixa.recycle(); 114 | pixaSorted.recycle(); 115 | } 116 | 117 | @SmallTest 118 | public void testPixaJoin() { 119 | internalTestPixaJoin(0, 0); 120 | internalTestPixaJoin(1, 0); 121 | internalTestPixaJoin(0, 1); 122 | internalTestPixaJoin(1, 1); 123 | } 124 | 125 | private void internalTestPixaJoin(int sizeA, int sizeB) { 126 | Pixa pixaA = Pixa.createPixa(0); 127 | Pixa pixaB = Pixa.createPixa(0); 128 | 129 | // Populate both Pixa. 130 | for (int i = 0; i < sizeA; i++) { 131 | addBlockToPixa(pixaA, 0, 0, 640, 640, 8); 132 | } 133 | 134 | for (int i = 0; i < sizeB; i++) { 135 | addBlockToPixa(pixaB, 0, 0, 640, 640, 8); 136 | } 137 | 138 | // Join pixaB into pixaA. 139 | pixaA.join(pixaB); 140 | 141 | // Ensure the join was successful. 142 | assertEquals(pixaA.size(), sizeA + sizeB); 143 | assertEquals(pixaB.size(), sizeB); 144 | 145 | pixaA.recycle(); 146 | pixaB.recycle(); 147 | } 148 | 149 | @SmallTest 150 | public void textPixaReplacePix() { 151 | Pixa pixa = Pixa.createPixa(0, 640, 480); 152 | 153 | // Populate the Pixa. 154 | addBlockToPixa(pixa, 0, 0, 640, 480, 8); 155 | 156 | Pix pix = new Pix(320, 240, 8); 157 | Box box = new Box(320, 240, 320, 240); 158 | 159 | // Replace the existing Pix. 160 | pixa.replacePix(0, pix, box); 161 | 162 | // Ensure the replacement was successful. 163 | Pix returnedPix = pixa.getPix(0); 164 | Box returnedBox = pixa.getBox(0); 165 | 166 | assertEquals(pix.getWidth(), returnedPix.getWidth()); 167 | assertEquals(pix.getHeight(), returnedPix.getHeight()); 168 | assertEquals(pix.getDepth(), returnedPix.getDepth()); 169 | 170 | assertEquals(box.getX(), returnedBox.getX()); 171 | assertEquals(box.getY(), returnedBox.getY()); 172 | assertEquals(box.getWidth(), returnedBox.getWidth()); 173 | assertEquals(box.getHeight(), returnedBox.getHeight()); 174 | 175 | pix.recycle(); 176 | box.recycle(); 177 | returnedPix.recycle(); 178 | returnedBox.recycle(); 179 | pixa.recycle(); 180 | } 181 | 182 | @SmallTest 183 | public void textPixaMergeAndReplacePix() { 184 | Pixa pixa = Pixa.createPixa(0, 640, 480); 185 | 186 | // Populate the Pixa. 187 | addBlockToPixa(pixa, 0, 0, 320, 240, 8); 188 | addBlockToPixa(pixa, 320, 240, 320, 240, 8); 189 | 190 | // Merge both Pix, removing the second Pix. 191 | pixa.mergeAndReplacePix(0, 1); 192 | 193 | // Ensure the merge was successful. 194 | Pix pix = pixa.getPix(0); 195 | Box box = pixa.getBox(0); 196 | 197 | assertEquals(pixa.size(), 1); 198 | 199 | assertEquals(pix.getWidth(), 640); 200 | assertEquals(pix.getHeight(), 480); 201 | assertEquals(pix.getDepth(), 8); 202 | 203 | assertEquals(box.getX(), 0); 204 | assertEquals(box.getY(), 0); 205 | assertEquals(box.getWidth(), 640); 206 | assertEquals(box.getHeight(), 480); 207 | 208 | pix.recycle(); 209 | box.recycle(); 210 | pixa.recycle(); 211 | } 212 | 213 | /** 214 | * Adds a block to the specified Pixa. 215 | * 216 | * @param pixa 217 | * @param x X-coordinate of the top-left corner of the block. 218 | * @param y Y-coordinate of the top-left corner of the block. 219 | * @param width Width of the block. 220 | * @param height Height of the block. 221 | * @param depth Bit-depth of the block. 222 | */ 223 | private static void addBlockToPixa(Pixa pixa, int x, int y, int width, int height, int depth) { 224 | final Pix pix = new Pix(width, height, depth); 225 | final Box box = new Box(x, y, width, height); 226 | 227 | pixa.add(pix, box, Constants.L_COPY); 228 | 229 | pix.recycle(); 230 | box.recycle(); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/ReadFileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.Bitmap.CompressFormat; 21 | import android.graphics.Canvas; 22 | import android.graphics.Color; 23 | import android.graphics.Paint; 24 | import android.graphics.Paint.Style; 25 | import android.graphics.Rect; 26 | import android.test.suitebuilder.annotation.SmallTest; 27 | 28 | import com.googlecode.leptonica.android.Pix; 29 | import com.googlecode.leptonica.android.ReadFile; 30 | 31 | import junit.framework.TestCase; 32 | 33 | import java.io.ByteArrayOutputStream; 34 | import java.io.File; 35 | import java.io.FileOutputStream; 36 | import java.io.IOException; 37 | 38 | /** 39 | * @author alanv@google.com (Your Name Here) 40 | */ 41 | public class ReadFileTest extends TestCase { 42 | @SmallTest 43 | public void testReadBitmap() { 44 | testReadBitmap(1, 1, Bitmap.Config.ARGB_8888); 45 | testReadBitmap(640, 480, Bitmap.Config.ARGB_8888); 46 | } 47 | 48 | private void testReadBitmap(int width, int height, Bitmap.Config format) { 49 | Bitmap bmp = Bitmap.createBitmap(width, height, format); 50 | Canvas canvas = new Canvas(bmp); 51 | Paint paint = new Paint(); 52 | 53 | if (width > 1 && height > 1) { 54 | // Paint the left half white 55 | paint.setColor(Color.WHITE); 56 | paint.setStyle(Style.FILL); 57 | canvas.drawRect(new Rect(0, 0, width / 2 , height - 1), paint); 58 | 59 | // Paint the right half black 60 | paint.setColor(Color.BLACK); 61 | paint.setStyle(Style.FILL); 62 | canvas.drawRect(new Rect(width / 2, 0, width - 1, height - 1), paint); 63 | } 64 | 65 | Pix pix = ReadFile.readBitmap(bmp); 66 | 67 | assertEquals(bmp.getWidth(), pix.getWidth()); 68 | assertEquals(bmp.getHeight(), pix.getHeight()); 69 | 70 | if (width > 1 && height > 1) { 71 | // Make sure the colors were preserved. 72 | assertEquals(Color.WHITE, pix.getPixel(0, 0)); 73 | assertEquals(Color.BLACK, pix.getPixel(width - 1, height - 1)); 74 | } 75 | 76 | bmp.recycle(); 77 | pix.recycle(); 78 | } 79 | 80 | @SmallTest 81 | public void testReadFile() throws IOException { 82 | File file = File.createTempFile("testReadFile", "jpg"); 83 | FileOutputStream fileStream = new FileOutputStream(file); 84 | Bitmap bmp = Bitmap.createBitmap(640, 480, Bitmap.Config.RGB_565); 85 | bmp.compress(CompressFormat.JPEG, 85, fileStream); 86 | Pix pix = ReadFile.readFile(file); 87 | 88 | assertEquals(bmp.getWidth(), pix.getWidth()); 89 | assertEquals(bmp.getHeight(), pix.getHeight()); 90 | 91 | fileStream.close(); 92 | bmp.recycle(); 93 | pix.recycle(); 94 | } 95 | 96 | @SmallTest 97 | public void testReadMem() throws IOException { 98 | ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 99 | Bitmap bmp = Bitmap.createBitmap(640, 480, Bitmap.Config.RGB_565); 100 | bmp.compress(CompressFormat.JPEG, 85, byteStream); 101 | byte[] encodedData = byteStream.toByteArray(); 102 | Pix pix = ReadFile.readMem(encodedData); 103 | 104 | assertEquals(bmp.getWidth(), pix.getWidth()); 105 | assertEquals(bmp.getHeight(), pix.getHeight()); 106 | 107 | // TODO(alanv): Need some way to test content, ex. Pix.getPixel(int, int) 108 | 109 | byteStream.close(); 110 | bmp.recycle(); 111 | encodedData = null; 112 | pix.recycle(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/RotateTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import com.googlecode.leptonica.android.Pix; 20 | import com.googlecode.leptonica.android.ReadFile; 21 | import com.googlecode.leptonica.android.Rotate; 22 | import com.googlecode.leptonica.android.WriteFile; 23 | 24 | import android.graphics.Bitmap; 25 | import android.graphics.Canvas; 26 | import android.graphics.Color; 27 | import android.graphics.Paint; 28 | import android.graphics.Paint.Style; 29 | import android.test.suitebuilder.annotation.SmallTest; 30 | 31 | import junit.framework.TestCase; 32 | 33 | public class RotateTest extends TestCase { 34 | @SmallTest 35 | public void testRotate() { 36 | Bitmap bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 37 | Canvas canvas = new Canvas(bmp); 38 | Paint paint = new Paint(); 39 | 40 | // Paint the background white 41 | canvas.drawColor(Color.WHITE); 42 | 43 | // Paint a black circle in the center 44 | paint.setColor(Color.BLACK); 45 | paint.setStyle(Style.FILL); 46 | canvas.drawCircle(50, 50, 10, paint); 47 | 48 | Pix pixs = ReadFile.readBitmap(bmp); 49 | Pix pixd = Rotate.rotate(pixs, 180); 50 | pixs.recycle(); 51 | 52 | Bitmap rotated = WriteFile.writeBitmap(pixd); 53 | pixd.recycle(); 54 | 55 | float match = TestUtils.compareBitmaps(bmp, rotated); 56 | bmp.recycle(); 57 | rotated.recycle(); 58 | 59 | assertTrue("Bitmaps match", (match > 0.99f)); 60 | } 61 | 62 | @SmallTest 63 | public void testRotateResize() { 64 | Bitmap bmp = Bitmap.createBitmap(100, 10, Bitmap.Config.ARGB_8888); 65 | Canvas canvas = new Canvas(bmp); 66 | Paint paint = new Paint(); 67 | 68 | // Paint the background white 69 | canvas.drawColor(Color.BLACK); 70 | 71 | // Paint a black circle in the center 72 | paint.setColor(Color.BLACK); 73 | paint.setStyle(Style.FILL); 74 | canvas.drawCircle(50, 50, 10, paint); 75 | 76 | Pix pixs = ReadFile.readBitmap(bmp); 77 | Pix pixd = Rotate.rotate(pixs, 180); 78 | pixs.recycle(); 79 | 80 | assertTrue("Rotated width is 100", (pixd.getWidth() == 100)); 81 | pixd.recycle(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/ScaleTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Bitmap; 20 | import android.test.suitebuilder.annotation.SmallTest; 21 | 22 | import com.googlecode.leptonica.android.Pix; 23 | import com.googlecode.leptonica.android.ReadFile; 24 | import com.googlecode.leptonica.android.Scale; 25 | 26 | import junit.framework.TestCase; 27 | 28 | public class ScaleTest extends TestCase { 29 | @SmallTest 30 | public void testScale() { 31 | testScale(640, 480, 1.0f, 1.0f); 32 | testScale(640, 480, 0.5f, 0.25f); 33 | } 34 | 35 | private void testScale(int inputWidth, int inputHeight, float scaleX, float scaleY) { 36 | Bitmap bmp = Bitmap.createBitmap(inputWidth, inputHeight, Bitmap.Config.ARGB_8888); 37 | Pix pixs = ReadFile.readBitmap(bmp); 38 | Pix pixd = Scale.scale(pixs, scaleX, scaleY); 39 | 40 | assertEquals((int) (inputWidth * scaleX), pixd.getWidth()); 41 | assertEquals((int) (inputHeight * scaleY), pixd.getHeight()); 42 | 43 | bmp.recycle(); 44 | pixs.recycle(); 45 | pixd.recycle(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/SkewTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import junit.framework.TestCase; 20 | 21 | public class SkewTest extends TestCase { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Bitmap; 20 | 21 | /** 22 | * Utility methods for running Leptonica unit tests. 23 | * 24 | * @author alanv@google.com (Alan Viverette) 25 | */ 26 | public class TestUtils { 27 | public static float compareBitmaps(Bitmap a, Bitmap b) { 28 | int found = 0; 29 | 30 | for (int y = 0; y < a.getHeight(); y++) { 31 | for (int x = 0; x < a.getWidth(); x++) { 32 | if (a.getPixel(x, y) == a.getPixel(x, y)) { 33 | found++; 34 | } 35 | } 36 | } 37 | 38 | return found / (float)(a.getWidth() * a.getHeight()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/leptonica/android/test/WriteFileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android.test; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | import android.test.suitebuilder.annotation.SmallTest; 22 | 23 | import com.googlecode.leptonica.android.Constants; 24 | import com.googlecode.leptonica.android.Pix; 25 | import com.googlecode.leptonica.android.ReadFile; 26 | import com.googlecode.leptonica.android.WriteFile; 27 | 28 | import junit.framework.TestCase; 29 | 30 | public class WriteFileTest extends TestCase { 31 | @SmallTest 32 | public void testWriteMem() { 33 | Bitmap bmps = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888); 34 | Pix pixs = ReadFile.readBitmap(bmps); 35 | byte[] encodedBytes = WriteFile.writeMem(pixs, Constants.IFF_BMP); 36 | 37 | assertNotNull(encodedBytes); 38 | 39 | Bitmap bmpd = BitmapFactory.decodeByteArray(encodedBytes, 0, encodedBytes.length); 40 | 41 | assertEquals(bmps.getWidth(), bmpd.getWidth()); 42 | assertEquals(bmps.getHeight(), bmpd.getHeight()); 43 | 44 | bmps.recycle(); 45 | pixs.recycle(); 46 | encodedBytes = null; 47 | bmpd.recycle(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/tesseract/android/test/AllTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.tesseract.android.test; 18 | 19 | import android.test.suitebuilder.TestSuiteBuilder; 20 | 21 | import com.googlecode.leptonica.android.test.ReadFileTest; 22 | 23 | import junit.framework.Test; 24 | import junit.framework.TestSuite; 25 | 26 | /** 27 | * A test suite containing all tests for ApiDemos. 28 | * 29 | * To run all suites found in this apk: 30 | * $ adb shell am instrument -w \ 31 | * com.example.android.apis.tests/android.test.InstrumentationTestRunner 32 | * 33 | * To run just this suite from the command line: 34 | * $ adb shell am instrument -w \ 35 | * -e class com.example.android.apis.AllTests \ 36 | * com.example.android.apis.tests/android.test.InstrumentationTestRunner 37 | * 38 | * To run an individual test case, e.g. {@link ReadFileTest}: 39 | * $ adb shell am instrument -w \ 40 | * -e class com.example.android.apis.os.MorseCodeConverterTest \ 41 | * com.example.android.apis.tests/android.test.InstrumentationTestRunner 42 | * 43 | * To run an individual test, e.g. {@link ReadFileTest#testReadBitmap()}: 44 | * $ adb shell am instrument -w \ 45 | * -e class com.example.android.apis.os.MorseCodeConverterTest#testCharacterS \ 46 | * com.example.android.apis.tests/android.test.InstrumentationTestRunner 47 | */ 48 | public class AllTests extends TestSuite { 49 | public static Test suite() { 50 | return new TestSuiteBuilder(AllTests.class) 51 | .includeAllPackagesUnderHere() 52 | .build(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tesseract-android-tools-test/src/com/googlecode/tesseract/android/test/TessBaseAPITest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.tesseract.android.test; 18 | 19 | import com.googlecode.leptonica.android.Pixa; 20 | import com.googlecode.tesseract.android.ResultIterator; 21 | import com.googlecode.tesseract.android.TessBaseAPI; 22 | import com.googlecode.tesseract.android.TessBaseAPI.PageIteratorLevel; 23 | 24 | import android.graphics.Bitmap; 25 | import android.graphics.Canvas; 26 | import android.graphics.Color; 27 | import android.graphics.Paint; 28 | import android.graphics.Paint.Align; 29 | import android.graphics.Paint.Style; 30 | import android.test.suitebuilder.annotation.SmallTest; 31 | 32 | import java.io.File; 33 | 34 | import junit.framework.TestCase; 35 | 36 | public class TessBaseAPITest extends TestCase { 37 | private static final String TESSBASE_PATH = "/mnt/sdcard/tesseract/"; 38 | private static final String DEFAULT_LANGUAGE = "eng"; 39 | private static final String EXPECTED_FILE = TESSBASE_PATH + "tessdata/" + DEFAULT_LANGUAGE 40 | + ".traineddata"; 41 | 42 | @SmallTest 43 | public void testInit() { 44 | // First, make sure the eng.traineddata file exists. 45 | assertTrue("Make sure that you've copied " + DEFAULT_LANGUAGE + ".traineddata to " 46 | + EXPECTED_FILE, new File(EXPECTED_FILE).exists()); 47 | 48 | // Attempt to initialize the API. 49 | final TessBaseAPI baseApi = new TessBaseAPI(); 50 | baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE); 51 | 52 | // Attempt to shut down the API. 53 | baseApi.end(); 54 | } 55 | 56 | @SmallTest 57 | public void testSetImage() { 58 | // First, make sure the eng.traineddata file exists. 59 | assertTrue("Make sure that you've copied " + DEFAULT_LANGUAGE + ".traineddata to " 60 | + EXPECTED_FILE, new File(EXPECTED_FILE).exists()); 61 | 62 | // Attempt to initialize the API. 63 | final TessBaseAPI baseApi = new TessBaseAPI(); 64 | baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE); 65 | 66 | // Set the image to a Bitmap. 67 | final Bitmap bmp = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888); 68 | baseApi.setImage(bmp); 69 | 70 | // Attempt to shut down the API. 71 | baseApi.end(); 72 | } 73 | 74 | private static Bitmap getTextImage(String text, int width, int height) { 75 | final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 76 | final Paint paint = new Paint(); 77 | final Canvas canvas = new Canvas(bmp); 78 | 79 | canvas.drawColor(Color.WHITE); 80 | 81 | paint.setColor(Color.BLACK); 82 | paint.setStyle(Style.FILL); 83 | paint.setAntiAlias(true); 84 | paint.setTextAlign(Align.CENTER); 85 | paint.setTextSize(24.0f); 86 | canvas.drawText(text, width / 2, height / 2, paint); 87 | 88 | return bmp; 89 | } 90 | 91 | @SmallTest 92 | public void testGetUTF8Text() { 93 | // First, make sure the eng.traineddata file exists. 94 | assertTrue("Make sure that you've copied " + DEFAULT_LANGUAGE + ".traineddata to " 95 | + EXPECTED_FILE, new File(EXPECTED_FILE).exists()); 96 | 97 | final String inputText = "hello"; 98 | final Bitmap bmp = getTextImage(inputText, 640, 480); 99 | 100 | // Attempt to initialize the API. 101 | final TessBaseAPI baseApi = new TessBaseAPI(); 102 | baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE); 103 | baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE); 104 | baseApi.setImage(bmp); 105 | 106 | // Ensure that the result is correct. 107 | final String outputText = baseApi.getUTF8Text(); 108 | assertEquals("\"" + outputText + "\" != \"" + inputText + "\"", inputText, outputText); 109 | 110 | // Ensure getRegions() works. 111 | final Pixa regions = baseApi.getRegions(); 112 | assertEquals("Found one region", regions.size(), 1); 113 | 114 | // Ensure getWords() works. 115 | final Pixa words = baseApi.getWords(); 116 | assertEquals("Found one word", words.size(), 1); 117 | 118 | // Iterate through the results. 119 | final ResultIterator iterator = baseApi.getResultIterator(); 120 | String lastUTF8Text; 121 | float lastConfidence; 122 | int count = 0; 123 | iterator.begin(); 124 | do { 125 | lastUTF8Text = iterator.getUTF8Text(PageIteratorLevel.RIL_WORD); 126 | lastConfidence = iterator.confidence(PageIteratorLevel.RIL_WORD); 127 | count++; 128 | } while (iterator.next(PageIteratorLevel.RIL_WORD)); 129 | 130 | assertEquals("Found only one result", count, 1); 131 | assertEquals("Found the correct result", lastUTF8Text, outputText); 132 | assertTrue("Result was high-confidence", lastConfidence > 80); 133 | 134 | // Attempt to shut down the API. 135 | baseApi.end(); 136 | bmp.recycle(); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /tesseract-android-tools/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tesseract-android-tools/.gitignore: -------------------------------------------------------------------------------- 1 | /obj 2 | /gen 3 | /libs 4 | /data 5 | -------------------------------------------------------------------------------- /tesseract-android-tools/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tesseract-android-tools 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /tesseract-android-tools/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 21 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tesseract-android-tools/README.md: -------------------------------------------------------------------------------- 1 | # Tesseract Android Tools 2 | 3 | ## Requirements 4 | * Download and install [Android NDK](http://developer.android.com/tools/sdk/ndk/index.html) 5 | 6 | 7 | ## Installation 8 | 9 | * Clone the repository and `cd` to it: 10 | ``` 11 | $ git clone https://github.com/rebbix/tesseract-android-tools.git 12 | $ cd tesseract-android-tools/tesseract-android-tools 13 | ``` 14 | 15 | * Download required libraries: 16 | ``` 17 | $ ./dependencies.sh 18 | ``` 19 | 20 | * Build using NDK: 21 | ``` 22 | $ /path/to/ndk/installation/ndk-build 23 | ``` 24 | 25 | 26 | ## Language Files 27 | You can optionally download language files, most probably you will need at least one to work with. 28 | 29 | 30 | ## Usage 31 | 32 | 33 | 34 | 35 | ----------------------- 36 | 37 | 38 | ## Old (original) README 39 | This project contains tools for compiling the Tesseract and Leptonica 40 | libraries for use on the Android platform. It contains an Eclipse Android 41 | library project that provides a Java API for accessing natively-compiled 42 | Tesseract and Leptonica APIs. 43 | 44 | NOTE: You must download and extract source files for the Tesseract and 45 | Leptonica libraries prior to building this library. 46 | 47 | To download the latest versions of these libraries and build this project, run 48 | the following commands in the terminal: 49 | 50 | cd 51 | curl -O https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.02.tar.gz 52 | curl -O http://leptonica.googlecode.com/files/leptonica-1.69.tar.gz 53 | tar -zxvf tesseract-ocr-3.02.02.tar.gz 54 | tar -zxvf leptonica-1.69.tar.gz 55 | rm -f tesseract-ocr-3.02.02.tar.gz 56 | rm -f leptonica-1.69.tar.gz 57 | mv tesseract-3.02.02 jni/com_googlecode_tesseract_android/src 58 | mv leptonica-1.69 jni/com_googlecode_leptonica_android/src 59 | ndk-build -j8 60 | android update project --path . 61 | ant debug 62 | 63 | To download the English language files for Tesseract and copy them to your 64 | device's external storage, run the following commands in the terminal: 65 | 66 | cd 67 | curl -O http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz 68 | tar -zxvf tesseract-ocr-3.02.eng.tar.gz 69 | rm -f tesseract-ocr-3.02.eng.tar.gz 70 | mkdir data 71 | mv tesseract-ocr data/tesseract 72 | adb push data/ /sdcard/ 73 | adb shell sync 74 | -------------------------------------------------------------------------------- /tesseract-android-tools/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 40 | 41 | 42 | 43 | 47 | 48 | 49 | 51 | 63 | 64 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /tesseract-android-tools/dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | curl -O https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.02.tar.gz 3 | curl -O http://leptonica.googlecode.com/files/leptonica-1.69.tar.gz 4 | tar -zxvf tesseract-ocr-3.02.02.tar.gz 5 | tar -zxvf leptonica-1.69.tar.gz 6 | rm -f tesseract-ocr-3.02.02.tar.gz 7 | rm -f leptonica-1.69.tar.gz 8 | mv tesseract-ocr jni/com_googlecode_tesseract_android/src 9 | mv leptonica-1.69 jni/com_googlecode_leptonica_android/src 10 | echo You may now run ndk-build to generate shared libraries. 11 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | TESSERACT_PATH := $(LOCAL_PATH)/com_googlecode_tesseract_android/src 3 | LEPTONICA_PATH := $(LOCAL_PATH)/com_googlecode_leptonica_android/src 4 | 5 | # Just build the Android.mk files in the subdirs 6 | include $(call all-subdir-makefiles) 7 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := gnustl_static 2 | APP_ABI := armeabi armeabi-v7a x86 mips 3 | APP_OPTIM := release 4 | APP_CPPFLAGS += -fexceptions -frtti 5 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/.gitignore: -------------------------------------------------------------------------------- 1 | /src 2 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := liblept 6 | 7 | # leptonica (minus freetype) 8 | 9 | BLACKLIST_SRC_FILES := \ 10 | %endiantest.c \ 11 | %freetype.c \ 12 | %xtractprotos.c 13 | 14 | LEPTONICA_SRC_FILES := \ 15 | $(subst $(LOCAL_PATH)/,,$(wildcard $(LEPTONICA_PATH)/src/*.c)) 16 | 17 | LOCAL_SRC_FILES := \ 18 | $(filter-out $(BLACKLIST_SRC_FILES),$(LEPTONICA_SRC_FILES)) 19 | 20 | LOCAL_CFLAGS := \ 21 | -DHAVE_CONFIG_H 22 | 23 | LOCAL_LDLIBS := \ 24 | -lz 25 | 26 | # missing stdio functions 27 | 28 | ifneq ($(TARGET_SIMULATOR),true) 29 | LOCAL_SRC_FILES += \ 30 | stdio/open_memstream.c \ 31 | stdio/fopencookie.c \ 32 | stdio/fmemopen.c 33 | LOCAL_C_INCLUDES += \ 34 | stdio 35 | endif 36 | 37 | # jni 38 | 39 | LOCAL_SRC_FILES += \ 40 | box.cpp \ 41 | pix.cpp \ 42 | pixa.cpp \ 43 | utilities.cpp \ 44 | readfile.cpp \ 45 | writefile.cpp \ 46 | jni.cpp 47 | 48 | LOCAL_C_INCLUDES += \ 49 | $(LOCAL_PATH) \ 50 | $(LEPTONICA_PATH)/src 51 | 52 | LOCAL_LDLIBS += \ 53 | -ljnigraphics \ 54 | -llog 55 | 56 | # common 57 | 58 | LOCAL_PRELINK_MODULE:= false 59 | 60 | include $(BUILD_SHARED_LIBRARY) 61 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/box.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif /* __cplusplus */ 22 | 23 | jint Java_com_googlecode_leptonica_android_Box_nativeCreate(JNIEnv *env, jclass clazz, jint x, 24 | jint y, jint w, jint h) { 25 | BOX *box = boxCreate((l_int32) x, (l_int32) y, (l_int32) w, (l_int32) h); 26 | 27 | return (jint) box; 28 | } 29 | 30 | void Java_com_googlecode_leptonica_android_Box_nativeDestroy(JNIEnv *env, jclass clazz, 31 | jint nativeBox) { 32 | BOX *box = (BOX *) nativeBox; 33 | 34 | boxDestroy(&box); 35 | } 36 | 37 | jint Java_com_googlecode_leptonica_android_Box_nativeGetX(JNIEnv *env, jclass clazz, jint nativeBox) { 38 | BOX *box = (BOX *) nativeBox; 39 | 40 | return (jint) box->x; 41 | } 42 | 43 | jint Java_com_googlecode_leptonica_android_Box_nativeGetY(JNIEnv *env, jclass clazz, jint nativeBox) { 44 | BOX *box = (BOX *) nativeBox; 45 | 46 | return (jint) box->y; 47 | } 48 | 49 | jint Java_com_googlecode_leptonica_android_Box_nativeGetWidth(JNIEnv *env, jclass clazz, 50 | jint nativeBox) { 51 | BOX *box = (BOX *) nativeBox; 52 | 53 | return (jint) box->w; 54 | } 55 | 56 | jint Java_com_googlecode_leptonica_android_Box_nativeGetHeight(JNIEnv *env, jclass clazz, 57 | jint nativeBox) { 58 | BOX *box = (BOX *) nativeBox; 59 | 60 | return (jint) box->h; 61 | } 62 | 63 | jboolean Java_com_googlecode_leptonica_android_Box_nativeGetGeometry(JNIEnv *env, jclass clazz, 64 | jint nativeBox, 65 | jintArray dimensions) { 66 | BOX *box = (BOX *) nativeBox; 67 | jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL); 68 | l_int32 x, y, w, h; 69 | 70 | if (boxGetGeometry(box, &x, &y, &w, &h)) { 71 | return JNI_FALSE; 72 | } 73 | 74 | dimensionArray[0] = x; 75 | dimensionArray[1] = y; 76 | dimensionArray[2] = w; 77 | dimensionArray[3] = h; 78 | 79 | env->ReleaseIntArrayElements(dimensions, dimensionArray, 0); 80 | 81 | return JNI_TRUE; 82 | } 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif /* __cplusplus */ 87 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LEPTONICA_JNI_COMMON_H 18 | #define LEPTONICA_JNI_COMMON_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef __BIG_ENDIAN 27 | #define SK_A32_SHIFT 0 28 | #define SK_R32_SHIFT 8 29 | #define SK_G32_SHIFT 16 30 | #define SK_B32_SHIFT 24 31 | #else 32 | #define SK_A32_SHIFT 24 33 | #define SK_R32_SHIFT 16 34 | #define SK_G32_SHIFT 8 35 | #define SK_B32_SHIFT 0 36 | #endif /* __BIG_ENDIAN */ 37 | 38 | #define LOG_TAG "Leptonica(native)" 39 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 40 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 41 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 42 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) 43 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 44 | #define LOG_ASSERT(_cond, ...) if (!_cond) __android_log_assert("conditional", LOG_TAG, __VA_ARGS__) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/config_auto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LEPTONICA_JNI_CONFIG_AUTO_H 18 | #define LEPTONICA_JNI_CONFIG_AUTO_H 19 | 20 | #define HAVE_LIBJPEG 0 21 | #define HAVE_LIBTIFF 0 22 | #define HAVE_LIBPNG 0 23 | #define HAVE_LIBZ 1 24 | #define HAVE_LIBGIF 0 25 | #define HAVE_LIBUNGIF 0 26 | #define HAVE_FMEMOPEN 1 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/jni.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | jint JNI_OnLoad(JavaVM* vm, void* reserved) { 20 | JNIEnv *env; 21 | 22 | if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) { 23 | LOGE("ERROR: GetEnv failed\n"); 24 | return -1; 25 | } 26 | assert(env != NULL); 27 | 28 | return JNI_VERSION_1_6; 29 | } 30 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/pix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | #include 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif /* __cplusplus */ 23 | 24 | jint Java_com_googlecode_leptonica_android_Pix_nativeCreatePix(JNIEnv *env, jclass clazz, jint w, 25 | jint h, jint d) { 26 | PIX *pix = pixCreate((l_int32) w, (l_int32) h, (l_int32) d); 27 | 28 | return (jint) pix; 29 | } 30 | 31 | jint Java_com_googlecode_leptonica_android_Pix_nativeCreateFromData(JNIEnv *env, jclass clazz, 32 | jbyteArray data, jint w, 33 | jint h, jint d) { 34 | PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, (l_int32) d); 35 | 36 | jbyte *data_buffer = env->GetByteArrayElements(data, NULL); 37 | l_uint8 *byte_buffer = (l_uint8 *) data_buffer; 38 | 39 | size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix); 40 | memcpy(pixGetData(pix), byte_buffer, size); 41 | 42 | env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT); 43 | 44 | return (jint) pix; 45 | } 46 | 47 | jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetData(JNIEnv *env, jclass clazz, 48 | jint nativePix, jbyteArray data) { 49 | PIX *pix = (PIX *) nativePix; 50 | 51 | jbyte *data_buffer = env->GetByteArrayElements(data, NULL); 52 | l_uint8 *byte_buffer = (l_uint8 *) data_buffer; 53 | 54 | size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix); 55 | memcpy(byte_buffer, pixGetData(pix), size); 56 | 57 | env->ReleaseByteArrayElements(data, data_buffer, 0); 58 | 59 | return JNI_TRUE; 60 | } 61 | 62 | jint Java_com_googlecode_leptonica_android_Pix_nativeGetDataSize(JNIEnv *env, jclass clazz, 63 | jint nativePix) { 64 | PIX *pix = (PIX *) nativePix; 65 | 66 | size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix); 67 | 68 | return (jint) size; 69 | } 70 | 71 | jint Java_com_googlecode_leptonica_android_Pix_nativeClone(JNIEnv *env, jclass clazz, 72 | jint nativePix) { 73 | PIX *pixs = (PIX *) nativePix; 74 | PIX *pixd = pixClone(pixs); 75 | 76 | return (jint) pixd; 77 | } 78 | 79 | jint Java_com_googlecode_leptonica_android_Pix_nativeCopy(JNIEnv *env, jclass clazz, jint nativePix) { 80 | PIX *pixs = (PIX *) nativePix; 81 | PIX *pixd = pixCopy(NULL, pixs); 82 | 83 | return (jint) pixd; 84 | } 85 | 86 | jboolean Java_com_googlecode_leptonica_android_Pix_nativeInvert(JNIEnv *env, jclass clazz, 87 | jint nativePix) { 88 | PIX *pixs = (PIX *) nativePix; 89 | 90 | if (pixInvert(pixs, pixs)) { 91 | return JNI_FALSE; 92 | } 93 | 94 | return JNI_TRUE; 95 | } 96 | 97 | void Java_com_googlecode_leptonica_android_Pix_nativeDestroy(JNIEnv *env, jclass clazz, 98 | jint nativePix) { 99 | PIX *pix = (PIX *) nativePix; 100 | 101 | pixDestroy(&pix); 102 | } 103 | 104 | jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetDimensions(JNIEnv *env, jclass clazz, 105 | jint nativePix, 106 | jintArray dimensions) { 107 | PIX *pix = (PIX *) nativePix; 108 | jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL); 109 | l_int32 w, h, d; 110 | 111 | if (pixGetDimensions(pix, &w, &h, &d)) { 112 | return JNI_FALSE; 113 | } 114 | 115 | dimensionArray[0] = w; 116 | dimensionArray[1] = h; 117 | dimensionArray[2] = d; 118 | 119 | env->ReleaseIntArrayElements(dimensions, dimensionArray, 0); 120 | 121 | return JNI_TRUE; 122 | } 123 | 124 | jint Java_com_googlecode_leptonica_android_Pix_nativeGetWidth(JNIEnv *env, jclass clazz, 125 | jint nativePix) { 126 | PIX *pix = (PIX *) nativePix; 127 | 128 | return (jint) pixGetWidth(pix); 129 | } 130 | 131 | jint Java_com_googlecode_leptonica_android_Pix_nativeGetHeight(JNIEnv *env, jclass clazz, 132 | jint nativePix) { 133 | PIX *pix = (PIX *) nativePix; 134 | 135 | return (jint) pixGetHeight(pix); 136 | } 137 | 138 | jint Java_com_googlecode_leptonica_android_Pix_nativeGetDepth(JNIEnv *env, jclass clazz, 139 | jint nativePix) { 140 | PIX *pix = (PIX *) nativePix; 141 | 142 | return (jint) pixGetDepth(pix); 143 | } 144 | 145 | void Java_com_googlecode_leptonica_android_Pix_nativeSetPixel(JNIEnv *env, jclass clazz, 146 | jint nativePix, jint xCoord, 147 | jint yCoord, jint argbColor) { 148 | PIX *pix = (PIX *) nativePix; 149 | l_int32 d = pixGetDepth(pix); 150 | l_int32 x = (l_int32) xCoord; 151 | l_int32 y = (l_int32) yCoord; 152 | 153 | // These shift values are based on RGBA_8888 154 | l_uint8 r = (argbColor >> SK_R32_SHIFT) & 0xFF; 155 | l_uint8 g = (argbColor >> SK_G32_SHIFT) & 0xFF; 156 | l_uint8 b = (argbColor >> SK_B32_SHIFT) & 0xFF; 157 | l_uint8 a = (argbColor >> SK_A32_SHIFT) & 0xFF; 158 | l_uint8 gray = ((r + g + b) / 3) & 0xFF; 159 | 160 | l_uint32 color; 161 | 162 | switch (d) { 163 | case 1: // 1-bit binary 164 | color = gray > 128 ? 1 : 0; 165 | break; 166 | case 2: // 2-bit grayscale 167 | color = gray >> 6; 168 | break; 169 | case 4: // 4-bit grayscale 170 | color = gray >> 4; 171 | break; 172 | case 8: // 8-bit grayscale 173 | color = gray; 174 | break; 175 | case 24: // 24-bit RGB 176 | SET_DATA_BYTE(&color, COLOR_RED, r); 177 | SET_DATA_BYTE(&color, COLOR_GREEN, g); 178 | SET_DATA_BYTE(&color, COLOR_BLUE, b); 179 | break; 180 | case 32: // 32-bit ARGB 181 | SET_DATA_BYTE(&color, COLOR_RED, r); 182 | SET_DATA_BYTE(&color, COLOR_GREEN, g); 183 | SET_DATA_BYTE(&color, COLOR_BLUE, b); 184 | SET_DATA_BYTE(&color, L_ALPHA_CHANNEL, a); 185 | break; 186 | default: // unsupported 187 | LOGE("Not a supported color depth: %d", d); 188 | color = 0; 189 | break; 190 | } 191 | 192 | pixSetPixel(pix, x, y, color); 193 | } 194 | 195 | jint Java_com_googlecode_leptonica_android_Pix_nativeGetPixel(JNIEnv *env, jclass clazz, 196 | jint nativePix, jint xCoord, 197 | jint yCoord) { 198 | PIX *pix = (PIX *) nativePix; 199 | l_int32 d = pixGetDepth(pix); 200 | l_int32 x = (l_int32) xCoord; 201 | l_int32 y = (l_int32) yCoord; 202 | l_uint32 pixel; 203 | l_uint32 color; 204 | l_uint8 a, r, g, b; 205 | 206 | pixGetPixel(pix, x, y, &pixel); 207 | 208 | switch (d) { 209 | case 1: // 1-bit binary 210 | a = 0xFF; 211 | r = g = b = (pixel == 0 ? 0x00 : 0xFF); 212 | break; 213 | case 2: // 2-bit grayscale 214 | a = 0xFF; 215 | r = g = b = (pixel << 6 | pixel << 4 | pixel); 216 | break; 217 | case 4: // 4-bit grayscale 218 | a = 0xFF; 219 | r = g = b = (pixel << 4 | pixel); 220 | break; 221 | case 8: // 8-bit grayscale 222 | a = 0xFF; 223 | r = g = b = pixel; 224 | break; 225 | case 24: // 24-bit RGB 226 | a = 0xFF; 227 | r = (pixel >> L_RED_SHIFT) & 0xFF; 228 | g = (pixel >> L_GREEN_SHIFT) & 0xFF; 229 | b = (pixel >> L_BLUE_SHIFT) & 0xFF; 230 | break; 231 | case 32: // 32-bit RGBA 232 | r = (pixel >> L_RED_SHIFT) & 0xFF; 233 | g = (pixel >> L_GREEN_SHIFT) & 0xFF; 234 | b = (pixel >> L_BLUE_SHIFT) & 0xFF; 235 | a = (pixel >> L_ALPHA_SHIFT) & 0xFF; 236 | break; 237 | default: // Not supported 238 | LOGE("Not a supported color depth: %d", d); 239 | a = r = g = b = 0x00; 240 | break; 241 | } 242 | 243 | color = a << SK_A32_SHIFT; 244 | color |= r << SK_R32_SHIFT; 245 | color |= g << SK_G32_SHIFT; 246 | color |= b << SK_B32_SHIFT; 247 | 248 | return (jint) color; 249 | } 250 | 251 | #ifdef __cplusplus 252 | } 253 | #endif /* __cplusplus */ 254 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/pixa.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif /* __cplusplus */ 22 | 23 | jint Java_com_googlecode_leptonica_android_Pixa_nativeCreate(JNIEnv *env, jclass clazz, jint size) { 24 | PIXA *pixa = pixaCreate((l_int32) size); 25 | 26 | return (jint) pixa; 27 | } 28 | 29 | jint Java_com_googlecode_leptonica_android_Pixa_nativeCopy(JNIEnv *env, jclass clazz, 30 | jint nativePixa) { 31 | PIXA *pixas = (PIXA *) nativePixa; 32 | PIXA *pixad = pixaCopy(pixas, L_CLONE); 33 | 34 | return (jint) pixad; 35 | } 36 | 37 | jint Java_com_googlecode_leptonica_android_Pixa_nativeSort(JNIEnv *env, jclass clazz, 38 | jint nativePixa, jint field, jint order) { 39 | PIXA *pixas = (PIXA *) nativePixa; 40 | PIXA *pixad = pixaSort(pixas, field, order, NULL, L_CLONE); 41 | 42 | return (jint) pixad; 43 | } 44 | 45 | void Java_com_googlecode_leptonica_android_Pixa_nativeDestroy(JNIEnv *env, jclass clazz, 46 | jint nativePixa) { 47 | PIXA *pixa = (PIXA *) nativePixa; 48 | 49 | pixaDestroy(&pixa); 50 | } 51 | 52 | jboolean Java_com_googlecode_leptonica_android_Pixa_nativeJoin(JNIEnv *env, jclass clazz, 53 | jint nativePixa, jint otherPixa) { 54 | PIXA *pixa = (PIXA *) nativePixa; 55 | PIXA *pixas = (PIXA *) otherPixa; 56 | 57 | if (pixaJoin(pixa, pixas, 0, 0)) { 58 | return JNI_FALSE; 59 | } 60 | 61 | return JNI_TRUE; 62 | } 63 | 64 | jint Java_com_googlecode_leptonica_android_Pixa_nativeGetCount(JNIEnv *env, jclass clazz, 65 | jint nativePixa) { 66 | PIXA *pixa = (PIXA *) nativePixa; 67 | 68 | return (jint) pixaGetCount(pixa); 69 | } 70 | 71 | void Java_com_googlecode_leptonica_android_Pixa_nativeAddPix(JNIEnv *env, jclass clazz, 72 | jint nativePixa, jint nativePix, 73 | jint mode) { 74 | PIXA *pixa = (PIXA *) nativePixa; 75 | PIX *pix = (PIX *) nativePix; 76 | 77 | pixaAddPix(pixa, pix, mode); 78 | } 79 | 80 | void Java_com_googlecode_leptonica_android_Pixa_nativeAddBox(JNIEnv *env, jclass clazz, 81 | jint nativePixa, jint nativeBox, 82 | jint mode) { 83 | PIXA *pixa = (PIXA *) nativePixa; 84 | BOX *box = (BOX *) nativeBox; 85 | 86 | pixaAddBox(pixa, box, mode); 87 | } 88 | 89 | void Java_com_googlecode_leptonica_android_Pixa_nativeAdd(JNIEnv *env, jclass clazz, 90 | jint nativePixa, jint nativePix, 91 | jint nativeBox, jint mode) { 92 | PIXA *pixa = (PIXA *) nativePixa; 93 | PIX *pix = (PIX *) nativePix; 94 | BOX *box = (BOX *) nativeBox; 95 | 96 | pixaAddPix(pixa, pix, mode); 97 | pixaAddBox(pixa, box, mode); 98 | } 99 | 100 | void Java_com_googlecode_leptonica_android_Pixa_nativeReplacePix(JNIEnv *env, jclass clazz, 101 | jint nativePixa, jint index, 102 | jint nativePix, jint nativeBox) { 103 | PIXA *pixa = (PIXA *) nativePixa; 104 | PIX *pix = (PIX *) nativePix; 105 | BOX *box = (BOX *) nativeBox; 106 | 107 | pixaReplacePix(pixa, index, pix, box); 108 | } 109 | 110 | void Java_com_googlecode_leptonica_android_Pixa_nativeMergeAndReplacePix(JNIEnv *env, jclass clazz, 111 | jint nativePixa, 112 | jint indexA, jint indexB) { 113 | PIXA *pixa = (PIXA *) nativePixa; 114 | 115 | l_int32 op; 116 | l_int32 x, y, w, h; 117 | l_int32 dx, dy, dw, dh; 118 | PIX *pixs, *pixd; 119 | BOX *boxA, *boxB, *boxd; 120 | 121 | boxA = pixaGetBox(pixa, indexA, L_CLONE); 122 | boxB = pixaGetBox(pixa, indexB, L_CLONE); 123 | boxd = boxBoundingRegion(boxA, boxB); 124 | 125 | boxGetGeometry(boxd, &x, &y, &w, &h); 126 | pixd = pixCreate(w, h, 1); 127 | 128 | op = PIX_SRC | PIX_DST; 129 | 130 | pixs = pixaGetPix(pixa, indexA, L_CLONE); 131 | boxGetGeometry(boxA, &dx, &dy, &dw, &dh); 132 | pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0); 133 | pixDestroy(&pixs); 134 | boxDestroy(&boxA); 135 | 136 | pixs = pixaGetPix(pixa, indexB, L_CLONE); 137 | boxGetGeometry(boxB, &dx, &dy, &dw, &dh); 138 | pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0); 139 | pixDestroy(&pixs); 140 | boxDestroy(&boxB); 141 | 142 | pixaReplacePix(pixa, indexA, pixd, boxd); 143 | 144 | } 145 | 146 | jboolean Java_com_googlecode_leptonica_android_Pixa_nativeWriteToFileRandomCmap(JNIEnv *env, 147 | jclass clazz, 148 | jint nativePixa, 149 | jstring fileName, 150 | jint width, 151 | jint height) { 152 | PIX *pixtemp; 153 | PIXA *pixa = (PIXA *) nativePixa; 154 | 155 | const char *c_fileName = env->GetStringUTFChars(fileName, NULL); 156 | if (c_fileName == NULL) { 157 | LOGE("could not extract fileName string!"); 158 | return JNI_FALSE; 159 | } 160 | 161 | if (pixaGetCount(pixa) > 0) { 162 | pixtemp = pixaDisplayRandomCmap(pixa, (l_int32) width, (l_int32) height); 163 | } else { 164 | pixtemp = pixCreate((l_int32) width, (l_int32) height, 1); 165 | } 166 | 167 | pixWrite(c_fileName, pixtemp, IFF_BMP); 168 | pixDestroy(&pixtemp); 169 | 170 | env->ReleaseStringUTFChars(fileName, c_fileName); 171 | 172 | return JNI_TRUE; 173 | } 174 | 175 | jint Java_com_googlecode_leptonica_android_Pixa_nativeGetPix(JNIEnv *env, jclass clazz, 176 | jint nativePixa, jint index) { 177 | PIXA *pixa = (PIXA *) nativePixa; 178 | PIX *pix = pixaGetPix(pixa, (l_int32) index, L_CLONE); 179 | 180 | return (jint) pix; 181 | } 182 | 183 | jint Java_com_googlecode_leptonica_android_Pixa_nativeGetBox(JNIEnv *env, jclass clazz, 184 | jint nativePixa, jint index) { 185 | PIXA *pixa = (PIXA *) nativePixa; 186 | BOX *box = pixaGetBox(pixa, (l_int32) index, L_CLONE); 187 | 188 | return (jint) box; 189 | } 190 | 191 | jboolean Java_com_googlecode_leptonica_android_Pixa_nativeGetBoxGeometry(JNIEnv *env, jclass clazz, 192 | jint nativePixa, 193 | jint index, 194 | jintArray dimensions) { 195 | PIXA *pixa = (PIXA *) nativePixa; 196 | jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL); 197 | l_int32 x, y, w, h; 198 | 199 | if (pixaGetBoxGeometry(pixa, (l_int32) index, &x, &y, &w, &h)) { 200 | return JNI_FALSE; 201 | } 202 | 203 | dimensionArray[0] = x; 204 | dimensionArray[1] = y; 205 | dimensionArray[2] = w; 206 | dimensionArray[3] = h; 207 | 208 | env->ReleaseIntArrayElements(dimensions, dimensionArray, 0); 209 | 210 | return JNI_TRUE; 211 | } 212 | 213 | #ifdef __cplusplus 214 | } 215 | #endif /* __cplusplus */ 216 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/readfile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif /* __cplusplus */ 25 | 26 | /************ 27 | * ReadFile * 28 | ************/ 29 | 30 | jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadMem(JNIEnv *env, jclass clazz, 31 | jbyteArray image, jint length) { 32 | jbyte *image_buffer = env->GetByteArrayElements(image, NULL); 33 | int buffer_length = env->GetArrayLength(image); 34 | 35 | PIX *pix = pixReadMem((const l_uint8 *) image_buffer, buffer_length); 36 | 37 | env->ReleaseByteArrayElements(image, image_buffer, JNI_ABORT); 38 | 39 | return (jint) pix; 40 | } 41 | 42 | jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadBytes8(JNIEnv *env, jclass clazz, 43 | jbyteArray data, jint w, 44 | jint h) { 45 | PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, 8); 46 | l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL); 47 | jbyte *data_buffer = env->GetByteArrayElements(data, NULL); 48 | l_uint8 *byte_buffer = (l_uint8 *) data_buffer; 49 | 50 | for (int i = 0; i < h; i++) { 51 | memcpy(lineptrs[i], (byte_buffer + (i * w)), w); 52 | } 53 | 54 | env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT); 55 | pixCleanupByteProcessing(pix, lineptrs); 56 | 57 | l_int32 d; 58 | 59 | pixGetDimensions(pix, &w, &h, &d); 60 | 61 | LOGE("Created image width w=%d, h=%d, d=%d", w, h, d); 62 | 63 | return (jint) pix; 64 | } 65 | 66 | jboolean Java_com_googlecode_leptonica_android_ReadFile_nativeReplaceBytes8(JNIEnv *env, 67 | jclass clazz, 68 | jint nativePix, 69 | jbyteArray data, 70 | jint srcw, jint srch) { 71 | PIX *pix = (PIX *) nativePix; 72 | l_int32 w, h, d; 73 | 74 | pixGetDimensions(pix, &w, &h, &d); 75 | 76 | if (d != 8 || (l_int32) srcw != w || (l_int32) srch != h) { 77 | LOGE("Failed to replace bytes at w=%d, h=%d, d=%d with w=%d, h=%d", w, h, d, srcw, srch); 78 | 79 | return JNI_FALSE; 80 | } 81 | 82 | l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL); 83 | jbyte *data_buffer = env->GetByteArrayElements(data, NULL); 84 | l_uint8 *byte_buffer = (l_uint8 *) data_buffer; 85 | 86 | for (int i = 0; i < h; i++) { 87 | memcpy(lineptrs[i], (byte_buffer + (i * w)), w); 88 | } 89 | 90 | env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT); 91 | pixCleanupByteProcessing(pix, lineptrs); 92 | 93 | return JNI_TRUE; 94 | } 95 | 96 | jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadFiles(JNIEnv *env, jclass clazz, 97 | jstring dirName, jstring prefix) { 98 | PIXA *pixad = NULL; 99 | 100 | const char *c_dirName = env->GetStringUTFChars(dirName, NULL); 101 | if (c_dirName == NULL) { 102 | LOGE("could not extract dirName string!"); 103 | return (jint) NULL; 104 | } 105 | 106 | const char *c_prefix = env->GetStringUTFChars(prefix, NULL); 107 | if (c_prefix == NULL) { 108 | LOGE("could not extract prefix string!"); 109 | return (jint) NULL; 110 | } 111 | 112 | pixad = pixaReadFiles(c_dirName, c_prefix); 113 | 114 | env->ReleaseStringUTFChars(dirName, c_dirName); 115 | env->ReleaseStringUTFChars(prefix, c_prefix); 116 | 117 | return (jint) pixad; 118 | } 119 | 120 | jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadFile(JNIEnv *env, jclass clazz, 121 | jstring fileName) { 122 | PIX *pixd = NULL; 123 | 124 | const char *c_fileName = env->GetStringUTFChars(fileName, NULL); 125 | if (c_fileName == NULL) { 126 | LOGE("could not extract fileName string!"); 127 | return (jint) NULL; 128 | } 129 | 130 | pixd = pixRead(c_fileName); 131 | 132 | env->ReleaseStringUTFChars(fileName, c_fileName); 133 | 134 | return (jint) pixd; 135 | } 136 | 137 | jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadBitmap(JNIEnv *env, jclass clazz, 138 | jobject bitmap) { 139 | l_int32 w, h, d; 140 | AndroidBitmapInfo info; 141 | void* pixels; 142 | int ret; 143 | 144 | if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { 145 | LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 146 | return JNI_FALSE; 147 | } 148 | 149 | if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { 150 | LOGE("Bitmap format is not RGBA_8888 !"); 151 | return JNI_FALSE; 152 | } 153 | 154 | if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { 155 | LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 156 | return JNI_FALSE; 157 | } 158 | 159 | PIX *pixd = pixCreate(info.width, info.height, 8); 160 | 161 | l_uint32 *src = (l_uint32 *) pixels; 162 | l_int32 srcWpl = (info.stride / 4); 163 | l_uint32 *dst = pixGetData(pixd); 164 | l_int32 dstWpl = pixGetWpl(pixd); 165 | l_uint8 a, r, g, b, pixel8; 166 | 167 | for (int y = 0; y < info.height; y++) { 168 | l_uint32 *dst_line = dst + (y * dstWpl); 169 | l_uint32 *src_line = src + (y * srcWpl); 170 | 171 | for (int x = 0; x < info.width; x++) { 172 | // Get pixel from RGBA_8888 173 | r = *src_line >> SK_R32_SHIFT; 174 | g = *src_line >> SK_G32_SHIFT; 175 | b = *src_line >> SK_B32_SHIFT; 176 | a = *src_line >> SK_A32_SHIFT; 177 | pixel8 = (l_uint8)((r + g + b) / 3); 178 | 179 | // Set pixel to LUMA_8 180 | SET_DATA_BYTE(dst_line, x, pixel8); 181 | 182 | // Move to the next pixel 183 | src_line++; 184 | } 185 | } 186 | 187 | AndroidBitmap_unlockPixels(env, bitmap); 188 | 189 | return (jint) pixd; 190 | } 191 | 192 | #ifdef __cplusplus 193 | } 194 | #endif /* __cplusplus */ 195 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/stdio/extrastdio.h: -------------------------------------------------------------------------------- 1 | #ifndef LEPTONICA__STDIO_H 2 | #define LEPTONICA__STDIO_H 3 | 4 | #ifndef BUILD_HOST 5 | 6 | #include 7 | #include 8 | 9 | typedef struct cookie_io_functions_t { 10 | ssize_t (*read)(void *cookie, char *buf, size_t n); 11 | ssize_t (*write)(void *cookie, const char *buf, size_t n); 12 | int (*seek)(void *cookie, off_t *pos, int whence); 13 | int (*close)(void *cookie); 14 | } cookie_io_functions_t; 15 | 16 | FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t functions); 17 | 18 | FILE *fmemopen(void *buf, size_t size, const char *mode); 19 | 20 | FILE *open_memstream(char **buf, size_t *size); 21 | 22 | #endif 23 | 24 | #endif /* LEPTONICA__STDIO_H */ 25 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/stdio/fmemopen.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2007 Eric Blake 2 | * Permission to use, copy, modify, and distribute this software 3 | * is freely granted, provided that this notice is preserved. 4 | * 5 | * Modifications for Android written Jul 2009 by Alan Viverette 6 | */ 7 | 8 | /* 9 | FUNCTION 10 | <>---open a stream around a fixed-length string 11 | 12 | INDEX 13 | fmemopen 14 | 15 | ANSI_SYNOPSIS 16 | #include 17 | FILE *fmemopen(void *restrict <[buf]>, size_t <[size]>, 18 | const char *restrict <[mode]>); 19 | 20 | DESCRIPTION 21 | <> creates a seekable <> stream that wraps a 22 | fixed-length buffer of <[size]> bytes starting at <[buf]>. The stream 23 | is opened with <[mode]> treated as in <>, where append mode 24 | starts writing at the first NUL byte. If <[buf]> is NULL, then 25 | <[size]> bytes are automatically provided as if by <>, with 26 | the initial size of 0, and <[mode]> must contain <<+>> so that data 27 | can be read after it is written. 28 | 29 | The stream maintains a current position, which moves according to 30 | bytes read or written, and which can be one past the end of the array. 31 | The stream also maintains a current file size, which is never greater 32 | than <[size]>. If <[mode]> starts with <>, the position starts at 33 | <<0>>, and file size starts at <[size]> if <[buf]> was provided. If 34 | <[mode]> starts with <>, the position and file size start at <<0>>, 35 | and if <[buf]> was provided, the first byte is set to NUL. If 36 | <[mode]> starts with <>, the position and file size start at the 37 | location of the first NUL byte, or else <[size]> if <[buf]> was 38 | provided. 39 | 40 | When reading, NUL bytes have no significance, and reads cannot exceed 41 | the current file size. When writing, the file size can increase up to 42 | <[size]> as needed, and NUL bytes may be embedded in the stream (see 43 | <> for an alternative that automatically enlarges the 44 | buffer). When the stream is flushed or closed after a write that 45 | changed the file size, a NUL byte is written at the current position 46 | if there is still room; if the stream is not also open for reading, a 47 | NUL byte is additionally written at the last byte of <[buf]> when the 48 | stream has exceeded <[size]>, so that a write-only <[buf]> is always 49 | NUL-terminated when the stream is flushed or closed (and the initial 50 | <[size]> should take this into account). It is not possible to seek 51 | outside the bounds of <[size]>. A NUL byte written during a flush is 52 | restored to its previous value when seeking elsewhere in the string. 53 | 54 | RETURNS 55 | The return value is an open FILE pointer on success. On error, 56 | <> is returned, and <> will be set to EINVAL if <[size]> 57 | is zero or <[mode]> is invalid, ENOMEM if <[buf]> was NULL and memory 58 | could not be allocated, or EMFILE if too many streams are already 59 | open. 60 | 61 | PORTABILITY 62 | This function is being added to POSIX 200x, but is not in POSIX 2001. 63 | 64 | Supporting OS subroutines required: <>. 65 | */ 66 | 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include "extrastdio.h" 73 | 74 | /* Describe details of an open memstream. */ 75 | typedef struct fmemcookie { 76 | void *storage; /* storage to free on close */ 77 | char *buf; /* buffer start */ 78 | size_t pos; /* current position */ 79 | size_t eof; /* current file size */ 80 | size_t max; /* maximum file size */ 81 | char append; /* nonzero if appending */ 82 | char writeonly; /* 1 if write-only */ 83 | char saved; /* saved character that lived at pos before write-only NUL */ 84 | } fmemcookie; 85 | 86 | /* Read up to non-zero N bytes into BUF from stream described by 87 | COOKIE; return number of bytes read (0 on EOF). */ 88 | static int 89 | fmemread(void *cookie, char *buf, int n) 90 | { 91 | fmemcookie *c = (fmemcookie *) cookie; 92 | /* Can't read beyond current size, but EOF condition is not an error. */ 93 | if (c->pos > c->eof) 94 | return 0; 95 | if (n >= c->eof - c->pos) 96 | n = c->eof - c->pos; 97 | memcpy (buf, c->buf + c->pos, n); 98 | c->pos += n; 99 | return n; 100 | } 101 | 102 | /* Write up to non-zero N bytes of BUF into the stream described by COOKIE, 103 | returning the number of bytes written or EOF on failure. */ 104 | static int 105 | fmemwrite(void *cookie, const char *buf, int n) 106 | { 107 | fmemcookie *c = (fmemcookie *) cookie; 108 | int adjust = 0; /* true if at EOF, but still need to write NUL. */ 109 | 110 | /* Append always seeks to eof; otherwise, if we have previously done 111 | a seek beyond eof, ensure all intermediate bytes are NUL. */ 112 | if (c->append) 113 | c->pos = c->eof; 114 | else if (c->pos > c->eof) 115 | memset (c->buf + c->eof, '\0', c->pos - c->eof); 116 | /* Do not write beyond EOF; saving room for NUL on write-only stream. */ 117 | if (c->pos + n > c->max - c->writeonly) 118 | { 119 | adjust = c->writeonly; 120 | n = c->max - c->pos; 121 | } 122 | /* Now n is the number of bytes being modified, and adjust is 1 if 123 | the last byte is NUL instead of from buf. Write a NUL if 124 | write-only; or if read-write, eof changed, and there is still 125 | room. When we are within the file contents, remember what we 126 | overwrite so we can restore it if we seek elsewhere later. */ 127 | if (c->pos + n > c->eof) 128 | { 129 | c->eof = c->pos + n; 130 | if (c->eof - adjust < c->max) 131 | c->saved = c->buf[c->eof - adjust] = '\0'; 132 | } 133 | else if (c->writeonly) 134 | { 135 | if (n) 136 | { 137 | c->saved = c->buf[c->pos + n - adjust]; 138 | c->buf[c->pos + n - adjust] = '\0'; 139 | } 140 | else 141 | adjust = 0; 142 | } 143 | c->pos += n; 144 | if (n - adjust) 145 | memcpy (c->buf + c->pos - n, buf, n - adjust); 146 | else 147 | { 148 | return EOF; 149 | } 150 | return n; 151 | } 152 | 153 | /* Seek to position POS relative to WHENCE within stream described by 154 | COOKIE; return resulting position or fail with EOF. */ 155 | static fpos_t 156 | fmemseek(void *cookie, fpos_t pos, int whence) 157 | { 158 | fmemcookie *c = (fmemcookie *) cookie; 159 | off_t offset = (off_t) pos; 160 | 161 | if (whence == SEEK_CUR) 162 | offset += c->pos; 163 | else if (whence == SEEK_END) 164 | offset += c->eof; 165 | if (offset < 0) 166 | { 167 | offset = -1; 168 | } 169 | else if (offset > c->max) 170 | { 171 | offset = -1; 172 | } 173 | else 174 | { 175 | if (c->writeonly && c->pos < c->eof) 176 | { 177 | c->buf[c->pos] = c->saved; 178 | c->saved = '\0'; 179 | } 180 | c->pos = offset; 181 | if (c->writeonly && c->pos < c->eof) 182 | { 183 | c->saved = c->buf[c->pos]; 184 | c->buf[c->pos] = '\0'; 185 | } 186 | } 187 | return (fpos_t) offset; 188 | } 189 | 190 | /* Reclaim resources used by stream described by COOKIE. */ 191 | static int 192 | fmemclose(void *cookie) 193 | { 194 | fmemcookie *c = (fmemcookie *) cookie; 195 | free (c->storage); 196 | return 0; 197 | } 198 | 199 | /* Open a memstream around buffer BUF of SIZE bytes, using MODE. 200 | Return the new stream, or fail with NULL. */ 201 | FILE * 202 | fmemopen(void *buf, size_t size, const char *mode) 203 | { 204 | FILE *fp; 205 | fmemcookie *c; 206 | int flags; 207 | int dummy; 208 | 209 | if ((flags = __sflags (mode, &dummy)) == 0) 210 | return NULL; 211 | if (!size || !(buf || flags & __SAPP)) 212 | { 213 | return NULL; 214 | } 215 | if ((fp = (FILE *) __sfp ()) == NULL) 216 | return NULL; 217 | if ((c = (fmemcookie *) malloc (sizeof *c + (buf ? 0 : size))) == NULL) 218 | { 219 | fp->_flags = 0; /* release */ 220 | 221 | return NULL; 222 | } 223 | 224 | c->storage = c; 225 | c->max = size; 226 | /* 9 modes to worry about. */ 227 | /* w/a, buf or no buf: Guarantee a NUL after any file writes. */ 228 | c->writeonly = (flags & __SWR) != 0; 229 | c->saved = '\0'; 230 | if (!buf) 231 | { 232 | /* r+/w+/a+, and no buf: file starts empty. */ 233 | c->buf = (char *) (c + 1); 234 | *(char *) buf = '\0'; 235 | c->pos = c->eof = 0; 236 | c->append = (flags & __SAPP) != 0; 237 | } 238 | else 239 | { 240 | c->buf = (char *) buf; 241 | switch (*mode) 242 | { 243 | case 'a': 244 | /* a/a+ and buf: position and size at first NUL. */ 245 | buf = memchr (c->buf, '\0', size); 246 | c->eof = c->pos = buf ? (char *) buf - c->buf : size; 247 | if (!buf && c->writeonly) 248 | /* a: guarantee a NUL within size even if no writes. */ 249 | c->buf[size - 1] = '\0'; 250 | c->append = 1; 251 | break; 252 | case 'r': 253 | /* r/r+ and buf: read at beginning, full size available. */ 254 | c->pos = c->append = 0; 255 | c->eof = size; 256 | break; 257 | case 'w': 258 | /* w/w+ and buf: write at beginning, truncate to empty. */ 259 | c->pos = c->append = c->eof = 0; 260 | *c->buf = '\0'; 261 | break; 262 | default: 263 | abort(); 264 | } 265 | } 266 | 267 | fp->_file = -1; 268 | fp->_flags = flags; 269 | fp->_cookie = c; 270 | fp->_read = flags & (__SRD | __SRW) ? fmemread : NULL; 271 | fp->_write = flags & (__SWR | __SRW) ? fmemwrite : NULL; 272 | fp->_seek = fmemseek; 273 | fp->_close = fmemclose; 274 | 275 | return fp; 276 | } 277 | 278 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/stdio/fopencookie.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2007 Eric Blake 2 | * Permission to use, copy, modify, and distribute this software 3 | * is freely granted, provided that this notice is preserved. 4 | * 5 | * Modifications for Android written Jul 2009 by Alan Viverette 6 | */ 7 | 8 | /* 9 | FUNCTION 10 | <>---open a stream with custom callbacks 11 | 12 | INDEX 13 | fopencookie 14 | 15 | ANSI_SYNOPSIS 16 | #include 17 | typedef ssize_t (*cookie_read_function_t)(void *_cookie, char *_buf, 18 | size_t _n); 19 | typedef ssize_t (*cookie_write_function_t)(void *_cookie, 20 | const char *_buf, size_t _n); 21 | typedef int (*cookie_seek_function_t)(void *_cookie, off_t *_off, 22 | int _whence); 23 | typedef int (*cookie_close_function_t)(void *_cookie); 24 | FILE *fopencookie(const void *<[cookie]>, const char *<[mode]>, 25 | cookie_io_functions_t <[functions]>); 26 | 27 | DESCRIPTION 28 | <> creates a <> stream where I/O is performed using 29 | custom callbacks. The callbacks are registered via the structure: 30 | 31 | . typedef struct 32 | . { 33 | . cookie_read_function_t *read; 34 | . cookie_write_function_t *write; 35 | . cookie_seek_function_t *seek; 36 | . cookie_close_function_t *close; 37 | . } cookie_io_functions_t; 38 | 39 | The stream is opened with <[mode]> treated as in <>. The 40 | callbacks <[functions.read]> and <[functions.write]> may only be NULL 41 | when <[mode]> does not require them. 42 | 43 | <[functions.read]> should return -1 on failure, or else the number of 44 | bytes read (0 on EOF). It is similar to <>, except that 45 | <[cookie]> will be passed as the first argument. 46 | 47 | <[functions.write]> should return -1 on failure, or else the number of 48 | bytes written. It is similar to <>, except that <[cookie]> 49 | will be passed as the first argument. 50 | 51 | <[functions.seek]> should return -1 on failure, and 0 on success, with 52 | *<[_off]> set to the current file position. It is a cross between 53 | <> and <>, with the <[_whence]> argument interpreted in 54 | the same manner. A NULL <[functions.seek]> makes the stream behave 55 | similarly to a pipe in relation to stdio functions that require 56 | positioning. 57 | 58 | <[functions.close]> should return -1 on failure, or 0 on success. It 59 | is similar to <>, except that <[cookie]> will be passed as the 60 | first argument. A NULL <[functions.close]> merely flushes all data 61 | then lets <> succeed. A failed close will still invalidate 62 | the stream. 63 | 64 | Read and write I/O functions are allowed to change the underlying 65 | buffer on fully buffered or line buffered streams by calling 66 | <>. They are also not required to completely fill or empty 67 | the buffer. They are not, however, allowed to change streams from 68 | unbuffered to buffered or to change the state of the line buffering 69 | flag. They must also be prepared to have read or write calls occur on 70 | buffers other than the one most recently specified. 71 | 72 | RETURNS 73 | The return value is an open FILE pointer on success. On error, 74 | <> is returned, and <> will be set to EINVAL if a 75 | function pointer is missing or <[mode]> is invalid, ENOMEM if the 76 | stream cannot be created, or EMFILE if too many streams are already 77 | open. 78 | 79 | PORTABILITY 80 | This function is a newlib extension, copying the prototype from Linux. 81 | It is not portable. See also the <> interface from BSD. 82 | 83 | Supporting OS subroutines required: <>. 84 | */ 85 | 86 | #include 87 | #include 88 | #include 89 | #include "extrastdio.h" 90 | 91 | typedef struct fccookie { 92 | void *cookie; 93 | FILE *fp; 94 | ssize_t (*readfn)(void *, char *, size_t); 95 | ssize_t (*writefn)(void *, const char *, size_t); 96 | int (*seekfn)(void *, off_t *, int); 97 | int (*closefn)(void *); 98 | } fccookie; 99 | 100 | static int 101 | fcread(void *cookie, char *buf, int n) 102 | { 103 | int result; 104 | fccookie *c = (fccookie *) cookie; 105 | result = c->readfn (c->cookie, buf, n); 106 | return result; 107 | } 108 | 109 | static int 110 | fcwrite(void *cookie, const char *buf, int n) 111 | { 112 | int result; 113 | fccookie *c = (fccookie *) cookie; 114 | if (c->fp->_flags & __SAPP && c->fp->_seek) 115 | { 116 | c->fp->_seek (cookie, 0, SEEK_END); 117 | } 118 | result = c->writefn (c->cookie, buf, n); 119 | return result; 120 | } 121 | 122 | static fpos_t 123 | fcseek(void *cookie, fpos_t pos, int whence) 124 | { 125 | fccookie *c = (fccookie *) cookie; 126 | off_t offset = (off_t) pos; 127 | 128 | c->seekfn (c->cookie, &offset, whence); 129 | 130 | return (fpos_t) offset; 131 | } 132 | 133 | static int 134 | fcclose(void *cookie) 135 | { 136 | int result = 0; 137 | fccookie *c = (fccookie *) cookie; 138 | if (c->closefn) 139 | { 140 | result = c->closefn (c->cookie); 141 | } 142 | free (c); 143 | return result; 144 | } 145 | 146 | FILE * 147 | fopencookie(void *cookie, const char *mode, cookie_io_functions_t functions) 148 | { 149 | FILE *fp; 150 | fccookie *c; 151 | int flags; 152 | int dummy; 153 | 154 | if ((flags = __sflags (mode, &dummy)) == 0) 155 | return NULL; 156 | if (((flags & (__SRD | __SRW)) && !functions.read) 157 | || ((flags & (__SWR | __SRW)) && !functions.write)) 158 | { 159 | return NULL; 160 | } 161 | if ((fp = (FILE *) __sfp ()) == NULL) 162 | return NULL; 163 | if ((c = (fccookie *) malloc (sizeof *c)) == NULL) 164 | { 165 | fp->_flags = 0; 166 | return NULL; 167 | } 168 | 169 | fp->_file = -1; 170 | fp->_flags = flags; 171 | c->cookie = cookie; 172 | c->fp = fp; 173 | fp->_cookie = c; 174 | c->readfn = functions.read; 175 | fp->_read = fcread; 176 | c->writefn = functions.write; 177 | fp->_write = fcwrite; 178 | c->seekfn = functions.seek; 179 | fp->_seek = functions.seek ? fcseek : NULL; 180 | c->closefn = functions.close; 181 | fp->_close = fcclose; 182 | 183 | return fp; 184 | } 185 | 186 | 187 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/stdio/open_memstream.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2007 Eric Blake 2 | * Permission to use, copy, modify, and distribute this software 3 | * is freely granted, provided that this notice is preserved. 4 | * 5 | * Modifications for Android written Jul 2009 by Alan Viverette 6 | */ 7 | 8 | /* 9 | FUNCTION 10 | <>---open a write stream around an arbitrary-length string 11 | 12 | INDEX 13 | open_memstream 14 | 15 | ANSI_SYNOPSIS 16 | #include 17 | FILE *open_memstream(char **restrict <[buf]>, 18 | size_t *restrict <[size]>); 19 | 20 | DESCRIPTION 21 | <> creates a seekable <> stream that wraps an 22 | arbitrary-length buffer, created as if by <>. The current 23 | contents of *<[buf]> are ignored; this implementation uses *<[size]> 24 | as a hint of the maximum size expected, but does not fail if the hint 25 | was wrong. The parameters <[buf]> and <[size]> are later stored 26 | through following any call to <> or <>, set to the 27 | current address and usable size of the allocated string; although 28 | after fflush, the pointer is only valid until another stream operation 29 | that results in a write. Behavior is undefined if the user alters 30 | either *<[buf]> or *<[size]> prior to <>. 31 | 32 | The stream is write-only, since the user can directly read *<[buf]> 33 | after a flush; see <> for a way to wrap a string with a 34 | readable stream. The user is responsible for calling <> on 35 | the final *<[buf]> after <>. 36 | 37 | Any time the stream is flushed, a NUL byte is written at the current 38 | position (but is not counted in the buffer length), so that the string 39 | is always NUL-terminated after at most *<[size]> bytes. However, data 40 | previously written beyond the current stream offset is not lost, and 41 | the NUL byte written during a flush is restored to its previous value 42 | when seeking elsewhere in the string. 43 | 44 | RETURNS 45 | The return value is an open FILE pointer on success. On error, 46 | <> is returned, and <> will be set to EINVAL if <[buf]> 47 | or <[size]> is NULL, ENOMEM if memory could not be allocated, or 48 | EMFILE if too many streams are already open. 49 | 50 | PORTABILITY 51 | This function is being added to POSIX 200x, but is not in POSIX 2001. 52 | 53 | Supporting OS subroutines required: <>. 54 | */ 55 | 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include "extrastdio.h" 61 | 62 | /* Describe details of an open memstream. */ 63 | typedef struct memstream { 64 | void *storage; /* storage to free on close */ 65 | char **pbuf; /* pointer to the current buffer */ 66 | size_t *psize; /* pointer to the current size, smaller of pos or eof */ 67 | size_t pos; /* current position */ 68 | size_t eof; /* current file size */ 69 | size_t max; /* current malloc buffer size, always > eof */ 70 | char saved; /* saved character that lived at *psize before NUL */ 71 | } memstream; 72 | 73 | /* Write up to non-zero N bytes of BUF into the stream described by COOKIE, 74 | returning the number of bytes written or EOF on failure. */ 75 | static int 76 | memwrite(void *cookie, const char *buf, int n) 77 | { 78 | memstream *c = (memstream *) cookie; 79 | char *cbuf = *c->pbuf; 80 | 81 | /* size_t is unsigned, but off_t is signed. Don't let stream get so 82 | big that user cannot do ftello. */ 83 | if (sizeof (off_t) == sizeof (size_t) && (ssize_t) (c->pos + n) < 0) 84 | { 85 | return EOF; 86 | } 87 | /* Grow the buffer, if necessary. Choose a geometric growth factor 88 | to avoid quadratic realloc behavior, but use a rate less than 89 | (1+sqrt(5))/2 to accomodate malloc overhead. Overallocate, so 90 | that we can add a trailing \0 without reallocating. The new 91 | allocation should thus be max(prev_size*1.5, c->pos+n+1). */ 92 | if (c->pos + n >= c->max) 93 | { 94 | size_t newsize = c->max * 3 / 2; 95 | if (newsize < c->pos + n + 1) 96 | newsize = c->pos + n + 1; 97 | cbuf = realloc (cbuf, newsize); 98 | if (! cbuf) 99 | return EOF; /* errno already set to ENOMEM */ 100 | *c->pbuf = cbuf; 101 | c->max = newsize; 102 | } 103 | /* If we have previously done a seek beyond eof, ensure all 104 | intermediate bytes are NUL. */ 105 | if (c->pos > c->eof) 106 | memset (cbuf + c->eof, '\0', c->pos - c->eof); 107 | memcpy (cbuf + c->pos, buf, n); 108 | c->pos += n; 109 | /* If the user has previously written further, remember what the 110 | trailing NUL is overwriting. Otherwise, extend the stream. */ 111 | if (c->pos > c->eof) 112 | c->eof = c->pos; 113 | else 114 | c->saved = cbuf[c->pos]; 115 | cbuf[c->pos] = '\0'; 116 | *c->psize = c->pos; 117 | return n; 118 | } 119 | 120 | /* Seek to position POS relative to WHENCE within stream described by 121 | COOKIE; return resulting position or fail with EOF. */ 122 | static fpos_t 123 | memseek(void *cookie, fpos_t pos, int whence) 124 | { 125 | memstream *c = (memstream *) cookie; 126 | off_t offset = (off_t) pos; 127 | 128 | if (whence == SEEK_CUR) 129 | offset += c->pos; 130 | else if (whence == SEEK_END) 131 | offset += c->eof; 132 | if (offset < 0) 133 | { 134 | offset = -1; 135 | } 136 | else if ((size_t) offset != offset) 137 | { 138 | offset = -1; 139 | } 140 | else 141 | { 142 | if (c->pos < c->eof) 143 | { 144 | (*c->pbuf)[c->pos] = c->saved; 145 | c->saved = '\0'; 146 | } 147 | c->pos = offset; 148 | if (c->pos < c->eof) 149 | { 150 | c->saved = (*c->pbuf)[c->pos]; 151 | (*c->pbuf)[c->pos] = '\0'; 152 | *c->psize = c->pos; 153 | } 154 | else 155 | *c->psize = c->eof; 156 | } 157 | return (fpos_t) offset; 158 | } 159 | 160 | /* Reclaim resources used by stream described by COOKIE. */ 161 | static int 162 | memclose(void *cookie) 163 | { 164 | memstream *c = (memstream *) cookie; 165 | char *buf; 166 | 167 | /* Be nice and try to reduce any unused memory. */ 168 | buf = realloc (*c->pbuf, *c->psize + 1); 169 | if (buf) 170 | *c->pbuf = buf; 171 | free (c->storage); 172 | return 0; 173 | } 174 | 175 | /* Open a memstream that tracks a dynamic buffer in BUF and SIZE. 176 | Return the new stream, or fail with NULL. */ 177 | FILE * 178 | open_memstream(char **buf, size_t *size) 179 | { 180 | FILE *fp; 181 | memstream *c; 182 | int flags; 183 | 184 | if (!buf || !size) 185 | { 186 | return NULL; 187 | } 188 | if ((fp = (FILE *) __sfp ()) == NULL) 189 | return NULL; 190 | if ((c = (memstream *) malloc (sizeof *c)) == NULL) 191 | { 192 | fp->_flags = 0; /* release */ 193 | return NULL; 194 | } 195 | 196 | /* Use *size as a hint for initial sizing, but bound the initial 197 | malloc between 64 bytes (same as asprintf, to avoid frequent 198 | mallocs on small strings) and 64k bytes (to avoid overusing the 199 | heap if *size was garbage). */ 200 | c->max = *size; 201 | if (c->max < 64) 202 | c->max = 64; 203 | else if (c->max > 64 * 1024) 204 | c->max = 64 * 1024; 205 | *size = 0; 206 | *buf = malloc (c->max); 207 | if (!*buf) 208 | { 209 | fp->_flags = 0; /* release */ 210 | free (c); 211 | return NULL; 212 | } 213 | **buf = '\0'; 214 | 215 | c->storage = c; 216 | c->pbuf = buf; 217 | c->psize = size; 218 | c->eof = 0; 219 | c->saved = '\0'; 220 | 221 | fp->_file = -1; 222 | fp->_flags = __SWR; 223 | fp->_cookie = c; 224 | fp->_read = NULL; 225 | fp->_write = memwrite; 226 | fp->_seek = memseek; 227 | fp->_close = memclose; 228 | 229 | return fp; 230 | } 231 | 232 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/utilities.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif /* __cplusplus */ 25 | 26 | /*************** 27 | * AdaptiveMap * 28 | ***************/ 29 | 30 | jint Java_com_googlecode_leptonica_android_AdaptiveMap_nativeBackgroundNormMorph(JNIEnv *env, 31 | jclass clazz, 32 | jint nativePix, 33 | jint reduction, 34 | jint size, 35 | jint bgval) { 36 | // Normalizes the background of each element in pixa. 37 | 38 | PIX *pixs = (PIX *) nativePix; 39 | PIX *pixd = pixBackgroundNormMorph(pixs, NULL, (l_int32) reduction, (l_int32) size, 40 | (l_int32) bgval); 41 | 42 | return (jint) pixd; 43 | } 44 | 45 | /************ 46 | * Binarize * 47 | ************/ 48 | 49 | jint Java_com_googlecode_leptonica_android_Binarize_nativeOtsuAdaptiveThreshold(JNIEnv *env, 50 | jclass clazz, 51 | jint nativePix, 52 | jint sizeX, 53 | jint sizeY, 54 | jint smoothX, 55 | jint smoothY, 56 | jfloat scoreFract) { 57 | 58 | PIX *pixs = (PIX *) nativePix; 59 | PIX *pixd; 60 | 61 | if (pixOtsuAdaptiveThreshold(pixs, (l_int32) sizeX, (l_int32) sizeY, (l_int32) smoothX, 62 | (l_int32) smoothY, (l_float32) scoreFract, NULL, &pixd)) { 63 | return (jint) 0; 64 | } 65 | 66 | return (jint) pixd; 67 | } 68 | 69 | /*********** 70 | * Convert * 71 | ***********/ 72 | 73 | jint Java_com_googlecode_leptonica_android_Convert_nativeConvertTo8(JNIEnv *env, jclass clazz, 74 | jint nativePix) { 75 | PIX *pixs = (PIX *) nativePix; 76 | PIX *pixd = pixConvertTo8(pixs, FALSE); 77 | 78 | return (jint) pixd; 79 | } 80 | 81 | /*********** 82 | * Enhance * 83 | ***********/ 84 | 85 | jint Java_com_googlecode_leptonica_android_Enhance_nativeUnsharpMasking(JNIEnv *env, jclass clazz, 86 | jint nativePix, 87 | jint halfwidth, 88 | jfloat fract) { 89 | PIX *pixs = (PIX *) nativePix; 90 | PIX *pixd = pixUnsharpMasking(pixs, (l_int32) halfwidth, (l_float32) fract); 91 | 92 | return (jint) pixd; 93 | } 94 | 95 | /********** 96 | * JpegIO * 97 | **********/ 98 | 99 | jbyteArray Java_com_googlecode_leptonica_android_JpegIO_nativeCompressToJpeg(JNIEnv *env, 100 | jclass clazz, 101 | jint nativePix, 102 | jint quality, 103 | jboolean progressive) { 104 | PIX *pix = (PIX *) nativePix; 105 | 106 | l_uint8 *data; 107 | size_t size; 108 | 109 | if (pixWriteMemJpeg(&data, &size, pix, (l_int32) quality, progressive == JNI_TRUE ? 1 : 0)) { 110 | LOGE("Failed to write JPEG data"); 111 | 112 | return NULL; 113 | } 114 | 115 | // TODO Can we just use the byte array directly? 116 | jbyteArray array = env->NewByteArray(size); 117 | env->SetByteArrayRegion(array, 0, size, (jbyte *) data); 118 | 119 | free(data); 120 | 121 | return array; 122 | } 123 | 124 | /********* 125 | * Scale * 126 | *********/ 127 | 128 | jint Java_com_googlecode_leptonica_android_Scale_nativeScale(JNIEnv *env, jclass clazz, 129 | jint nativePix, jfloat scaleX, 130 | jfloat scaleY) { 131 | PIX *pixs = (PIX *) nativePix; 132 | PIX *pixd = pixScale(pixs, (l_float32) scaleX, (l_float32) scaleY); 133 | 134 | return (jint) pixd; 135 | } 136 | 137 | /******** 138 | * Skew * 139 | ********/ 140 | 141 | jfloat Java_com_googlecode_leptonica_android_Skew_nativeFindSkew(JNIEnv *env, jclass clazz, 142 | jint nativePix, jfloat sweepRange, 143 | jfloat sweepDelta, 144 | jint sweepReduction, 145 | jint searchReduction, 146 | jfloat searchMinDelta) { 147 | // Corrects the rotation of each element in pixa to 0 degrees. 148 | 149 | PIX *pixs = (PIX *) nativePix; 150 | 151 | l_float32 angle, conf; 152 | 153 | if (!pixFindSkewSweepAndSearch(pixs, &angle, &conf, (l_int32) sweepReduction, 154 | (l_int32) searchReduction, (l_float32) sweepRange, 155 | (l_int32) sweepDelta, (l_float32) searchMinDelta)) { 156 | if (conf <= 0) { 157 | return (jfloat) 0; 158 | } 159 | 160 | return (jfloat) angle; 161 | } 162 | 163 | return (jfloat) 0; 164 | } 165 | 166 | /********** 167 | * Rotate * 168 | **********/ 169 | 170 | jint Java_com_googlecode_leptonica_android_Rotate_nativeRotate(JNIEnv *env, jclass clazz, 171 | jint nativePix, jfloat degrees, 172 | jboolean quality, jboolean resize) { 173 | PIX *pixd; 174 | PIX *pixs = (PIX *) nativePix; 175 | 176 | l_float32 deg2rad = 3.1415926535 / 180.0; 177 | l_float32 radians = degrees * deg2rad; 178 | l_int32 w, h, bpp, type; 179 | 180 | pixGetDimensions(pixs, &w, &h, &bpp); 181 | 182 | if (bpp == 1 && quality == JNI_TRUE) { 183 | pixd = pixRotateBinaryNice(pixs, radians, L_BRING_IN_WHITE); 184 | } else { 185 | type = quality == JNI_TRUE ? L_ROTATE_AREA_MAP : L_ROTATE_SAMPLING; 186 | w = (resize == JNI_TRUE) ? w : 0; 187 | h = (resize == JNI_TRUE) ? h : 0; 188 | pixd = pixRotate(pixs, radians, type, L_BRING_IN_WHITE, w, h); 189 | } 190 | 191 | return (jint) pixd; 192 | } 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif /* __cplusplus */ 197 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_leptonica_android/writefile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common.h" 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif /* __cplusplus */ 25 | 26 | /************* 27 | * WriteFile * 28 | *************/ 29 | 30 | jint Java_com_googlecode_leptonica_android_WriteFile_nativeWriteBytes8(JNIEnv *env, jclass clazz, 31 | jint nativePix, 32 | jbyteArray data) { 33 | l_int32 w, h, d; 34 | PIX *pix = (PIX *) nativePix; 35 | pixGetDimensions(pix, &w, &h, &d); 36 | 37 | l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL); 38 | jbyte *data_buffer = env->GetByteArrayElements(data, NULL); 39 | l_uint8 *byte_buffer = (l_uint8 *) data_buffer; 40 | 41 | for (int i = 0; i < h; i++) { 42 | memcpy((byte_buffer + (i * w)), lineptrs[i], w); 43 | } 44 | 45 | env->ReleaseByteArrayElements(data, data_buffer, 0); 46 | pixCleanupByteProcessing(pix, lineptrs); 47 | 48 | return (jint)(w * h); 49 | } 50 | 51 | jboolean Java_com_googlecode_leptonica_android_WriteFile_nativeWriteFiles(JNIEnv *env, 52 | jclass clazz, 53 | jint nativePixa, 54 | jstring rootName, 55 | jint format) { 56 | PIXA *pixas = (PIXA *) nativePixa; 57 | 58 | const char *c_rootName = env->GetStringUTFChars(rootName, NULL); 59 | if (c_rootName == NULL) { 60 | LOGE("could not extract rootName string!"); 61 | return JNI_FALSE; 62 | } 63 | 64 | jboolean result = JNI_TRUE; 65 | 66 | if (pixaWriteFiles(c_rootName, pixas, (l_uint32) format)) { 67 | LOGE("could not write pixa data to %s", c_rootName); 68 | result = JNI_FALSE; 69 | } 70 | 71 | env->ReleaseStringUTFChars(rootName, c_rootName); 72 | 73 | return result; 74 | } 75 | 76 | jbyteArray Java_com_googlecode_leptonica_android_WriteFile_nativeWriteMem(JNIEnv *env, 77 | jclass clazz, 78 | jint nativePix, 79 | jint format) { 80 | PIX *pixs = (PIX *) nativePix; 81 | 82 | l_uint8 *data; 83 | size_t size; 84 | 85 | if (pixWriteMem(&data, &size, pixs, (l_uint32) format)) { 86 | LOGE("Failed to write pix data"); 87 | return NULL; 88 | } 89 | 90 | // TODO Can we just use the byte array directly? 91 | jbyteArray array = env->NewByteArray(size); 92 | env->SetByteArrayRegion(array, 0, size, (jbyte *) data); 93 | 94 | free(data); 95 | 96 | return array; 97 | } 98 | 99 | jboolean Java_com_googlecode_leptonica_android_WriteFile_nativeWriteImpliedFormat( 100 | JNIEnv *env, 101 | jclass clazz, 102 | jint nativePix, 103 | jstring fileName, 104 | jint quality, 105 | jboolean progressive) { 106 | PIX *pixs = (PIX *) nativePix; 107 | 108 | const char *c_fileName = env->GetStringUTFChars(fileName, NULL); 109 | if (c_fileName == NULL) { 110 | LOGE("could not extract fileName string!"); 111 | return JNI_FALSE; 112 | } 113 | 114 | jboolean result = JNI_TRUE; 115 | 116 | if (pixWriteImpliedFormat(c_fileName, pixs, (l_int32) quality, (progressive == JNI_TRUE))) { 117 | LOGE("could not write pix data to %s", c_fileName); 118 | result = JNI_FALSE; 119 | } 120 | 121 | env->ReleaseStringUTFChars(fileName, c_fileName); 122 | 123 | return result; 124 | } 125 | 126 | jboolean Java_com_googlecode_leptonica_android_WriteFile_nativeWriteBitmap(JNIEnv *env, 127 | jclass clazz, 128 | jint nativePix, 129 | jobject bitmap) { 130 | PIX *pixs = (PIX *) nativePix; 131 | 132 | l_int32 w, h, d; 133 | AndroidBitmapInfo info; 134 | void* pixels; 135 | int ret; 136 | 137 | if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { 138 | LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 139 | return JNI_FALSE; 140 | } 141 | 142 | if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { 143 | LOGE("Bitmap format is not RGBA_8888 !"); 144 | return JNI_FALSE; 145 | } 146 | 147 | pixGetDimensions(pixs, &w, &h, &d); 148 | 149 | if (w != info.width || h != info.height) { 150 | LOGE("Bitmap width and height do not match Pix dimensions!"); 151 | return JNI_FALSE; 152 | } 153 | 154 | if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { 155 | LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 156 | return JNI_FALSE; 157 | } 158 | 159 | pixEndianByteSwap(pixs); 160 | 161 | l_uint8 *dst = (l_uint8 *) pixels; 162 | l_uint8 *src = (l_uint8 *) pixGetData(pixs); 163 | l_int32 dstBpl = info.stride; 164 | l_int32 srcBpl = 4 * pixGetWpl(pixs); 165 | 166 | LOGE("Writing 32bpp RGBA bitmap (w=%d, h=%d, stride=%d) from %dbpp Pix (wpl=%d)", info.width, 167 | info.height, info.stride, d, pixGetWpl(pixs)); 168 | 169 | for (int dy = 0; dy < info.height; dy++) { 170 | l_uint8 *dstx = dst; 171 | l_uint8 *srcx = src; 172 | 173 | if (d == 32) { 174 | memcpy(dst, src, 4 * info.width); 175 | } else if (d == 8) { 176 | for (int dw = 0; dw < info.width; dw++) { 177 | dstx[0] = dstx[1] = dstx[2] = srcx[0]; 178 | dstx[3] = 0xFF; 179 | 180 | dstx += 4; 181 | srcx += 1; 182 | } 183 | } else if (d == 1) { 184 | for (int dw = 0; dw < info.width; dw++) { 185 | dstx[0] = dstx[1] = dstx[2] = (1 << (7 - (dw & 7)) & srcx[0]) ? 0x00 : 0xFF; 186 | dstx[3] = 0xFF; 187 | 188 | dstx += 4; 189 | srcx += ((dw % 8) == 7) ? 1 : 0; 190 | } 191 | } 192 | 193 | dst += dstBpl; 194 | src += srcBpl; 195 | } 196 | 197 | AndroidBitmap_unlockPixels(env, bitmap); 198 | 199 | return JNI_TRUE; 200 | } 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif /* __cplusplus */ 205 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/.gitignore: -------------------------------------------------------------------------------- 1 | /src 2 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := libtess 6 | 7 | # tesseract (minus executable) 8 | 9 | BLACKLIST_SRC_FILES := \ 10 | %api/tesseractmain.cpp \ 11 | %viewer/svpaint.cpp 12 | 13 | TESSERACT_SRC_FILES := \ 14 | $(wildcard $(TESSERACT_PATH)/api/*.cpp) \ 15 | $(wildcard $(TESSERACT_PATH)/ccmain/*.cpp) \ 16 | $(wildcard $(TESSERACT_PATH)/ccstruct/*.cpp) \ 17 | $(wildcard $(TESSERACT_PATH)/ccutil/*.cpp) \ 18 | $(wildcard $(TESSERACT_PATH)/classify/*.cpp) \ 19 | $(wildcard $(TESSERACT_PATH)/cube/*.cpp) \ 20 | $(wildcard $(TESSERACT_PATH)/cutil/*.cpp) \ 21 | $(wildcard $(TESSERACT_PATH)/dict/*.cpp) \ 22 | $(wildcard $(TESSERACT_PATH)/image/*.cpp) \ 23 | $(wildcard $(TESSERACT_PATH)/neural_networks/runtime/*.cpp) \ 24 | $(wildcard $(TESSERACT_PATH)/textord/*.cpp) \ 25 | $(wildcard $(TESSERACT_PATH)/viewer/*.cpp) \ 26 | $(wildcard $(TESSERACT_PATH)/wordrec/*.cpp) 27 | 28 | LOCAL_SRC_FILES := \ 29 | $(filter-out $(BLACKLIST_SRC_FILES),$(subst $(LOCAL_PATH)/,,$(TESSERACT_SRC_FILES))) 30 | 31 | LOCAL_C_INCLUDES := \ 32 | $(TESSERACT_PATH)/api \ 33 | $(TESSERACT_PATH)/ccmain \ 34 | $(TESSERACT_PATH)/ccstruct \ 35 | $(TESSERACT_PATH)/ccutil \ 36 | $(TESSERACT_PATH)/classify \ 37 | $(TESSERACT_PATH)/cube \ 38 | $(TESSERACT_PATH)/cutil \ 39 | $(TESSERACT_PATH)/dict \ 40 | $(TESSERACT_PATH)/image \ 41 | $(TESSERACT_PATH)/neural_networks/runtime \ 42 | $(TESSERACT_PATH)/textord \ 43 | $(TESSERACT_PATH)/viewer \ 44 | $(TESSERACT_PATH)/wordrec \ 45 | $(LEPTONICA_PATH)/src 46 | 47 | LOCAL_CFLAGS := \ 48 | -DHAVE_LIBLEPT \ 49 | -DUSE_STD_NAMESPACE \ 50 | -D'VERSION="Android"' \ 51 | -include ctype.h \ 52 | -include unistd.h \ 53 | 54 | # missing glibc functions 55 | 56 | ifneq ($(TARGET_SIMULATOR),true) 57 | LOCAL_SRC_FILES += \ 58 | glibc/glob.c 59 | LOCAL_C_INCLUDES += \ 60 | $(LOCAL_PATH)/glibc 61 | endif 62 | 63 | # jni 64 | 65 | LOCAL_SRC_FILES += \ 66 | pageiterator.cpp \ 67 | resultiterator.cpp \ 68 | tessbaseapi.cpp 69 | 70 | LOCAL_C_INCLUDES += \ 71 | $(LOCAL_PATH) 72 | 73 | LOCAL_LDLIBS += \ 74 | -ljnigraphics \ 75 | -llog 76 | 77 | # common 78 | 79 | LOCAL_PRELINK_MODULE := false 80 | LOCAL_SHARED_LIBRARIES := liblept 81 | 82 | include $(BUILD_SHARED_LIBRARY) 83 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef TESSERACT_JNI_COMMON_H 18 | #define TESSERACT_JNI_COMMON_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define LOG_TAG "Tesseract(native)" 25 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 26 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 27 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 28 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) 29 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 30 | #define LOG_ASSERT(_cond, ...) if (!_cond) __android_log_assert("conditional", LOG_TAG, __VA_ARGS__) 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/glibc/glob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1989, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * This code is derived from software contributed to Berkeley by 6 | * Guido van Rossum. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of the University nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | * SUCH DAMAGE. 31 | * 32 | * @(#)glob.h 8.1 (Berkeley) 6/2/93 33 | * $FreeBSD$ 34 | */ 35 | 36 | #ifndef _GLOB_H_ 37 | #define _GLOB_H_ 38 | 39 | #include 40 | #include 41 | 42 | #ifndef _SIZE_T_DECLARED 43 | typedef __size_t size_t; 44 | #define _SIZE_T_DECLARED 45 | #endif 46 | 47 | struct stat; 48 | typedef struct { 49 | size_t gl_pathc; /* Count of total paths so far. */ 50 | size_t gl_matchc; /* Count of paths matching pattern. */ 51 | size_t gl_offs; /* Reserved at beginning of gl_pathv. */ 52 | int gl_flags; /* Copy of flags parameter to glob. */ 53 | char **gl_pathv; /* List of paths matching pattern. */ 54 | /* Copy of errfunc parameter to glob. */ 55 | int (*gl_errfunc)(const char *, int); 56 | 57 | /* 58 | * Alternate filesystem access methods for glob; replacement 59 | * versions of closedir(3), readdir(3), opendir(3), stat(2) 60 | * and lstat(2). 61 | */ 62 | void (*gl_closedir)(void *); 63 | struct dirent *(*gl_readdir)(void *); 64 | void *(*gl_opendir)(const char *); 65 | int (*gl_lstat)(const char *, struct stat *); 66 | int (*gl_stat)(const char *, struct stat *); 67 | } glob_t; 68 | 69 | #if __POSIX_VISIBLE >= 199209 70 | /* Believed to have been introduced in 1003.2-1992 */ 71 | #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ 72 | #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ 73 | #define GLOB_ERR 0x0004 /* Return on error. */ 74 | #define GLOB_MARK 0x0008 /* Append / to matching directories. */ 75 | #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ 76 | #define GLOB_NOSORT 0x0020 /* Don't sort. */ 77 | #define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */ 78 | 79 | /* Error values returned by glob(3) */ 80 | #define GLOB_NOSPACE (-1) /* Malloc call failed. */ 81 | #define GLOB_ABORTED (-2) /* Unignored error. */ 82 | #define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */ 83 | #define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */ 84 | #endif /* __POSIX_VISIBLE >= 199209 */ 85 | 86 | #if __BSD_VISIBLE 87 | #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ 88 | #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ 89 | #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ 90 | #define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ 91 | #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ 92 | #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ 93 | #define GLOB_LIMIT 0x1000 /* limit number of returned paths */ 94 | 95 | /* source compatibility, these are the old names */ 96 | #define GLOB_MAXPATH GLOB_LIMIT 97 | #define GLOB_ABEND GLOB_ABORTED 98 | #endif /* __BSD_VISIBLE */ 99 | 100 | __BEGIN_DECLS 101 | int glob(const char *, int, int (*)(const char *, int), glob_t *); 102 | void globfree(glob_t *); 103 | __END_DECLS 104 | 105 | #endif /* !_GLOB_H_ */ 106 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/pageiterator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "common.h" 19 | #include "pageiterator.h" 20 | #include "allheaders.h" 21 | #include "helpers.h" 22 | #include "pageres.h" 23 | #include "tesseractclass.h" 24 | 25 | using namespace tesseract; 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif /* __cplusplus */ 30 | 31 | void Java_com_googlecode_tesseract_android_PageIterator_nativeBegin(JNIEnv *env, jclass clazz, 32 | jint nativePageIterator) { 33 | ((PageIterator *) nativePageIterator)->Begin(); 34 | } 35 | 36 | jboolean Java_com_googlecode_tesseract_android_PageIterator_nativeNext(JNIEnv *env, jclass clazz, 37 | jint nativePageIterator, jint level) { 38 | PageIterator *pageIterator = (PageIterator *) nativePageIterator; 39 | PageIteratorLevel enumLevel = (PageIteratorLevel) level; 40 | 41 | return pageIterator->Next(enumLevel) ? JNI_TRUE : JNI_FALSE; 42 | } 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif /* __cplusplus */ 47 | -------------------------------------------------------------------------------- /tesseract-android-tools/jni/com_googlecode_tesseract_android/resultiterator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "common.h" 19 | #include "resultiterator.h" 20 | #include "allheaders.h" 21 | #include "pageres.h" 22 | #include "tesseractclass.h" 23 | 24 | using namespace tesseract; 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | jstring Java_com_googlecode_tesseract_android_ResultIterator_nativeGetUTF8Text(JNIEnv *env, 31 | jclass clazz, jint nativeResultIterator, jint level) { 32 | ResultIterator *resultIterator = (ResultIterator *) nativeResultIterator; 33 | PageIteratorLevel enumLevel = (PageIteratorLevel) level; 34 | 35 | char *text = resultIterator->GetUTF8Text(enumLevel); 36 | jstring result = env->NewStringUTF(text); 37 | 38 | free(text); 39 | 40 | return result; 41 | } 42 | 43 | jfloat Java_com_googlecode_tesseract_android_ResultIterator_nativeConfidence(JNIEnv *env, 44 | jclass clazz, jint nativeResultIterator, jint level) { 45 | ResultIterator *resultIterator = (ResultIterator *) nativeResultIterator; 46 | PageIteratorLevel enumLevel = (PageIteratorLevel) level; 47 | 48 | return (jfloat) resultIterator->Confidence(enumLevel); 49 | } 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif /* __cplusplus */ 54 | -------------------------------------------------------------------------------- /tesseract-android-tools/languages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | curl -O http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz 3 | tar -zxvf tesseract-ocr-3.02.eng.tar.gz 4 | rm -f tesseract-ocr-3.02.eng.tar.gz 5 | mkdir data 6 | mv tesseract-ocr data/tesseract 7 | adb push data/ /sdcard/ 8 | adb shell sync 9 | -------------------------------------------------------------------------------- /tesseract-android-tools/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /tesseract-android-tools/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | android.library=true 11 | # Project target. 12 | target=android-8 13 | -------------------------------------------------------------------------------- /tesseract-android-tools/res/.stub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rebbix/tesseract-android-tools/65bebaed366e189230b97a349a3c275716a49403/tesseract-android-tools/res/.stub -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/AdaptiveMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image adaptive mapping methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class AdaptiveMap { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | // Background normalization constants 30 | 31 | /** Image reduction value; possible values are 1, 2, 4, 8 */ 32 | private final static int NORM_REDUCTION = 16; 33 | 34 | /** Desired tile size; actual size may vary */ 35 | private final static int NORM_SIZE = 3; 36 | 37 | /** Background brightness value; values over 200 may result in clipping */ 38 | private final static int NORM_BG_VALUE = 200; 39 | 40 | /** 41 | * Normalizes an image's background using default parameters. 42 | * 43 | * @param pixs A source pix image. 44 | * @return the source pix image with a normalized background 45 | */ 46 | public static Pix backgroundNormMorph(Pix pixs) { 47 | return backgroundNormMorph(pixs, NORM_REDUCTION, NORM_SIZE, NORM_BG_VALUE); 48 | } 49 | 50 | /** 51 | * Normalizes an image's background to a specified value. 52 | *

53 | * Notes: 54 | *

    55 | *
  1. This is a top-level interface for normalizing the image intensity by 56 | * mapping the image so that the background is near the input value 'bgval'. 57 | *
  2. The input image is either grayscale or rgb. 58 | *
  3. For each component in the input image, the background value is 59 | * estimated using a grayscale closing; hence the 'Morph' in the function 60 | * name. 61 | *
  4. An optional binary mask can be specified, with the foreground pixels 62 | * typically over image regions. The resulting background map values will be 63 | * determined by surrounding pixels that are not under the mask foreground. 64 | * The origin (0,0) of this mask is assumed to be aligned with the origin of 65 | * the input image. This binary mask must not fully cover pixs, because then 66 | * there will be no pixels in the input image available to compute the 67 | * background. 68 | *
  5. The map is computed at reduced size (given by 'reduction') from the 69 | * input pixs and optional pixim. At this scale, pixs is closed to remove 70 | * the background, using a square Sel of odd dimension. The product of 71 | * reduction * size should be large enough to remove most of the text 72 | * foreground. 73 | *
  6. No convolutional smoothing needs to be done on the map before 74 | * inverting it. 75 | *
  7. A 'bgval' target background value for the normalized image. This 76 | * should be at least 128. If set too close to 255, some clipping will occur 77 | * in the result. 78 | *
79 | * 80 | * @param pixs A source pix image. 81 | * @param normReduction Reduction at which morphological closings are done. 82 | * @param normSize Size of square Sel for the closing. 83 | * @param normBgValue Target background value. 84 | * @return the source pix image with a normalized background 85 | */ 86 | public static Pix backgroundNormMorph( 87 | Pix pixs, int normReduction, int normSize, int normBgValue) { 88 | if (pixs == null) 89 | throw new IllegalArgumentException("Source pix must be non-null"); 90 | 91 | int nativePix = nativeBackgroundNormMorph( 92 | pixs.mNativePix, normReduction, normSize, normBgValue); 93 | 94 | if (nativePix == 0) 95 | throw new RuntimeException("Failed to normalize image background"); 96 | 97 | return new Pix(nativePix); 98 | } 99 | 100 | // *************** 101 | // * NATIVE CODE * 102 | // *************** 103 | 104 | private static native int nativeBackgroundNormMorph( 105 | int nativePix, int reduction, int size, int bgval); 106 | } 107 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Binarize.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image binarization methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Binarize { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | // Otsu thresholding constants 30 | 31 | /** Desired tile X dimension; actual size may vary */ 32 | public final static int OTSU_SIZE_X = 32; 33 | 34 | /** Desired tile Y dimension; actual size may vary */ 35 | public final static int OTSU_SIZE_Y = 32; 36 | 37 | /** Desired X smoothing value */ 38 | public final static int OTSU_SMOOTH_X = 2; 39 | 40 | /** Desired Y smoothing value */ 41 | public final static int OTSU_SMOOTH_Y = 2; 42 | 43 | /** Fraction of the max Otsu score, typically 0.1 */ 44 | public final static float OTSU_SCORE_FRACTION = 0.1f; 45 | 46 | /** 47 | * Performs locally-adaptive Otsu threshold binarization with default 48 | * parameters. 49 | * 50 | * @param pixs An 8 bpp PIX source image. 51 | * @return A 1 bpp thresholded PIX image. 52 | */ 53 | public static Pix otsuAdaptiveThreshold(Pix pixs) { 54 | return otsuAdaptiveThreshold( 55 | pixs, OTSU_SIZE_X, OTSU_SIZE_Y, OTSU_SMOOTH_X, OTSU_SMOOTH_Y, OTSU_SCORE_FRACTION); 56 | } 57 | 58 | /** 59 | * Performs locally-adaptive Otsu threshold binarization. 60 | *

61 | * Notes: 62 | *

    63 | *
  1. The Otsu method finds a single global threshold for an image. This 64 | * function allows a locally adapted threshold to be found for each tile 65 | * into which the image is broken up. 66 | *
  2. The array of threshold values, one for each tile, constitutes a 67 | * highly downscaled image. This array is optionally smoothed using a 68 | * convolution. The full width and height of the convolution kernel are (2 * 69 | * smoothX + 1) and (2 * smoothY + 1). 70 | *
  3. The minimum tile dimension allowed is 16. If such small tiles are 71 | * used, it is recommended to use smoothing, because without smoothing, each 72 | * small tile determines the splitting threshold independently. A tile that 73 | * is entirely in the image bg will then hallucinate fg, resulting in a very 74 | * noisy binarization. The smoothing should be large enough that no tile is 75 | * only influenced by one type (fg or bg) of pixels, because it will force a 76 | * split of its pixels. 77 | *
  4. To get a single global threshold for the entire image, use input 78 | * values of sizeX and sizeY that are larger than the image. For this 79 | * situation, the smoothing parameters are ignored. 80 | *
  5. The threshold values partition the image pixels into two classes: one 81 | * whose values are less than the threshold and another whose values are 82 | * greater than or equal to the threshold. This is the same use of 83 | * 'threshold' as in pixThresholdToBinary(). 84 | *
  6. The scorefract is the fraction of the maximum Otsu score, which is 85 | * used to determine the range over which the histogram minimum is searched. 86 | * See numaSplitDistribution() for details on the underlying method of 87 | * choosing a threshold. 88 | *
  7. This uses enables a modified version of the Otsu criterion for 89 | * splitting the distribution of pixels in each tile into a fg and bg part. 90 | * The modification consists of searching for a minimum in the histogram 91 | * over a range of pixel values where the Otsu score is within a defined 92 | * fraction, scoreFraction, of the max score. To get the original Otsu 93 | * algorithm, set scoreFraction == 0. 94 | *
95 | * 96 | * @param pixs An 8 bpp PIX source image. 97 | * @param sizeX Desired tile X dimension; actual size may vary. 98 | * @param sizeY Desired tile Y dimension; actual size may vary. 99 | * @param smoothX Half-width of convolution kernel applied to threshold 100 | * array: use 0 for no smoothing. 101 | * @param smoothY Half-height of convolution kernel applied to threshold 102 | * array: use 0 for no smoothing. 103 | * @param scoreFraction Fraction of the max Otsu score; typ. 0.1 (use 0.0 104 | * for standard Otsu). 105 | * @return A 1 bpp thresholded PIX image. 106 | */ 107 | public static Pix otsuAdaptiveThreshold( 108 | Pix pixs, int sizeX, int sizeY, int smoothX, int smoothY, float scoreFraction) { 109 | if (pixs == null) 110 | throw new IllegalArgumentException("Source pix must be non-null"); 111 | if (pixs.getDepth() != 8) 112 | throw new IllegalArgumentException("Source pix depth must be 8bpp"); 113 | 114 | int nativePix = nativeOtsuAdaptiveThreshold( 115 | pixs.mNativePix, sizeX, sizeY, smoothX, smoothY, scoreFraction); 116 | 117 | if (nativePix == 0) 118 | throw new RuntimeException("Failed to perform Otsu adaptive threshold on image"); 119 | 120 | return new Pix(nativePix); 121 | } 122 | 123 | // *************** 124 | // * NATIVE CODE * 125 | // *************** 126 | 127 | private static native int nativeOtsuAdaptiveThreshold( 128 | int nativePix, int sizeX, int sizeY, int smoothX, int smoothY, float scoreFract); 129 | } 130 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Box.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Wrapper for Leptonica's native BOX. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Box { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | /** The index of the X coordinate within the geometry array. */ 30 | public static final int INDEX_X = 0; 31 | 32 | /** The index of the Y coordinate within the geometry array. */ 33 | public static final int INDEX_Y = 1; 34 | 35 | /** The index of the width within the geometry array. */ 36 | public static final int INDEX_W = 2; 37 | 38 | /** The index of the height within the geometry array. */ 39 | public static final int INDEX_H = 3; 40 | 41 | /** 42 | * A pointer to the native Box object. This is used internally by native 43 | * code. 44 | */ 45 | final int mNativeBox; 46 | 47 | private boolean mRecycled = false; 48 | 49 | /** 50 | * Creates a new Box wrapper for the specified native BOX. 51 | * 52 | * @param nativeBox A pointer to the native BOX. 53 | */ 54 | Box(int nativeBox) { 55 | mNativeBox = nativeBox; 56 | mRecycled = false; 57 | } 58 | 59 | /** 60 | * Creates a box with the specified geometry. All dimensions should be 61 | * non-negative and specified in pixels. 62 | * 63 | * @param x X-coordinate of the top-left corner of the box. 64 | * @param y Y-coordinate of the top-left corner of the box. 65 | * @param w Width of the box. 66 | * @param h Height of the box. 67 | */ 68 | public Box(int x, int y, int w, int h) { 69 | if (x < 0 || y < 0 || w < 0 || h < 0) { 70 | throw new IllegalArgumentException("All box dimensions must be non-negative"); 71 | } 72 | 73 | int nativeBox = nativeCreate(x, y, w, h); 74 | 75 | if (nativeBox == 0) { 76 | throw new OutOfMemoryError(); 77 | } 78 | 79 | mNativeBox = nativeBox; 80 | mRecycled = false; 81 | } 82 | 83 | /** 84 | * Returns the box's x-coordinate in pixels. 85 | * 86 | * @return The box's x-coordinate in pixels. 87 | */ 88 | public int getX() { 89 | return nativeGetX(mNativeBox); 90 | } 91 | 92 | /** 93 | * Returns the box's y-coordinate in pixels. 94 | * 95 | * @return The box's y-coordinate in pixels. 96 | */ 97 | public int getY() { 98 | return nativeGetY(mNativeBox); 99 | } 100 | 101 | /** 102 | * Returns the box's width in pixels. 103 | * 104 | * @return The box's width in pixels. 105 | */ 106 | public int getWidth() { 107 | return nativeGetWidth(mNativeBox); 108 | } 109 | 110 | /** 111 | * Returns the box's height in pixels. 112 | * 113 | * @return The box's height in pixels. 114 | */ 115 | public int getHeight() { 116 | return nativeGetHeight(mNativeBox); 117 | } 118 | 119 | /** 120 | * Returns an array containing the coordinates of this box. See INDEX_* 121 | * constants for indices. 122 | * 123 | * @return an array of box oordinates 124 | */ 125 | public int[] getGeometry() { 126 | int[] geometry = new int[4]; 127 | 128 | if (getGeometry(geometry)) { 129 | return geometry; 130 | } 131 | 132 | return null; 133 | } 134 | 135 | /** 136 | * Fills an array containing the coordinates of this box. See INDEX_* 137 | * constants for indices. 138 | * 139 | * @param geometry A 4+ element integer array to fill with coordinates. 140 | * @return true on success 141 | */ 142 | public boolean getGeometry(int[] geometry) { 143 | if (geometry.length < 4) { 144 | throw new IllegalArgumentException("Geometry array must be at least 4 elements long"); 145 | } 146 | 147 | return nativeGetGeometry(mNativeBox, geometry); 148 | } 149 | 150 | /** 151 | * Releases resources and frees any memory associated with this Box. 152 | */ 153 | public void recycle() { 154 | if (!mRecycled) { 155 | nativeDestroy(mNativeBox); 156 | 157 | mRecycled = true; 158 | } 159 | } 160 | 161 | @Override 162 | protected void finalize() throws Throwable { 163 | recycle(); 164 | 165 | super.finalize(); 166 | } 167 | 168 | // *************** 169 | // * NATIVE CODE * 170 | // *************** 171 | 172 | private static native int nativeCreate(int x, int y, int w, int h); 173 | private static native int nativeGetX(int nativeBox); 174 | private static native int nativeGetY(int nativeBox); 175 | private static native int nativeGetWidth(int nativeBox); 176 | private static native int nativeGetHeight(int nativeBox); 177 | private static native void nativeDestroy(int nativeBox); 178 | private static native boolean nativeGetGeometry(int nativeBox, int[] geometry); 179 | } 180 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Leptonica constants. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Constants { 25 | /*-------------------------------------------------------------------------* 26 | * Access and storage flags * 27 | *-------------------------------------------------------------------------*/ 28 | /* 29 | * For Pix, Box, Pta and Numa, there are 3 standard methods for handling the 30 | * retrieval or insertion of a struct: (1) direct insertion (Don't do this 31 | * if there is another handle somewhere to this same struct!) (2) copy 32 | * (Always safe, sets up a refcount of 1 on the new object. Can be 33 | * undesirable if very large, such as an image or an array of images.) (3) 34 | * clone (Makes another handle to the same struct, and bumps the refcount up 35 | * by 1. Safe to do unless you're changing data through one of the handles 36 | * but don't want those changes to be seen by the other handle.) For Pixa 37 | * and Boxa, which are structs that hold an array of clonable structs, there 38 | * is an additional method: (4) copy-clone (Makes a new higher-level struct 39 | * with a refcount of 1, but clones all the structs in the array.) Unlike 40 | * the other structs, when retrieving a string from an Sarray, you are 41 | * allowed to get a handle without a copy or clone (i.e., that you don't 42 | * own!). You must not free or insert such a string! Specifically, for an 43 | * Sarray, the copyflag for retrieval is either: TRUE (or 1 or L_COPY) or 44 | * FALSE (or 0 or L_NOCOPY) For insertion, the copyflag is either: TRUE (or 45 | * 1 or L_COPY) or FALSE (or 0 or L_INSERT) Note that L_COPY is always 1, 46 | * and L_INSERT and L_NOCOPY are always 0. 47 | */ 48 | 49 | /* Stuff it in; no copy, clone or copy-clone */ 50 | public static final int L_INSERT = 0; 51 | 52 | /* Make/use a copy of the object */ 53 | public static final int L_COPY = 1; 54 | 55 | /* Make/use clone (ref count) of the object */ 56 | public static final int L_CLONE = 2; 57 | 58 | /* 59 | * Make a new object and fill with with clones of each object in the 60 | * array(s) 61 | */ 62 | public static final int L_COPY_CLONE = 3; 63 | 64 | /*--------------------------------------------------------------------------* 65 | * Sort flags * 66 | *--------------------------------------------------------------------------*/ 67 | 68 | /* Sort in increasing order */ 69 | public static final int L_SORT_INCREASING = 1; 70 | 71 | /* Sort in decreasing order */ 72 | public static final int L_SORT_DECREASING = 2; 73 | 74 | /* Sort box or c.c. by horiz location */ 75 | public static final int L_SORT_BY_X = 3; 76 | 77 | /* Sort box or c.c. by vert location */ 78 | public static final int L_SORT_BY_Y = 4; 79 | 80 | /* Sort box or c.c. by width */ 81 | public static final int L_SORT_BY_WIDTH = 5; 82 | 83 | /* Sort box or c.c. by height */ 84 | public static final int L_SORT_BY_HEIGHT = 6; 85 | 86 | /* Sort box or c.c. by min dimension */ 87 | public static final int L_SORT_BY_MIN_DIMENSION = 7; 88 | 89 | /* Sort box or c.c. by max dimension */ 90 | public static final int L_SORT_BY_MAX_DIMENSION = 8; 91 | 92 | /* Sort box or c.c. by perimeter */ 93 | public static final int L_SORT_BY_PERIMETER = 9; 94 | 95 | /* Sort box or c.c. by area */ 96 | public static final int L_SORT_BY_AREA = 10; 97 | 98 | /* Sort box or c.c. by width/height ratio */ 99 | public static final int L_SORT_BY_ASPECT_RATIO = 11; 100 | 101 | /* ------------------ Image file format types -------------- */ 102 | /* 103 | * The IFF_DEFAULT flag is used to write the file out in the same (input) 104 | * file format that the pix was read from. If the pix was not read from 105 | * file, the input format field will be IFF_UNKNOWN and the output file 106 | * format will be chosen to be compressed and lossless; namely, IFF_TIFF_G4 107 | * for d = 1 and IFF_PNG for everything else. IFF_JP2 is for jpeg2000, which 108 | * is not supported in leptonica. 109 | */ 110 | 111 | public static final int IFF_UNKNOWN = 0; 112 | 113 | public static final int IFF_BMP = 1; 114 | 115 | public static final int IFF_JFIF_JPEG = 2; 116 | 117 | public static final int IFF_PNG = 3; 118 | 119 | public static final int IFF_TIFF = 4; 120 | 121 | public static final int IFF_TIFF_PACKBITS = 5; 122 | 123 | public static final int IFF_TIFF_RLE = 6; 124 | 125 | public static final int IFF_TIFF_G3 = 7; 126 | 127 | public static final int IFF_TIFF_G4 = 8; 128 | 129 | public static final int IFF_TIFF_LZW = 9; 130 | 131 | public static final int IFF_TIFF_ZIP = 10; 132 | 133 | public static final int IFF_PNM = 11; 134 | 135 | public static final int IFF_PS = 12; 136 | 137 | public static final int IFF_GIF = 13; 138 | 139 | public static final int IFF_JP2 = 14; 140 | 141 | public static final int IFF_DEFAULT = 15; 142 | 143 | public static final int IFF_SPIX = 16; 144 | } 145 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Convert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image bit-depth conversion methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Convert { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | /** 30 | * Converts an image of any bit depth to 8-bit grayscale. 31 | * 32 | * @param pixs Source pix of any bit-depth. 33 | * @return a new Pix image or null on error 34 | */ 35 | public static Pix convertTo8(Pix pixs) { 36 | if (pixs == null) 37 | throw new IllegalArgumentException("Source pix must be non-null"); 38 | 39 | int nativePix = nativeConvertTo8(pixs.mNativePix); 40 | 41 | if (nativePix == 0) 42 | throw new RuntimeException("Failed to natively convert pix"); 43 | 44 | return new Pix(nativePix); 45 | } 46 | 47 | // *************** 48 | // * NATIVE CODE * 49 | // *************** 50 | 51 | private static native int nativeConvertTo8(int nativePix); 52 | } 53 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Enhance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image sharpening methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Enhance { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | /** 30 | * Performs unsharp masking (edge enhancement). 31 | *

32 | * Notes: 33 | *

    34 | *
  • We use symmetric smoothing filters of odd dimension, typically use 35 | * sizes of 3, 5, 7, etc. The halfwidth parameter for these is 36 | * (size - 1)/2; i.e., 1, 2, 3, etc.
  • 37 | *
  • The fract parameter is typically taken in the range: 0.2 38 | * < fract < 0.7
  • 39 | *
40 | * 41 | * @param halfwidth The half-width of the smoothing filter. 42 | * @param fraction The fraction of edge to be added back into the source 43 | * image. 44 | * @return an edge-enhanced Pix image or copy if no enhancement requested 45 | */ 46 | public static Pix unsharpMasking(Pix pixs, int halfwidth, float fraction) { 47 | if (pixs == null) 48 | throw new IllegalArgumentException("Source pix must be non-null"); 49 | 50 | int nativePix = nativeUnsharpMasking(pixs.mNativePix, halfwidth, fraction); 51 | 52 | if (nativePix == 0) { 53 | throw new OutOfMemoryError(); 54 | } 55 | 56 | return new Pix(nativePix); 57 | } 58 | 59 | // *************** 60 | // * NATIVE CODE * 61 | // *************** 62 | 63 | private static native int nativeUnsharpMasking(int nativePix, int halfwidth, float fract); 64 | } 65 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/JpegIO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.Bitmap.CompressFormat; 21 | 22 | import java.io.ByteArrayOutputStream; 23 | import java.io.IOException; 24 | 25 | /** 26 | * JPEG input and output methods. 27 | * 28 | * @author alanv@google.com (Alan Viverette) 29 | */ 30 | public class JpegIO { 31 | static { 32 | System.loadLibrary("lept"); 33 | } 34 | 35 | /** Default quality is 85%, which is reasonably good. */ 36 | public static final int DEFAULT_QUALITY = 85; 37 | 38 | /** Progressive encoding is disabled by default to increase compatibility. */ 39 | public static final boolean DEFAULT_PROGRESSIVE = false; 40 | 41 | /** 42 | * Returns a compressed JPEG byte representation of this Pix using default 43 | * parameters. 44 | * 45 | * @param pixs 46 | * @return a compressed JPEG byte array representation of the Pix 47 | */ 48 | public static byte[] compressToJpeg(Pix pixs) { 49 | return compressToJpeg(pixs, DEFAULT_QUALITY, DEFAULT_PROGRESSIVE); 50 | } 51 | 52 | /** 53 | * Returns a compressed JPEG byte representation of this Pix. 54 | * 55 | * @param pixs A source pix image. 56 | * @param quality The quality of the compressed image. Valid range is 0-100. 57 | * @param progressive Whether to use progressive compression. 58 | * @return a compressed JPEG byte array representation of the Pix 59 | */ 60 | public static byte[] compressToJpeg(Pix pixs, int quality, boolean progressive) { 61 | if (pixs == null) 62 | throw new IllegalArgumentException("Source pix must be non-null"); 63 | if (quality < 0 || quality > 100) 64 | throw new IllegalArgumentException("Quality must be between 0 and 100 (inclusive)"); 65 | 66 | final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 67 | final Bitmap bmp = WriteFile.writeBitmap(pixs); 68 | bmp.compress(CompressFormat.JPEG, quality, byteStream); 69 | bmp.recycle(); 70 | 71 | final byte[] encodedData = byteStream.toByteArray(); 72 | 73 | try { 74 | byteStream.close(); 75 | } catch (IOException e) { 76 | e.printStackTrace(); 77 | } 78 | 79 | return encodedData; 80 | } 81 | 82 | // *************** 83 | // * NATIVE CODE * 84 | // *************** 85 | 86 | private static native byte[] nativeCompressToJpeg( 87 | int nativePix, int quality, boolean progressive); 88 | } 89 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Pix.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | import android.graphics.Rect; 20 | 21 | /** 22 | * Java representation of a native Leptonica PIX object. 23 | * 24 | * @author alanv@google.com (Alan Viverette) 25 | */ 26 | public class Pix { 27 | static { 28 | System.loadLibrary("lept"); 29 | } 30 | 31 | /** Index of the image width within the dimensions array. */ 32 | public static final int INDEX_W = 0; 33 | 34 | /** Index of the image height within the dimensions array. */ 35 | public static final int INDEX_H = 1; 36 | 37 | /** Index of the image bit-depth within the dimensions array. */ 38 | public static final int INDEX_D = 2; 39 | 40 | /** Package-accessible pointer to native pix. */ 41 | final int mNativePix; 42 | 43 | private boolean mRecycled; 44 | 45 | /** 46 | * Creates a new Pix wrapper for the specified native PIX object. Never call 47 | * this twice on the same native pointer, because finalize() will attempt to 48 | * free native memory twice. 49 | * 50 | * @param nativePix A pointer to the native PIX object. 51 | */ 52 | public Pix(int nativePix) { 53 | mNativePix = nativePix; 54 | mRecycled = false; 55 | } 56 | 57 | public Pix(int width, int height, int depth) { 58 | if (width <= 0 || height <= 0) { 59 | throw new IllegalArgumentException("Pix width and height must be > 0"); 60 | } else if (depth != 1 && depth != 2 && depth != 4 && depth != 8 && depth != 16 61 | && depth != 24 && depth != 32) { 62 | throw new IllegalArgumentException("Depth must be one of 1, 2, 4, 8, 16, or 32"); 63 | } 64 | 65 | mNativePix = nativeCreatePix(width, height, depth); 66 | mRecycled = false; 67 | } 68 | 69 | /** 70 | * Returns a pointer to the native Pix object. This is used by native code 71 | * and is only valid within the same process in which the Pix was created. 72 | * 73 | * @return a native pointer to the Pix object 74 | */ 75 | public int getNativePix() { 76 | return mNativePix; 77 | } 78 | 79 | /** 80 | * Return the raw bytes of the native PIX object. You can reconstruct the 81 | * Pix from this data using createFromPix(). 82 | * 83 | * @return a copy of this PIX object's raw data 84 | */ 85 | public byte[] getData() { 86 | int size = nativeGetDataSize(mNativePix); 87 | 88 | byte[] buffer = new byte[size]; 89 | 90 | if (!nativeGetData(mNativePix, buffer)) { 91 | throw new RuntimeException("native getData failed"); 92 | } 93 | 94 | return buffer; 95 | } 96 | 97 | /** 98 | * Returns an array of this image's dimensions. See Pix.INDEX_* for indices. 99 | * 100 | * @return an array of this image's dimensions or null on 101 | * failure 102 | */ 103 | public int[] getDimensions() { 104 | int[] dimensions = new int[4]; 105 | 106 | if (getDimensions(dimensions)) { 107 | return dimensions; 108 | } 109 | 110 | return null; 111 | } 112 | 113 | /** 114 | * Fills an array with this image's dimensions. The array must be at least 3 115 | * elements long. 116 | * 117 | * @param dimensions An integer array with at least three elements. 118 | * @return true on success 119 | */ 120 | public boolean getDimensions(int[] dimensions) { 121 | return nativeGetDimensions(mNativePix, dimensions); 122 | } 123 | 124 | /** 125 | * Returns a clone of this Pix. This does NOT create a separate copy, just a 126 | * new pointer that can be recycled without affecting other clones. 127 | * 128 | * @return a clone (shallow copy) of the Pix 129 | */ 130 | @Override 131 | public Pix clone() { 132 | int nativePix = nativeClone(mNativePix); 133 | 134 | if (nativePix == 0) { 135 | throw new OutOfMemoryError(); 136 | } 137 | 138 | return new Pix(nativePix); 139 | } 140 | 141 | /** 142 | * Returns a deep copy of this Pix that can be modified without affecting 143 | * the original Pix. 144 | * 145 | * @return a copy of the Pix 146 | */ 147 | public Pix copy() { 148 | int nativePix = nativeCopy(mNativePix); 149 | 150 | if (nativePix == 0) { 151 | throw new OutOfMemoryError(); 152 | } 153 | 154 | return new Pix(nativePix); 155 | } 156 | 157 | /** 158 | * Inverts this Pix in-place. 159 | * 160 | * @return true on success 161 | */ 162 | public boolean invert() { 163 | return nativeInvert(mNativePix); 164 | } 165 | 166 | /** 167 | * Releases resources and frees any memory associated with this Pix. You may 168 | * not modify or access the pix after calling this method. 169 | */ 170 | public void recycle() { 171 | if (!mRecycled) { 172 | nativeDestroy(mNativePix); 173 | 174 | mRecycled = true; 175 | } 176 | } 177 | 178 | @Override 179 | protected void finalize() throws Throwable { 180 | recycle(); 181 | 182 | super.finalize(); 183 | } 184 | 185 | /** 186 | * Creates a new Pix from raw Pix data obtained from getData(). 187 | * 188 | * @param pixData Raw pix data obtained from getData(). 189 | * @param width The width of the original Pix. 190 | * @param height The height of the original Pix. 191 | * @param depth The bit-depth of the original Pix. 192 | * @return a new Pix or null on error 193 | */ 194 | public static Pix createFromPix(byte[] pixData, int width, int height, int depth) { 195 | int nativePix = nativeCreateFromData(pixData, width, height, depth); 196 | 197 | if (nativePix == 0) { 198 | throw new OutOfMemoryError(); 199 | } 200 | 201 | return new Pix(nativePix); 202 | } 203 | 204 | /** 205 | * Returns a Rect with the width and height of this Pix. 206 | * 207 | * @return a Rect with the width and height of this Pix 208 | */ 209 | public Rect getRect() { 210 | int w = getWidth(); 211 | int h = getHeight(); 212 | 213 | return new Rect(0, 0, w, h); 214 | } 215 | 216 | /** 217 | * Returns the width of this Pix. 218 | * 219 | * @return the width of this Pix 220 | */ 221 | public int getWidth() { 222 | return nativeGetWidth(mNativePix); 223 | } 224 | 225 | /** 226 | * Returns the height of this Pix. 227 | * 228 | * @return the height of this Pix 229 | */ 230 | public int getHeight() { 231 | return nativeGetHeight(mNativePix); 232 | } 233 | 234 | /** 235 | * Returns the depth of this Pix. 236 | * 237 | * @return the depth of this Pix 238 | */ 239 | public int getDepth() { 240 | return nativeGetDepth(mNativePix); 241 | } 242 | 243 | /** 244 | * Returns the {@link android.graphics.Color} at the specified location. 245 | * 246 | * @param x The x coordinate (0...width-1) of the pixel to return. 247 | * @param y The y coordinate (0...height-1) of the pixel to return. 248 | * @return The argb {@link android.graphics.Color} at the specified 249 | * coordinate. 250 | * @throws IllegalArgumentException If x, y exceeds the image bounds. 251 | */ 252 | public int getPixel(int x, int y) { 253 | if (x < 0 || x >= getWidth()) { 254 | throw new IllegalArgumentException("Supplied x coordinate exceeds image bounds"); 255 | } else if (y < 0 || y >= getHeight()) { 256 | throw new IllegalArgumentException("Supplied x coordinate exceeds image bounds"); 257 | } 258 | 259 | return nativeGetPixel(mNativePix, x, y); 260 | } 261 | 262 | /** 263 | * Sets the {@link android.graphics.Color} at the specified location. 264 | * 265 | * @param x The x coordinate (0...width-1) of the pixel to set. 266 | * @param y The y coordinate (0...height-1) of the pixel to set. 267 | * @param color The argb {@link android.graphics.Color} to set at the 268 | * specified coordinate. 269 | * @throws IllegalArgumentException If x, y exceeds the image bounds. 270 | */ 271 | public void setPixel(int x, int y, int color) { 272 | if (x < 0 || x >= getWidth()) { 273 | throw new IllegalArgumentException("Supplied x coordinate exceeds image bounds"); 274 | } else if (y < 0 || y >= getHeight()) { 275 | throw new IllegalArgumentException("Supplied x coordinate exceeds image bounds"); 276 | } 277 | 278 | nativeSetPixel(mNativePix, x, y, color); 279 | } 280 | 281 | // *************** 282 | // * NATIVE CODE * 283 | // *************** 284 | 285 | private static native int nativeCreatePix(int w, int h, int d); 286 | private static native int nativeCreateFromData(byte[] data, int w, int h, int d); 287 | private static native boolean nativeGetData(int nativePix, byte[] data); 288 | private static native int nativeGetDataSize(int nativePix); 289 | private static native int nativeClone(int nativePix); 290 | private static native int nativeCopy(int nativePix); 291 | private static native boolean nativeInvert(int nativePix); 292 | private static native void nativeDestroy(int nativePix); 293 | private static native boolean nativeGetDimensions(int nativePix, int[] dimensions); 294 | private static native int nativeGetWidth(int nativePix); 295 | private static native int nativeGetHeight(int nativePix); 296 | private static native int nativeGetDepth(int nativePix); 297 | private static native int nativeGetPixel(int nativePix, int x, int y); 298 | private static native void nativeSetPixel(int nativePix, int x, int y, int color); 299 | } 300 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/ReadFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | 22 | import java.io.File; 23 | 24 | /** 25 | * Image input and output methods. 26 | * 27 | * @author alanv@google.com (Alan Viverette) 28 | */ 29 | public class ReadFile { 30 | static { 31 | System.loadLibrary("lept"); 32 | } 33 | 34 | /** 35 | * Creates a 32bpp Pix object from encoded data. Supported formats are BMP 36 | * and JPEG. 37 | * 38 | * @param encodedData JPEG or BMP encoded byte data. 39 | * @return a 32bpp Pix object 40 | */ 41 | public static Pix readMem(byte[] encodedData) { 42 | if (encodedData == null) 43 | throw new IllegalArgumentException("Image data byte array must be non-null"); 44 | 45 | final BitmapFactory.Options opts = new BitmapFactory.Options(); 46 | opts.inPreferredConfig = Bitmap.Config.ARGB_8888; 47 | 48 | final Bitmap bmp = BitmapFactory.decodeByteArray(encodedData, 0, encodedData.length, 49 | opts); 50 | final Pix pix = readBitmap(bmp); 51 | 52 | bmp.recycle(); 53 | 54 | return pix; 55 | } 56 | 57 | /** 58 | * Creates an 8bpp Pix object from raw 8bpp grayscale pixels. 59 | * 60 | * @param pixelData 8bpp grayscale pixel data. 61 | * @param width The width of the input image. 62 | * @param height The height of the input image. 63 | * @return an 8bpp Pix object 64 | */ 65 | public static Pix readBytes8(byte[] pixelData, int width, int height) { 66 | if (pixelData == null) 67 | throw new IllegalArgumentException("Byte array must be non-null"); 68 | if (width <= 0) 69 | throw new IllegalArgumentException("Image width must be greater than 0"); 70 | if (height <= 0) 71 | throw new IllegalArgumentException("Image height must be greater than 0"); 72 | if (pixelData.length < width * height) 73 | throw new IllegalArgumentException("Array length does not match dimensions"); 74 | 75 | int nativePix = nativeReadBytes8(pixelData, width, height); 76 | 77 | if (nativePix == 0) 78 | throw new RuntimeException("Failed to read pix from memory"); 79 | 80 | return new Pix(nativePix); 81 | } 82 | 83 | /** 84 | * Replaces the bytes in an 8bpp Pix object with raw grayscale 8bpp pixels. 85 | * Width and height be identical to the input Pix. 86 | * 87 | * @param pixs The Pix whose bytes will be replaced. 88 | * @param pixelData 8bpp grayscale pixel data. 89 | * @param width The width of the input image. 90 | * @param height The height of the input image. 91 | * @return an 8bpp Pix object 92 | */ 93 | public static boolean replaceBytes8(Pix pixs, byte[] pixelData, int width, int height) { 94 | if (pixs == null) 95 | throw new IllegalArgumentException("Source pix must be non-null"); 96 | if (pixelData == null) 97 | throw new IllegalArgumentException("Byte array must be non-null"); 98 | if (width <= 0) 99 | throw new IllegalArgumentException("Image width must be greater than 0"); 100 | if (height <= 0) 101 | throw new IllegalArgumentException("Image height must be greater than 0"); 102 | if (pixelData.length < width * height) 103 | throw new IllegalArgumentException("Array length does not match dimensions"); 104 | if (pixs.getWidth() != width) 105 | throw new IllegalArgumentException("Source pix width does not match image width"); 106 | if (pixs.getHeight() != height) 107 | throw new IllegalArgumentException("Source pix width does not match image width"); 108 | 109 | return nativeReplaceBytes8(pixs.mNativePix, pixelData, width, height); 110 | } 111 | 112 | /** 113 | * Creates a Pixa object from encoded files in a directory. Supported 114 | * formats are BMP and JPEG. 115 | * 116 | * @param dir The directory containing the files. 117 | * @param prefix The prefix of the files to load into a Pixa. 118 | * @return a Pixa object containing one Pix for each file 119 | */ 120 | public static Pixa readFiles(File dir, String prefix) { 121 | if (dir == null) 122 | throw new IllegalArgumentException("Directory must be non-null"); 123 | if (!dir.exists()) 124 | throw new IllegalArgumentException("Directory does not exist"); 125 | if (!dir.canRead()) 126 | throw new IllegalArgumentException("Cannot read directory"); 127 | 128 | // TODO: Remove or fix this. 129 | throw new RuntimeException("readFiles() is not current supported"); 130 | } 131 | 132 | /** 133 | * Creates a Pix object from encoded file data. Supported formats are BMP 134 | * and JPEG. 135 | * 136 | * @param file The JPEG or BMP-encoded file to read in as a Pix. 137 | * @return a Pix object 138 | */ 139 | public static Pix readFile(File file) { 140 | if (file == null) 141 | throw new IllegalArgumentException("File must be non-null"); 142 | if (!file.exists()) 143 | throw new IllegalArgumentException("File does not exist"); 144 | if (!file.canRead()) 145 | throw new IllegalArgumentException("Cannot read file"); 146 | 147 | final BitmapFactory.Options opts = new BitmapFactory.Options(); 148 | opts.inPreferredConfig = Bitmap.Config.ARGB_8888; 149 | 150 | final Bitmap bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), opts); 151 | final Pix pix = readBitmap(bmp); 152 | 153 | bmp.recycle(); 154 | 155 | return pix; 156 | } 157 | 158 | /** 159 | * Creates a Pix object from Bitmap data. Currently supports only 160 | * ARGB_8888-formatted bitmaps. 161 | * 162 | * @param bmp The Bitmap object to convert to a Pix. 163 | * @return a Pix object 164 | */ 165 | public static Pix readBitmap(Bitmap bmp) { 166 | if (bmp == null) 167 | throw new IllegalArgumentException("Bitmap must be non-null"); 168 | if (bmp.getConfig() != Bitmap.Config.ARGB_8888) 169 | throw new IllegalArgumentException("Bitmap config must be ARGB_8888"); 170 | 171 | int nativePix = nativeReadBitmap(bmp); 172 | 173 | if (nativePix == 0) 174 | throw new RuntimeException("Failed to read pix from bitmap"); 175 | 176 | return new Pix(nativePix); 177 | } 178 | 179 | // *************** 180 | // * NATIVE CODE * 181 | // *************** 182 | 183 | private static native int nativeReadMem(byte[] data, int size); 184 | 185 | private static native int nativeReadBytes8(byte[] data, int w, int h); 186 | 187 | private static native boolean nativeReplaceBytes8(int nativePix, byte[] data, int w, int h); 188 | 189 | private static native int nativeReadFiles(String dirname, String prefix); 190 | 191 | private static native int nativeReadFile(String filename); 192 | 193 | private static native int nativeReadBitmap(Bitmap bitmap); 194 | } 195 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Rotate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * @author alanv@google.com (Alan Viverette) 21 | */ 22 | public class Rotate { 23 | static { 24 | System.loadLibrary("lept"); 25 | } 26 | 27 | // Rotation default 28 | 29 | /** Default rotation quality is high. */ 30 | public static final boolean ROTATE_QUALITY = true; 31 | 32 | /** 33 | * Performs rotation using the default parameters. 34 | * 35 | * @param pixs The source pix. 36 | * @param degrees The number of degrees to rotate; clockwise is positive. 37 | * @return the rotated source image 38 | */ 39 | public static Pix rotate(Pix pixs, float degrees) { 40 | return rotate(pixs, degrees, false); 41 | } 42 | 43 | /** 44 | * Performs rotation with resizing using the default parameters. 45 | * 46 | * @param pixs The source pix. 47 | * @param degrees The number of degrees to rotate; clockwise is positive. 48 | * @param quality Whether to use high-quality rotation. 49 | * @return the rotated source image 50 | */ 51 | public static Pix rotate(Pix pixs, float degrees, boolean quality) { 52 | return rotate(pixs, degrees, quality, true); 53 | } 54 | 55 | /** 56 | * Performs basic image rotation about the center. 57 | *

58 | * Notes: 59 | *

    60 | *
  1. Rotation is about the center of the image. 61 | *
  2. For very small rotations, just return a clone. 62 | *
  3. Rotation brings either white or black pixels in from outside the 63 | * image. 64 | *
  4. Above 20 degrees, if rotation by shear is requested, we rotate by 65 | * sampling. 66 | *
  5. Colormaps are removed for rotation by area map and shear. 67 | *
  6. The dest can be expanded so that no image pixels are lost. To invoke 68 | * expansion, input the original width and height. For repeated rotation, 69 | * use of the original width and height allows the expansion to stop at the 70 | * maximum required size, which is a square with side = sqrt(w*w + h*h). 71 | *
72 | * 73 | * @param pixs The source pix. 74 | * @param degrees The number of degrees to rotate; clockwise is positive. 75 | * @param quality Whether to use high-quality rotation. 76 | * @param resize Whether to expand the output so that no pixels are lost. 77 | * Note: 1bpp images are always resized when 78 | * quality is {@code true}. 79 | * @return the rotated source image 80 | */ 81 | public static Pix rotate(Pix pixs, float degrees, boolean quality, boolean resize) { 82 | if (pixs == null) 83 | throw new IllegalArgumentException("Source pix must be non-null"); 84 | 85 | int nativePix = nativeRotate(pixs.mNativePix, degrees, quality, resize); 86 | 87 | if (nativePix == 0) 88 | return null; 89 | 90 | return new Pix(nativePix); 91 | } 92 | 93 | // *************** 94 | // * NATIVE CODE * 95 | // *************** 96 | 97 | private static native int nativeRotate(int nativePix, float degrees, boolean quality, 98 | boolean resize); 99 | } 100 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Scale.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image scaling methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Scale { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | public enum ScaleType { 30 | /* Scale in X and Y independently, so that src matches dst exactly. */ 31 | FILL, 32 | 33 | /* 34 | * Compute a scale that will maintain the original src aspect ratio, but 35 | * will also ensure that src fits entirely inside dst. May shrink or 36 | * expand src to fit dst. 37 | */ 38 | FIT, 39 | 40 | /* 41 | * Compute a scale that will maintain the original src aspect ratio, but 42 | * will also ensure that src fits entirely inside dst. May shrink src to 43 | * fit dst, but will not expand it. 44 | */ 45 | FIT_SHRINK, 46 | } 47 | 48 | /** 49 | * Scales the Pix to a specified width and height using a specified scaling 50 | * type (fill, stretch, etc.). Returns a scaled image or a clone of the Pix 51 | * if no scaling is required. 52 | * 53 | * @param pixs 54 | * @param width 55 | * @param height 56 | * @param type 57 | * @return a scaled image or a clone of the Pix if no scaling is required 58 | */ 59 | public static Pix scaleToSize(Pix pixs, int width, int height, ScaleType type) { 60 | if (pixs == null) 61 | throw new IllegalArgumentException("Source pix must be non-null"); 62 | 63 | int pixWidth = pixs.getWidth(); 64 | int pixHeight = pixs.getHeight(); 65 | 66 | float scaleX = width / (float) pixWidth; 67 | float scaleY = height / (float) pixHeight; 68 | 69 | switch (type) { 70 | case FILL: 71 | // Retains default scaleX and scaleY values 72 | break; 73 | case FIT: 74 | scaleX = Math.min(scaleX, scaleY); 75 | scaleY = scaleX; 76 | break; 77 | case FIT_SHRINK: 78 | scaleX = Math.min(1.0f, Math.min(scaleX, scaleY)); 79 | scaleY = scaleX; 80 | break; 81 | } 82 | 83 | return scale(pixs, scaleX, scaleY); 84 | } 85 | 86 | /** 87 | * Scales the Pix to specified scale. If no scaling is required, returns a 88 | * clone of the source Pix. 89 | * 90 | * @param pixs the source Pix 91 | * @param scale dimension scaling factor 92 | * @return a Pix scaled according to the supplied factors 93 | */ 94 | public static Pix scale(Pix pixs, float scale) { 95 | return scale(pixs, scale, scale); 96 | } 97 | 98 | /** 99 | * Scales the Pix to specified x and y scale. If no scaling is required, 100 | * returns a clone of the source Pix. 101 | * 102 | * @param pixs the source Pix 103 | * @param scaleX x-dimension (width) scaling factor 104 | * @param scaleY y-dimension (height) scaling factor 105 | * @return a Pix scaled according to the supplied factors 106 | */ 107 | public static Pix scale(Pix pixs, float scaleX, float scaleY) { 108 | if (pixs == null) 109 | throw new IllegalArgumentException("Source pix must be non-null"); 110 | if (scaleX <= 0.0f) 111 | throw new IllegalArgumentException("X scaling factor must be positive"); 112 | if (scaleY <= 0.0f) 113 | throw new IllegalArgumentException("Y scaling factor must be positive"); 114 | 115 | int nativePix = nativeScale(pixs.mNativePix, scaleX, scaleY); 116 | 117 | if (nativePix == 0) 118 | throw new RuntimeException("Failed to natively scale pix"); 119 | 120 | return new Pix(nativePix); 121 | } 122 | 123 | // *************** 124 | // * NATIVE CODE * 125 | // *************** 126 | 127 | private static native int nativeScale(int nativePix, float scaleX, float scaleY); 128 | } 129 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/Skew.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | /** 20 | * Image rotation and skew detection methods. 21 | * 22 | * @author alanv@google.com (Alan Viverette) 23 | */ 24 | public class Skew { 25 | static { 26 | System.loadLibrary("lept"); 27 | } 28 | 29 | // Text alignment defaults 30 | 31 | /** Default range for sweep, will detect rotation of + or - 30 degrees. */ 32 | public final static float SWEEP_RANGE = 30.0f; 33 | 34 | /** Default sweep delta, reasonably accurate within 0.05 degrees. */ 35 | public final static float SWEEP_DELTA = 5.0f; 36 | 37 | /** Default sweep reduction, one-eighth the size of the original image. */ 38 | public final static int SWEEP_REDUCTION = 8; 39 | 40 | /** Default sweep reduction, one-fourth the size of the original image. */ 41 | public final static int SEARCH_REDUCTION = 4; 42 | 43 | /** Default search minimum delta, reasonably accurate within 0.05 degrees. */ 44 | public final static float SEARCH_MIN_DELTA = 0.01f; 45 | 46 | /** 47 | * Finds and returns the skew angle using default parameters. 48 | * 49 | * @param pixs Input pix (1 bpp). 50 | * @return the detected skew angle, or 0.0 on failure 51 | */ 52 | public static float findSkew(Pix pixs) { 53 | return findSkew(pixs, SWEEP_RANGE, SWEEP_DELTA, SWEEP_REDUCTION, SEARCH_REDUCTION, 54 | SEARCH_MIN_DELTA); 55 | } 56 | 57 | /** 58 | * Finds and returns the skew angle, doing first a sweep through a set of 59 | * equal angles, and then doing a binary search until convergence. 60 | *

61 | * Notes: 62 | *

    63 | *
  1. In computing the differential line sum variance score, we sum the 64 | * result over scanlines, but we always skip: 65 | *
      66 | *
    • at least one scanline 67 | *
    • not more than 10% of the image height 68 | *
    • not more than 5% of the image width 69 | *
    70 | *
71 | * 72 | * @param pixs Input pix (1 bpp). 73 | * @param sweepRange Half the full search range, assumed about 0; in 74 | * degrees. 75 | * @param sweepDelta Angle increment of sweep; in degrees. 76 | * @param sweepReduction Sweep reduction factor = 1, 2, 4 or 8. 77 | * @param searchReduction Binary search reduction factor = 1, 2, 4 or 8; and 78 | * must not exceed redsweep. 79 | * @param searchMinDelta Minimum binary search increment angle; in degrees. 80 | * @return the detected skew angle, or 0.0 on failure 81 | */ 82 | public static float findSkew(Pix pixs, float sweepRange, float sweepDelta, int sweepReduction, 83 | int searchReduction, float searchMinDelta) { 84 | if (pixs == null) 85 | throw new IllegalArgumentException("Source pix must be non-null"); 86 | 87 | return nativeFindSkew(pixs.mNativePix, sweepRange, sweepDelta, sweepReduction, 88 | searchReduction, searchMinDelta); 89 | } 90 | 91 | // *************** 92 | // * NATIVE CODE * 93 | // *************** 94 | 95 | private static native float nativeFindSkew(int nativePix, float sweepRange, float sweepDelta, 96 | int sweepReduction, int searchReduction, float searchMinDelta); 97 | 98 | } 99 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/leptonica/android/WriteFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.leptonica.android; 18 | 19 | import android.graphics.Bitmap; 20 | 21 | import java.io.File; 22 | 23 | /** 24 | * @author alanv@google.com (Alan Viverette) 25 | */ 26 | public class WriteFile { 27 | static { 28 | System.loadLibrary("lept"); 29 | } 30 | 31 | /* Default JPEG quality */ 32 | public static final int DEFAULT_QUALITY = 85; 33 | 34 | /* Default JPEG progressive encoding */ 35 | public static final boolean DEFAULT_PROGRESSIVE = true; 36 | 37 | /** 38 | * Write an 8bpp Pix to a flat byte array. 39 | * 40 | * @param pixs The 8bpp source image. 41 | * @return a byte array where each byte represents a single 8-bit pixel 42 | */ 43 | public static byte[] writeBytes8(Pix pixs) { 44 | if (pixs == null) 45 | throw new IllegalArgumentException("Source pix must be non-null"); 46 | 47 | int size = pixs.getWidth() * pixs.getHeight(); 48 | 49 | if (pixs.getDepth() != 8) { 50 | Pix pix8 = Convert.convertTo8(pixs); 51 | pixs.recycle(); 52 | pixs = pix8; 53 | } 54 | 55 | byte[] data = new byte[size]; 56 | 57 | writeBytes8(pixs, data); 58 | 59 | return data; 60 | } 61 | 62 | /** 63 | * Write an 8bpp Pix to a flat byte array. 64 | * 65 | * @param pixs The 8bpp source image. 66 | * @param data A byte array large enough to hold the pixels of pixs. 67 | * @return the number of bytes written to data 68 | */ 69 | public static int writeBytes8(Pix pixs, byte[] data) { 70 | if (pixs == null) 71 | throw new IllegalArgumentException("Source pix must be non-null"); 72 | 73 | int size = pixs.getWidth() * pixs.getHeight(); 74 | 75 | if (data.length < size) 76 | throw new IllegalArgumentException("Data array must be large enough to hold image bytes"); 77 | 78 | int bytesWritten = nativeWriteBytes8(pixs.mNativePix, data); 79 | 80 | return bytesWritten; 81 | } 82 | 83 | /** 84 | * Writes all the images in a Pixa array to individual files using the 85 | * specified format. The output file extension will be determined by the 86 | * format. 87 | *

88 | * Output file names will take the format /. 89 | * 90 | * @param pixas The source Pixa image array. 91 | * @param path The output directory. 92 | * @param prefix The prefix to give output files. 93 | * @param format The format to use for output files. 94 | * @return true on success 95 | */ 96 | public static boolean writeFiles(Pixa pixas, File path, String prefix, int format) { 97 | if (pixas == null) 98 | throw new IllegalArgumentException("Source pixa must be non-null"); 99 | if (path == null) 100 | throw new IllegalArgumentException("Destination path non-null"); 101 | if (prefix == null) 102 | throw new IllegalArgumentException("Filename prefix must be non-null"); 103 | 104 | throw new RuntimeException("writeFiles() is not currently supported"); 105 | } 106 | 107 | /** 108 | * Write a Pix to a byte array using the specified encoding from 109 | * Constants.IFF_*. 110 | * 111 | * @param pixs The source image. 112 | * @param format A format from Constants.IFF_*. 113 | * @return a byte array containing encoded bytes 114 | */ 115 | public static byte[] writeMem(Pix pixs, int format) { 116 | if (pixs == null) 117 | throw new IllegalArgumentException("Source pix must be non-null"); 118 | 119 | return nativeWriteMem(pixs.mNativePix, format); 120 | } 121 | 122 | /** 123 | * Writes a Pix to file using the file extension as the output format; 124 | * supported formats are .jpg or .jpeg for JPEG and .bmp for bitmap. 125 | *

126 | * Uses default quality and progressive encoding settings. 127 | * 128 | * @param pixs Source image. 129 | * @param file The file to write. 130 | * @return true on success 131 | */ 132 | public static boolean writeImpliedFormat(Pix pixs, File file) { 133 | return writeImpliedFormat(pixs, file, DEFAULT_QUALITY, DEFAULT_PROGRESSIVE); 134 | } 135 | 136 | /** 137 | * Writes a Pix to file using the file extension as the output format; 138 | * supported formats are .jpg or .jpeg for JPEG and .bmp for bitmap. 139 | *

140 | * Notes: 141 | *

    142 | *
  1. This determines the output format from the filename extension. 143 | *
  2. The last two args are ignored except for requests for jpeg files. 144 | *
  3. The jpeg default quality is 75. 145 | *
146 | * 147 | * @param pixs Source image. 148 | * @param file The file to write. 149 | * @param quality (Only for lossy formats) Quality between 1 - 100, 0 for 150 | * default. 151 | * @param progressive (Only for JPEG) Whether to encode as progressive. 152 | * @return true on success 153 | */ 154 | public static boolean writeImpliedFormat( 155 | Pix pixs, File file, int quality, boolean progressive) { 156 | if (pixs == null) 157 | throw new IllegalArgumentException("Source pix must be non-null"); 158 | if (file == null) 159 | throw new IllegalArgumentException("File must be non-null"); 160 | 161 | return nativeWriteImpliedFormat( 162 | pixs.mNativePix, file.getAbsolutePath(), quality, progressive); 163 | } 164 | 165 | /** 166 | * Writes a Pix to an Android Bitmap object. The output Bitmap will always 167 | * be in ARGB_8888 format, but the input Pixs may be any bit-depth. 168 | * 169 | * @param pixs The source image. 170 | * @return a Bitmap containing a copy of the source image, or null 171 | * on failure 172 | */ 173 | public static Bitmap writeBitmap(Pix pixs) { 174 | if (pixs == null) 175 | throw new IllegalArgumentException("Source pix must be non-null"); 176 | 177 | final int[] dimensions = pixs.getDimensions(); 178 | final int width = dimensions[Pix.INDEX_W]; 179 | final int height = dimensions[Pix.INDEX_H]; 180 | //final int depth = dimensions[Pix.INDEX_D]; 181 | 182 | final Bitmap.Config config = Bitmap.Config.ARGB_8888; 183 | final Bitmap bitmap = Bitmap.createBitmap(width, height, config); 184 | 185 | if (nativeWriteBitmap(pixs.mNativePix, bitmap)) { 186 | return bitmap; 187 | } 188 | 189 | bitmap.recycle(); 190 | 191 | return null; 192 | } 193 | 194 | // *************** 195 | // * NATIVE CODE * 196 | // *************** 197 | 198 | private static native int nativeWriteBytes8(int nativePix, byte[] data); 199 | 200 | private static native boolean nativeWriteFiles(int nativePix, String rootname, int format); 201 | 202 | private static native byte[] nativeWriteMem(int nativePix, int format); 203 | 204 | private static native boolean nativeWriteImpliedFormat( 205 | int nativePix, String fileName, int quality, boolean progressive); 206 | 207 | private static native boolean nativeWriteBitmap(int nativePix, Bitmap bitmap); 208 | } 209 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/tesseract/android/PageIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.tesseract.android; 18 | 19 | import com.googlecode.tesseract.android.TessBaseAPI.PageIteratorLevel; 20 | 21 | public class PageIterator { 22 | static { 23 | System.loadLibrary("lept"); 24 | System.loadLibrary("tess"); 25 | } 26 | 27 | /** Pointer to native page iterator. */ 28 | private final int mNativePageIterator; 29 | 30 | /* package */PageIterator(int nativePageIterator) { 31 | mNativePageIterator = nativePageIterator; 32 | } 33 | 34 | /** 35 | * Resets the iterator to point to the start of the page. 36 | */ 37 | public void begin() { 38 | nativeBegin(mNativePageIterator); 39 | } 40 | 41 | /** 42 | * Moves to the start of the next object at the given level in the page 43 | * hierarchy, and returns false if the end of the page was reached. 44 | *

45 | * NOTE that {@link PageIteratorLevel#RIL_SYMBOL} will skip non-text blocks, 46 | * but all other {@link PageIteratorLevel} level values will visit each 47 | * non-text block once. Think of non text blocks as containing a single 48 | * para, with a single line, with a single imaginary word. 49 | *

50 | * Calls to {@link #next} with different levels may be freely intermixed. 51 | *

52 | * This function iterates words in right-to-left scripts correctly, if the 53 | * appropriate language has been loaded into Tesseract. 54 | * 55 | * @param level the page iterator level. See {@link PageIteratorLevel}. 56 | * @return {@code false} if the end of the page was reached, {@code true} 57 | * otherwise. 58 | */ 59 | public boolean next(int level) { 60 | return nativeNext(mNativePageIterator, level); 61 | } 62 | 63 | private static native void nativeBegin(int nativeIterator); 64 | private static native boolean nativeNext(int nativeIterator, int level); 65 | } 66 | -------------------------------------------------------------------------------- /tesseract-android-tools/src/com/googlecode/tesseract/android/ResultIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.googlecode.tesseract.android; 18 | 19 | import com.googlecode.tesseract.android.TessBaseAPI.PageIteratorLevel; 20 | 21 | /** 22 | * Java interface for the ResultIterator. Does not implement all available JNI 23 | * methods, but does implement enough to be useful. Comments are adapted from 24 | * original Tesseract source. 25 | * 26 | * @author alanv@google.com (Alan Viverette) 27 | */ 28 | public class ResultIterator extends PageIterator { 29 | static { 30 | System.loadLibrary("lept"); 31 | System.loadLibrary("tess"); 32 | } 33 | 34 | /** Pointer to native result iterator. */ 35 | private final int mNativeResultIterator; 36 | 37 | /* package */ResultIterator(int nativeResultIterator) { 38 | super(nativeResultIterator); 39 | 40 | mNativeResultIterator = nativeResultIterator; 41 | } 42 | 43 | /** 44 | * Returns the text string for the current object at the given level. 45 | * 46 | * @param level the page iterator level. See {@link PageIteratorLevel}. 47 | * @return the text string for the current object at the given level. 48 | */ 49 | public String getUTF8Text(int level) { 50 | return nativeGetUTF8Text(mNativeResultIterator, level); 51 | } 52 | 53 | /** 54 | * Returns the mean confidence of the current object at the given level. The 55 | * number should be interpreted as a percent probability (0-100). 56 | * 57 | * @param level the page iterator level. See {@link PageIteratorLevel}. 58 | * @return the mean confidence of the current object at the given level. 59 | */ 60 | public float confidence(int level) { 61 | return nativeConfidence(mNativeResultIterator, level); 62 | } 63 | 64 | private static native String nativeGetUTF8Text(int nativeResultIterator, int level); 65 | private static native float nativeConfidence(int nativeResultIterator, int level); 66 | } 67 | --------------------------------------------------------------------------------