#include
#include
#include
#include "java_wrapper.h"
#ifdef ANDROID
#include
#define LOG(...) __android_log_print(ANDROID_LOG_INFO, "ArrayFireJNI", __VA_ARGS__)
#else
#define LOG(msg,...) do { \
printf(__FILE__":%d: " msg "\n", \
__LINE__, ##__VA_ARGS__); \
} while (0)
#endif
const int MaxDimSupported = 3;
JNIEXPORT void JNICALL Java_com_arrayfire_Array_info(JNIEnv *env, jclass clazz)
{
try{
#ifndef ANDROID
af::info();
#endif
} catch(af::exception& e) {
} catch(std::exception& e) {
}
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createRanduArray(JNIEnv *env, jclass clazz, jintArray dims, jint type)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
af::dtype ty = (af::dtype)(type);
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3], ty);
*A = af::randu(dimptr[0],dimptr[1],dimptr[2], ty);
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createRandnArray(JNIEnv *env, jclass clazz, jintArray dims, jint type)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
af::dtype ty = (af::dtype)(type);
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3], ty);
*A = af::randn(dimptr[0],dimptr[1],dimptr[2], ty);
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createConstantsArray(JNIEnv *env, jclass clazz, jdouble val, jintArray dims, jint type)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
af::dtype ty = (af::dtype)(type);
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3], ty);
*A = af::constant(val, dimptr[0],dimptr[1],dimptr[2], ty);
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createEmptyArray(JNIEnv *env, jclass clazz, jintArray dims, jint type)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
af::dtype ty = (af::dtype)(type);
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3], ty);
*A = af::constant(0.0f,dimptr[0],dimptr[1],dimptr[2], ty);
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
#define CREATE_ARRAY_T_(Ty, ty, wty) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createArrayFrom##Ty \
(JNIEnv *env, jclass clazz, jintArray dims, j##ty##Array elems) \
{ \
jlong ret; \
try{ \
jint* dimptr = env->GetIntArrayElements(dims,0); \
wty* inptr= (wty*)env->Get##Ty##ArrayElements(elems,0); \
af::array *A = new af::array(dimptr[0],dimptr[1], \
dimptr[2],dimptr[3],inptr);\
\
ret = (jlong)(A); \
env->ReleaseIntArrayElements(dims,dimptr,0); \
env->Release##Ty##ArrayElements(elems,(j##ty*)inptr,0); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
} \
#define CREATE_ARRAY_T(Ty, ty) CREATE_ARRAY_T_(Ty, ty, ty)
CREATE_ARRAY_T(Float, float);
CREATE_ARRAY_T(Double, double);
CREATE_ARRAY_T(Int, int);
CREATE_ARRAY_T_(Boolean, boolean, bool);
#undef CREATE_ARRAY_T
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createArrayFromFloatComplex(JNIEnv *env, jclass clazz, jintArray dims, jobjectArray objs)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
jint len = env->GetArrayLength(objs);
static jclass cls;
static jfieldID re, im;
static bool isfirst = true;
if (isfirst) {
cls = env->FindClass("com/arrayfire/FloatComplex");
re = env->GetFieldID(cls, "real", "F");
im = env->GetFieldID(cls, "imag", "F");
isfirst = false;
}
cfloat *tmp = new cfloat[len];
for (int i = 0; i < len; i++) {
jobject obj = env->GetObjectArrayElement(objs, i);
jfloat real = env->GetFloatField(obj, re);
jfloat imag = env->GetFloatField(obj, im);
#ifdef AFCL
tmp[i].s[0] = real;
tmp[i].s[1] = imag;
#else
tmp[i].x = real;
tmp[i].y = imag;
#endif
}
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3],tmp);
delete[] tmp;
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_createArrayFromDoubleComplex(JNIEnv *env, jclass clazz, jintArray dims, jobjectArray objs)
{
jlong ret;
try{
jint* dimptr = env->GetIntArrayElements(dims,0);
jint len = env->GetArrayLength(objs);
static jclass cls;
static jfieldID re, im;
static bool isfirst = true;
cdouble *tmp = new cdouble[len];
for (int i = 0; i < len; i++) {
jobject obj = env->GetObjectArrayElement(objs, i);
if (isfirst) {
cls = env->GetObjectClass(obj);
re = env->GetFieldID(cls, "real", "F");
im = env->GetFieldID(cls, "imag", "F");
isfirst = false;
}
jdouble real = env->GetDoubleField(obj, re);
jdouble imag = env->GetDoubleField(obj, im);
#ifdef AFCL
tmp[i].s[0] = real;
tmp[i].s[1] = imag;
#else
tmp[i].x = real;
tmp[i].y = imag;
#endif
}
af::array *A = new af::array(dimptr[0],dimptr[1],dimptr[2],dimptr[3],tmp);
delete[] tmp;
ret = (jlong)(A);
env->ReleaseIntArrayElements(dims,dimptr,0);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT void JNICALL Java_com_arrayfire_Array_destroyArray(JNIEnv *env, jclass clazz, jlong ref)
{
try{
af::array *A = (af::array*)(ref);
delete A;
} catch(af::exception& e) {
} catch(std::exception& e) {
}
}
#define GET_T_FROM_ARRAY(Ty, ty) \
JNIEXPORT j##ty##Array JNICALL Java_com_arrayfire_Array_get##Ty##FromArray \
(JNIEnv *env, jclass clazz, jlong ref) \
{ \
j##ty##Array result; \
try { \
af::array *A = (af::array*)(ref); \
int size = (*A).elements(); \
result = env->New##Ty##Array(size); \
if (result == NULL) { \
LOG("Something terrible happened. " \
"Couldn't allocate heap space!!!!"); \
return NULL; \
} \
j##ty* resf = env->Get##Ty##ArrayElements(result, 0); \
(*A).host(resf); \
env->Release##Ty##ArrayElements(result, resf, 0); \
} catch(af::exception& e) { \
result = NULL; \
} catch(std::exception& e) { \
result = NULL; \
} \
return result; \
} \
GET_T_FROM_ARRAY(Float, float);
GET_T_FROM_ARRAY(Double, double);
GET_T_FROM_ARRAY(Int, int);
GET_T_FROM_ARRAY(Boolean, boolean);
JNIEXPORT jobjectArray JNICALL Java_com_arrayfire_Array_getFloatComplexFromArray(JNIEnv *env, jclass clazz, jlong ref)
{
jobjectArray result;
try {
af::array *A = (af::array *)(ref);
int size = (*A).elements();
jclass cls = env->FindClass("com/arrayfire/FloatComplex");
jmethodID id = env->GetMethodID(cls, "", "(FF)V");
if (id == NULL) return NULL;
result = env->NewObjectArray(size, cls, NULL);
cfloat *tmp = (*A).host();
for (int i = 0; i < size; i++) {
#ifdef AFCL
float re = tmp[i].s[0];
float im = tmp[i].s[1];
#else
float re = tmp[i].x;
float im = tmp[i].y;
#endif
jobject obj = env->NewObject(cls, id, re, im);
env->SetObjectArrayElement(result, i, obj);
}
af::array::free(tmp);
} catch (af::exception& e) {
result = NULL;
} catch (std::exception& e) {
result = NULL;
}
return result;
}
JNIEXPORT jobjectArray JNICALL Java_com_arrayfire_Array_getDoubleComplexFromArray(JNIEnv *env, jclass clazz, jlong ref)
{
jobjectArray result;
try {
af::array *A = (af::array *)(ref);
int size = (*A).elements();
jclass cls = env->FindClass("com/arrayfire/DoubleComplex");
jmethodID id = env->GetMethodID(cls, "", "(FF)V");
if (id == NULL) return NULL;
result = env->NewObjectArray(size, cls, NULL);
cdouble *tmp = (*A).host();
for (int i = 0; i < size; i++) {
#ifdef AFCL
double re = tmp[i].s[0];
double im = tmp[i].s[1];
#else
double re = tmp[i].x;
double im = tmp[i].y;
#endif
jobject obj = env->NewObject(cls, id, re, im);
env->SetObjectArrayElement(result, i, obj);
}
af::array::free(tmp);
} catch (af::exception& e) {
result = NULL;
} catch (std::exception& e) {
result = NULL;
}
return result;
}
JNIEXPORT jintArray JNICALL Java_com_arrayfire_Array_getDims(JNIEnv *env, jclass clazz, jlong ref)
{
jintArray result;
try {
af::array *A = (af::array*)(ref);
af::dim4 mydims = (*A).dims();
result = env->NewIntArray(MaxDimSupported);
if (result == NULL) {
return NULL;
}
jint* dimsf = env->GetIntArrayElements(result, 0);
for(int k=0; kReleaseIntArrayElements(result, dimsf, 0);
} catch(af::exception& e) {
result = NULL;
} catch(std::exception& e) {
result = NULL;
}
return result;
}
JNIEXPORT jint JNICALL Java_com_arrayfire_Array_getType(JNIEnv *env, jclass clazz, jlong ref)
{
af::array *A = (af::array *)(ref);
jint ty = (jint)((*A).type());
return ty;
}
#define BINARY_OP_DEF(func, operation) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func(JNIEnv *env, jclass clazz, jlong a, jlong b) \
{ \
jlong ret; \
try { \
af::array *A = (af::array*)(a); \
af::array *B = (af::array*)(b); \
af::array *res = new af::array(); \
(*res) = (*A) operation (*B); \
ret = (jlong)(res); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
}
BINARY_OP_DEF(add,+)
BINARY_OP_DEF(sub,-)
BINARY_OP_DEF(mul,*)
BINARY_OP_DEF(div,/)
BINARY_OP_DEF(le,<=)
BINARY_OP_DEF(lt,<)
BINARY_OP_DEF(ge,>=)
BINARY_OP_DEF(gt,>)
BINARY_OP_DEF(eq,==)
BINARY_OP_DEF(ne,!=)
#define UNARY_OP_DEF(func) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func(JNIEnv *env, jclass clazz, jlong a) \
{ \
jlong ret; \
try { \
af::array *A = (af::array*)(a); \
af::array *res = new af::array(); \
(*res) = af::func( (*A) ); \
ret = (jlong)(res); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
}
UNARY_OP_DEF(sin)
UNARY_OP_DEF(cos)
UNARY_OP_DEF(tan)
UNARY_OP_DEF(asin)
UNARY_OP_DEF(acos)
UNARY_OP_DEF(atan)
UNARY_OP_DEF(sinh)
UNARY_OP_DEF(cosh)
UNARY_OP_DEF(tanh)
UNARY_OP_DEF(asinh)
UNARY_OP_DEF(acosh)
UNARY_OP_DEF(atanh)
UNARY_OP_DEF(exp)
UNARY_OP_DEF(log)
UNARY_OP_DEF(abs)
UNARY_OP_DEF(sqrt)
#define SCALAR_RET_OP_DEF(func) \
JNIEXPORT jdouble JNICALL Java_com_arrayfire_Array_##func##All \
(JNIEnv *env, jclass clazz, jlong a) \
{ \
try { \
af::array *A = (af::array*)(a); \
if (A->type() == af::f32) \
return af::func( (*A) ); \
if (A->type() == af::s32) \
return af::func( (*A) ); \
if (A->type() == af::f64) \
return af::func( (*A) ); \
if (A->type() == af::b8) \
return af::func( (*A) ); \
return af::NaN; \
} catch(af::exception& e) { \
return af::NaN; \
} catch(std::exception& e) { \
return af::NaN; \
} \
}
SCALAR_RET_OP_DEF(sum)
SCALAR_RET_OP_DEF(max)
SCALAR_RET_OP_DEF(min)
#define ARRAY_RET_OP_DEF(func) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func \
(JNIEnv *env, jclass clazz, jlong a, jint dim) \
{ \
jlong ret = 0; \
try { \
af::array *A = (af::array*)(a); \
af::array *res = new af::array(); \
*res = af::func((*A), dim); \
ret = (jlong)res; \
} catch(af::exception& e) { \
return 0; \
} catch(std::exception& e) { \
return 0; \
} \
return ret; \
}
ARRAY_RET_OP_DEF(sum)
ARRAY_RET_OP_DEF(max)
ARRAY_RET_OP_DEF(min)
#define FFT_DEF(func) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func \
(JNIEnv *env, jclass clazz, jlong a) \
{ \
jlong ret = 0; \
try { \
af::array *A = (af::array*)(a); \
af::array *res = new af::array(); \
*res = af::func((*A)); \
ret = (jlong)res; \
} catch(af::exception& e) { \
return 0; \
} catch(std::exception& e) { \
return 0; \
} \
return ret; \
}
FFT_DEF(fft)
FFT_DEF(fft2)
FFT_DEF(fft3)
FFT_DEF(ifft)
FFT_DEF(ifft2)
FFT_DEF(ifft3)
#define SCALAR_OP1_DEF(func,operation) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func( \
JNIEnv *env, jclass clazz, jlong a, jfloat b) \
{ \
jlong ret; \
try { \
af::array *A = (af::array*)(a); \
af::array *res = new af::array(); \
(*res) = (*A) operation (b); \
ret = (jlong)(res); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
}
SCALAR_OP1_DEF(addf,+)
SCALAR_OP1_DEF(subf,-)
SCALAR_OP1_DEF(mulf,*)
SCALAR_OP1_DEF(divf,/)
SCALAR_OP1_DEF(lef,<=)
SCALAR_OP1_DEF(ltf,<)
SCALAR_OP1_DEF(gef,>=)
SCALAR_OP1_DEF(gtf,>)
SCALAR_OP1_DEF(eqf,==)
SCALAR_OP1_DEF(nef,!=)
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_pow(JNIEnv *env, jclass clazz, jlong a, jfloat b)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::pow((*A),b);
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
#define SCALAR_OP2_DEF(func,operation) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Array_##func(JNIEnv *env, jclass clazz, jfloat a, jlong b) \
{ \
jlong ret; \
try { \
af::array *B = (af::array*)(b); \
af::array *res = new af::array(); \
(*res) = (a) operation (*B); \
ret = (jlong)(res); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
}
SCALAR_OP2_DEF(fsub,-)
SCALAR_OP2_DEF(fdiv,/)
SCALAR_OP2_DEF(fle,<=)
SCALAR_OP2_DEF(flt,<)
SCALAR_OP2_DEF(fge,>=)
SCALAR_OP2_DEF(fgt,>)
void convert_uchar2float(float** out,unsigned char* in, int size, int chnls)
{
float *temp = *out;
int coff = size;
for (int k = 0; k < size; k++) {
for (int j = 0; j < chnls; j++) {
temp[j * coff + k] = (float)(in[k * chnls + j])/255.0f;
}
}
}
void convert_float2uchar(unsigned char* out, float* in, int size, int chnls)
{
int coff = size;
for (int k = 0; k < size; k++) {
for (int j = 0; j < chnls; j++) {
out[k * chnls + j] = (unsigned char)(255*in[j * coff + k]);
}
out[k * chnls + 3] = 255;
}
}
void blur_logic(unsigned char* bufIn, unsigned char* bufOut, int* info)
{
int width = info[0];
int height = info[1];
int chnls = info[2];
unsigned int imgsz = width*height;
float* inptr = new float[imgsz * chnls];
float* outptr = new float[imgsz * chnls];
convert_uchar2float(&inptr,bufIn,imgsz, chnls);
af::array img(width,height,chnls,inptr);
af::array ker = af::gaussiankernel(5,5);
af::array res = af::convolve(img, ker);
res(af::span, af::span, 3) = 1;
res.host(outptr);
convert_float2uchar(bufOut, outptr, imgsz, chnls);
}
#define MORPH_OP_DEF(func) \
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_##func(JNIEnv *env, jclass clazz, jlong a, jlong b) \
{ \
jlong ret; \
try { \
af::array *A = (af::array*)(a); \
af::array *B = (af::array*)(b); \
af::array *res = new af::array(); \
(*res) = af::func( (*A) , (*B) ); \
ret = (jlong)(res); \
} catch(af::exception& e) { \
ret = 0; \
} catch(std::exception& e) { \
ret = 0; \
} \
return ret; \
}
MORPH_OP_DEF(erode)
MORPH_OP_DEF(dilate)
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_convolve(JNIEnv *env, jclass clazz, jlong a, jlong b)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *B = (af::array*)(b);
af::array *res = new af::array();
(*res) = af::convolve( (*A) , (*B) );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_medfilt(JNIEnv *env, jclass clazz, jlong a, jint w, jint h)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::medfilt( (*A) , w, h );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_bilateral(JNIEnv *env, jclass clazz, jlong a, jfloat space, jfloat color)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::bilateral( (*A) , space, color );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_meanshift(JNIEnv *env, jclass clazz, jlong a, jfloat space, jfloat color, jint iter)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::meanshift( (*A) , space, color, iter );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_histogram(JNIEnv *env, jclass clazz, jlong a, jint nbins)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::histogram( (*A) , nbins );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_hist_mnmx(JNIEnv *env, jclass clazz, jlong a, jint nbins, jfloat min, jfloat max)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::histogram( (*A) , nbins, min, max );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_rotate(JNIEnv *env, jclass clazz, jlong a, jfloat theta, jboolean crop)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::rotate( (*A) , theta, crop );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_resize1(JNIEnv *env, jclass clazz, jlong a, jfloat scale, jchar method)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::resize( scale, (*A) , method );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_resize2(JNIEnv *env, jclass clazz, jlong a, jfloat scalex, jfloat scaley, jchar method)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::resize( scalex, scaley, (*A) , method );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}
JNIEXPORT jlong JNICALL Java_com_arrayfire_Image_resize3(JNIEnv *env, jclass clazz, jlong a, jint height, jint width, jchar method)
{
jlong ret;
try {
af::array *A = (af::array*)(a);
af::array *res = new af::array();
(*res) = af::resize( (unsigned int)height, (unsigned int)width, (*A) , method );
ret = (jlong)(res);
} catch(af::exception& e) {
ret = 0;
} catch(std::exception& e) {
ret = 0;
}
return ret;
}