@@ -0,0 +1,13 @@
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.googlecode.tesseract.android;

public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.googlecode.tesseract.android";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "";
}
@@ -0,0 +1,13 @@
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.googlecode.tesseract.android;

public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String APPLICATION_ID = "com.googlecode.tesseract.android";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "";
}
Binary file not shown.
@@ -0,0 +1,6 @@
LOCAL_PATH := $(call my-dir)
TESSERACT_PATH := $(LOCAL_PATH)/com_googlecode_tesseract_android/src
LEPTONICA_PATH := $(LOCAL_PATH)/com_googlecode_leptonica_android/src

# Just build the Android.mk files in the subdirs
include $(call all-subdir-makefiles)
@@ -0,0 +1,6 @@
APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a x86 mips # arm64-v8a x86_64 mips64
APP_OPTIM := release
APP_PLATFORM := android-8
APP_CPPFLAGS += -fexceptions -frtti
NDK_TOOLCHAIN_VERSION := 4.8
@@ -0,0 +1,49 @@
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := liblept

# leptonica (minus freetype)

BLACKLIST_SRC_FILES := \
%endiantest.c \
%freetype.c \
%xtractprotos.c

LEPTONICA_SRC_FILES := \
$(subst $(LOCAL_PATH)/,,$(wildcard $(LEPTONICA_PATH)/src/*.c))

LOCAL_SRC_FILES := \
$(filter-out $(BLACKLIST_SRC_FILES),$(LEPTONICA_SRC_FILES))

LOCAL_CFLAGS := \
-DHAVE_CONFIG_H

LOCAL_LDLIBS := \
-lz

# jni

LOCAL_SRC_FILES += \
box.cpp \
pix.cpp \
pixa.cpp \
utilities.cpp \
readfile.cpp \
writefile.cpp \
jni.cpp

LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LEPTONICA_PATH)/src

LOCAL_LDLIBS += \
-ljnigraphics \
-llog

# common

LOCAL_PRELINK_MODULE:= false

include $(BUILD_SHARED_LIBRARY)
@@ -0,0 +1,86 @@
/*
* Copyright 2011, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

jlong Java_com_googlecode_leptonica_android_Box_nativeCreate(JNIEnv *env, jclass clazz, jint x,
jint y, jint w, jint h) {
BOX *box = boxCreate((l_int32) x, (l_int32) y, (l_int32) w, (l_int32) h);

return (jlong) box;
}

void Java_com_googlecode_leptonica_android_Box_nativeDestroy(JNIEnv *env, jclass clazz,
jlong nativeBox) {
BOX *box = (BOX *) nativeBox;

boxDestroy(&box);
}

jint Java_com_googlecode_leptonica_android_Box_nativeGetX(JNIEnv *env, jclass clazz, jlong nativeBox) {
BOX *box = (BOX *) nativeBox;

return (jint) box->x;
}

jint Java_com_googlecode_leptonica_android_Box_nativeGetY(JNIEnv *env, jclass clazz, jlong nativeBox) {
BOX *box = (BOX *) nativeBox;

return (jint) box->y;
}

jint Java_com_googlecode_leptonica_android_Box_nativeGetWidth(JNIEnv *env, jclass clazz,
jlong nativeBox) {
BOX *box = (BOX *) nativeBox;

return (jint) box->w;
}

jint Java_com_googlecode_leptonica_android_Box_nativeGetHeight(JNIEnv *env, jclass clazz,
jlong nativeBox) {
BOX *box = (BOX *) nativeBox;

return (jint) box->h;
}

jboolean Java_com_googlecode_leptonica_android_Box_nativeGetGeometry(JNIEnv *env, jclass clazz,
jlong nativeBox,
jintArray dimensions) {
BOX *box = (BOX *) nativeBox;
jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL);
l_int32 x, y, w, h;

if (boxGetGeometry(box, &x, &y, &w, &h)) {
return JNI_FALSE;
}

dimensionArray[0] = x;
dimensionArray[1] = y;
dimensionArray[2] = w;
dimensionArray[3] = h;

env->ReleaseIntArrayElements(dimensions, dimensionArray, 0);

return JNI_TRUE;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -0,0 +1,46 @@
/*
* Copyright 2010, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef LEPTONICA_JNI_COMMON_H
#define LEPTONICA_JNI_COMMON_H

#include <jni.h>
#include <assert.h>
#include <allheaders.h>
#include <android/log.h>
#include <asm/byteorder.h>

#ifdef __BIG_ENDIAN
#define SK_A32_SHIFT 0
#define SK_R32_SHIFT 8
#define SK_G32_SHIFT 16
#define SK_B32_SHIFT 24
#else
#define SK_A32_SHIFT 24
#define SK_R32_SHIFT 16
#define SK_G32_SHIFT 8
#define SK_B32_SHIFT 0
#endif /* __BIG_ENDIAN */

#define LOG_TAG "Leptonica(native)"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOG_ASSERT(_cond, ...) if (!_cond) __android_log_assert("conditional", LOG_TAG, __VA_ARGS__)

#endif
@@ -0,0 +1,28 @@
/*
* Copyright 2010, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef LEPTONICA_JNI_CONFIG_AUTO_H
#define LEPTONICA_JNI_CONFIG_AUTO_H

#define HAVE_LIBJPEG 0
#define HAVE_LIBTIFF 0
#define HAVE_LIBPNG 0
#define HAVE_LIBZ 1
#define HAVE_LIBGIF 0
#define HAVE_LIBUNGIF 0
#define HAVE_FMEMOPEN 0

#endif
@@ -0,0 +1,29 @@
/*
* Copyright 2011, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv *env;

if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
LOGE("ERROR: GetEnv failed\n");
return -1;
}
assert(env != NULL);

return JNI_VERSION_1_6;
}
@@ -0,0 +1,253 @@
/*
* Copyright 2011, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

jlong Java_com_googlecode_leptonica_android_Pix_nativeCreatePix(JNIEnv *env, jclass clazz, jint w,
jint h, jint d) {
PIX *pix = pixCreate((l_int32) w, (l_int32) h, (l_int32) d);

return (jlong) pix;
}

jlong Java_com_googlecode_leptonica_android_Pix_nativeCreateFromData(JNIEnv *env, jclass clazz,
jbyteArray data, jint w,
jint h, jint d) {
PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, (l_int32) d);

jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);
memcpy(pixGetData(pix), byte_buffer, size);

env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT);

return (jlong) pix;
}

jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetData(JNIEnv *env, jclass clazz,
jlong nativePix, jbyteArray data) {
PIX *pix = (PIX *) nativePix;

jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);
memcpy(byte_buffer, pixGetData(pix), size);

env->ReleaseByteArrayElements(data, data_buffer, 0);

return JNI_TRUE;
}

jint Java_com_googlecode_leptonica_android_Pix_nativeGetDataSize(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pix = (PIX *) nativePix;

size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);

return (jint) size;
}

jlong Java_com_googlecode_leptonica_android_Pix_nativeClone(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pixs = (PIX *) nativePix;
PIX *pixd = pixClone(pixs);

return (jlong) pixd;
}

jlong Java_com_googlecode_leptonica_android_Pix_nativeCopy(JNIEnv *env, jclass clazz, jlong nativePix) {
PIX *pixs = (PIX *) nativePix;
PIX *pixd = pixCopy(NULL, pixs);

return (jlong) pixd;
}

jboolean Java_com_googlecode_leptonica_android_Pix_nativeInvert(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pixs = (PIX *) nativePix;

if (pixInvert(pixs, pixs)) {
return JNI_FALSE;
}

return JNI_TRUE;
}

void Java_com_googlecode_leptonica_android_Pix_nativeDestroy(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pix = (PIX *) nativePix;

pixDestroy(&pix);
}

jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetDimensions(JNIEnv *env, jclass clazz,
jlong nativePix,
jintArray dimensions) {
PIX *pix = (PIX *) nativePix;
jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL);
l_int32 w, h, d;

if (pixGetDimensions(pix, &w, &h, &d)) {
return JNI_FALSE;
}

dimensionArray[0] = w;
dimensionArray[1] = h;
dimensionArray[2] = d;

env->ReleaseIntArrayElements(dimensions, dimensionArray, 0);

return JNI_TRUE;
}

jint Java_com_googlecode_leptonica_android_Pix_nativeGetWidth(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pix = (PIX *) nativePix;

return (jint) pixGetWidth(pix);
}

jint Java_com_googlecode_leptonica_android_Pix_nativeGetHeight(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pix = (PIX *) nativePix;

return (jint) pixGetHeight(pix);
}

jint Java_com_googlecode_leptonica_android_Pix_nativeGetDepth(JNIEnv *env, jclass clazz,
jlong nativePix) {
PIX *pix = (PIX *) nativePix;

return (jint) pixGetDepth(pix);
}

void Java_com_googlecode_leptonica_android_Pix_nativeSetPixel(JNIEnv *env, jclass clazz,
jlong nativePix, jint xCoord,
jint yCoord, jint argbColor) {
PIX *pix = (PIX *) nativePix;
l_int32 d = pixGetDepth(pix);
l_int32 x = (l_int32) xCoord;
l_int32 y = (l_int32) yCoord;

// These shift values are based on RGBA_8888
l_uint8 r = (argbColor >> SK_R32_SHIFT) & 0xFF;
l_uint8 g = (argbColor >> SK_G32_SHIFT) & 0xFF;
l_uint8 b = (argbColor >> SK_B32_SHIFT) & 0xFF;
l_uint8 a = (argbColor >> SK_A32_SHIFT) & 0xFF;
l_uint8 gray = ((r + g + b) / 3) & 0xFF;

l_uint32 color;

switch (d) {
case 1: // 1-bit binary
color = gray > 128 ? 1 : 0;
break;
case 2: // 2-bit grayscale
color = gray >> 6;
break;
case 4: // 4-bit grayscale
color = gray >> 4;
break;
case 8: // 8-bit grayscale
color = gray;
break;
case 24: // 24-bit RGB
SET_DATA_BYTE(&color, COLOR_RED, r);
SET_DATA_BYTE(&color, COLOR_GREEN, g);
SET_DATA_BYTE(&color, COLOR_BLUE, b);
break;
case 32: // 32-bit ARGB
SET_DATA_BYTE(&color, COLOR_RED, r);
SET_DATA_BYTE(&color, COLOR_GREEN, g);
SET_DATA_BYTE(&color, COLOR_BLUE, b);
SET_DATA_BYTE(&color, L_ALPHA_CHANNEL, a);
break;
default: // unsupported
LOGE("Not a supported color depth: %d", d);
color = 0;
break;
}

pixSetPixel(pix, x, y, color);
}

jint Java_com_googlecode_leptonica_android_Pix_nativeGetPixel(JNIEnv *env, jclass clazz,
jlong nativePix, jint xCoord,
jint yCoord) {
PIX *pix = (PIX *) nativePix;
l_int32 d = pixGetDepth(pix);
l_int32 x = (l_int32) xCoord;
l_int32 y = (l_int32) yCoord;
l_uint32 pixel;
l_uint32 color;
l_uint8 a, r, g, b;

pixGetPixel(pix, x, y, &pixel);

switch (d) {
case 1: // 1-bit binary
a = 0xFF;
r = g = b = (pixel == 0 ? 0x00 : 0xFF);
break;
case 2: // 2-bit grayscale
a = 0xFF;
r = g = b = (pixel << 6 | pixel << 4 | pixel);
break;
case 4: // 4-bit grayscale
a = 0xFF;
r = g = b = (pixel << 4 | pixel);
break;
case 8: // 8-bit grayscale
a = 0xFF;
r = g = b = pixel;
break;
case 24: // 24-bit RGB
a = 0xFF;
r = (pixel >> L_RED_SHIFT) & 0xFF;
g = (pixel >> L_GREEN_SHIFT) & 0xFF;
b = (pixel >> L_BLUE_SHIFT) & 0xFF;
break;
case 32: // 32-bit RGBA
r = (pixel >> L_RED_SHIFT) & 0xFF;
g = (pixel >> L_GREEN_SHIFT) & 0xFF;
b = (pixel >> L_BLUE_SHIFT) & 0xFF;
a = (pixel >> L_ALPHA_SHIFT) & 0xFF;
break;
default: // Not supported
LOGE("Not a supported color depth: %d", d);
a = r = g = b = 0x00;
break;
}

color = a << SK_A32_SHIFT;
color |= r << SK_R32_SHIFT;
color |= g << SK_G32_SHIFT;
color |= b << SK_B32_SHIFT;

return (jint) color;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -0,0 +1,215 @@
/*
* Copyright 2011, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

jlong Java_com_googlecode_leptonica_android_Pixa_nativeCreate(JNIEnv *env, jclass clazz, jint size) {
PIXA *pixa = pixaCreate((l_int32) size);

return (jlong) pixa;
}

jlong Java_com_googlecode_leptonica_android_Pixa_nativeCopy(JNIEnv *env, jclass clazz,
jlong nativePixa) {
PIXA *pixas = (PIXA *) nativePixa;
PIXA *pixad = pixaCopy(pixas, L_CLONE);

return (jlong) pixad;
}

jlong Java_com_googlecode_leptonica_android_Pixa_nativeSort(JNIEnv *env, jclass clazz,
jlong nativePixa, jint field, jint order) {
PIXA *pixas = (PIXA *) nativePixa;
PIXA *pixad = pixaSort(pixas, field, order, NULL, L_CLONE);

return (jlong) pixad;
}

void Java_com_googlecode_leptonica_android_Pixa_nativeDestroy(JNIEnv *env, jclass clazz,
jlong nativePixa) {
PIXA *pixa = (PIXA *) nativePixa;

pixaDestroy(&pixa);
}

jboolean Java_com_googlecode_leptonica_android_Pixa_nativeJoin(JNIEnv *env, jclass clazz,
jlong nativePixa, jlong otherPixa) {
PIXA *pixa = (PIXA *) nativePixa;
PIXA *pixas = (PIXA *) otherPixa;

if (pixaJoin(pixa, pixas, 0, 0)) {
return JNI_FALSE;
}

return JNI_TRUE;
}

jint Java_com_googlecode_leptonica_android_Pixa_nativeGetCount(JNIEnv *env, jclass clazz,
jlong nativePixa) {
PIXA *pixa = (PIXA *) nativePixa;

return (jint) pixaGetCount(pixa);
}

void Java_com_googlecode_leptonica_android_Pixa_nativeAddPix(JNIEnv *env, jclass clazz,
jlong nativePixa, jlong nativePix,
jint mode) {
PIXA *pixa = (PIXA *) nativePixa;
PIX *pix = (PIX *) nativePix;

pixaAddPix(pixa, pix, mode);
}

void Java_com_googlecode_leptonica_android_Pixa_nativeAddBox(JNIEnv *env, jclass clazz,
jlong nativePixa, jlong nativeBox,
jint mode) {
PIXA *pixa = (PIXA *) nativePixa;
BOX *box = (BOX *) nativeBox;

pixaAddBox(pixa, box, mode);
}

void Java_com_googlecode_leptonica_android_Pixa_nativeAdd(JNIEnv *env, jclass clazz,
jlong nativePixa, jlong nativePix,
jlong nativeBox, jint mode) {
PIXA *pixa = (PIXA *) nativePixa;
PIX *pix = (PIX *) nativePix;
BOX *box = (BOX *) nativeBox;

pixaAddPix(pixa, pix, mode);
pixaAddBox(pixa, box, mode);
}

void Java_com_googlecode_leptonica_android_Pixa_nativeReplacePix(JNIEnv *env, jclass clazz,
jlong nativePixa, jint index,
jlong nativePix, jlong nativeBox) {
PIXA *pixa = (PIXA *) nativePixa;
PIX *pix = (PIX *) nativePix;
BOX *box = (BOX *) nativeBox;

pixaReplacePix(pixa, index, pix, box);
}

void Java_com_googlecode_leptonica_android_Pixa_nativeMergeAndReplacePix(JNIEnv *env, jclass clazz,
jlong nativePixa,
jint indexA, jint indexB) {
PIXA *pixa = (PIXA *) nativePixa;

l_int32 op;
l_int32 x, y, w, h;
l_int32 dx, dy, dw, dh;
PIX *pixs, *pixd;
BOX *boxA, *boxB, *boxd;

boxA = pixaGetBox(pixa, indexA, L_CLONE);
boxB = pixaGetBox(pixa, indexB, L_CLONE);
boxd = boxBoundingRegion(boxA, boxB);

boxGetGeometry(boxd, &x, &y, &w, &h);
pixd = pixCreate(w, h, 1);

op = PIX_SRC | PIX_DST;

pixs = pixaGetPix(pixa, indexA, L_CLONE);
boxGetGeometry(boxA, &dx, &dy, &dw, &dh);
pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0);
pixDestroy(&pixs);
boxDestroy(&boxA);

pixs = pixaGetPix(pixa, indexB, L_CLONE);
boxGetGeometry(boxB, &dx, &dy, &dw, &dh);
pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0);
pixDestroy(&pixs);
boxDestroy(&boxB);

pixaReplacePix(pixa, indexA, pixd, boxd);

}

jboolean Java_com_googlecode_leptonica_android_Pixa_nativeWriteToFileRandomCmap(JNIEnv *env,
jclass clazz,
jlong nativePixa,
jstring fileName,
jint width,
jint height) {
PIX *pixtemp;
PIXA *pixa = (PIXA *) nativePixa;

const char *c_fileName = env->GetStringUTFChars(fileName, NULL);
if (c_fileName == NULL) {
LOGE("could not extract fileName string!");
return JNI_FALSE;
}

if (pixaGetCount(pixa) > 0) {
pixtemp = pixaDisplayRandomCmap(pixa, (l_int32) width, (l_int32) height);
} else {
pixtemp = pixCreate((l_int32) width, (l_int32) height, 1);
}

pixWrite(c_fileName, pixtemp, IFF_BMP);
pixDestroy(&pixtemp);

env->ReleaseStringUTFChars(fileName, c_fileName);

return JNI_TRUE;
}

jint Java_com_googlecode_leptonica_android_Pixa_nativeGetPix(JNIEnv *env, jclass clazz,
jlong nativePixa, jint index) {
PIXA *pixa = (PIXA *) nativePixa;
PIX *pix = pixaGetPix(pixa, (l_int32) index, L_CLONE);

return (jlong) pix;
}

jlong Java_com_googlecode_leptonica_android_Pixa_nativeGetBox(JNIEnv *env, jclass clazz,
jlong nativePixa, jint index) {
PIXA *pixa = (PIXA *) nativePixa;
BOX *box = pixaGetBox(pixa, (l_int32) index, L_CLONE);

return (jlong) box;
}

jboolean Java_com_googlecode_leptonica_android_Pixa_nativeGetBoxGeometry(JNIEnv *env, jclass clazz,
jlong nativePixa,
jint index,
jintArray dimensions) {
PIXA *pixa = (PIXA *) nativePixa;
jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL);
l_int32 x, y, w, h;

if (pixaGetBoxGeometry(pixa, (l_int32) index, &x, &y, &w, &h)) {
return JNI_FALSE;
}

dimensionArray[0] = x;
dimensionArray[1] = y;
dimensionArray[2] = w;
dimensionArray[3] = h;

env->ReleaseIntArrayElements(dimensions, dimensionArray, 0);

return JNI_TRUE;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -0,0 +1,194 @@
/*
* Copyright 2011, Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "common.h"

#include <string.h>
#include <android/bitmap.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/************
* ReadFile *
************/

jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadMem(JNIEnv *env, jclass clazz,
jbyteArray image, jint length) {
jbyte *image_buffer = env->GetByteArrayElements(image, NULL);
int buffer_length = env->GetArrayLength(image);

PIX *pix = pixReadMem((const l_uint8 *) image_buffer, buffer_length);

env->ReleaseByteArrayElements(image, image_buffer, JNI_ABORT);

return (jlong) pix;
}

jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadBytes8(JNIEnv *env, jclass clazz,
jbyteArray data, jint w,
jint h) {
PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, 8);
l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL);
jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

for (int i = 0; i < h; i++) {
memcpy(lineptrs[i], (byte_buffer + (i * w)), w);
}

env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT);
pixCleanupByteProcessing(pix, lineptrs);

