/*
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sun_awt_image_ImagingLib.h"
#include "java_awt_Transparency.h"
#include "java_awt_image_AffineTransformOp.h"
#include "java_awt_image_BufferedImage.h"
#include "java_awt_color_ColorSpace.h"
#include "java_awt_image_ConvolveOp.h"
#include "sun_awt_image_IntegerComponentRaster.h"
#include "awt_ImagingLib.h"
#include "awt_parseImage.h"
#include "imageInitIDs.h"
#include <jni.h>
#include <jni_util.h>
#include <assert.h>
#include "awt_Mlib.h"
#include "gdefs.h"
#include "safe_alloc.h"
#include "safe_math.h"

/***************************************************************************
 *                               Definitions                               *
 ***************************************************************************/
#define jio_fprintf fprintf

#ifndef TRUE
#define TRUE 1
#endif /* TRUE */

#ifndef FALSE
#define FALSE 0
#endif /* FALSE */

#define TYPE_CUSTOM         java_awt_image_BufferedImage_TYPE_CUSTOM
#define TYPE_INT_RGB        java_awt_image_BufferedImage_TYPE_INT_RGB
#define TYPE_INT_ARGB       java_awt_image_BufferedImage_TYPE_INT_ARGB
#define TYPE_INT_ARGB_PRE   java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE
#define TYPE_INT_BGR        java_awt_image_BufferedImage_TYPE_INT_BGR
#define TYPE_4BYTE_ABGR     java_awt_image_BufferedImage_TYPE_4BYTE_ABGR
#define TYPE_4BYTE_ABGR_PRE java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE

/* (alpha*color)>>nbits + alpha>>(nbits-1) */
#define BLEND(color, alpha, alphaNbits) \
    ((((alpha)*(color))>>(alphaNbits)) + ((alpha) >> ((alphaNbits)-1)))

    /* ((color - (alpha>>(nBits-1)))<<nBits)/alpha */
#define UNBLEND(color, alpha, alphaNbits) \
    ((((color)-((alpha)>>((alphaNbits)-1)))<<(alphaNbits))/(alpha))

/* Enumeration of all of the mlib functions used */
typedef enum {
    MLIB_CONVMxN,
    MLIB_AFFINE,
    MLIB_LOOKUP,
    MLIB_CONVKERNCVT
} mlibTypeE_t;

typedef struct {
    int dataType;           /* One of BYTE_DATA_TYPE, SHORT_DATA_TYPE, */
    int needToCopy;
    int cvtSrcToDefault;    /* If TRUE, convert the src to def CM (pre?) */
    int allocDefaultDst;    /* If TRUE, alloc def CM dst buffer */
    int cvtToDst;           /* If TRUE, convert dst buffer to Dst CM */
    int addAlpha;
} mlibHintS_t;

/***************************************************************************
 *                     Static Variables/Structures                         *
 ***************************************************************************/

static mlibSysFnS_t sMlibSysFns = {
    NULL, // placeholder for j2d_mlib_ImageCreate
    NULL, // placeholder for j2d_mlib_ImageCreateStruct
    NULL, // placeholder for j2d_mlib_ImageDelete
};

static mlibFnS_t sMlibFns[] = {
    {NULL, "j2d_mlib_ImageConvMxN"},
    {NULL, "j2d_mlib_ImageAffine"},
    {NULL, "j2d_mlib_ImageLookUp"},
    {NULL, "j2d_mlib_ImageConvKernelConvert"},
    {NULL, NULL},
};

static int s_timeIt = 0;
static int s_printIt = 0;
static int s_startOff = 0;
static int s_nomlib = 0;

/***************************************************************************
 *                          Static Function Prototypes                     *
 ***************************************************************************/

static int
allocateArray(JNIEnv *env, BufImageS_t *imageP,
              mlib_image **mlibImagePP, void **dataPP, int isSrc,
              int cvtToDefault, int addAlpha);
static int
allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
                    mlib_image **mlibImagePP, void **dataPP, int isSrc);

static void
freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
          void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
          void *dstdataP);
static void
freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
          void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
          void *dstdataP);

static int
storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
                mlib_image *mlibImP);

static int
storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
                mlib_image *mlibImP);

static int
storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
              mlib_image *mlibImP);

static int
colorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors);

static int
setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
              int expandICM, int useAlpha,
              int premultiply, mlibHintS_t *hintP);


static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP);
static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP);
static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP);
static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP);
static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha);
static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha);
static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha);
static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
                        unsigned char *outDataP);
static int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
                        unsigned char *outDataP);
static int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
                        unsigned char *outDataP);
static int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *outDataP,
                               int supportsAlpha);
static int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *outDataP,
                               int supportsAlpha);
static int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *outDataP,
                               int supportsAlpha);

mlib_start_timer start_timer = NULL;
mlib_stop_timer stop_timer = NULL;

/***************************************************************************
 *                          Debugging Definitions                          *
 ***************************************************************************/
#ifdef DEBUG

static void
printMedialibError(int status) {
    switch(status) {
    case MLIB_FAILURE:
        jio_fprintf(stderr, "failure\n");
        break;
    case MLIB_NULLPOINTER:
        jio_fprintf(stderr, "null pointer\n");
        break;
    case MLIB_OUTOFRANGE:
        jio_fprintf (stderr, "out of range\n");
        break;
    default:
        jio_fprintf (stderr, "medialib error\n");
        break;
    }
}
#else /* ! DEBUG */
#  define printMedialibError(x)

#endif /* ! DEBUG */

static int
getMlibEdgeHint(jint edgeHint) {
    switch (edgeHint) {
    case java_awt_image_ConvolveOp_EDGE_NO_OP:
        return MLIB_EDGE_DST_COPY_SRC;
    case java_awt_image_ConvolveOp_EDGE_ZERO_FILL:
    default:
        return MLIB_EDGE_DST_FILL_ZERO;
    }
}

/*
 * We have to make sure that awt_setPixels can be safely applied to the given pair of
 * raster and mlib image.
 *
 * In particular, make sure that
 *  - dimension is the same
 *  - number of channels in mlib image corresponds to the number of bands in the raster
 *  - sample size in image and raster are the same.
 *
 * Returns:
 *  -1 to indicate failure,
 *   1 to indicate success
 */
static int setPixelsFormMlibImage(JNIEnv *env, RasterS_t *rasterP, mlib_image* img) {
    if (rasterP->width != img->width || rasterP->height != img->height) {
        /* dimension does not match */
        return -1;
    }

    if (rasterP->numBands != img->channels) {
        /* number of bands does not match */
        return -1;
    }

    switch (rasterP->dataType) {
    case BYTE_DATA_TYPE:
        if (img->type != MLIB_BYTE) {
            return -1;
        }
        break;
    case SHORT_DATA_TYPE:
        if (img->type != MLIB_SHORT && img->type != MLIB_USHORT) {
            return -1;
        }
        break;
    default:
        /* awt_setPixels does not support such rasters */
        return -1;
    }

    return awt_setPixels(env, rasterP, mlib_ImageGetData(img));
}

/***************************************************************************
 *                          External Functions                             *
 ***************************************************************************/
JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_convolveBI(JNIEnv *env, jobject this,
                                         jobject jsrc, jobject jdst,
                                         jobject jkernel, jint edgeHint)
{
    void *sdata, *ddata;
    mlib_image *src;
    mlib_image *dst;
    int i, scale;
    mlib_d64 *dkern;
    mlib_s32 *kdata;
    int klen;
    float kmax;
    mlib_s32 cmask;
    mlib_status status;
    int retStatus = 1;
    float *kern;
    BufImageS_t *srcImageP, *dstImageP;
    jobject jdata;
    int kwidth;
    int kheight;
    int w, h;
    int x, y;
    mlibHintS_t hint;
    int nbands;

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt)     (*start_timer)(3600);

    kwidth  = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
    kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
    jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
    klen  = (*env)->GetArrayLength(env, jdata);
    kern  = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
    if (kern == NULL) {
        /* out of memory exception already thrown */
        return 0;
    }

    if ((kwidth&0x1) == 0) {
        /* Kernel has even width */
        w = kwidth+1;
    }
    else {
        w = kwidth;
    }
    if ((kheight&0x1) == 0) {
        /* Kernel has even height */
        h = kheight+1;
    }
    else {
        h = kheight;
    }

    dkern = NULL;
    if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
        dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
    }
    if (dkern == NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
        return 0;
    }

    /* Need to flip and find max value of the kernel.
     * Also, save the kernel values as mlib_d64 values.
     * The flip is to operate correctly with medialib,
     * which doesn't do the mathemetically correct thing,
     * i.e. it doesn't rotate the kernel by 180 degrees.
     * REMIND: This should perhaps be done at the Java
     * level by ConvolveOp.
     * REMIND: Should the max test be looking at absolute
     * values?
     * REMIND: What if klen != kheight * kwidth?
     */
    kmax = kern[klen-1];
    i = klen-1;
    for (y=0; y < kheight; y++) {
        for (x=0; x < kwidth; x++, i--) {
            dkern[y*w+x] = (mlib_d64) kern[i];
            if (kern[i] > kmax) {
                kmax = kern[i];
            }
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);

    if (kmax > 1<<16) {
        /* We can only handle 16 bit max */
        free(dkern);
        return 0;
    }


    /* Parse the source image */
    if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        free(dkern);
        return 0;
    }

    /* Parse the destination image */
    if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        free(dkern);
        return 0;
    }

    nbands = setImageHints(env, srcImageP, dstImageP, TRUE, TRUE,
                        FALSE, &hint);
    if (nbands < 1) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        free(dkern);
        return 0;
    }
    /* Allocate the arrays */
    if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
                      hint.cvtSrcToDefault, hint.addAlpha) < 0) {
        /* Must be some problem */
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        free(dkern);
        return 0;
    }
    if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
                      hint.cvtToDst, FALSE) < 0) {
        /* Must be some problem */
        freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        free(dkern);
        return 0;
    }

    kdata = NULL;
    if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
        kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
    }
    if (kdata == NULL) {
        freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        free(dkern);
        return 0;
    }

    if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
                                    mlib_ImageGetType(src)) != MLIB_SUCCESS) {
        freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        free(dkern);
        free(kdata);
        return 0;
    }

    if (s_printIt) {
        fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
        for (y=kheight-1; y >= 0; y--) {
            for (x=kwidth-1; x >= 0; x--) {
                fprintf(stderr, "%g ", dkern[y*w+x]);
            }
            fprintf(stderr, "\n");
        }
        fprintf(stderr, "New Kernel(scale=%d):\n", scale);
        for (y=kheight-1; y >= 0; y--) {
            for (x=kwidth-1; x >= 0; x--) {
                fprintf(stderr, "%d ", kdata[y*w+x]);
            }
            fprintf(stderr, "\n");
        }
    }

    cmask = (1<<src->channels)-1;
    status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
                               (w-1)/2, (h-1)/2, scale, cmask,
                               getMlibEdgeHint(edgeHint));

    if (status != MLIB_SUCCESS) {
        printMedialibError(status);
        retStatus = 0;
    }

    if (s_printIt) {
        unsigned int *dP;
        if (s_startOff != 0) {
            printf("Starting at %d\n", s_startOff);
        }
        if (sdata == NULL) {
            dP = (unsigned int *) mlib_ImageGetData(src);
        }
        else {
            dP = (unsigned int *) sdata;
        }
        printf("src is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[s_startOff+i]);
        }
        printf("\n");
        if (ddata == NULL) {
            dP = (unsigned int *)mlib_ImageGetData(dst);
        }
        else {
            dP = (unsigned int *) ddata;
        }
        printf("dst is \n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[s_startOff+i]);
        }
        printf("\n");
    }

    /* Means that we couldn't write directly into the destination buffer */
    if (ddata == NULL) {

        /* Need to store it back into the array */
        if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
            /* Error */
            retStatus = 0;
        }
    }

    /* Release the pinned memory */
    freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
    awt_freeParsedImage(srcImageP, TRUE);
    awt_freeParsedImage(dstImageP, TRUE);
    free(dkern);
    free(kdata);

    if (s_timeIt) (*stop_timer)(3600, 1);

    return retStatus;
}

JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
                                             jobject jsrc, jobject jdst,
                                             jobject jkernel, jint edgeHint)
{
    mlib_image *src;
    mlib_image *dst;
    int i, scale;
    mlib_d64 *dkern;
    mlib_s32 *kdata;
    int klen;
    float kmax;
    int retStatus = 1;
    mlib_status status;
    mlib_s32 cmask;
    void *sdata;
    void *ddata;
    RasterS_t *srcRasterP;
    RasterS_t *dstRasterP;
    int kwidth;
    int kheight;
    int w, h;
    int x, y;
    jobject jdata;
    float *kern;

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt)     (*start_timer)(3600);

    kwidth  = (*env)->GetIntField(env, jkernel, g_KernelWidthID);
    kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID);
    jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID);
    klen  = (*env)->GetArrayLength(env, jdata);
    kern  = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
    if (kern == NULL) {
        /* out of memory exception already thrown */
        return 0;
    }

    if ((kwidth&0x1) == 0) {
        /* Kernel has even width */
        w = kwidth+1;
    }
    else {
        w = kwidth;
    }
    if ((kheight&0x1) == 0) {
        /* Kernel has even height */
        h = kheight+1;
    }
    else {
        h = kheight;
    }

    dkern = NULL;
    if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))) {
        dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64));
    }
    if (dkern == NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);
        return 0;
    }

    /* Need to flip and find max value of the kernel.
     * Also, save the kernel values as mlib_d64 values.
     * The flip is to operate correctly with medialib,
     * which doesn't do the mathemetically correct thing,
     * i.e. it doesn't rotate the kernel by 180 degrees.
     * REMIND: This should perhaps be done at the Java
     * level by ConvolveOp.
     * REMIND: Should the max test be looking at absolute
     * values?
     * REMIND: What if klen != kheight * kwidth?
     */
    kmax = kern[klen-1];
    i = klen-1;
    for (y=0; y < kheight; y++) {
        for (x=0; x < kwidth; x++, i--) {
            dkern[y*w+x] = (mlib_d64) kern[i];
            if (kern[i] > kmax) {
                kmax = kern[i];
            }
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT);

    if (kmax > 1<<16) {
        /* We can only handle 16 bit max */
        free(dkern);
        return 0;
    }

    /* Parse the source image */
    if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        free(dkern);
        return -1;
    }

    if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        free(srcRasterP);
        free(dkern);
        return -1;
    }

    /* Parse the source raster */
    if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
        /* Can't handle any custom rasters */
        free(srcRasterP);
        free(dstRasterP);
        free(dkern);
        return 0;
    }

    /* Parse the destination raster */
    if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
        /* Can't handle any custom images */
        awt_freeParsedRaster(srcRasterP, TRUE);
        free(dstRasterP);
        free(dkern);
        return 0;
    }

    /* Allocate the arrays */
    if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
        /* Must be some problem */
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        free(dkern);
        return 0;
    }
    if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
        /* Must be some problem */
        freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        free(dkern);
        return 0;
    }

    kdata = NULL;
    if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))) {
        kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32));
    }
    if (kdata == NULL) {
        freeDataArray(env, srcRasterP->jdata, src, sdata,
                      dstRasterP->jdata, dst, ddata);
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        free(dkern);
        return 0;
    }

    if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h,
                                    mlib_ImageGetType(src)) != MLIB_SUCCESS) {
        freeDataArray(env, srcRasterP->jdata, src, sdata,
                      dstRasterP->jdata, dst, ddata);
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        free(dkern);
        free(kdata);
        return 0;
    }

    if (s_printIt) {
        fprintf(stderr, "Orig Kernel(len=%d):\n",klen);
        for (y=kheight-1; y >= 0; y--) {
            for (x=kwidth-1; x >= 0; x--) {
                fprintf(stderr, "%g ", dkern[y*w+x]);
            }
            fprintf(stderr, "\n");
        }
        fprintf(stderr, "New Kernel(scale=%d):\n", scale);
        for (y=kheight-1; y >= 0; y--) {
            for (x=kwidth-1; x >= 0; x--) {
                fprintf(stderr, "%d ", kdata[y*w+x]);
            }
            fprintf(stderr, "\n");
        }
    }

    cmask = (1<<src->channels)-1;
    status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
                               (w-1)/2, (h-1)/2, scale, cmask,
                               getMlibEdgeHint(edgeHint));

    if (status != MLIB_SUCCESS) {
        printMedialibError(status);
        retStatus = 0;
    }

    if (s_printIt) {
        unsigned int *dP;
        if (s_startOff != 0) {
            printf("Starting at %d\n", s_startOff);
        }
        if (sdata == NULL) {
            dP = (unsigned int *) mlib_ImageGetData(src);
        }
        else {
            dP = (unsigned int *) sdata;
        }
        printf("src is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[s_startOff+i]);
        }
        printf("\n");
        if (ddata == NULL) {
            dP = (unsigned int *)mlib_ImageGetData(dst);
        }
        else {
            dP = (unsigned int *) ddata;
        }
        printf("dst is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[s_startOff+i]);
        }
        printf("\n");
    }

    /* Means that we couldn't write directly into the destination buffer */
    if (ddata == NULL) {
        if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
        }
    }

    /* Release the pinned memory */
    freeDataArray(env, srcRasterP->jdata, src, sdata,
                  dstRasterP->jdata, dst, ddata);
    awt_freeParsedRaster(srcRasterP, TRUE);
    awt_freeParsedRaster(dstRasterP, TRUE);
    free(dkern);
    free(kdata);

    if (s_timeIt) (*stop_timer)(3600,1);

    return retStatus;
}


JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_transformBI(JNIEnv *env, jobject this,
                                          jobject jsrc,
                                          jobject jdst,
                                          jdoubleArray jmatrix,
                                          jint interpType)
{
    mlib_image *src;
    mlib_image *dst;
    int i;
    int retStatus = 1;
    mlib_status status;
    double *matrix;
    mlib_d64 mtx[6];
    void *sdata;
    void *ddata;
    BufImageS_t *srcImageP;
    BufImageS_t *dstImageP;
    mlib_filter filter;
    mlibHintS_t hint;
    unsigned int *dP;
    int useIndexed;
    int nbands;

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt) {
        (*start_timer)(3600);
    }

    switch(interpType) {
    case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
        filter = MLIB_BILINEAR;
        break;
    case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
        filter = MLIB_NEAREST;
        break;
    case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
        filter = MLIB_BICUBIC;
        break;
    default:
        JNU_ThrowInternalError(env, "Unknown interpolation type");
        return -1;
    }

    if ((*env)->GetArrayLength(env, jmatrix) < 6) {
        /*
         * Very unlikely, however we should check for this:
         * if given matrix array is too short, we can't handle it
         */
        return 0;
    }

    matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
    if (matrix == NULL) {
        /* out of memory error already thrown */
        return 0;
    }

    if (s_printIt) {
        printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
               matrix[2], matrix[3], matrix[4], matrix[5]);
    }

    mtx[0] = matrix[0];
    mtx[1] = matrix[2];
    mtx[2] = matrix[4];
    mtx[3] = matrix[1];
    mtx[4] = matrix[3];
    mtx[5] = matrix[5];

    (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);

    /* Parse the source image */
    if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        return 0;
    }

    /* Parse the destination image */
    if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        return 0;
    }

    /* REMIND!!  Can't assume that it is the same LUT!! */
    /* Fix 4213160, 4184283 */
    useIndexed = (srcImageP->cmodel.cmType == INDEX_CM_TYPE &&
                  dstImageP->cmodel.cmType == INDEX_CM_TYPE &&
                  srcImageP->raster.rasterType == dstImageP->raster.rasterType &&
                  srcImageP->raster.rasterType == COMPONENT_RASTER_TYPE);

    nbands = setImageHints(env, srcImageP, dstImageP, !useIndexed, TRUE,
                        FALSE, &hint);
    if (nbands < 1) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }

    /* Allocate the arrays */
    if (allocateArray(env, srcImageP, &src, &sdata, TRUE,
                      hint.cvtSrcToDefault, hint.addAlpha) < 0) {
        /* Must be some problem */
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }
    if (allocateArray(env, dstImageP, &dst, &ddata, FALSE,
                      hint.cvtToDst, FALSE) < 0) {
        /* Must be some problem */
        freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }
#if 0
fprintf(stderr,"Src----------------\n");
fprintf(stderr,"Type : %d\n",src->type);
fprintf(stderr,"Channels: %d\n",src->channels);
fprintf(stderr,"Width   : %d\n",src->width);
fprintf(stderr,"Height  : %d\n",src->height);
fprintf(stderr,"Stride  : %d\n",src->stride);
fprintf(stderr,"Flags   : %d\n",src->flags);

