0N/A/*
3261N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include <stdio.h>
0N/A#include <stdlib.h>
0N/A#include <string.h>
0N/A#include "sun_awt_image_ImagingLib.h"
0N/A#include "java_awt_Transparency.h"
0N/A#include "java_awt_image_AffineTransformOp.h"
0N/A#include "java_awt_image_BufferedImage.h"
0N/A#include "java_awt_color_ColorSpace.h"
0N/A#include "java_awt_image_ConvolveOp.h"
0N/A#include "sun_awt_image_IntegerComponentRaster.h"
0N/A#include "awt_ImagingLib.h"
0N/A#include "awt_parseImage.h"
0N/A#include "imageInitIDs.h"
0N/A#include <jni.h>
0N/A#include <jni_util.h>
0N/A#include <assert.h>
0N/A#include "awt_Mlib.h"
0N/A#include "gdefs.h"
0N/A#include "safe_alloc.h"
5817N/A#include "safe_math.h"
0N/A
0N/A/***************************************************************************
0N/A * Definitions *
0N/A ***************************************************************************/
0N/A#define jio_fprintf fprintf
0N/A
0N/A#ifndef TRUE
0N/A#define TRUE 1
0N/A#endif /* TRUE */
0N/A
0N/A#ifndef FALSE
0N/A#define FALSE 0
0N/A#endif /* FALSE */
0N/A
0N/A#define TYPE_CUSTOM java_awt_image_BufferedImage_TYPE_CUSTOM
0N/A#define TYPE_INT_RGB java_awt_image_BufferedImage_TYPE_INT_RGB
0N/A#define TYPE_INT_ARGB java_awt_image_BufferedImage_TYPE_INT_ARGB
0N/A#define TYPE_INT_ARGB_PRE java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE
0N/A#define TYPE_INT_BGR java_awt_image_BufferedImage_TYPE_INT_BGR
0N/A#define TYPE_4BYTE_ABGR java_awt_image_BufferedImage_TYPE_4BYTE_ABGR
0N/A#define TYPE_4BYTE_ABGR_PRE java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE
0N/A
0N/A/* (alpha*color)>>nbits + alpha>>(nbits-1) */
0N/A#define BLEND(color, alpha, alphaNbits) \
0N/A ((((alpha)*(color))>>(alphaNbits)) + ((alpha) >> ((alphaNbits)-1)))
0N/A
0N/A /* ((color - (alpha>>(nBits-1)))<<nBits)/alpha */
0N/A#define UNBLEND(color, alpha, alphaNbits) \
0N/A ((((color)-((alpha)>>((alphaNbits)-1)))<<(alphaNbits))/(alpha))
0N/A
0N/A/* Enumeration of all of the mlib functions used */
0N/Atypedef enum {
0N/A MLIB_CONVMxN,
0N/A MLIB_AFFINE,
0N/A MLIB_LOOKUP,
0N/A MLIB_CONVKERNCVT
0N/A} mlibTypeE_t;
0N/A
0N/Atypedef struct {
0N/A int dataType; /* One of BYTE_DATA_TYPE, SHORT_DATA_TYPE, */
0N/A int needToCopy;
0N/A int cvtSrcToDefault; /* If TRUE, convert the src to def CM (pre?) */
0N/A int allocDefaultDst; /* If TRUE, alloc def CM dst buffer */
0N/A int cvtToDst; /* If TRUE, convert dst buffer to Dst CM */
0N/A int addAlpha;
0N/A} mlibHintS_t;
0N/A
0N/A/***************************************************************************
0N/A * Static Variables/Structures *
0N/A ***************************************************************************/
0N/A
0N/Astatic mlibSysFnS_t sMlibSysFns = {
0N/A NULL, // placeholder for j2d_mlib_ImageCreate
0N/A NULL, // placeholder for j2d_mlib_ImageCreateStruct
0N/A NULL, // placeholder for j2d_mlib_ImageDelete
0N/A};
0N/A
0N/Astatic mlibFnS_t sMlibFns[] = {
0N/A {NULL, "j2d_mlib_ImageConvMxN"},
0N/A {NULL, "j2d_mlib_ImageAffine"},
0N/A {NULL, "j2d_mlib_ImageLookUp"},
0N/A {NULL, "j2d_mlib_ImageConvKernelConvert"},
0N/A {NULL, NULL},
0N/A};
0N/A
0N/Astatic int s_timeIt = 0;
0N/Astatic int s_printIt = 0;
0N/Astatic int s_startOff = 0;
0N/Astatic int s_nomlib = 0;
0N/A
0N/A/***************************************************************************
0N/A * Static Function Prototypes *
0N/A ***************************************************************************/
0N/A
0N/Astatic int
0N/AallocateArray(JNIEnv *env, BufImageS_t *imageP,
0N/A mlib_image **mlibImagePP, void **dataPP, int isSrc,
0N/A int cvtToDefault, int addAlpha);
0N/Astatic int
0N/AallocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
0N/A mlib_image **mlibImagePP, void **dataPP, int isSrc);
0N/A
0N/Astatic void
0N/AfreeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
0N/A void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
0N/A void *dstdataP);
0N/Astatic void
0N/AfreeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
0N/A void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
0N/A void *dstdataP);
0N/A
0N/Astatic int
0N/AstoreImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A mlib_image *mlibImP);
0N/A
0N/Astatic int
0N/AstoreRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
0N/A mlib_image *mlibImP);
0N/A
0N/Astatic int
0N/AstoreICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A mlib_image *mlibImP);
0N/A
0N/Astatic int
0N/AcolorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors);
0N/A
0N/Astatic int
0N/AsetImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A int expandICM, int useAlpha,
0N/A int premultiply, mlibHintS_t *hintP);
0N/A
0N/A
0N/Astatic int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP);
0N/Astatic int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha);
0N/Astatic int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha);
0N/Astatic int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha);
0N/Astatic int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP);
0N/Astatic int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int supportsAlpha);
0N/Astatic int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int supportsAlpha);
0N/Astatic int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int supportsAlpha);
0N/A
0N/Amlib_start_timer start_timer = NULL;
0N/Amlib_stop_timer stop_timer = NULL;
0N/A
0N/A/***************************************************************************
0N/A * Debugging Definitions *
0N/A ***************************************************************************/
0N/A#ifdef DEBUG
0N/A
0N/Astatic void
0N/AprintMedialibError(int status) {
0N/A switch(status) {
0N/A case MLIB_FAILURE:
0N/A jio_fprintf(stderr, "failure\n");
0N/A break;
0N/A case MLIB_NULLPOINTER:
0N/A jio_fprintf(stderr, "null pointer\n");
0N/A break;
0N/A case MLIB_OUTOFRANGE:
0N/A jio_fprintf (stderr, "out of range\n");
0N/A break;
0N/A default:
0N/A jio_fprintf (stderr, "medialib error\n");
0N/A break;
0N/A }
0N/A}
0N/A#else /* ! DEBUG */
0N/A# define printMedialibError(x)
0N/A
0N/A#endif /* ! DEBUG */
0N/A
1115N/Astatic int
1115N/AgetMlibEdgeHint(jint edgeHint) {
1115N/A switch (edgeHint) {
1115N/A case java_awt_image_ConvolveOp_EDGE_NO_OP:
1115N/A return MLIB_EDGE_DST_COPY_SRC;
1115N/A case java_awt_image_ConvolveOp_EDGE_ZERO_FILL:
1115N/A default:
1115N/A return MLIB_EDGE_DST_FILL_ZERO;
1115N/A }
1115N/A}
0N/A
0N/A/***************************************************************************
0N/A * External Functions *
0N/A ***************************************************************************/
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_awt_image_ImagingLib_convolveBI(JNIEnv *env, jobject this,
0N/A jobject jsrc, jobject jdst,
0N/A jobject jkernel, jint edgeHint)
0N/A{
0N/A void *sdata, *ddata;
0N/A mlib_image *src;
0N/A mlib_image *dst;
0N/A int i, scale;
0N/A mlib_d64 *dkern;
0N/A mlib_s32 *kdata;
0N/A int klen;
0N/A float kmax;
0N/A mlib_s32 cmask;
0N/A mlib_status status;
0N/A int retStatus = 1;
0N/A float *kern;
0N/A BufImageS_t *srcImageP, *dstImageP;
0N/A jobject jdata;
0N/A int kwidth;
0N/A int kheight;
0N/A int w, h;
0N/A int x, y;
0N/A mlibHintS_t hint;
0N/A int nbands;
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
0N/A if (s_nomlib) return 0;
0N/A if (s_timeIt) (*start_timer)(3600);
0N/A
0N/A kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
0N/A kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
0N/A jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
0N/A klen = (*env)->GetArrayLength(env, jdata);
0N/A kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
0N/A if (kern == NULL) {
0N/A /* out of memory exception already thrown */
0N/A return 0;
0N/A }
0N/A
0N/A if ((kwidth&0x1) == 0) {
0N/A /* Kernel has even width */
0N/A w = kwidth+1;
0N/A }
0N/A else {
0N/A w = kwidth;
0N/A }
0N/A if ((kheight&0x1) == 0) {
0N/A /* Kernel has even height */
0N/A h = kheight+1;
0N/A }
0N/A else {
0N/A h = kheight;
0N/A }
0N/A
0N/A dkern = NULL;
0N/A if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
0N/A dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
0N/A }
0N/A if (dkern == NULL) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
0N/A return 0;
0N/A }
0N/A
0N/A /* Need to flip and find max value of the kernel.
0N/A * Also, save the kernel values as mlib_d64 values.
0N/A * The flip is to operate correctly with medialib,
0N/A * which doesn't do the mathemetically correct thing,
0N/A * i.e. it doesn't rotate the kernel by 180 degrees.
0N/A * REMIND: This should perhaps be done at the Java
0N/A * level by ConvolveOp.
0N/A * REMIND: Should the max test be looking at absolute
0N/A * values?
0N/A * REMIND: What if klen != kheight * kwidth?
0N/A */
0N/A kmax = kern[klen-1];
0N/A i = klen-1;
0N/A for (y=0; y < kheight; y++) {
0N/A for (x=0; x < kwidth; x++, i--) {
0N/A dkern[y*w+x] = (mlib_d64) kern[i];
0N/A if (kern[i] > kmax) {
0N/A kmax = kern[i];
0N/A }
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
0N/A
0N/A if (kmax > 1<<16) {
0N/A /* We can only handle 16 bit max */
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A
0N/A /* Parse the source image */
0N/A if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination image */
0N/A if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A nbands = setImageHints(env, srcImageP, dstImageP, TRUE, TRUE,
0N/A FALSE, &hint);
0N/A if (nbands < 1) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A /* Allocate the arrays */
0N/A if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
0N/A hint.cvtSrcToDefault, hint.addAlpha) < 0) {
0N/A /* Must be some problem */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
0N/A hint.cvtToDst, FALSE) < 0) {
0N/A /* Must be some problem */
0N/A freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A kdata = NULL;
0N/A if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
0N/A kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
0N/A }
0N/A if (kdata == NULL) {
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
0N/A mlib_ImageGetType(src)) != MLIB_SUCCESS) {
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A free(kdata);
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
0N/A for (y=kheight-1; y >= 0; y--) {
0N/A for (x=kwidth-1; x >= 0; x--) {
0N/A fprintf(stderr, "%g ", dkern[y*w+x]);
0N/A }
0N/A fprintf(stderr, "\n");
0N/A }
0N/A fprintf(stderr, "New Kernel(scale=%d):\n", scale);
0N/A for (y=kheight-1; y >= 0; y--) {
0N/A for (x=kwidth-1; x >= 0; x--) {
0N/A fprintf(stderr, "%d ", kdata[y*w+x]);
0N/A }
0N/A fprintf(stderr, "\n");
0N/A }
0N/A }
0N/A
0N/A cmask = (1<<src->channels)-1;
0N/A status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
0N/A (w-1)/2, (h-1)/2, scale, cmask,
1115N/A getMlibEdgeHint(edgeHint));
0N/A
0N/A if (status != MLIB_SUCCESS) {
0N/A printMedialibError(status);
0N/A retStatus = 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A unsigned int *dP;
0N/A if (s_startOff != 0) {
0N/A printf("Starting at %d\n", s_startOff);
0N/A }
0N/A if (sdata == NULL) {
0N/A dP = (unsigned int *) mlib_ImageGetData(src);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) sdata;
0N/A }
0N/A printf("src is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[s_startOff+i]);
0N/A }
0N/A printf("\n");
0N/A if (ddata == NULL) {
0N/A dP = (unsigned int *)mlib_ImageGetData(dst);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) ddata;
0N/A }
0N/A printf("dst is \n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[s_startOff+i]);
0N/A }
0N/A printf("\n");
0N/A }
0N/A
0N/A /* Means that we couldn't write directly into the destination buffer */
0N/A if (ddata == NULL) {
0N/A
0N/A /* Need to store it back into the array */
0N/A if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
0N/A /* Error */
0N/A retStatus = 0;
0N/A }
0N/A }
0N/A
0N/A /* Release the pinned memory */
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A free(dkern);
0N/A free(kdata);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600, 1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
0N/A jobject jsrc, jobject jdst,
0N/A jobject jkernel, jint edgeHint)
0N/A{
0N/A mlib_image *src;
0N/A mlib_image *dst;
0N/A int i, scale;
0N/A mlib_d64 *dkern;
0N/A mlib_s32 *kdata;
0N/A int klen;
0N/A float kmax;
0N/A int retStatus = 1;
0N/A mlib_status status;
0N/A mlib_s32 cmask;
0N/A void *sdata;
0N/A void *ddata;
0N/A RasterS_t *srcRasterP;
0N/A RasterS_t *dstRasterP;
0N/A int kwidth;
0N/A int kheight;
0N/A int w, h;
0N/A int x, y;
0N/A jobject jdata;
0N/A float *kern;
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
0N/A if (s_nomlib) return 0;
0N/A if (s_timeIt) (*start_timer)(3600);
0N/A
0N/A kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
0N/A kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
0N/A jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
0N/A klen = (*env)->GetArrayLength(env, jdata);
0N/A kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
0N/A if (kern == NULL) {
0N/A /* out of memory exception already thrown */
0N/A return 0;
0N/A }
0N/A
0N/A if ((kwidth&0x1) == 0) {
0N/A /* Kernel has even width */
0N/A w = kwidth+1;
0N/A }
0N/A else {
0N/A w = kwidth;
0N/A }
0N/A if ((kheight&0x1) == 0) {
0N/A /* Kernel has even height */
0N/A h = kheight+1;
0N/A }
0N/A else {
0N/A h = kheight;
0N/A }
0N/A
0N/A dkern = NULL;
0N/A if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
0N/A dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
0N/A }
0N/A if (dkern == NULL) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
0N/A return 0;
0N/A }
0N/A
0N/A /* Need to flip and find max value of the kernel.
0N/A * Also, save the kernel values as mlib_d64 values.
0N/A * The flip is to operate correctly with medialib,
0N/A * which doesn't do the mathemetically correct thing,
0N/A * i.e. it doesn't rotate the kernel by 180 degrees.
0N/A * REMIND: This should perhaps be done at the Java
0N/A * level by ConvolveOp.
0N/A * REMIND: Should the max test be looking at absolute
0N/A * values?
0N/A * REMIND: What if klen != kheight * kwidth?
0N/A */
0N/A kmax = kern[klen-1];
0N/A i = klen-1;
0N/A for (y=0; y < kheight; y++) {
0N/A for (x=0; x < kwidth; x++, i--) {
0N/A dkern[y*w+x] = (mlib_d64) kern[i];
0N/A if (kern[i] > kmax) {
0N/A kmax = kern[i];
0N/A }
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
0N/A
0N/A if (kmax > 1<<16) {
0N/A /* We can only handle 16 bit max */
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the source image */
0N/A if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
0N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
0N/A free(dkern);
0N/A return -1;
0N/A }
0N/A
0N/A if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
0N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
0N/A free(srcRasterP);
0N/A free(dkern);
0N/A return -1;
0N/A }
0N/A
0N/A /* Parse the source raster */
0N/A if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
0N/A /* Can't handle any custom rasters */
0N/A free(srcRasterP);
0N/A free(dstRasterP);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination raster */
0N/A if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A free(dstRasterP);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A /* Allocate the arrays */
0N/A if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
0N/A /* Must be some problem */
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
0N/A /* Must be some problem */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A kdata = NULL;
0N/A if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
0N/A kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
0N/A }
0N/A if (kdata == NULL) {
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A free(dkern);
0N/A return 0;
0N/A }
0N/A
0N/A if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
0N/A mlib_ImageGetType(src)) != MLIB_SUCCESS) {
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A free(dkern);
0N/A free(kdata);
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
0N/A for (y=kheight-1; y >= 0; y--) {
0N/A for (x=kwidth-1; x >= 0; x--) {
0N/A fprintf(stderr, "%g ", dkern[y*w+x]);
0N/A }
0N/A fprintf(stderr, "\n");
0N/A }
0N/A fprintf(stderr, "New Kernel(scale=%d):\n", scale);
0N/A for (y=kheight-1; y >= 0; y--) {
0N/A for (x=kwidth-1; x >= 0; x--) {
0N/A fprintf(stderr, "%d ", kdata[y*w+x]);
0N/A }
0N/A fprintf(stderr, "\n");
0N/A }
0N/A }
0N/A
0N/A cmask = (1<<src->channels)-1;
0N/A status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
0N/A (w-1)/2, (h-1)/2, scale, cmask,
1115N/A getMlibEdgeHint(edgeHint));
0N/A
0N/A if (status != MLIB_SUCCESS) {
0N/A printMedialibError(status);
0N/A retStatus = 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A unsigned int *dP;
0N/A if (s_startOff != 0) {
0N/A printf("Starting at %d\n", s_startOff);
0N/A }
0N/A if (sdata == NULL) {
0N/A dP = (unsigned int *) mlib_ImageGetData(src);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) sdata;
0N/A }
0N/A printf("src is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[s_startOff+i]);
0N/A }
0N/A printf("\n");
0N/A if (ddata == NULL) {
0N/A dP = (unsigned int *)mlib_ImageGetData(dst);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) ddata;
0N/A }
0N/A printf("dst is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[s_startOff+i]);
0N/A }
0N/A printf("\n");
0N/A }
0N/A
0N/A /* Means that we couldn't write directly into the destination buffer */
0N/A if (ddata == NULL) {
0N/A unsigned char *bdataP;
0N/A unsigned short *sdataP;
0N/A
0N/A /* Punt for now */
0N/A switch (dstRasterP->dataType) {
0N/A case BYTE_DATA_TYPE:
0N/A bdataP = (unsigned char *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
0N/A break;
0N/A case SHORT_DATA_TYPE:
0N/A sdataP = (unsigned short *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
0N/A break;
0N/A default:
0N/A retStatus = 0;
0N/A }
0N/A }
0N/A
0N/A /* Release the pinned memory */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A free(dkern);
0N/A free(kdata);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600,1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_awt_image_ImagingLib_transformBI(JNIEnv *env, jobject this,
0N/A jobject jsrc,
0N/A jobject jdst,
0N/A jdoubleArray jmatrix,
0N/A jint interpType)
0N/A{
0N/A mlib_image *src;
0N/A mlib_image *dst;
0N/A int i;
0N/A int retStatus = 1;
0N/A mlib_status status;
0N/A double *matrix;
0N/A mlib_d64 mtx[6];
0N/A void *sdata;
0N/A void *ddata;
0N/A BufImageS_t *srcImageP;
0N/A BufImageS_t *dstImageP;
0N/A mlib_filter filter;
0N/A mlibHintS_t hint;
0N/A unsigned int *dP;
0N/A int useIndexed;
0N/A int nbands;
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
0N/A if (s_nomlib) return 0;
0N/A if (s_timeIt) {
0N/A (*start_timer)(3600);
0N/A }
0N/A
0N/A switch(interpType) {
0N/A case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
0N/A filter = MLIB_BILINEAR;
0N/A break;
0N/A case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
0N/A filter = MLIB_NEAREST;
0N/A break;
0N/A case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
0N/A filter = MLIB_BICUBIC;
0N/A break;
0N/A default:
0N/A JNU_ThrowInternalError(env, "Unknown interpolation type");
0N/A return -1;
0N/A }
0N/A
0N/A if ((*env)->GetArrayLength(env, jmatrix) < 6) {
0N/A /*
0N/A * Very unlikely, however we should check for this:
0N/A * if given matrix array is too short, we can't handle it
0N/A */
0N/A return 0;
0N/A }
0N/A
0N/A matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
0N/A if (matrix == NULL) {
0N/A /* out of memory error already thrown */
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
0N/A matrix[2], matrix[3], matrix[4], matrix[5]);
0N/A }
0N/A
0N/A mtx[0] = matrix[0];
0N/A mtx[1] = matrix[2];
0N/A mtx[2] = matrix[4];
0N/A mtx[3] = matrix[1];
0N/A mtx[4] = matrix[3];
0N/A mtx[5] = matrix[5];
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
0N/A
0N/A /* Parse the source image */
0N/A if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination image */
0N/A if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A /* REMIND!! Can't assume that it is the same LUT!! */
0N/A /* Fix 4213160, 4184283 */
0N/A useIndexed = (srcImageP->cmodel.cmType == INDEX_CM_TYPE &&
0N/A dstImageP->cmodel.cmType == INDEX_CM_TYPE &&
0N/A srcImageP->raster.rasterType == dstImageP->raster.rasterType &&
0N/A srcImageP->raster.rasterType == COMPONENT_RASTER_TYPE);
0N/A
0N/A nbands = setImageHints(env, srcImageP, dstImageP, !useIndexed, TRUE,
0N/A FALSE, &hint);
0N/A if (nbands < 1) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A /* Allocate the arrays */
0N/A if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
0N/A hint.cvtSrcToDefault, hint.addAlpha) < 0) {
0N/A /* Must be some problem */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
0N/A hint.cvtToDst, FALSE) < 0) {
0N/A /* Must be some problem */
0N/A freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A#if 0
0N/Afprintf(stderr,"Src----------------\n");
0N/Afprintf(stderr,"Type : %d\n",src->type);
0N/Afprintf(stderr,"Channels: %d\n",src->channels);
0N/Afprintf(stderr,"Width : %d\n",src->width);
0N/Afprintf(stderr,"Height : %d\n",src->height);
0N/Afprintf(stderr,"Stride : %d\n",src->stride);
0N/Afprintf(stderr,"Flags : %d\n",src->flags);
0N/A
0N/Afprintf(stderr,"Dst----------------\n");
0N/Afprintf(stderr,"Type : %d\n",dst->type);
0N/Afprintf(stderr,"Channels: %d\n",dst->channels);
0N/Afprintf(stderr,"Width : %d\n",dst->width);
0N/Afprintf(stderr,"Height : %d\n",dst->height);
0N/Afprintf(stderr,"Stride : %d\n",dst->stride);
0N/Afprintf(stderr,"Flags : %d\n",dst->flags);
0N/A#endif
0N/A
0N/A if (dstImageP->cmodel.cmType == INDEX_CM_TYPE) {
0N/A /* Need to clear the destination to the transparent pixel */
0N/A unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);
0N/A
0N/A memset(cP, dstImageP->cmodel.transIdx,
0N/A mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
0N/A }
0N/A /* Perform the transformation */
0N/A if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
0N/A MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
0N/A {
0N/A printMedialibError(status);
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A if (sdata == NULL) {
0N/A dP = (unsigned int *) mlib_ImageGetData(src);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) sdata;
0N/A }
0N/A printf("src is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[i]);
0N/A }
0N/A printf("\n");
0N/A if (ddata == NULL) {
0N/A dP = (unsigned int *)mlib_ImageGetData(dst);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) ddata;
0N/A }
0N/A printf("dst is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[i]);
0N/A }
0N/A printf("\n");
0N/A }
0N/A
0N/A /* Means that we couldn't write directly into the destination buffer */
0N/A if (ddata == NULL) {
0N/A freeDataArray(env, srcImageP->raster.jdata, src, sdata,
0N/A NULL, NULL, NULL);
0N/A /* Need to store it back into the array */
0N/A if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
0N/A /* Error */
0N/A retStatus = 0;
0N/A }
0N/A freeDataArray(env, NULL, NULL, NULL, dstImageP->raster.jdata,
0N/A dst, ddata);
0N/A }
0N/A else {
0N/A /* Release the pinned memory */
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A }
0N/A
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600,1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
0N/A jobject jsrc,
0N/A jobject jdst,
0N/A jdoubleArray jmatrix,
0N/A jint interpType)
0N/A{
0N/A mlib_image *src;
0N/A mlib_image *dst;
0N/A int i;
0N/A int retStatus = 1;
0N/A mlib_status status;
0N/A double *matrix;
0N/A mlib_d64 mtx[6];
0N/A void *sdata;
0N/A void *ddata;
0N/A RasterS_t *srcRasterP;
0N/A RasterS_t *dstRasterP;
0N/A mlib_filter filter;
0N/A unsigned int *dP;
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
1883N/A if (s_nomlib) return 0;
1883N/A if (s_timeIt) {
1883N/A (*start_timer)(3600);
1883N/A }
1883N/A
0N/A switch(interpType) {
0N/A case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
0N/A filter = MLIB_BILINEAR;
0N/A break;
0N/A case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
0N/A filter = MLIB_NEAREST;
0N/A break;
0N/A case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
0N/A filter = MLIB_BICUBIC;
0N/A break;
0N/A default:
0N/A JNU_ThrowInternalError(env, "Unknown interpolation type");
0N/A return -1;
0N/A }
0N/A
1883N/A if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
1883N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
1883N/A return -1;
1883N/A }
1883N/A
1883N/A if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
1883N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
1883N/A free(srcRasterP);
1883N/A return -1;
0N/A }
0N/A
0N/A if ((*env)->GetArrayLength(env, jmatrix) < 6) {
0N/A /*
0N/A * Very unlikely, however we should check for this:
0N/A * if given matrix array is too short, we can't handle it.
0N/A */
0N/A free(srcRasterP);
0N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
0N/A if (matrix == NULL) {
0N/A /* out of memory error already thrown */
0N/A free(srcRasterP);
0N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
0N/A matrix[2], matrix[3], matrix[4], matrix[5]);
0N/A }
0N/A
0N/A mtx[0] = matrix[0];
0N/A mtx[1] = matrix[2];
0N/A mtx[2] = matrix[4];
0N/A mtx[3] = matrix[1];
0N/A mtx[4] = matrix[3];
0N/A mtx[5] = matrix[5];
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
0N/A
0N/A /* Parse the source raster */
0N/A if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
0N/A /* Can't handle any custom rasters */
0N/A free(srcRasterP);
0N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination raster */
0N/A if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A /* Allocate the arrays */
0N/A if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
0N/A /* Must be some problem */
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
0N/A /* Must be some problem */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A#if 0
0N/Afprintf(stderr,"Src----------------\n");
0N/Afprintf(stderr,"Type : %d\n",src->type);
0N/Afprintf(stderr,"Channels: %d\n",src->channels);
0N/Afprintf(stderr,"Width : %d\n",src->width);
0N/Afprintf(stderr,"Height : %d\n",src->height);
0N/Afprintf(stderr,"Stride : %d\n",src->stride);
0N/Afprintf(stderr,"Flags : %d\n",src->flags);
0N/A
0N/Afprintf(stderr,"Dst----------------\n");
0N/Afprintf(stderr,"Type : %d\n",dst->type);
0N/Afprintf(stderr,"Channels: %d\n",dst->channels);
0N/Afprintf(stderr,"Width : %d\n",dst->width);
0N/Afprintf(stderr,"Height : %d\n",dst->height);
0N/Afprintf(stderr,"Stride : %d\n",dst->stride);
0N/Afprintf(stderr,"Flags : %d\n",dst->flags);
0N/A#endif
0N/A
0N/A {
0N/A unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);
0N/A
0N/A memset(cP, 0, mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
0N/A }
0N/A
0N/A /* Perform the transformation */
0N/A if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
0N/A MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
0N/A {
0N/A printMedialibError(status);
0N/A /* REMIND: Free the regions */
0N/A return 0;
0N/A }
0N/A
0N/A if (s_printIt) {
0N/A if (sdata == NULL) {
0N/A dP = (unsigned int *) mlib_ImageGetData(src);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) sdata;
0N/A }
0N/A printf("src is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[i]);
0N/A }
0N/A printf("\n");
0N/A if (ddata == NULL) {
0N/A dP = (unsigned int *)mlib_ImageGetData(dst);
0N/A }
0N/A else {
0N/A dP = (unsigned int *) ddata;
0N/A }
0N/A printf("dst is\n");
0N/A for (i=0; i < 20; i++) {
0N/A printf("%x ",dP[i]);
0N/A }
0N/A printf("\n");
0N/A }
0N/A
0N/A /* Means that we couldn't write directly into the destination buffer */
0N/A if (ddata == NULL) {
0N/A unsigned char *bdataP;
0N/A unsigned short *sdataP;
0N/A
0N/A /* Need to store it back into the array */
0N/A if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
0N/A /* Punt for now */
0N/A switch (dst->type) {
0N/A case MLIB_BYTE:
0N/A bdataP = (unsigned char *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
0N/A break;
0N/A case MLIB_SHORT:
0N/A sdataP = (unsigned short *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
0N/A break;
0N/A default:
0N/A retStatus = 0;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* Release the pinned memory */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600,1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
6344N/Atypedef struct {
6344N/A jobject jArray;
6344N/A jsize length;
6344N/A unsigned char *table;
6344N/A} LookupArrayInfo;
6344N/A
6344N/A#define NLUT 8
6344N/A
6344N/A#ifdef _LITTLE_ENDIAN
6344N/A#define INDEXES { 3, 2, 1, 0, 7, 6, 5, 4 }
6344N/A#else
6344N/A#define INDEXES { 0, 1, 2, 3, 4, 5, 6, 7 }
6344N/A#endif
6344N/A
6344N/Astatic int lookupShortData(mlib_image* src, mlib_image* dst,
6344N/A LookupArrayInfo* lookup)
6344N/A{
6344N/A int x, y;
6344N/A unsigned int mask = NLUT-1;
6344N/A
6344N/A unsigned short* srcLine = (unsigned short*)src->data;
6344N/A unsigned char* dstLine = (unsigned char*)dst->data;
6344N/A
6344N/A static int indexes[NLUT] = INDEXES;
6344N/A
6367N/A if (src->width != dst->width || src->height != dst->height) {
6367N/A return 0;
6367N/A }
6367N/A
6344N/A for (y=0; y < src->height; y++) {
6344N/A int nloop, nx;
6344N/A int npix = src->width;
6344N/A
6344N/A unsigned short* srcPixel = srcLine;
6344N/A unsigned char* dstPixel = dstLine;
6344N/A
6344N/A#ifdef SIMPLE_LOOKUP_LOOP
6344N/A for (x=0; status && x < width; x++) {
6344N/A unsigned short s = *srcPixel++;
6344N/A if (s >= lookup->length) {
6344N/A /* we can not handle source image using
6344N/A * byte lookup table. Fall back to processing
6344N/A * images in java
6344N/A */
6344N/A return 0;
6344N/A }
6344N/A *dstPixel++ = lookup->table[s];
6344N/A }
6344N/A#else
6344N/A /* Get to 32 bit-aligned point */
6344N/A while(((uintptr_t)dstPixel & 0x3) != 0 && npix>0) {
6344N/A unsigned short s = *srcPixel++;
6344N/A if (s >= lookup->length) {
6344N/A return 0;
6344N/A }
6344N/A *dstPixel++ = lookup->table[s];
6344N/A npix--;
6344N/A }
6344N/A
6344N/A /*
6344N/A * Do NLUT pixels per loop iteration.
6344N/A * Pack into ints and write out 2 at a time.
6344N/A */
6344N/A nloop = npix/NLUT;
6344N/A nx = npix%NLUT;
6344N/A
6344N/A for(x=nloop; x!=0; x--) {
6344N/A int i = 0;
6344N/A int* dstP = (int*)dstPixel;
6344N/A
6344N/A for (i = 0; i < NLUT; i++) {
6344N/A if (srcPixel[i] >= lookup->length) {
6344N/A return 0;
6344N/A }
6344N/A }
6344N/A
6344N/A dstP[0] = (int)
6344N/A ((lookup->table[srcPixel[indexes[0]]] << 24) |
6344N/A (lookup->table[srcPixel[indexes[1]]] << 16) |
6344N/A (lookup->table[srcPixel[indexes[2]]] << 8) |
6344N/A lookup->table[srcPixel[indexes[3]]]);
6344N/A dstP[1] = (int)
6344N/A ((lookup->table[srcPixel[indexes[4]]] << 24) |
6344N/A (lookup->table[srcPixel[indexes[5]]] << 16) |
6344N/A (lookup->table[srcPixel[indexes[6]]] << 8) |
6344N/A lookup->table[srcPixel[indexes[7]]]);
6344N/A
6344N/A
6344N/A dstPixel += NLUT;
6344N/A srcPixel += NLUT;
6344N/A }
6344N/A
6344N/A /*
6344N/A * Complete any remaining pixels
6344N/A */
6344N/A for(x=nx; x!=0; x--) {
6344N/A unsigned short s = *srcPixel++;
6344N/A if (s >= lookup->length) {
6344N/A return 0;
6344N/A }
6344N/A *dstPixel++ = lookup->table[s];
6344N/A }
6344N/A#endif
6344N/A
6344N/A dstLine += dst->stride; // array of bytes, scan stride in bytes
6344N/A srcLine += src->stride / 2; // array of shorts, scan stride in bytes
6344N/A }
6344N/A return 1;
6344N/A}
6344N/A
0N/AJNIEXPORT jint JNICALL
6344N/AJava_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
0N/A jobject jsrc, jobject jdst,
0N/A jobjectArray jtableArrays)
0N/A{
0N/A mlib_image *src;
0N/A mlib_image *dst;
0N/A void *sdata, *ddata;
0N/A unsigned char **tbl;
0N/A unsigned char lut[256];
0N/A int retStatus = 1;
0N/A int i;
0N/A mlib_status status;
6344N/A int lut_nbands;
6344N/A LookupArrayInfo *jtable;
0N/A BufImageS_t *srcImageP, *dstImageP;
0N/A int nbands;
0N/A int ncomponents;
0N/A mlibHintS_t hint;
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
0N/A if (s_nomlib) return 0;
0N/A if (s_timeIt) (*start_timer)(3600);
0N/A
0N/A /* Parse the source image */
0N/A if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination image */
0N/A if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
0N/A /* Can't handle any custom images */
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A return 0;
0N/A }
0N/A
6352N/A nbands = setImageHints(env, srcImageP, dstImageP, FALSE, TRUE,
6352N/A FALSE, &hint);
6352N/A
6352N/A if (nbands < 1 || nbands > srcImageP->cmodel.numComponents) {
6352N/A /* Can't handle any custom images */
6352N/A awt_freeParsedImage(srcImageP, TRUE);
6352N/A awt_freeParsedImage(dstImageP, TRUE);
6352N/A return 0;
6352N/A }
6352N/A
6353N/A ncomponents = srcImageP->cmodel.isDefaultCompatCM
6353N/A ? 4
6353N/A : srcImageP->cmodel.numComponents;
6353N/A
6352N/A /* Make sure that color order can be used for
6352N/A * re-ordering of lookup arrays.
6352N/A */
6352N/A for (i = 0; i < nbands; i++) {
6352N/A int idx = srcImageP->hints.colorOrder[i];
6352N/A
6353N/A if (idx < 0 || idx >= ncomponents) {
6352N/A awt_freeParsedImage(srcImageP, TRUE);
6352N/A awt_freeParsedImage(dstImageP, TRUE);
6352N/A return 0;
6352N/A }
6352N/A }
6352N/A
6344N/A lut_nbands = (*env)->GetArrayLength(env, jtableArrays);
0N/A
6344N/A if (lut_nbands > ncomponents) {
6344N/A lut_nbands = ncomponents;
6344N/A }
6344N/A
0N/A tbl = NULL;
0N/A if (SAFE_TO_ALLOC_2(ncomponents, sizeof(unsigned char *))) {
0N/A tbl = (unsigned char **)
0N/A calloc(1, ncomponents * sizeof(unsigned char *));
0N/A }
0N/A
0N/A jtable = NULL;
6344N/A if (SAFE_TO_ALLOC_2(lut_nbands, sizeof(LookupArrayInfo))) {
6344N/A jtable = (LookupArrayInfo *)malloc(lut_nbands * sizeof (LookupArrayInfo));
0N/A }
0N/A
6344N/A if (tbl == NULL || jtable == NULL) {
1883N/A if (tbl != NULL) free(tbl);
1883N/A if (jtable != NULL) free(jtable);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A JNU_ThrowNullPointerException(env, "NULL LUT");
0N/A return 0;
0N/A }
0N/A /* Need to grab these pointers before we lock down arrays */
6344N/A for (i=0; i < lut_nbands; i++) {
6344N/A jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
6344N/A
6344N/A if (jtable[i].jArray != NULL) {
6344N/A jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
6344N/A jtable[i].table = NULL;
6344N/A
6344N/A if (jtable[i].length < 256) {
6344N/A /* we may read outside the table during lookup */
6344N/A jtable[i].jArray = NULL;
6344N/A jtable[i].length = 0;
6344N/A }
6344N/A }
6344N/A if (jtable[i].jArray == NULL) {
1883N/A free(tbl);
1883N/A free(jtable);
1883N/A awt_freeParsedImage(srcImageP, TRUE);
1883N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A /* Allocate the arrays */
0N/A if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
0N/A /* Must be some problem */
1883N/A free(tbl);
1883N/A free(jtable);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
0N/A /* Must be some problem */
1883N/A free(tbl);
1883N/A free(jtable);
0N/A freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A /* Set up a straight lut so we don't mess around with alpha */
0N/A /*
0N/A * NB: medialib lookup routine expects lookup array for each
0N/A * component of source image including alpha.
0N/A * If lookup table we got form the java layer does not contain
0N/A * sufficient number of lookup arrays we add references to identity
0N/A * lookup array to make medialib happier.
0N/A */
6344N/A if (lut_nbands < ncomponents) {
0N/A int j;
0N/A /* REMIND: This should be the size of the input lut!! */
0N/A for (j=0; j < 256; j++) {
0N/A lut[j] = j;
0N/A }
0N/A for (j=0; j < ncomponents; j++) {
0N/A tbl[j] = lut;
0N/A }
0N/A }
0N/A
6344N/A for (i=0; i < lut_nbands; i++) {
6344N/A jtable[i].table = (unsigned char *)
6344N/A (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
6344N/A if (jtable[i].table == NULL) {
0N/A /* Free what we've got so far. */
0N/A int j;
0N/A for (j = 0; j < i; j++) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env,
6344N/A jtable[j].jArray,
6344N/A (jbyte *) jtable[j].table,
0N/A JNI_ABORT);
0N/A }
1883N/A free(tbl);
1883N/A free(jtable);
0N/A freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A return 0;
0N/A }
6344N/A tbl[srcImageP->hints.colorOrder[i]] = jtable[i].table;
0N/A }
0N/A
6344N/A if (lut_nbands == 1) {
0N/A for (i=1; i < nbands -
0N/A srcImageP->cmodel.supportsAlpha; i++) {
6344N/A tbl[srcImageP->hints.colorOrder[i]] = jtable[0].table;
0N/A }
0N/A }
0N/A
0N/A /* Mlib needs 16bit lookuptable and must be signed! */
0N/A if (src->type == MLIB_SHORT) {
0N/A if (dst->type == MLIB_BYTE) {
0N/A if (nbands > 1) {
0N/A retStatus = 0;
0N/A }
0N/A else {
6344N/A retStatus = lookupShortData(src, dst, &jtable[0]);
0N/A }
0N/A }
0N/A /* How about ddata == null? */
0N/A }
0N/A else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
0N/A (void **)tbl) != MLIB_SUCCESS)) {
0N/A printMedialibError(status);
0N/A retStatus = 0;
0N/A }
0N/A
0N/A /*
0N/A * Means that we couldn't write directly into
0N/A * the destination buffer
0N/A */
0N/A if (ddata == NULL) {
0N/A
0N/A /* Need to store it back into the array */
0N/A if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
0N/A /* Error */
0N/A retStatus = 0;
0N/A }
0N/A }
0N/A
0N/A /* Release the LUT */
6344N/A for (i=0; i < lut_nbands; i++) {
6344N/A (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
6344N/A (jbyte *) jtable[i].table, JNI_ABORT);
0N/A }
0N/A free ((void *) jtable);
0N/A free ((void *) tbl);
0N/A
0N/A /* Release the pinned memory */
0N/A freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
0N/A
0N/A awt_freeParsedImage(srcImageP, TRUE);
0N/A awt_freeParsedImage(dstImageP, TRUE);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600, 1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
0N/A jobject this,
0N/A jobject jsrc,
0N/A jobject jdst,
0N/A jobjectArray jtableArrays)
0N/A{
0N/A RasterS_t* srcRasterP;
0N/A RasterS_t* dstRasterP;
0N/A mlib_image* src;
0N/A mlib_image* dst;
0N/A void* sdata;
0N/A void* ddata;
6344N/A LookupArrayInfo jtable[4];
6344N/A unsigned char* mlib_lookupTable[4];
0N/A int i;
0N/A int retStatus = 1;
0N/A mlib_status status;
0N/A int jlen;
0N/A int lut_nbands;
0N/A int src_nbands;
0N/A int dst_nbands;
0N/A unsigned char ilut[256];
0N/A
0N/A /* This function requires a lot of local refs ??? Is 64 enough ??? */
0N/A if ((*env)->EnsureLocalCapacity(env, 64) < 0)
0N/A return 0;
0N/A
0N/A if (s_nomlib) return 0;
0N/A if (s_timeIt) (*start_timer)(3600);
0N/A
0N/A if ((srcRasterP = (RasterS_t*) calloc(1, sizeof(RasterS_t))) == NULL) {
0N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
0N/A return -1;
0N/A }
0N/A
0N/A if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
0N/A JNU_ThrowOutOfMemoryError(env, "Out of memory");
0N/A free(srcRasterP);
0N/A return -1;
0N/A }
0N/A
0N/A /* Parse the source raster - reject custom images */
0N/A if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
1883N/A free(srcRasterP);
1883N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A /* Parse the destination image - reject custom images */
0N/A if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
1883N/A free(dstRasterP);
0N/A return 0;
0N/A }
0N/A
0N/A jlen = (*env)->GetArrayLength(env, jtableArrays);
0N/A
0N/A lut_nbands = jlen;
0N/A src_nbands = srcRasterP->numBands;
0N/A dst_nbands = dstRasterP->numBands;
0N/A
6344N/A /* adjust number of lookup bands */
6344N/A if (lut_nbands > src_nbands) {
6344N/A lut_nbands = src_nbands;
6344N/A }
6344N/A
0N/A /* MediaLib can't do more than 4 bands */
0N/A if (src_nbands <= 0 || src_nbands > 4 ||
0N/A dst_nbands <= 0 || dst_nbands > 4 ||
0N/A lut_nbands <= 0 || lut_nbands > 4 ||
0N/A src_nbands != dst_nbands ||
0N/A ((lut_nbands != 1) && (lut_nbands != src_nbands)))
0N/A {
0N/A // we should free parsed rasters here
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A /* Allocate the raster arrays */
0N/A if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
0N/A /* Must be some problem */
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
0N/A /* Must be some problem */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A /*
0N/A * Well, until now we have analyzed number of bands in
0N/A * src and dst rasters.
0N/A * However, it is not enough because medialib lookup routine uses
0N/A * number of channels of medialib image. Note that in certain
0N/A * case number of channels may differs form the number of bands.
0N/A * Good example is raster that is used in TYPE_INT_RGB buffered
0N/A * image: it has 3 bands, but their medialib representation has
0N/A * 4 channels.
0N/A *
0N/A * In order to avoid the lookup routine failure, we need:
0N/A *
0N/A * 1. verify that src and dst have same number of channels.
0N/A * 2. provide lookup array for every channel. If we have "extra"
0N/A * channel (like the raster described above) then we need to
0N/A * provide identical lookup array.
0N/A */
0N/A if (src->channels != dst->channels) {
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A
0N/A if (src_nbands < src->channels) {
0N/A for (i = 0; i < 256; i++) {
0N/A ilut[i] = i;
0N/A }
0N/A }
0N/A
0N/A
0N/A /* Get references to the lookup table arrays */
0N/A /* Need to grab these pointers before we lock down arrays */
0N/A for (i=0; i < lut_nbands; i++) {
6344N/A jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
6344N/A jtable[i].table = NULL;
6344N/A if (jtable[i].jArray != NULL) {
6344N/A jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
6344N/A if (jtable[i].length < 256) {
6344N/A /* we may read outside the table during lookup */
6344N/A jtable[i].jArray = NULL;
6344N/A }
6344N/A }
6344N/A
6344N/A if (jtable[i].jArray == NULL)
6344N/A {
6344N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
6344N/A dstRasterP->jdata, dst, ddata);
6344N/A
6344N/A awt_freeParsedRaster(srcRasterP, TRUE);
6344N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A for (i=0; i < lut_nbands; i++) {
6344N/A jtable[i].table = (unsigned char *)
6344N/A (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
6344N/A if (jtable[i].table == NULL) {
0N/A /* Free what we've got so far. */
0N/A int j;
0N/A for (j = 0; j < i; j++) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env,
6344N/A jtable[j].jArray,
6344N/A (jbyte *) jtable[j].table,
0N/A JNI_ABORT);
0N/A }
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A return 0;
0N/A }
6344N/A mlib_lookupTable[i] = jtable[i].table;
0N/A }
0N/A
0N/A /*
0N/A * Medialib routine expects lookup array for each band of raster.
0N/A * Setup the rest of lookup arrays if supplied lookup table
0N/A * contains single lookup array.
0N/A */
0N/A for (i = lut_nbands; i < src_nbands; i++) {
6344N/A mlib_lookupTable[i] = jtable[0].table;
0N/A }
0N/A
0N/A /*
0N/A * Setup lookup array for "extra" channels
0N/A */
0N/A for ( ; i < src->channels; i++) {
6344N/A mlib_lookupTable[i] = ilut;
0N/A }
0N/A
0N/A /* Mlib needs 16bit lookuptable and must be signed! */
0N/A if (src->type == MLIB_SHORT) {
0N/A if (dst->type == MLIB_BYTE) {
0N/A if (lut_nbands > 1) {
0N/A retStatus = 0;
0N/A } else {
6344N/A retStatus = lookupShortData(src, dst, &jtable[0]);
0N/A }
0N/A }
0N/A /* How about ddata == null? */
0N/A } else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
6344N/A (void **)mlib_lookupTable) != MLIB_SUCCESS)) {
0N/A printMedialibError(status);
0N/A retStatus = 0;
0N/A }
0N/A
0N/A /*
0N/A * Means that we couldn't write directly into
0N/A * the destination buffer
0N/A */
0N/A if (ddata == NULL) {
0N/A unsigned char* bdataP;
0N/A unsigned short* sdataP;
0N/A
0N/A switch (dstRasterP->dataType) {
0N/A case BYTE_DATA_TYPE:
0N/A bdataP = (unsigned char *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ;
0N/A break;
0N/A case SHORT_DATA_TYPE:
0N/A sdataP = (unsigned short *) mlib_ImageGetData(dst);
0N/A retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ;
0N/A break;
0N/A default:
0N/A retStatus = 0;
0N/A }
0N/A }
0N/A
0N/A /* Release the LUT */
0N/A for (i=0; i < lut_nbands; i++) {
6344N/A (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
6344N/A (jbyte *) jtable[i].table, JNI_ABORT);
0N/A }
0N/A
0N/A /* Release the pinned memory */
0N/A freeDataArray(env, srcRasterP->jdata, src, sdata,
0N/A dstRasterP->jdata, dst, ddata);
0N/A
0N/A awt_freeParsedRaster(srcRasterP, TRUE);
0N/A awt_freeParsedRaster(dstRasterP, TRUE);
0N/A
0N/A if (s_timeIt) (*stop_timer)(3600, 1);
0N/A
0N/A return retStatus;
0N/A}
0N/A
0N/A
0N/AJNIEXPORT jboolean JNICALL
0N/AJava_sun_awt_image_ImagingLib_init(JNIEnv *env, jclass thisClass) {
0N/A char *start;
0N/A if (getenv("IMLIB_DEBUG")) {
0N/A start_timer = awt_setMlibStartTimer();
0N/A stop_timer = awt_setMlibStopTimer();
0N/A if (start_timer && stop_timer) {
0N/A s_timeIt = 1;
0N/A }
0N/A }
0N/A
0N/A if (getenv("IMLIB_PRINT")) {
0N/A s_printIt = 1;
0N/A }
0N/A if ((start = getenv("IMLIB_START")) != NULL) {
0N/A sscanf(start, "%d", &s_startOff);
0N/A }
0N/A
0N/A if (getenv ("IMLIB_NOMLIB")) {
0N/A s_nomlib = 1;
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A /* This function is platform-dependent and is in awt_mlib.c */
0N/A if (awt_getImagingLib(env, (mlibFnS_t *)&sMlibFns, &sMlibSysFns) !=
0N/A MLIB_SUCCESS)
0N/A {
0N/A s_nomlib = 1;
0N/A return JNI_FALSE;
0N/A }
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/* REMIND: How to specify border? */
0N/Astatic void extendEdge(JNIEnv *env, BufImageS_t *imageP,
0N/A int *widthP, int *heightP) {
0N/A RasterS_t *rasterP = &imageP->raster;
0N/A int width;
0N/A int height;
0N/A /* Useful for convolution? */
0N/A
0N/A jobject jbaseraster = (*env)->GetObjectField(env, rasterP->jraster,
0N/A g_RasterBaseRasterID);
0N/A width = rasterP->width;
0N/A height = rasterP->height;
0N/A#ifdef WORKING
0N/A if (! JNU_IsNull(env, jbaseraster) &&
0N/A !(*env)->IsSameObject(env, rasterP->jraster, jbaseraster)) {
0N/A int xOff;
0N/A int yOff;
0N/A int baseWidth;
0N/A int baseHeight;
0N/A int baseXoff;
0N/A int baseYoff;
0N/A /* Not the same object so get the width and height */
0N/A xOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterXOffsetID);
0N/A yOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterYOffsetID);
0N/A baseWidth = (*env)->GetIntField(env, jbaseraster, g_RasterWidthID);
0N/A baseHeight = (*env)->GetIntField(env, jbaseraster, g_RasterHeightID);
0N/A baseXoff = (*env)->GetIntField(env, jbaseraster, g_RasterXOffsetID);
0N/A baseYoff = (*env)->GetIntField(env, jbaseraster, g_RasterYOffsetID);
0N/A
0N/A if (xOff + rasterP->width < baseXoff + baseWidth) {
0N/A /* Can use edge */
0N/A width++;
0N/A }
0N/A if (yOff + rasterP->height < baseYoff + baseHeight) {
0N/A /* Can use edge */
0N/A height++;
0N/A }
0N/A
0N/A }
0N/A#endif
0N/A
0N/A}
0N/A
0N/Astatic int
0N/AsetImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A int expandICM, int useAlpha,
0N/A int premultiply, mlibHintS_t *hintP)
0N/A{
0N/A ColorModelS_t *srcCMP = &srcP->cmodel;
0N/A ColorModelS_t *dstCMP = &dstP->cmodel;
0N/A int nbands = 0;
0N/A int ncomponents;
0N/A
0N/A hintP->dataType = srcP->raster.dataType;
0N/A hintP->addAlpha = FALSE;
0N/A
0N/A /* Are the color spaces the same? */
0N/A if (srcCMP->csType != dstCMP->csType) {
0N/A /* If the src is GRAY and dst RGB, we can handle it */
0N/A if (!(srcCMP->csType == java_awt_color_ColorSpace_TYPE_GRAY &&
0N/A dstCMP->csType == java_awt_color_ColorSpace_TYPE_RGB)) {
0N/A /* Nope, need to handle that in java for now */
0N/A return -1;
0N/A }
0N/A else {
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A }
0N/A }
0N/A else {
0N/A if (srcP->hints.needToExpand) {
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A }
0N/A else {
0N/A /* Need to initialize this */
0N/A hintP->cvtSrcToDefault = FALSE;
0N/A }
0N/A }
0N/A
0N/A ncomponents = srcCMP->numComponents;
0N/A if ((useAlpha == 0) && srcCMP->supportsAlpha) {
0N/A ncomponents--; /* ?? */
0N/A /* Not really, more like shrink src to get rid of alpha */
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A }
0N/A
0N/A hintP->dataType = srcP->raster.dataType;
0N/A if (hintP->cvtSrcToDefault == FALSE) {
0N/A if (srcCMP->cmType == INDEX_CM_TYPE) {
0N/A if (expandICM) {
0N/A nbands = srcCMP->numComponents;
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A
0N/A if (dstCMP->isDefaultCompatCM) {
0N/A hintP->allocDefaultDst = FALSE;
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A else if (dstCMP->isDefaultCompatCM) {
0N/A hintP->allocDefaultDst = FALSE;
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A }
0N/A else {
0N/A nbands = 1;
0N/A hintP->cvtSrcToDefault = FALSE;
0N/A }
0N/A
0N/A }
0N/A else {
0N/A if (srcP->hints.packing & INTERLEAVED) {
0N/A nbands = srcCMP->numComponents;
0N/A }
0N/A else {
0N/A nbands = 1;
0N/A }
0N/A
0N/A /* Look at the packing */
0N/A if ((srcP->hints.packing&BYTE_INTERLEAVED)==BYTE_INTERLEAVED ||
0N/A (srcP->hints.packing&SHORT_INTERLEAVED)==SHORT_INTERLEAVED||
0N/A (srcP->hints.packing&BYTE_SINGLE_BAND) == BYTE_SINGLE_BAND||
0N/A (srcP->hints.packing&SHORT_SINGLE_BAND)==SHORT_SINGLE_BAND||
0N/A (srcP->hints.packing&BYTE_BANDED) == BYTE_BANDED ||
0N/A (srcP->hints.packing&SHORT_BANDED) == SHORT_BANDED) {
0N/A /* Can use src directly */
0N/A hintP->cvtSrcToDefault = FALSE;
0N/A }
0N/A else {
0N/A /* Must be packed or custom */
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A }
0N/A }
0N/A }
0N/A if (hintP->cvtSrcToDefault) {
0N/A /* By definition */
0N/A nbands = 4; /* What about alpha? */
0N/A hintP->dataType = BYTE_DATA_TYPE;
0N/A hintP->needToCopy = TRUE;
0N/A
0N/A if (srcP->imageType == dstP->imageType) {
0N/A hintP->cvtToDst = TRUE;
0N/A }
0N/A else if (dstP->cmodel.isDefaultCM) {
0N/A /* Not necessarily */
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A else {
0N/A hintP->cvtToDst = TRUE;
0N/A }
0N/A }
0N/A else {
0N/A int srcImageType = srcP->imageType;
0N/A int dstImageType = dstP->imageType;
0N/A /* Special case where we need to fill in alpha values */
0N/A if (srcCMP->isDefaultCompatCM && dstCMP->isDefaultCompatCM) {
0N/A int i;
0N/A if (!srcCMP->supportsAlpha &&dstCMP->supportsAlpha) {
0N/A hintP->addAlpha = TRUE;
0N/A }
0N/A for (i=0; i < srcCMP->numComponents; i++) {
0N/A if (srcP->hints.colorOrder[i] != dstP->hints.colorOrder[i]){
0N/A if (!srcCMP->isDefaultCM) {
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
0N/A }
0N/A if (!dstCMP->isDefaultCM) {
0N/A hintP->cvtToDst = TRUE;
0N/A dstImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
0N/A }
0N/A
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A else if (srcCMP->cmType != INDEX_CM_TYPE &&
0N/A !srcCMP->supportsAlpha && dstCMP->supportsAlpha)
0N/A {
0N/A /* We've already handled the index case. This is for the rest of the cases */
0N/A srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
0N/A hintP->cvtSrcToDefault = TRUE;
0N/A }
0N/A
0N/A hintP->allocDefaultDst = FALSE;
0N/A if (srcImageType == dstImageType) {
0N/A /* Same image type so use it */
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A else if (srcImageType == TYPE_INT_RGB &&
0N/A (dstImageType == TYPE_INT_ARGB ||
0N/A dstImageType == TYPE_INT_ARGB_PRE)) {
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A else if (srcImageType == TYPE_INT_BGR &&
0N/A (dstImageType == TYPE_4BYTE_ABGR ||
0N/A dstImageType == TYPE_4BYTE_ABGR_PRE)) {
0N/A hintP->cvtToDst = FALSE;
0N/A }
0N/A else if (srcP->hints.packing == dstP->hints.packing) {
0N/A /* Now what? */
0N/A
0N/A /* Check color order */
0N/A
0N/A /* Check if just need to scale the data */
0N/A
0N/A hintP->cvtToDst = TRUE;
0N/A }
0N/A else {
0N/A /* Don't know what it is so convert it */
0N/A hintP->allocDefaultDst = TRUE;
0N/A hintP->cvtToDst = TRUE;
0N/A }
0N/A hintP->needToCopy = (ncomponents > nbands);
0N/A }
0N/A
0N/A return nbands;
0N/A}
0N/A
0N/A
0N/Astatic int
0N/AexpandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP,
0N/A RasterS_t *rasterP, int component, unsigned char *bdataP) {
0N/A
0N/A if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
0N/A switch (rasterP->dataType) {
0N/A case BYTE_DATA_TYPE:
0N/A if (expandPackedBCR(env, rasterP, component, bdataP) < 0) {
0N/A /* Must have been an error */
0N/A return -1;
0N/A }
0N/A break;
0N/A
0N/A case SHORT_DATA_TYPE:
0N/A if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
0N/A /* Must have been an error */
0N/A return -1;
0N/A }
0N/A break;
0N/A
0N/A case INT_DATA_TYPE:
0N/A if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
0N/A /* Must have been an error */
0N/A return -1;
0N/A }
0N/A break;
0N/A
0N/A default:
0N/A /* REMIND: Return some sort of error */
0N/A return -1;
0N/A }
0N/A }
0N/A else {
0N/A /* REMIND: Return some sort of error */
0N/A return -1;
0N/A }
0N/A
0N/A return 0;
0N/A}
0N/A
0N/Astatic int
0N/AcvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component,
0N/A unsigned char *dataP) {
0N/A ColorModelS_t *cmP = &imageP->cmodel;
0N/A RasterS_t *rasterP = &imageP->raster;
0N/A int y;
0N/A jobject jpixels = NULL;
0N/A jint *pixels;
0N/A unsigned char *dP = dataP;
0N/A#define NUM_LINES 10
0N/A int numLines = NUM_LINES;
5817N/A /* it is safe to calculate the scan length, because width has been verified
5817N/A * on creation of the mlib image
5817N/A */
5817N/A int scanLength = rasterP->width * 4;
5817N/A
5817N/A int nbytes = 0;
5817N/A if (!SAFE_TO_MULT(numLines, scanLength)) {
5817N/A return -1;
5817N/A }
5817N/A
5817N/A nbytes = numLines * scanLength;
0N/A
0N/A for (y=0; y < rasterP->height; y+=numLines) {
0N/A /* getData, one scanline at a time */
0N/A if (y+numLines > rasterP->height) {
0N/A numLines = rasterP->height - y;
5817N/A nbytes = numLines * scanLength;
0N/A }
0N/A jpixels = (*env)->CallObjectMethod(env, imageP->jimage,
0N/A g_BImgGetRGBMID, 0, y,
0N/A rasterP->width, numLines,
0N/A jpixels,0, rasterP->width);
0N/A if (jpixels == NULL) {
0N/A JNU_ThrowInternalError(env, "Can't retrieve pixels.");
0N/A return -1;
0N/A }
0N/A
0N/A pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
0N/A memcpy(dP, pixels, nbytes);
0N/A dP += nbytes;
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels,
0N/A JNI_ABORT);
0N/A }
0N/A return 0;
0N/A}
0N/A
0N/Astatic int
0N/AcvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component,
0N/A unsigned char *dataP) {
0N/A ColorModelS_t *cmP = &imageP->cmodel;
0N/A RasterS_t *rasterP = &imageP->raster;
0N/A int y;
0N/A jint *pixels;
0N/A unsigned char *dP = dataP;
0N/A#define NUM_LINES 10
0N/A int numLines = NUM_LINES;
0N/A int nbytes = rasterP->width*4*NUM_LINES;
0N/A jintArray jpixels;
0N/A
0N/A jpixels = (*env)->NewIntArray(env, nbytes);
0N/A if (JNU_IsNull(env, jpixels)) {
0N/A JNU_ThrowOutOfMemoryError(env, "Out of Memory");
0N/A return -1;
0N/A }
0N/A
0N/A for (y=0; y < rasterP->height; y+=NUM_LINES) {
0N/A if (y+numLines > rasterP->height) {
0N/A numLines = rasterP->height - y;
0N/A nbytes = rasterP->width*4*numLines;
0N/A }
0N/A pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
0N/A if (pixels == NULL) {
0N/A /* JNI error */
0N/A return -1;
0N/A }
0N/A
0N/A memcpy(pixels, dP, nbytes);
0N/A dP += nbytes;
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, 0);
0N/A
0N/A /* setData, one scanline at a time */
0N/A /* Fix 4223648, 4184283 */
0N/A (*env)->CallVoidMethod(env, imageP->jimage, g_BImgSetRGBMID, 0, y,
0N/A rasterP->width, numLines, jpixels, 0,
0N/A rasterP->width);
0N/A if ((*env)->ExceptionOccurred(env)) {
0N/A return -1;
0N/A }
0N/A }
0N/A
0N/A /* Need to release the array */
0N/A (*env)->DeleteLocalRef(env, jpixels);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/Astatic int
0N/AallocateArray(JNIEnv *env, BufImageS_t *imageP,
0N/A mlib_image **mlibImagePP, void **dataPP, int isSrc,
0N/A int cvtToDefault, int addAlpha) {
0N/A void *dataP;
0N/A unsigned char *cDataP;
0N/A RasterS_t *rasterP = &imageP->raster;
0N/A ColorModelS_t *cmP = &imageP->cmodel;
0N/A int dataType = BYTE_DATA_TYPE;
0N/A int width;
0N/A int height;
0N/A HintS_t *hintP = &imageP->hints;
0N/A *dataPP = NULL;
0N/A
0N/A width = rasterP->width;
0N/A height = rasterP->height;
0N/A
0N/A /* Useful for convolution? */
0N/A /* This code is zero'ed out so that it cannot be called */
0N/A
0N/A /* To do this correctly, we need to expand src and dst in the */
0N/A /* same direction up/down/left/right only if both can be expanded */
0N/A /* in that direction. Expanding right and down is easy - */
0N/A /* increment width. Expanding top and left requires bumping */
0N/A /* around pointers and incrementing the width/height */
0N/A
0N/A#if 0
0N/A if (0 && useEdges) {
0N/A baseWidth = rasterP->baseRasterWidth;
0N/A baseHeight = rasterP->baseRasterHeight;
0N/A baseXoff = rasterP->baseOriginX;
0N/A baseYoff = rasterP->baseOriginY;
0N/A
0N/A if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
0N/A /* Can use edge */
0N/A width++;
0N/A }
0N/A if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
0N/A /* Can use edge */
0N/A height++;
0N/A }
0N/A
0N/A if (rasterP->minX > baseXoff ) {
0N/A /* Can use edge */
0N/A width++;
0N/A /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
0N/A }
0N/A if (rasterP->minY > baseYoff) {
0N/A /* Can use edge */
0N/A height++;
0N/A /* NEED TO BUMP POINTER BACK A SCANLINE */
0N/A }
0N/A
0N/A
0N/A }
0N/A#endif
0N/A if (cvtToDefault) {
0N/A int status = 0;
0N/A *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
5817N/A if (*mlibImagePP == NULL) {
5817N/A return -1;
5817N/A }
0N/A cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
5817N/A /* Make sure the image is cleared.
5817N/A * NB: the image dimension is already verified, so we can
5817N/A * safely calculate the length of the buffer.
5817N/A */
0N/A memset(cDataP, 0, width*height*4);
0N/A
0N/A if (!isSrc) {
0N/A return 0;
0N/A }
0N/A
0N/A switch(imageP->cmodel.cmType) {
0N/A case INDEX_CM_TYPE:
0N/A /* REMIND: Need to rearrange according to dst cm */
0N/A /* Fix 4213160, 4184283 */
0N/A if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
0N/A return expandICM(env, imageP, (unsigned int *)cDataP);
0N/A }
0N/A else {
0N/A return cvtCustomToDefault(env, imageP, -1, cDataP);
0N/A }
0N/A
0N/A case DIRECT_CM_TYPE:
0N/A switch(imageP->raster.dataType) {
0N/A case BYTE_DATA_TYPE:
0N/A return expandPackedBCRdefault(env, rasterP, -1, cDataP,
0N/A !imageP->cmodel.supportsAlpha);
0N/A case SHORT_DATA_TYPE:
0N/A return expandPackedSCRdefault(env, rasterP, -1, cDataP,
0N/A !imageP->cmodel.supportsAlpha);
0N/A case INT_DATA_TYPE:
0N/A return expandPackedICRdefault(env, rasterP, -1, cDataP,
0N/A !imageP->cmodel.supportsAlpha);
0N/A }
0N/A } /* switch(imageP->cmodel.cmType) */
0N/A
0N/A return cvtCustomToDefault(env, imageP, -1, cDataP);
0N/A }
0N/A
0N/A /* Interleaved with shared data */
0N/A dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
0N/A NULL);
0N/A if (dataP == NULL) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Means we need to fill in alpha */
0N/A if (!cvtToDefault && addAlpha) {
0N/A *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
0N/A if (*mlibImagePP != NULL) {
0N/A unsigned int *dstP = (unsigned int *)
0N/A mlib_ImageGetData(*mlibImagePP);
0N/A int dstride = (*mlibImagePP)->stride>>2;
0N/A int sstride = hintP->sStride>>2;
0N/A unsigned int *srcP = (unsigned int *)
0N/A ((unsigned char *)dataP + hintP->dataOffset);
0N/A unsigned int *dP, *sP;
0N/A int x, y;
0N/A for (y=0; y < height; y++, srcP += sstride, dstP += dstride){
0N/A sP = srcP;
0N/A dP = dstP;
0N/A for (x=0; x < width; x++) {
0N/A dP[x] = sP[x] | 0xff000000;
0N/A }
0N/A }
0N/A }
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A return 0;
0N/A }
0N/A else if ((hintP->packing & BYTE_INTERLEAVED) == BYTE_INTERLEAVED) {
0N/A int nChans = (cmP->isDefaultCompatCM ? 4 : hintP->numChans);
0N/A /* Easy case. It is or is similar to the default CM so use
0N/A * the array. Must be byte data.
0N/A */
0N/A /* Create the medialib image */
0N/A *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE,
0N/A nChans,
0N/A width,
0N/A height,
0N/A hintP->sStride,
0N/A (unsigned char *)dataP
0N/A + hintP->dataOffset);
0N/A }
0N/A else if ((hintP->packing & SHORT_INTERLEAVED) == SHORT_INTERLEAVED) {
0N/A *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
0N/A hintP->numChans,
0N/A width,
0N/A height,
0N/A imageP->raster.scanlineStride*2,
0N/A (unsigned short *)dataP
0N/A + hintP->channelOffset);
0N/A }
0N/A else {
0N/A /* Release the data array */
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A return -1;
0N/A }
0N/A
0N/A *dataPP = dataP;
0N/A return 0;
0N/A}
0N/A
0N/Astatic int
0N/AallocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
0N/A mlib_image **mlibImagePP, void **dataPP, int isSrc) {
0N/A void *dataP;
0N/A unsigned char *cDataP;
0N/A unsigned short *sdataP;
0N/A int dataType = BYTE_DATA_TYPE;
0N/A int width;
0N/A int height;
2266N/A int dataSize;
2266N/A int offset;
0N/A
0N/A *dataPP = NULL;
0N/A
0N/A width = rasterP->width;
0N/A height = rasterP->height;
0N/A
0N/A if (rasterP->numBands <= 0 || rasterP->numBands > 4) {
0N/A /* REMIND: Fix this */
0N/A return -1;
0N/A }
0N/A
0N/A /* Useful for convolution? */
0N/A /* This code is zero'ed out so that it cannot be called */
0N/A
0N/A /* To do this correctly, we need to expand src and dst in the */
0N/A /* same direction up/down/left/right only if both can be expanded */
0N/A /* in that direction. Expanding right and down is easy - */
0N/A /* increment width. Expanding top and left requires bumping */
0N/A /* around pointers and incrementing the width/height */
0N/A
0N/A#if 0
0N/A if (0 && useEdges) {
0N/A baseWidth = rasterP->baseRasterWidth;
0N/A baseHeight = rasterP->baseRasterHeight;
0N/A baseXoff = rasterP->baseOriginX;
0N/A baseYoff = rasterP->baseOriginY;
0N/A
0N/A if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
0N/A /* Can use edge */
0N/A width++;
0N/A }
0N/A if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
0N/A /* Can use edge */
0N/A height++;
0N/A }
0N/A
0N/A if (rasterP->minX > baseXoff ) {
0N/A /* Can use edge */
0N/A width++;
0N/A /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
0N/A }
0N/A if (rasterP->minY > baseYoff) {
0N/A /* Can use edge */
0N/A height++;
0N/A /* NEED TO BUMP POINTER BACK A SCANLINE */
0N/A }
0N/A
0N/A
0N/A }
0N/A#endif
0N/A switch (rasterP->type) {
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_INT_8BIT_SAMPLES:
2266N/A if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 4)) &&
2266N/A SAFE_TO_ALLOC_2(width, 4) &&
2266N/A SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 4)))
2266N/A {
2266N/A return -1;
2266N/A }
2266N/A offset = 4 * rasterP->chanOffsets[0];
2266N/A dataSize = 4 * (*env)->GetArrayLength(env, rasterP->jdata);
2266N/A
2266N/A if (offset < 0 || offset >= dataSize ||
2266N/A width > rasterP->scanlineStride ||
2266N/A height * rasterP->scanlineStride * 4 > dataSize - offset)
2266N/A {
2266N/A // raster data buffer is too short
2266N/A return -1;
2266N/A }
0N/A dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
0N/A NULL);
0N/A if (dataP == NULL) {
0N/A return -1;
0N/A }
0N/A *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, 4,
0N/A width, height,
0N/A rasterP->scanlineStride*4,
2266N/A (unsigned char *)dataP + offset);
0N/A *dataPP = dataP;
0N/A return 0;
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES:
2266N/A if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands) &&
2266N/A SAFE_TO_ALLOC_2(height, rasterP->scanlineStride)))
2266N/A {
2266N/A return -1;
2266N/A }
2266N/A offset = rasterP->chanOffsets[0];
2266N/A dataSize = (*env)->GetArrayLength(env, rasterP->jdata);
2266N/A
2266N/A if (offset < 0 || offset >= dataSize ||
2266N/A width * rasterP->numBands > rasterP->scanlineStride ||
2266N/A height * rasterP->scanlineStride > dataSize - offset)
2266N/A {
2266N/A // raster data buffer is too short
2266N/A return -1;
2266N/A }
0N/A dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
0N/A NULL);
0N/A if (dataP == NULL) {
0N/A return -1;
0N/A }
0N/A *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, rasterP->numBands,
0N/A width, height,
0N/A rasterP->scanlineStride,
2266N/A (unsigned char *)dataP + offset);
0N/A *dataPP = dataP;
0N/A return 0;
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_SAMPLES:
2266N/A if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 2)) &&
2266N/A SAFE_TO_ALLOC_3(width, rasterP->numBands, 2) &&
2266N/A SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 2)))
2266N/A {
2266N/A return -1;
2266N/A }
2266N/A offset = rasterP->chanOffsets[0] * 2;
2266N/A dataSize = 2 * (*env)->GetArrayLength(env, rasterP->jdata);
2266N/A
2266N/A if (offset < 0 || offset >= dataSize ||
2266N/A width * rasterP->numBands > rasterP->scanlineStride ||
2266N/A height * rasterP->scanlineStride * 2 > dataSize - offset)
2266N/A {
2266N/A // raster data buffer is too short
2266N/A return -1;
2266N/A }
0N/A dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
0N/A NULL);
0N/A if (dataP == NULL) {
0N/A return -1;
0N/A }
0N/A *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
0N/A rasterP->numBands,
0N/A width, height,
0N/A rasterP->scanlineStride*2,
2266N/A (unsigned char *)dataP + offset);
0N/A *dataPP = dataP;
0N/A return 0;
0N/A
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
0N/A *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
0N/A width, height);
5817N/A if (*mlibImagePP == NULL) {
5817N/A return -1;
5817N/A }
0N/A if (!isSrc) return 0;
0N/A cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
0N/A return expandPackedBCR(env, rasterP, -1, cDataP);
0N/A
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
0N/A if (rasterP->sppsm.maxBitSize <= 8) {
0N/A *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
0N/A width, height);
5817N/A if (*mlibImagePP == NULL) {
5817N/A return -1;
5817N/A }
0N/A if (!isSrc) return 0;
0N/A cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
0N/A return expandPackedSCR(env, rasterP, -1, cDataP);
0N/A }
0N/A break;
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
0N/A if (rasterP->sppsm.maxBitSize <= 8) {
0N/A *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
0N/A width, height);
5817N/A if (*mlibImagePP == NULL) {
5817N/A return -1;
5817N/A }
0N/A if (!isSrc) return 0;
0N/A cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
0N/A return expandPackedICR(env, rasterP, -1, cDataP);
0N/A }
0N/A break;
0N/A }
0N/A
0N/A /* Just expand it right now */
0N/A switch (rasterP->dataType) {
0N/A case BYTE_DATA_TYPE:
0N/A if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
0N/A width, height)) == NULL) {
0N/A return -1;
0N/A }
0N/A if (isSrc) {
0N/A cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
0N/A if (awt_getPixelByte(env, -1, rasterP, cDataP) < 0) {
0N/A (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
0N/A return -1;
0N/A }
0N/A }
0N/A break;
0N/A
0N/A case SHORT_DATA_TYPE:
0N/A if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_SHORT,
0N/A rasterP->numBands,
0N/A width, height)) == NULL) {
0N/A return -1;
0N/A }
0N/A if (isSrc) {
0N/A sdataP = (unsigned short *) mlib_ImageGetData(*mlibImagePP);
0N/A if (awt_getPixelShort(env, -1, rasterP, sdataP) < 0) {
0N/A (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
0N/A return -1;
0N/A }
0N/A }
0N/A break;
0N/A
0N/A default:
0N/A return -1;
0N/A }
0N/A return 0;
0N/A}
0N/A
0N/Astatic void
0N/AfreeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
0N/A void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
0N/A void *dstdataP) {
0N/A jobject srcJdata = (srcimageP != NULL ? srcimageP->raster.jdata : NULL);
0N/A jobject dstJdata = (dstimageP != NULL ? dstimageP->raster.jdata : NULL);
0N/A freeDataArray(env, srcJdata, srcmlibImP, srcdataP,
0N/A dstJdata, dstmlibImP, dstdataP);
0N/A}
0N/Astatic void
0N/AfreeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
0N/A void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
0N/A void *dstdataP)
0N/A{
0N/A /* Free the medialib image */
0N/A if (srcmlibImP) {
0N/A (*sMlibSysFns.deleteImageFP)(srcmlibImP);
0N/A }
0N/A
0N/A /* Release the array */
0N/A if (srcdataP) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, srcJdata,
0N/A srcdataP, JNI_ABORT);
0N/A }
0N/A
0N/A /* Free the medialib image */
0N/A if (dstmlibImP) {
0N/A (*sMlibSysFns.deleteImageFP)(dstmlibImP);
0N/A }
0N/A
0N/A /* Release the array */
0N/A if (dstdataP) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, dstJdata,
0N/A dstdataP, 0);
0N/A }
0N/A}
0N/A
0N/Astatic int
0N/AstoreDstArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A mlibHintS_t *hintP, mlib_image *mlibImP, void *ddata) {
0N/A RasterS_t *rasterP = &dstP->raster;
0N/A
0N/A /* Nothing to do since it is the same image type */
0N/A if (srcP->imageType == dstP->imageType
0N/A && srcP->imageType != java_awt_image_BufferedImage_TYPE_CUSTOM
0N/A && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_INDEXED
0N/A && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_BINARY) {
0N/A /* REMIND: Should check the ICM LUTS to see if it is the same */
0N/A return 0;
0N/A }
0N/A
0N/A /* These types are compatible with TYPE_INT_RGB */
0N/A if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB
0N/A && (dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
0N/A dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)){
0N/A return 0;
0N/A }
0N/A
0N/A if (hintP->cvtSrcToDefault &&
0N/A (srcP->cmodel.isAlphaPre == dstP->cmodel.isAlphaPre)) {
0N/A if (srcP->cmodel.isAlphaPre) {
0N/A if (dstP->imageType ==
0N/A java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
0N/A {
0N/A return 0;
0N/A }
0N/A if (!srcP->cmodel.supportsAlpha &&
0N/A dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB){
0N/A return 0;
0N/A }
0N/A }
0N/A else {
0N/A /* REMIND: */
0N/A }
0N/A }
0N/A
0N/A if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
0N/A /* Just need to move bits */
0N/A if (mlibImP->type == MLIB_BYTE) {
0N/A return awt_setPixelByte(env, -1, &dstP->raster,
0N/A (unsigned char *) mlibImP->data);
0N/A }
0N/A else if (mlibImP->type == MLIB_SHORT) {
0N/A return awt_setPixelByte(env, -1, &dstP->raster,
0N/A (unsigned char *) mlibImP->data);
0N/A }
0N/A }
0N/A
0N/A return 0;
0N/A}
0N/A
6378N/A#define ERR_BAD_IMAGE_LAYOUT (-2)
6378N/A
6378N/A#define CHECK_DST_ARRAY(start_offset, elements_per_pixel) \
6378N/A do { \
6378N/A int offset = (start_offset); \
6378N/A int lastScanOffset; \
6378N/A \
6378N/A if (!SAFE_TO_MULT(rasterP->scanlineStride, \
6378N/A (rasterP->height - 1))) \
6378N/A { \
6378N/A return ERR_BAD_IMAGE_LAYOUT; \
6378N/A } \
6378N/A lastScanOffset = rasterP->scanlineStride * \
6378N/A (rasterP->height - 1); \
6378N/A \
6378N/A if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
6378N/A return ERR_BAD_IMAGE_LAYOUT; \
6378N/A } \
6378N/A lastScanOffset += offset; \
6378N/A \
6378N/A if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) { \
6378N/A return ERR_BAD_IMAGE_LAYOUT; \
6378N/A } \
6378N/A offset = (elements_per_pixel) * rasterP->width; \
6378N/A \
6378N/A if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
6378N/A return ERR_BAD_IMAGE_LAYOUT; \
6378N/A } \
6378N/A lastScanOffset += offset; \
6378N/A \
6378N/A if (dataArrayLength < lastScanOffset) { \
6378N/A return ERR_BAD_IMAGE_LAYOUT; \
6378N/A } \
6378N/A } while(0); \
6378N/A
0N/Astatic int
0N/AstoreImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A mlib_image *mlibImP) {
0N/A int mStride;
0N/A unsigned char *cmDataP, *dataP, *cDataP;
0N/A HintS_t *hintP = &dstP->hints;
0N/A RasterS_t *rasterP = &dstP->raster;
6378N/A jsize dataArrayLength = (*env)->GetArrayLength(env, rasterP->jdata);
0N/A int y;
0N/A
0N/A /* REMIND: Store mlib data type? */
0N/A
0N/A /* Check if it is an IndexColorModel */
0N/A if (dstP->cmodel.cmType == INDEX_CM_TYPE) {
0N/A if (dstP->raster.rasterType == COMPONENT_RASTER_TYPE) {
0N/A return storeICMarray(env, srcP, dstP, mlibImP);
0N/A }
0N/A else {
0N/A /* Packed or some other custom raster */
0N/A cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A return cvtDefaultToCustom(env, dstP, -1, cmDataP);
0N/A }
0N/A }
0N/A
0N/A if (hintP->packing == BYTE_INTERLEAVED) {
0N/A /* Write it back to the destination */
6378N/A CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
0N/A cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A mStride = mlib_ImageGetStride(mlibImP);
0N/A dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env,
0N/A rasterP->jdata, NULL);
0N/A if (dataP == NULL) return 0;
6378N/A cDataP = dataP + hintP->channelOffset;
0N/A for (y=0; y < rasterP->height;
6378N/A y++, cmDataP += mStride, cDataP += rasterP->scanlineStride)
0N/A {
0N/A memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans);
0N/A }
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A }
0N/A else if (hintP->packing == SHORT_INTERLEAVED) {
0N/A /* Write it back to the destination */
0N/A unsigned short *sdataP, *sDataP;
0N/A unsigned short *smDataP = (unsigned short *)mlib_ImageGetData(mlibImP);
6378N/A CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
0N/A mStride = mlib_ImageGetStride(mlibImP);
0N/A sdataP = (unsigned short *)(*env)->GetPrimitiveArrayCritical(env,
0N/A rasterP->jdata, NULL);
0N/A if (sdataP == NULL) return -1;
6378N/A sDataP = sdataP + hintP->channelOffset;
0N/A for (y=0; y < rasterP->height;
6378N/A y++, smDataP += mStride, sDataP += rasterP->scanlineStride)
0N/A {
0N/A memcpy(sDataP, smDataP, rasterP->width*hintP->numChans);
0N/A }
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, sdataP,
0N/A JNI_ABORT);
0N/A }
0N/A else if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
0N/A /* Just need to move bits */
0N/A if (mlibImP->type == MLIB_BYTE) {
0N/A if (dstP->hints.packing == PACKED_BYTE_INTER) {
0N/A return setPackedBCRdefault(env, rasterP, -1,
0N/A (unsigned char *) mlibImP->data,
0N/A dstP->cmodel.supportsAlpha);
0N/A } else if (dstP->hints.packing == PACKED_SHORT_INTER) {
0N/A return setPackedSCRdefault(env, rasterP, -1,
0N/A (unsigned char *) mlibImP->data,
0N/A dstP->cmodel.supportsAlpha);
0N/A } else if (dstP->hints.packing == PACKED_INT_INTER) {
0N/A return setPackedICRdefault(env, rasterP, -1,
0N/A (unsigned char *) mlibImP->data,
0N/A dstP->cmodel.supportsAlpha);
0N/A }
0N/A }
0N/A else if (mlibImP->type == MLIB_SHORT) {
0N/A return awt_setPixelShort(env, -1, rasterP,
0N/A (unsigned short *) mlibImP->data);
0N/A }
0N/A }
0N/A else {
0N/A return cvtDefaultToCustom(env, dstP, -1,
0N/A (unsigned char *)mlibImP->data);
0N/A }
0N/A
0N/A return 0;
0N/A}
0N/A
0N/Astatic int
0N/AstoreRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
0N/A mlib_image *mlibImP) {
0N/A unsigned char *cDataP;
0N/A
0N/A switch(dstP->type) {
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
0N/A cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A return setPackedBCR(env, dstP, -1, cDataP);
0N/A
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
0N/A if (dstP->sppsm.maxBitSize <= 8) {
0N/A cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A return setPackedSCR(env, dstP, -1, cDataP);
0N/A }
0N/A break;
0N/A case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
0N/A if (dstP->sppsm.maxBitSize <= 8) {
0N/A cDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A return setPackedICR(env, dstP, -1, cDataP);
0N/A }
0N/A }
0N/A
0N/A return -1;
0N/A}
0N/A
0N/A
0N/Astatic int
0N/AstoreICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
0N/A mlib_image *mlibImP)
0N/A{
0N/A int *argb;
0N/A int x, y;
0N/A unsigned char *dataP, *cDataP, *cP;
0N/A unsigned char *sP;
0N/A int aIdx, rIdx, gIdx, bIdx;
0N/A ColorModelS_t *cmodelP = &dstP->cmodel;
0N/A RasterS_t *rasterP = &dstP->raster;
0N/A
0N/A /* REMIND: Only works for RGB */
0N/A if (cmodelP->csType != java_awt_color_ColorSpace_TYPE_RGB) {
0N/A JNU_ThrowInternalError(env, "Writing to non-RGB images not implemented yet");
0N/A return -1;
0N/A }
0N/A
0N/A if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
0N/A srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE ||
0N/A srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB)
0N/A {
0N/A aIdx = 0;
0N/A rIdx = 1;
0N/A gIdx = 2;
0N/A bIdx = 3;
0N/A }
0N/A else if (srcP->imageType ==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR||
0N/A srcP->imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE)
0N/A {
0N/A aIdx = 0;
0N/A rIdx = 3;
0N/A gIdx = 2;
0N/A bIdx = 1;
0N/A }
0N/A else if (srcP->imageType == java_awt_image_BufferedImage_TYPE_3BYTE_BGR){
0N/A rIdx = 2;
0N/A gIdx = 1;
0N/A bIdx = 0;
0N/A aIdx = 0; /* Ignored */
0N/A }
0N/A else if (srcP->cmodel.cmType == INDEX_CM_TYPE) {
0N/A rIdx = 0;
0N/A gIdx = 1;
0N/A bIdx = 2;
0N/A aIdx = 3; /* Use supportsAlpha to see if it is really there */
0N/A }
0N/A else {
0N/A return -1;
0N/A }
0N/A
0N/A /* Lock down the destination raster */
0N/A dataP = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env,
0N/A rasterP->jdata, NULL);
0N/A if (dataP == NULL) {
0N/A return -1;
0N/A }
0N/A argb = (*env)->GetPrimitiveArrayCritical(env, cmodelP->jrgb, NULL);
0N/A if (argb == NULL) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A return -1;
0N/A }
0N/A
0N/A cDataP = dataP + dstP->hints.dataOffset;
0N/A sP = (unsigned char *) mlib_ImageGetData(mlibImP);
0N/A
0N/A for (y=0; y < rasterP->height; y++, cDataP += rasterP->scanlineStride) {
0N/A cP = cDataP;
0N/A for (x=0; x < rasterP->width; x++, cP += rasterP->pixelStride) {
0N/A *cP = colorMatch(sP[rIdx], sP[gIdx], sP[bIdx], sP[aIdx],
0N/A (unsigned char *)argb, cmodelP->mapSize);
0N/A sP += cmodelP->numComponents;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, cmodelP->jrgb, argb, JNI_ABORT);
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A return -1;
0N/A}
0N/A
0N/Astatic int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP)
0N/A{
0N/A ColorModelS_t *cmP = &imageP->cmodel;
0N/A RasterS_t *rasterP = &imageP->raster;
0N/A HintS_t *hintP = &imageP->hints;
0N/A int *rgb;
0N/A int status = 0;
0N/A unsigned char *dataP, *cP;
0N/A unsigned int *mP;
0N/A int width = rasterP->width;
0N/A int height = rasterP->height;
0N/A int x, y;
0N/A
0N/A /* Need to grab the lookup tables. Right now only bytes */
0N/A rgb = (int *) (*env)->GetPrimitiveArrayCritical(env, cmP->jrgb, NULL);
0N/A
0N/A /* Interleaved with shared data */
0N/A dataP = (void *) (*env)->GetPrimitiveArrayCritical(env,
0N/A rasterP->jdata, NULL);
0N/A if (rgb == NULL || dataP == NULL) {
0N/A /* Release the lookup tables */
0N/A if (rgb) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, cmP->jrgb, rgb,
0N/A JNI_ABORT);
0N/A }
0N/A if (dataP) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env,
0N/A rasterP->jdata, dataP,
0N/A JNI_ABORT);
0N/A }
0N/A return -1;
0N/A }
0N/A
0N/A if (rasterP->dataType == BYTE_DATA_TYPE) {
0N/A unsigned char *cDataP = ((unsigned char *)dataP) + hintP->dataOffset;
0N/A
0N/A for (y=0; y < height; y++) {
0N/A mP = mDataP;
0N/A cP = cDataP;
0N/A for (x=0; x < width; x++, cP += rasterP->pixelStride) {
0N/A *mP++ = rgb[*cP];
0N/A }
0N/A mDataP += width;
0N/A cDataP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else if (rasterP->dataType == SHORT_DATA_TYPE) {
0N/A unsigned short *sDataP, *sP;
0N/A sDataP = ((unsigned short *)dataP) + hintP->channelOffset;
0N/A
0N/A for (y=0; y < height; y++) {
0N/A mP = mDataP;
0N/A sP = sDataP;
0N/A for (x=0; x < width; x++, sP+=rasterP->pixelStride) {
0N/A *mP++ = rgb[*sP];
0N/A }
0N/A mDataP += width;
0N/A sDataP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A /* Unknown type */
0N/A status = -1;
0N/A }
0N/A /* Release the lookup table data */
0N/A (*env)->ReleasePrimitiveArrayCritical(env, imageP->cmodel.jrgb,
0N/A rgb, JNI_ABORT);
0N/A /* Release the data array */
0N/A (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata,
0N/A dataP, JNI_ABORT);
0N/A return status;
0N/A}
0N/A/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
0N/Astatic int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned char *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (rasterP->numBands < 4) {
0N/A /* Need to put in alpha */
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
0N/Astatic int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned char *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
0N/A int a = numBands;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A
0N/A /* Need to put in alpha */
0N/A if (forceAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = 0xff;
0N/A for (c=0; c < numBands; c++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
0N/A <<loff[a]);
0N/A for (c=0; c < numBands; c++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
0N/Astatic int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned short *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (rasterP->numBands < 4) {
0N/A /* Need to put in alpha */
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A /*
0N/A *Not correct. Might need to unpremult,
0N/A * shift, etc
0N/A */
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A } else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A /*
0N/A *Not correct. Might need to unpremult,
0N/A * shift, etc
0N/A */
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
0N/Astatic int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned short *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
0N/A int a = numBands;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A
0N/A /* Need to put in alpha */
0N/A if (forceAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = 0xff;
0N/A for (c=0; c < numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to unpremult,
0N/A * shift, etc
0N/A */
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
0N/A <<loff[a]);
0N/A for (c=0; c < numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to
0N/A * unpremult, shift, etc
0N/A */
0N/A *outP++ = (unsigned char)
0N/A (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)
0N/A ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A
0N/A}
0N/A
0N/A/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
0N/Astatic int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *outDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned int *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (rasterP->numBands < 4) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to unpremult,
0N/A * shift, etc
0N/A */
0N/A *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to
0N/A * unpremult, shift, etc
0N/A */
0N/A *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
0N/Astatic int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *outDataP,
0N/A int forceAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *outP = outDataP;
0N/A unsigned int *lineInP, *inP;
0N/A jarray jInDataP;
0N/A jint *inDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
0N/A int a = numBands;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
0N/A inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
0N/A if (inDataP == NULL) {
0N/A return -1;
0N/A }
0N/A lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[c] < 0) {
0N/A loff[c] = -roff[c];
0N/A roff[c] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A }
0N/A
0N/A /* Need to put in alpha */
0N/A if (forceAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = 0xff;
0N/A for (c=0; c < numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to unpremult,
0N/A * shift, etc
0N/A */
0N/A *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
0N/A <<loff[a]);
0N/A for (c=0; c < numBands; c++) {
0N/A /*
0N/A * Not correct. Might need to
0N/A * unpremult, shift, etc
0N/A */
0N/A *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
0N/A <<loff[c]);
0N/A }
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (roff[0] < 0) {
0N/A loff[0] = -roff[0];
0N/A roff[0] = 0;
0N/A }
0N/A else loff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A inP = lineInP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
0N/A inP++;
0N/A }
0N/A lineInP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
0N/Astatic int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *inDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned char *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned char *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A *outP = 0;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
0N/Astatic int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *inDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned short *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned short *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
0N/Astatic int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
0N/A unsigned char *inDataP)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned int *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned int *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
0N/Astatic int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *inDataP,
0N/A int supportsAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned char *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned char *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int a = rasterP->numBands - 1;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (supportsAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A *outP = 0;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP |= (*inP<<loff[a]>>roff[a])&
0N/A rasterP->sppsm.maskArray[a];
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands-1; c++, inP++) {
0N/A *outP |= (*inP<<loff[c]>>roff[c])&
0N/A rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A *outP = 0;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
0N/Astatic int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *inDataP,
0N/A int supportsAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned short *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned short *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int a = rasterP->numBands - 1;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (supportsAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP |= (*inP<<loff[a]>>roff[a])&
0N/A rasterP->sppsm.maskArray[a];
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands-1; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&
0N/A rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
0N/Astatic int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
0N/A int component, unsigned char *inDataP,
0N/A int supportsAlpha)
0N/A{
0N/A int x, y, c;
0N/A unsigned char *inP = inDataP;
0N/A unsigned int *lineOutP, *outP;
0N/A jarray jOutDataP;
6378N/A jsize dataArrayLength;
6378N/A unsigned int *outDataP;
0N/A int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
0N/A int a = rasterP->numBands - 1;
0N/A
0N/A if (rasterP->numBands > MAX_NUMBANDS) {
0N/A return -1;
0N/A }
0N/A
0N/A /* Grab data ptr, strides, offsets from raster */
0N/A jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
6378N/A if (JNU_IsNull(env, jOutDataP)) {
6378N/A return -1;
6378N/A }
6378N/A
6378N/A dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
6378N/A CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
6378N/A
0N/A outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
0N/A if (outDataP == NULL) {
0N/A return -1;
0N/A }
6378N/A lineOutP = outDataP + rasterP->chanOffsets[0];
0N/A
0N/A if (component < 0) {
0N/A for (c=0; c < rasterP->numBands; c++) {
0N/A loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[c] < 0) {
0N/A roff[c] = -loff[c];
0N/A loff[c] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A }
0N/A /* Convert the all bands */
0N/A if (supportsAlpha) {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A *outP |= (*inP<<loff[a]>>roff[a])&
0N/A rasterP->sppsm.maskArray[a];
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands-1; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&
0N/A rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A else {
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++) {
0N/A inP++;
0N/A for (c=0; c < rasterP->numBands; c++, inP++) {
0N/A /* Not correct. Might need to unpremult, shift, etc */
0N/A *outP |= (*inP<<loff[c]>>roff[c])&
0N/A rasterP->sppsm.maskArray[c];
0N/A }
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A c = component;
0N/A loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
0N/A if (loff[0] < 0) {
0N/A roff[0] = -loff[0];
0N/A loff[0] = 0;
0N/A }
0N/A else roff[c] = 0;
0N/A
0N/A for (y=0; y < rasterP->height; y++) {
0N/A outP = lineOutP;
0N/A for (x=0; x < rasterP->width; x++, inP++) {
0N/A *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
0N/A outP++;
0N/A }
0N/A lineOutP += rasterP->scanlineStride;
0N/A }
0N/A }
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);
0N/A
0N/A return 0;
0N/A}
0N/A
0N/A/* This is temporary code. Should go away when there is better color
0N/A * conversion code available.
0N/A * REMIND: Ignoring alpha
0N/A */
0N/A/* returns the absolute value x */
0N/A#define ABS(x) ((x) < 0 ? -(x) : (x))
0N/A#define CLIP(val,min,max) ((val < min) ? min : ((val > max) ? max : val))
0N/A
0N/Astatic int
0N/AcolorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors) {
0N/A int besti = 0;
0N/A int mindist, i, t, d;
0N/A unsigned char red, green, blue;
0N/A
0N/A r = CLIP(r, 0, 255);
0N/A g = CLIP(g, 0, 255);
0N/A b = CLIP(b, 0, 255);
0N/A
0N/A /* look for pure gray match */
0N/A if ((r == g) && (g == b)) {
0N/A mindist = 256;
0N/A for (i = 0 ; i < numColors ; i++, argb+=4) {
0N/A red = argb[1];
0N/A green = argb[2];
0N/A blue = argb[3];
0N/A if (! ((red == green) && (green == blue)) ) {
0N/A continue;
0N/A }
0N/A d = ABS(red - r);
0N/A if (d == 0)
0N/A return i;
0N/A if (d < mindist) {
0N/A besti = i;
0N/A mindist = d;
0N/A }
0N/A }
0N/A return besti;
0N/A }
0N/A
0N/A /* look for non-pure gray match */
0N/A mindist = 256 * 256 * 256;
0N/A for (i = 0 ; i < numColors ; i++, argb+=4) {
0N/A red = argb[1];
0N/A green = argb[2];
0N/A blue = argb[3];
0N/A t = red - r;
0N/A d = t * t;
0N/A if (d >= mindist) {
0N/A continue;
0N/A }
0N/A t = green - g;
0N/A d += t * t;
0N/A if (d >= mindist) {
0N/A continue;
0N/A }
0N/A t = blue - b;
0N/A d += t * t;
0N/A if (d >= mindist) {
0N/A continue;
0N/A }
0N/A if (d == 0)
0N/A return i;
0N/A if (d < mindist) {
0N/A besti = i;
0N/A mindist = d;
0N/A }
0N/A }
0N/A
0N/A return besti;
0N/A}