l_int32 d;

pixGetDimensions(pix, &w, &h, &d);

LOGE("Created image width w=%d, h=%d, d=%d", w, h, d);

return (jlong) pix;
}

jboolean Java_com_googlecode_leptonica_android_ReadFile_nativeReplaceBytes8(JNIEnv *env,
jclass clazz,
jlong nativePix,
jbyteArray data,
jint srcw, jint srch) {
PIX *pix = (PIX *) nativePix;
l_int32 w, h, d;

pixGetDimensions(pix, &w, &h, &d);

if (d != 8 || (l_int32) srcw != w || (l_int32) srch != h) {
LOGE("Failed to replace bytes at w=%d, h=%d, d=%d with w=%d, h=%d", w, h, d, srcw, srch);

return JNI_FALSE;
}

l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL);
jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

for (int i = 0; i < h; i++) {
memcpy(lineptrs[i], (byte_buffer + (i * w)), w);
}

env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT);
pixCleanupByteProcessing(pix, lineptrs);

return JNI_TRUE;
}

jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadFiles(JNIEnv *env, jclass clazz,
jstring dirName, jstring prefix) {
PIXA *pixad = NULL;

const char *c_dirName = env->GetStringUTFChars(dirName, NULL);
if (c_dirName == NULL) {
LOGE("could not extract dirName string!");
return (jlong) NULL;
}

const char *c_prefix = env->GetStringUTFChars(prefix, NULL);
if (c_prefix == NULL) {
LOGE("could not extract prefix string!");
return (jlong) NULL;
}

pixad = pixaReadFiles(c_dirName, c_prefix);

env->ReleaseStringUTFChars(dirName, c_dirName);
env->ReleaseStringUTFChars(prefix, c_prefix);

return (jlong) pixad;
}

jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadFile(JNIEnv *env, jclass clazz,
jstring fileName) {
PIX *pixd = NULL;

const char *c_fileName = env->GetStringUTFChars(fileName, NULL);
if (c_fileName == NULL) {
LOGE("could not extract fileName string!");
return (jlong) NULL;
}

pixd = pixRead(c_fileName);

env->ReleaseStringUTFChars(fileName, c_fileName);

return (jlong) pixd;
}

jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadBitmap(JNIEnv *env, jclass clazz,
jobject bitmap) {
l_int32 w, h, d;
AndroidBitmapInfo info;
void* pixels;
int ret;

if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return (jlong) NULL;
}

if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return (jlong) NULL;
}

if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return (jlong) NULL;
}

PIX *pixd = pixCreate(info.width, info.height, 8);

l_uint32 *src = (l_uint32 *) pixels;
l_int32 srcWpl = (info.stride / 4);
l_uint32 *dst = pixGetData(pixd);
l_int32 dstWpl = pixGetWpl(pixd);
l_uint8 a, r, g, b, pixel8;

for (int y = 0; y < info.height; y++) {
l_uint32 *dst_line = dst + (y * dstWpl);
l_uint32 *src_line = src + (y * srcWpl);

for (int x = 0; x < info.width; x++) {
// Get pixel from RGBA_8888
r = *src_line >> SK_R32_SHIFT;
g = *src_line >> SK_G32_SHIFT;
b = *src_line >> SK_B32_SHIFT;
a = *src_line >> SK_A32_SHIFT;
pixel8 = (l_uint8)((r + g + b) / 3);

// Set pixel to LUMA_8
SET_DATA_BYTE(dst_line, x, pixel8);

// Move to the next pixel
src_line++;
}
}

AndroidBitmap_unlockPixels(env, bitmap);

return (jlong) pixd;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -0,0 +1,8 @@
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = config README.html leptonica-license.txt moller52.jpg version-notes.html make-for-auto make-for-local autobuild

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = lept.pc

SUBDIRS = src prog

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,10 @@
#!/bin/sh
#
# autobuild

libtoolize -c -f
aclocal
autoheader
autoconf
automake -a -c

Large diffs are not rendered by default.

@@ -0,0 +1,104 @@
/* config/config.h.in. Generated from configure.ac by autoheader. */

/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD

/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

/* Define to 1 if you have the `fmemopen' function. */
#undef HAVE_FMEMOPEN

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have giflib. */
#undef HAVE_LIBGIF

/* Define to 1 if you have libopenjp2. */
#undef HAVE_LIBJP2K

/* Define to 1 if you have jpeg. */
#undef HAVE_LIBJPEG

/* Define to 1 if you have libpng. */
#undef HAVE_LIBPNG

/* Define to 1 if you have libtiff. */
#undef HAVE_LIBTIFF

/* Define to 1 if you have libwebp. */
#undef HAVE_LIBWEBP

/* Define to 1 if you have zlib. */
#undef HAVE_LIBZ

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR

/* Name of package */
#undef PACKAGE

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

/* Version number of package */
#undef VERSION

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,331 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.

scriptversion=2012-01-06.13; # UTC

# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi

run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'

# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi

msg="missing on your system"

case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;

-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;

-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;

-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;

esac

# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`

# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;

*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac

# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;

autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;

autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;

automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;

autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."

file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;

bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;

lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;

help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."

file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;

makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;

*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac

exit 0

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Large diffs are not rendered by default.

@@ -0,0 +1,121 @@
AC_PREREQ([2.50])
AC_INIT([leptonica], [1.71])
AC_CONFIG_AUX_DIR([config])
AM_CONFIG_HEADER([config_auto.h:config/config.h.in])
AC_CONFIG_SRCDIR([src/adaptmap.c])

AC_CONFIG_MACRO_DIR([m4])
LT_INIT

AM_INIT_AUTOMAKE
AC_LANG(C)
AC_CANONICAL_HOST

# Checks for programs.
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_PROG_LN_S
AC_PROG_MAKE_SET

# Checks for arguments.
AC_ARG_WITH([zlib], AS_HELP_STRING([--without-zlib], [do not include zlib support]))
AC_ARG_WITH([libpng], AS_HELP_STRING([--without-libpng], [do not include libpng support]))
AC_ARG_WITH([jpeg], AS_HELP_STRING([--without-jpeg], [do not include jpeg support]))
AC_ARG_WITH([giflib], AS_HELP_STRING([--without-giflib], [do not include giflib support]))
AC_ARG_WITH([libtiff], AS_HELP_STRING([--without-libtiff], [do not include libtiff support]))
AC_ARG_WITH([libwebp], AS_HELP_STRING([--without-libwebp], [do not include libwebp support]))
AC_ARG_WITH([libopenjpeg], AS_HELP_STRING([--without-libopenjpeg], [do not include libopenjpeg support]))

AC_ARG_ENABLE([programs], AS_HELP_STRING([--disable-programs], [do not build additional programs]))
AM_CONDITIONAL([ENABLE_PROGRAMS], [test "x$enable_programs" != xno])

# Checks for libraries.
LT_LIB_M

AS_IF([test "x$with_zlib" != xno],
AC_CHECK_LIB([z], [deflate],
AC_DEFINE([HAVE_LIBZ], 1, [Define to 1 if you have zlib.]) AC_SUBST([ZLIB_LIBS], [-lz]),
AS_IF([test "x$with_zlib" = xyes], AC_MSG_ERROR([zlib support requested but library not found]))
)
)

AS_IF([test "x$with_libpng" != xno],
AC_CHECK_LIB([png], [png_read_png],
AC_DEFINE([HAVE_LIBPNG], 1, [Define to 1 if you have libpng.]) AC_SUBST([LIBPNG_LIBS], [-lpng]),
AS_IF([test "x$with_libpng" = xyes], AC_MSG_ERROR([libpng support requested but library not found]))
)
)

AS_IF([test "x$with_jpeg" != xno],
AC_CHECK_LIB([jpeg], [jpeg_read_scanlines],
AC_DEFINE([HAVE_LIBJPEG], 1, [Define to 1 if you have jpeg.]) AC_SUBST([JPEG_LIBS], [-ljpeg]),
AS_IF([test "x$with_jpeg" = xyes], AC_MSG_ERROR([jpeg support requested but library not found]))
)
)

