提交 828dfb25 编写于 作者: B bae

8014093: Improve parsing of images

Reviewed-by: prr, jgodinez
上级 cb341e2a
......@@ -873,363 +873,204 @@ setHints(JNIEnv *env, BufImageS_t *imageP) {
return 1;
}
/*
* This routine will fill in a buffer of data for either 1 band or all
* bands (if band == -1).
*/
#define MAX_TO_GRAB (10240)
int awt_getPixelByte(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned char *bufferP) {
int w = rasterP->width;
int h = rasterP->height;
int numBands = rasterP->numBands;
typedef union {
void *pv;
unsigned char *pb;
unsigned short *ps;
} PixelData_t;
int awt_getPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) {
const int w = rasterP->width;
const int h = rasterP->height;
const int numBands = rasterP->numBands;
int y;
int i;
int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w);
int maxLines;
jobject jsm;
int off;
int off = 0;
jarray jdata = NULL;
jobject jdatabuffer;
int *dataP;
int maxBytes = w;
int maxSamples;
PixelData_t p;
jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
g_RasterDataBufferID);
jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines);
if (JNU_IsNull(env, jdata)) {
JNU_ThrowOutOfMemoryError(env, "Out of Memory");
if (bufferP == NULL) {
return -1;
}
/* Here is the generic code */
if (band >= 0) {
int dOff;
if (band >= numBands) {
(*env)->DeleteLocalRef(env, jdata);
JNU_ThrowInternalError(env, "Band out of range.");
return -1;
}
off = 0;
for (y=0; y < h; ) {
(*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
dOff = band;
for (i=0; i < maxBytes; i++, dOff += numBands) {
bufferP[off++] = (unsigned char) dataP[dOff];
}
if (rasterP->dataType != BYTE_DATA_TYPE &&
rasterP->dataType != SHORT_DATA_TYPE)
{
return -1;
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
p.pv = bufferP;
if (y+maxLines < h) {
y += maxLines;
}
else {
y++;
maxBytes = w;
}
}
if (!SAFE_TO_MULT(w, numBands)) {
return -1;
}
else {
off = 0;
maxBytes *= numBands;
for (y=0; y < h; ) {
(*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
for (i=0; i < maxBytes; i++) {
bufferP[off++] = (unsigned char) dataP[i];
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
maxSamples = w * numBands;
if (y+maxLines < h) {
y += maxLines;
}
else {
y++;
maxBytes = w*numBands;
}
}
maxLines = maxSamples > MAX_TO_GRAB ? 1 : (MAX_TO_GRAB / maxSamples);
if (maxLines > h) {
maxLines = h;
}
if (!SAFE_TO_MULT(maxSamples, maxLines)) {
return -1;
}
(*env)->DeleteLocalRef(env, jdata);
return 0;
}
int awt_setPixelByte(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned char *bufferP) {
int w = rasterP->width;
int h = rasterP->height;
int numBands = rasterP->numBands;
int y;
int i;
int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w);
jobject jsm;
int off;
jarray jdata = NULL;
jobject jdatabuffer;
int *dataP;
int maxBytes = w;
maxSamples *= maxLines;
jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
g_RasterDataBufferID);
/* Here is the generic code */
jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines);
jdata = (*env)->NewIntArray(env, maxSamples);
if (JNU_IsNull(env, jdata)) {
JNU_ThrowOutOfMemoryError(env, "Out of Memory");
return -1;
}
if (band >= 0) {
int dOff;
if (band >= numBands) {
for (y = 0; y < h; y += maxLines) {
if (y + maxLines > h) {
maxLines = h - y;
maxSamples = w * numBands * maxLines;
}
(*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
if ((*env)->ExceptionOccurred(env)) {
(*env)->DeleteLocalRef(env, jdata);
JNU_ThrowInternalError(env, "Band out of range.");
return -1;
}
off = 0;
for (y=0; y < h; y+=maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
dOff = band;
for (i=0; i < maxBytes; i++, dOff += numBands) {
dataP[dOff] = bufferP[off++];
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
(*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
}
else {
off = 0;
maxBytes *= numBands;
for (y=0; y < h; y+=maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
switch (rasterP->dataType) {
case BYTE_DATA_TYPE:
for (i = 0; i < maxSamples; i ++) {
p.pb[off++] = (unsigned char) dataP[i];
}
for (i=0; i < maxBytes; i++) {
dataP[i] = bufferP[off++];
break;
case SHORT_DATA_TYPE:
for (i = 0; i < maxSamples; i ++) {
p.ps[off++] = (unsigned short) dataP[i];
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
(*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
break;
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
}
(*env)->DeleteLocalRef(env, jdata);
return 0;
return 1;
}
int awt_getPixelShort(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned short *bufferP) {
int w = rasterP->width;
int h = rasterP->height;
int numBands = rasterP->numBands;
int awt_setPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) {
const int w = rasterP->width;
const int h = rasterP->height;
const int numBands = rasterP->numBands;
int y;
int i;
int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w);
int maxLines;
jobject jsm;
int off;
int off = 0;
jarray jdata = NULL;
jobject jdatabuffer;
int *dataP;
int maxBytes = w*maxLines;
int maxSamples;
PixelData_t p;
jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
g_RasterDataBufferID);
jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines);
if (JNU_IsNull(env, jdata)) {
JNU_ThrowOutOfMemoryError(env, "Out of Memory");
if (bufferP == NULL) {
return -1;
}
/* Here is the generic code */
if (band >= 0) {
int dOff;
if (band >= numBands) {
(*env)->DeleteLocalRef(env, jdata);
JNU_ThrowInternalError(env, "Band out of range.");
return -1;
}
off = 0;
for (y=0; y < h; y += maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
(*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
dOff = band;
for (i=0; i < maxBytes; i++, dOff += numBands) {
bufferP[off++] = (unsigned short) dataP[dOff];
}
if (rasterP->dataType != BYTE_DATA_TYPE &&
rasterP->dataType != SHORT_DATA_TYPE)
{
return -1;
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
}
p.pv = bufferP;
if (!SAFE_TO_MULT(w, numBands)) {
return -1;
}
else {
off = 0;
maxBytes *= numBands;
for (y=0; y < h; y+=maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
(*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
for (i=0; i < maxBytes; i++) {
bufferP[off++] = (unsigned short) dataP[i];
}
maxSamples = w * numBands;
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
}
maxLines = maxSamples > MAX_TO_GRAB ? 1 : (MAX_TO_GRAB / maxSamples);
if (maxLines > h) {
maxLines = h;
}
if (!SAFE_TO_MULT(maxSamples, maxLines)) {
return -1;
}
(*env)->DeleteLocalRef(env, jdata);
return 0;
}
int awt_setPixelShort(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned short *bufferP) {
int w = rasterP->width;
int h = rasterP->height;
int numBands = rasterP->numBands;
int y;
int i;
int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w);
jobject jsm;
int off;
jarray jdata = NULL;
jobject jdatabuffer;
int *dataP;
int maxBytes = w;
maxSamples *= maxLines;
jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
g_RasterDataBufferID);
if (band >= numBands) {
JNU_ThrowInternalError(env, "Band out of range.");
return -1;
}
/* Here is the generic code */
jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines);
jdata = (*env)->NewIntArray(env, maxSamples);
if (JNU_IsNull(env, jdata)) {
JNU_ThrowOutOfMemoryError(env, "Out of Memory");
return -1;
}
if (band >= 0) {
int dOff;
off = 0;
for (y=0; y < h; y+=maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
dOff = band;
for (i=0; i < maxBytes; i++, dOff += numBands) {
dataP[dOff] = bufferP[off++];
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
(*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
for (y = 0; y < h; y += maxLines) {
if (y + maxLines > h) {
maxLines = h - y;
maxSamples = w * numBands * maxLines;
}
}
else {
off = 0;
maxBytes *= numBands;
for (y=0; y < h; y+=maxLines) {
if (y+maxLines > h) {
maxBytes = w*numBands;
maxLines = h - y;
}
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
NULL);
if (dataP == NULL) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
switch (rasterP->dataType) {
case BYTE_DATA_TYPE:
for (i = 0; i < maxSamples; i ++) {
dataP[i] = p.pb[off++];
}
for (i=0; i < maxBytes; i++) {
dataP[i] = bufferP[off++];
break;
case SHORT_DATA_TYPE:
for (i = 0; i < maxSamples; i ++) {
dataP[i] = p.ps[off++];
}
break;
}
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
JNI_ABORT);
(*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
}
(*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
0, y, w,
maxLines, jdata, jdatabuffer);
if ((*env)->ExceptionOccurred(env)) {
(*env)->DeleteLocalRef(env, jdata);
return -1;
}
}
(*env)->DeleteLocalRef(env, jdata);
return 0;
return 1;
}
......@@ -188,13 +188,8 @@ void awt_freeParsedRaster(RasterS_t *rasterP, int freeRasterP);
void awt_freeParsedImage(BufImageS_t *imageP, int freeImageP);
int awt_getPixelByte(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned char *bufferP);
int awt_setPixelByte(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned char *bufferP);
int awt_getPixelShort(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned short *bufferP);
int awt_setPixelShort(JNIEnv *env, int band, RasterS_t *rasterP,
unsigned short *bufferP);
int awt_getPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP);
int awt_setPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP);
#endif /* AWT_PARSE_IMAGE_H */
......@@ -700,22 +700,7 @@ Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
/* Means that we couldn't write directly into the destination buffer */
if (ddata == NULL) {
unsigned char *bdataP;
unsigned short *sdataP;
/* Punt for now */
switch (dstRasterP->dataType) {
case BYTE_DATA_TYPE:
bdataP = (unsigned char *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
break;
case SHORT_DATA_TYPE:
sdataP = (unsigned short *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
break;
default:
retStatus = 0;
}
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
}
/* Release the pinned memory */
......@@ -1119,24 +1104,9 @@ fprintf(stderr,"Flags : %d\n",dst->flags);
/* Means that we couldn't write directly into the destination buffer */
if (ddata == NULL) {
unsigned char *bdataP;
unsigned short *sdataP;
/* Need to store it back into the array */
if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
/* Punt for now */
switch (dst->type) {
case MLIB_BYTE:
bdataP = (unsigned char *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
break;
case MLIB_SHORT:
sdataP = (unsigned short *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
break;
default:
retStatus = 0;
}
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
}
}
......@@ -1704,21 +1674,7 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
* the destination buffer
*/
if (ddata == NULL) {
unsigned char* bdataP;
unsigned short* sdataP;
switch (dstRasterP->dataType) {
case BYTE_DATA_TYPE:
bdataP = (unsigned char *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
break;
case SHORT_DATA_TYPE:
sdataP = (unsigned short *) mlib_ImageGetData(dst);
retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
break;
default:
retStatus = 0;
}
retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
}
/* Release the LUT */
......@@ -2298,7 +2254,6 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
mlib_image **mlibImagePP, void **dataPP, int isSrc) {
void *dataP;
unsigned char *cDataP;
unsigned short *sdataP;
int dataType = BYTE_DATA_TYPE;
int width;
int height;
......@@ -2484,8 +2439,7 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
return -1;
}
if (isSrc) {
cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
if (awt_getPixelByte(env, -1, rasterP, cDataP) < 0) {
if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) {
(*sMlibSysFns.deleteImageFP)(*mlibImagePP);
return -1;
}
......@@ -2499,8 +2453,7 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
return -1;
}
if (isSrc) {
sdataP = (unsigned short *) mlib_ImageGetData(*mlibImagePP);
if (awt_getPixelShort(env, -1, rasterP, sdataP) < 0) {
if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) {
(*sMlibSysFns.deleteImageFP)(*mlibImagePP);
return -1;
}
......@@ -2550,60 +2503,6 @@ freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
}
}
static int
storeDstArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
mlibHintS_t *hintP, mlib_image *mlibImP, void *ddata) {
RasterS_t *rasterP = &dstP->raster;
/* Nothing to do since it is the same image type */
if (srcP->imageType == dstP->imageType
&& srcP->imageType != java_awt_image_BufferedImage_TYPE_CUSTOM
&& srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_INDEXED
&& srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_BINARY) {
/* REMIND: Should check the ICM LUTS to see if it is the same */
return 0;
}
/* These types are compatible with TYPE_INT_RGB */
if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB
&& (dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)){
return 0;
}
if (hintP->cvtSrcToDefault &&
(srcP->cmodel.isAlphaPre == dstP->cmodel.isAlphaPre)) {
if (srcP->cmodel.isAlphaPre) {
if (dstP->imageType ==
java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
{
return 0;
}
if (!srcP->cmodel.supportsAlpha &&
dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB){
return 0;
}
}
else {
/* REMIND: */
}
}
if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
/* Just need to move bits */
if (mlibImP->type == MLIB_BYTE) {
return awt_setPixelByte(env, -1, &dstP->raster,
(unsigned char *) mlibImP->data);
}
else if (mlibImP->type == MLIB_SHORT) {
return awt_setPixelByte(env, -1, &dstP->raster,
(unsigned char *) mlibImP->data);
}
}
return 0;
}
#define ERR_BAD_IMAGE_LAYOUT (-2)
#define CHECK_DST_ARRAY(start_offset, elements_per_pixel) \
......@@ -2716,8 +2615,7 @@ storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
}
}
else if (mlibImP->type == MLIB_SHORT) {
return awt_setPixelShort(env, -1, rasterP,
(unsigned short *) mlibImP->data);
return awt_setPixels(env, rasterP, mlibImP->data);
}
}
else {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册