fprintf(stderr,"Dst----------------\n");
fprintf(stderr,"Type : %d\n",dst->type);
fprintf(stderr,"Channels: %d\n",dst->channels);
fprintf(stderr,"Width   : %d\n",dst->width);
fprintf(stderr,"Height  : %d\n",dst->height);
fprintf(stderr,"Stride  : %d\n",dst->stride);
fprintf(stderr,"Flags   : %d\n",dst->flags);
#endif

    if (dstImageP->cmodel.cmType == INDEX_CM_TYPE) {
        /* Need to clear the destination to the transparent pixel */
        unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);

        memset(cP, dstImageP->cmodel.transIdx,
               mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
    }
    /* Perform the transformation */
    if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
                                  MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
    {
        printMedialibError(status);
        freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);

        return 0;
    }

    if (s_printIt) {
        if (sdata == NULL) {
            dP = (unsigned int *) mlib_ImageGetData(src);
        }
        else {
            dP = (unsigned int *) sdata;
        }
        printf("src is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[i]);
        }
        printf("\n");
        if (ddata == NULL) {
            dP = (unsigned int *)mlib_ImageGetData(dst);
        }
        else {
            dP = (unsigned int *) ddata;
        }
        printf("dst is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[i]);
        }
        printf("\n");
    }

    /* Means that we couldn't write directly into the destination buffer */
    if (ddata == NULL) {
        freeDataArray(env, srcImageP->raster.jdata, src, sdata,
                      NULL, NULL, NULL);
        /* Need to store it back into the array */
        if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
            /* Error */
            retStatus = 0;
        }
        freeDataArray(env, NULL, NULL, NULL, dstImageP->raster.jdata,
                      dst, ddata);
    }
    else {
        /* Release the pinned memory */
        freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
    }

    awt_freeParsedImage(srcImageP, TRUE);
    awt_freeParsedImage(dstImageP, TRUE);

    if (s_timeIt) (*stop_timer)(3600,1);

    return retStatus;
}

JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
                                              jobject jsrc,
                                              jobject jdst,
                                              jdoubleArray jmatrix,
                                              jint interpType)
{
    mlib_image *src;
    mlib_image *dst;
    int i;
    int retStatus = 1;
    mlib_status status;
    double *matrix;
    mlib_d64 mtx[6];
    void *sdata;
    void *ddata;
    RasterS_t *srcRasterP;
    RasterS_t *dstRasterP;
    mlib_filter filter;
    unsigned int *dP;

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt) {
        (*start_timer)(3600);
    }

    switch(interpType) {
    case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
        filter = MLIB_BILINEAR;
        break;
    case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
        filter = MLIB_NEAREST;
        break;
    case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
        filter = MLIB_BICUBIC;
        break;
    default:
        JNU_ThrowInternalError(env, "Unknown interpolation type");
        return -1;
    }

    if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        return -1;
    }

    if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        free(srcRasterP);
        return -1;
    }

    if ((*env)->GetArrayLength(env, jmatrix) < 6) {
        /*
         * Very unlikely, however we should check for this:
         * if given matrix array is too short, we can't handle it.
         */
        free(srcRasterP);
        free(dstRasterP);
        return 0;
    }

    matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL);
    if (matrix == NULL) {
        /* out of memory error already thrown */
        free(srcRasterP);
        free(dstRasterP);
        return 0;
    }

    if (s_printIt) {
        printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],
               matrix[2], matrix[3], matrix[4], matrix[5]);
    }

    mtx[0] = matrix[0];
    mtx[1] = matrix[2];
    mtx[2] = matrix[4];
    mtx[3] = matrix[1];
    mtx[4] = matrix[3];
    mtx[5] = matrix[5];

    (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);

    /* Parse the source raster */
    if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
        /* Can't handle any custom rasters */
        free(srcRasterP);
        free(dstRasterP);
        return 0;
    }

    /* Parse the destination raster */
    if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
        /* Can't handle any custom images */
        awt_freeParsedRaster(srcRasterP, TRUE);
        free(dstRasterP);
        return 0;
    }

    /* Allocate the arrays */
    if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
        /* Must be some problem */
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }
    if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
        /* Must be some problem */
        freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }

#if 0
fprintf(stderr,"Src----------------\n");
fprintf(stderr,"Type : %d\n",src->type);
fprintf(stderr,"Channels: %d\n",src->channels);
fprintf(stderr,"Width   : %d\n",src->width);
fprintf(stderr,"Height  : %d\n",src->height);
fprintf(stderr,"Stride  : %d\n",src->stride);
fprintf(stderr,"Flags   : %d\n",src->flags);

fprintf(stderr,"Dst----------------\n");
fprintf(stderr,"Type : %d\n",dst->type);
fprintf(stderr,"Channels: %d\n",dst->channels);
fprintf(stderr,"Width   : %d\n",dst->width);
fprintf(stderr,"Height  : %d\n",dst->height);
fprintf(stderr,"Stride  : %d\n",dst->stride);
fprintf(stderr,"Flags   : %d\n",dst->flags);
#endif

    {
        unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst);

        memset(cP, 0, mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst));
    }

    /* Perform the transformation */
    if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter,
                                  MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS))
    {
        printMedialibError(status);
        /* REMIND: Free the regions */
        return 0;
    }

    if (s_printIt) {
        if (sdata == NULL) {
            dP = (unsigned int *) mlib_ImageGetData(src);
        }
        else {
            dP = (unsigned int *) sdata;
        }
        printf("src is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[i]);
        }
        printf("\n");
        if (ddata == NULL) {
            dP = (unsigned int *)mlib_ImageGetData(dst);
        }
        else {
            dP = (unsigned int *) ddata;
        }
        printf("dst is\n");
        for (i=0; i < 20; i++) {
            printf("%x ",dP[i]);
        }
        printf("\n");
    }

    /* Means that we couldn't write directly into the destination buffer */
    if (ddata == NULL) {
        /* Need to store it back into the array */
        if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
            (*env)->ExceptionClear(env); // Could not store the array, try another way
            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
        }
    }

    /* Release the pinned memory */
    freeDataArray(env, srcRasterP->jdata, src, sdata,
                  dstRasterP->jdata, dst, ddata);

    awt_freeParsedRaster(srcRasterP, TRUE);
    awt_freeParsedRaster(dstRasterP, TRUE);

    if (s_timeIt) (*stop_timer)(3600,1);

    return retStatus;
}

typedef struct {
    jobject jArray;
    jsize length;
    unsigned char *table;
} LookupArrayInfo;

#define NLUT 8

#ifdef _LITTLE_ENDIAN
#define INDEXES    { 3, 2, 1, 0, 7, 6, 5, 4 }
#else
#define INDEXES    { 0, 1, 2, 3, 4, 5, 6, 7 }
#endif

static int lookupShortData(mlib_image* src, mlib_image* dst,
    LookupArrayInfo* lookup)
{
    int x, y;
    unsigned int mask = NLUT-1;

    unsigned short* srcLine = (unsigned short*)src->data;
    unsigned char* dstLine = (unsigned char*)dst->data;

    static int indexes[NLUT] = INDEXES;

    if (src->width != dst->width || src->height != dst->height) {
        return 0;
    }

    for (y=0; y < src->height; y++) {
        int nloop, nx;
        int npix = src->width;

        unsigned short* srcPixel = srcLine;
        unsigned char* dstPixel = dstLine;

#ifdef SIMPLE_LOOKUP_LOOP
        for (x=0; status && x < width; x++) {
            unsigned short s = *srcPixel++;
            if (s >= lookup->length) {
                /* we can not handle source image using
                * byte lookup table. Fall back to processing
                * images in java
                */
                return 0;
            }
            *dstPixel++ = lookup->table[s];
        }
#else
        /* Get to 32 bit-aligned point */
        while(((uintptr_t)dstPixel & 0x3) != 0 && npix>0) {
            unsigned short s = *srcPixel++;
            if (s >= lookup->length) {
                return 0;
            }
            *dstPixel++ = lookup->table[s];
            npix--;
        }

        /*
         * Do NLUT pixels per loop iteration.
         * Pack into ints and write out 2 at a time.
         */
        nloop = npix/NLUT;
        nx = npix%NLUT;

        for(x=nloop; x!=0; x--) {
            int i = 0;
            int* dstP = (int*)dstPixel;

            for (i = 0; i < NLUT; i++) {
                if (srcPixel[i] >= lookup->length) {
                    return 0;
                }
            }

            dstP[0] = (int)
                ((lookup->table[srcPixel[indexes[0]]] << 24) |
                 (lookup->table[srcPixel[indexes[1]]] << 16) |
                 (lookup->table[srcPixel[indexes[2]]] << 8)  |
                  lookup->table[srcPixel[indexes[3]]]);
            dstP[1] = (int)
                ((lookup->table[srcPixel[indexes[4]]] << 24) |
                 (lookup->table[srcPixel[indexes[5]]] << 16) |
                 (lookup->table[srcPixel[indexes[6]]] << 8)  |
                  lookup->table[srcPixel[indexes[7]]]);


            dstPixel += NLUT;
            srcPixel += NLUT;
        }

        /*
         * Complete any remaining pixels
         */
        for(x=nx; x!=0; x--) {
            unsigned short s = *srcPixel++;
            if (s >= lookup->length) {
                return 0;
            }
            *dstPixel++ = lookup->table[s];
        }
#endif

        dstLine += dst->stride;     // array of bytes, scan stride in bytes
        srcLine += src->stride / 2; // array of shorts, scan stride in bytes
    }
    return 1;
}

JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
                                           jobject jsrc, jobject jdst,
                                           jobjectArray jtableArrays)
{
    mlib_image *src;
    mlib_image *dst;
    void *sdata, *ddata;
    unsigned char **tbl;
    unsigned char lut[256];
    int retStatus = 1;
    int i;
    mlib_status status;
    int lut_nbands;
    LookupArrayInfo *jtable;
    BufImageS_t *srcImageP, *dstImageP;
    int nbands;
    int ncomponents;
    mlibHintS_t hint;

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt) (*start_timer)(3600);

    /* Parse the source image */
    if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        return 0;
    }

    /* Parse the destination image */
    if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        return 0;
    }

    nbands = setImageHints(env, srcImageP, dstImageP, FALSE, TRUE,
                        FALSE, &hint);

    if (nbands < 1 || nbands > srcImageP->cmodel.numComponents) {
        /* Can't handle any custom images */
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }

    ncomponents = srcImageP->cmodel.isDefaultCompatCM
        ? 4
        : srcImageP->cmodel.numComponents;

    /* Make sure that color order can be used for
     * re-ordering of lookup arrays.
     */
    for (i = 0; i < nbands; i++) {
        int idx = srcImageP->hints.colorOrder[i];

        if (idx < 0 || idx >= ncomponents) {
            awt_freeParsedImage(srcImageP, TRUE);
            awt_freeParsedImage(dstImageP, TRUE);
            return 0;
        }
    }

    lut_nbands = (*env)->GetArrayLength(env, jtableArrays);

    if (lut_nbands > ncomponents) {
        lut_nbands = ncomponents;
    }

    tbl = NULL;
    if (SAFE_TO_ALLOC_2(ncomponents, sizeof(unsigned char *))) {
        tbl = (unsigned char **)
            calloc(1, ncomponents * sizeof(unsigned char *));
    }

    jtable = NULL;
    if (SAFE_TO_ALLOC_2(lut_nbands, sizeof(LookupArrayInfo))) {
        jtable = (LookupArrayInfo *)malloc(lut_nbands * sizeof (LookupArrayInfo));
    }

    if (tbl == NULL || jtable == NULL) {
        if (tbl != NULL) free(tbl);
        if (jtable != NULL) free(jtable);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        JNU_ThrowNullPointerException(env, "NULL LUT");
        return 0;
    }
    /* Need to grab these pointers before we lock down arrays */
    for (i=0; i < lut_nbands; i++) {
        jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);

        if (jtable[i].jArray != NULL) {
            jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
            jtable[i].table = NULL;

            if (jtable[i].length < 256) {
                /* we may read outside the table during lookup */
                jtable[i].jArray = NULL;
                jtable[i].length = 0;
            }
        }
        if (jtable[i].jArray == NULL) {
            free(tbl);
            free(jtable);
            awt_freeParsedImage(srcImageP, TRUE);
            awt_freeParsedImage(dstImageP, TRUE);
            return 0;
        }
    }

    /* Allocate the arrays */
    if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
        /* Must be some problem */
        free(tbl);
        free(jtable);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }
    if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
        /* Must be some problem */
        free(tbl);
        free(jtable);
        freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
        awt_freeParsedImage(srcImageP, TRUE);
        awt_freeParsedImage(dstImageP, TRUE);
        return 0;
    }

    /* Set up a straight lut so we don't mess around with alpha */
    /*
     * NB: medialib lookup routine expects lookup array for each
     * component of source image including alpha.
     * If lookup table we got form the java layer does not contain
     * sufficient number of lookup arrays we add references to identity
     * lookup array to make medialib happier.
     */
    if (lut_nbands < ncomponents) {
        int j;
        /* REMIND: This should be the size of the input lut!! */
        for (j=0; j < 256; j++) {
            lut[j] = j;
        }
        for (j=0; j < ncomponents; j++) {
            tbl[j] = lut;
        }
    }

    for (i=0; i < lut_nbands; i++) {
        jtable[i].table = (unsigned char *)
            (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
        if (jtable[i].table == NULL) {
            /* Free what we've got so far. */
            int j;
            for (j = 0; j < i; j++) {
                (*env)->ReleasePrimitiveArrayCritical(env,
                                                      jtable[j].jArray,
                                                      (jbyte *) jtable[j].table,
                                                      JNI_ABORT);
            }
            free(tbl);
            free(jtable);
            freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
            awt_freeParsedImage(srcImageP, TRUE);
            awt_freeParsedImage(dstImageP, TRUE);
            return 0;
        }
        tbl[srcImageP->hints.colorOrder[i]] = jtable[i].table;
    }

    if (lut_nbands == 1) {
        for (i=1; i < nbands -
                 srcImageP->cmodel.supportsAlpha; i++) {
                     tbl[srcImageP->hints.colorOrder[i]] = jtable[0].table;
        }
    }

    /* Mlib needs 16bit lookuptable and must be signed! */
    if (src->type == MLIB_SHORT) {
        if (dst->type == MLIB_BYTE) {
            if (nbands > 1) {
                retStatus = 0;
            }
            else {
                retStatus = lookupShortData(src, dst, &jtable[0]);
            }
        }
        /* How about ddata == null? */
    }
    else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
                                      (void **)tbl) != MLIB_SUCCESS)) {
        printMedialibError(status);
        retStatus = 0;
    }

   /* Release the LUT */
    for (i=0; i < lut_nbands; i++) {
        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
            (jbyte *) jtable[i].table, JNI_ABORT);
    }
    free ((void *) jtable);
    free ((void *) tbl);

    /*
     * Means that we couldn't write directly into
     * the destination buffer
     */
    if (ddata == NULL) {

        /* Need to store it back into the array */
        if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) {
            /* Error */
            retStatus = 0;
        }
    }


    /* Release the pinned memory */
    freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);

    awt_freeParsedImage(srcImageP, TRUE);
    awt_freeParsedImage(dstImageP, TRUE);

    if (s_timeIt) (*stop_timer)(3600, 1);

    return retStatus;
}

JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
                                               jobject this,
                                               jobject jsrc,
                                               jobject jdst,
                                               jobjectArray jtableArrays)
{
    RasterS_t*     srcRasterP;
    RasterS_t*     dstRasterP;
    mlib_image*    src;
    mlib_image*    dst;
    void*          sdata;
    void*          ddata;
    LookupArrayInfo jtable[4];
    unsigned char* mlib_lookupTable[4];
    int            i;
    int            retStatus = 1;
    mlib_status    status;
    int            jlen;
    int            lut_nbands;
    int            src_nbands;
    int            dst_nbands;
    unsigned char  ilut[256];

    /* This function requires a lot of local refs ??? Is 64 enough ??? */
    if ((*env)->EnsureLocalCapacity(env, 64) < 0)
        return 0;

    if (s_nomlib) return 0;
    if (s_timeIt) (*start_timer)(3600);

    if ((srcRasterP = (RasterS_t*) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        return -1;
    }

    if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Out of memory");
        free(srcRasterP);
        return -1;
    }

    /* Parse the source raster - reject custom images */
    if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
        free(srcRasterP);
        free(dstRasterP);
        return 0;
    }

    /* Parse the destination image - reject custom images */
    if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
        awt_freeParsedRaster(srcRasterP, TRUE);
        free(dstRasterP);
        return 0;
    }

    jlen = (*env)->GetArrayLength(env, jtableArrays);

    lut_nbands = jlen;
    src_nbands = srcRasterP->numBands;
    dst_nbands = dstRasterP->numBands;

    /* adjust number of lookup bands */
    if (lut_nbands > src_nbands) {
        lut_nbands = src_nbands;
    }

    /* MediaLib can't do more than 4 bands */
    if (src_nbands <= 0 || src_nbands > 4 ||
        dst_nbands <= 0 || dst_nbands > 4 ||
        lut_nbands <= 0 || lut_nbands > 4 ||
        src_nbands != dst_nbands ||
        ((lut_nbands != 1) && (lut_nbands != src_nbands)))
    {
        // we should free parsed rasters here
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }

    /* Allocate the raster arrays */
    if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE) < 0) {
        /* Must be some problem */
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }
    if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE) < 0) {
        /* Must be some problem */
        freeDataArray(env, srcRasterP->jdata, src, sdata, NULL, NULL, NULL);
        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }

    /*
     * Well, until now we have analyzed number of bands in
     * src and dst rasters.
     * However, it is not enough because medialib lookup routine uses
     * number of channels of medialib image. Note that in certain
     * case number of channels may differs form the number of bands.
     * Good example is raster that is used in TYPE_INT_RGB buffered
     * image: it has 3 bands, but their medialib representation has
     * 4 channels.
     *
     * In order to avoid the lookup routine failure, we need:
     *
     * 1. verify that src and dst have same number of channels.
     * 2. provide lookup array for every channel. If we have "extra"
     *    channel (like the raster described above) then we need to
     *    provide identical lookup array.
     */
    if (src->channels != dst->channels) {
        freeDataArray(env, srcRasterP->jdata, src, sdata,
                      dstRasterP->jdata, dst, ddata);

        awt_freeParsedRaster(srcRasterP, TRUE);
        awt_freeParsedRaster(dstRasterP, TRUE);
        return 0;
    }

    if (src_nbands < src->channels) {
        for (i = 0; i < 256; i++) {
            ilut[i] = i;
        }
    }


    /* Get references to the lookup table arrays */
    /* Need to grab these pointers before we lock down arrays */
    for (i=0; i < lut_nbands; i++) {
        jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
        jtable[i].table = NULL;
        if (jtable[i].jArray != NULL) {
            jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
            if (jtable[i].length < 256) {
                 /* we may read outside the table during lookup */
                jtable[i].jArray = NULL;
            }
        }

        if (jtable[i].jArray == NULL)
        {
            freeDataArray(env, srcRasterP->jdata, src, sdata,
                          dstRasterP->jdata, dst, ddata);

            awt_freeParsedRaster(srcRasterP, TRUE);
            awt_freeParsedRaster(dstRasterP, TRUE);
            return 0;
        }
    }

    for (i=0; i < lut_nbands; i++) {
        jtable[i].table = (unsigned char *)
            (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
        if (jtable[i].table == NULL) {
            /* Free what we've got so far. */
            int j;
            for (j = 0; j < i; j++) {
                (*env)->ReleasePrimitiveArrayCritical(env,
                                                      jtable[j].jArray,
                                                      (jbyte *) jtable[j].table,
                                                      JNI_ABORT);
            }
            freeDataArray(env, srcRasterP->jdata, src, sdata,
                          dstRasterP->jdata, dst, ddata);
            awt_freeParsedRaster(srcRasterP, TRUE);
            awt_freeParsedRaster(dstRasterP, TRUE);
            return 0;
        }
        mlib_lookupTable[i] = jtable[i].table;
    }

    /*
     * Medialib routine expects lookup array for each band of raster.
     * Setup the  rest of lookup arrays if supplied lookup table
     * contains single lookup array.
     */
    for (i = lut_nbands; i < src_nbands; i++) {
        mlib_lookupTable[i] = jtable[0].table;
    }

    /*
     * Setup lookup array for "extra" channels
     */
    for ( ; i < src->channels; i++) {
        mlib_lookupTable[i] = ilut;
    }

    /* Mlib needs 16bit lookuptable and must be signed! */
    if (src->type == MLIB_SHORT) {
        if (dst->type == MLIB_BYTE) {
            if (lut_nbands > 1) {
                retStatus = 0;
            } else {
                retStatus = lookupShortData(src, dst, &jtable[0]);
            }
        }
        /* How about ddata == null? */
    } else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
                                      (void **)mlib_lookupTable) != MLIB_SUCCESS)) {
        printMedialibError(status);
        retStatus = 0;
    }

    /* Release the LUT */
    for (i=0; i < lut_nbands; i++) {
        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
                                              (jbyte *) jtable[i].table, JNI_ABORT);
    }

    /*
     * Means that we couldn't write directly into
     * the destination buffer
     */
    if (ddata == NULL) {
        if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
        }
    }

    /* Release the pinned memory */
    freeDataArray(env, srcRasterP->jdata, src, sdata,
                  dstRasterP->jdata, dst, ddata);

    awt_freeParsedRaster(srcRasterP, TRUE);
    awt_freeParsedRaster(dstRasterP, TRUE);

    if (s_timeIt) (*stop_timer)(3600, 1);

    return retStatus;
}


