/** * Load Java ImageData instance with image data in RAW format. * Image data is provided either in native buffer, or in Java * byte array. Java array is used with more priority. * * @param imageData Java ImageData object to be loaded with image data * @param nativeBuffer pointer to native buffer with raw image data, * this parameter is alternative to javaBuffer * @param javaBuffer Java byte array with raw image data, * this parameter is alternative to nativeBuffer * @param offset offset of the raw image data in the buffer * @param length length of the raw image data in the buffer * starting from the offset * * @return KNI_TRUE in the case ImageData is successfully loaded with * raw image data, otherwise KNI_FALSE. */ static int gx_load_imagedata_from_raw_buffer(KNIDECLARGS kjobject imageData, unsigned char *nativeBuffer, kjobject javaBuffer, int offset, int length) { int imageSize; int pixelSize, alphaSize; int status = KNI_FALSE; gxutl_image_buffer_raw *rawBuffer = NULL; KNI_StartHandles(2); KNI_DeclareHandle(pixelData); KNI_DeclareHandle(alphaData); do { /** Check native and Java buffer parameters */ if (!KNI_IsNullHandle(javaBuffer)) { if (nativeBuffer != NULL) { REPORT_ERROR(LC_LOWUI, "Native and Java buffers should not be used together"); break; } nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS javaBuffer, offset, length); } if (nativeBuffer == NULL) { REPORT_ERROR(LC_LOWUI, "Null raw image buffer is provided"); break; } /** Check header */ rawBuffer = (gxutl_image_buffer_raw *)(nativeBuffer + offset); if (memcmp(rawBuffer->header, gxutl_raw_header, 4) != 0) { REPORT_ERROR(LC_LOWUI, "Unexpected raw image type"); break; } imageSize = rawBuffer->width * rawBuffer->height; pixelSize = sizeof(gxj_pixel_type) * imageSize; alphaSize = 0; if (rawBuffer->hasAlpha) { alphaSize = sizeof(gxj_alpha_type) * imageSize; } /** Check data array length */ if ((unsigned int)length != (offsetof(gxutl_image_buffer_raw, data) + pixelSize + alphaSize)) { REPORT_ERROR(LC_LOWUI, "Raw image is corrupted"); break; } if (rawBuffer->hasAlpha) { /* Has alpha */ SNI_NewArray(SNI_BYTE_ARRAY, alphaSize, alphaData); if (KNI_IsNullHandle(alphaData)) { KNI_ThrowNew(midpOutOfMemoryError, NULL); break; } /** Link the new array into ImageData to protect if from GC */ midp_set_jobject_field(KNIPASSARGS imageData, "alphaData", "[B", alphaData); /** New array allocation could cause GC and buffer moving */ if (!KNI_IsNullHandle(javaBuffer)) { nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS javaBuffer, offset, length); rawBuffer = (gxutl_image_buffer_raw *) (nativeBuffer + offset); } memcpy(JavaByteArray(alphaData), rawBuffer->data + pixelSize, alphaSize); } SNI_NewArray(SNI_BYTE_ARRAY, pixelSize, pixelData); if (KNI_IsNullHandle(pixelData)) { KNI_ThrowNew(midpOutOfMemoryError, NULL); break; } midp_set_jobject_field(KNIPASSARGS imageData, "pixelData", "[B", pixelData); /** New array allocation could cause GC and buffer moving */ if (!KNI_IsNullHandle(javaBuffer)) { nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS javaBuffer, offset, length); rawBuffer = (gxutl_image_buffer_raw *) (nativeBuffer + offset); } memcpy(JavaByteArray(pixelData), rawBuffer->data, pixelSize); GXAPI_GET_IMAGEDATA_PTR(imageData)->width = (jint)rawBuffer->width; GXAPI_GET_IMAGEDATA_PTR(imageData)->height = (jint)rawBuffer->height; status = KNI_TRUE; } while(0); KNI_EndHandles(); return status; }
/** * Decodes the given byte array into the <tt>ImageData</tt>. * <p> * Java declaration: * <pre> * loadNative(Ljavax/microedition/lcdui/ImageDataFactory;[BII)Z * </pre> * * @param imageData the ImageData to load to * @param imageBytes A byte array containing the encoded PNG image data * @param offset The start of the image data within the byte array * @param length The length of the image data in the byte array * * @return true if able to decode */ KNIEXPORT KNI_RETURNTYPE_BOOLEAN KNIDECL(javax_microedition_lcdui_ImageDataFactory_loadNative) { int length = KNI_GetParameterAsInt(4); int offset = KNI_GetParameterAsInt(3); int status = KNI_TRUE; unsigned char* srcBuffer = NULL; PIXEL* imgPixelData = NULL; ALPHA* imgAlphaData = NULL; java_imagedata* midpImageData = NULL; TBool generateMask = EFalse; KNI_StartHandles(4); KNI_DeclareHandle(pixelData); KNI_DeclareHandle(alphaData); KNI_DeclareHandle(inData); KNI_DeclareHandle(imageData); KNI_GetParameterAsObject(2, inData); KNI_GetParameterAsObject(1, imageData); midpImageData = IMGAPI_GET_IMAGEDATA_PTR(imageData); srcBuffer = (unsigned char *)JavaByteArray(inData); int byteArrayLength = KNI_GetArrayLength(inData); if (offset >= 0 && length >= 0 && offset + length <= byteArrayLength) { TPtrC8 sourceData(srcBuffer + offset, length); TInt width; TInt height; if (static_cast<MApplication*>(Dll::Tls())->InitializeDecoder(sourceData, width, height, generateMask) == KErrNone) { midpImageData->width = width; midpImageData->height = height; SNI_NewArray(SNI_BYTE_ARRAY, midpImageData->width * midpImageData->height * 2, pixelData); if (generateMask) { SNI_NewArray(SNI_BYTE_ARRAY, midpImageData->width * midpImageData->height, alphaData); } if (!KNI_IsNullHandle(pixelData) && (!KNI_IsNullHandle(alphaData) || !generateMask)) { if (generateMask) { imgAlphaData = (ALPHA*)JavaByteArray(alphaData); } midp_set_jobject_field(KNIPASSARGS imageData, "pixelData", "[B", pixelData); imgPixelData = (PIXEL*)JavaByteArray(pixelData); if (static_cast<MApplication*>(Dll::Tls())->DecodeImage((char*)imgPixelData, (char*)imgAlphaData) != KErrNone) { status = KNI_FALSE; } if (imgAlphaData) { midp_set_jobject_field(KNIPASSARGS imageData, "alphaData", "[B", alphaData); } } else { status = KNI_FALSE; } } } KNI_EndHandles(); KNI_ReturnBoolean(status); }