annotate src/share/native/sun/awt/medialib/awt_ImagingLib.c @ 6381:2a9c79db0040

8012597: Better image channel verification Reviewed-by: ahgross, vadim, prr
author bae
date Tue, 30 Apr 2013 04:20:46 +0400
parents b79d56eee18e
children c103e0918d60 26edfc8182bb
rev   line source
duke@0 1 /*
ohair@3261 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
ohair@2362 7 * published by the Free Software Foundation. Oracle designates this
duke@0 8 * particular file as subject to the "Classpath" exception as provided
ohair@2362 9 * by Oracle in the LICENSE file that accompanied this code.
duke@0 10 *
duke@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 15 * accompanied this code).
duke@0 16 *
duke@0 17 * You should have received a copy of the GNU General Public License version
duke@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 20 *
ohair@2362 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@2362 22 * or visit www.oracle.com if you need additional information or have any
ohair@2362 23 * questions.
duke@0 24 */
duke@0 25
duke@0 26 #include <stdio.h>
duke@0 27 #include <stdlib.h>
duke@0 28 #include <string.h>
duke@0 29 #include "sun_awt_image_ImagingLib.h"
duke@0 30 #include "java_awt_Transparency.h"
duke@0 31 #include "java_awt_image_AffineTransformOp.h"
duke@0 32 #include "java_awt_image_BufferedImage.h"
duke@0 33 #include "java_awt_color_ColorSpace.h"
duke@0 34 #include "java_awt_image_ConvolveOp.h"
duke@0 35 #include "sun_awt_image_IntegerComponentRaster.h"
duke@0 36 #include "awt_ImagingLib.h"
duke@0 37 #include "awt_parseImage.h"
duke@0 38 #include "imageInitIDs.h"
duke@0 39 #include <jni.h>
duke@0 40 #include <jni_util.h>
duke@0 41 #include <assert.h>
duke@0 42 #include "awt_Mlib.h"
duke@0 43 #include "gdefs.h"
duke@0 44 #include "safe_alloc.h"
bae@5813 45 #include "safe_math.h"
duke@0 46
duke@0 47 /***************************************************************************
duke@0 48 * Definitions *
duke@0 49 ***************************************************************************/
duke@0 50 #define jio_fprintf fprintf
duke@0 51
duke@0 52 #ifndef TRUE
duke@0 53 #define TRUE 1
duke@0 54 #endif /* TRUE */
duke@0 55
duke@0 56 #ifndef FALSE
duke@0 57 #define FALSE 0
duke@0 58 #endif /* FALSE */
duke@0 59
duke@0 60 #define TYPE_CUSTOM java_awt_image_BufferedImage_TYPE_CUSTOM
duke@0 61 #define TYPE_INT_RGB java_awt_image_BufferedImage_TYPE_INT_RGB
duke@0 62 #define TYPE_INT_ARGB java_awt_image_BufferedImage_TYPE_INT_ARGB
duke@0 63 #define TYPE_INT_ARGB_PRE java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE
duke@0 64 #define TYPE_INT_BGR java_awt_image_BufferedImage_TYPE_INT_BGR
duke@0 65 #define TYPE_4BYTE_ABGR java_awt_image_BufferedImage_TYPE_4BYTE_ABGR
duke@0 66 #define TYPE_4BYTE_ABGR_PRE java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE
duke@0 67
duke@0 68 /* (alpha*color)>>nbits + alpha>>(nbits-1) */
duke@0 69 #define BLEND(color, alpha, alphaNbits) \
duke@0 70 ((((alpha)*(color))>>(alphaNbits)) + ((alpha) >> ((alphaNbits)-1)))
duke@0 71
duke@0 72 /* ((color - (alpha>>(nBits-1)))<<nBits)/alpha */
duke@0 73 #define UNBLEND(color, alpha, alphaNbits) \
duke@0 74 ((((color)-((alpha)>>((alphaNbits)-1)))<<(alphaNbits))/(alpha))
duke@0 75
duke@0 76 /* Enumeration of all of the mlib functions used */
duke@0 77 typedef enum {
duke@0 78 MLIB_CONVMxN,
duke@0 79 MLIB_AFFINE,
duke@0 80 MLIB_LOOKUP,
duke@0 81 MLIB_CONVKERNCVT
duke@0 82 } mlibTypeE_t;
duke@0 83
duke@0 84 typedef struct {
duke@0 85 int dataType; /* One of BYTE_DATA_TYPE, SHORT_DATA_TYPE, */
duke@0 86 int needToCopy;
duke@0 87 int cvtSrcToDefault; /* If TRUE, convert the src to def CM (pre?) */
duke@0 88 int allocDefaultDst; /* If TRUE, alloc def CM dst buffer */
duke@0 89 int cvtToDst; /* If TRUE, convert dst buffer to Dst CM */
duke@0 90 int addAlpha;
duke@0 91 } mlibHintS_t;
duke@0 92
duke@0 93 /***************************************************************************
duke@0 94 * Static Variables/Structures *
duke@0 95 ***************************************************************************/
duke@0 96
duke@0 97 static mlibSysFnS_t sMlibSysFns = {
duke@0 98 NULL, // placeholder for j2d_mlib_ImageCreate
duke@0 99 NULL, // placeholder for j2d_mlib_ImageCreateStruct
duke@0 100 NULL, // placeholder for j2d_mlib_ImageDelete
duke@0 101 };
duke@0 102
duke@0 103 static mlibFnS_t sMlibFns[] = {
duke@0 104 {NULL, "j2d_mlib_ImageConvMxN"},
duke@0 105 {NULL, "j2d_mlib_ImageAffine"},
duke@0 106 {NULL, "j2d_mlib_ImageLookUp"},
duke@0 107 {NULL, "j2d_mlib_ImageConvKernelConvert"},
duke@0 108 {NULL, NULL},
duke@0 109 };
duke@0 110
duke@0 111 static int s_timeIt = 0;
duke@0 112 static int s_printIt = 0;
duke@0 113 static int s_startOff = 0;
duke@0 114 static int s_nomlib = 0;
duke@0 115
duke@0 116 /***************************************************************************
duke@0 117 * Static Function Prototypes *
duke@0 118 ***************************************************************************/
duke@0 119
duke@0 120 static int
duke@0 121 allocateArray(JNIEnv *env, BufImageS_t *imageP,
duke@0 122 mlib_image **mlibImagePP, void **dataPP, int isSrc,
duke@0 123 int cvtToDefault, int addAlpha);
duke@0 124 static int
duke@0 125 allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
duke@0 126 mlib_image **mlibImagePP, void **dataPP, int isSrc);
duke@0 127
duke@0 128 static void
duke@0 129 freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
duke@0 130 void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
duke@0 131 void *dstdataP);
duke@0 132 static void
duke@0 133 freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
duke@0 134 void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
duke@0 135 void *dstdataP);
duke@0 136
duke@0 137 static int
duke@0 138 storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 139 mlib_image *mlibImP);
duke@0 140
duke@0 141 static int
duke@0 142 storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
duke@0 143 mlib_image *mlibImP);
duke@0 144
duke@0 145 static int
duke@0 146 storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 147 mlib_image *mlibImP);
duke@0 148
duke@0 149 static int
duke@0 150 colorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors);
duke@0 151
duke@0 152 static int
duke@0 153 setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 154 int expandICM, int useAlpha,
duke@0 155 int premultiply, mlibHintS_t *hintP);
duke@0 156
duke@0 157
duke@0 158 static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP);
duke@0 159 static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 160 unsigned char *outDataP);
duke@0 161 static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 162 unsigned char *outDataP);
duke@0 163 static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 164 unsigned char *outDataP);
duke@0 165 static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 166 int component, unsigned char *outDataP,
duke@0 167 int forceAlpha);
duke@0 168 static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 169 int component, unsigned char *outDataP,
duke@0 170 int forceAlpha);
duke@0 171 static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 172 int component, unsigned char *outDataP,
duke@0 173 int forceAlpha);
duke@0 174 static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 175 unsigned char *outDataP);
duke@0 176 static int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 177 unsigned char *outDataP);
duke@0 178 static int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 179 unsigned char *outDataP);
duke@0 180 static int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 181 int component, unsigned char *outDataP,
duke@0 182 int supportsAlpha);
duke@0 183 static int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 184 int component, unsigned char *outDataP,
duke@0 185 int supportsAlpha);
duke@0 186 static int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 187 int component, unsigned char *outDataP,
duke@0 188 int supportsAlpha);
duke@0 189
duke@0 190 mlib_start_timer start_timer = NULL;
duke@0 191 mlib_stop_timer stop_timer = NULL;
duke@0 192
duke@0 193 /***************************************************************************
duke@0 194 * Debugging Definitions *
duke@0 195 ***************************************************************************/
duke@0 196 #ifdef DEBUG
duke@0 197
duke@0 198 static void
duke@0 199 printMedialibError(int status) {
duke@0 200 switch(status) {
duke@0 201 case MLIB_FAILURE:
duke@0 202 jio_fprintf(stderr, "failure\n");
duke@0 203 break;
duke@0 204 case MLIB_NULLPOINTER:
duke@0 205 jio_fprintf(stderr, "null pointer\n");
duke@0 206 break;
duke@0 207 case MLIB_OUTOFRANGE:
duke@0 208 jio_fprintf (stderr, "out of range\n");
duke@0 209 break;
duke@0 210 default:
duke@0 211 jio_fprintf (stderr, "medialib error\n");
duke@0 212 break;
duke@0 213 }
duke@0 214 }
duke@0 215 #else /* ! DEBUG */
duke@0 216 # define printMedialibError(x)
duke@0 217
duke@0 218 #endif /* ! DEBUG */
duke@0 219
bae@1115 220 static int
bae@1115 221 getMlibEdgeHint(jint edgeHint) {
bae@1115 222 switch (edgeHint) {
bae@1115 223 case java_awt_image_ConvolveOp_EDGE_NO_OP:
bae@1115 224 return MLIB_EDGE_DST_COPY_SRC;
bae@1115 225 case java_awt_image_ConvolveOp_EDGE_ZERO_FILL:
bae@1115 226 default:
bae@1115 227 return MLIB_EDGE_DST_FILL_ZERO;
bae@1115 228 }
bae@1115 229 }
duke@0 230
duke@0 231 /***************************************************************************
duke@0 232 * External Functions *
duke@0 233 ***************************************************************************/
duke@0 234 JNIEXPORT jint JNICALL
duke@0 235 Java_sun_awt_image_ImagingLib_convolveBI(JNIEnv *env, jobject this,
duke@0 236 jobject jsrc, jobject jdst,
duke@0 237 jobject jkernel, jint edgeHint)
duke@0 238 {
duke@0 239 void *sdata, *ddata;
duke@0 240 mlib_image *src;
duke@0 241 mlib_image *dst;
duke@0 242 int i, scale;
duke@0 243 mlib_d64 *dkern;
duke@0 244 mlib_s32 *kdata;
duke@0 245 int klen;
duke@0 246 float kmax;
duke@0 247 mlib_s32 cmask;
duke@0 248 mlib_status status;
duke@0 249 int retStatus = 1;
duke@0 250 float *kern;
duke@0 251 BufImageS_t *srcImageP, *dstImageP;
duke@0 252 jobject jdata;
duke@0 253 int kwidth;
duke@0 254 int kheight;
duke@0 255 int w, h;
duke@0 256 int x, y;
duke@0 257 mlibHintS_t hint;
duke@0 258 int nbands;
duke@0 259
duke@0 260 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 261 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 262 return 0;
duke@0 263
duke@0 264 if (s_nomlib) return 0;
duke@0 265 if (s_timeIt) (*start_timer)(3600);
duke@0 266
duke@0 267 kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
duke@0 268 kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
duke@0 269 jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
duke@0 270 klen = (*env)->GetArrayLength(env, jdata);
duke@0 271 kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
duke@0 272 if (kern == NULL) {
duke@0 273 /* out of memory exception already thrown */
duke@0 274 return 0;
duke@0 275 }
duke@0 276
duke@0 277 if ((kwidth&0x1) == 0) {
duke@0 278 /* Kernel has even width */
duke@0 279 w = kwidth+1;
duke@0 280 }
duke@0 281 else {
duke@0 282 w = kwidth;
duke@0 283 }
duke@0 284 if ((kheight&0x1) == 0) {
duke@0 285 /* Kernel has even height */
duke@0 286 h = kheight+1;
duke@0 287 }
duke@0 288 else {
duke@0 289 h = kheight;
duke@0 290 }
duke@0 291
duke@0 292 dkern = NULL;
duke@0 293 if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
duke@0 294 dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
duke@0 295 }
duke@0 296 if (dkern == NULL) {
duke@0 297 (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
duke@0 298 return 0;
duke@0 299 }
duke@0 300
duke@0 301 /* Need to flip and find max value of the kernel.
duke@0 302 * Also, save the kernel values as mlib_d64 values.
duke@0 303 * The flip is to operate correctly with medialib,
duke@0 304 * which doesn't do the mathemetically correct thing,
duke@0 305 * i.e. it doesn't rotate the kernel by 180 degrees.
duke@0 306 * REMIND: This should perhaps be done at the Java
duke@0 307 * level by ConvolveOp.
duke@0 308 * REMIND: Should the max test be looking at absolute
duke@0 309 * values?
duke@0 310 * REMIND: What if klen != kheight * kwidth?
duke@0 311 */
duke@0 312 kmax = kern[klen-1];
duke@0 313 i = klen-1;
duke@0 314 for (y=0; y < kheight; y++) {
duke@0 315 for (x=0; x < kwidth; x++, i--) {
duke@0 316 dkern[y*w+x] = (mlib_d64) kern[i];
duke@0 317 if (kern[i] > kmax) {
duke@0 318 kmax = kern[i];
duke@0 319 }
duke@0 320 }
duke@0 321 }
duke@0 322
duke@0 323 (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
duke@0 324
duke@0 325 if (kmax > 1<<16) {
duke@0 326 /* We can only handle 16 bit max */
duke@0 327 free(dkern);
duke@0 328 return 0;
duke@0 329 }
duke@0 330
duke@0 331
duke@0 332 /* Parse the source image */
duke@0 333 if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
duke@0 334 /* Can't handle any custom images */
duke@0 335 free(dkern);
duke@0 336 return 0;
duke@0 337 }
duke@0 338
duke@0 339 /* Parse the destination image */
duke@0 340 if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
duke@0 341 /* Can't handle any custom images */
duke@0 342 awt_freeParsedImage(srcImageP, TRUE);
duke@0 343 free(dkern);
duke@0 344 return 0;
duke@0 345 }
duke@0 346
duke@0 347 nbands = setImageHints(env, srcImageP, dstImageP, TRUE, TRUE,
duke@0 348 FALSE, &hint);
duke@0 349 if (nbands < 1) {
duke@0 350 /* Can't handle any custom images */
duke@0 351 awt_freeParsedImage(srcImageP, TRUE);
duke@0 352 awt_freeParsedImage(dstImageP, TRUE);
duke@0 353 free(dkern);
duke@0 354 return 0;
duke@0 355 }
duke@0 356 /* Allocate the arrays */
duke@0 357 if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
duke@0 358 hint.cvtSrcToDefault, hint.addAlpha) < 0) {
duke@0 359 /* Must be some problem */
duke@0 360 awt_freeParsedImage(srcImageP, TRUE);
duke@0 361 awt_freeParsedImage(dstImageP, TRUE);
duke@0 362 free(dkern);
duke@0 363 return 0;
duke@0 364 }
duke@0 365 if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
duke@0 366 hint.cvtToDst, FALSE) < 0) {
duke@0 367 /* Must be some problem */
duke@0 368 freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
duke@0 369 awt_freeParsedImage(srcImageP, TRUE);
duke@0 370 awt_freeParsedImage(dstImageP, TRUE);
duke@0 371 free(dkern);
duke@0 372 return 0;
duke@0 373 }
duke@0 374
duke@0 375 kdata = NULL;
duke@0 376 if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
duke@0 377 kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
duke@0 378 }
duke@0 379 if (kdata == NULL) {
duke@0 380 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 381 awt_freeParsedImage(srcImageP, TRUE);
duke@0 382 awt_freeParsedImage(dstImageP, TRUE);
duke@0 383 free(dkern);
duke@0 384 return 0;
duke@0 385 }
duke@0 386
duke@0 387 if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
duke@0 388 mlib_ImageGetType(src)) != MLIB_SUCCESS) {
duke@0 389 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 390 awt_freeParsedImage(srcImageP, TRUE);
duke@0 391 awt_freeParsedImage(dstImageP, TRUE);
duke@0 392 free(dkern);
duke@0 393 free(kdata);
duke@0 394 return 0;
duke@0 395 }
duke@0 396
duke@0 397 if (s_printIt) {
duke@0 398 fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
duke@0 399 for (y=kheight-1; y >= 0; y--) {
duke@0 400 for (x=kwidth-1; x >= 0; x--) {
duke@0 401 fprintf(stderr, "%g ", dkern[y*w+x]);
duke@0 402 }
duke@0 403 fprintf(stderr, "\n");
duke@0 404 }
duke@0 405 fprintf(stderr, "New Kernel(scale=%d):\n", scale);
duke@0 406 for (y=kheight-1; y >= 0; y--) {
duke@0 407 for (x=kwidth-1; x >= 0; x--) {
duke@0 408 fprintf(stderr, "%d ", kdata[y*w+x]);
duke@0 409 }
duke@0 410 fprintf(stderr, "\n");
duke@0 411 }
duke@0 412 }
duke@0 413
duke@0 414 cmask = (1<<src->channels)-1;
duke@0 415 status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
duke@0 416 (w-1)/2, (h-1)/2, scale, cmask,
bae@1115 417 getMlibEdgeHint(edgeHint));
duke@0 418
duke@0 419 if (status != MLIB_SUCCESS) {
duke@0 420 printMedialibError(status);
duke@0 421 retStatus = 0;
duke@0 422 }
duke@0 423
duke@0 424 if (s_printIt) {
duke@0 425 unsigned int *dP;
duke@0 426 if (s_startOff != 0) {
duke@0 427 printf("Starting at %d\n", s_startOff);
duke@0 428 }
duke@0 429 if (sdata == NULL) {
duke@0 430 dP = (unsigned int *) mlib_ImageGetData(src);
duke@0 431 }
duke@0 432 else {
duke@0 433 dP = (unsigned int *) sdata;
duke@0 434 }
duke@0 435 printf("src is\n");
duke@0 436 for (i=0; i < 20; i++) {
duke@0 437 printf("%x ",dP[s_startOff+i]);
duke@0 438 }
duke@0 439 printf("\n");
duke@0 440 if (ddata == NULL) {
duke@0 441 dP = (unsigned int *)mlib_ImageGetData(dst);
duke@0 442 }
duke@0 443 else {
duke@0 444 dP = (unsigned int *) ddata;
duke@0 445 }
duke@0 446 printf("dst is \n");
duke@0 447 for (i=0; i < 20; i++) {
duke@0 448 printf("%x ",dP[s_startOff+i]);
duke@0 449 }
duke@0 450 printf("\n");
duke@0 451 }
duke@0 452
duke@0 453 /* Means that we couldn't write directly into the destination buffer */
duke@0 454 if (ddata == NULL) {
duke@0 455
duke@0 456 /* Need to store it back into the array */
duke@0 457 if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
duke@0 458 /* Error */
duke@0 459 retStatus = 0;
duke@0 460 }
duke@0 461 }
duke@0 462
duke@0 463 /* Release the pinned memory */
duke@0 464 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 465 awt_freeParsedImage(srcImageP, TRUE);
duke@0 466 awt_freeParsedImage(dstImageP, TRUE);
duke@0 467 free(dkern);
duke@0 468 free(kdata);
duke@0 469
duke@0 470 if (s_timeIt) (*stop_timer)(3600, 1);
duke@0 471
duke@0 472 return retStatus;
duke@0 473 }
duke@0 474
duke@0 475 JNIEXPORT jint JNICALL
duke@0 476 Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
duke@0 477 jobject jsrc, jobject jdst,
duke@0 478 jobject jkernel, jint edgeHint)
duke@0 479 {
duke@0 480 mlib_image *src;
duke@0 481 mlib_image *dst;
duke@0 482 int i, scale;
duke@0 483 mlib_d64 *dkern;
duke@0 484 mlib_s32 *kdata;
duke@0 485 int klen;
duke@0 486 float kmax;
duke@0 487 int retStatus = 1;
duke@0 488 mlib_status status;
duke@0 489 mlib_s32 cmask;
duke@0 490 void *sdata;
duke@0 491 void *ddata;
duke@0 492 RasterS_t *srcRasterP;
duke@0 493 RasterS_t *dstRasterP;
duke@0 494 int kwidth;
duke@0 495 int kheight;
duke@0 496 int w, h;
duke@0 497 int x, y;
duke@0 498 jobject jdata;
duke@0 499 float *kern;
duke@0 500
duke@0 501 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 502 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 503 return 0;
duke@0 504
duke@0 505 if (s_nomlib) return 0;
duke@0 506 if (s_timeIt) (*start_timer)(3600);
duke@0 507
duke@0 508 kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
duke@0 509 kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
duke@0 510 jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
duke@0 511 klen = (*env)->GetArrayLength(env, jdata);
duke@0 512 kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
duke@0 513 if (kern == NULL) {
duke@0 514 /* out of memory exception already thrown */
duke@0 515 return 0;
duke@0 516 }
duke@0 517
duke@0 518 if ((kwidth&0x1) == 0) {
duke@0 519 /* Kernel has even width */
duke@0 520 w = kwidth+1;
duke@0 521 }
duke@0 522 else {
duke@0 523 w = kwidth;
duke@0 524 }
duke@0 525 if ((kheight&0x1) == 0) {
duke@0 526 /* Kernel has even height */
duke@0 527 h = kheight+1;
duke@0 528 }
duke@0 529 else {
duke@0 530 h = kheight;
duke@0 531 }
duke@0 532
duke@0 533 dkern = NULL;
duke@0 534 if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
duke@0 535 dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
duke@0 536 }
duke@0 537 if (dkern == NULL) {
duke@0 538 (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
duke@0 539 return 0;
duke@0 540 }
duke@0 541
duke@0 542 /* Need to flip and find max value of the kernel.
duke@0 543 * Also, save the kernel values as mlib_d64 values.
duke@0 544 * The flip is to operate correctly with medialib,
duke@0 545 * which doesn't do the mathemetically correct thing,
duke@0 546 * i.e. it doesn't rotate the kernel by 180 degrees.
duke@0 547 * REMIND: This should perhaps be done at the Java
duke@0 548 * level by ConvolveOp.
duke@0 549 * REMIND: Should the max test be looking at absolute
duke@0 550 * values?
duke@0 551 * REMIND: What if klen != kheight * kwidth?
duke@0 552 */
duke@0 553 kmax = kern[klen-1];
duke@0 554 i = klen-1;
duke@0 555 for (y=0; y < kheight; y++) {
duke@0 556 for (x=0; x < kwidth; x++, i--) {
duke@0 557 dkern[y*w+x] = (mlib_d64) kern[i];
duke@0 558 if (kern[i] > kmax) {
duke@0 559 kmax = kern[i];
duke@0 560 }
duke@0 561 }
duke@0 562 }
duke@0 563
duke@0 564 (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
duke@0 565
duke@0 566 if (kmax > 1<<16) {
duke@0 567 /* We can only handle 16 bit max */
duke@0 568 free(dkern);
duke@0 569 return 0;
duke@0 570 }
duke@0 571
duke@0 572 /* Parse the source image */
duke@0 573 if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
duke@0 574 JNU_ThrowOutOfMemoryError(env, "Out of memory");
duke@0 575 free(dkern);
duke@0 576 return -1;
duke@0 577 }
duke@0 578
duke@0 579 if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
duke@0 580 JNU_ThrowOutOfMemoryError(env, "Out of memory");
duke@0 581 free(srcRasterP);
duke@0 582 free(dkern);
duke@0 583 return -1;
duke@0 584 }
duke@0 585
duke@0 586 /* Parse the source raster */
duke@0 587 if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
duke@0 588 /* Can't handle any custom rasters */
duke@0 589 free(srcRasterP);
duke@0 590 free(dstRasterP);
duke@0 591 free(dkern);
duke@0 592 return 0;
duke@0 593 }
duke@0 594
duke@0 595 /* Parse the destination raster */
duke@0 596 if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
duke@0 597 /* Can't handle any custom images */
duke@0 598 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 599 free(dstRasterP);
duke@0 600 free(dkern);
duke@0 601 return 0;
duke@0 602 }
duke@0 603
duke@0 604 /* Allocate the arrays */
duke@0 605 if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
duke@0 606 /* Must be some problem */
duke@0 607 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 608 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 609 free(dkern);
duke@0 610 return 0;
duke@0 611 }
duke@0 612 if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
duke@0 613 /* Must be some problem */
duke@0 614 freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
duke@0 615 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 616 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 617 free(dkern);
duke@0 618 return 0;
duke@0 619 }
duke@0 620
duke@0 621 kdata = NULL;
duke@0 622 if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
duke@0 623 kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
duke@0 624 }
duke@0 625 if (kdata == NULL) {
duke@0 626 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 627 dstRasterP->jdata, dst, ddata);
duke@0 628 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 629 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 630 free(dkern);
duke@0 631 return 0;
duke@0 632 }
duke@0 633
duke@0 634 if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
duke@0 635 mlib_ImageGetType(src)) != MLIB_SUCCESS) {
duke@0 636 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 637 dstRasterP->jdata, dst, ddata);
duke@0 638 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 639 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 640 free(dkern);
duke@0 641 free(kdata);
duke@0 642 return 0;
duke@0 643 }
duke@0 644
duke@0 645 if (s_printIt) {
duke@0 646 fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
duke@0 647 for (y=kheight-1; y >= 0; y--) {
duke@0 648 for (x=kwidth-1; x >= 0; x--) {
duke@0 649 fprintf(stderr, "%g ", dkern[y*w+x]);
duke@0 650 }
duke@0 651 fprintf(stderr, "\n");
duke@0 652 }
duke@0 653 fprintf(stderr, "New Kernel(scale=%d):\n", scale);
duke@0 654 for (y=kheight-1; y >= 0; y--) {
duke@0 655 for (x=kwidth-1; x >= 0; x--) {
duke@0 656 fprintf(stderr, "%d ", kdata[y*w+x]);
duke@0 657 }
duke@0 658 fprintf(stderr, "\n");
duke@0 659 }
duke@0 660 }
duke@0 661
duke@0 662 cmask = (1<<src->channels)-1;
duke@0 663 status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
duke@0 664 (w-1)/2, (h-1)/2, scale, cmask,
bae@1115 665 getMlibEdgeHint(edgeHint));
duke@0 666
duke@0 667 if (status != MLIB_SUCCESS) {
duke@0 668 printMedialibError(status);
duke@0 669 retStatus = 0;
duke@0 670 }
duke@0 671
duke@0 672 if (s_printIt) {
duke@0 673 unsigned int *dP;
duke@0 674 if (s_startOff != 0) {
duke@0 675 printf("Starting at %d\n", s_startOff);
duke@0 676 }
duke@0 677 if (sdata == NULL) {
duke@0 678 dP = (unsigned int *) mlib_ImageGetData(src);
duke@0 679 }
duke@0 680 else {
duke@0 681 dP = (unsigned int *) sdata;
duke@0 682 }
duke@0 683 printf("src is\n");
duke@0 684 for (i=0; i < 20; i++) {
duke@0 685 printf("%x ",dP[s_startOff+i]);
duke@0 686 }
duke@0 687 printf("\n");
duke@0 688 if (ddata == NULL) {
duke@0 689 dP = (unsigned int *)mlib_ImageGetData(dst);
duke@0 690 }
duke@0 691 else {
duke@0 692 dP = (unsigned int *) ddata;
duke@0 693 }
duke@0 694 printf("dst is\n");
duke@0 695 for (i=0; i < 20; i++) {
duke@0 696 printf("%x ",dP[s_startOff+i]);
duke@0 697 }
duke@0 698 printf("\n");
duke@0 699 }
duke@0 700
duke@0 701 /* Means that we couldn't write directly into the destination buffer */
duke@0 702 if (ddata == NULL) {
duke@0 703 unsigned char *bdataP;
duke@0 704 unsigned short *sdataP;
duke@0 705
duke@0 706 /* Punt for now */
duke@0 707 switch (dstRasterP->dataType) {
duke@0 708 case BYTE_DATA_TYPE:
duke@0 709 bdataP = (unsigned char *) mlib_ImageGetData(dst);
duke@0 710 retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
duke@0 711 break;
duke@0 712 case SHORT_DATA_TYPE:
duke@0 713 sdataP = (unsigned short *) mlib_ImageGetData(dst);
duke@0 714 retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
duke@0 715 break;
duke@0 716 default:
duke@0 717 retStatus = 0;
duke@0 718 }
duke@0 719 }
duke@0 720
duke@0 721 /* Release the pinned memory */
duke@0 722 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 723 dstRasterP->jdata, dst, ddata);
duke@0 724 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 725 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 726 free(dkern);
duke@0 727 free(kdata);
duke@0 728
duke@0 729 if (s_timeIt) (*stop_timer)(3600,1);
duke@0 730
duke@0 731 return retStatus;
duke@0 732 }
duke@0 733
duke@0 734
duke@0 735 JNIEXPORT jint JNICALL
duke@0 736 Java_sun_awt_image_ImagingLib_transformBI(JNIEnv *env, jobject this,
duke@0 737 jobject jsrc,
duke@0 738 jobject jdst,
duke@0 739 jdoubleArray jmatrix,
duke@0 740 jint interpType)
duke@0 741 {
duke@0 742 mlib_image *src;
duke@0 743 mlib_image *dst;
duke@0 744 int i;
duke@0 745 int retStatus = 1;
duke@0 746 mlib_status status;
duke@0 747 double *matrix;
duke@0 748 mlib_d64 mtx[6];
duke@0 749 void *sdata;
duke@0 750 void *ddata;
duke@0 751 BufImageS_t *srcImageP;
duke@0 752 BufImageS_t *dstImageP;
duke@0 753 mlib_filter filter;
duke@0 754 mlibHintS_t hint;
duke@0 755 unsigned int *dP;
duke@0 756 int useIndexed;
duke@0 757 int nbands;
duke@0 758
duke@0 759 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 760 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 761 return 0;
duke@0 762
duke@0 763 if (s_nomlib) return 0;
duke@0 764 if (s_timeIt) {
duke@0 765 (*start_timer)(3600);
duke@0 766 }
duke@0 767
duke@0 768 switch(interpType) {
duke@0 769 case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
duke@0 770 filter = MLIB_BILINEAR;
duke@0 771 break;
duke@0 772 case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
duke@0 773 filter = MLIB_NEAREST;
duke@0 774 break;
duke@0 775 case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
duke@0 776 filter = MLIB_BICUBIC;
duke@0 777 break;
duke@0 778 default:
duke@0 779 JNU_ThrowInternalError(env, "Unknown interpolation type");
duke@0 780 return -1;
duke@0 781 }
duke@0 782
duke@0 783 if ((*env)->GetArrayLength(env, jmatrix) < 6) {
duke@0 784 /*
duke@0 785 * Very unlikely, however we should check for this:
duke@0 786 * if given matrix array is too short, we can't handle it
duke@0 787 */
duke@0 788 return 0;
duke@0 789 }
duke@0 790
duke@0 791 matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
duke@0 792 if (matrix == NULL) {
duke@0 793 /* out of memory error already thrown */
duke@0 794 return 0;
duke@0 795 }
duke@0 796
duke@0 797 if (s_printIt) {
duke@0 798 printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
duke@0 799 matrix[2], matrix[3], matrix[4], matrix[5]);
duke@0 800 }
duke@0 801
duke@0 802 mtx[0] = matrix[0];
duke@0 803 mtx[1] = matrix[2];
duke@0 804 mtx[2] = matrix[4];
duke@0 805 mtx[3] = matrix[1];
duke@0 806 mtx[4] = matrix[3];
duke@0 807 mtx[5] = matrix[5];
duke@0 808
duke@0 809 (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
duke@0 810
duke@0 811 /* Parse the source image */
duke@0 812 if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
duke@0 813 /* Can't handle any custom images */
duke@0 814 return 0;
duke@0 815 }
duke@0 816
duke@0 817 /* Parse the destination image */
duke@0 818 if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
duke@0 819 /* Can't handle any custom images */
duke@0 820 awt_freeParsedImage(srcImageP, TRUE);
duke@0 821 return 0;
duke@0 822 }
duke@0 823
duke@0 824 /* REMIND!! Can't assume that it is the same LUT!! */
duke@0 825 /* Fix 4213160, 4184283 */
duke@0 826 useIndexed = (srcImageP->cmodel.cmType == INDEX_CM_TYPE &&
duke@0 827 dstImageP->cmodel.cmType == INDEX_CM_TYPE &&
duke@0 828 srcImageP->raster.rasterType == dstImageP->raster.rasterType &&
duke@0 829 srcImageP->raster.rasterType == COMPONENT_RASTER_TYPE);
duke@0 830
duke@0 831 nbands = setImageHints(env, srcImageP, dstImageP, !useIndexed, TRUE,
duke@0 832 FALSE, &hint);
duke@0 833 if (nbands < 1) {
duke@0 834 /* Can't handle any custom images */
duke@0 835 awt_freeParsedImage(srcImageP, TRUE);
duke@0 836 awt_freeParsedImage(dstImageP, TRUE);
duke@0 837 return 0;
duke@0 838 }
duke@0 839
duke@0 840 /* Allocate the arrays */
duke@0 841 if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
duke@0 842 hint.cvtSrcToDefault, hint.addAlpha) < 0) {
duke@0 843 /* Must be some problem */
duke@0 844 awt_freeParsedImage(srcImageP, TRUE);
duke@0 845 awt_freeParsedImage(dstImageP, TRUE);
duke@0 846 return 0;
duke@0 847 }
duke@0 848 if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
duke@0 849 hint.cvtToDst, FALSE) < 0) {
duke@0 850 /* Must be some problem */
duke@0 851 freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
duke@0 852 awt_freeParsedImage(srcImageP, TRUE);
duke@0 853 awt_freeParsedImage(dstImageP, TRUE);
duke@0 854 return 0;
duke@0 855 }
duke@0 856 #if 0
duke@0 857 fprintf(stderr,"Src----------------\n");
duke@0 858 fprintf(stderr,"Type : %d\n",src->type);
duke@0 859 fprintf(stderr,"Channels: %d\n",src->channels);
duke@0 860 fprintf(stderr,"Width : %d\n",src->width);
duke@0 861 fprintf(stderr,"Height : %d\n",src->height);
duke@0 862 fprintf(stderr,"Stride : %d\n",src->stride);
duke@0 863 fprintf(stderr,"Flags : %d\n",src->flags);
duke@0 864
duke@0 865 fprintf(stderr,"Dst----------------\n");
duke@0 866 fprintf(stderr,"Type : %d\n",dst->type);
duke@0 867 fprintf(stderr,"Channels: %d\n",dst->channels);
duke@0 868 fprintf(stderr,"Width : %d\n",dst->width);
duke@0 869 fprintf(stderr,"Height : %d\n",dst->height);
duke@0 870 fprintf(stderr,"Stride : %d\n",dst->stride);
duke@0 871 fprintf(stderr,"Flags : %d\n",dst->flags);
duke@0 872 #endif
duke@0 873
duke@0 874 if (dstImageP->cmodel.cmType == INDEX_CM_TYPE) {
duke@0 875 /* Need to clear the destination to the transparent pixel */
duke@0 876 unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);
duke@0 877
duke@0 878 memset(cP, dstImageP->cmodel.transIdx,
duke@0 879 mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
duke@0 880 }
duke@0 881 /* Perform the transformation */
duke@0 882 if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
duke@0 883 MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
duke@0 884 {
duke@0 885 printMedialibError(status);
duke@0 886 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 887 awt_freeParsedImage(srcImageP, TRUE);
duke@0 888 awt_freeParsedImage(dstImageP, TRUE);
duke@0 889
duke@0 890 return 0;
duke@0 891 }
duke@0 892
duke@0 893 if (s_printIt) {
duke@0 894 if (sdata == NULL) {
duke@0 895 dP = (unsigned int *) mlib_ImageGetData(src);
duke@0 896 }
duke@0 897 else {
duke@0 898 dP = (unsigned int *) sdata;
duke@0 899 }
duke@0 900 printf("src is\n");
duke@0 901 for (i=0; i < 20; i++) {
duke@0 902 printf("%x ",dP[i]);
duke@0 903 }
duke@0 904 printf("\n");
duke@0 905 if (ddata == NULL) {
duke@0 906 dP = (unsigned int *)mlib_ImageGetData(dst);
duke@0 907 }
duke@0 908 else {
duke@0 909 dP = (unsigned int *) ddata;
duke@0 910 }
duke@0 911 printf("dst is\n");
duke@0 912 for (i=0; i < 20; i++) {
duke@0 913 printf("%x ",dP[i]);
duke@0 914 }
duke@0 915 printf("\n");
duke@0 916 }
duke@0 917
duke@0 918 /* Means that we couldn't write directly into the destination buffer */
duke@0 919 if (ddata == NULL) {
duke@0 920 freeDataArray(env, srcImageP->raster.jdata, src, sdata,
duke@0 921 NULL, NULL, NULL);
duke@0 922 /* Need to store it back into the array */
duke@0 923 if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
duke@0 924 /* Error */
duke@0 925 retStatus = 0;
duke@0 926 }
duke@0 927 freeDataArray(env, NULL, NULL, NULL, dstImageP->raster.jdata,
duke@0 928 dst, ddata);
duke@0 929 }
duke@0 930 else {
duke@0 931 /* Release the pinned memory */
duke@0 932 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 933 }
duke@0 934
duke@0 935 awt_freeParsedImage(srcImageP, TRUE);
duke@0 936 awt_freeParsedImage(dstImageP, TRUE);
duke@0 937
duke@0 938 if (s_timeIt) (*stop_timer)(3600,1);
duke@0 939
duke@0 940 return retStatus;
duke@0 941 }
duke@0 942
duke@0 943 JNIEXPORT jint JNICALL
duke@0 944 Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
duke@0 945 jobject jsrc,
duke@0 946 jobject jdst,
duke@0 947 jdoubleArray jmatrix,
duke@0 948 jint interpType)
duke@0 949 {
duke@0 950 mlib_image *src;
duke@0 951 mlib_image *dst;
duke@0 952 int i;
duke@0 953 int retStatus = 1;
duke@0 954 mlib_status status;
duke@0 955 double *matrix;
duke@0 956 mlib_d64 mtx[6];
duke@0 957 void *sdata;
duke@0 958 void *ddata;
duke@0 959 RasterS_t *srcRasterP;
duke@0 960 RasterS_t *dstRasterP;
duke@0 961 mlib_filter filter;
duke@0 962 unsigned int *dP;
duke@0 963
duke@0 964 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 965 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 966 return 0;
duke@0 967
bae@1883 968 if (s_nomlib) return 0;
bae@1883 969 if (s_timeIt) {
bae@1883 970 (*start_timer)(3600);
bae@1883 971 }
bae@1883 972
duke@0 973 switch(interpType) {
duke@0 974 case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
duke@0 975 filter = MLIB_BILINEAR;
duke@0 976 break;
duke@0 977 case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
duke@0 978 filter = MLIB_NEAREST;
duke@0 979 break;
duke@0 980 case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
duke@0 981 filter = MLIB_BICUBIC;
duke@0 982 break;
duke@0 983 default:
duke@0 984 JNU_ThrowInternalError(env, "Unknown interpolation type");
duke@0 985 return -1;
duke@0 986 }
duke@0 987
bae@1883 988 if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
bae@1883 989 JNU_ThrowOutOfMemoryError(env, "Out of memory");
bae@1883 990 return -1;
bae@1883 991 }
bae@1883 992
bae@1883 993 if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
bae@1883 994 JNU_ThrowOutOfMemoryError(env, "Out of memory");
bae@1883 995 free(srcRasterP);
bae@1883 996 return -1;
duke@0 997 }
duke@0 998
duke@0 999 if ((*env)->GetArrayLength(env, jmatrix) < 6) {
duke@0 1000 /*
duke@0 1001 * Very unlikely, however we should check for this:
duke@0 1002 * if given matrix array is too short, we can't handle it.
duke@0 1003 */
duke@0 1004 free(srcRasterP);
duke@0 1005 free(dstRasterP);
duke@0 1006 return 0;
duke@0 1007 }
duke@0 1008
duke@0 1009 matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
duke@0 1010 if (matrix == NULL) {
duke@0 1011 /* out of memory error already thrown */
duke@0 1012 free(srcRasterP);
duke@0 1013 free(dstRasterP);
duke@0 1014 return 0;
duke@0 1015 }
duke@0 1016
duke@0 1017 if (s_printIt) {
duke@0 1018 printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
duke@0 1019 matrix[2], matrix[3], matrix[4], matrix[5]);
duke@0 1020 }
duke@0 1021
duke@0 1022 mtx[0] = matrix[0];
duke@0 1023 mtx[1] = matrix[2];
duke@0 1024 mtx[2] = matrix[4];
duke@0 1025 mtx[3] = matrix[1];
duke@0 1026 mtx[4] = matrix[3];
duke@0 1027 mtx[5] = matrix[5];
duke@0 1028
duke@0 1029 (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
duke@0 1030
duke@0 1031 /* Parse the source raster */
duke@0 1032 if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
duke@0 1033 /* Can't handle any custom rasters */
duke@0 1034 free(srcRasterP);
duke@0 1035 free(dstRasterP);
duke@0 1036 return 0;
duke@0 1037 }
duke@0 1038
duke@0 1039 /* Parse the destination raster */
duke@0 1040 if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
duke@0 1041 /* Can't handle any custom images */
duke@0 1042 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1043 free(dstRasterP);
duke@0 1044 return 0;
duke@0 1045 }
duke@0 1046
duke@0 1047 /* Allocate the arrays */
duke@0 1048 if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
duke@0 1049 /* Must be some problem */
duke@0 1050 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1051 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1052 return 0;
duke@0 1053 }
duke@0 1054 if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
duke@0 1055 /* Must be some problem */
duke@0 1056 freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
duke@0 1057 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1058 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1059 return 0;
duke@0 1060 }
duke@0 1061
duke@0 1062 #if 0
duke@0 1063 fprintf(stderr,"Src----------------\n");
duke@0 1064 fprintf(stderr,"Type : %d\n",src->type);
duke@0 1065 fprintf(stderr,"Channels: %d\n",src->channels);
duke@0 1066 fprintf(stderr,"Width : %d\n",src->width);
duke@0 1067 fprintf(stderr,"Height : %d\n",src->height);
duke@0 1068 fprintf(stderr,"Stride : %d\n",src->stride);
duke@0 1069 fprintf(stderr,"Flags : %d\n",src->flags);
duke@0 1070
duke@0 1071 fprintf(stderr,"Dst----------------\n");
duke@0 1072 fprintf(stderr,"Type : %d\n",dst->type);
duke@0 1073 fprintf(stderr,"Channels: %d\n",dst->channels);
duke@0 1074 fprintf(stderr,"Width : %d\n",dst->width);
duke@0 1075 fprintf(stderr,"Height : %d\n",dst->height);
duke@0 1076 fprintf(stderr,"Stride : %d\n",dst->stride);
duke@0 1077 fprintf(stderr,"Flags : %d\n",dst->flags);
duke@0 1078 #endif
duke@0 1079
duke@0 1080 {
duke@0 1081 unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);
duke@0 1082
duke@0 1083 memset(cP, 0, mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
duke@0 1084 }
duke@0 1085
duke@0 1086 /* Perform the transformation */
duke@0 1087 if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
duke@0 1088 MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
duke@0 1089 {
duke@0 1090 printMedialibError(status);
duke@0 1091 /* REMIND: Free the regions */
duke@0 1092 return 0;
duke@0 1093 }
duke@0 1094
duke@0 1095 if (s_printIt) {
duke@0 1096 if (sdata == NULL) {
duke@0 1097 dP = (unsigned int *) mlib_ImageGetData(src);
duke@0 1098 }
duke@0 1099 else {
duke@0 1100 dP = (unsigned int *) sdata;
duke@0 1101 }
duke@0 1102 printf("src is\n");
duke@0 1103 for (i=0; i < 20; i++) {
duke@0 1104 printf("%x ",dP[i]);
duke@0 1105 }
duke@0 1106 printf("\n");
duke@0 1107 if (ddata == NULL) {
duke@0 1108 dP = (unsigned int *)mlib_ImageGetData(dst);
duke@0 1109 }
duke@0 1110 else {
duke@0 1111 dP = (unsigned int *) ddata;
duke@0 1112 }
duke@0 1113 printf("dst is\n");
duke@0 1114 for (i=0; i < 20; i++) {
duke@0 1115 printf("%x ",dP[i]);
duke@0 1116 }
duke@0 1117 printf("\n");
duke@0 1118 }
duke@0 1119
duke@0 1120 /* Means that we couldn't write directly into the destination buffer */
duke@0 1121 if (ddata == NULL) {
duke@0 1122 unsigned char *bdataP;
duke@0 1123 unsigned short *sdataP;
duke@0 1124
duke@0 1125 /* Need to store it back into the array */
duke@0 1126 if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
duke@0 1127 /* Punt for now */
duke@0 1128 switch (dst->type) {
duke@0 1129 case MLIB_BYTE:
duke@0 1130 bdataP = (unsigned char *) mlib_ImageGetData(dst);
duke@0 1131 retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
duke@0 1132 break;
duke@0 1133 case MLIB_SHORT:
duke@0 1134 sdataP = (unsigned short *) mlib_ImageGetData(dst);
duke@0 1135 retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
duke@0 1136 break;
duke@0 1137 default:
duke@0 1138 retStatus = 0;
duke@0 1139 }
duke@0 1140 }
duke@0 1141 }
duke@0 1142
duke@0 1143 /* Release the pinned memory */
duke@0 1144 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 1145 dstRasterP->jdata, dst, ddata);
duke@0 1146
duke@0 1147 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1148 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1149
duke@0 1150 if (s_timeIt) (*stop_timer)(3600,1);
duke@0 1151
duke@0 1152 return retStatus;
duke@0 1153 }
duke@0 1154
bae@6347 1155 typedef struct {
bae@6347 1156 jobject jArray;
bae@6347 1157 jsize length;
bae@6347 1158 unsigned char *table;
bae@6347 1159 } LookupArrayInfo;
bae@6347 1160
bae@6347 1161 #define NLUT 8
bae@6347 1162
bae@6347 1163 #ifdef _LITTLE_ENDIAN
bae@6347 1164 #define INDEXES { 3, 2, 1, 0, 7, 6, 5, 4 }
bae@6347 1165 #else
bae@6347 1166 #define INDEXES { 0, 1, 2, 3, 4, 5, 6, 7 }
bae@6347 1167 #endif
bae@6347 1168
bae@6347 1169 static int lookupShortData(mlib_image* src, mlib_image* dst,
bae@6347 1170 LookupArrayInfo* lookup)
bae@6347 1171 {
bae@6347 1172 int x, y;
bae@6347 1173 unsigned int mask = NLUT-1;
bae@6347 1174
bae@6347 1175 unsigned short* srcLine = (unsigned short*)src->data;
bae@6347 1176 unsigned char* dstLine = (unsigned char*)dst->data;
bae@6347 1177
bae@6347 1178 static int indexes[NLUT] = INDEXES;
bae@6347 1179
bae@6370 1180 if (src->width != dst->width || src->height != dst->height) {
bae@6370 1181 return 0;
bae@6370 1182 }
bae@6370 1183
bae@6347 1184 for (y=0; y < src->height; y++) {
bae@6347 1185 int nloop, nx;
bae@6347 1186 int npix = src->width;
bae@6347 1187
bae@6347 1188 unsigned short* srcPixel = srcLine;
bae@6347 1189 unsigned char* dstPixel = dstLine;
bae@6347 1190
bae@6347 1191 #ifdef SIMPLE_LOOKUP_LOOP
bae@6347 1192 for (x=0; status && x < width; x++) {
bae@6347 1193 unsigned short s = *srcPixel++;
bae@6347 1194 if (s >= lookup->length) {
bae@6347 1195 /* we can not handle source image using
bae@6347 1196 * byte lookup table. Fall back to processing
bae@6347 1197 * images in java
bae@6347 1198 */
bae@6347 1199 return 0;
bae@6347 1200 }
bae@6347 1201 *dstPixel++ = lookup->table[s];
bae@6347 1202 }
bae@6347 1203 #else
bae@6347 1204 /* Get to 32 bit-aligned point */
bae@6347 1205 while(((uintptr_t)dstPixel & 0x3) != 0 && npix>0) {
bae@6347 1206 unsigned short s = *srcPixel++;
bae@6347 1207 if (s >= lookup->length) {
bae@6347 1208 return 0;
bae@6347 1209 }
bae@6347 1210 *dstPixel++ = lookup->table[s];
bae@6347 1211 npix--;
bae@6347 1212 }
bae@6347 1213
bae@6347 1214 /*
bae@6347 1215 * Do NLUT pixels per loop iteration.
bae@6347 1216 * Pack into ints and write out 2 at a time.
bae@6347 1217 */
bae@6347 1218 nloop = npix/NLUT;
bae@6347 1219 nx = npix%NLUT;
bae@6347 1220
bae@6347 1221 for(x=nloop; x!=0; x--) {
bae@6347 1222 int i = 0;
bae@6347 1223 int* dstP = (int*)dstPixel;
bae@6347 1224
bae@6347 1225 for (i = 0; i < NLUT; i++) {
bae@6347 1226 if (srcPixel[i] >= lookup->length) {
bae@6347 1227 return 0;
bae@6347 1228 }
bae@6347 1229 }
bae@6347 1230
bae@6347 1231 dstP[0] = (int)
bae@6347 1232 ((lookup->table[srcPixel[indexes[0]]] << 24) |
bae@6347 1233 (lookup->table[srcPixel[indexes[1]]] << 16) |
bae@6347 1234 (lookup->table[srcPixel[indexes[2]]] << 8) |
bae@6347 1235 lookup->table[srcPixel[indexes[3]]]);
bae@6347 1236 dstP[1] = (int)
bae@6347 1237 ((lookup->table[srcPixel[indexes[4]]] << 24) |
bae@6347 1238 (lookup->table[srcPixel[indexes[5]]] << 16) |
bae@6347 1239 (lookup->table[srcPixel[indexes[6]]] << 8) |
bae@6347 1240 lookup->table[srcPixel[indexes[7]]]);
bae@6347 1241
bae@6347 1242
bae@6347 1243 dstPixel += NLUT;
bae@6347 1244 srcPixel += NLUT;
bae@6347 1245 }
bae@6347 1246
bae@6347 1247 /*
bae@6347 1248 * Complete any remaining pixels
bae@6347 1249 */
bae@6347 1250 for(x=nx; x!=0; x--) {
bae@6347 1251 unsigned short s = *srcPixel++;
bae@6347 1252 if (s >= lookup->length) {
bae@6347 1253 return 0;
bae@6347 1254 }
bae@6347 1255 *dstPixel++ = lookup->table[s];
bae@6347 1256 }
bae@6347 1257 #endif
bae@6347 1258
bae@6347 1259 dstLine += dst->stride; // array of bytes, scan stride in bytes
bae@6347 1260 srcLine += src->stride / 2; // array of shorts, scan stride in bytes
bae@6347 1261 }
bae@6347 1262 return 1;
bae@6347 1263 }
bae@6347 1264
duke@0 1265 JNIEXPORT jint JNICALL
bae@6347 1266 Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
duke@0 1267 jobject jsrc, jobject jdst,
duke@0 1268 jobjectArray jtableArrays)
duke@0 1269 {
duke@0 1270 mlib_image *src;
duke@0 1271 mlib_image *dst;
duke@0 1272 void *sdata, *ddata;
duke@0 1273 unsigned char **tbl;
duke@0 1274 unsigned char lut[256];
duke@0 1275 int retStatus = 1;
duke@0 1276 int i;
duke@0 1277 mlib_status status;
bae@6347 1278 int lut_nbands;
bae@6347 1279 LookupArrayInfo *jtable;
duke@0 1280 BufImageS_t *srcImageP, *dstImageP;
duke@0 1281 int nbands;
duke@0 1282 int ncomponents;
duke@0 1283 mlibHintS_t hint;
duke@0 1284
duke@0 1285 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 1286 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 1287 return 0;
duke@0 1288
duke@0 1289 if (s_nomlib) return 0;
duke@0 1290 if (s_timeIt) (*start_timer)(3600);
duke@0 1291
duke@0 1292 /* Parse the source image */
duke@0 1293 if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
duke@0 1294 /* Can't handle any custom images */
duke@0 1295 return 0;
duke@0 1296 }
duke@0 1297
duke@0 1298 /* Parse the destination image */
duke@0 1299 if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
duke@0 1300 /* Can't handle any custom images */
duke@0 1301 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1302 return 0;
duke@0 1303 }
duke@0 1304
bae@6355 1305 nbands = setImageHints(env, srcImageP, dstImageP, FALSE, TRUE,
bae@6355 1306 FALSE, &hint);
bae@6355 1307
bae@6355 1308 if (nbands < 1 || nbands > srcImageP->cmodel.numComponents) {
bae@6355 1309 /* Can't handle any custom images */
bae@6355 1310 awt_freeParsedImage(srcImageP, TRUE);
bae@6355 1311 awt_freeParsedImage(dstImageP, TRUE);
bae@6355 1312 return 0;
bae@6347 1313 }
bae@6347 1314
bae@6356 1315 ncomponents = srcImageP->cmodel.isDefaultCompatCM
bae@6356 1316 ? 4
bae@6356 1317 : srcImageP->cmodel.numComponents;
bae@6356 1318
bae@6347 1319 /* Make sure that color order can be used for
bae@6347 1320 * re-ordering of lookup arrays.
bae@6347 1321 */
bae@6355 1322 for (i = 0; i < nbands; i++) {
bae@6347 1323 int idx = srcImageP->hints.colorOrder[i];
bae@6347 1324
bae@6356 1325 if (idx < 0 || idx >= ncomponents) {
bae@6347 1326 awt_freeParsedImage(srcImageP, TRUE);
bae@6347 1327 awt_freeParsedImage(dstImageP, TRUE);
bae@6347 1328 return 0;
bae@6347 1329 }
bae@6347 1330 }
bae@6347 1331
bae@6355 1332 lut_nbands = (*env)->GetArrayLength(env, jtableArrays);
bae@6355 1333
bae@6355 1334 if (lut_nbands > ncomponents) {
bae@6355 1335 lut_nbands = ncomponents;
bae@6355 1336 }
bae@6355 1337
duke@0 1338 tbl = NULL;
duke@0 1339 if (SAFE_TO_ALLOC_2(ncomponents, sizeof(unsigned char *))) {
duke@0 1340 tbl = (unsigned char **)
duke@0 1341 calloc(1, ncomponents * sizeof(unsigned char *));
duke@0 1342 }
duke@0 1343
duke@0 1344 jtable = NULL;
bae@6347 1345 if (SAFE_TO_ALLOC_2(lut_nbands, sizeof(LookupArrayInfo))) {
bae@6347 1346 jtable = (LookupArrayInfo *)malloc(lut_nbands * sizeof (LookupArrayInfo));
duke@0 1347 }
duke@0 1348
bae@6347 1349 if (tbl == NULL || jtable == NULL) {
bae@1883 1350 if (tbl != NULL) free(tbl);
bae@1883 1351 if (jtable != NULL) free(jtable);
duke@0 1352 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1353 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1354 JNU_ThrowNullPointerException(env, "NULL LUT");
duke@0 1355 return 0;
duke@0 1356 }
duke@0 1357 /* Need to grab these pointers before we lock down arrays */
bae@6347 1358 for (i=0; i < lut_nbands; i++) {
bae@6347 1359 jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
bae@6347 1360
bae@6347 1361 if (jtable[i].jArray != NULL) {
bae@6347 1362 jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
bae@6347 1363 jtable[i].table = NULL;
bae@6347 1364
bae@6347 1365 if (jtable[i].length < 256) {
bae@6347 1366 /* we may read outside the table during lookup */
bae@6347 1367 jtable[i].jArray = NULL;
bae@6347 1368 jtable[i].length = 0;
bae@6347 1369 }
bae@6347 1370 }
bae@6347 1371 if (jtable[i].jArray == NULL) {
bae@1883 1372 free(tbl);
bae@1883 1373 free(jtable);
bae@1883 1374 awt_freeParsedImage(srcImageP, TRUE);
bae@1883 1375 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1376 return 0;
duke@0 1377 }
duke@0 1378 }
duke@0 1379
duke@0 1380 /* Allocate the arrays */
duke@0 1381 if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
duke@0 1382 /* Must be some problem */
bae@1883 1383 free(tbl);
bae@1883 1384 free(jtable);
duke@0 1385 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1386 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1387 return 0;
duke@0 1388 }
duke@0 1389 if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
duke@0 1390 /* Must be some problem */
bae@1883 1391 free(tbl);
bae@1883 1392 free(jtable);
duke@0 1393 freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
duke@0 1394 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1395 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1396 return 0;
duke@0 1397 }
duke@0 1398
duke@0 1399 /* Set up a straight lut so we don't mess around with alpha */
duke@0 1400 /*
duke@0 1401 * NB: medialib lookup routine expects lookup array for each
duke@0 1402 * component of source image including alpha.
duke@0 1403 * If lookup table we got form the java layer does not contain
duke@0 1404 * sufficient number of lookup arrays we add references to identity
duke@0 1405 * lookup array to make medialib happier.
duke@0 1406 */
bae@6347 1407 if (lut_nbands < ncomponents) {
duke@0 1408 int j;
duke@0 1409 /* REMIND: This should be the size of the input lut!! */
duke@0 1410 for (j=0; j < 256; j++) {
duke@0 1411 lut[j] = j;
duke@0 1412 }
duke@0 1413 for (j=0; j < ncomponents; j++) {
duke@0 1414 tbl[j] = lut;
duke@0 1415 }
duke@0 1416 }
duke@0 1417
bae@6347 1418 for (i=0; i < lut_nbands; i++) {
bae@6347 1419 jtable[i].table = (unsigned char *)
bae@6347 1420 (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
bae@6347 1421 if (jtable[i].table == NULL) {
duke@0 1422 /* Free what we've got so far. */
duke@0 1423 int j;
duke@0 1424 for (j = 0; j < i; j++) {
duke@0 1425 (*env)->ReleasePrimitiveArrayCritical(env,
bae@6347 1426 jtable[j].jArray,
bae@6347 1427 (jbyte *) jtable[j].table,
duke@0 1428 JNI_ABORT);
duke@0 1429 }
bae@1883 1430 free(tbl);
bae@1883 1431 free(jtable);
duke@0 1432 freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
duke@0 1433 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1434 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1435 return 0;
duke@0 1436 }
bae@6347 1437 tbl[srcImageP->hints.colorOrder[i]] = jtable[i].table;
duke@0 1438 }
duke@0 1439
bae@6347 1440 if (lut_nbands == 1) {
duke@0 1441 for (i=1; i < nbands -
duke@0 1442 srcImageP->cmodel.supportsAlpha; i++) {
bae@6347 1443 tbl[srcImageP->hints.colorOrder[i]] = jtable[0].table;
duke@0 1444 }
duke@0 1445 }
duke@0 1446
duke@0 1447 /* Mlib needs 16bit lookuptable and must be signed! */
duke@0 1448 if (src->type == MLIB_SHORT) {
duke@0 1449 if (dst->type == MLIB_BYTE) {
duke@0 1450 if (nbands > 1) {
duke@0 1451 retStatus = 0;
duke@0 1452 }
duke@0 1453 else {
bae@6347 1454 retStatus = lookupShortData(src, dst, &jtable[0]);
duke@0 1455 }
duke@0 1456 }
duke@0 1457 /* How about ddata == null? */
duke@0 1458 }
duke@0 1459 else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
duke@0 1460 (void **)tbl) != MLIB_SUCCESS)) {
duke@0 1461 printMedialibError(status);
duke@0 1462 retStatus = 0;
duke@0 1463 }
duke@0 1464
duke@0 1465 /*
duke@0 1466 * Means that we couldn't write directly into
duke@0 1467 * the destination buffer
duke@0 1468 */
duke@0 1469 if (ddata == NULL) {
duke@0 1470
duke@0 1471 /* Need to store it back into the array */
duke@0 1472 if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
duke@0 1473 /* Error */
duke@0 1474 retStatus = 0;
duke@0 1475 }
duke@0 1476 }
duke@0 1477
duke@0 1478 /* Release the LUT */
bae@6347 1479 for (i=0; i < lut_nbands; i++) {
bae@6347 1480 (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
bae@6347 1481 (jbyte *) jtable[i].table, JNI_ABORT);
duke@0 1482 }
duke@0 1483 free ((void *) jtable);
duke@0 1484 free ((void *) tbl);
duke@0 1485
duke@0 1486 /* Release the pinned memory */
duke@0 1487 freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
duke@0 1488
duke@0 1489 awt_freeParsedImage(srcImageP, TRUE);
duke@0 1490 awt_freeParsedImage(dstImageP, TRUE);
duke@0 1491
duke@0 1492 if (s_timeIt) (*stop_timer)(3600, 1);
duke@0 1493
duke@0 1494 return retStatus;
duke@0 1495 }
duke@0 1496
duke@0 1497 JNIEXPORT jint JNICALL
duke@0 1498 Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
duke@0 1499 jobject this,
duke@0 1500 jobject jsrc,
duke@0 1501 jobject jdst,
duke@0 1502 jobjectArray jtableArrays)
duke@0 1503 {
duke@0 1504 RasterS_t* srcRasterP;
duke@0 1505 RasterS_t* dstRasterP;
duke@0 1506 mlib_image* src;
duke@0 1507 mlib_image* dst;
duke@0 1508 void* sdata;
duke@0 1509 void* ddata;
bae@6347 1510 LookupArrayInfo jtable[4];
bae@6347 1511 unsigned char* mlib_lookupTable[4];
duke@0 1512 int i;
duke@0 1513 int retStatus = 1;
duke@0 1514 mlib_status status;
duke@0 1515 int jlen;
duke@0 1516 int lut_nbands;
duke@0 1517 int src_nbands;
duke@0 1518 int dst_nbands;
duke@0 1519 unsigned char ilut[256];
duke@0 1520
duke@0 1521 /* This function requires a lot of local refs ??? Is 64 enough ??? */
duke@0 1522 if ((*env)->EnsureLocalCapacity(env, 64) < 0)
duke@0 1523 return 0;
duke@0 1524
duke@0 1525 if (s_nomlib) return 0;
duke@0 1526 if (s_timeIt) (*start_timer)(3600);
duke@0 1527
duke@0 1528 if ((srcRasterP = (RasterS_t*) calloc(1, sizeof(RasterS_t))) == NULL) {
duke@0 1529 JNU_ThrowOutOfMemoryError(env, "Out of memory");
duke@0 1530 return -1;
duke@0 1531 }
duke@0 1532
duke@0 1533 if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
duke@0 1534 JNU_ThrowOutOfMemoryError(env, "Out of memory");
duke@0 1535 free(srcRasterP);
duke@0 1536 return -1;
duke@0 1537 }
duke@0 1538
duke@0 1539 /* Parse the source raster - reject custom images */
duke@0 1540 if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
bae@1883 1541 free(srcRasterP);
bae@1883 1542 free(dstRasterP);
duke@0 1543 return 0;
duke@0 1544 }
duke@0 1545
duke@0 1546 /* Parse the destination image - reject custom images */
duke@0 1547 if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
duke@0 1548 awt_freeParsedRaster(srcRasterP, TRUE);
bae@1883 1549 free(dstRasterP);
duke@0 1550 return 0;
duke@0 1551 }
duke@0 1552
duke@0 1553 jlen = (*env)->GetArrayLength(env, jtableArrays);
duke@0 1554
duke@0 1555 lut_nbands = jlen;
duke@0 1556 src_nbands = srcRasterP->numBands;
duke@0 1557 dst_nbands = dstRasterP->numBands;
duke@0 1558
bae@6347 1559 /* adjust number of lookup bands */
bae@6347 1560 if (lut_nbands > src_nbands) {
bae@6347 1561 lut_nbands = src_nbands;
bae@6347 1562 }
bae@6347 1563
duke@0 1564 /* MediaLib can't do more than 4 bands */
duke@0 1565 if (src_nbands <= 0 || src_nbands > 4 ||
duke@0 1566 dst_nbands <= 0 || dst_nbands > 4 ||
duke@0 1567 lut_nbands <= 0 || lut_nbands > 4 ||
duke@0 1568 src_nbands != dst_nbands ||
duke@0 1569 ((lut_nbands != 1) && (lut_nbands != src_nbands)))
duke@0 1570 {
duke@0 1571 // we should free parsed rasters here
duke@0 1572 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1573 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1574 return 0;
duke@0 1575 }
duke@0 1576
duke@0 1577 /* Allocate the raster arrays */
duke@0 1578 if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
duke@0 1579 /* Must be some problem */
duke@0 1580 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1581 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1582 return 0;
duke@0 1583 }
duke@0 1584 if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
duke@0 1585 /* Must be some problem */
duke@0 1586 freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
duke@0 1587 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1588 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1589 return 0;
duke@0 1590 }
duke@0 1591
duke@0 1592 /*
duke@0 1593 * Well, until now we have analyzed number of bands in
duke@0 1594 * src and dst rasters.
duke@0 1595 * However, it is not enough because medialib lookup routine uses
duke@0 1596 * number of channels of medialib image. Note that in certain
duke@0 1597 * case number of channels may differs form the number of bands.
duke@0 1598 * Good example is raster that is used in TYPE_INT_RGB buffered
duke@0 1599 * image: it has 3 bands, but their medialib representation has
duke@0 1600 * 4 channels.
duke@0 1601 *
duke@0 1602 * In order to avoid the lookup routine failure, we need:
duke@0 1603 *
duke@0 1604 * 1. verify that src and dst have same number of channels.
duke@0 1605 * 2. provide lookup array for every channel. If we have "extra"
duke@0 1606 * channel (like the raster described above) then we need to
duke@0 1607 * provide identical lookup array.
duke@0 1608 */
duke@0 1609 if (src->channels != dst->channels) {
duke@0 1610 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 1611 dstRasterP->jdata, dst, ddata);
duke@0 1612
duke@0 1613 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1614 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1615 return 0;
duke@0 1616 }
duke@0 1617
duke@0 1618 if (src_nbands < src->channels) {
duke@0 1619 for (i = 0; i < 256; i++) {
duke@0 1620 ilut[i] = i;
duke@0 1621 }
duke@0 1622 }
duke@0 1623
duke@0 1624
duke@0 1625 /* Get references to the lookup table arrays */
duke@0 1626 /* Need to grab these pointers before we lock down arrays */
duke@0 1627 for (i=0; i < lut_nbands; i++) {
bae@6347 1628 jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
bae@6347 1629 jtable[i].table = NULL;
bae@6347 1630 if (jtable[i].jArray != NULL) {
bae@6347 1631 jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
bae@6347 1632 if (jtable[i].length < 256) {
bae@6347 1633 /* we may read outside the table during lookup */
bae@6347 1634 jtable[i].jArray = NULL;
bae@6347 1635 }
bae@6347 1636 }
bae@6347 1637
bae@6347 1638 if (jtable[i].jArray == NULL)
bae@6347 1639 {
bae@6347 1640 freeDataArray(env, srcRasterP->jdata, src, sdata,
bae@6347 1641 dstRasterP->jdata, dst, ddata);
bae@6347 1642
bae@6347 1643 awt_freeParsedRaster(srcRasterP, TRUE);
bae@6347 1644 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1645 return 0;
duke@0 1646 }
duke@0 1647 }
duke@0 1648
duke@0 1649 for (i=0; i < lut_nbands; i++) {
bae@6347 1650 jtable[i].table = (unsigned char *)
bae@6347 1651 (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
bae@6347 1652 if (jtable[i].table == NULL) {
duke@0 1653 /* Free what we've got so far. */
duke@0 1654 int j;
duke@0 1655 for (j = 0; j < i; j++) {
duke@0 1656 (*env)->ReleasePrimitiveArrayCritical(env,
bae@6347 1657 jtable[j].jArray,
bae@6347 1658 (jbyte *) jtable[j].table,
duke@0 1659 JNI_ABORT);
duke@0 1660 }
duke@0 1661 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 1662 dstRasterP->jdata, dst, ddata);
duke@0 1663 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1664 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1665 return 0;
duke@0 1666 }
bae@6347 1667 mlib_lookupTable[i] = jtable[i].table;
duke@0 1668 }
duke@0 1669
duke@0 1670 /*
duke@0 1671 * Medialib routine expects lookup array for each band of raster.
duke@0 1672 * Setup the rest of lookup arrays if supplied lookup table
duke@0 1673 * contains single lookup array.
duke@0 1674 */
duke@0 1675 for (i = lut_nbands; i < src_nbands; i++) {
bae@6347 1676 mlib_lookupTable[i] = jtable[0].table;
duke@0 1677 }
duke@0 1678
duke@0 1679 /*
duke@0 1680 * Setup lookup array for "extra" channels
duke@0 1681 */
duke@0 1682 for ( ; i < src->channels; i++) {
bae@6347 1683 mlib_lookupTable[i] = ilut;
duke@0 1684 }
duke@0 1685
duke@0 1686 /* Mlib needs 16bit lookuptable and must be signed! */
duke@0 1687 if (src->type == MLIB_SHORT) {
duke@0 1688 if (dst->type == MLIB_BYTE) {
duke@0 1689 if (lut_nbands > 1) {
duke@0 1690 retStatus = 0;
duke@0 1691 } else {
bae@6347 1692 retStatus = lookupShortData(src, dst, &jtable[0]);
duke@0 1693 }
duke@0 1694 }
duke@0 1695 /* How about ddata == null? */
duke@0 1696 } else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
bae@6347 1697 (void **)mlib_lookupTable) != MLIB_SUCCESS)) {
duke@0 1698 printMedialibError(status);
duke@0 1699 retStatus = 0;
duke@0 1700 }
duke@0 1701
duke@0 1702 /*
duke@0 1703 * Means that we couldn't write directly into
duke@0 1704 * the destination buffer
duke@0 1705 */
duke@0 1706 if (ddata == NULL) {
duke@0 1707 unsigned char* bdataP;
duke@0 1708 unsigned short* sdataP;
duke@0 1709
duke@0 1710 switch (dstRasterP->dataType) {
duke@0 1711 case BYTE_DATA_TYPE:
duke@0 1712 bdataP = (unsigned char *) mlib_ImageGetData(dst);
duke@0 1713 retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
duke@0 1714 break;
duke@0 1715 case SHORT_DATA_TYPE:
duke@0 1716 sdataP = (unsigned short *) mlib_ImageGetData(dst);
duke@0 1717 retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
duke@0 1718 break;
duke@0 1719 default:
duke@0 1720 retStatus = 0;
duke@0 1721 }
duke@0 1722 }
duke@0 1723
duke@0 1724 /* Release the LUT */
duke@0 1725 for (i=0; i < lut_nbands; i++) {
bae@6347 1726 (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
bae@6347 1727 (jbyte *) jtable[i].table, JNI_ABORT);
duke@0 1728 }
duke@0 1729
duke@0 1730 /* Release the pinned memory */
duke@0 1731 freeDataArray(env, srcRasterP->jdata, src, sdata,
duke@0 1732 dstRasterP->jdata, dst, ddata);
duke@0 1733
duke@0 1734 awt_freeParsedRaster(srcRasterP, TRUE);
duke@0 1735 awt_freeParsedRaster(dstRasterP, TRUE);
duke@0 1736
duke@0 1737 if (s_timeIt) (*stop_timer)(3600, 1);
duke@0 1738
duke@0 1739 return retStatus;
duke@0 1740 }
duke@0 1741
duke@0 1742
duke@0 1743 JNIEXPORT jboolean JNICALL
duke@0 1744 Java_sun_awt_image_ImagingLib_init(JNIEnv *env, jclass thisClass) {
duke@0 1745 char *start;
duke@0 1746 if (getenv("IMLIB_DEBUG")) {
duke@0 1747 start_timer = awt_setMlibStartTimer();
duke@0 1748 stop_timer = awt_setMlibStopTimer();
duke@0 1749 if (start_timer && stop_timer) {
duke@0 1750 s_timeIt = 1;
duke@0 1751 }
duke@0 1752 }
duke@0 1753
duke@0 1754 if (getenv("IMLIB_PRINT")) {
duke@0 1755 s_printIt = 1;
duke@0 1756 }
duke@0 1757 if ((start = getenv("IMLIB_START")) != NULL) {
duke@0 1758 sscanf(start, "%d", &s_startOff);
duke@0 1759 }
duke@0 1760
duke@0 1761 if (getenv ("IMLIB_NOMLIB")) {
duke@0 1762 s_nomlib = 1;
duke@0 1763 return JNI_FALSE;
duke@0 1764 }
duke@0 1765
duke@0 1766 /* This function is platform-dependent and is in awt_mlib.c */
duke@0 1767 if (awt_getImagingLib(env, (mlibFnS_t *)&sMlibFns, &sMlibSysFns) !=
duke@0 1768 MLIB_SUCCESS)
duke@0 1769 {
duke@0 1770 s_nomlib = 1;
duke@0 1771 return JNI_FALSE;
duke@0 1772 }
duke@0 1773 return JNI_TRUE;
duke@0 1774 }
duke@0 1775
duke@0 1776 /* REMIND: How to specify border? */
duke@0 1777 static void extendEdge(JNIEnv *env, BufImageS_t *imageP,
duke@0 1778 int *widthP, int *heightP) {
duke@0 1779 RasterS_t *rasterP = &imageP->raster;
duke@0 1780 int width;
duke@0 1781 int height;
duke@0 1782 /* Useful for convolution? */
duke@0 1783
duke@0 1784 jobject jbaseraster = (*env)->GetObjectField(env, rasterP->jraster,
duke@0 1785 g_RasterBaseRasterID);
duke@0 1786 width = rasterP->width;
duke@0 1787 height = rasterP->height;
duke@0 1788 #ifdef WORKING
duke@0 1789 if (! JNU_IsNull(env, jbaseraster) &&
duke@0 1790 !(*env)->IsSameObject(env, rasterP->jraster, jbaseraster)) {
duke@0 1791 int xOff;
duke@0 1792 int yOff;
duke@0 1793 int baseWidth;
duke@0 1794 int baseHeight;
duke@0 1795 int baseXoff;
duke@0 1796 int baseYoff;
duke@0 1797 /* Not the same object so get the width and height */
duke@0 1798 xOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterXOffsetID);
duke@0 1799 yOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterYOffsetID);
duke@0 1800 baseWidth = (*env)->GetIntField(env, jbaseraster, g_RasterWidthID);
duke@0 1801 baseHeight = (*env)->GetIntField(env, jbaseraster, g_RasterHeightID);
duke@0 1802 baseXoff = (*env)->GetIntField(env, jbaseraster, g_RasterXOffsetID);
duke@0 1803 baseYoff = (*env)->GetIntField(env, jbaseraster, g_RasterYOffsetID);
duke@0 1804
duke@0 1805 if (xOff + rasterP->width < baseXoff + baseWidth) {
duke@0 1806 /* Can use edge */
duke@0 1807 width++;
duke@0 1808 }
duke@0 1809 if (yOff + rasterP->height < baseYoff + baseHeight) {
duke@0 1810 /* Can use edge */
duke@0 1811 height++;
duke@0 1812 }
duke@0 1813
duke@0 1814 }
duke@0 1815 #endif
duke@0 1816
duke@0 1817 }
duke@0 1818
duke@0 1819 static int
duke@0 1820 setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 1821 int expandICM, int useAlpha,
duke@0 1822 int premultiply, mlibHintS_t *hintP)
duke@0 1823 {
duke@0 1824 ColorModelS_t *srcCMP = &srcP->cmodel;
duke@0 1825 ColorModelS_t *dstCMP = &dstP->cmodel;
duke@0 1826 int nbands = 0;
duke@0 1827 int ncomponents;
duke@0 1828
duke@0 1829 hintP->dataType = srcP->raster.dataType;
duke@0 1830 hintP->addAlpha = FALSE;
duke@0 1831
duke@0 1832 /* Are the color spaces the same? */
duke@0 1833 if (srcCMP->csType != dstCMP->csType) {
duke@0 1834 /* If the src is GRAY and dst RGB, we can handle it */
duke@0 1835 if (!(srcCMP->csType == java_awt_color_ColorSpace_TYPE_GRAY &&
duke@0 1836 dstCMP->csType == java_awt_color_ColorSpace_TYPE_RGB)) {
duke@0 1837 /* Nope, need to handle that in java for now */
duke@0 1838 return -1;
duke@0 1839 }
duke@0 1840 else {
duke@0 1841 hintP->cvtSrcToDefault = TRUE;
duke@0 1842 }
duke@0 1843 }
duke@0 1844 else {
duke@0 1845 if (srcP->hints.needToExpand) {
duke@0 1846 hintP->cvtSrcToDefault = TRUE;
duke@0 1847 }
duke@0 1848 else {
duke@0 1849 /* Need to initialize this */
duke@0 1850 hintP->cvtSrcToDefault = FALSE;
duke@0 1851 }
duke@0 1852 }
duke@0 1853
duke@0 1854 ncomponents = srcCMP->numComponents;
duke@0 1855 if ((useAlpha == 0) && srcCMP->supportsAlpha) {
duke@0 1856 ncomponents--; /* ?? */
duke@0 1857 /* Not really, more like shrink src to get rid of alpha */
duke@0 1858 hintP->cvtSrcToDefault = TRUE;
duke@0 1859 }
duke@0 1860
duke@0 1861 hintP->dataType = srcP->raster.dataType;
duke@0 1862 if (hintP->cvtSrcToDefault == FALSE) {
duke@0 1863 if (srcCMP->cmType == INDEX_CM_TYPE) {
duke@0 1864 if (expandICM) {
duke@0 1865 nbands = srcCMP->numComponents;
duke@0 1866 hintP->cvtSrcToDefault = TRUE;
duke@0 1867
duke@0 1868 if (dstCMP->isDefaultCompatCM) {
duke@0 1869 hintP->allocDefaultDst = FALSE;
duke@0 1870 hintP->cvtToDst = FALSE;
duke@0 1871 }
duke@0 1872 else if (dstCMP->isDefaultCompatCM) {
duke@0 1873 hintP->allocDefaultDst = FALSE;
duke@0 1874 hintP->cvtToDst = FALSE;
duke@0 1875 }
duke@0 1876 }
duke@0 1877 else {
duke@0 1878 nbands = 1;
duke@0 1879 hintP->cvtSrcToDefault = FALSE;
duke@0 1880 }
duke@0 1881
duke@0 1882 }
duke@0 1883 else {
duke@0 1884 if (srcP->hints.packing & INTERLEAVED) {
duke@0 1885 nbands = srcCMP->numComponents;
duke@0 1886 }
duke@0 1887 else {
duke@0 1888 nbands = 1;
duke@0 1889 }
duke@0 1890
duke@0 1891 /* Look at the packing */
duke@0 1892 if ((srcP->hints.packing&BYTE_INTERLEAVED)==BYTE_INTERLEAVED ||
duke@0 1893 (srcP->hints.packing&SHORT_INTERLEAVED)==SHORT_INTERLEAVED||
duke@0 1894 (srcP->hints.packing&BYTE_SINGLE_BAND) == BYTE_SINGLE_BAND||
duke@0 1895 (srcP->hints.packing&SHORT_SINGLE_BAND)==SHORT_SINGLE_BAND||
duke@0 1896 (srcP->hints.packing&BYTE_BANDED) == BYTE_BANDED ||
duke@0 1897 (srcP->hints.packing&SHORT_BANDED) == SHORT_BANDED) {
duke@0 1898 /* Can use src directly */
duke@0 1899 hintP->cvtSrcToDefault = FALSE;
duke@0 1900 }
duke@0 1901 else {
duke@0 1902 /* Must be packed or custom */
duke@0 1903 hintP->cvtSrcToDefault = TRUE;
duke@0 1904 }
duke@0 1905 }
duke@0 1906 }
duke@0 1907 if (hintP->cvtSrcToDefault) {
duke@0 1908 /* By definition */
duke@0 1909 nbands = 4; /* What about alpha? */
duke@0 1910 hintP->dataType = BYTE_DATA_TYPE;
duke@0 1911 hintP->needToCopy = TRUE;
duke@0 1912
duke@0 1913 if (srcP->imageType == dstP->imageType) {
duke@0 1914 hintP->cvtToDst = TRUE;
duke@0 1915 }
duke@0 1916 else if (dstP->cmodel.isDefaultCM) {
duke@0 1917 /* Not necessarily */
duke@0 1918 hintP->cvtToDst = FALSE;
duke@0 1919 }
duke@0 1920 else {
duke@0 1921 hintP->cvtToDst = TRUE;
duke@0 1922 }
duke@0 1923 }
duke@0 1924 else {
duke@0 1925 int srcImageType = srcP->imageType;
duke@0 1926 int dstImageType = dstP->imageType;
duke@0 1927 /* Special case where we need to fill in alpha values */
duke@0 1928 if (srcCMP->isDefaultCompatCM && dstCMP->isDefaultCompatCM) {
duke@0 1929 int i;
duke@0 1930 if (!srcCMP->supportsAlpha &&dstCMP->supportsAlpha) {
duke@0 1931 hintP->addAlpha = TRUE;
duke@0 1932 }
duke@0 1933 for (i=0; i < srcCMP->numComponents; i++) {
duke@0 1934 if (srcP->hints.colorOrder[i] != dstP->hints.colorOrder[i]){
duke@0 1935 if (!srcCMP->isDefaultCM) {
duke@0 1936 hintP->cvtSrcToDefault = TRUE;
duke@0 1937 srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
duke@0 1938 }
duke@0 1939 if (!dstCMP->isDefaultCM) {
duke@0 1940 hintP->cvtToDst = TRUE;
duke@0 1941 dstImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
duke@0 1942 }
duke@0 1943
duke@0 1944 break;
duke@0 1945 }
duke@0 1946 }
duke@0 1947 }
duke@0 1948 else if (srcCMP->cmType != INDEX_CM_TYPE &&
duke@0 1949 !srcCMP->supportsAlpha && dstCMP->supportsAlpha)
duke@0 1950 {
duke@0 1951 /* We've already handled the index case. This is for the rest of the cases */
duke@0 1952 srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
duke@0 1953 hintP->cvtSrcToDefault = TRUE;
duke@0 1954 }
duke@0 1955
duke@0 1956 hintP->allocDefaultDst = FALSE;
duke@0 1957 if (srcImageType == dstImageType) {
duke@0 1958 /* Same image type so use it */
duke@0 1959 hintP->cvtToDst = FALSE;
duke@0 1960 }
duke@0 1961 else if (srcImageType == TYPE_INT_RGB &&
duke@0 1962 (dstImageType == TYPE_INT_ARGB ||
duke@0 1963 dstImageType == TYPE_INT_ARGB_PRE)) {
duke@0 1964 hintP->cvtToDst = FALSE;
duke@0 1965 }
duke@0 1966 else if (srcImageType == TYPE_INT_BGR &&
duke@0 1967 (dstImageType == TYPE_4BYTE_ABGR ||
duke@0 1968 dstImageType == TYPE_4BYTE_ABGR_PRE)) {
duke@0 1969 hintP->cvtToDst = FALSE;
duke@0 1970 }
duke@0 1971 else if (srcP->hints.packing == dstP->hints.packing) {
duke@0 1972 /* Now what? */
duke@0 1973
duke@0 1974 /* Check color order */
duke@0 1975
duke@0 1976 /* Check if just need to scale the data */
duke@0 1977
duke@0 1978 hintP->cvtToDst = TRUE;
duke@0 1979 }
duke@0 1980 else {
duke@0 1981 /* Don't know what it is so convert it */
duke@0 1982 hintP->allocDefaultDst = TRUE;
duke@0 1983 hintP->cvtToDst = TRUE;
duke@0 1984 }
duke@0 1985 hintP->needToCopy = (ncomponents > nbands);
duke@0 1986 }
duke@0 1987
duke@0 1988 return nbands;
duke@0 1989 }
duke@0 1990
duke@0 1991
duke@0 1992 static int
duke@0 1993 expandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP,
duke@0 1994 RasterS_t *rasterP, int component, unsigned char *bdataP) {
duke@0 1995
duke@0 1996 if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
duke@0 1997 switch (rasterP->dataType) {
duke@0 1998 case BYTE_DATA_TYPE:
duke@0 1999 if (expandPackedBCR(env, rasterP, component, bdataP) < 0) {
duke@0 2000 /* Must have been an error */
duke@0 2001 return -1;
duke@0 2002 }
duke@0 2003 break;
duke@0 2004
duke@0 2005 case SHORT_DATA_TYPE:
duke@0 2006 if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
duke@0 2007 /* Must have been an error */
duke@0 2008 return -1;
duke@0 2009 }
duke@0 2010 break;
duke@0 2011
duke@0 2012 case INT_DATA_TYPE:
duke@0 2013 if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
duke@0 2014 /* Must have been an error */
duke@0 2015 return -1;
duke@0 2016 }
duke@0 2017 break;
duke@0 2018
duke@0 2019 default:
duke@0 2020 /* REMIND: Return some sort of error */
duke@0 2021 return -1;
duke@0 2022 }
duke@0 2023 }
duke@0 2024 else {
duke@0 2025 /* REMIND: Return some sort of error */
duke@0 2026 return -1;
duke@0 2027 }
duke@0 2028
duke@0 2029 return 0;
duke@0 2030 }
duke@0 2031
duke@0 2032 static int
duke@0 2033 cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component,
duke@0 2034 unsigned char *dataP) {
duke@0 2035 ColorModelS_t *cmP = &imageP->cmodel;
duke@0 2036 RasterS_t *rasterP = &imageP->raster;
duke@0 2037 int y;
duke@0 2038 jobject jpixels = NULL;
duke@0 2039 jint *pixels;
duke@0 2040 unsigned char *dP = dataP;
duke@0 2041 #define NUM_LINES 10
duke@0 2042 int numLines = NUM_LINES;
bae@5813 2043 /* it is safe to calculate the scan length, because width has been verified
bae@5813 2044 * on creation of the mlib image
bae@5813 2045 */
bae@5813 2046 int scanLength = rasterP->width * 4;
bae@5813 2047
bae@5813 2048 int nbytes = 0;
bae@5813 2049 if (!SAFE_TO_MULT(numLines, scanLength)) {
bae@5813 2050 return -1;
bae@5813 2051 }
bae@5813 2052
bae@5813 2053 nbytes = numLines * scanLength;
duke@0 2054
duke@0 2055 for (y=0; y < rasterP->height; y+=numLines) {
duke@0 2056 /* getData, one scanline at a time */
duke@0 2057 if (y+numLines > rasterP->height) {
duke@0 2058 numLines = rasterP->height - y;
bae@5813 2059 nbytes = numLines * scanLength;
duke@0 2060 }
duke@0 2061 jpixels = (*env)->CallObjectMethod(env, imageP->jimage,
duke@0 2062 g_BImgGetRGBMID, 0, y,
duke@0 2063 rasterP->width, numLines,
duke@0 2064 jpixels,0, rasterP->width);
duke@0 2065 if (jpixels == NULL) {
duke@0 2066 JNU_ThrowInternalError(env, "Can't retrieve pixels.");
duke@0 2067 return -1;
duke@0 2068 }
duke@0 2069
duke@0 2070 pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
duke@0 2071 memcpy(dP, pixels, nbytes);
duke@0 2072 dP += nbytes;
duke@0 2073 (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels,
duke@0 2074 JNI_ABORT);
duke@0 2075 }
duke@0 2076 return 0;
duke@0 2077 }
duke@0 2078
duke@0 2079 static int
duke@0 2080 cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component,
duke@0 2081 unsigned char *dataP) {
duke@0 2082 ColorModelS_t *cmP = &imageP->cmodel;
duke@0 2083 RasterS_t *rasterP = &imageP->raster;
duke@0 2084 int y;
duke@0 2085 jint *pixels;
duke@0 2086 unsigned char *dP = dataP;
duke@0 2087 #define NUM_LINES 10
duke@0 2088 int numLines = NUM_LINES;
duke@0 2089 int nbytes = rasterP->width*4*NUM_LINES;
duke@0 2090 jintArray jpixels;
duke@0 2091
duke@0 2092 jpixels = (*env)->NewIntArray(env, nbytes);
duke@0 2093 if (JNU_IsNull(env, jpixels)) {
duke@0 2094 JNU_ThrowOutOfMemoryError(env, "Out of Memory");
duke@0 2095 return -1;
duke@0 2096 }
duke@0 2097
duke@0 2098 for (y=0; y < rasterP->height; y+=NUM_LINES) {
duke@0 2099 if (y+numLines > rasterP->height) {
duke@0 2100 numLines = rasterP->height - y;
duke@0 2101 nbytes = rasterP->width*4*numLines;
duke@0 2102 }
duke@0 2103 pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
duke@0 2104 if (pixels == NULL) {
duke@0 2105 /* JNI error */
duke@0 2106 return -1;
duke@0 2107 }
duke@0 2108
duke@0 2109 memcpy(pixels, dP, nbytes);
duke@0 2110 dP += nbytes;
duke@0 2111
duke@0 2112 (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, 0);
duke@0 2113
duke@0 2114 /* setData, one scanline at a time */
duke@0 2115 /* Fix 4223648, 4184283 */
duke@0 2116 (*env)->CallVoidMethod(env, imageP->jimage, g_BImgSetRGBMID, 0, y,
duke@0 2117 rasterP->width, numLines, jpixels, 0,
duke@0 2118 rasterP->width);
duke@0 2119 if ((*env)->ExceptionOccurred(env)) {
duke@0 2120 return -1;
duke@0 2121 }
duke@0 2122 }
duke@0 2123
duke@0 2124 /* Need to release the array */
duke@0 2125 (*env)->DeleteLocalRef(env, jpixels);
duke@0 2126
duke@0 2127 return 0;
duke@0 2128 }
duke@0 2129
duke@0 2130 static int
duke@0 2131 allocateArray(JNIEnv *env, BufImageS_t *imageP,
duke@0 2132 mlib_image **mlibImagePP, void **dataPP, int isSrc,
duke@0 2133 int cvtToDefault, int addAlpha) {
duke@0 2134 void *dataP;
duke@0 2135 unsigned char *cDataP;
duke@0 2136 RasterS_t *rasterP = &imageP->raster;
duke@0 2137 ColorModelS_t *cmP = &imageP->cmodel;
duke@0 2138 int dataType = BYTE_DATA_TYPE;
duke@0 2139 int width;
duke@0 2140 int height;
duke@0 2141 HintS_t *hintP = &imageP->hints;
duke@0 2142 *dataPP = NULL;
duke@0 2143
duke@0 2144 width = rasterP->width;
duke@0 2145 height = rasterP->height;
duke@0 2146
duke@0 2147 /* Useful for convolution? */
duke@0 2148 /* This code is zero'ed out so that it cannot be called */
duke@0 2149
duke@0 2150 /* To do this correctly, we need to expand src and dst in the */
duke@0 2151 /* same direction up/down/left/right only if both can be expanded */
duke@0 2152 /* in that direction. Expanding right and down is easy - */
duke@0 2153 /* increment width. Expanding top and left requires bumping */
duke@0 2154 /* around pointers and incrementing the width/height */
duke@0 2155
duke@0 2156 #if 0
duke@0 2157 if (0 && useEdges) {
duke@0 2158 baseWidth = rasterP->baseRasterWidth;
duke@0 2159 baseHeight = rasterP->baseRasterHeight;
duke@0 2160 baseXoff = rasterP->baseOriginX;
duke@0 2161 baseYoff = rasterP->baseOriginY;
duke@0 2162
duke@0 2163 if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
duke@0 2164 /* Can use edge */
duke@0 2165 width++;
duke@0 2166 }
duke@0 2167 if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
duke@0 2168 /* Can use edge */
duke@0 2169 height++;
duke@0 2170 }
duke@0 2171
duke@0 2172 if (rasterP->minX > baseXoff ) {
duke@0 2173 /* Can use edge */
duke@0 2174 width++;
duke@0 2175 /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
duke@0 2176 }
duke@0 2177 if (rasterP->minY > baseYoff) {
duke@0 2178 /* Can use edge */
duke@0 2179 height++;
duke@0 2180 /* NEED TO BUMP POINTER BACK A SCANLINE */
duke@0 2181 }
duke@0 2182
duke@0 2183
duke@0 2184 }
duke@0 2185 #endif
duke@0 2186 if (cvtToDefault) {
duke@0 2187 int status = 0;
duke@0 2188 *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
bae@5813 2189 if (*mlibImagePP == NULL) {
bae@5813 2190 return -1;
bae@5813 2191 }
duke@0 2192 cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
bae@5813 2193 /* Make sure the image is cleared.
bae@5813 2194 * NB: the image dimension is already verified, so we can
bae@5813 2195 * safely calculate the length of the buffer.
bae@5813 2196 */
duke@0 2197 memset(cDataP, 0, width*height*4);
duke@0 2198
duke@0 2199 if (!isSrc) {
duke@0 2200 return 0;
duke@0 2201 }
duke@0 2202
duke@0 2203 switch(imageP->cmodel.cmType) {
duke@0 2204 case INDEX_CM_TYPE:
duke@0 2205 /* REMIND: Need to rearrange according to dst cm */
duke@0 2206 /* Fix 4213160, 4184283 */
duke@0 2207 if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
duke@0 2208 return expandICM(env, imageP, (unsigned int *)cDataP);
duke@0 2209 }
duke@0 2210 else {
duke@0 2211 return cvtCustomToDefault(env, imageP, -1, cDataP);
duke@0 2212 }
duke@0 2213
duke@0 2214 case DIRECT_CM_TYPE:
duke@0 2215 switch(imageP->raster.dataType) {
duke@0 2216 case BYTE_DATA_TYPE:
duke@0 2217 return expandPackedBCRdefault(env, rasterP, -1, cDataP,
duke@0 2218 !imageP->cmodel.supportsAlpha);
duke@0 2219 case SHORT_DATA_TYPE:
duke@0 2220 return expandPackedSCRdefault(env, rasterP, -1, cDataP,
duke@0 2221 !imageP->cmodel.supportsAlpha);
duke@0 2222 case INT_DATA_TYPE:
duke@0 2223 return expandPackedICRdefault(env, rasterP, -1, cDataP,
duke@0 2224 !imageP->cmodel.supportsAlpha);
duke@0 2225 }
duke@0 2226 } /* switch(imageP->cmodel.cmType) */
duke@0 2227
duke@0 2228 return cvtCustomToDefault(env, imageP, -1, cDataP);
duke@0 2229 }
duke@0 2230
duke@0 2231 /* Interleaved with shared data */
duke@0 2232 dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
duke@0 2233 NULL);
duke@0 2234 if (dataP == NULL) {
duke@0 2235 return -1;
duke@0 2236 }
duke@0 2237
duke@0 2238 /* Means we need to fill in alpha */
duke@0 2239 if (!cvtToDefault && addAlpha) {
duke@0 2240 *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
duke@0 2241 if (*mlibImagePP != NULL) {
duke@0 2242 unsigned int *dstP = (unsigned int *)
duke@0 2243 mlib_ImageGetData(*mlibImagePP);
duke@0 2244 int dstride = (*mlibImagePP)->stride>>2;
duke@0 2245 int sstride = hintP->sStride>>2;
duke@0 2246 unsigned int *srcP = (unsigned int *)
duke@0 2247 ((unsigned char *)dataP + hintP->dataOffset);
duke@0 2248 unsigned int *dP, *sP;
duke@0 2249 int x, y;
duke@0 2250 for (y=0; y < height; y++, srcP += sstride, dstP += dstride){
duke@0 2251 sP = srcP;
duke@0 2252 dP = dstP;
duke@0 2253 for (x=0; x < width; x++) {
duke@0 2254 dP[x] = sP[x] | 0xff000000;
duke@0 2255 }
duke@0 2256 }
duke@0 2257 }
duke@0 2258 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
duke@0 2259 JNI_ABORT);
duke@0 2260 return 0;
duke@0 2261 }
duke@0 2262 else if ((hintP->packing & BYTE_INTERLEAVED) == BYTE_INTERLEAVED) {
duke@0 2263 int nChans = (cmP->isDefaultCompatCM ? 4 : hintP->numChans);
duke@0 2264 /* Easy case. It is or is similar to the default CM so use
duke@0 2265 * the array. Must be byte data.
duke@0 2266 */
duke@0 2267 /* Create the medialib image */
duke@0 2268 *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE,
duke@0 2269 nChans,
duke@0 2270 width,
duke@0 2271 height,
duke@0 2272 hintP->sStride,
duke@0 2273 (unsigned char *)dataP
duke@0 2274 + hintP->dataOffset);
duke@0 2275 }
duke@0 2276 else if ((hintP->packing & SHORT_INTERLEAVED) == SHORT_INTERLEAVED) {
duke@0 2277 *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
duke@0 2278 hintP->numChans,
duke@0 2279 width,
duke@0 2280 height,
duke@0 2281 imageP->raster.scanlineStride*2,
duke@0 2282 (unsigned short *)dataP
duke@0 2283 + hintP->channelOffset);
duke@0 2284 }
duke@0 2285 else {
duke@0 2286 /* Release the data array */
duke@0 2287 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
duke@0 2288 JNI_ABORT);
duke@0 2289 return -1;
duke@0 2290 }
duke@0 2291
duke@0 2292 *dataPP = dataP;
duke@0 2293 return 0;
duke@0 2294 }
duke@0 2295
duke@0 2296 static int
duke@0 2297 allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
duke@0 2298 mlib_image **mlibImagePP, void **dataPP, int isSrc) {
duke@0 2299 void *dataP;
duke@0 2300 unsigned char *cDataP;
duke@0 2301 unsigned short *sdataP;
duke@0 2302 int dataType = BYTE_DATA_TYPE;
duke@0 2303 int width;
duke@0 2304 int height;
bae@2266 2305 int dataSize;
bae@2266 2306 int offset;
duke@0 2307
duke@0 2308 *dataPP = NULL;
duke@0 2309
duke@0 2310 width = rasterP->width;
duke@0 2311 height = rasterP->height;
duke@0 2312
duke@0 2313 if (rasterP->numBands <= 0 || rasterP->numBands > 4) {
duke@0 2314 /* REMIND: Fix this */
duke@0 2315 return -1;
duke@0 2316 }
duke@0 2317
duke@0 2318 /* Useful for convolution? */
duke@0 2319 /* This code is zero'ed out so that it cannot be called */
duke@0 2320
duke@0 2321 /* To do this correctly, we need to expand src and dst in the */
duke@0 2322 /* same direction up/down/left/right only if both can be expanded */
duke@0 2323 /* in that direction. Expanding right and down is easy - */
duke@0 2324 /* increment width. Expanding top and left requires bumping */
duke@0 2325 /* around pointers and incrementing the width/height */
duke@0 2326
duke@0 2327 #if 0
duke@0 2328 if (0 && useEdges) {
duke@0 2329 baseWidth = rasterP->baseRasterWidth;
duke@0 2330 baseHeight = rasterP->baseRasterHeight;
duke@0 2331 baseXoff = rasterP->baseOriginX;
duke@0 2332 baseYoff = rasterP->baseOriginY;
duke@0 2333
duke@0 2334 if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
duke@0 2335 /* Can use edge */
duke@0 2336 width++;
duke@0 2337 }
duke@0 2338 if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
duke@0 2339 /* Can use edge */
duke@0 2340 height++;
duke@0 2341 }
duke@0 2342
duke@0 2343 if (rasterP->minX > baseXoff ) {
duke@0 2344 /* Can use edge */
duke@0 2345 width++;
duke@0 2346 /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
duke@0 2347 }
duke@0 2348 if (rasterP->minY > baseYoff) {
duke@0 2349 /* Can use edge */
duke@0 2350 height++;
duke@0 2351 /* NEED TO BUMP POINTER BACK A SCANLINE */
duke@0 2352 }
duke@0 2353
duke@0 2354
duke@0 2355 }
duke@0 2356 #endif
duke@0 2357 switch (rasterP->type) {
duke@0 2358 case sun_awt_image_IntegerComponentRaster_TYPE_INT_8BIT_SAMPLES:
bae@2266 2359 if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 4)) &&
bae@2266 2360 SAFE_TO_ALLOC_2(width, 4) &&
bae@2266 2361 SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 4)))
bae@2266 2362 {
bae@2266 2363 return -1;
bae@2266 2364 }
bae@2266 2365 offset = 4 * rasterP->chanOffsets[0];
bae@2266 2366 dataSize = 4 * (*env)->GetArrayLength(env, rasterP->jdata);
bae@2266 2367
bae@2266 2368 if (offset < 0 || offset >= dataSize ||
bae@2266 2369 width > rasterP->scanlineStride ||
bae@2266 2370 height * rasterP->scanlineStride * 4 > dataSize - offset)
bae@2266 2371 {
bae@2266 2372 // raster data buffer is too short
bae@2266 2373 return -1;
bae@2266 2374 }
duke@0 2375 dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
duke@0 2376 NULL);
duke@0 2377 if (dataP == NULL) {
duke@0 2378 return -1;
duke@0 2379 }
duke@0 2380 *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, 4,
duke@0 2381 width, height,
duke@0 2382 rasterP->scanlineStride*4,
bae@2266 2383 (unsigned char *)dataP + offset);
duke@0 2384 *dataPP = dataP;
duke@0 2385 return 0;
duke@0 2386 case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES:
bae@2266 2387 if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands) &&
bae@2266 2388 SAFE_TO_ALLOC_2(height, rasterP->scanlineStride)))
bae@2266 2389 {
bae@2266 2390 return -1;
bae@2266 2391 }
bae@2266 2392 offset = rasterP->chanOffsets[0];
bae@2266 2393 dataSize = (*env)->GetArrayLength(env, rasterP->jdata);
bae@2266 2394
bae@2266 2395 if (offset < 0 || offset >= dataSize ||
bae@2266 2396 width * rasterP->numBands > rasterP->scanlineStride ||
bae@2266 2397 height * rasterP->scanlineStride > dataSize - offset)
bae@2266 2398 {
bae@2266 2399 // raster data buffer is too short
bae@2266 2400 return -1;
bae@2266 2401 }
duke@0 2402 dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
duke@0 2403 NULL);
duke@0 2404 if (dataP == NULL) {
duke@0 2405 return -1;
duke@0 2406 }
duke@0 2407 *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, rasterP->numBands,
duke@0 2408 width, height,
duke@0 2409 rasterP->scanlineStride,
bae@2266 2410 (unsigned char *)dataP + offset);
duke@0 2411 *dataPP = dataP;
duke@0 2412 return 0;
duke@0 2413 case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_SAMPLES:
bae@2266 2414 if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 2)) &&
bae@2266 2415 SAFE_TO_ALLOC_3(width, rasterP->numBands, 2) &&
bae@2266 2416 SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 2)))
bae@2266 2417 {
bae@2266 2418 return -1;
bae@2266 2419 }
bae@2266 2420 offset = rasterP->chanOffsets[0] * 2;
bae@2266 2421 dataSize = 2 * (*env)->GetArrayLength(env, rasterP->jdata);
bae@2266 2422
bae@2266 2423 if (offset < 0 || offset >= dataSize ||
bae@2266 2424 width * rasterP->numBands > rasterP->scanlineStride ||
bae@2266 2425 height * rasterP->scanlineStride * 2 > dataSize - offset)
bae@2266 2426 {
bae@2266 2427 // raster data buffer is too short
bae@2266 2428 return -1;
bae@2266 2429 }
duke@0 2430 dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
duke@0 2431 NULL);
duke@0 2432 if (dataP == NULL) {
duke@0 2433 return -1;
duke@0 2434 }
duke@0 2435 *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
duke@0 2436 rasterP->numBands,
duke@0 2437 width, height,
duke@0 2438 rasterP->scanlineStride*2,
bae@2266 2439 (unsigned char *)dataP + offset);
duke@0 2440 *dataPP = dataP;
duke@0 2441 return 0;
duke@0 2442
duke@0 2443 case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
duke@0 2444 *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
duke@0 2445 width, height);
bae@5813 2446 if (*mlibImagePP == NULL) {
bae@5813 2447 return -1;
bae@5813 2448 }
duke@0 2449 if (!isSrc) return 0;
duke@0 2450 cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
duke@0 2451 return expandPackedBCR(env, rasterP, -1, cDataP);
duke@0 2452
duke@0 2453 case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
duke@0 2454 if (rasterP->sppsm.maxBitSize <= 8) {
duke@0 2455 *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
duke@0 2456 width, height);
bae@5813 2457 if (*mlibImagePP == NULL) {
bae@5813 2458 return -1;
bae@5813 2459 }
duke@0 2460 if (!isSrc) return 0;
duke@0 2461 cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
duke@0 2462 return expandPackedSCR(env, rasterP, -1, cDataP);
duke@0 2463 }
duke@0 2464 break;
duke@0 2465 case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
duke@0 2466 if (rasterP->sppsm.maxBitSize <= 8) {
duke@0 2467 *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
duke@0 2468 width, height);
bae@5813 2469 if (*mlibImagePP == NULL) {
bae@5813 2470 return -1;
bae@5813 2471 }
duke@0 2472 if (!isSrc) return 0;
duke@0 2473 cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
duke@0 2474 return expandPackedICR(env, rasterP, -1, cDataP);
duke@0 2475 }
duke@0 2476 break;
duke@0 2477 }
duke@0 2478
duke@0 2479 /* Just expand it right now */
duke@0 2480 switch (rasterP->dataType) {
duke@0 2481 case BYTE_DATA_TYPE:
duke@0 2482 if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
duke@0 2483 width, height)) == NULL) {
duke@0 2484 return -1;
duke@0 2485 }
duke@0 2486 if (isSrc) {
duke@0 2487 cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
duke@0 2488 if (awt_getPixelByte(env, -1, rasterP, cDataP) < 0) {
duke@0 2489 (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
duke@0 2490 return -1;
duke@0 2491 }
duke@0 2492 }
duke@0 2493 break;
duke@0 2494
duke@0 2495 case SHORT_DATA_TYPE:
duke@0 2496 if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_SHORT,
duke@0 2497 rasterP->numBands,
duke@0 2498 width, height)) == NULL) {
duke@0 2499 return -1;
duke@0 2500 }
duke@0 2501 if (isSrc) {
duke@0 2502 sdataP = (unsigned short *) mlib_ImageGetData(*mlibImagePP);
duke@0 2503 if (awt_getPixelShort(env, -1, rasterP, sdataP) < 0) {
duke@0 2504 (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
duke@0 2505 return -1;
duke@0 2506 }
duke@0 2507 }
duke@0 2508 break;
duke@0 2509
duke@0 2510 default:
duke@0 2511 return -1;
duke@0 2512 }
duke@0 2513 return 0;
duke@0 2514 }
duke@0 2515
duke@0 2516 static void
duke@0 2517 freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
duke@0 2518 void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
duke@0 2519 void *dstdataP) {
duke@0 2520 jobject srcJdata = (srcimageP != NULL ? srcimageP->raster.jdata : NULL);
duke@0 2521 jobject dstJdata = (dstimageP != NULL ? dstimageP->raster.jdata : NULL);
duke@0 2522 freeDataArray(env, srcJdata, srcmlibImP, srcdataP,
duke@0 2523 dstJdata, dstmlibImP, dstdataP);
duke@0 2524 }
duke@0 2525 static void
duke@0 2526 freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
duke@0 2527 void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
duke@0 2528 void *dstdataP)
duke@0 2529 {
duke@0 2530 /* Free the medialib image */
duke@0 2531 if (srcmlibImP) {
duke@0 2532 (*sMlibSysFns.deleteImageFP)(srcmlibImP);
duke@0 2533 }
duke@0 2534
duke@0 2535 /* Release the array */
duke@0 2536 if (srcdataP) {
duke@0 2537 (*env)->ReleasePrimitiveArrayCritical(env, srcJdata,
duke@0 2538 srcdataP, JNI_ABORT);
duke@0 2539 }
duke@0 2540
duke@0 2541 /* Free the medialib image */
duke@0 2542 if (dstmlibImP) {
duke@0 2543 (*sMlibSysFns.deleteImageFP)(dstmlibImP);
duke@0 2544 }
duke@0 2545
duke@0 2546 /* Release the array */
duke@0 2547 if (dstdataP) {
duke@0 2548 (*env)->ReleasePrimitiveArrayCritical(env, dstJdata,
duke@0 2549 dstdataP, 0);
duke@0 2550 }
duke@0 2551 }
duke@0 2552
duke@0 2553 static int
duke@0 2554 storeDstArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 2555 mlibHintS_t *hintP, mlib_image *mlibImP, void *ddata) {
duke@0 2556 RasterS_t *rasterP = &dstP->raster;
duke@0 2557
duke@0 2558 /* Nothing to do since it is the same image type */
duke@0 2559 if (srcP->imageType == dstP->imageType
duke@0 2560 && srcP->imageType != java_awt_image_BufferedImage_TYPE_CUSTOM
duke@0 2561 && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_INDEXED
duke@0 2562 && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_BINARY) {
duke@0 2563 /* REMIND: Should check the ICM LUTS to see if it is the same */
duke@0 2564 return 0;
duke@0 2565 }
duke@0 2566
duke@0 2567 /* These types are compatible with TYPE_INT_RGB */
duke@0 2568 if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB
duke@0 2569 && (dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
duke@0 2570 dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)){
duke@0 2571 return 0;
duke@0 2572 }
duke@0 2573
duke@0 2574 if (hintP->cvtSrcToDefault &&
duke@0 2575 (srcP->cmodel.isAlphaPre == dstP->cmodel.isAlphaPre)) {
duke@0 2576 if (srcP->cmodel.isAlphaPre) {
duke@0 2577 if (dstP->imageType ==
duke@0 2578 java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
duke@0 2579 {
duke@0 2580 return 0;
duke@0 2581 }
duke@0 2582 if (!srcP->cmodel.supportsAlpha &&
duke@0 2583 dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB){
duke@0 2584 return 0;
duke@0 2585 }
duke@0 2586 }
duke@0 2587 else {
duke@0 2588 /* REMIND: */
duke@0 2589 }
duke@0 2590 }
duke@0 2591
duke@0 2592 if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
duke@0 2593 /* Just need to move bits */
duke@0 2594 if (mlibImP->type == MLIB_BYTE) {
duke@0 2595 return awt_setPixelByte(env, -1, &dstP->raster,
duke@0 2596 (unsigned char *) mlibImP->data);
duke@0 2597 }
duke@0 2598 else if (mlibImP->type == MLIB_SHORT) {
duke@0 2599 return awt_setPixelByte(env, -1, &dstP->raster,
duke@0 2600 (unsigned char *) mlibImP->data);
duke@0 2601 }
duke@0 2602 }
duke@0 2603
duke@0 2604 return 0;
duke@0 2605 }
duke@0 2606
bae@6381 2607 #define ERR_BAD_IMAGE_LAYOUT (-2)
bae@6381 2608
bae@6381 2609 #define CHECK_DST_ARRAY(start_offset, elements_per_pixel) \
bae@6381 2610 do { \
bae@6381 2611 int offset = (start_offset); \
bae@6381 2612 int lastScanOffset; \
bae@6381 2613 \
bae@6381 2614 if (!SAFE_TO_MULT(rasterP->scanlineStride, \
bae@6381 2615 (rasterP->height - 1))) \
bae@6381 2616 { \
bae@6381 2617 return ERR_BAD_IMAGE_LAYOUT; \
bae@6381 2618 } \
bae@6381 2619 lastScanOffset = rasterP->scanlineStride * \
bae@6381 2620 (rasterP->height - 1); \
bae@6381 2621 \
bae@6381 2622 if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
bae@6381 2623 return ERR_BAD_IMAGE_LAYOUT; \
bae@6381 2624 } \
bae@6381 2625 lastScanOffset += offset; \
bae@6381 2626 \
bae@6381 2627 if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) { \
bae@6381 2628 return ERR_BAD_IMAGE_LAYOUT; \
bae@6381 2629 } \
bae@6381 2630 offset = (elements_per_pixel) * rasterP->width; \
bae@6381 2631 \
bae@6381 2632 if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
bae@6381 2633 return ERR_BAD_IMAGE_LAYOUT; \
bae@6381 2634 } \
bae@6381 2635 lastScanOffset += offset; \
bae@6381 2636 \
bae@6381 2637 if (dataArrayLength < lastScanOffset) { \
bae@6381 2638 return ERR_BAD_IMAGE_LAYOUT; \
bae@6381 2639 } \
bae@6381 2640 } while(0); \
bae@6381 2641
duke@0 2642 static int
duke@0 2643 storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 2644 mlib_image *mlibImP) {
duke@0 2645 int mStride;
duke@0 2646 unsigned char *cmDataP, *dataP, *cDataP;
duke@0 2647 HintS_t *hintP = &dstP->hints;
duke@0 2648 RasterS_t *rasterP = &dstP->raster;
bae@6381 2649 jsize dataArrayLength = (*env)->GetArrayLength(env, rasterP->jdata);
duke@0 2650 int y;
duke@0 2651
duke@0 2652 /* REMIND: Store mlib data type? */
duke@0 2653
duke@0 2654 /* Check if it is an IndexColorModel */
duke@0 2655 if (dstP->cmodel.cmType == INDEX_CM_TYPE) {
duke@0 2656 if (dstP->raster.rasterType == COMPONENT_RASTER_TYPE) {
duke@0 2657 return storeICMarray(env, srcP, dstP, mlibImP);
duke@0 2658 }
duke@0 2659 else {
duke@0 2660 /* Packed or some other custom raster */
duke@0 2661 cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2662 return cvtDefaultToCustom(env, dstP, -1, cmDataP);
duke@0 2663 }
duke@0 2664 }
duke@0 2665
duke@0 2666 if (hintP->packing == BYTE_INTERLEAVED) {
duke@0 2667 /* Write it back to the destination */
bae@6381 2668 CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
duke@0 2669 cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2670 mStride = mlib_ImageGetStride(mlibImP);
duke@0 2671 dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env,
duke@0 2672 rasterP->jdata, NULL);
duke@0 2673 if (dataP == NULL) return 0;
bae@6381 2674 cDataP = dataP + hintP->channelOffset;
duke@0 2675 for (y=0; y < rasterP->height;
bae@6381 2676 y++, cmDataP += mStride, cDataP += rasterP->scanlineStride)
duke@0 2677 {
duke@0 2678 memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans);
duke@0 2679 }
duke@0 2680 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
duke@0 2681 JNI_ABORT);
duke@0 2682 }
duke@0 2683 else if (hintP->packing == SHORT_INTERLEAVED) {
duke@0 2684 /* Write it back to the destination */
duke@0 2685 unsigned short *sdataP, *sDataP;
duke@0 2686 unsigned short *smDataP = (unsigned short *)mlib_ImageGetData(mlibImP);
bae@6381 2687 CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
duke@0 2688 mStride = mlib_ImageGetStride(mlibImP);
duke@0 2689 sdataP = (unsigned short *)(*env)->GetPrimitiveArrayCritical(env,
duke@0 2690 rasterP->jdata, NULL);
duke@0 2691 if (sdataP == NULL) return -1;
bae@6381 2692 sDataP = sdataP + hintP->channelOffset;
duke@0 2693 for (y=0; y < rasterP->height;
bae@6381 2694 y++, smDataP += mStride, sDataP += rasterP->scanlineStride)
duke@0 2695 {
duke@0 2696 memcpy(sDataP, smDataP, rasterP->width*hintP->numChans);
duke@0 2697 }
duke@0 2698 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, sdataP,
duke@0 2699 JNI_ABORT);
duke@0 2700 }
duke@0 2701 else if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
duke@0 2702 /* Just need to move bits */
duke@0 2703 if (mlibImP->type == MLIB_BYTE) {
duke@0 2704 if (dstP->hints.packing == PACKED_BYTE_INTER) {
duke@0 2705 return setPackedBCRdefault(env, rasterP, -1,
duke@0 2706 (unsigned char *) mlibImP->data,
duke@0 2707 dstP->cmodel.supportsAlpha);
duke@0 2708 } else if (dstP->hints.packing == PACKED_SHORT_INTER) {
duke@0 2709 return setPackedSCRdefault(env, rasterP, -1,
duke@0 2710 (unsigned char *) mlibImP->data,
duke@0 2711 dstP->cmodel.supportsAlpha);
duke@0 2712 } else if (dstP->hints.packing == PACKED_INT_INTER) {
duke@0 2713 return setPackedICRdefault(env, rasterP, -1,
duke@0 2714 (unsigned char *) mlibImP->data,
duke@0 2715 dstP->cmodel.supportsAlpha);
duke@0 2716 }
duke@0 2717 }
duke@0 2718 else if (mlibImP->type == MLIB_SHORT) {
duke@0 2719 return awt_setPixelShort(env, -1, rasterP,
duke@0 2720 (unsigned short *) mlibImP->data);
duke@0 2721 }
duke@0 2722 }
duke@0 2723 else {
duke@0 2724 return cvtDefaultToCustom(env, dstP, -1,
duke@0 2725 (unsigned char *)mlibImP->data);
duke@0 2726 }
duke@0 2727
duke@0 2728 return 0;
duke@0 2729 }
duke@0 2730
duke@0 2731 static int
duke@0 2732 storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
duke@0 2733 mlib_image *mlibImP) {
duke@0 2734 unsigned char *cDataP;
duke@0 2735
duke@0 2736 switch(dstP->type) {
duke@0 2737 case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
duke@0 2738 cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2739 return setPackedBCR(env, dstP, -1, cDataP);
duke@0 2740
duke@0 2741 case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
duke@0 2742 if (dstP->sppsm.maxBitSize <= 8) {
duke@0 2743 cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2744 return setPackedSCR(env, dstP, -1, cDataP);
duke@0 2745 }
duke@0 2746 break;
duke@0 2747 case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
duke@0 2748 if (dstP->sppsm.maxBitSize <= 8) {
duke@0 2749 cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2750 return setPackedICR(env, dstP, -1, cDataP);
duke@0 2751 }
duke@0 2752 }
duke@0 2753
duke@0 2754 return -1;
duke@0 2755 }
duke@0 2756
duke@0 2757
duke@0 2758 static int
duke@0 2759 storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
duke@0 2760 mlib_image *mlibImP)
duke@0 2761 {
duke@0 2762 int *argb;
duke@0 2763 int x, y;
duke@0 2764 unsigned char *dataP, *cDataP, *cP;
duke@0 2765 unsigned char *sP;
duke@0 2766 int aIdx, rIdx, gIdx, bIdx;
duke@0 2767 ColorModelS_t *cmodelP = &dstP->cmodel;
duke@0 2768 RasterS_t *rasterP = &dstP->raster;
duke@0 2769
duke@0 2770 /* REMIND: Only works for RGB */
duke@0 2771 if (cmodelP->csType != java_awt_color_ColorSpace_TYPE_RGB) {
duke@0 2772 JNU_ThrowInternalError(env, "Writing to non-RGB images not implemented yet");
duke@0 2773 return -1;
duke@0 2774 }
duke@0 2775
duke@0 2776 if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
duke@0 2777 srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE ||
duke@0 2778 srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB)
duke@0 2779 {
duke@0 2780 aIdx = 0;
duke@0 2781 rIdx = 1;
duke@0 2782 gIdx = 2;
duke@0 2783 bIdx = 3;
duke@0 2784 }
duke@0 2785 else if (srcP->imageType ==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR||
duke@0 2786 srcP->imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE)
duke@0 2787 {
duke@0 2788 aIdx = 0;
duke@0 2789 rIdx = 3;
duke@0 2790 gIdx = 2;
duke@0 2791 bIdx = 1;
duke@0 2792 }
duke@0 2793 else if (srcP->imageType == java_awt_image_BufferedImage_TYPE_3BYTE_BGR){
duke@0 2794 rIdx = 2;
duke@0 2795 gIdx = 1;
duke@0 2796 bIdx = 0;
duke@0 2797 aIdx = 0; /* Ignored */
duke@0 2798 }
duke@0 2799 else if (srcP->cmodel.cmType == INDEX_CM_TYPE) {
duke@0 2800 rIdx = 0;
duke@0 2801 gIdx = 1;
duke@0 2802 bIdx = 2;
duke@0 2803 aIdx = 3; /* Use supportsAlpha to see if it is really there */
duke@0 2804 }
duke@0 2805 else {
duke@0 2806 return -1;
duke@0 2807 }
duke@0 2808
duke@0 2809 /* Lock down the destination raster */
duke@0 2810 dataP = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env,
duke@0 2811 rasterP->jdata, NULL);
duke@0 2812 if (dataP == NULL) {
duke@0 2813 return -1;
duke@0 2814 }
duke@0 2815 argb = (*env)->GetPrimitiveArrayCritical(env, cmodelP->jrgb, NULL);
duke@0 2816 if (argb == NULL) {
duke@0 2817 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
duke@0 2818 JNI_ABORT);
duke@0 2819 return -1;
duke@0 2820 }
duke@0 2821
duke@0 2822 cDataP = dataP + dstP->hints.dataOffset;
duke@0 2823 sP = (unsigned char *) mlib_ImageGetData(mlibImP);
duke@0 2824
duke@0 2825 for (y=0; y < rasterP->height; y++, cDataP += rasterP->scanlineStride) {
duke@0 2826 cP = cDataP;
duke@0 2827 for (x=0; x < rasterP->width; x++, cP += rasterP->pixelStride) {
duke@0 2828 *cP = colorMatch(sP[rIdx], sP[gIdx], sP[bIdx], sP[aIdx],
duke@0 2829 (unsigned char *)argb, cmodelP->mapSize);
duke@0 2830 sP += cmodelP->numComponents;
duke@0 2831 }
duke@0 2832 }
duke@0 2833
duke@0 2834 (*env)->ReleasePrimitiveArrayCritical(env, cmodelP->jrgb, argb, JNI_ABORT);
duke@0 2835 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
duke@0 2836 JNI_ABORT);
duke@0 2837 return -1;
duke@0 2838 }
duke@0 2839
duke@0 2840 static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP)
duke@0 2841 {
duke@0 2842 ColorModelS_t *cmP = &imageP->cmodel;
duke@0 2843 RasterS_t *rasterP = &imageP->raster;
duke@0 2844 HintS_t *hintP = &imageP->hints;
duke@0 2845 int *rgb;
duke@0 2846 int status = 0;
duke@0 2847 unsigned char *dataP, *cP;
duke@0 2848 unsigned int *mP;
duke@0 2849 int width = rasterP->width;
duke@0 2850 int height = rasterP->height;
duke@0 2851 int x, y;
duke@0 2852
duke@0 2853 /* Need to grab the lookup tables. Right now only bytes */
duke@0 2854 rgb = (int *) (*env)->GetPrimitiveArrayCritical(env, cmP->jrgb, NULL);
duke@0 2855
duke@0 2856 /* Interleaved with shared data */
duke@0 2857 dataP = (void *) (*env)->GetPrimitiveArrayCritical(env,
duke@0 2858 rasterP->jdata, NULL);
duke@0 2859 if (rgb == NULL || dataP == NULL) {
duke@0 2860 /* Release the lookup tables */
duke@0 2861 if (rgb) {
duke@0 2862 (*env)->ReleasePrimitiveArrayCritical(env, cmP->jrgb, rgb,
duke@0 2863 JNI_ABORT);
duke@0 2864 }
duke@0 2865 if (dataP) {
duke@0 2866 (*env)->ReleasePrimitiveArrayCritical(env,
duke@0 2867 rasterP->jdata, dataP,
duke@0 2868 JNI_ABORT);
duke@0 2869 }
duke@0 2870 return -1;
duke@0 2871 }
duke@0 2872
duke@0 2873 if (rasterP->dataType == BYTE_DATA_TYPE) {
duke@0 2874 unsigned char *cDataP = ((unsigned char *)dataP) + hintP->dataOffset;
duke@0 2875
duke@0 2876 for (y=0; y < height; y++) {
duke@0 2877 mP = mDataP;
duke@0 2878 cP = cDataP;
duke@0 2879 for (x=0; x < width; x++, cP += rasterP->pixelStride) {
duke@0 2880 *mP++ = rgb[*cP];
duke@0 2881 }
duke@0 2882 mDataP += width;
duke@0 2883 cDataP += rasterP->scanlineStride;
duke@0 2884 }
duke@0 2885 }
duke@0 2886 else if (rasterP->dataType == SHORT_DATA_TYPE) {
duke@0 2887 unsigned short *sDataP, *sP;
duke@0 2888 sDataP = ((unsigned short *)dataP) + hintP->channelOffset;
duke@0 2889
duke@0 2890 for (y=0; y < height; y++) {
duke@0 2891 mP = mDataP;
duke@0 2892 sP = sDataP;
duke@0 2893 for (x=0; x < width; x++, sP+=rasterP->pixelStride) {
duke@0 2894 *mP++ = rgb[*sP];
duke@0 2895 }
duke@0 2896 mDataP += width;
duke@0 2897 sDataP += rasterP->scanlineStride;
duke@0 2898 }
duke@0 2899 }
duke@0 2900 else {
duke@0 2901 /* Unknown type */
duke@0 2902 status = -1;
duke@0 2903 }
duke@0 2904 /* Release the lookup table data */
duke@0 2905 (*env)->ReleasePrimitiveArrayCritical(env, imageP->cmodel.jrgb,
duke@0 2906 rgb, JNI_ABORT);
duke@0 2907 /* Release the data array */
duke@0 2908 (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata,
duke@0 2909 dataP, JNI_ABORT);
duke@0 2910 return status;
duke@0 2911 }
duke@0 2912 /* This routine is expecting a ByteComponentRaster with a PackedColorModel */
duke@0 2913 static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 2914 unsigned char *outDataP)
duke@0 2915 {
duke@0 2916 int x, y, c;
duke@0 2917 unsigned char *outP = outDataP;
duke@0 2918 unsigned char *lineInP, *inP;
duke@0 2919 jarray jInDataP;
duke@0 2920 jint *inDataP;
duke@0 2921 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 2922
duke@0 2923 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 2924 return -1;
duke@0 2925 }
duke@0 2926
duke@0 2927 /* Grab data ptr, strides, offsets from raster */
duke@0 2928 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
duke@0 2929 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 2930 if (inDataP == NULL) {
duke@0 2931 return -1;
duke@0 2932 }
duke@0 2933 lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0];
duke@0 2934
duke@0 2935 if (component < 0) {
duke@0 2936 for (c=0; c < rasterP->numBands; c++) {
duke@0 2937 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 2938 if (roff[c] < 0) {
duke@0 2939 loff[c] = -roff[c];
duke@0 2940 roff[c] = 0;
duke@0 2941 }
duke@0 2942 else loff[c] = 0;
duke@0 2943 }
duke@0 2944 /* Convert the all bands */
duke@0 2945 if (rasterP->numBands < 4) {
duke@0 2946 /* Need to put in alpha */
duke@0 2947 for (y=0; y < rasterP->height; y++) {
duke@0 2948 inP = lineInP;
duke@0 2949 for (x=0; x < rasterP->width; x++) {
duke@0 2950 for (c=0; c < rasterP->numBands; c++) {
duke@0 2951 *outP++ = (unsigned char)
duke@0 2952 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 2953 <<loff[c]);
duke@0 2954 }
duke@0 2955 inP++;
duke@0 2956 }
duke@0 2957 lineInP += rasterP->scanlineStride;
duke@0 2958 }
duke@0 2959 }
duke@0 2960 else {
duke@0 2961 for (y=0; y < rasterP->height; y++) {
duke@0 2962 inP = lineInP;
duke@0 2963 for (x=0; x < rasterP->width; x++) {
duke@0 2964 for (c=0; c < rasterP->numBands; c++) {
duke@0 2965 *outP++ = (unsigned char)
duke@0 2966 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 2967 <<loff[c]);
duke@0 2968 }
duke@0 2969 inP++;
duke@0 2970 }
duke@0 2971 lineInP += rasterP->scanlineStride;
duke@0 2972 }
duke@0 2973 }
duke@0 2974 }
duke@0 2975 else {
duke@0 2976 c = component;
duke@0 2977 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 2978 if (roff[0] < 0) {
duke@0 2979 loff[0] = -roff[0];
duke@0 2980 roff[0] = 0;
duke@0 2981 }
duke@0 2982 else loff[c] = 0;
duke@0 2983 for (y=0; y < rasterP->height; y++) {
duke@0 2984 inP = lineInP;
duke@0 2985 for (x=0; x < rasterP->width; x++) {
duke@0 2986 *outP++ = (unsigned char)
duke@0 2987 ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
duke@0 2988 inP++;
duke@0 2989 }
duke@0 2990 lineInP += rasterP->scanlineStride;
duke@0 2991 }
duke@0 2992 }
duke@0 2993
duke@0 2994 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 2995
duke@0 2996 return 0;
duke@0 2997 }
duke@0 2998
duke@0 2999 /* This routine is expecting a ByteComponentRaster with a PackedColorModel */
duke@0 3000 static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 3001 int component, unsigned char *outDataP,
duke@0 3002 int forceAlpha)
duke@0 3003 {
duke@0 3004 int x, y, c;
duke@0 3005 unsigned char *outP = outDataP;
duke@0 3006 unsigned char *lineInP, *inP;
duke@0 3007 jarray jInDataP;
duke@0 3008 jint *inDataP;
duke@0 3009 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3010 int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
duke@0 3011 int a = numBands;
duke@0 3012
duke@0 3013 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3014 return -1;
duke@0 3015 }
duke@0 3016
duke@0 3017 /* Grab data ptr, strides, offsets from raster */
duke@0 3018 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
duke@0 3019 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 3020 if (inDataP == NULL) {
duke@0 3021 return -1;
duke@0 3022 }
duke@0 3023 lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0];
duke@0 3024
duke@0 3025 if (component < 0) {
duke@0 3026 for (c=0; c < rasterP->numBands; c++) {
duke@0 3027 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3028 if (roff[c] < 0) {
duke@0 3029 loff[c] = -roff[c];
duke@0 3030 roff[c] = 0;
duke@0 3031 }
duke@0 3032 else loff[c] = 0;
duke@0 3033 }
duke@0 3034
duke@0 3035 /* Need to put in alpha */
duke@0 3036 if (forceAlpha) {
duke@0 3037 for (y=0; y < rasterP->height; y++) {
duke@0 3038 inP = lineInP;
duke@0 3039 for (x=0; x < rasterP->width; x++) {
duke@0 3040 *outP++ = 0xff;
duke@0 3041 for (c=0; c < numBands; c++) {
duke@0 3042 *outP++ = (unsigned char)
duke@0 3043 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3044 <<loff[c]);
duke@0 3045 }
duke@0 3046 inP++;
duke@0 3047 }
duke@0 3048 lineInP += rasterP->scanlineStride;
duke@0 3049 }
duke@0 3050 }
duke@0 3051 else {
duke@0 3052 for (y=0; y < rasterP->height; y++) {
duke@0 3053 inP = lineInP;
duke@0 3054 for (x=0; x < rasterP->width; x++) {
duke@0 3055 *outP++ = (unsigned char)
duke@0 3056 (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
duke@0 3057 <<loff[a]);
duke@0 3058 for (c=0; c < numBands; c++) {
duke@0 3059 *outP++ = (unsigned char)
duke@0 3060 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3061 <<loff[c]);
duke@0 3062 }
duke@0 3063 inP++;
duke@0 3064 }
duke@0 3065 lineInP += rasterP->scanlineStride;
duke@0 3066 }
duke@0 3067 }
duke@0 3068 }
duke@0 3069 else {
duke@0 3070 c = component;
duke@0 3071 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3072 if (roff[0] < 0) {
duke@0 3073 loff[0] = -roff[0];
duke@0 3074 roff[0] = 0;
duke@0 3075 }
duke@0 3076 else loff[c] = 0;
duke@0 3077 for (y=0; y < rasterP->height; y++) {
duke@0 3078 inP = lineInP;
duke@0 3079 for (x=0; x < rasterP->width; x++) {
duke@0 3080 *outP++ = (unsigned char)
duke@0 3081 ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
duke@0 3082 inP++;
duke@0 3083 }
duke@0 3084 lineInP += rasterP->scanlineStride;
duke@0 3085 }
duke@0 3086 }
duke@0 3087
duke@0 3088 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 3089
duke@0 3090 return 0;
duke@0 3091 }
duke@0 3092
duke@0 3093 /* This routine is expecting a ShortComponentRaster with a PackedColorModel */
duke@0 3094 static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 3095 unsigned char *outDataP)
duke@0 3096 {
duke@0 3097 int x, y, c;
duke@0 3098 unsigned char *outP = outDataP;
duke@0 3099 unsigned short *lineInP, *inP;
duke@0 3100 jarray jInDataP;
duke@0 3101 jint *inDataP;
duke@0 3102 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3103
duke@0 3104 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3105 return -1;
duke@0 3106 }
duke@0 3107
duke@0 3108 /* Grab data ptr, strides, offsets from raster */
duke@0 3109 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
duke@0 3110 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 3111 if (inDataP == NULL) {
duke@0 3112 return -1;
duke@0 3113 }
duke@0 3114 lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0];
duke@0 3115
duke@0 3116 if (component < 0) {
duke@0 3117 for (c=0; c < rasterP->numBands; c++) {
duke@0 3118 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3119 if (roff[c] < 0) {
duke@0 3120 loff[c] = -roff[c];
duke@0 3121 roff[c] = 0;
duke@0 3122 }
duke@0 3123 else loff[c] = 0;
duke@0 3124 }
duke@0 3125 /* Convert the all bands */
duke@0 3126 if (rasterP->numBands < 4) {
duke@0 3127 /* Need to put in alpha */
duke@0 3128 for (y=0; y < rasterP->height; y++) {
duke@0 3129 inP = lineInP;
duke@0 3130 for (x=0; x < rasterP->width; x++) {
duke@0 3131 for (c=0; c < rasterP->numBands; c++) {
duke@0 3132 /*
duke@0 3133 *Not correct. Might need to unpremult,
duke@0 3134 * shift, etc
duke@0 3135 */
duke@0 3136 *outP++ = (unsigned char)
duke@0 3137 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3138 <<loff[c]);
duke@0 3139 }
duke@0 3140 inP++;
duke@0 3141 }
duke@0 3142 lineInP += rasterP->scanlineStride;
duke@0 3143 }
duke@0 3144 } else {
duke@0 3145 for (y=0; y < rasterP->height; y++) {
duke@0 3146 inP = lineInP;
duke@0 3147 for (x=0; x < rasterP->width; x++) {
duke@0 3148 for (c=0; c < rasterP->numBands; c++) {
duke@0 3149 /*
duke@0 3150 *Not correct. Might need to unpremult,
duke@0 3151 * shift, etc
duke@0 3152 */
duke@0 3153 *outP++ = (unsigned char)
duke@0 3154 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3155 <<loff[c]);
duke@0 3156 }
duke@0 3157 inP++;
duke@0 3158 }
duke@0 3159 lineInP += rasterP->scanlineStride;
duke@0 3160 }
duke@0 3161 }
duke@0 3162 }
duke@0 3163 else {
duke@0 3164 c = component;
duke@0 3165 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3166 if (roff[0] < 0) {
duke@0 3167 loff[0] = -roff[0];
duke@0 3168 roff[0] = 0;
duke@0 3169 }
duke@0 3170 else loff[c] = 0;
duke@0 3171 for (y=0; y < rasterP->height; y++) {
duke@0 3172 inP = lineInP;
duke@0 3173 for (x=0; x < rasterP->width; x++) {
duke@0 3174 *outP++ = (unsigned char)
duke@0 3175 ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
duke@0 3176 inP++;
duke@0 3177 }
duke@0 3178 lineInP += rasterP->scanlineStride;
duke@0 3179 }
duke@0 3180 }
duke@0 3181
duke@0 3182 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 3183
duke@0 3184 return 0;
duke@0 3185 }
duke@0 3186
duke@0 3187 /* This routine is expecting a ShortComponentRaster with a PackedColorModel */
duke@0 3188 static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 3189 int component, unsigned char *outDataP,
duke@0 3190 int forceAlpha)
duke@0 3191 {
duke@0 3192 int x, y, c;
duke@0 3193 unsigned char *outP = outDataP;
duke@0 3194 unsigned short *lineInP, *inP;
duke@0 3195 jarray jInDataP;
duke@0 3196 jint *inDataP;
duke@0 3197 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3198 int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
duke@0 3199 int a = numBands;
duke@0 3200
duke@0 3201 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3202 return -1;
duke@0 3203 }
duke@0 3204
duke@0 3205 /* Grab data ptr, strides, offsets from raster */
duke@0 3206 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
duke@0 3207 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 3208 if (inDataP == NULL) {
duke@0 3209 return -1;
duke@0 3210 }
duke@0 3211 lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0];
duke@0 3212
duke@0 3213 if (component < 0) {
duke@0 3214 for (c=0; c < rasterP->numBands; c++) {
duke@0 3215 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3216 if (roff[c] < 0) {
duke@0 3217 loff[c] = -roff[c];
duke@0 3218 roff[c] = 0;
duke@0 3219 }
duke@0 3220 else loff[c] = 0;
duke@0 3221 }
duke@0 3222
duke@0 3223 /* Need to put in alpha */
duke@0 3224 if (forceAlpha) {
duke@0 3225 for (y=0; y < rasterP->height; y++) {
duke@0 3226 inP = lineInP;
duke@0 3227 for (x=0; x < rasterP->width; x++) {
duke@0 3228 *outP++ = 0xff;
duke@0 3229 for (c=0; c < numBands; c++) {
duke@0 3230 /*
duke@0 3231 * Not correct. Might need to unpremult,
duke@0 3232 * shift, etc
duke@0 3233 */
duke@0 3234 *outP++ = (unsigned char)
duke@0 3235 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3236 <<loff[c]);
duke@0 3237 }
duke@0 3238 inP++;
duke@0 3239 }
duke@0 3240 lineInP += rasterP->scanlineStride;
duke@0 3241 }
duke@0 3242 }
duke@0 3243 else {
duke@0 3244 for (y=0; y < rasterP->height; y++) {
duke@0 3245 inP = lineInP;
duke@0 3246 for (x=0; x < rasterP->width; x++) {
duke@0 3247 *outP++ = (unsigned char)
duke@0 3248 (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
duke@0 3249 <<loff[a]);
duke@0 3250 for (c=0; c < numBands; c++) {
duke@0 3251 /*
duke@0 3252 * Not correct. Might need to
duke@0 3253 * unpremult, shift, etc
duke@0 3254 */
duke@0 3255 *outP++ = (unsigned char)
duke@0 3256 (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3257 <<loff[c]);
duke@0 3258 }
duke@0 3259 inP++;
duke@0 3260 }
duke@0 3261 lineInP += rasterP->scanlineStride;
duke@0 3262 }
duke@0 3263 }
duke@0 3264 }
duke@0 3265 else {
duke@0 3266 c = component;
duke@0 3267 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3268 if (roff[0] < 0) {
duke@0 3269 loff[0] = -roff[0];
duke@0 3270 roff[0] = 0;
duke@0 3271 }
duke@0 3272 else loff[c] = 0;
duke@0 3273 for (y=0; y < rasterP->height; y++) {
duke@0 3274 inP = lineInP;
duke@0 3275 for (x=0; x < rasterP->width; x++) {
duke@0 3276 *outP++ = (unsigned char)
duke@0 3277 ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
duke@0 3278 inP++;
duke@0 3279 }
duke@0 3280 lineInP += rasterP->scanlineStride;
duke@0 3281 }
duke@0 3282 }
duke@0 3283
duke@0 3284 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 3285
duke@0 3286 return 0;
duke@0 3287
duke@0 3288 }
duke@0 3289
duke@0 3290 /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
duke@0 3291 static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 3292 unsigned char *outDataP)
duke@0 3293 {
duke@0 3294 int x, y, c;
duke@0 3295 unsigned char *outP = outDataP;
duke@0 3296 unsigned int *lineInP, *inP;
duke@0 3297 jarray jInDataP;
duke@0 3298 jint *inDataP;
duke@0 3299 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3300
duke@0 3301 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3302 return -1;
duke@0 3303 }
duke@0 3304
duke@0 3305 /* Grab data ptr, strides, offsets from raster */
duke@0 3306 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
duke@0 3307 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 3308 if (inDataP == NULL) {
duke@0 3309 return -1;
duke@0 3310 }
duke@0 3311 lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0];
duke@0 3312
duke@0 3313 if (component < 0) {
duke@0 3314 for (c=0; c < rasterP->numBands; c++) {
duke@0 3315 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3316 if (roff[c] < 0) {
duke@0 3317 loff[c] = -roff[c];
duke@0 3318 roff[c] = 0;
duke@0 3319 }
duke@0 3320 else loff[c] = 0;
duke@0 3321 }
duke@0 3322 /* Convert the all bands */
duke@0 3323 if (rasterP->numBands < 4) {
duke@0 3324 for (y=0; y < rasterP->height; y++) {
duke@0 3325 inP = lineInP;
duke@0 3326 for (x=0; x < rasterP->width; x++) {
duke@0 3327 for (c=0; c < rasterP->numBands; c++) {
duke@0 3328 /*
duke@0 3329 * Not correct. Might need to unpremult,
duke@0 3330 * shift, etc
duke@0 3331 */
duke@0 3332 *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3333 <<loff[c]);
duke@0 3334 }
duke@0 3335 inP++;
duke@0 3336 }
duke@0 3337 lineInP += rasterP->scanlineStride;
duke@0 3338 }
duke@0 3339 }
duke@0 3340 else {
duke@0 3341 for (y=0; y < rasterP->height; y++) {
duke@0 3342 inP = lineInP;
duke@0 3343 for (x=0; x < rasterP->width; x++) {
duke@0 3344 for (c=0; c < rasterP->numBands; c++) {
duke@0 3345 /*
duke@0 3346 * Not correct. Might need to
duke@0 3347 * unpremult, shift, etc
duke@0 3348 */
duke@0 3349 *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3350 <<loff[c]);
duke@0 3351 }
duke@0 3352 inP++;
duke@0 3353 }
duke@0 3354 lineInP += rasterP->scanlineStride;
duke@0 3355 }
duke@0 3356 }
duke@0 3357 }
duke@0 3358 else {
duke@0 3359 c = component;
duke@0 3360 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3361 if (roff[0] < 0) {
duke@0 3362 loff[0] = -roff[0];
duke@0 3363 roff[0] = 0;
duke@0 3364 }
duke@0 3365 else loff[c] = 0;
duke@0 3366 for (y=0; y < rasterP->height; y++) {
duke@0 3367 inP = lineInP;
duke@0 3368 for (x=0; x < rasterP->width; x++) {
duke@0 3369 *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
duke@0 3370 inP++;
duke@0 3371 }
duke@0 3372 lineInP += rasterP->scanlineStride;
duke@0 3373 }
duke@0 3374 }
duke@0 3375
duke@0 3376 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 3377
duke@0 3378 return 0;
duke@0 3379 }
duke@0 3380
duke@0 3381 /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
duke@0 3382 static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
duke@0 3383 int component, unsigned char *outDataP,
duke@0 3384 int forceAlpha)
duke@0 3385 {
duke@0 3386 int x, y, c;
duke@0 3387 unsigned char *outP = outDataP;
duke@0 3388 unsigned int *lineInP, *inP;
duke@0 3389 jarray jInDataP;
duke@0 3390 jint *inDataP;
duke@0 3391 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3392 int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
duke@0 3393 int a = numBands;
duke@0 3394
duke@0 3395 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3396 return -1;
duke@0 3397 }
duke@0 3398
duke@0 3399 /* Grab data ptr, strides, offsets from raster */
duke@0 3400 jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
duke@0 3401 inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
duke@0 3402 if (inDataP == NULL) {
duke@0 3403 return -1;
duke@0 3404 }
duke@0 3405 lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0];
duke@0 3406
duke@0 3407 if (component < 0) {
duke@0 3408 for (c=0; c < rasterP->numBands; c++) {
duke@0 3409 roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3410 if (roff[c] < 0) {
duke@0 3411 loff[c] = -roff[c];
duke@0 3412 roff[c] = 0;
duke@0 3413 }
duke@0 3414 else loff[c] = 0;
duke@0 3415 }
duke@0 3416
duke@0 3417 /* Need to put in alpha */
duke@0 3418 if (forceAlpha) {
duke@0 3419 for (y=0; y < rasterP->height; y++) {
duke@0 3420 inP = lineInP;
duke@0 3421 for (x=0; x < rasterP->width; x++) {
duke@0 3422 *outP++ = 0xff;
duke@0 3423 for (c=0; c < numBands; c++) {
duke@0 3424 /*
duke@0 3425 * Not correct. Might need to unpremult,
duke@0 3426 * shift, etc
duke@0 3427 */
duke@0 3428 *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3429 <<loff[c]);
duke@0 3430 }
duke@0 3431 inP++;
duke@0 3432 }
duke@0 3433 lineInP += rasterP->scanlineStride;
duke@0 3434 }
duke@0 3435 }
duke@0 3436 else {
duke@0 3437 for (y=0; y < rasterP->height; y++) {
duke@0 3438 inP = lineInP;
duke@0 3439 for (x=0; x < rasterP->width; x++) {
duke@0 3440 *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
duke@0 3441 <<loff[a]);
duke@0 3442 for (c=0; c < numBands; c++) {
duke@0 3443 /*
duke@0 3444 * Not correct. Might need to
duke@0 3445 * unpremult, shift, etc
duke@0 3446 */
duke@0 3447 *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
duke@0 3448 <<loff[c]);
duke@0 3449 }
duke@0 3450 inP++;
duke@0 3451 }
duke@0 3452 lineInP += rasterP->scanlineStride;
duke@0 3453 }
duke@0 3454 }
duke@0 3455 }
duke@0 3456 else {
duke@0 3457 c = component;
duke@0 3458 roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3459 if (roff[0] < 0) {
duke@0 3460 loff[0] = -roff[0];
duke@0 3461 roff[0] = 0;
duke@0 3462 }
duke@0 3463 else loff[c] = 0;
duke@0 3464 for (y=0; y < rasterP->height; y++) {
duke@0 3465 inP = lineInP;
duke@0 3466 for (x=0; x < rasterP->width; x++) {
duke@0 3467 *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
duke@0 3468 inP++;
duke@0 3469 }
duke@0 3470 lineInP += rasterP->scanlineStride;
duke@0 3471 }
duke@0 3472 }
duke@0 3473
duke@0 3474 (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
duke@0 3475
duke@0 3476 return 0;
duke@0 3477 }
duke@0 3478
duke@0 3479 /* This routine is expecting a ByteComponentRaster with a PackedColorModel */
duke@0 3480 static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
duke@0 3481 unsigned char *inDataP)
duke@0 3482 {
duke@0 3483 int x, y, c;
duke@0 3484 unsigned char *inP = inDataP;
duke@0 3485 unsigned char *lineOutP, *outP;
duke@0 3486 jarray jOutDataP;
bae@6381 3487 jsize dataArrayLength;
bae@6381 3488 unsigned char *outDataP;
duke@0 3489 int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
duke@0 3490
duke@0 3491 if (rasterP->numBands > MAX_NUMBANDS) {
duke@0 3492 return -1;
duke@0 3493 }
duke@0 3494
duke@0 3495 /* Grab data ptr, strides, offsets from raster */
duke@0 3496 jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
bae@6381 3497 if (JNU_IsNull(env, jOutDataP)) {
bae@6381 3498 return -1;
bae@6381 3499 }
bae@6381 3500
bae@6381 3501 dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
bae@6381 3502 CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
bae@6381 3503
duke@0 3504 outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
duke@0 3505 if (outDataP == NULL) {
duke@0 3506 return -1;
duke@0 3507 }
bae@6381 3508 lineOutP = outDataP + rasterP->chanOffsets[0];
duke@0 3509
duke@0 3510 if (component < 0) {
duke@0 3511 for (c=0; c < rasterP->numBands; c++) {
duke@0 3512 loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
duke@0 3513 if (loff[c] < 0) {
duke@0 3514 roff[c] = -loff[c];
duke@0 3515 loff[c] = 0;
duke@0 3516 }
duke@0 3517 else roff[c] = 0;
duke@0 3518 }
duke@0 3519 /* Convert the all bands */
duke@0 3520 for (y=0; y < rasterP->height; y++) {
duke@0 3521 outP = lineOutP;
duke@0 3522 *outP = 0;
duke@0 3523 for (x=0; x < rasterP->width; x++) {
duke@0 3524 for (c=0; c < rasterP->numBands; c++, inP++) {
duke@0 3525 *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
duke@0 3526 }
duke@0 3527 outP++;