JNIEXPORT jboolean JNICALL
Java_sun_awt_image_ImagingLib_init(JNIEnv *env, jclass thisClass) {
    char *start;
    if (getenv("IMLIB_DEBUG")) {
        start_timer = awt_setMlibStartTimer();
        stop_timer = awt_setMlibStopTimer();
        if (start_timer && stop_timer) {
            s_timeIt = 1;
        }
    }

    if (getenv("IMLIB_PRINT")) {
        s_printIt = 1;
    }
    if ((start = getenv("IMLIB_START")) != NULL) {
        sscanf(start, "%d", &s_startOff);
    }

    if (getenv ("IMLIB_NOMLIB")) {
        s_nomlib = 1;
        return JNI_FALSE;
    }

    /* This function is platform-dependent and is in awt_mlib.c */
    if (awt_getImagingLib(env, (mlibFnS_t *)&sMlibFns, &sMlibSysFns) !=
        MLIB_SUCCESS)
    {
        s_nomlib = 1;
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

/* REMIND: How to specify border? */
static void extendEdge(JNIEnv *env, BufImageS_t *imageP,
                       int *widthP, int *heightP) {
    RasterS_t *rasterP = &imageP->raster;
    int width;
    int height;
    /* Useful for convolution? */

    jobject jbaseraster = (*env)->GetObjectField(env, rasterP->jraster,
                                                 g_RasterBaseRasterID);
    width = rasterP->width;
    height = rasterP->height;
#ifdef WORKING
    if (! JNU_IsNull(env, jbaseraster) &&
        !(*env)->IsSameObject(env, rasterP->jraster, jbaseraster)) {
        int xOff;
        int yOff;
        int baseWidth;
        int baseHeight;
        int baseXoff;
        int baseYoff;
        /* Not the same object so get the width and height */
        xOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterXOffsetID);
        yOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterYOffsetID);
        baseWidth  = (*env)->GetIntField(env, jbaseraster, g_RasterWidthID);
        baseHeight = (*env)->GetIntField(env, jbaseraster, g_RasterHeightID);
        baseXoff   = (*env)->GetIntField(env, jbaseraster, g_RasterXOffsetID);
        baseYoff   = (*env)->GetIntField(env, jbaseraster, g_RasterYOffsetID);

        if (xOff + rasterP->width < baseXoff + baseWidth) {
            /* Can use edge */
            width++;
        }
        if (yOff + rasterP->height < baseYoff + baseHeight) {
            /* Can use edge */
            height++;
        }

    }
#endif

}

static int
setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
              int expandICM, int useAlpha,
              int premultiply, mlibHintS_t *hintP)
{
    ColorModelS_t *srcCMP = &srcP->cmodel;
    ColorModelS_t *dstCMP = &dstP->cmodel;
    int nbands = 0;
    int ncomponents;

    hintP->dataType = srcP->raster.dataType;
    hintP->addAlpha = FALSE;

    /* Are the color spaces the same? */
    if (srcCMP->csType != dstCMP->csType) {
        /* If the src is GRAY and dst RGB, we can handle it */
        if (!(srcCMP->csType == java_awt_color_ColorSpace_TYPE_GRAY &&
              dstCMP->csType == java_awt_color_ColorSpace_TYPE_RGB)) {
            /* Nope, need to handle that in java for now */
            return -1;
        }
        else {
            hintP->cvtSrcToDefault = TRUE;
        }
    }
    else {
        if (srcP->hints.needToExpand) {
            hintP->cvtSrcToDefault = TRUE;
        }
        else {
            /* Need to initialize this */
            hintP->cvtSrcToDefault = FALSE;
        }
    }

    ncomponents = srcCMP->numComponents;
    if ((useAlpha == 0) && srcCMP->supportsAlpha) {
        ncomponents--;  /* ?? */
        /* Not really, more like shrink src to get rid of alpha */
        hintP->cvtSrcToDefault = TRUE;
    }

    hintP->dataType = srcP->raster.dataType;
    if (hintP->cvtSrcToDefault == FALSE) {
        if (srcCMP->cmType == INDEX_CM_TYPE) {
            if (expandICM) {
                nbands = srcCMP->numComponents;
                hintP->cvtSrcToDefault = TRUE;

                if (dstCMP->isDefaultCompatCM) {
                    hintP->allocDefaultDst = FALSE;
                    hintP->cvtToDst = FALSE;
                }
                else if (dstCMP->isDefaultCompatCM) {
                    hintP->allocDefaultDst = FALSE;
                    hintP->cvtToDst = FALSE;
                }
            }
            else {
                nbands = 1;
                hintP->cvtSrcToDefault = FALSE;
            }

        }
        else {
            if (srcP->hints.packing & INTERLEAVED) {
                nbands = srcCMP->numComponents;
            }
            else {
                nbands = 1;
            }

            /* Look at the packing */
            if ((srcP->hints.packing&BYTE_INTERLEAVED)==BYTE_INTERLEAVED ||
                (srcP->hints.packing&SHORT_INTERLEAVED)==SHORT_INTERLEAVED||
                (srcP->hints.packing&BYTE_SINGLE_BAND) == BYTE_SINGLE_BAND||
                (srcP->hints.packing&SHORT_SINGLE_BAND)==SHORT_SINGLE_BAND||
                (srcP->hints.packing&BYTE_BANDED)  == BYTE_BANDED       ||
                (srcP->hints.packing&SHORT_BANDED) == SHORT_BANDED) {
                /* Can use src directly */
                hintP->cvtSrcToDefault = FALSE;
            }
            else {
                /* Must be packed or custom */
                hintP->cvtSrcToDefault = TRUE;
            }
        }
    }
    if (hintP->cvtSrcToDefault) {
        /* By definition */
        nbands = 4;  /* What about alpha? */
        hintP->dataType = BYTE_DATA_TYPE;
        hintP->needToCopy = TRUE;

        if (srcP->imageType == dstP->imageType) {
            hintP->cvtToDst = TRUE;
        }
        else if (dstP->cmodel.isDefaultCM) {
            /* Not necessarily */
            hintP->cvtToDst = FALSE;
        }
        else {
            hintP->cvtToDst = TRUE;
        }
    }
    else {
        int srcImageType = srcP->imageType;
        int dstImageType = dstP->imageType;
        /* Special case where we need to fill in alpha values */
        if (srcCMP->isDefaultCompatCM && dstCMP->isDefaultCompatCM) {
            int i;
            if (!srcCMP->supportsAlpha &&dstCMP->supportsAlpha) {
                hintP->addAlpha = TRUE;
            }
            for (i=0; i < srcCMP->numComponents; i++) {
                if (srcP->hints.colorOrder[i] != dstP->hints.colorOrder[i]){
                    if (!srcCMP->isDefaultCM) {
                        hintP->cvtSrcToDefault = TRUE;
                        srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
                    }
                    if (!dstCMP->isDefaultCM) {
                        hintP->cvtToDst = TRUE;
                        dstImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
                    }

                    break;
                }
            }
        }
        else if (srcCMP->cmType != INDEX_CM_TYPE &&
                 !srcCMP->supportsAlpha && dstCMP->supportsAlpha)
        {
            /* We've already handled the index case.  This is for the rest of the cases */
            srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB;
            hintP->cvtSrcToDefault = TRUE;
        }

        hintP->allocDefaultDst = FALSE;
        if (srcImageType == dstImageType) {
            /* Same image type so use it */
            hintP->cvtToDst = FALSE;
        }
        else if (srcImageType == TYPE_INT_RGB &&
                 (dstImageType == TYPE_INT_ARGB ||
                  dstImageType == TYPE_INT_ARGB_PRE)) {
            hintP->cvtToDst = FALSE;
        }
        else if (srcImageType == TYPE_INT_BGR &&
                 (dstImageType == TYPE_4BYTE_ABGR ||
                  dstImageType == TYPE_4BYTE_ABGR_PRE)) {
            hintP->cvtToDst = FALSE;
        }
        else if (srcP->hints.packing == dstP->hints.packing) {
            /* Now what? */

            /* Check color order */

            /* Check if just need to scale the data */

            hintP->cvtToDst = TRUE;
        }
        else {
            /* Don't know what it is so convert it */
            hintP->allocDefaultDst = TRUE;
            hintP->cvtToDst = TRUE;
        }
        hintP->needToCopy = (ncomponents > nbands);
    }

    return nbands;
}


static int
expandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP,
             RasterS_t *rasterP, int component, unsigned char *bdataP) {

    if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
        switch (rasterP->dataType) {
        case BYTE_DATA_TYPE:
            if (expandPackedBCR(env, rasterP, component, bdataP) < 0) {
                /* Must have been an error */
                return -1;
            }
            break;

        case SHORT_DATA_TYPE:
            if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
                /* Must have been an error */
                return -1;
            }
            break;

        case INT_DATA_TYPE:
            if (expandPackedICR(env, rasterP, component, bdataP) < 0) {
                /* Must have been an error */
                return -1;
            }
            break;

        default:
            /* REMIND: Return some sort of error */
            return -1;
        }
    }
    else {
        /* REMIND: Return some sort of error */
        return -1;
    }

    return 0;
}

#define NUM_LINES    10

static int
cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component,
                   unsigned char *dataP) {
    const RasterS_t *rasterP = &imageP->raster;
    const int w = rasterP->width;
    const int h = rasterP->height;

    int y;
    jintArray jpixels = NULL;
    jint *pixels;
    unsigned char *dP = dataP;
    int numLines = h > NUM_LINES ? NUM_LINES : h;

    /* it is safe to calculate the scan length, because width has been verified
     * on creation of the mlib image
     */
    const int scanLength = w * 4;

    int nbytes = 0;
    if (!SAFE_TO_MULT(numLines, scanLength)) {
        return -1;
    }

    nbytes = numLines * scanLength;

    jpixels = (*env)->NewIntArray(env, nbytes);
    if (JNU_IsNull(env, jpixels)) {
        (*env)->ExceptionClear(env);
        JNU_ThrowOutOfMemoryError(env, "Out of Memory");
        return -1;
    }

    for (y = 0; y < h; y += numLines) {
        if (y + numLines > h) {
            numLines = h - y;
            nbytes = numLines * scanLength;
        }

        (*env)->CallObjectMethod(env, imageP->jimage,
                                 g_BImgGetRGBMID, 0, y,
                                 w, numLines,
                                 jpixels, 0, w);
        if ((*env)->ExceptionOccurred(env)) {
            (*env)->DeleteLocalRef(env, jpixels);
            return -1;
        }

        pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
        if (pixels == NULL) {
            (*env)->DeleteLocalRef(env, jpixels);
            return -1;
        }

        memcpy(dP, pixels, nbytes);
        dP += nbytes;

        (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels,
                                              JNI_ABORT);
    }

    /* Need to release the array */
    (*env)->DeleteLocalRef(env, jpixels);

    return 0;
}

