0N/A/*
3261N/A * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include "BufImgSurfaceData.h"
4632N/A#include <stdlib.h>
0N/A
0N/A#include "sun_awt_image_BufImgSurfaceData.h"
0N/A
0N/A#include "img_util_md.h"
0N/A#include "jni_util.h"
0N/A/* Define uintptr_t */
0N/A#include "gdefs.h"
0N/A
0N/A/**
0N/A * This include file contains support code for loops using the
0N/A * SurfaceData interface to talk to an X11 drawable from native
0N/A * code.
0N/A */
0N/A
0N/Astatic LockFunc BufImg_Lock;
0N/Astatic GetRasInfoFunc BufImg_GetRasInfo;
0N/Astatic ReleaseFunc BufImg_Release;
0N/Astatic DisposeFunc BufImg_Dispose;
0N/A
0N/Astatic ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo);
0N/A
0N/Astatic jfieldID rgbID;
0N/Astatic jfieldID mapSizeID;
2895N/Astatic jfieldID colorDataID;
2895N/Astatic jfieldID pDataID;
0N/Astatic jfieldID allGrayID;
0N/A
2895N/Astatic jclass clsICMCD;
2895N/Astatic jmethodID initICMCDmID;
0N/A/*
0N/A * Class: sun_awt_image_BufImgSurfaceData
0N/A * Method: initIDs
0N/A * Signature: ()V
0N/A */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_image_BufImgSurfaceData_initIDs
2895N/A(JNIEnv *env, jclass bisd, jclass icm, jclass cd)
0N/A{
0N/A if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
0N/A JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
0N/A return;
0N/A }
0N/A
2895N/A clsICMCD = (*env)->NewWeakGlobalRef(env, cd);
2895N/A initICMCDmID = (*env)->GetMethodID(env, cd, "<init>", "(J)V");
2895N/A pDataID = (*env)->GetFieldID(env, cd, "pData", "J");
2895N/A
0N/A rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I");
0N/A allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z");
0N/A mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I");
2895N/A colorDataID = (*env)->GetFieldID(env, icm, "colorData",
2895N/A "Lsun/awt/image/BufImgSurfaceData$ICMColorData;");
2895N/A if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || pDataID == 0|| colorDataID == 0 || initICMCDmID == 0) {
0N/A JNU_ThrowInternalError(env, "Could not get field IDs");
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_java2d_SurfaceData
0N/A * Method: freeNativeICMData
0N/A * Signature: (Ljava/awt/image/IndexColorModel;)V
0N/A */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_image_BufImgSurfaceData_freeNativeICMData
2895N/A (JNIEnv *env, jclass sd, jlong pData)
0N/A{
2895N/A ColorData *cdata = (ColorData*)jlong_to_ptr(pData);
0N/A freeICMColorData(cdata);
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_awt_image_BufImgSurfaceData
0N/A * Method: initOps
0N/A * Signature: (Ljava/lang/Object;IIIII)V
0N/A */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_image_BufImgSurfaceData_initRaster(JNIEnv *env, jobject bisd,
0N/A jobject array,
0N/A jint offset, jint bitoffset,
0N/A jint width, jint height,
0N/A jint pixStr, jint scanStr,
0N/A jobject icm)
0N/A{
0N/A BufImgSDOps *bisdo =
0N/A (BufImgSDOps*)SurfaceData_InitOps(env, bisd, sizeof(BufImgSDOps));
2514N/A if (bisdo == NULL) {
2514N/A JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
2514N/A return;
2514N/A }
0N/A bisdo->sdOps.Lock = BufImg_Lock;
0N/A bisdo->sdOps.GetRasInfo = BufImg_GetRasInfo;
0N/A bisdo->sdOps.Release = BufImg_Release;
0N/A bisdo->sdOps.Unlock = NULL;
0N/A bisdo->sdOps.Dispose = BufImg_Dispose;
0N/A bisdo->array = (*env)->NewWeakGlobalRef(env, array);
0N/A bisdo->offset = offset;
0N/A bisdo->bitoffset = bitoffset;
0N/A bisdo->scanStr = scanStr;
0N/A bisdo->pixStr = pixStr;
0N/A if (JNU_IsNull(env, icm)) {
0N/A bisdo->lutarray = NULL;
0N/A bisdo->lutsize = 0;
0N/A bisdo->icm = NULL;
0N/A } else {
0N/A jobject lutarray = (*env)->GetObjectField(env, icm, rgbID);
0N/A bisdo->lutarray = (*env)->NewWeakGlobalRef(env, lutarray);
0N/A bisdo->lutsize = (*env)->GetIntField(env, icm, mapSizeID);
0N/A bisdo->icm = (*env)->NewWeakGlobalRef(env, icm);
0N/A }
0N/A bisdo->rasbounds.x1 = 0;
0N/A bisdo->rasbounds.y1 = 0;
0N/A bisdo->rasbounds.x2 = width;
0N/A bisdo->rasbounds.y2 = height;
0N/A}
0N/A
0N/A/*
0N/A * Method for disposing native BufImgSD
0N/A */
0N/Astatic void BufImg_Dispose(JNIEnv *env, SurfaceDataOps *ops)
0N/A{
0N/A /* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
0N/A BufImgSDOps *bisdo = (BufImgSDOps *)ops;
0N/A (*env)->DeleteWeakGlobalRef(env, bisdo->array);
0N/A if (bisdo->lutarray != NULL) {
0N/A (*env)->DeleteWeakGlobalRef(env, bisdo->lutarray);
0N/A }
0N/A if (bisdo->icm != NULL) {
0N/A (*env)->DeleteWeakGlobalRef(env, bisdo->icm);
0N/A }
0N/A}
0N/A
0N/Astatic jint BufImg_Lock(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo,
0N/A jint lockflags)
0N/A{
0N/A BufImgSDOps *bisdo = (BufImgSDOps *)ops;
0N/A BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
0N/A
0N/A if ((lockflags & (SD_LOCK_LUT)) != 0 && JNU_IsNull(env, bisdo->lutarray)) {
0N/A /* REMIND: Should this be an InvalidPipe exception? */
0N/A JNU_ThrowNullPointerException(env, "Attempt to lock missing colormap");
0N/A return SD_FAILURE;
0N/A }
0N/A if ((lockflags & SD_LOCK_INVCOLOR) != 0 ||
0N/A (lockflags & SD_LOCK_INVGRAY) != 0)
0N/A {
0N/A bipriv->cData = BufImg_SetupICM(env, bisdo);
0N/A if (bipriv->cData == NULL) {
0N/A JNU_ThrowNullPointerException(env, "Could not initialize "
0N/A "inverse tables");
0N/A return SD_FAILURE;
0N/A }
0N/A } else {
0N/A bipriv->cData = NULL;
0N/A }
0N/A
0N/A bipriv->lockFlags = lockflags;
0N/A bipriv->base = NULL;
0N/A bipriv->lutbase = NULL;
0N/A
0N/A SurfaceData_IntersectBounds(&pRasInfo->bounds, &bisdo->rasbounds);
0N/A
0N/A return SD_SUCCESS;
0N/A}
0N/A
0N/Astatic void BufImg_GetRasInfo(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo)
0N/A{
0N/A BufImgSDOps *bisdo = (BufImgSDOps *)ops;
0N/A BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
0N/A
0N/A if ((bipriv->lockFlags & (SD_LOCK_RD_WR)) != 0) {
0N/A bipriv->base =
0N/A (*env)->GetPrimitiveArrayCritical(env, bisdo->array, NULL);
0N/A }
0N/A if ((bipriv->lockFlags & (SD_LOCK_LUT)) != 0) {
0N/A bipriv->lutbase =
0N/A (*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL);
0N/A }
0N/A
0N/A if (bipriv->base == NULL) {
0N/A pRasInfo->rasBase = NULL;
0N/A pRasInfo->pixelStride = 0;
0N/A pRasInfo->pixelBitOffset = 0;
0N/A pRasInfo->scanStride = 0;
0N/A } else {
0N/A pRasInfo->rasBase = (void *)
0N/A (((uintptr_t) bipriv->base) + bisdo->offset);
0N/A pRasInfo->pixelStride = bisdo->pixStr;
0N/A pRasInfo->pixelBitOffset = bisdo->bitoffset;
0N/A pRasInfo->scanStride = bisdo->scanStr;
0N/A }
0N/A if (bipriv->lutbase == NULL) {
0N/A pRasInfo->lutBase = NULL;
0N/A pRasInfo->lutSize = 0;
0N/A } else {
0N/A pRasInfo->lutBase = bipriv->lutbase;
0N/A pRasInfo->lutSize = bisdo->lutsize;
0N/A }
0N/A if (bipriv->cData == NULL) {
0N/A pRasInfo->invColorTable = NULL;
0N/A pRasInfo->redErrTable = NULL;
0N/A pRasInfo->grnErrTable = NULL;
0N/A pRasInfo->bluErrTable = NULL;
0N/A } else {
0N/A pRasInfo->invColorTable = bipriv->cData->img_clr_tbl;
0N/A pRasInfo->redErrTable = bipriv->cData->img_oda_red;
0N/A pRasInfo->grnErrTable = bipriv->cData->img_oda_green;
0N/A pRasInfo->bluErrTable = bipriv->cData->img_oda_blue;
0N/A pRasInfo->invGrayTable = bipriv->cData->pGrayInverseLutData;
0N/A }
0N/A}
0N/A
0N/Astatic void BufImg_Release(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo)
0N/A{
0N/A BufImgSDOps *bisdo = (BufImgSDOps *)ops;
0N/A BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
0N/A
0N/A if (bipriv->base != NULL) {
0N/A jint mode = (((bipriv->lockFlags & (SD_LOCK_WRITE)) != 0)
0N/A ? 0 : JNI_ABORT);
0N/A (*env)->ReleasePrimitiveArrayCritical(env, bisdo->array,
0N/A bipriv->base, mode);
0N/A }
0N/A if (bipriv->lutbase != NULL) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray,
0N/A bipriv->lutbase, JNI_ABORT);
0N/A }
0N/A}
0N/A
0N/Astatic ColorData *BufImg_SetupICM(JNIEnv *env,
0N/A BufImgSDOps *bisdo)
0N/A{
2895N/A ColorData *cData = NULL;
2895N/A jobject colorData;
0N/A
0N/A if (JNU_IsNull(env, bisdo->icm)) {
0N/A return (ColorData *) NULL;
0N/A }
0N/A
2895N/A colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID);
0N/A
2895N/A if (JNU_IsNull(env, colorData)) {
2895N/A if (JNU_IsNull(env, clsICMCD)) {
2895N/A // we are unable to create a wrapper object
2895N/A return (ColorData*)NULL;
2895N/A }
2895N/A } else {
2895N/A cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID);
2895N/A }
2895N/A
2895N/A if (cData != NULL) {
2895N/A return cData;
2895N/A }
2895N/A
2895N/A cData = (ColorData*)calloc(1, sizeof(ColorData));
0N/A
2895N/A if (cData != NULL) {
2895N/A jboolean allGray
2895N/A = (*env)->GetBooleanField(env, bisdo->icm, allGrayID);
2895N/A int *pRgb = (int *)
2895N/A ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL));
2895N/A cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32);
2895N/A if (allGray == JNI_TRUE) {
2895N/A initInverseGrayLut(pRgb, bisdo->lutsize, cData);
2895N/A }
2895N/A (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb,
2895N/A JNI_ABORT);
0N/A
2895N/A initDitherTables(cData);
0N/A
2895N/A if (JNU_IsNull(env, colorData)) {
2895N/A jlong pData = ptr_to_jlong(cData);
2895N/A colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData);
2895N/A (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData);
0N/A }
0N/A }
0N/A
0N/A return cData;
0N/A}