AS_IF([test "x$with_giflib" != xno],
AC_CHECK_LIB([gif], [DGifOpenFileHandle],
AC_DEFINE([HAVE_LIBGIF], 1, [Define to 1 if you have giflib.]) AC_SUBST([GIFLIB_LIBS], [-lgif]),
AS_IF([test "x$with_giflib" = xyes], AC_MSG_ERROR([giflib support requested but library not found]))
)
)

AS_IF([test "x$with_libtiff" != xno],
AC_CHECK_LIB([tiff], [TIFFOpen],
AC_DEFINE([HAVE_LIBTIFF], 1, [Define to 1 if you have libtiff.]) AC_SUBST([LIBTIFF_LIBS], [-ltiff]),
AS_IF([test "x$with_libtiff" = xyes], AC_MSG_ERROR([libtiff support requested but library not found])),
${ZLIB_LIBS} ${JPEG_LIBS}
)
)

AS_IF([test "x$with_libwebp" != xno],
AC_CHECK_LIB([webp], [WebPGetInfo],
AC_DEFINE([HAVE_LIBWEBP], 1, [Define to 1 if you have libwebp.]) AC_SUBST([LIBWEBP_LIBS], [-lwebp]),
AS_IF([test "x$with_libwebp" = xyes], AC_MSG_ERROR([libwebp support requested but library not found]))
)
)

AS_IF([test "x$with_libopenjp2" != xno],
AC_CHECK_LIB([openjp2], [opj_create_decompress],
AC_DEFINE([HAVE_LIBJP2K], 1, [Define to 1 if you have libopenjp2.]) AC_SUBST([LIBJP2K_LIBS], [-lopenjp2]),
AS_IF([test "x$with_libopenjp2" = xyes], AC_MSG_ERROR([libopenjp2 support requested but library not found]))
)
)

case "$host_os" in
mingw32*) AC_SUBST([GDI_LIBS], [-lgdi32]) ;;
esac

# Enable less verbose output when building.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
AC_C_BIGENDIAN

AC_SUBST([APPLE_UNIVERSAL_BUILD], [0])
AC_SUBST([ENDIANNESS], [L_LITTLE_ENDIAN])

case "$ac_cv_c_bigendian" in
yes) AC_SUBST([ENDIANNESS], [L_BIG_ENDIAN]) ;;
universal) AC_SUBST([APPLE_UNIVERSAL_BUILD], [1]) ;;
esac

# Add the -Wl and --as-needed flags to gcc compiler
AC_MSG_CHECKING([whether compiler supports -Wl,--as-needed])
OLD_LDFLAGS="${LDFLAGS}"
LDFLAGS="-Wl,--as-needed ${LDFLAGS}"

AC_LINK_IFELSE([AC_LANG_PROGRAM()],
AC_MSG_RESULT([yes]),
LDFLAGS="${OLD_LDFLAGS}"; AC_MSG_RESULT([no])
)

# Checks for library functions.
AC_CHECK_FUNCS([fmemopen])

AC_CONFIG_FILES([Makefile src/endianness.h src/Makefile prog/Makefile lept.pc])
AC_OUTPUT
@@ -0,0 +1,50 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* endiantest.c
*
* This test was contributed by Bill Janssen. When used with the
* gnu compiler, it allows efficient computation of the endian
* flag as part of the normal compilation process. As a result,
* it is not necessary to set this flag either manually or
* through the configure Makefile generator.
*/

#include <stdio.h>

int main()
{
/* fprintf(stderr, "doing the test\n"); */
long v = 0x04030201;
if (*((unsigned char *)(&v)) == 0x04)
printf("L_BIG_ENDIAN\n");
else
printf("L_LITTLE_ENDIAN\n");
return 0;
}


@@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/leptonica

Name: leptonica
Description: An open source C library for efficient image processing and image analysis operations
Version: @VERSION@
Libs: -L${libdir} -llept
Libs.private: @ZLIB_LIBS@ @LIBPNG_LIBS@ @JPEG_LIBS@ @GIFLIB_LIBS@ @LIBTIFF_LIBS@ @LIBWEBP_LIBS@
Cflags: -I${includedir}

@@ -0,0 +1,26 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

@@ -0,0 +1,8 @@
#!/bin/sh
#
# make-for-auto
#
# Run this to make with autoconf if you've previously run make-for-local

mv src/makefile src/makefile.static
mv prog/makefile prog/makefile.static
@@ -0,0 +1,8 @@
#!/bin/sh
#
# make-for-local
#
# Run this first if you want to use these static makefiles