static int
cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component,
                   unsigned char *dataP) {
    const RasterS_t *rasterP = &imageP->raster;
    const int w = rasterP->width;
    const int h = rasterP->height;

    int y;
    jintArray jpixels = NULL;
    jint *pixels;
    unsigned char *dP = dataP;
    int numLines = h > NUM_LINES ? NUM_LINES : h;

    /* it is safe to calculate the scan length, because width has been verified
     * on creation of the mlib image
     */
    const int scanLength = w * 4;

    int nbytes = 0;
    if (!SAFE_TO_MULT(numLines, scanLength)) {
        return -1;
    }

    nbytes = numLines * scanLength;

    jpixels = (*env)->NewIntArray(env, nbytes);
    if (JNU_IsNull(env, jpixels)) {
        (*env)->ExceptionClear(env);
        JNU_ThrowOutOfMemoryError(env, "Out of Memory");
        return -1;
    }

    for (y = 0; y < h; y += numLines) {
        if (y + numLines > h) {
            numLines = h - y;
            nbytes = numLines * scanLength;
        }

        pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL);
        if (pixels == NULL) {
            (*env)->DeleteLocalRef(env, jpixels);
            return -1;
        }

        memcpy(pixels, dP, nbytes);
        dP += nbytes;

       (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, 0);

       (*env)->CallVoidMethod(env, imageP->jimage, g_BImgSetRGBMID, 0, y,
                                w, numLines, jpixels,
                                0, w);
       if ((*env)->ExceptionOccurred(env)) {
           (*env)->DeleteLocalRef(env, jpixels);
           return -1;
       }
    }

    /* Need to release the array */
    (*env)->DeleteLocalRef(env, jpixels);

    return 0;
}

static int
allocateArray(JNIEnv *env, BufImageS_t *imageP,
              mlib_image **mlibImagePP, void **dataPP, int isSrc,
              int cvtToDefault, int addAlpha) {
    void *dataP;
    unsigned char *cDataP;
    RasterS_t *rasterP = &imageP->raster;
    ColorModelS_t *cmP = &imageP->cmodel;
    int dataType = BYTE_DATA_TYPE;
    int width;
    int height;
    HintS_t *hintP = &imageP->hints;
    *dataPP = NULL;

    width = rasterP->width;
    height = rasterP->height;

    /* Useful for convolution? */
    /* This code is zero'ed out so that it cannot be called */

    /* To do this correctly, we need to expand src and dst in the     */
    /* same direction up/down/left/right only if both can be expanded */
    /* in that direction.  Expanding right and down is easy -         */
    /* increment width.  Expanding top and left requires bumping      */
    /* around pointers and incrementing the width/height              */

#if 0
    if (0 && useEdges) {
        baseWidth  = rasterP->baseRasterWidth;
        baseHeight = rasterP->baseRasterHeight;
        baseXoff = rasterP->baseOriginX;
        baseYoff = rasterP->baseOriginY;

        if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
            /* Can use edge */
            width++;
        }
        if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
            /* Can use edge */
            height++;
        }

        if (rasterP->minX > baseXoff ) {
            /* Can use edge */
            width++;
            /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
        }
        if (rasterP->minY  > baseYoff) {
            /* Can use edge */
            height++;
            /* NEED TO BUMP POINTER BACK A SCANLINE */
        }


    }
#endif
    if (cvtToDefault) {
        int status = 0;
        *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
        if (*mlibImagePP == NULL) {
            return -1;
        }
        cDataP  = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
        /* Make sure the image is cleared.
         * NB: the image dimension is already verified, so we can
         * safely calculate the length of the buffer.
         */
        memset(cDataP, 0, width*height*4);

        if (!isSrc) {
            return 0;
        }

        switch(imageP->cmodel.cmType) {
        case INDEX_CM_TYPE:
            /* REMIND: Need to rearrange according to dst cm */
            /* Fix 4213160, 4184283 */
            if (rasterP->rasterType == COMPONENT_RASTER_TYPE) {
                return expandICM(env, imageP, (unsigned int *)cDataP);
            }
            else {
                return cvtCustomToDefault(env, imageP, -1, cDataP);
            }

        case DIRECT_CM_TYPE:
            switch(imageP->raster.dataType) {
            case BYTE_DATA_TYPE:
                return expandPackedBCRdefault(env, rasterP, -1, cDataP,
                                              !imageP->cmodel.supportsAlpha);
            case SHORT_DATA_TYPE:
                return expandPackedSCRdefault(env, rasterP, -1, cDataP,
                                              !imageP->cmodel.supportsAlpha);
            case INT_DATA_TYPE:
                return expandPackedICRdefault(env, rasterP, -1, cDataP,
                                              !imageP->cmodel.supportsAlpha);
            }
        } /* switch(imageP->cmodel.cmType) */

        return cvtCustomToDefault(env, imageP, -1, cDataP);
    }

    /* Interleaved with shared data */
    dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
                                                       NULL);
    if (dataP == NULL) {
        return -1;
    }

    /* Means we need to fill in alpha */
    if (!cvtToDefault && addAlpha) {
        *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
        if (*mlibImagePP != NULL) {
            unsigned int *dstP  = (unsigned int *)
                mlib_ImageGetData(*mlibImagePP);
            int dstride = (*mlibImagePP)->stride>>2;
            int sstride = hintP->sStride>>2;
            unsigned int *srcP = (unsigned int *)
                ((unsigned char *)dataP + hintP->dataOffset);
            unsigned int *dP, *sP;
            int x, y;
            for (y=0; y < height; y++, srcP += sstride, dstP += dstride){
                sP = srcP;
                dP = dstP;
                for (x=0; x < width; x++) {
                    dP[x] = sP[x] | 0xff000000;
                }
            }
        }
        (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
                                              JNI_ABORT);
        return 0;
    }
    else if ((hintP->packing & BYTE_INTERLEAVED) == BYTE_INTERLEAVED) {
        int nChans = (cmP->isDefaultCompatCM ? 4 : hintP->numChans);
        /* Easy case.  It is or is similar to the default CM so use
     * the array.  Must be byte data.
         */
            /* Create the medialib image */
        *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE,
                                              nChans,
                                              width,
                                              height,
                                              hintP->sStride,
                                              (unsigned char *)dataP
                                              + hintP->dataOffset);
    }
    else if ((hintP->packing & SHORT_INTERLEAVED) == SHORT_INTERLEAVED) {
        *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
                                              hintP->numChans,
                                              width,
                                              height,
                                              imageP->raster.scanlineStride*2,
                                              (unsigned short *)dataP
                                              + hintP->channelOffset);
    }
    else {
        /* Release the data array */
        (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
                                              JNI_ABORT);
        return -1;
    }

    *dataPP = dataP;
    return 0;
}

static int
allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
                    mlib_image **mlibImagePP, void **dataPP, int isSrc) {
    void *dataP;
    unsigned char *cDataP;
    int dataType = BYTE_DATA_TYPE;
    int width;
    int height;
    int dataSize;
    int offset;

    *dataPP = NULL;

    width = rasterP->width;
    height = rasterP->height;

    if (rasterP->numBands <= 0 || rasterP->numBands > 4) {
        /* REMIND: Fix this */
        return -1;
    }

    /* Useful for convolution? */
    /* This code is zero'ed out so that it cannot be called */

    /* To do this correctly, we need to expand src and dst in the     */
    /* same direction up/down/left/right only if both can be expanded */
    /* in that direction.  Expanding right and down is easy -         */
    /* increment width.  Expanding top and left requires bumping      */
    /* around pointers and incrementing the width/height              */

#if 0
    if (0 && useEdges) {
        baseWidth  = rasterP->baseRasterWidth;
        baseHeight = rasterP->baseRasterHeight;
        baseXoff = rasterP->baseOriginX;
        baseYoff = rasterP->baseOriginY;

        if (rasterP->minX + rasterP->width < baseXoff + baseWidth) {
            /* Can use edge */
            width++;
        }
        if (rasterP->minY + rasterP->height < baseYoff + baseHeight) {
            /* Can use edge */
            height++;
        }

        if (rasterP->minX > baseXoff ) {
            /* Can use edge */
            width++;
            /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */
        }
        if (rasterP->minY  > baseYoff) {
            /* Can use edge */
            height++;
            /* NEED TO BUMP POINTER BACK A SCANLINE */
        }


    }
#endif
    switch (rasterP->type) {
    case sun_awt_image_IntegerComponentRaster_TYPE_INT_8BIT_SAMPLES:
        if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 4)) &&
              SAFE_TO_ALLOC_2(width, 4) &&
              SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 4)))
        {
            return -1;
        }
        offset = 4 * rasterP->chanOffsets[0];
        dataSize = 4 * (*env)->GetArrayLength(env, rasterP->jdata);

        if (offset < 0 || offset >= dataSize ||
            width > rasterP->scanlineStride ||
            height * rasterP->scanlineStride * 4 > dataSize - offset)
        {
            // raster data buffer is too short
            return -1;
        }
        dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
                                                           NULL);
        if (dataP == NULL) {
            return -1;
        }
        *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, 4,
                                              width, height,
                                              rasterP->scanlineStride*4,
                                              (unsigned char *)dataP + offset);
        *dataPP = dataP;
        return 0;
    case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES:
        if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands) &&
              SAFE_TO_ALLOC_2(height, rasterP->scanlineStride)))
        {
            return -1;
        }
        offset = rasterP->chanOffsets[0];
        dataSize = (*env)->GetArrayLength(env, rasterP->jdata);

        if (offset < 0 || offset >= dataSize ||
            width * rasterP->numBands > rasterP->scanlineStride ||
            height * rasterP->scanlineStride > dataSize - offset)
        {
            // raster data buffer is too short
            return -1;
        }
        dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
                                                           NULL);
        if (dataP == NULL) {
            return -1;
        }
        *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, rasterP->numBands,
                                              width, height,
                                              rasterP->scanlineStride,
                                              (unsigned char *)dataP + offset);
        *dataPP = dataP;
        return 0;
    case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_SAMPLES:
        if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 2)) &&
              SAFE_TO_ALLOC_3(width, rasterP->numBands, 2) &&
              SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 2)))
        {
              return -1;
        }
        offset = rasterP->chanOffsets[0] * 2;
        dataSize = 2 * (*env)->GetArrayLength(env, rasterP->jdata);

        if (offset < 0 || offset >= dataSize ||
            width * rasterP->numBands > rasterP->scanlineStride ||
            height * rasterP->scanlineStride * 2 > dataSize - offset)
        {
            // raster data buffer is too short
             return -1;
        }
        dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata,
                                                           NULL);
        if (dataP == NULL) {
            return -1;
        }
        *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT,
                                                     rasterP->numBands,
                                                     width, height,
                                                     rasterP->scanlineStride*2,
                                                     (unsigned char *)dataP + offset);
        *dataPP = dataP;
        return 0;

    case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
        *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
                                        width, height);
        if (*mlibImagePP == NULL) {
            return -1;
        }
        if (!isSrc) return 0;
        cDataP  = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
        return expandPackedBCR(env, rasterP, -1, cDataP);

    case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
        if (rasterP->sppsm.maxBitSize <= 8) {
            *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
                                            width, height);
            if (*mlibImagePP == NULL) {
                return -1;
            }
            if (!isSrc) return 0;
            cDataP  = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
            return expandPackedSCR(env, rasterP, -1, cDataP);
        }
        break;
    case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
        if (rasterP->sppsm.maxBitSize <= 8) {
            *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
                                            width, height);
            if (*mlibImagePP == NULL) {
                return -1;
            }
            if (!isSrc) return 0;
            cDataP  = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
            return expandPackedICR(env, rasterP, -1, cDataP);
        }
        break;
    }

    /* Just expand it right now */
    switch (rasterP->dataType) {
    case BYTE_DATA_TYPE:
        if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
                                             width, height)) == NULL) {
            return -1;
        }
        if (isSrc) {
            if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) {
                (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
                return -1;
            }
        }
        break;

    case SHORT_DATA_TYPE:
        if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_SHORT,
                                                    rasterP->numBands,
                                                    width, height)) == NULL) {
            return -1;
        }
        if (isSrc) {
            if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) {
                (*sMlibSysFns.deleteImageFP)(*mlibImagePP);
                return -1;
            }
        }
        break;

    default:
        return -1;
    }
    return 0;
}

