Tengo un código de procesamiento de imágenes Java en Android que actúa sobre dos matrices int grandes. La mayoría de las veces, Java es lo suficientemente rápido, pero necesito usar C a través de JNI y NDK para acelerar algunas operaciones.Envío de int [] s entre Java y C
La única forma en que sé que puedo pasar los datos de las matrices en int a C es usar ByteBuffer.allocateDirect para crear un nuevo búfer, copiar los datos a eso y luego hacer que el código C actúe sobre el búfer.
Sin embargo, no veo ninguna manera de manipular los datos en este búfer en Java como si el búfer fuera un int [] o un byte []. Por ejemplo, una llamada a ByteBuffer.array() fallará en el búfer recién creado. ¿Hay alguna manera de hacer funcionar esto?
Tengo memoria limitada y quiero reducir la cantidad de matrices/almacenamientos intermedios que necesito. Por ejemplo, sería bueno si pudiera usar IntBuffer.wrap (new int [...]) para crear el búfer y luego manipular la matriz que respalda el búfer directamente en Java, pero no puedo hacer esto porque lo único que parece trabajar aquí para JNI es ByteBuffer.allocateDirect.
¿Hay alguna otra forma de enviar y recibir datos entre C y Java? ¿Puedo de alguna manera asignar memoria en el lado C y hacer que Java envíe datos directamente a allí?
Editar: Un punto de referencia que compara el uso de tampón a int [] uso:
int size = 1000;
IntBuffer allocateDirect = java.nio.ByteBuffer.allocateDirect(4 * size).asIntBuffer();
for (int i = 0; i < 100; ++i)
{
for (int x = 0; x < size; ++x)
{
int v = allocateDirect.get(x);
allocateDirect.put(x, v + 1);
}
}
int[] intArray = new int[size];
for (int i = 0; i < 100; ++i)
{
for (int x = 0; x < size; ++x)
{
int v = intArray[x];
intArray[x] = v + 1;
}
}
En un teléfono Droid, la versión tampón toma ~ 10 segundos para terminar y la versión de matriz toma ~ 0.01 segundos.
Espera, ¿qué pasa con [ 'ByteBuffer.asIntBuffer'] (http://developer.android.com/reference/java/nio/ByteBuffer.html#asIntBuffer%28%29)? ¿De verdad necesitas tener un 'int []'? – ephemient
... y, además, puede llamar .array() en el IntBuffer si así lo desea. – mpontillo
.array() arroja una excepción no admitida para ByteBuffer e IntBuffer para las matrices directamente asignadas en Java. Realmente quiero acceder a un int [] para poder hacer algunas de las tareas de procesamiento de imágenes menos intensivas en Java, p. Ej. convierta una imagen a blanco y negro verificando qué píxeles están por encima/debajo de un umbral de brillo. Usar IntBuffer get/put para cada píxel sería demasiado lento en Android, además de torpe. – rbcc