cp src/makefile.static src/makefile
cp prog/makefile.static prog/makefile
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,123 @@
AUTOMAKE_OPTIONS = parallel-tests
AM_CFLAGS = $(DEBUG_FLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/src
LDADD = $(top_builddir)/src/liblept.la $(LIBM)

INSTALL_PROGS = convertfilestopdf convertfilestops \
convertformat \
convertsegfilestopdf convertsegfilestops \
converttopdf converttops fileinfo \
printimage printsplitimage printtiff \
splitimage2pdf xtractprotos

AUTO_REG_PROGS = alphaops_reg alphaxform_reg \
bilateral2_reg binarize_reg blackwhite_reg \
blend3_reg blend4_reg \
colorcontent_reg coloring_reg \
colormask_reg colorquant_reg \
colorspace_reg compare_reg \
convolve_reg dewarp_reg \
dna_reg dwamorph1_reg enhance_reg \
files_reg findcorners_reg findpattern_reg \
fpix1_reg fpix2_reg \
graymorph2_reg hardlight_reg \
insert_reg ioformats_reg \
jpegio_reg kernel_reg label_reg \
maze_reg multitype_reg \
nearline_reg newspaper_reg \
overlap_reg paint_reg paintmask_reg \
pdfseg_reg pixa2_reg \
pixserial_reg pngio_reg \
projection_reg psio_reg psioseg_reg \
pta_reg rankbin_reg rankhisto_reg \
rasteropip_reg \
rotate1_reg rotate2_reg rotateorth_reg \
scale_reg seedspread_reg \
selio_reg shear1_reg shear2_reg \
skew_reg splitcomp_reg subpixel_reg \
threshnorm_reg translate_reg \
warper_reg writetext_reg xformbox_reg

MANUAL_REG_PROGS = alltests_reg adaptnorm_reg affine_reg \
bilateral1_reg bilinear_reg \
binmorph1_reg binmorph2_reg binmorph3_reg \
binmorph4_reg binmorph5_reg \
blend1_reg blend2_reg boxa1_reg \
ccthin1_reg ccthin2_reg cmapquant_reg \
colorize_reg colorseg_reg compfilter_reg \
conncomp_reg conversion_reg distance_reg \
dwamorph2_reg equal_reg expand_reg extrema_reg \
fhmtauto_reg flipdetect_reg fmorphauto_reg \
gifio_reg grayfill_reg graymorph1_reg \
grayquant_reg heap_reg \
jp2kio_reg locminmax_reg \
logicops_reg lowaccess_reg morphseq_reg \
numa1_reg numa2_reg pixa1_reg \
pixadisp_reg pixalloc_reg pixcomp_reg \
pixmem_reg pixtile_reg projective_reg \
ptra1_reg ptra2_reg \
rank_reg rasterop_reg smallpix_reg \
smoothedge_reg string_reg \
webpio_reg wordboxes_reg

OTHER_PROGS = adaptmaptest adaptmap_dark \
arabic_lines arithtest \
barcodetest baselinetest \
binarizefiles binarize_set bincompare \
blendcmaptest buffertest \
byteatest ccbordtest cctest1 \
colormorphtest colorsegtest colorspacetest \
comparepages comparetest concatpdf \
contrasttest converttogray \
convolvetest cornertest \
croptest croptext \
dewarprules dewarptest1 dewarptest2 \
dewarptest3 dewarptest4 \
digitprep1 displayboxa \
displaypix displaypixa \
dithertest dwalineargen \
edgetest falsecolortest \
fcombautogen fhmtautogen \
findpattern1 findpattern2 findpattern3 \
flipselgen fmorphautogen \
fpixcontours gammatest genfonts \
graphicstest graymorphtest \
histotest iotest italictest \
jbcorrelation jbrankhaus jbwords \
lineremoval listtest \
livre_adapt livre_hmt \
livre_makefigs livre_orient \
livre_pageseg livre_seedgen livre_tophat \
maketile misctest1 \
modifyhuesat morphtest1 mtifftest \
numaranktest otsutest1 otsutest2 \
pagesegtest1 pagesegtest2 \
partitiontest pdfiotest \
pixaatest plottest \
quadtreetest ranktest \
recogsort recogtest1 \
reducetest removecmap \
renderfonts rotatefastalt \
rotateorthtest1 rotatetest1 \
runlengthtest scaleandtile \
scaletest1 scaletest2 \
seedfilltest sharptest \
sheartest showedges \
skewtest snapcolortest \
sorttest sudokutest trctest \
viewertest warpertest \
watershedtest wordsinorder \
writemtiff yuvtest

if ENABLE_PROGRAMS
bin_PROGRAMS = $(INSTALL_PROGS)
noinst_PROGRAMS = $(AUTO_REG_PROGS) $(MANUAL_REG_PROGS) $(OTHER_PROGS)
endif

check_PROGRAMS = $(AUTO_REG_PROGS)
TESTS = $(AUTO_REG_PROGS)
TESTS_ENVIRONMENT = $(srcdir)/reg_wrapper.sh
EXTRA_DIST = reg_wrapper.sh

dwamorph1_reg_SOURCES = dwamorph1_reg.c dwalinear.3.c dwalinearlow.3.c
dwamorph2_reg_SOURCES = dwamorph2_reg.c dwalinear.3.c dwalinearlow.3.c

Large diffs are not rendered by default.

@@ -0,0 +1,138 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* adaptmap_dark.c
*
* Demonstrates the effect of the fg threshold on adaptive mapping
* and cleaning for images with dark and variable background.
*
* The example pages are text and image. For both, because the
* background is both dark and variable, using a lower threshold
* gives much better results.
*
* For text, cleaning the background to white after adaptively
* remapping to make the background uniform is preferable.
* The final cleaning step uses pixGammaTRC() where the white value
* (here, 180) is set below the remapped gray value (here, 200).
*
* For the image, however, it is best to stop after remapping
* the background. Going further and moving pixels near the
* background color to white removes the details in the lighter
* regions of the image. In practice, parts of a scanned page
* that are image (as opposed to text) don't necessarily have
* background pixels that should be white. These regions can be
* protected by masks from operations, such as pixGammaTRC(),
* where the white value is less than 255.
*/

#include "string.h"
#include "allheaders.h"

void GenCleans(const char *fname, l_int32 *pindex, l_int32 thresh, L_BMF *bmf);

l_int32 main(int argc,
char **argv)
{
l_int32 index;
L_BMF *bmf;

PROCNAME("adaptmap_dark");

bmf = bmfCreate("fonts", 10);
index = 0;
lept_mkdir("lept");

/* Using a variety of different thresholds */
GenCleans("cavalerie.29.jpg", &index, 80, bmf);
GenCleans("cavalerie.29.jpg", &index, 60, bmf);
GenCleans("cavalerie.29.jpg", &index, 40, bmf);
GenCleans("cavalerie.11.jpg", &index, 80, bmf);
GenCleans("cavalerie.11.jpg", &index, 60, bmf);
GenCleans("cavalerie.11.jpg", &index, 40, bmf);

/* Write the nup files in /tmp/adapt2 */
convertToNUpFiles("/tmp/lept", "adapt_", 2, 1, 500, 6, 2, NULL, "adapt2");

/* Gather up into a pdf */
L_INFO("Writing to /tmp/lept/adapt_cleaning.pdf\n", procName);
convertFilesToPdf("/tmp/lept", "adapt_", 100, 1.0, L_JPEG_ENCODE,
75, "Adaptive cleaning", "/tmp/lept/adapt_cleaning.pdf");

bmfDestroy(&bmf);
lept_rmdir("adapt2");
return 0;
}

void
GenCleans(const char *fname,
l_int32 *pindex,
l_int32 thresh,
L_BMF *bmf)
{
l_int32 index, blackval, whiteval;
char buf[256];
PIX *pix1, *pix2, *pix3, *pix4, *pix5;

blackval = 70;
whiteval = 180;
index = *pindex;
pix1 = pixRead(fname);
snprintf(buf, sizeof(buf), "/tmp/lept/adapt_%03d.jpg", index++);
pixWrite(buf, pix1, IFF_JFIF_JPEG);

pix2 = pixBackgroundNorm(pix1, NULL, NULL, 10, 15, thresh, 25, 200, 2, 1);
snprintf(buf, sizeof(buf), "Norm color: fg thresh = %d", thresh);
fprintf(stderr, "%s\n", buf);
pix3 = pixAddSingleTextline(pix2, bmf, buf, 0x00ff0000, L_ADD_BELOW);
snprintf(buf, sizeof(buf), "/tmp/lept/adapt_%03d.jpg", index++);
pixWrite(buf, pix3, IFF_JFIF_JPEG);
pixDestroy(&pix3);
pix3 = pixGammaTRC(NULL, pix2, 1.0, blackval, whiteval);
snprintf(buf, sizeof(buf), "Clean color: fg thresh = %d", thresh);
pix4 = pixAddSingleTextblock(pix3, bmf, buf, 0x00ff0000, L_ADD_BELOW, NULL);
snprintf(buf, sizeof(buf), "/tmp/lept/adapt_%03d.jpg", index++);
pixWrite(buf, pix4, IFF_JFIF_JPEG);
pixDestroy(&pix2);
pixDestroy(&pix3);
pixDestroy(&pix4);

pix2 = pixConvertRGBToGray(pix1, 0.33, 0.34, 0.33);
pix3 = pixBackgroundNorm(pix2, NULL, NULL, 10, 15, thresh, 25, 200, 2, 1);
pix4 = pixGammaTRC(NULL, pix3, 1.0, blackval, whiteval);
snprintf(buf, sizeof(buf), "Clean gray: fg thresh = %d", thresh);
pix5 = pixAddSingleTextblock(pix4, bmf, buf, 0x00ff0000, L_ADD_BELOW, NULL);
snprintf(buf, sizeof(buf), "/tmp/lept/adapt_%03d.jpg", index++);
pixWrite(buf, pix5, IFF_JFIF_JPEG);
pixDestroy(&pix2);
pixDestroy(&pix3);
pixDestroy(&pix4);
pixDestroy(&pix5);

pixDestroy(&pix1);
*pindex = index;
return;
}
@@ -0,0 +1,218 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* adaptmaptest.c
*
* Generates adaptive mappings in both gray and color, testing
* individual parts.
*
* e.g., use with wet-day.jpg
*/

#include "allheaders.h"

#define SIZE_X 10
#define SIZE_Y 30
#define BINTHRESH 50
#define MINCOUNT 30

#define BGVAL 200
#define SMOOTH_X 2
#define SMOOTH_Y 1

/* Location of image region in wet-day.jpg */
#define XS 151
#define YS 225
#define WS 913
#define HS 1285


int main(int argc,
char **argv)
{
l_int32 w, h, d;
PIX *pixs, *pixc, *pixg, *pixgm, *pixmi, *pixd, *pixd2;
PIX *pixmr, *pixmg, *pixmb, *pixmri, *pixmgi, *pixmbi;
PIX *pixim;
PIXA *pixa;
char *filein;
static char mainName[] = "adaptmaptest";

if (argc != 2)
return ERROR_INT(" Syntax: adaptmaptest filein", mainName, 1);

filein = argv[1];
if ((pixs = pixRead(filein)) == NULL)
return ERROR_INT("pix not made", mainName, 1);
pixGetDimensions(pixs, &w, &h, &d);
if (d != 8 && d != 32)
return ERROR_INT("pix not 8 or 32 bpp", mainName, 1);
pixDisplayWrite(NULL, -1);
pixa = pixaCreate(0);
pixSaveTiled(pixs, pixa, 1.0, 1, 20, 32);
pixDisplayWrite(pixs, 1);

if (d == 32) {
pixc = pixClone(pixs);
pixg = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33);
} else {
pixc = pixConvertTo32(pixs);
pixg = pixClone(pixs);
}
pixSaveTiled(pixg, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixg, 1);

#if 1
/* Process in grayscale */
startTimer();
pixim = NULL;
pixim = pixCreate(w, h, 1);
pixRasterop(pixim, XS, YS, WS, HS, PIX_SET, NULL, 0, 0);
pixGetBackgroundGrayMap(pixg, pixim, SIZE_X, SIZE_Y,
BINTHRESH, MINCOUNT, &pixgm);
fprintf(stderr, "time for gray adaptmap gen: %7.3f\n", stopTimer());
pixWrite("/tmp/pixgm1.png", pixgm, IFF_PNG);
pixSaveTiled(pixgm, pixa, 1.0, 1, 20, 32);
pixDisplayWrite(pixgm, 1);

startTimer();
pixmi = pixGetInvBackgroundMap(pixgm, BGVAL, SMOOTH_X, SMOOTH_Y);
fprintf(stderr, "time for gray inv map generation: %7.3f\n", stopTimer());
pixWrite("/tmp/pixmi1.png", pixmi, IFF_PNG);
pixSaveTiled(pixmi, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixmi, 1);

startTimer();
pixd = pixApplyInvBackgroundGrayMap(pixg, pixmi, SIZE_X, SIZE_Y);
fprintf(stderr, "time to apply gray inv map: %7.3f\n", stopTimer());
pixWrite("/tmp/pixd1.jpg", pixd, IFF_JFIF_JPEG);
pixSaveTiled(pixd, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixd, 1);

pixd2 = pixGammaTRCMasked(NULL, pixd, pixim, 1.0, 0, 190);
pixInvert(pixim, pixim);
pixGammaTRCMasked(pixd2, pixd2, pixim, 1.0, 60, 190);
pixWrite("/tmp/pixo1.jpg", pixd2, IFF_JFIF_JPEG);
pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixd2, 1);
pixDestroy(&pixim);
pixDestroy(&pixgm);
pixDestroy(&pixmi);
pixDestroy(&pixd);
pixDestroy(&pixd2);
#endif

#if 1
/* Process in color */
startTimer();
pixmr = pixmg = pixmb = NULL;
pixim = pixCreate(w, h, 1);
pixRasterop(pixim, XS, YS, WS, HS, PIX_SET, NULL, 0, 0);
pixGetBackgroundRGBMap(pixc, pixim, NULL, SIZE_X, SIZE_Y,
BINTHRESH, MINCOUNT,
&pixmr, &pixmg, &pixmb);
fprintf(stderr, "time for color adaptmap gen: %7.3f\n", stopTimer());
pixWrite("/tmp/pixmr.png", pixmr, IFF_PNG);
pixWrite("/tmp/pixmg.png", pixmg, IFF_PNG);
pixWrite("/tmp/pixmb.png", pixmb, IFF_PNG);