static void
freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP,
          void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP,
          void *dstdataP) {
    jobject srcJdata = (srcimageP != NULL ? srcimageP->raster.jdata : NULL);
    jobject dstJdata = (dstimageP != NULL ? dstimageP->raster.jdata : NULL);
    freeDataArray(env, srcJdata, srcmlibImP, srcdataP,
                  dstJdata, dstmlibImP, dstdataP);
}
static void
freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP,
          void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP,
          void *dstdataP)
{
    /* Free the medialib image */
    if (srcmlibImP) {
        (*sMlibSysFns.deleteImageFP)(srcmlibImP);
    }

    /* Release the array */
    if (srcdataP) {
        (*env)->ReleasePrimitiveArrayCritical(env, srcJdata,
                                              srcdataP, JNI_ABORT);
    }

    /* Free the medialib image */
    if (dstmlibImP) {
        (*sMlibSysFns.deleteImageFP)(dstmlibImP);
    }

    /* Release the array */
    if (dstdataP) {
        (*env)->ReleasePrimitiveArrayCritical(env, dstJdata,
                                              dstdataP, 0);
    }
}

#define ERR_BAD_IMAGE_LAYOUT (-2)

#define CHECK_DST_ARRAY(start_offset, elements_per_scan, elements_per_pixel) \
    do {                                                                     \
        int offset = (start_offset);                                         \
        int lastScanOffset;                                                  \
                                                                             \
        if (!SAFE_TO_MULT((elements_per_scan),                               \
                          (rasterP->height - 1)))                            \
        {                                                                    \
            return ERR_BAD_IMAGE_LAYOUT;                                     \
        }                                                                    \
        lastScanOffset = (elements_per_scan) * (rasterP->height - 1);        \
                                                                             \
        if (!SAFE_TO_ADD(offset, lastScanOffset)) {                          \
            return ERR_BAD_IMAGE_LAYOUT;                                     \
        }                                                                    \
        lastScanOffset += offset;                                            \
                                                                             \
        if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) {           \
            return ERR_BAD_IMAGE_LAYOUT;                                     \
        }                                                                    \
        offset = (elements_per_pixel) * rasterP->width;                      \
                                                                             \
        if (!SAFE_TO_ADD(offset, lastScanOffset)) {                          \
            return ERR_BAD_IMAGE_LAYOUT;                                     \
        }                                                                    \
        lastScanOffset += offset;                                            \
                                                                             \
        if (dataArrayLength < lastScanOffset) {                              \
            return ERR_BAD_IMAGE_LAYOUT;                                     \
        }                                                                    \
    } while(0);                                                              \

static int
storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
                mlib_image *mlibImP) {
    int mStride;
    unsigned char *cmDataP, *dataP, *cDataP;
    HintS_t *hintP = &dstP->hints;
    RasterS_t *rasterP = &dstP->raster;
    jsize dataArrayLength = (*env)->GetArrayLength(env, rasterP->jdata);
    int y;

    /* REMIND: Store mlib data type? */

    /* Check if it is an IndexColorModel */
    if (dstP->cmodel.cmType == INDEX_CM_TYPE) {
        if (dstP->raster.rasterType == COMPONENT_RASTER_TYPE) {
            return storeICMarray(env, srcP, dstP, mlibImP);
        }
        else {
            /* Packed or some other custom raster */
            cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
            return cvtDefaultToCustom(env, dstP, -1, cmDataP);
        }
    }

    if (hintP->packing == BYTE_INTERLEAVED) {
        /* Write it back to the destination */
        if (rasterP->dataType != BYTE_DATA_TYPE) {
            /* We are working with a raster which was marked
               as a byte interleaved due to performance reasons.
               So, we have to convert the length of the data
               array to bytes as well.
            */
            if (!SAFE_TO_MULT(rasterP->dataSize, dataArrayLength)) {
                return ERR_BAD_IMAGE_LAYOUT;
            }
            dataArrayLength *= rasterP->dataSize;
        }

        CHECK_DST_ARRAY(hintP->dataOffset, hintP->sStride, hintP->numChans);
        cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
        mStride = mlib_ImageGetStride(mlibImP);
        dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env,
                                                      rasterP->jdata, NULL);
        if (dataP == NULL) return 0;
        cDataP = dataP + hintP->dataOffset;
        for (y=0; y < rasterP->height;
             y++, cmDataP += mStride, cDataP += hintP->sStride)
        {
            memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans);
        }
        (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
                                              JNI_ABORT);
    }
    else if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
        /* Just need to move bits */
        if (mlibImP->type == MLIB_BYTE) {
            if (dstP->hints.packing == PACKED_BYTE_INTER) {
                return setPackedBCRdefault(env, rasterP, -1,
                                           (unsigned char *) mlibImP->data,
                                           dstP->cmodel.supportsAlpha);
            } else if (dstP->hints.packing == PACKED_SHORT_INTER) {
                return setPackedSCRdefault(env, rasterP, -1,
                                           (unsigned char *) mlibImP->data,
                                           dstP->cmodel.supportsAlpha);
            } else if (dstP->hints.packing == PACKED_INT_INTER) {
                return setPackedICRdefault(env, rasterP, -1,
                                           (unsigned char *) mlibImP->data,
                                           dstP->cmodel.supportsAlpha);
            }
        }
        else if (mlibImP->type == MLIB_SHORT) {
            return setPixelsFormMlibImage(env, rasterP, mlibImP);
        }
    }
    else {
        return cvtDefaultToCustom(env, dstP, -1,
                                  (unsigned char *)mlibImP->data);
    }

    return 0;
}

static int
storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP,
                mlib_image *mlibImP) {
    unsigned char *cDataP;

    switch(dstP->type) {
    case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
        cDataP  = (unsigned char *) mlib_ImageGetData(mlibImP);
        return setPackedBCR(env, dstP, -1, cDataP);

    case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES:
        if (dstP->sppsm.maxBitSize <= 8) {
            cDataP  = (unsigned char *) mlib_ImageGetData(mlibImP);
            return setPackedSCR(env, dstP, -1, cDataP);
        }
        break;
    case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES:
        if (dstP->sppsm.maxBitSize <= 8) {
            cDataP  = (unsigned char *) mlib_ImageGetData(mlibImP);
            return setPackedICR(env, dstP, -1, cDataP);
        }
    }

    return -1;
}


static int
storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
              mlib_image *mlibImP)
{
    int *argb;
    int x, y;
    unsigned char *dataP, *cDataP, *cP;
    unsigned char *sP;
    int aIdx, rIdx, gIdx, bIdx;
    ColorModelS_t *cmodelP = &dstP->cmodel;
    RasterS_t *rasterP = &dstP->raster;

    /* REMIND: Only works for RGB */
    if (cmodelP->csType != java_awt_color_ColorSpace_TYPE_RGB) {
        JNU_ThrowInternalError(env, "Writing to non-RGB images not implemented yet");
        return -1;
    }

    if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB ||
        srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE ||
        srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB)
    {
        aIdx = 0;
        rIdx = 1;
        gIdx = 2;
        bIdx = 3;
    }
    else if (srcP->imageType ==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR||
        srcP->imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE)
    {
        aIdx = 0;
        rIdx = 3;
        gIdx = 2;
        bIdx = 1;
    }
    else if (srcP->imageType == java_awt_image_BufferedImage_TYPE_3BYTE_BGR){
        rIdx = 2;
        gIdx = 1;
        bIdx = 0;
        aIdx = 0;       /* Ignored */
    }
    else if (srcP->cmodel.cmType == INDEX_CM_TYPE) {
        rIdx = 0;
        gIdx = 1;
        bIdx = 2;
        aIdx = 3;   /* Use supportsAlpha to see if it is really there */
    }
    else {
        return -1;
    }

    /* Lock down the destination raster */
    dataP = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env,
                                                  rasterP->jdata, NULL);
    if (dataP == NULL) {
        return -1;
    }
    argb = (*env)->GetPrimitiveArrayCritical(env, cmodelP->jrgb, NULL);
    if (argb == NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
                                              JNI_ABORT);
        return -1;
    }

    cDataP = dataP + dstP->hints.dataOffset;
    sP = (unsigned char *) mlib_ImageGetData(mlibImP);

    for (y=0; y < rasterP->height; y++, cDataP += rasterP->scanlineStride) {
        cP = cDataP;
        for (x=0; x < rasterP->width; x++, cP += rasterP->pixelStride) {
            *cP = colorMatch(sP[rIdx], sP[gIdx], sP[bIdx], sP[aIdx],
                             (unsigned char *)argb, cmodelP->mapSize);
            sP += cmodelP->numComponents;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, cmodelP->jrgb, argb, JNI_ABORT);
    (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
                                          JNI_ABORT);
    return -1;
}

