imggci_imagedatafactory_kni.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 918 行 · 第 1/2 页

C
918
字号
/* * * * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  */#include <stddef.h>#include <string.h>#include <sni.h>#include <commonKNIMacros.h>#include <midpUtilKni.h>#include <midpMalloc.h>#include <gxapi_constants.h>#include <imgapi_image.h>#include <img_errorcodes.h>#include <img_imagedata_load.h>#include <imgdcd_image_util.h>/** Convenenient for convert Java image object to screen buffer */#define getImageData(jimgData, width, height, pixelData, alphaData)       \       imggci_get_image_data(IMGAPI_GET_IMAGEDATA_PTR(jimgData),          \                                            width, height,        \                                            pixelData, alphaData)/** Convert 24-bit RGB color to 16bit (565) color */#define RGB24TORGB16(x) (((( x ) & 0x00F80000) >> 8) + \                             ((( x ) & 0x0000FC00) >> 5) + \                             ((( x ) & 0x000000F8) >> 3) )/** Convert 16-bit (565) color to 24-bit RGB color */#define RGB16TORGB24(x) ( ((x & 0x001F) << 3) | ((x & 0x001C) >> 2) |\                              ((x & 0x07E0) << 5) | ((x & 0x0600) >> 1) |\                              ((x & 0xF800) << 8) | ((x & 0xE000) << 3) )#define PIXEL imgdcd_pixel_type#define ALPHA imgdcd_alpha_type/** * Create native representation for a image. * * @param jimg Java Image ROM structure to convert from * @param width to populate * @param height to populate * @param pixelData to populate * @param alphaData to populate * @param g optional Graphics object for debugging clip code. *            give NULL if don't care. * * @return KNI_TRUE if image data was retrieved  *           or KNI_FALSE if the image is null. */static int imggci_get_image_data(const java_imagedata *img,                                 int *width, int *height,                                 PIXEL **pixelData,                                 ALPHA **alphaData) {    /* NOTE:     * Since this routine is called by every graphics operations     * We use ROMStruct directly instead of macros     * like JavaByteArray, etc, for max performance.     */    if (img == NULL) {        return KNI_FALSE;    }    *width  = img->width;    *height = img->height;    /* Only use nativePixelData and nativeAlphaData if     * pixelData is null */    if (img->pixelData != NULL) {        *pixelData = (PIXEL *)&(img->pixelData->elements[0]);        *alphaData = (img->alphaData != NULL)          ? (ALPHA *)&(img->alphaData->elements[0])          : NULL;    } else {        *pixelData = (PIXEL *)img->nativePixelData;        *alphaData = (ALPHA *)img->nativeAlphaData;    }    return KNI_TRUE;}/** * Decodes the given input data into a cache representation that can * be saved and loaded quickly. * The input data should be in a self-identifying format; that is, * the data must contain a description of the decoding process. * *  @param srcBuffer input data to be decoded. *  @param length length of the input data. *  @param ret_dataBuffer pointer to the platform representation data that *         be saved. *  @param ret_length pointer to the length of the return data. *  @return one of error codes: *              MIDP_ERROR_NONE, *              MIDP_ERROR_OUT_MEM, *              MIDP_ERROR_UNSUPPORTED, *              MIDP_ERROR_OUT_OF_RESOURCE, *              MIDP_ERROR_IMAGE_CORRUPTED */MIDP_ERROR img_decode_data2cache(unsigned char* srcBuffer,                                 unsigned int length,                                 unsigned char** ret_dataBuffer,                                 unsigned int* ret_length) {    unsigned int pixelSize, alphaSize;    imgdcd_image_format format;    MIDP_ERROR err;    int width, height;    PIXEL  *pixelData;    ALPHA  *alphaData;    imgdcd_image_buffer_raw *rawBuffer;    img_native_error_codes creationError = IMG_NATIVE_IMAGE_NO_ERROR;    err = imgdcd_image_get_info(srcBuffer, length,                                &format, (unsigned int *)&width,                                (unsigned int *)&height);    if (err != MIDP_ERROR_NONE) {        return err;    }    pixelSize = sizeof(PIXEL) * width * height;    alphaSize = sizeof(ALPHA) * width * height;    switch (format) {    case IMGDCD_IMAGE_FORMAT_JPEG:        /* JPEG does not contain alpha data */        alphaSize = 0;        /* Fall through */    case IMGDCD_IMAGE_FORMAT_PNG:        /* Decode PNG/JPEG to screen buffer format */        rawBuffer = (imgdcd_image_buffer_raw *)          midpMalloc(offsetof(imgdcd_image_buffer_raw, data)+pixelSize+alphaSize);        if (rawBuffer == NULL) {            return MIDP_ERROR_OUT_MEM;        }        pixelData = (PIXEL *)rawBuffer->data;        if (format == IMGDCD_IMAGE_FORMAT_PNG) {            alphaData = rawBuffer->data + pixelSize;            rawBuffer->hasAlpha = imgdcd_decode_png(srcBuffer, length,                                                    width, height,                                                    pixelData, alphaData,                                                    &creationError);            if (!rawBuffer->hasAlpha) {                alphaData = NULL;                alphaSize = 0; /* Exclude alpha data */            }        } else {            alphaData = NULL;            rawBuffer->hasAlpha = KNI_FALSE;            imgdcd_decode_jpeg(srcBuffer, length,                               width, height,                               pixelData, alphaData,                               &creationError);        }        if (IMG_NATIVE_IMAGE_NO_ERROR != creationError) {            midpFree(rawBuffer);            return MIDP_ERROR_IMAGE_CORRUPTED;        }        memcpy(rawBuffer->header, imgdcd_raw_header, 4);        rawBuffer->width  = width;        /* Use default endian */        rawBuffer->height = height;        /* Use default endian */        *ret_dataBuffer = (unsigned char *)rawBuffer;        *ret_length = offsetof(imgdcd_image_buffer_raw, data)+pixelSize+alphaSize;        return MIDP_ERROR_NONE;    case IMGDCD_IMAGE_FORMAT_RAW:        /* Already in screen buffer format, simply copy the data */        *ret_dataBuffer = (unsigned char *)midpMalloc(length);        if (*ret_dataBuffer == NULL) {            return MIDP_ERROR_OUT_MEM;        } else {            memcpy(*ret_dataBuffer, srcBuffer, length);            *ret_length = length;            return MIDP_ERROR_NONE;        }    default:        return MIDP_ERROR_UNSUPPORTED;    } /* switch (image_type) */}/** * Get pointer to internal buffer of Java byte array and * check that expected offset/length can be applied to the buffer * * @param byteArray Java byte array object to get buffer from * @param offset offset of the data needed in the buffer * @param length length of the data needed in the buffer *          starting from the offset * @return pointer to the buffer, or NULL if offset/length are *    are not applicable. */static unsigned char *get_java_byte_buffer(KNIDECLARGS jobject byteArray,                                            int offset, int length) {    unsigned char *buffer = (unsigned char *)JavaByteArray(byteArray);    int byteArrayLength = KNI_GetArrayLength(byteArray);    if (offset < 0 || length < 0 || offset + length > byteArrayLength ) {        KNI_ThrowNew(midpArrayIndexOutOfBoundsException, NULL);        return NULL;    }    return buffer;}/** * 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 load_imagedata_from_raw_buffer(KNIDECLARGS jobject imageData,    unsigned char *nativeBuffer, jobject javaBuffer,    int offset, int length) {    int imageSize;    int pixelSize, alphaSize;    int status = KNI_FALSE;    imgdcd_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 = 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 = (imgdcd_image_buffer_raw *)(nativeBuffer + offset);        if (memcmp(rawBuffer->header, imgdcd_raw_header, 4) != 0) {            REPORT_ERROR(LC_LOWUI, "Unexpected raw image type");            break;        }        imageSize = rawBuffer->width * rawBuffer->height;        pixelSize = sizeof(PIXEL) * imageSize;        alphaSize = 0;        if (rawBuffer->hasAlpha) {            alphaSize = sizeof(ALPHA) * imageSize;        }        /** Check data array length */        if ((unsigned int)length !=            (offsetof(imgdcd_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 = get_java_byte_buffer(KNIPASSARGS                    javaBuffer, offset, length);                rawBuffer = (imgdcd_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 = get_java_byte_buffer(KNIPASSARGS                javaBuffer, offset, length);            rawBuffer = (imgdcd_image_buffer_raw *)                (nativeBuffer + offset);        }            memcpy(JavaByteArray(pixelData), rawBuffer->data, pixelSize);        IMGAPI_GET_IMAGEDATA_PTR(imageData)->width =            (jint)rawBuffer->width;        IMGAPI_GET_IMAGEDATA_PTR(imageData)->height =            (jint)rawBuffer->height;        status = KNI_TRUE;    } while(0);    KNI_EndHandles();    return status;}/** * Load Java ImageData instance with image data in RAW format. * Image data is provided in native buffer. * * @param imageData Java ImageData object to be loaded with image data * @param buffer pointer to native buffer with raw image data * @param length length of the raw image data in the buffer * * @return KNI_TRUE in the case ImageData is successfully loaded with *    raw image data, otherwise KNI_FALSE. */int img_load_imagedata_from_raw_buffer(KNIDECLARGS jobject imageData,    unsigned char *buffer, int length) {    int status = KNI_FALSE;    KNI_StartHandles(1);    /* A handle for which KNI_IsNullHandle() check is true */    KNI_DeclareHandle(nullHandle);    status = load_imagedata_from_raw_buffer(KNIPASSARGS                    imageData, buffer, nullHandle, 0, length);    KNI_EndHandles();    return status;}/** * Loads the <tt>ImageData</tt> with the given raw data array. * The array consists of raw image data including header info. * <p> * Java declaration: * <pre> *     loadRAW(Ljavax/microedition/lcdui/ImageData;[B)V * </pre> * * @param imageData The instance of ImageData to be loaded from array * @param imageBytes The array of raw image data * @param imageOffset the offset of the start of the data in the array * @param imageLength the length of the data in the array */KNIEXPORT KNI_RETURNTYPE_VOIDKNIDECL(javax_microedition_lcdui_ImageDataFactory_loadRAW) {    int offset = KNI_GetParameterAsInt(3);    int length = KNI_GetParameterAsInt(4);    KNI_StartHandles(2);    KNI_DeclareHandle(imageData);    KNI_DeclareHandle(imageBytes);    KNI_GetParameterAsObject(1, imageData);    KNI_GetParameterAsObject(2, imageBytes);    /* Load ImageData content from Java byte array with raw image data */    if (load_imagedata_from_raw_buffer(KNIPASSARGS            imageData, NULL, imageBytes, offset, length) != KNI_TRUE) {        KNI_ThrowNew(midpIllegalArgumentException, NULL);    }    KNI_EndHandles();    KNI_ReturnVoid();}/** * Decodes the given byte array into the <tt>ImageData</tt>. * <p> * Java declaration: * <pre> *     loadPNG(Ljavax/microedition/lcdui/ImageData;[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 there is alpha data */KNIEXPORT KNI_RETURNTYPE_BOOLEANKNIDECL(javax_microedition_lcdui_ImageDataFactory_loadPNG) {    int            length = KNI_GetParameterAsInt(4);    int            offset = KNI_GetParameterAsInt(3);    int            status = KNI_TRUE;    unsigned char* srcBuffer = NULL;        PIXEL *imgPixelData;    ALPHA *imgAlphaData;    java_imagedata * midpImageData = NULL;    /* variable to hold error codes */    img_native_error_codes creationError = IMG_NATIVE_IMAGE_NO_ERROR;    KNI_StartHandles(4);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?