startTimer();
pixmri = pixGetInvBackgroundMap(pixmr, BGVAL, SMOOTH_X, SMOOTH_Y);
pixmgi = pixGetInvBackgroundMap(pixmg, BGVAL, SMOOTH_X, SMOOTH_Y);
pixmbi = pixGetInvBackgroundMap(pixmb, BGVAL, SMOOTH_X, SMOOTH_Y);
fprintf(stderr, "time for color inv map generation: %7.3f\n", stopTimer());
pixWrite("/tmp/pixmri.png", pixmri, IFF_PNG);
pixWrite("/tmp/pixmgi.png", pixmgi, IFF_PNG);
pixWrite("/tmp/pixmbi.png", pixmbi, IFF_PNG);

startTimer();
pixd = pixApplyInvBackgroundRGBMap(pixc, pixmri, pixmgi, pixmbi,
SIZE_X, SIZE_Y);
fprintf(stderr, "time to apply color inv maps: %7.3f\n", stopTimer());
pixWrite("/tmp/pixd2.jpg", pixd, IFF_JFIF_JPEG);
pixSaveTiled(pixd, pixa, 1.0, 1, 20, 32);
pixDisplayWrite(pixd, 1);

pixd2 = pixGammaTRCMasked(NULL, pixd, pixim, 1.0, 0, 190);
pixInvert(pixim, pixim);
pixGammaTRCMasked(pixd2, pixd2, pixim, 1.0, 60, 190);
pixWrite("/tmp/pixo2.jpg", pixd2, IFF_JFIF_JPEG);
pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixd2, 1);
pixDestroy(&pixmr);
pixDestroy(&pixmg);
pixDestroy(&pixmb);
pixDestroy(&pixmri);
pixDestroy(&pixmgi);
pixDestroy(&pixmbi);
pixDestroy(&pixim);
pixDestroy(&pixd);
pixDestroy(&pixd2);
#endif

#if 1
/* Process in either gray or color, depending on the source */
startTimer();
pixim = pixCreate(w, h, 1);
pixRasterop(pixim, XS, YS, WS, HS, PIX_SET, NULL, 0, 0);
/* pixd = pixBackgroundNorm(pixs, pixim, NULL,SIZE_X, SIZE_Y,
BINTHRESH, MINCOUNT,
BGVAL, SMOOTH_X, SMOOTH_Y); */
pixd = pixBackgroundNorm(pixs, pixim, NULL, 5, 10, BINTHRESH, 20,
BGVAL, SMOOTH_X, SMOOTH_Y);
fprintf(stderr, "time for bg normalization: %7.3f\n", stopTimer());
pixWrite("/tmp/pixd3.jpg", pixd, IFF_JFIF_JPEG);
pixSaveTiled(pixd, pixa, 1.0, 1, 20, 32);
pixDisplayWrite(pixd, 1);

pixd2 = pixGammaTRCMasked(NULL, pixd, pixim, 1.0, 0, 190);
pixInvert(pixim, pixim);
pixGammaTRCMasked(pixd2, pixd2, pixim, 1.0, 60, 190);
pixWrite("/tmp/pixo3.jpg", pixd2, IFF_JFIF_JPEG);
pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 32);
pixDisplayWrite(pixd2, 1);

pixDestroy(&pixd);
pixDestroy(&pixd2);
pixDestroy(&pixim);
#endif

/* Display results */
pixd = pixaDisplay(pixa, 0, 0);
pixDisplay(pixd, 100, 100);
pixWrite("/tmp/adapt.jpg", pixd, IFF_JFIF_JPEG);
pixDestroy(&pixd);
pixaDestroy(&pixa);

pixDisplayMultiple("/tmp/display/file*");

pixDestroy(&pixs);
pixDestroy(&pixg);
pixDestroy(&pixc);
return 0;
}

@@ -0,0 +1,158 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* adaptnorm_reg.c
*
* Image normalization for two extreme cases:
* * variable and low contrast
* * good contrast but fast varying background
*/

#include "allheaders.h"

int main(int argc,
char **argv)
{
l_int32 w, h;
l_float32 mps;
PIX *pixs, *pixt, *pixmin, *pixd;
PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6;
PIX *pixt7, *pixt8, *pixt9, *pixt10, *pixt11, *pixt12;
PIX *pixt13, *pixt14, *pixt15, *pixt16;
PIXA *pixac;
static char mainName[] = "adaptnorm_reg";

/* ---------------------------------------------------------- *
* Normalize by adaptively expanding the dynamic range *
* ---------------------------------------------------------- */
pixac = pixaCreate(0);
pixs = pixRead("lighttext.jpg");
pixGetDimensions(pixs, &w, &h, NULL);
pixSaveTiled(pixs, pixac, 1.0, 1, 20, 8);
startTimer();
pixt1 = pixContrastNorm(NULL, pixs, 10, 10, 40, 2, 2);
mps = 0.000001 * w * h / stopTimer();
fprintf(stderr, "Time: Contrast norm: %7.3f Mpix/sec\n", mps);
pixSaveTiled(pixt1, pixac, 1.0, 1, 40, 8);
pixWrite("/tmp/pixt1.png", pixt1, IFF_PNG);

/* Apply a gamma to clean up the remaining background */
pixt2 = pixGammaTRC(NULL, pixt1, 1.5, 50, 235);
pixSaveTiled(pixt2, pixac, 1.0, 0, 40, 8);
pixWrite("/tmp/pixt2.png", pixt2, IFF_PNG);

/* Here are two possible output display images; a dithered
* 2 bpp image and a 7 level thresholded 4 bpp image */
pixt3 = pixDitherTo2bpp(pixt2, 1);
pixSaveTiled(pixt3, pixac, 1.0, 0, 40, 8);
pixWrite("/tmp/pixt3.png", pixt3, IFF_PNG);
pixt4 = pixThresholdTo4bpp(pixt2, 7, 1);
pixSaveTiled(pixt4, pixac, 1.0, 0, 40, 8);
pixWrite("/tmp/pixt4.png", pixt4, IFF_PNG);

/* Binary image produced from 8 bpp normalized ones,
* before and after the gamma correction. */
pixt5 = pixThresholdToBinary(pixt1, 180);
pixSaveTiled(pixt5, pixac, 1.0, 1, 40, 8);
pixWrite("/tmp/pixt5.png", pixt5, IFF_PNG);
pixt6 = pixThresholdToBinary(pixt2, 200);
pixSaveTiled(pixt6, pixac, 1.0, 0, 40, 8);
pixWrite("/tmp/pixt6.png", pixt6, IFF_PNG);

pixDestroy(&pixs);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixt3);
pixDestroy(&pixt4);
pixDestroy(&pixt5);
pixDestroy(&pixt6);

pixd = pixaDisplay(pixac, 0, 0);
pixDisplay(pixd, 100, 100);
pixWrite("/tmp/norm.png", pixd, IFF_PNG);
pixDestroy(&pixd);
pixaDestroy(&pixac);


/* ---------------------------------------------------------- *
* Normalize for rapidly varying background *
* ---------------------------------------------------------- */
pixac = pixaCreate(0);
pixs = pixRead("w91frag.jpg");
pixGetDimensions(pixs, &w, &h, NULL);
pixSaveTiled(pixs, pixac, 1.0, 1, 20, 8);
startTimer();
pixt7 = pixBackgroundNormFlex(pixs, 7, 7, 1, 1, 10);
mps = 0.000001 * w * h / stopTimer();
fprintf(stderr, "Time: Flexible bg norm: %7.3f Mpix/sec\n", mps);
pixSaveTiled(pixt7, pixac, 1.0, 0, 40, 8);
pixWrite("/tmp/pixt7.png", pixt7, IFF_PNG);

/* Now do it again in several steps */
pixt8 = pixScaleSmooth(pixs, 1./7., 1./7.);
pixt = pixScale(pixt8, 7.0, 7.0);
pixSaveTiled(pixt, pixac, 1.0, 1, 20, 8);
pixDestroy(&pixt);
pixLocalExtrema(pixt8, 0, 0, &pixmin, NULL); /* 1's at minima */
pixt9 = pixExpandBinaryReplicate(pixmin, 7);
pixSaveTiled(pixt9, pixac, 1.0, 0, 20, 8);
pixt10 = pixSeedfillGrayBasin(pixmin, pixt8, 10, 4);
pixt11 = pixExtendByReplication(pixt10, 1, 1);
pixt12 = pixGetInvBackgroundMap(pixt11, 200, 1, 1); /* smoothing incl. */
pixt13 = pixApplyInvBackgroundGrayMap(pixs, pixt12, 7, 7);
pixSaveTiled(pixt13, pixac, 1.0, 0, 20, 8);

/* Process the result for gray and binary output */
pixt14 = pixGammaTRCMasked(NULL, pixt7, NULL, 1.0, 100, 175);
pixSaveTiled(pixt14, pixac, 1.0, 1, 20, 8);
pixt15 = pixThresholdTo4bpp(pixt14, 10, 1);
pixSaveTiled(pixt15, pixac, 1.0, 0, 20, 8);
pixt16 = pixThresholdToBinary(pixt14, 190);
pixSaveTiled(pixt16, pixac, 1.0, 0, 20, 8);

