Nikoi
Nikoi

Reputation: 389

create big arrays from jni (ndk) and return them to android

I am developing an aplication where I need to read large image files (6000x6000) ,then applying some filtering (like blurring and color effects) and then saving the image. The filtering library is a 3rd party library that is programmed in Java and take something like this as a input :

/**
* rgbArray : is an Array of pixels 
*/
public int[] ImageFiltering(int[] rgbArray,int Width,int Height);

The problem is that if I load the image in memory (6000 x 6000 x 4 = 137.33 MB) android throws OutOfMemory error. After reading some documentation and knowing that the memory allocated from NDK is not part of the application heap ,I get an interesting idea:

  1. Open the image from NDK Read it contents and save it in an array

  2. Pass the array back to Java

  3. Apply filter to the array data

  4. Return the array to NDK

  5. Save the data array into a new image and release the array memory

Here is an example of NDK function with returns the big,fat array:

jint*
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz,jint w,jint h)
{

    int* pixels = (int*)malloc(w * h * 4);
    read_image_into_array("image.jpg",pixels);

    return pixels;
}

The goal is to reserve the memory in native in order to avoid getting OutOfMemory error,and pass the memory reference to Java in order to work with it. Since I am have not C developer and have never touched JNI ,is all this making sense and how could it be implemented in NDK.

Upvotes: 1

Views: 1236

Answers (1)

technomage
technomage

Reputation: 10069

Use a direct ByteBuffer, using the allocated memory as its backing buffer. You can allocate a direct byte buffer from JNI (using NewDirectByteBuffer()) and return it.

You'll need to provide a complementary method for disposing of the memory or otherwise indicating to the native side that it is no longer in use.

Upvotes: 1

Related Questions