In JNI I have a pointer to an 8-bit integer array (uint8_t*). I want to pass its data to Java part.
My problem is, that data in array must be in uint_8 format, because I achieved it as colour information from a bitmap of format RGB565, which I want to change into grayscale:
Java part:
private void loadJPEG(String fileName) {
Bitmap old = BitmapFactory.decodeFile(fileName);
Bitmap bmp = old.copy(Config.RGB_565, false);
byte[] grayScaledBitmap = new byte[]{};
if (bmp != null && bmp.getConfig() == Bitmap.Config.RGB_565) {
ShortBuffer rgbBuf = ShortBuffer.allocate(bmp.getWidth() * bmp.getHeight());
bmp.copyPixelsToBuffer(rgbBuf);
grayScaledBitmap = convertToLum(rgbBuf.array(), bmp.getWidth(), bmp.getHeight());
}
}
private native byte[] convertToLum(short[] data, int w, int h);
C++ part:
void convertRGB565ToGrayScale(JNIEnv* env, uint8_t* src, unsigned int srcWidth, unsigned int srcHeight, uint8_t* dst) {
unsigned int size = srcWidth * srcHeight;
uint16_t rgb;
uint16_t r;
uint16_t g;
uint16_t b;
for (unsigned int i = 0; i < size; i++) {
rgb = ((uint16_t*) src)[i];
uint16_t tmp = (uint16_t) (rgb & 0xF800);
tmp = tmp >> 8;
r = (uint16_t) ((rgb & 0xF800) >> 8); //to rgb888
g = (uint16_t) ((rgb & 0x07E0) >> 3);
b = (uint16_t) ((rgb & 0x001F) << 3);
dst[i] = (uint8_t) (((r << 1) + (g << 2) + g + b) >> 3); //to grayscale
}
}
JNIEXPORT jbyteArray JNICALL Java_com_qualcomm_loadjpeg_LoadJpeg_convertToLum(JNIEnv* env, jobject obj, jshortArray img, jint w, jint h) {
jshort* jimgData = NULL;
jboolean isCopy = 0;
jbyte* grayScaled;
jbyteArray arrayToJava
DPRINTF("%s %d\n", __FILE__, __LINE__);
if (img != NULL) {
// Get data from JNI
jimgData = env->GetShortArrayElements(img, &isCopy);
uint8_t* lum = (uint8_t*) fcvMemAlloc(w * h, 16);
convertRGB565ToGrayScale(env, (uint8_t*) jimgData, w, h, lum);
grayScaled = (jbyte*) lum;
arrayToJava = env->NewByteArray(w*h);
env->SetByteArrayRegion(arrayToJava, 0, w*h, grayScaled);
env->ReleaseShortArrayElements(img, jimgData, JNI_ABORT);
fcvMemFree(lum);
DPRINTF("%s %d Done\n", __FILE__, __LINE__);
}
return arrayToJava;
}
The error comes on line with SetShortArrayRegion function:
No source available for memcpy() at [hexadecimal adress]
No source available for ioctl() at ...
EDIT >> the error above no longer appears, it was caused because of bad memory-freeing via fcvmemfree, code is re-editet. I have still a problem with filling jbyteArray arrayToJava with data from convertRGB565ToGrayScale, it is always empty after SetByteArrayRegion call. The question is still:
How am I supposed to pass changed data to Java part?