pixDestroy(&pixs);
pixDestroy(&pixt7);
pixDestroy(&pixmin);
pixDestroy(&pixt8);
pixDestroy(&pixt9);
pixDestroy(&pixt10);
pixDestroy(&pixt11);
pixDestroy(&pixt12);
pixDestroy(&pixt13);
pixDestroy(&pixt14);
pixDestroy(&pixt15);
pixDestroy(&pixt16);

pixd = pixaDisplay(pixac, 0, 0);
pixDisplay(pixd, 100, 100);
pixWrite("/tmp/flex.png", pixd, IFF_PNG);
pixDestroy(&pixd);
pixaDestroy(&pixac);
return 0;
}


@@ -0,0 +1,392 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* affine_reg.c
*
*/

#include "allheaders.h"

static void MakePtas(l_int32 i, PTA **pptas, PTA **pptad);
l_int32 RenderHashedBoxa(PIX *pixt, BOXA *boxa, l_int32 i);


/* Sample values.
* 1-3: invertability tests
* 4: comparison between sampling and sequential
* 5: test with large distortion
*/
static const l_int32 x1[] = { 300, 300, 300, 95, 32};
static const l_int32 y1[] = {1200, 1200, 1250, 2821, 934};
static const l_int32 x2[] = {1200, 1200, 1125, 1432, 487};
static const l_int32 y2[] = {1100, 1100, 1100, 2682, 934};
static const l_int32 x3[] = { 200, 200, 200, 232, 32};
static const l_int32 y3[] = { 200, 200, 200, 657, 67};

static const l_int32 xp1[] = { 500, 300, 350, 117, 32};
static const l_int32 yp1[] = {1700, 1400, 1400, 2629, 934};
static const l_int32 xp2[] = {850, 1400, 1400, 1464, 487};
static const l_int32 yp2[] = {850, 1500, 1500, 2432, 804};
static const l_int32 xp3[] = { 450, 200, 400, 183, 61};
static const l_int32 yp3[] = { 300, 300, 400, 490, 83};

static const l_int32 SHIFTX = 44;
static const l_int32 SHIFTY = 39;
static const l_float32 SCALEX = 0.83;
static const l_float32 SCALEY = 0.78;
static const l_float32 ROTATION = 0.11; /* radian */

#define ADDED_BORDER_PIXELS 1000
#define ALL 1


int main(int argc,
char **argv)
{
char bufname[256];
l_int32 i, w, h;
l_float32 *mat1, *mat2, *mat3, *mat1i, *mat2i, *mat3i, *matdinv;
l_float32 matd[9], matdi[9];
BOXA *boxa, *boxa2;
PIX *pix, *pixs, *pixb, *pixg, *pixc, *pixcs;
PIX *pixd, *pixt1, *pixt2, *pixt3;
PIXA *pixa;
PTA *ptas, *ptad;
static char mainName[] = "affine_reg";

if (argc != 1)
return ERROR_INT(" Syntax: affine_reg", mainName, 1);

if ((pixs = pixRead("feyn.tif")) == NULL)
return ERROR_INT("pixs not made", mainName, 1);

#if 1
/* Test invertability of sequential. */
pixa = pixaCreate(0);
for (i = 0; i < 3; i++) {
pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0);
MakePtas(i, &ptas, &ptad);
pixt1 = pixAffineSequential(pixb, ptad, ptas, 0, 0);
pixSaveTiled(pixt1, pixa, 0.3333, 1, 20, 8);
pixt2 = pixAffineSequential(pixt1, ptas, ptad, 0, 0);
pixSaveTiled(pixt2, pixa, 0.3333, 0, 20, 0);
pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS);
pixXor(pixd, pixd, pixs);
pixSaveTiled(pixd, pixa, 0.3333, 0, 20, 0);
sprintf(bufname, "/tmp/seq%d.png", i);
pixWrite(bufname, pixd, IFF_PNG);
pixDestroy(&pixb);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixd);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
}

pixt1 = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine1.png", pixt1, IFF_PNG);
pixDisplay(pixt1, 100, 100);
pixDestroy(&pixt1);
pixaDestroy(&pixa);
#endif

#if ALL
/* Test invertability of sampling */
pixa = pixaCreate(0);
for (i = 0; i < 3; i++) {
pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0);
MakePtas(i, &ptas, &ptad);
pixt1 = pixAffineSampledPta(pixb, ptad, ptas, L_BRING_IN_WHITE);
pixSaveTiled(pixt1, pixa, 0.3333, 1, 20, 8);
pixt2 = pixAffineSampledPta(pixt1, ptas, ptad, L_BRING_IN_WHITE);
pixSaveTiled(pixt2, pixa, 0.3333, 0, 20, 0);
pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS);
pixXor(pixd, pixd, pixs);
pixSaveTiled(pixd, pixa, 0.3333, 0, 20, 0);
if (i == 0) pixWrite("/tmp/samp.png", pixt1, IFF_PNG);
pixDestroy(&pixb);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixd);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
}

pixt1 = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine2.png", pixt1, IFF_PNG);
pixDisplay(pixt1, 100, 300);
pixDestroy(&pixt1);
pixaDestroy(&pixa);
#endif

#if ALL
/* Test invertability of interpolation on grayscale */
pixa = pixaCreate(0);
pixg = pixScaleToGray3(pixs);
for (i = 0; i < 3; i++) {
pixb = pixAddBorder(pixg, ADDED_BORDER_PIXELS / 3, 255);
MakePtas(i, &ptas, &ptad);
pixt1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE);
pixSaveTiled(pixt1, pixa, 1.0, 1, 20, 8);
pixt2 = pixAffinePta(pixt1, ptas, ptad, L_BRING_IN_WHITE);
pixSaveTiled(pixt2, pixa, 1.0, 0, 20, 0);
pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS / 3);
pixXor(pixd, pixd, pixg);
pixSaveTiled(pixd, pixa, 1.0, 0, 20, 0);
if (i == 0) pixWrite("/tmp/interp.png", pixt1, IFF_PNG);
pixDestroy(&pixb);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixd);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
}

pixt1 = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine3.png", pixt1, IFF_PNG);
pixDisplay(pixt1, 100, 500);
pixDestroy(&pixt1);
pixaDestroy(&pixa);
pixDestroy(&pixg);
#endif

#if ALL
/* Test invertability of interpolation on color */
pixa = pixaCreate(0);
pixc = pixRead("test24.jpg");
pixcs = pixScale(pixc, 0.3, 0.3);
for (i = 0; i < 3; i++) {
pixb = pixAddBorder(pixcs, ADDED_BORDER_PIXELS / 4, 0xffffff00);
MakePtas(i, &ptas, &ptad);
pixt1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE);
pixSaveTiled(pixt1, pixa, 1.0, 1, 20, 32);
pixt2 = pixAffinePta(pixt1, ptas, ptad, L_BRING_IN_WHITE);
pixSaveTiled(pixt2, pixa, 1.0, 0, 20, 0);
pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS / 4);
pixXor(pixd, pixd, pixcs);
pixSaveTiled(pixd, pixa, 1.0, 0, 20, 0);
pixDestroy(&pixb);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixd);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
}

pixt1 = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine4.png", pixt1, IFF_PNG);
pixDisplay(pixt1, 100, 500);
pixDestroy(&pixt1);
pixaDestroy(&pixa);
pixDestroy(&pixc);
pixDestroy(&pixcs);
#endif

#if ALL
/* Comparison between sequential and sampling */
MakePtas(3, &ptas, &ptad);
pixa = pixaCreate(0);

/* Use sequential transforms */
pixt1 = pixAffineSequential(pixs, ptas, ptad,
ADDED_BORDER_PIXELS, ADDED_BORDER_PIXELS);
pixSaveTiled(pixt1, pixa, 0.5, 0, 20, 8);

/* Use sampled transform */
pixt2 = pixAffineSampledPta(pixs, ptas, ptad, L_BRING_IN_WHITE);
pixSaveTiled(pixt2, pixa, 0.5, 0, 20, 8);

/* Compare the results */
pixXor(pixt2, pixt2, pixt1);
pixSaveTiled(pixt2, pixa, 0.5, 0, 20, 8);

pixd = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine5.png", pixd, IFF_PNG);
pixDisplay(pixd, 100, 700);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixd);
pixaDestroy(&pixa);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
#endif

#if ALL
/* Get timings and test with large distortion */
MakePtas(4, &ptas, &ptad);
pixa = pixaCreate(0);
pixg = pixScaleToGray3(pixs);

startTimer();
pixt1 = pixAffineSequential(pixg, ptas, ptad, 0, 0);
fprintf(stderr, " Time for pixAffineSequentialPta(): %6.2f sec\n",
stopTimer());
pixSaveTiled(pixt1, pixa, 1.0, 1, 20, 8);

startTimer();
pixt2 = pixAffineSampledPta(pixg, ptas, ptad, L_BRING_IN_WHITE);
fprintf(stderr, " Time for pixAffineSampledPta(): %6.2f sec\n", stopTimer());
pixSaveTiled(pixt2, pixa, 1.0, 0, 20, 8);

startTimer();
pixt3 = pixAffinePta(pixg, ptas, ptad, L_BRING_IN_WHITE);
fprintf(stderr, " Time for pixAffinePta(): %6.2f sec\n", stopTimer());
pixSaveTiled(pixt3, pixa, 1.0, 0, 20, 8);

pixXor(pixt1, pixt1, pixt2);
pixSaveTiled(pixt1, pixa, 1.0, 1, 20, 8);
pixXor(pixt2, pixt2, pixt3);
pixSaveTiled(pixt2, pixa, 1.0, 0, 20, 8);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixDestroy(&pixt3);