static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP)
{
    ColorModelS_t *cmP = &imageP->cmodel;
    RasterS_t *rasterP = &imageP->raster;
    HintS_t *hintP     = &imageP->hints;
    int *rgb;
    int status = 0;
    unsigned char *dataP, *cP;
    unsigned int *mP;
    int width = rasterP->width;
    int height = rasterP->height;
    int x, y;

    /* Need to grab the lookup tables.  Right now only bytes */
    rgb = (int *) (*env)->GetPrimitiveArrayCritical(env, cmP->jrgb, NULL);
    CHECK_NULL_RETURN(rgb, -1);

    /* Interleaved with shared data */
    dataP = (void *) (*env)->GetPrimitiveArrayCritical(env,
                                                       rasterP->jdata, NULL);
    if (dataP == NULL) {
        /* Release the lookup tables */
        (*env)->ReleasePrimitiveArrayCritical(env, cmP->jrgb, rgb, JNI_ABORT);
        return -1;
    }

    if (rasterP->dataType == BYTE_DATA_TYPE) {
        unsigned char *cDataP = ((unsigned char *)dataP) + hintP->dataOffset;

        for (y=0; y < height; y++) {
            mP = mDataP;
            cP = cDataP;
            for (x=0; x < width; x++, cP += rasterP->pixelStride) {
                *mP++ = rgb[*cP];
            }
            mDataP += width;
            cDataP += rasterP->scanlineStride;
        }
    }
    else if (rasterP->dataType == SHORT_DATA_TYPE) {
        unsigned short *sDataP, *sP;
        sDataP = ((unsigned short *)dataP) + hintP->channelOffset;

        for (y=0; y < height; y++) {
            mP = mDataP;
            sP = sDataP;
            for (x=0; x < width; x++, sP+=rasterP->pixelStride) {
                *mP++ = rgb[*sP];
            }
            mDataP += width;
            sDataP += rasterP->scanlineStride;
        }
    }
    else {
        /* Unknown type */
        status = -1;
    }
    /* Release the lookup table data */
    (*env)->ReleasePrimitiveArrayCritical(env, imageP->cmodel.jrgb,
                                          rgb, JNI_ABORT);
    /* Release the data array */
    (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata,
                                          dataP, JNI_ABORT);
    return status;
}
/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned char *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned char *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }
        /* Convert the all bands */
        if (rasterP->numBands < 4) {
            /* Need to put in alpha */
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)
                    ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned char *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
    int a = numBands;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned char *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }

        /* Need to put in alpha */
        if (forceAlpha) {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = 0xff;
                    for (c=0; c < numBands; c++) {
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = (unsigned char)
                        (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
                         <<loff[a]);
                    for (c=0; c < numBands; c++) {
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)
                    ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned short *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned short *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }
        /* Convert the all bands */
        if (rasterP->numBands < 4) {
            /* Need to put in alpha */
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        /*
                         *Not correct.  Might need to unpremult,
                         * shift, etc
                         */
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        } else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        /*
                         *Not correct.  Might need to unpremult,
                         * shift, etc
                         */
                        *outP++ = (unsigned char)
                            (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                             <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)
                    ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned short *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
    int a = numBands;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned short *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }

        /* Need to put in alpha */
        if (forceAlpha) {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = 0xff;
                    for (c=0; c < numBands; c++) {
                        /*
                         * Not correct.  Might need to unpremult,
                         * shift, etc
                         */
                        *outP++ = (unsigned char)
                                (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = (unsigned char)
                        (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
                                   <<loff[a]);
                    for (c=0; c < numBands; c++) {
                        /*
                         * Not correct.  Might need to
                         * unpremult, shift, etc
                         */
                        *outP++ = (unsigned char)
                                (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)
                        ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0];
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;

}

/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *outDataP)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned int *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned int *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }
        /* Convert the all bands */
        if (rasterP->numBands < 4) {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        /*
                         * Not correct.  Might need to unpremult,
                         * shift, etc
                         */
                        *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    for (c=0; c < rasterP->numBands; c++) {
                        /*
                         * Not correct.  Might need to
                         * unpremult, shift, etc
                         */
                        *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
                                  int component, unsigned char *outDataP,
                                  int forceAlpha)
{
    int x, y, c;
    unsigned char *outP = outDataP;
    unsigned int *lineInP, *inP;
    jarray jInDataP;
    jint   *inDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int numBands = rasterP->numBands - (forceAlpha ? 0 : 1);
    int a = numBands;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
    inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0);
    if (inDataP == NULL) {
        return -1;
    }
    lineInP =  (unsigned int *)inDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (roff[c] < 0) {
                loff[c] = -roff[c];
                roff[c] = 0;
            }
            else loff[c] = 0;
        }

        /* Need to put in alpha */
        if (forceAlpha) {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = 0xff;
                    for (c=0; c < numBands; c++) {
                        /*
                         * Not correct.  Might need to unpremult,
                         * shift, etc
                         */
                        *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                inP = lineInP;
                for (x=0; x < rasterP->width; x++) {
                    *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[a]) >> roff[a])
                                   <<loff[a]);
                    for (c=0; c < numBands; c++) {
                        /*
                         * Not correct.  Might need to
                         * unpremult, shift, etc
                         */
                        *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c])
                                   <<loff[c]);
                    }
                    inP++;
                }
                lineInP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (roff[0] < 0) {
            loff[0] = -roff[0];
            roff[0] = 0;
        }
        else loff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            inP = lineInP;
            for (x=0; x < rasterP->width; x++) {
                *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]);
                inP++;
            }
            lineInP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component,
                        unsigned char *inDataP)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned char *lineOutP, *outP;
    jarray jOutDataP;
    jsize dataArrayLength;
    unsigned char *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }

    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            *outP = 0;
            for (x=0; x < rasterP->width; x++) {
                for (c=0; c < rasterP->numBands; c++, inP++) {
                    *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
                }
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
static int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *inDataP)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned short *lineOutP, *outP;
    jarray jOutDataP;
    jsize dataArrayLength;
    unsigned short *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }

    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++) {
                for (c=0; c < rasterP->numBands; c++, inP++) {
                    /* Not correct.  Might need to unpremult, shift, etc */
                    *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
                }
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
static int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component,
                           unsigned char *inDataP)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned int *lineOutP, *outP;
    jarray jOutDataP;
    jsize dataArrayLength;
    unsigned int *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }

    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++) {
                for (c=0; c < rasterP->numBands; c++, inP++) {
                    /* Not correct.  Might need to unpremult, shift, etc */
                    *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
                }
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;

        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ByteComponentRaster with a PackedColorModel */
static int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *inDataP,
                               int supportsAlpha)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned char *lineOutP, *outP;
    jarray jOutDataP;
    jsize  dataArrayLength;
    unsigned char *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int a = rasterP->numBands - 1;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }

    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        if (supportsAlpha) {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                *outP = 0;
                for (x=0; x < rasterP->width; x++) {
                    *outP |= (*inP<<loff[a]>>roff[a])&
                        rasterP->sppsm.maskArray[a];
                    inP++;
                    for (c=0; c < rasterP->numBands-1; c++, inP++) {
                        *outP |= (*inP<<loff[c]>>roff[c])&
                            rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                *outP = 0;
                for (x=0; x < rasterP->width; x++) {
                    inP++;
                    for (c=0; c < rasterP->numBands; c++, inP++) {
                        *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a ShortComponentRaster with a PackedColorModel */
static int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *inDataP,
                               int supportsAlpha)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned short *lineOutP, *outP;
    jarray jOutDataP;
    jsize dataArrayLength;
    unsigned short *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int a = rasterP->numBands - 1;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }
    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        if (supportsAlpha) {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                for (x=0; x < rasterP->width; x++) {
                    *outP |= (*inP<<loff[a]>>roff[a])&
                        rasterP->sppsm.maskArray[a];
                    inP++;
                    for (c=0; c < rasterP->numBands-1; c++, inP++) {
                        /* Not correct.  Might need to unpremult, shift, etc */
                        *outP |= (*inP<<loff[c]>>roff[c])&
                            rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                for (x=0; x < rasterP->width; x++) {
                    inP++;
                    for (c=0; c < rasterP->numBands; c++, inP++) {
                        /* Not correct.  Might need to unpremult, shift, etc */
                        *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;
        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/
static int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP,
                               int component, unsigned char *inDataP,
                               int supportsAlpha)
{
    int x, y, c;
    unsigned char *inP = inDataP;
    unsigned int *lineOutP, *outP;
    jarray jOutDataP;
    jsize dataArrayLength;
    unsigned int *outDataP;
    int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
    int a = rasterP->numBands - 1;

    if (rasterP->numBands > MAX_NUMBANDS) {
        return -1;
    }

    /* Grab data ptr, strides, offsets from raster */
    jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
    if (JNU_IsNull(env, jOutDataP)) {
        return -1;
    }

    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
    CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);

    outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
    if (outDataP == NULL) {
        return -1;
    }
    lineOutP = outDataP + rasterP->chanOffsets[0];

    if (component < 0) {
        for (c=0; c < rasterP->numBands; c++) {
            loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
            if (loff[c] < 0) {
                roff[c] = -loff[c];
                loff[c] = 0;
            }
            else roff[c] = 0;
        }
        /* Convert the all bands */
        if (supportsAlpha) {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                for (x=0; x < rasterP->width; x++) {
                    *outP |= (*inP<<loff[a]>>roff[a])&
                        rasterP->sppsm.maskArray[a];
                    inP++;
                    for (c=0; c < rasterP->numBands-1; c++, inP++) {
                        /* Not correct.  Might need to unpremult, shift, etc */
                        *outP |= (*inP<<loff[c]>>roff[c])&
                            rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
        else {
            for (y=0; y < rasterP->height; y++) {
                outP = lineOutP;
                for (x=0; x < rasterP->width; x++) {
                    inP++;
                    for (c=0; c < rasterP->numBands; c++, inP++) {
                        /* Not correct.  Might need to unpremult, shift, etc */
                        *outP |= (*inP<<loff[c]>>roff[c])&
                            rasterP->sppsm.maskArray[c];
                    }
                    outP++;
                }
                lineOutP += rasterP->scanlineStride;
            }
        }
    }
    else {
        c = component;
        loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8);
        if (loff[0] < 0) {
            roff[0] = -loff[0];
            loff[0] = 0;
        }
        else roff[c] = 0;

        for (y=0; y < rasterP->height; y++) {
            outP = lineOutP;
            for (x=0; x < rasterP->width; x++, inP++) {
                *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c];
                outP++;
            }
            lineOutP += rasterP->scanlineStride;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT);

    return 0;
}

/* This is temporary code.  Should go away when there is better color
 * conversion code available.
 * REMIND:  Ignoring alpha
 */
/* returns the absolute value x */
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define CLIP(val,min,max)       ((val < min) ? min : ((val > max) ? max : val))

static int
colorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors) {
    int besti = 0;
    int mindist, i, t, d;
    unsigned char red, green, blue;

    r = CLIP(r, 0, 255);
    g = CLIP(g, 0, 255);
    b = CLIP(b, 0, 255);

    /* look for pure gray match */
    if ((r == g) && (g == b)) {
        mindist = 256;
        for (i = 0 ; i < numColors ; i++, argb+=4) {
            red = argb[1];
            green = argb[2];
            blue = argb[3];
            if (! ((red == green) && (green == blue)) ) {
                continue;
            }
            d = ABS(red - r);
            if (d == 0)
                return i;
            if (d < mindist) {
                besti = i;
                mindist = d;
            }
        }
        return besti;
    }

    /* look for non-pure gray match */
    mindist = 256 * 256 * 256;
    for (i = 0 ; i < numColors ; i++, argb+=4) {
        red = argb[1];
        green = argb[2];
        blue = argb[3];
        t = red - r;
        d = t * t;
        if (d >= mindist) {
            continue;
        }
        t = green - g;
        d += t * t;
        if (d >= mindist) {
            continue;
        }
        t = blue - b;
        d += t * t;
        if (d >= mindist) {
            continue;
        }
        if (d == 0)
            return i;
        if (d < mindist) {
            besti = i;
            mindist = d;
        }
    }

    return besti;
}
