Ejemplo n.º 1
0
/**
 * 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);
}