pixd = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine6.png", pixd, IFF_PNG);
pixDisplay(pixd, 100, 900);
pixDestroy(&pixd);
pixDestroy(&pixg);
pixaDestroy(&pixa);
ptaDestroy(&ptas);
ptaDestroy(&ptad);
#endif

pixDestroy(&pixs);

#if ALL
/* Set up pix and boxa */
pixa = pixaCreate(0);
pix = pixRead("lucasta.1.300.tif");
pixTranslate(pix, pix, 70, 0, L_BRING_IN_WHITE);
pixt1 = pixCloseBrick(NULL, pix, 14, 5);
pixOpenBrick(pixt1, pixt1, 1, 2);
boxa = pixConnComp(pixt1, NULL, 8);
pixs = pixConvertTo32(pix);
pixGetDimensions(pixs, &w, &h, NULL);
pixc = pixCopy(NULL, pixs);
RenderHashedBoxa(pixc, boxa, 113);
pixSaveTiled(pixc, pixa, 0.5, 1, 30, 32);
pixDestroy(&pix);
pixDestroy(&pixc);
pixDestroy(&pixt1);

/* Set up an affine transform in matd, and apply it to boxa */
mat1 = createMatrix2dTranslate(SHIFTX, SHIFTY);
mat2 = createMatrix2dScale(SCALEX, SCALEY);
mat3 = createMatrix2dRotate(w / 2, h / 2, ROTATION);
l_productMat3(mat3, mat2, mat1, matd, 3);
boxa2 = boxaAffineTransform(boxa, matd);

/* Set up the inverse transform in matdi */
mat1i = createMatrix2dTranslate(-SHIFTX, -SHIFTY);
mat2i = createMatrix2dScale(1.0/ SCALEX, 1.0 / SCALEY);
mat3i = createMatrix2dRotate(w / 2, h / 2, -ROTATION);
l_productMat3(mat1i, mat2i, mat3i, matdi, 3);

/* Invert the original affine transform in matdinv */
affineInvertXform(matd, &matdinv);
fprintf(stderr, "Affine transform, applied to boxa\n");
for (i = 0; i < 9; i++) {
if (i && (i % 3 == 0)) fprintf(stderr, "\n");
fprintf(stderr, " %7.3f ", matd[i]);
}
fprintf(stderr, "\nInverse transform, made by composing inverse parts");
for (i = 0; i < 9; i++) {
if (i % 3 == 0) fprintf(stderr, "\n");
fprintf(stderr, " %7.3f ", matdi[i]);
}
fprintf(stderr, "\nInverse transform, made by inverting the affine xform");
for (i = 0; i < 6; i++) {
if (i % 3 == 0) fprintf(stderr, "\n");
fprintf(stderr, " %7.3f ", matdinv[i]);
}
fprintf(stderr, "\n");

/* Apply the inverted affine transform pixs */
pixd = pixAffine(pixs, matdinv, L_BRING_IN_WHITE);
RenderHashedBoxa(pixd, boxa2, 513);
pixSaveTiled(pixd, pixa, 0.5, 0, 30, 32);
pixDestroy(&pixd);

pixd = pixaDisplay(pixa, 0, 0);
pixWrite("/tmp/affine7.png", pixd, IFF_PNG);
pixDisplay(pixd, 100, 900);
pixDestroy(&pixd);
pixDestroy(&pixs);
pixaDestroy(&pixa);
boxaDestroy(&boxa);
boxaDestroy(&boxa2);
lept_free(mat1);
lept_free(mat2);
lept_free(mat3);
lept_free(mat1i);
lept_free(mat2i);
lept_free(mat3i);
#endif

return 0;
}

static void
MakePtas(l_int32 i,
PTA **pptas,
PTA **pptad)
{

*pptas = ptaCreate(3);
ptaAddPt(*pptas, x1[i], y1[i]);
ptaAddPt(*pptas, x2[i], y2[i]);
ptaAddPt(*pptas, x3[i], y3[i]);
*pptad = ptaCreate(3);
ptaAddPt(*pptad, xp1[i], yp1[i]);
ptaAddPt(*pptad, xp2[i], yp2[i]);
ptaAddPt(*pptad, xp3[i], yp3[i]);
return;
}


l_int32
RenderHashedBoxa(PIX *pixt,
BOXA *boxa,
l_int32 i)
{
l_int32 j, n, rval, gval, bval;
BOX *box;

n = boxaGetCount(boxa);
rval = (1413 * i) % 256;
gval = (4917 * i) % 256;
bval = (7341 * i) % 256;
for (j = 0; j < n; j++) {
box = boxaGetBox(boxa, j, L_CLONE);
pixRenderHashBoxArb(pixt, box, 10, 3, i % 4, 1, rval, gval, bval);
boxDestroy(&box);
}
return 0;
}


@@ -0,0 +1,188 @@
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/

/*
* alltests_reg.c
*
* Tests all the reg tests:
*
* alltests_reg command
*
* where
* <command> == "generate" to make the golden files in /tmp/golden
* <command> == "compare" to make local files and compare with
* the golden files
* <command> == "display" to make local files and display
*
* You can also run each test individually with any one of these
* arguments. Warning: if you run this with "display", a very
* large number of images will be displayed on the screen.
*/

#include <string.h>
#include "allheaders.h"

static const char *tests[] = {
"alphaops_reg",
"alphaxform_reg",
"bilateral2_reg",
"binarize_reg",
"blackwhite_reg",
"blend3_reg",
"blend4_reg",
"colorcontent_reg",
"coloring_reg",
"colormask_reg",
"colorquant_reg",
"colorspace_reg",
"compare_reg",
"convolve_reg",
"dewarp_reg",
/* "distance_reg", */
"dna_reg",
"dwamorph1_reg",
"enhance_reg",
"files_reg",
"findcorners_reg",
"findpattern_reg",
"fpix1_reg",
"fpix2_reg",
/* "gifio_reg", */
"graymorph2_reg",
"hardlight_reg",
"insert_reg",
"ioformats_reg",
"jpegio_reg",
"kernel_reg",
"label_reg",
"maze_reg",
"multitype_reg",
"nearline_reg",
"newspaper_reg",
"overlap_reg",
"paint_reg",
"paintmask_reg",
"pdfseg_reg",
"pixa2_reg",
"pixserial_reg",
"pngio_reg",
"projection_reg",
"psio_reg",
"psioseg_reg",
"pta_reg",
"rankbin_reg",
"rankhisto_reg",
"rasteropip_reg",
"rotateorth_reg",
"rotate1_reg",
"rotate2_reg",
"scale_reg",
"seedspread_reg",
"selio_reg",
"shear1_reg",
"shear2_reg",
"skew_reg",
"splitcomp_reg",
"subpixel_reg",
"threshnorm_reg",
"translate_reg",
"warper_reg",
"writetext_reg",
"xformbox_reg",
};

static const char *header = {"\n=======================\n"
"Regression Test Results\n"
"======================="};

int main(int argc,
char **argv)
{
char *str, *results_file;
char command[256], buf[256];
l_int32 i, ntests, dotest, nfail, ret, start, stop;
SARRAY *sa;
static char mainName[] = "alltests_reg";

if (argc != 2)
return ERROR_INT(" Syntax alltests_reg [generate | compare | display]",
mainName, 1);

l_getCurrentTime(&start, NULL);
ntests = sizeof(tests) / sizeof(char *);
fprintf(stderr, "Running alltests_reg:\n"
"This currently tests %d of the 120 Regression Test\n"
"programs in the /prog directory.\n", ntests);

/* Clear the output file if we're doing the set of reg tests */
dotest = strcmp(argv[1], "compare") ? 0 : 1;
if (dotest) {
results_file = genPathname("/tmp", "reg_results.txt");
sa = sarrayCreate(3);
sarrayAddString(sa, (char *)header, L_COPY);
sarrayAddString(sa, getLeptonicaVersion(), L_INSERT);
sarrayAddString(sa, getImagelibVersions(), L_INSERT);
str = sarrayToString(sa, 1);
sarrayDestroy(&sa);
l_binaryWrite("/tmp/reg_results.txt", "w", str, strlen(str));
lept_free(str);
}

nfail = 0;
for (i = 0; i < ntests; i++) {
#ifndef _WIN32
snprintf(command, sizeof(command) - 2, "./%s %s", tests[i], argv[1]);
#else /* windows interprets '/' as a commandline flag */
snprintf(command, sizeof(command) - 2, "%s %s", tests[i], argv[1]);
#endif /* ! _WIN32 */
ret = system(command);
if (ret) {
snprintf(buf, sizeof(buf), "Failed to complete %s\n", tests[i]);
if (dotest) {
l_binaryWrite("/tmp/reg_results.txt", "a", buf, strlen(buf));
nfail++;
}
else
fprintf(stderr, "%s", buf);
}
}

if (dotest) {
#ifndef _WIN32
snprintf(command, sizeof(command) - 2, "cat %s", results_file);
#else
snprintf(command, sizeof(command) - 2, "type \"%s\"", results_file);
#endif /* !_WIN32 */
lept_free(results_file);
ret = system(command);
fprintf(stderr, "Success in %d of %d *_reg programs (output matches"
" the \"golden\" files)\n", ntests - nfail, ntests);
}

l_getCurrentTime(&stop, NULL);
fprintf(stderr, "Time for all regression tests: %d sec\n", stop - start);
return 0;
}