1

In Java, I have the user select an image file. I then decode it, covert to PNG, and pass through to JNI. I suspect that I do not need to copy and allocate so much memory constantly. How can I pare this down? Is there a way I can detect if the image type is JPEG or PNG and not decode & re-encode the bitmap and just pass the original JPEG/PNG data? Or do the conversion with fewer allocations? Right now it is eating up a LOT of memory.

Java:

Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
yourSelectedImage.compress(Bitmap.CompressFormat.PNG, 100, outStream);
byte[] byteData = outStream.toByteArray();

JNILib.PickedImage(byteData);

In C, I have the following code for PickedImage:

jbyte *b = (jbyte*)env->GetByteArrayElements(data, NULL);
jsize dataSize = env->GetArrayLength(data);
byte* imageData = (byte*)malloc(dataSize);
memcpy(imageData, b, dataSize);
env->ReleaseByteArrayElements(data, b, 0);

imageSelectCallback(imageData, dataSize);
user1054922
  • 1,917
  • 2
  • 20
  • 34
  • Have a look at [this question](http://stackoverflow.com/questions/9643228/test-if-file-is-an-image) - it may give you some clues – Aleks G Sep 24 '14 at 20:03

1 Answers1

0

Use a java.nio.ByteBuffer and call the allocateDirect function to allocate memory accessible by both Java and C. Then in C, get the pointer to the buffer by doing: env->GetDirectBufferAddress and the size of it by doing env->GetDirectBufferCapacity.

This way, you only have ONE buffer shared by both sides of the same coin. Both Java and C will be operating on the same image.

So again, read the file into a java.nio.ByteBuffer and pass that to C. If C needs a COPY of the image, then you'll have no choice but to allocate 2 buffers (like you are doing now).. I suspect that you don't need a copy and that it's okay for you to modify the buffer given to you by Java..

Brandon
  • 20,445
  • 9
  • 73
  • 162