/*
 * Copyright (c) 2000, 2007, 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.
 */

/*
 * This file contains the code to link the Java Image I/O JPEG plug-in
 * to the IJG library used to read and write JPEG files.  Much of it has
 * been copied, updated, and annotated from the jpegdecoder.c AWT JPEG
 * decoder.  Where that code was unclear, the present author has either
 * rewritten the relevant section or commented it for the sake of future
 * maintainers.
 *
 * In particular, the way the AWT code handled progressive JPEGs seems
 * to me to be only accidentally correct and somewhat inefficient.  The
 * scheme used here represents the way I think it should work. (REV 11/00)
 */

#include <stdlib.h>
#include <setjmp.h>
#include <assert.h>
#include <string.h>


/* java native interface headers */
#include "jni.h"
#include "jni_util.h"

#include "com_sun_imageio_plugins_jpeg_JPEGImageReader.h"
#include "com_sun_imageio_plugins_jpeg_JPEGImageWriter.h"

/* headers from the JPEG library */
#include <jpeglib.h>
#include "jerror.h"

#undef MAX
#define MAX(a,b)        ((a) > (b) ? (a) : (b))

/* Cached Java method ids */
static jmethodID ImageInputStream_readID;
static jmethodID ImageInputStream_skipBytesID;
static jmethodID JPEGImageReader_warningOccurredID;
static jmethodID JPEGImageReader_warningWithMessageID;
static jmethodID JPEGImageReader_setImageDataID;
static jmethodID JPEGImageReader_acceptPixelsID;
static jmethodID JPEGImageReader_pushBackID;
static jmethodID JPEGImageReader_passStartedID;
static jmethodID JPEGImageReader_passCompleteID;
static jmethodID ImageOutputStream_writeID;
static jmethodID JPEGImageWriter_warningOccurredID;
static jmethodID JPEGImageWriter_warningWithMessageID;
static jmethodID JPEGImageWriter_writeMetadataID;
static jmethodID JPEGImageWriter_grabPixelsID;
static jfieldID JPEGQTable_tableID;
static jfieldID JPEGHuffmanTable_lengthsID;
static jfieldID JPEGHuffmanTable_valuesID;

/*
 * Defined in jpegdecoder.c.  Copy code from there if and
 * when that disappears. */
extern JavaVM *jvm;

/*
 * The following sets of defines must match the warning messages in the
 * Java code.
 */

/* Reader warnings */
#define READ_NO_EOI          0

/* Writer warnings */

/* Return codes for various ops */
#define OK     1
#define NOT_OK 0

/*
 * First we define two objects, one for the stream and buffer and one
 * for pixels.  Both contain references to Java objects and pointers to
 * pinned arrays.  These objects can be used for either input or
 * output.  Pixels can be accessed as either INT32s or bytes.
 * Every I/O operation will have one of each these objects, one for
 * the stream and the other to hold pixels, regardless of the I/O direction.
 */

/******************** StreamBuffer definition ************************/

typedef struct streamBufferStruct {
    jobject stream;            // ImageInputStream or ImageOutputStream
    jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
    JOCTET *buf;               // Pinned buffer pointer */
    int bufferOffset;          // holds offset between unpin and the next pin
    int bufferLength;          // Allocated, nut just used
    int suspendable;           // Set to true to suspend input
    long remaining_skip;       // Used only on input
} streamBuffer, *streamBufferPtr;

/*
 * This buffer size was set to 64K in the old classes, 4K by default in the
 * IJG library, with the comment "an efficiently freadable size", and 1K
 * in AWT.
 * Unlike in the other Java designs, these objects will persist, so 64K
 * seems too big and 1K seems too small.  If 4K was good enough for the
 * IJG folks, it's good enough for me.
 */
#define STREAMBUF_SIZE 4096

/*
 * Used to signal that no data need be restored from an unpin to a pin.
 * I.e. the buffer is empty.
 */
#define NO_DATA -1

// Forward reference
static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb);

/*
 * Initialize a freshly allocated StreamBuffer object.  The stream is left
 * null, as it will be set from Java by setSource, but the buffer object
 * is created and a global reference kept.  Returns OK on success, NOT_OK
 * if allocating the buffer or getting a global reference for it failed.
 */
static int initStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
    /* Initialize a new buffer */
    jbyteArray hInputBuffer = (*env)->NewByteArray(env, STREAMBUF_SIZE);
    if (hInputBuffer == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
        return NOT_OK;
    }
    sb->bufferLength = (*env)->GetArrayLength(env, hInputBuffer);
    sb->hstreamBuffer = (*env)->NewGlobalRef(env, hInputBuffer);
    if (sb->hstreamBuffer == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
        return NOT_OK;
    }


    sb->stream = NULL;

    sb->buf = NULL;

    resetStreamBuffer(env, sb);

    return OK;
}

/*
 * Free all resources associated with this streamBuffer.  This must
 * be called to dispose the object to avoid leaking global references, as
 * resetStreamBuffer does not release the buffer reference.
 */
static void destroyStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
    resetStreamBuffer(env, sb);
    if (sb->hstreamBuffer != NULL) {
        (*env)->DeleteGlobalRef(env, sb->hstreamBuffer);
    }
}

// Forward reference
static void unpinStreamBuffer(JNIEnv *env,
                              streamBufferPtr sb,
                              const JOCTET *next_byte);
/*
 * Resets the state of a streamBuffer object that has been in use.
 * The global reference to the stream is released, but the reference
 * to the buffer is retained.  The buffer is unpinned if it was pinned.
 * All other state is reset.
 */
static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
    if (sb->stream != NULL) {
        (*env)->DeleteGlobalRef(env, sb->stream);
        sb->stream = NULL;
    }
    unpinStreamBuffer(env, sb, NULL);
    sb->bufferOffset = NO_DATA;
    sb->suspendable = FALSE;
    sb->remaining_skip = 0;
}

/*
 * Pins the data buffer associated with this stream.  Returns OK on
 * success, NOT_OK on failure, as GetPrimitiveArrayCritical may fail.
 */
static int pinStreamBuffer(JNIEnv *env,
                           streamBufferPtr sb,
                           const JOCTET **next_byte) {
    if (sb->hstreamBuffer != NULL) {
        assert(sb->buf == NULL);
        sb->buf =
            (JOCTET *)(*env)->GetPrimitiveArrayCritical(env,
                                                        sb->hstreamBuffer,
                                                        NULL);
        if (sb->buf == NULL) {
            return NOT_OK;
        }
        if (sb->bufferOffset != NO_DATA) {
            *next_byte = sb->buf + sb->bufferOffset;
        }
    }
    return OK;
}

/*
 * Unpins the data buffer associated with this stream.
 */
static void unpinStreamBuffer(JNIEnv *env,
                              streamBufferPtr sb,
                              const JOCTET *next_byte) {
    if (sb->buf != NULL) {
        assert(sb->hstreamBuffer != NULL);
        if (next_byte == NULL) {
            sb->bufferOffset = NO_DATA;
        } else {
            sb->bufferOffset = next_byte - sb->buf;
        }
        (*env)->ReleasePrimitiveArrayCritical(env,
                                              sb->hstreamBuffer,
                                              sb->buf,
                                              0);
        sb->buf = NULL;
    }
}

/*
 * Clear out the streamBuffer.  This just invalidates the data in the buffer.
 */
static void clearStreamBuffer(streamBufferPtr sb) {
    sb->bufferOffset = NO_DATA;
}

/*************************** end StreamBuffer definition *************/

/*************************** Pixel Buffer definition ******************/

typedef struct pixelBufferStruct {
    jobject hpixelObject;   // Usually a DataBuffer bank as a byte array
    unsigned int byteBufferLength;
    union pixptr {
        INT32         *ip;  // Pinned buffer pointer, as 32-bit ints
        unsigned char *bp;  // Pinned buffer pointer, as bytes
    } buf;
} pixelBuffer, *pixelBufferPtr;

/*
 * Initialize a freshly allocated PixelBuffer.  All fields are simply
 * set to NULL, as we have no idea what size buffer we will need.
 */
static void initPixelBuffer(pixelBufferPtr pb) {
    pb->hpixelObject = NULL;
    pb->byteBufferLength = 0;
    pb->buf.ip = NULL;
}

/*
 * Set the pixelBuffer to use the given buffer, acquiring a new global
 * reference for it.  Returns OK on success, NOT_OK on failure.
 */
static int setPixelBuffer(JNIEnv *env, pixelBufferPtr pb, jobject obj) {
    pb->hpixelObject = (*env)->NewGlobalRef(env, obj);
    if (pb->hpixelObject == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Setting Pixel Buffer");
        return NOT_OK;
    }
    pb->byteBufferLength = (*env)->GetArrayLength(env, pb->hpixelObject);
    return OK;
}

// Forward reference
static void unpinPixelBuffer(JNIEnv *env, pixelBufferPtr pb);

/*
 * Resets a pixel buffer to its initial state.  Unpins any pixel buffer,
 * releases the global reference, and resets fields to NULL.  Use this
 * method to dispose the object as well (there is no destroyPixelBuffer).
 */
static void resetPixelBuffer(JNIEnv *env, pixelBufferPtr pb) {
    if (pb->hpixelObject != NULL) {
        unpinPixelBuffer(env, pb);
        (*env)->DeleteGlobalRef(env, pb->hpixelObject);
        pb->hpixelObject = NULL;
        pb->byteBufferLength = 0;
    }
}

/*
 * Pins the data buffer.  Returns OK on success, NOT_OK on failure.
 */
static int pinPixelBuffer(JNIEnv *env, pixelBufferPtr pb) {
    if (pb->hpixelObject != NULL) {
        assert(pb->buf.ip == NULL);
        pb->buf.bp = (unsigned char *)(*env)->GetPrimitiveArrayCritical
            (env, pb->hpixelObject, NULL);
        if (pb->buf.bp == NULL) {
            return NOT_OK;
        }
    }
    return OK;
}

/*
 * Unpins the data buffer.
 */
static void unpinPixelBuffer(JNIEnv *env, pixelBufferPtr pb) {

    if (pb->buf.ip != NULL) {
        assert(pb->hpixelObject != NULL);
        (*env)->ReleasePrimitiveArrayCritical(env,
                                              pb->hpixelObject,
                                              pb->buf.ip,
                                              0);
        pb->buf.ip = NULL;
    }
}

/********************* end PixelBuffer definition *******************/

/********************* ImageIOData definition ***********************/

#define MAX_BANDS 4
#define JPEG_BAND_SIZE 8
#define NUM_BAND_VALUES (1<<JPEG_BAND_SIZE)
#define MAX_JPEG_BAND_VALUE (NUM_BAND_VALUES-1)
#define HALF_MAX_JPEG_BAND_VALUE (MAX_JPEG_BAND_VALUE>>1)

/* The number of possible incoming values to be scaled. */
#define NUM_INPUT_VALUES (1 << 16)

/*
 * The principal imageioData object, opaque to I/O direction.
 * Each JPEGImageReader will have associated with it a
 * jpeg_decompress_struct, and similarly each JPEGImageWriter will
 * have associated with it a jpeg_compress_struct.  In order to
 * ensure that these associations persist from one native call to
 * the next, and to provide a central locus of imageio-specific
 * data, we define an imageioData struct containing references
 * to the Java object and the IJG structs.  The functions
 * that manipulate these objects know whether input or output is being
 * performed and therefore know how to manipulate the contents correctly.
 * If for some reason they don't, the direction can be determined by
 * checking the is_decompressor field of the jpegObj.
 * In order for lower level code to determine a
 * Java object given an IJG struct, such as for dispatching warnings,
 * we use the client_data field of the jpeg object to store a pointer
 * to the imageIOData object.  Maintenance of this pointer is performed
 * exclusively within the following access functions.  If you
 * change that, you run the risk of dangling pointers.
 */
typedef struct imageIODataStruct {
    j_common_ptr jpegObj;     // Either struct is fine
    jobject imageIOobj;       // A JPEGImageReader or a JPEGImageWriter

    streamBuffer streamBuf;   // Buffer for the stream
    pixelBuffer pixelBuf;     // Buffer for pixels

    jboolean abortFlag;       // Passed down from Java abort method
} imageIOData, *imageIODataPtr;

/*
 * Allocate and initialize a new imageIOData object to associate the
 * jpeg object and the Java object.  Returns a pointer to the new object
 * on success, NULL on failure.
 */
static imageIODataPtr initImageioData (JNIEnv *env,
                                       j_common_ptr cinfo,
                                       jobject obj) {
    int i, j;

    imageIODataPtr data = (imageIODataPtr) malloc (sizeof(imageIOData));
    if (data == NULL) {
        return NULL;
    }

    data->jpegObj = cinfo;
    cinfo->client_data = data;

#ifdef DEBUG_IIO_JPEG
    printf("new structures: data is %p, cinfo is %p\n", data, cinfo);
#endif

    data->imageIOobj = (*env)->NewWeakGlobalRef(env, obj);
    if (data->imageIOobj == NULL) {
        free (data);
        return NULL;
    }
    if (initStreamBuffer(env, &data->streamBuf) == NOT_OK) {
        (*env)->DeleteWeakGlobalRef(env, data->imageIOobj);
        free (data);
        return NULL;
    }
    initPixelBuffer(&data->pixelBuf);

    data->abortFlag = JNI_FALSE;

    return data;
}

/*
 * Resets the imageIOData object to its initial state, as though
 * it had just been allocated and initialized.
 */
static void resetImageIOData(JNIEnv *env, imageIODataPtr data) {
    resetStreamBuffer(env, &data->streamBuf);
    resetPixelBuffer(env, &data->pixelBuf);
    data->abortFlag = JNI_FALSE;
}

/*
 * Releases all resources held by this object and its subobjects,
 * frees the object, and returns the jpeg object.  This method must
 * be called to avoid leaking global references.
 * Note that the jpeg object is not freed or destroyed, as that is
 * the client's responsibility, although the client_data field is
 * cleared.
 */
static j_common_ptr destroyImageioData(JNIEnv *env, imageIODataPtr data) {
    j_common_ptr ret = data->jpegObj;
    (*env)->DeleteWeakGlobalRef(env, data->imageIOobj);
    destroyStreamBuffer(env, &data->streamBuf);
    resetPixelBuffer(env, &data->pixelBuf);
    ret->client_data = NULL;
    free(data);
    return ret;
}

/******************** end ImageIOData definition ***********************/

/******************** Java array pinning and unpinning *****************/

/* We use Get/ReleasePrimitiveArrayCritical functions to avoid
 * the need to copy array elements for the above two objects.
 *
 * MAKE SURE TO:
 *
 * - carefully insert pairs of RELEASE_ARRAYS and GET_ARRAYS around
 *   callbacks to Java.
 * - call RELEASE_ARRAYS before returning to Java.
 *
 * Otherwise things will go horribly wrong. There may be memory leaks,
 * excessive pinning, or even VM crashes!
 *
 * Note that GetPrimitiveArrayCritical may fail!
 */

/*
 * Release (unpin) all the arrays in use during a read.
 */
static void RELEASE_ARRAYS(JNIEnv *env, imageIODataPtr data, const JOCTET *next_byte)
{
    unpinStreamBuffer(env, &data->streamBuf, next_byte);

    unpinPixelBuffer(env, &data->pixelBuf);

}

/*
 * Get (pin) all the arrays in use during a read.
 */
static int GET_ARRAYS(JNIEnv *env, imageIODataPtr data, const JOCTET **next_byte) {
    if (pinStreamBuffer(env, &data->streamBuf, next_byte) == NOT_OK) {
        return NOT_OK;
    }

    if (pinPixelBuffer(env, &data->pixelBuf) == NOT_OK) {
        RELEASE_ARRAYS(env, data, *next_byte);
        return NOT_OK;
    }
    return OK;
}

/****** end of Java array pinning and unpinning ***********/

/****** Error Handling *******/

/*
 * Set up error handling to use setjmp/longjmp.  This is the third such
 * setup, as both the AWT jpeg decoder and the com.sun... JPEG classes
 * setup thier own.  Ultimately these should be integrated, as they all
 * do pretty much the same thing.
 */

struct sun_jpeg_error_mgr {
  struct jpeg_error_mgr pub;    /* "public" fields */

  jmp_buf setjmp_buffer;        /* for return to caller */
};

typedef struct sun_jpeg_error_mgr * sun_jpeg_error_ptr;

/*
 * Here's the routine that will replace the standard error_exit method:
 */

METHODDEF(void)
sun_jpeg_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a sun_jpeg_error_mgr struct */
  sun_jpeg_error_ptr myerr = (sun_jpeg_error_ptr) cinfo->err;

  /* For Java, we will format the message and put it in the error we throw. */

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}

/*
 * Error Message handling
 *
 * This overrides the output_message method to send JPEG messages
 *
 */

METHODDEF(void)
sun_jpeg_output_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];
  jstring string;
  imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
  JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
  jobject theObject;

  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);

  // Create a new java string from the message
  string = (*env)->NewStringUTF(env, buffer);

  theObject = data->imageIOobj;

  if (cinfo->is_decompressor) {
      (*env)->CallVoidMethod(env, theObject,
                             JPEGImageReader_warningWithMessageID,
                             string);
  } else {
      (*env)->CallVoidMethod(env, theObject,
                             JPEGImageWriter_warningWithMessageID,
                             string);
  }
}

/* End of verbatim copy from jpegdecoder.c */

/*************** end of error handling *********************/

/*************** Shared utility code ***********************/

static void imageio_set_stream(JNIEnv *env,
                               j_common_ptr cinfo,
                               imageIODataPtr data,
                               jobject stream){
    streamBufferPtr sb;
    sun_jpeg_error_ptr jerr;

    sb = &data->streamBuf;

    resetStreamBuffer(env, sb);  // Removes any old stream

    /* Now we need a new global reference for the stream */
    if (stream != NULL) { // Fix for 4411955
        sb->stream = (*env)->NewGlobalRef(env, stream);
        if (sb->stream == NULL) {
            JNU_ThrowByName(env,
                            "java/lang/OutOfMemoryError",
                            "Setting Stream");
            return;
        }
    }

    /* And finally reset state */
    data->abortFlag = JNI_FALSE;

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while aborting. */
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) (cinfo,
                                           buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        return;
    }

    jpeg_abort(cinfo);  // Frees any markers, but not tables

}

static void imageio_reset(JNIEnv *env,
                          j_common_ptr cinfo,
                          imageIODataPtr data) {
    sun_jpeg_error_ptr jerr;

    resetImageIOData(env, data);  // Mapping to jpeg object is retained.

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while aborting. */
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) (cinfo, buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        return;
    }

    jpeg_abort(cinfo);  // Does not reset tables

}

static void imageio_dispose(j_common_ptr info) {

    if (info != NULL) {
        free(info->err);
        info->err = NULL;
        if (info->is_decompressor) {
            j_decompress_ptr dinfo = (j_decompress_ptr) info;
            free(dinfo->src);
            dinfo->src = NULL;
        } else {
            j_compress_ptr cinfo = (j_compress_ptr) info;
            free(cinfo->dest);
            cinfo->dest = NULL;
        }
        jpeg_destroy(info);
        free(info);
    }
}

static void imageio_abort(JNIEnv *env, jobject this,
                          imageIODataPtr data) {
    data->abortFlag = JNI_TRUE;
}

static int setQTables(JNIEnv *env,
                      j_common_ptr cinfo,
                      jobjectArray qtables,
                      boolean write) {
    jsize qlen;
    jobject table;
    jintArray qdata;
    jint *qdataBody;
    JQUANT_TBL *quant_ptr;
    int i, j;
    j_compress_ptr comp;
    j_decompress_ptr decomp;

    qlen = (*env)->GetArrayLength(env, qtables);
#ifdef DEBUG_IIO_JPEG
    printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
#endif
    if (qlen > NUM_QUANT_TBLS) {
        /* Ignore extra qunterization tables. */
        qlen = NUM_QUANT_TBLS;
    }
    for (i = 0; i < qlen; i++) {
        table = (*env)->GetObjectArrayElement(env, qtables, i);
        qdata = (*env)->GetObjectField(env, table, JPEGQTable_tableID);
        qdataBody = (*env)->GetPrimitiveArrayCritical(env, qdata, NULL);

        if (cinfo->is_decompressor) {
            decomp = (j_decompress_ptr) cinfo;
            if (decomp->quant_tbl_ptrs[i] == NULL) {
                decomp->quant_tbl_ptrs[i] =
                    jpeg_alloc_quant_table(cinfo);
            }
            quant_ptr = decomp->quant_tbl_ptrs[i];
        } else {
            comp = (j_compress_ptr) cinfo;
            if (comp->quant_tbl_ptrs[i] == NULL) {
                comp->quant_tbl_ptrs[i] =
                    jpeg_alloc_quant_table(cinfo);
            }
            quant_ptr = comp->quant_tbl_ptrs[i];
        }

        for (j = 0; j < 64; j++) {
            quant_ptr->quantval[j] = (UINT16)qdataBody[j];
        }
        quant_ptr->sent_table = !write;
        (*env)->ReleasePrimitiveArrayCritical(env,
                                              qdata,
                                              qdataBody,
                                              0);
    }
    return qlen;
}

static void setHuffTable(JNIEnv *env,
                         JHUFF_TBL *huff_ptr,
                         jobject table) {

    jshortArray huffLens;
    jshortArray huffValues;
    jshort *hlensBody, *hvalsBody;
    jsize hlensLen, hvalsLen;
    int i;

    // lengths
    huffLens = (*env)->GetObjectField(env,
                                      table,
                                      JPEGHuffmanTable_lengthsID);
    hlensLen = (*env)->GetArrayLength(env, huffLens);
    hlensBody = (*env)->GetShortArrayElements(env,
                                              huffLens,
                                              NULL);
    if (hlensLen > 16) {
        /* Ignore extra elements of bits array. Only 16 elements can be
           stored. 0-th element is not used. (see jpeglib.h, line 107)  */
        hlensLen = 16;
    }
    for (i = 1; i <= hlensLen; i++) {
        huff_ptr->bits[i] = (UINT8)hlensBody[i-1];
    }
    (*env)->ReleaseShortArrayElements(env,
                                      huffLens,
                                      hlensBody,
                                      JNI_ABORT);
    // values
    huffValues = (*env)->GetObjectField(env,
                                        table,
                                        JPEGHuffmanTable_valuesID);
    hvalsLen = (*env)->GetArrayLength(env, huffValues);
    hvalsBody = (*env)->GetShortArrayElements(env,
                                              huffValues,
                                              NULL);

    if (hvalsLen > 256) {
        /* Ignore extra elements of hufval array. Only 256 elements
           can be stored. (see jpeglib.h, line 109)                  */
        hlensLen = 256;
    }
    for (i = 0; i < hvalsLen; i++) {
        huff_ptr->huffval[i] = (UINT8)hvalsBody[i];
    }
    (*env)->ReleaseShortArrayElements(env,
                                      huffValues,
                                      hvalsBody,
                                      JNI_ABORT);
}

static int setHTables(JNIEnv *env,
                      j_common_ptr cinfo,
                      jobjectArray DCHuffmanTables,
                      jobjectArray ACHuffmanTables,
                      boolean write) {
    int i;
    jobject table;
    JHUFF_TBL *huff_ptr;
    j_compress_ptr comp;
    j_decompress_ptr decomp;
    jsize hlen = (*env)->GetArrayLength(env, DCHuffmanTables);

    if (hlen > NUM_HUFF_TBLS) {
        /* Ignore extra DC huffman tables. */
        hlen = NUM_HUFF_TBLS;
    }
    for (i = 0; i < hlen; i++) {
        if (cinfo->is_decompressor) {
            decomp = (j_decompress_ptr) cinfo;
            if (decomp->dc_huff_tbl_ptrs[i] == NULL) {
                decomp->dc_huff_tbl_ptrs[i] =
                    jpeg_alloc_huff_table(cinfo);
            }
            huff_ptr = decomp->dc_huff_tbl_ptrs[i];
        } else {
            comp = (j_compress_ptr) cinfo;
            if (comp->dc_huff_tbl_ptrs[i] == NULL) {
                comp->dc_huff_tbl_ptrs[i] =
                    jpeg_alloc_huff_table(cinfo);
            }
            huff_ptr = comp->dc_huff_tbl_ptrs[i];
        }
        table = (*env)->GetObjectArrayElement(env, DCHuffmanTables, i);
        setHuffTable(env, huff_ptr, table);
        huff_ptr->sent_table = !write;
    }
    hlen = (*env)->GetArrayLength(env, ACHuffmanTables);
    if (hlen > NUM_HUFF_TBLS) {
        /* Ignore extra AC huffman tables. */
        hlen = NUM_HUFF_TBLS;
    }
    for (i = 0; i < hlen; i++) {
        if (cinfo->is_decompressor) {
            decomp = (j_decompress_ptr) cinfo;
            if (decomp->ac_huff_tbl_ptrs[i] == NULL) {
                decomp->ac_huff_tbl_ptrs[i] =
                    jpeg_alloc_huff_table(cinfo);
            }
            huff_ptr = decomp->ac_huff_tbl_ptrs[i];
        } else {
            comp = (j_compress_ptr) cinfo;
            if (comp->ac_huff_tbl_ptrs[i] == NULL) {
                comp->ac_huff_tbl_ptrs[i] =
                    jpeg_alloc_huff_table(cinfo);
            }
            huff_ptr = comp->ac_huff_tbl_ptrs[i];
        }
        table = (*env)->GetObjectArrayElement(env, ACHuffmanTables, i);
        setHuffTable(env, huff_ptr, table);
        huff_ptr->sent_table = !write;
    }
    return hlen;
}


/*************** end of shared utility code ****************/

/********************** Reader Support **************************/

/********************** Source Management ***********************/

/*
 * INPUT HANDLING:
 *
 * The JPEG library's input management is defined by the jpeg_source_mgr
 * structure which contains two fields to convey the information in the
 * buffer and 5 methods which perform all buffer management.  The library
 * defines a standard input manager that uses stdio for obtaining compressed
 * jpeg data, but here we need to use Java to get our data.
 *
 * We use the library jpeg_source_mgr but our own routines that access
 * imageio-specific information in the imageIOData structure.
 */

/*
 * Initialize source.  This is called by jpeg_read_header() before any
 * data is actually read.  Unlike init_destination(), it may leave
 * bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
 * will occur immediately).
 */

GLOBAL(void)
imageio_init_source(j_decompress_ptr cinfo)
{
    struct jpeg_source_mgr *src = cinfo->src;
    src->next_input_byte = NULL;
    src->bytes_in_buffer = 0;
}

/*
 * This is called whenever bytes_in_buffer has reached zero and more
 * data is wanted.  In typical applications, it should read fresh data
 * into the buffer (ignoring the current state of next_input_byte and
 * bytes_in_buffer), reset the pointer & count to the start of the
 * buffer, and return TRUE indicating that the buffer has been reloaded.
 * It is not necessary to fill the buffer entirely, only to obtain at
 * least one more byte.  bytes_in_buffer MUST be set to a positive value
 * if TRUE is returned.  A FALSE return should only be used when I/O
 * suspension is desired (this mode is discussed in the next section).
 */
/*
 * Note that with I/O suspension turned on, this procedure should not
 * do any work since the JPEG library has a very simple backtracking
 * mechanism which relies on the fact that the buffer will be filled
 * only when it has backed out to the top application level.  When
 * suspendable is turned on, imageio_fill_suspended_buffer will
 * do the actual work of filling the buffer.
 */

GLOBAL(boolean)
imageio_fill_input_buffer(j_decompress_ptr cinfo)
{
    struct jpeg_source_mgr *src = cinfo->src;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    int ret;

    /* This is where input suspends */
    if (sb->suspendable) {
        return FALSE;
    }

#ifdef DEBUG_IIO_JPEG
    printf("Filling input buffer, remaining skip is %ld, ",
           sb->remaining_skip);
    printf("Buffer length is %d\n", sb->bufferLength);
#endif

    /*
     * Definitively skips.  Could be left over if we tried to skip
     * more than a buffer's worth but suspended when getting the next
     * buffer.  Now we aren't suspended, so we can catch up.
     */
    if (sb->remaining_skip) {
        src->skip_input_data(cinfo, 0);
    }

    /*
     * Now fill a complete buffer, or as much of one as the stream
     * will give us if we are near the end.
     */
    RELEASE_ARRAYS(env, data, src->next_input_byte);
    ret = (*env)->CallIntMethod(env,
                                sb->stream,
                                ImageInputStream_readID,
                                sb->hstreamBuffer, 0,
                                sb->bufferLength);
    if ((*env)->ExceptionOccurred(env)
        || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
    }

#ifdef DEBUG_IIO_JPEG
      printf("Buffer filled. ret = %d\n", ret);
#endif
    /*
     * If we have reached the end of the stream, then the EOI marker
     * is missing.  We accept such streams but generate a warning.
     * The image is likely to be corrupted, though everything through
     * the end of the last complete MCU should be usable.
     */
    if (ret <= 0) {
        jobject reader = data->imageIOobj;
#ifdef DEBUG_IIO_JPEG
      printf("YO! Early EOI! ret = %d\n", ret);
#endif
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        (*env)->CallVoidMethod(env, reader,
                               JPEGImageReader_warningOccurredID,
                               READ_NO_EOI);
        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
        }

        sb->buf[0] = (JOCTET) 0xFF;
        sb->buf[1] = (JOCTET) JPEG_EOI;
        ret = 2;
    }

    src->next_input_byte = sb->buf;
    src->bytes_in_buffer = ret;

    return TRUE;
}

/*
 * With I/O suspension turned on, the JPEG library requires that all
 * buffer filling be done at the top application level, using this
 * function.  Due to the way that backtracking works, this procedure
 * saves all of the data that was left in the buffer when suspension
 * occured and read new data only at the end.
 */

GLOBAL(void)
imageio_fill_suspended_buffer(j_decompress_ptr cinfo)
{
    struct jpeg_source_mgr *src = cinfo->src;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jint ret;
    int offset, buflen;

    /*
     * The original (jpegdecoder.c) had code here that called
     * InputStream.available and just returned if the number of bytes
     * available was less than any remaining skip.  Presumably this was
     * to avoid blocking, although the benefit was unclear, as no more
     * decompression can take place until more data is available, so
     * the code would block on input a little further along anyway.
     * ImageInputStreams don't have an available method, so we'll just
     * block in the skip if we have to.
     */

    if (sb->remaining_skip) {
        src->skip_input_data(cinfo, 0);
    }

    /* Save the data currently in the buffer */
    offset = src->bytes_in_buffer;
    if (src->next_input_byte > sb->buf) {
        memcpy(sb->buf, src->next_input_byte, offset);
    }
    RELEASE_ARRAYS(env, data, src->next_input_byte);
    buflen = sb->bufferLength - offset;
    if (buflen <= 0) {
        if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
        }
        return;
    }

    ret = (*env)->CallIntMethod(env, sb->stream,
                                ImageInputStream_readID,
                                sb->hstreamBuffer,
                                offset, buflen);
    if ((*env)->ExceptionOccurred(env)
        || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
        cinfo->err->error_exit((j_common_ptr) cinfo);
    }
    /*
     * If we have reached the end of the stream, then the EOI marker
     * is missing.  We accept such streams but generate a warning.
     * The image is likely to be corrupted, though everything through
     * the end of the last complete MCU should be usable.
     */
    if (ret <= 0) {
        jobject reader = data->imageIOobj;
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        (*env)->CallVoidMethod(env, reader,
                               JPEGImageReader_warningOccurredID,
                               READ_NO_EOI);
        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
        }

        sb->buf[offset] = (JOCTET) 0xFF;
        sb->buf[offset + 1] = (JOCTET) JPEG_EOI;
        ret = 2;
    }

    src->next_input_byte = sb->buf;
    src->bytes_in_buffer = ret + offset;

    return;
}

/*
 * Skip num_bytes worth of data.  The buffer pointer and count are
 * advanced over num_bytes input bytes, using the input stream
 * skipBytes method if the skip is greater than the number of bytes
 * in the buffer.  This is used to skip over a potentially large amount of
 * uninteresting data (such as an APPn marker).  bytes_in_buffer will be
 * zero on return if the skip is larger than the current contents of the
 * buffer.
 *
 * A negative skip count is treated as a no-op.  A zero skip count
 * skips any remaining skip from a previous skip while suspended.
 *
 * Note that with I/O suspension turned on, this procedure does not
 * call skipBytes since the JPEG library has a very simple backtracking
 * mechanism which relies on the fact that the application level has
 * exclusive control over actual I/O.
 */

GLOBAL(void)
imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
    struct jpeg_source_mgr *src = cinfo->src;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jlong ret;
    jobject reader;

    if (num_bytes < 0) {
        return;
    }
    num_bytes += sb->remaining_skip;
    sb->remaining_skip = 0;

    /* First the easy case where we are skipping <= the current contents. */
    ret = src->bytes_in_buffer;
    if (ret >= num_bytes) {
        src->next_input_byte += num_bytes;
        src->bytes_in_buffer -= num_bytes;
        return;
    }

    /*
     * We are skipping more than is in the buffer.  We empty the buffer and,
     * if we aren't suspended, call the Java skipBytes method.  We always
     * leave the buffer empty, to be filled by either fill method above.
     */
    src->bytes_in_buffer = 0;
    src->next_input_byte = sb->buf;

    num_bytes -= (long)ret;
    if (sb->suspendable) {
        sb->remaining_skip = num_bytes;
        return;
    }

    RELEASE_ARRAYS(env, data, src->next_input_byte);
    ret = (*env)->CallLongMethod(env,
                                 sb->stream,
                                 ImageInputStream_skipBytesID,
                                 (jlong) num_bytes);
    if ((*env)->ExceptionOccurred(env)
        || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
    }

    /*
     * If we have reached the end of the stream, then the EOI marker
     * is missing.  We accept such streams but generate a warning.
     * The image is likely to be corrupted, though everything through
     * the end of the last complete MCU should be usable.
     */
    if (ret <= 0) {
        reader = data->imageIOobj;
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        (*env)->CallVoidMethod(env,
                               reader,
                               JPEGImageReader_warningOccurredID,
                               READ_NO_EOI);

        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
                cinfo->err->error_exit((j_common_ptr) cinfo);
        }
        sb->buf[0] = (JOCTET) 0xFF;
        sb->buf[1] = (JOCTET) JPEG_EOI;
        src->bytes_in_buffer = 2;
        src->next_input_byte = sb->buf;
    }
}

/*
 * Terminate source --- called by jpeg_finish_decompress() after all
 * data for an image has been read.  In our case pushes back any
 * remaining data, as it will be for another image and must be available
 * for java to find out that there is another image.  Also called if
 * reseting state after reading a tables-only image.
 */

GLOBAL(void)
imageio_term_source(j_decompress_ptr cinfo)
{
    // To pushback, just seek back by src->bytes_in_buffer
    struct jpeg_source_mgr *src = cinfo->src;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject reader = data->imageIOobj;
    if (src->bytes_in_buffer > 0) {
         RELEASE_ARRAYS(env, data, src->next_input_byte);
         (*env)->CallVoidMethod(env,
                                reader,
                                JPEGImageReader_pushBackID,
                                src->bytes_in_buffer);

         if ((*env)->ExceptionOccurred(env)
             || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
             cinfo->err->error_exit((j_common_ptr) cinfo);
         }
         src->bytes_in_buffer = 0;
         //src->next_input_byte = sb->buf;
    }
}

/********************* end of source manager ******************/

/********************* ICC profile support ********************/
/*
 * The following routines are modified versions of the ICC
 * profile support routines available from the IJG website.
 * The originals were written by Todd Newman
 * <tdn@eccentric.esd.sgi.com> and modified by Tom Lane for
 * the IJG.  They are further modified to fit in the context
 * of the imageio JPEG plug-in.
 */

/*
 * Since an ICC profile can be larger than the maximum size of a JPEG marker
 * (64K), we need provisions to split it into multiple markers.  The format
 * defined by the ICC specifies one or more APP2 markers containing the
 * following data:
 *      Identifying string      ASCII "ICC_PROFILE\0"  (12 bytes)
 *      Marker sequence number  1 for first APP2, 2 for next, etc (1 byte)
 *      Number of markers       Total number of APP2's used (1 byte)
 *      Profile data            (remainder of APP2 data)
 * Decoders should use the marker sequence numbers to reassemble the profile,
 * rather than assuming that the APP2 markers appear in the correct sequence.
 */

#define ICC_MARKER  (JPEG_APP0 + 2)     /* JPEG marker code for ICC */
#define ICC_OVERHEAD_LEN  14            /* size of non-profile data in APP2 */
#define MAX_BYTES_IN_MARKER  65533      /* maximum data len of a JPEG marker */
#define MAX_DATA_BYTES_IN_ICC_MARKER  (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)


/*
 * Handy subroutine to test whether a saved marker is an ICC profile marker.
 */

static boolean
marker_is_icc (jpeg_saved_marker_ptr marker)
{
  return
    marker->marker == ICC_MARKER &&
    marker->data_length >= ICC_OVERHEAD_LEN &&
    /* verify the identifying string */
    GETJOCTET(marker->data[0]) == 0x49 &&
    GETJOCTET(marker->data[1]) == 0x43 &&
    GETJOCTET(marker->data[2]) == 0x43 &&
    GETJOCTET(marker->data[3]) == 0x5F &&
    GETJOCTET(marker->data[4]) == 0x50 &&
    GETJOCTET(marker->data[5]) == 0x52 &&
    GETJOCTET(marker->data[6]) == 0x4F &&
    GETJOCTET(marker->data[7]) == 0x46 &&
    GETJOCTET(marker->data[8]) == 0x49 &&
    GETJOCTET(marker->data[9]) == 0x4C &&
    GETJOCTET(marker->data[10]) == 0x45 &&
    GETJOCTET(marker->data[11]) == 0x0;
}

/*
 * See if there was an ICC profile in the JPEG file being read;
 * if so, reassemble and return the profile data as a new Java byte array.
 * If there was no ICC profile, return NULL.
 *
 * If the file contains invalid ICC APP2 markers, we throw an IIOException
 * with an appropriate message.
 */

jbyteArray
read_icc_profile (JNIEnv *env, j_decompress_ptr cinfo)
{
    jpeg_saved_marker_ptr marker;
    int num_markers = 0;
    int num_found_markers = 0;
    int seq_no;
    JOCTET *icc_data;
    JOCTET *dst_ptr;
    unsigned int total_length;
#define MAX_SEQ_NO  255         // sufficient since marker numbers are bytes
    jpeg_saved_marker_ptr icc_markers[MAX_SEQ_NO + 1];
    int first;         // index of the first marker in the icc_markers array
    int last;          // index of the last marker in the icc_markers array
    jbyteArray data = NULL;

    /* This first pass over the saved markers discovers whether there are
     * any ICC markers and verifies the consistency of the marker numbering.
     */

    for (seq_no = 0; seq_no <= MAX_SEQ_NO; seq_no++)
        icc_markers[seq_no] = NULL;


    for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
        if (marker_is_icc(marker)) {
            if (num_markers == 0)
                num_markers = GETJOCTET(marker->data[13]);
            else if (num_markers != GETJOCTET(marker->data[13])) {
                JNU_ThrowByName(env, "javax/imageio/IIOException",
                     "Invalid icc profile: inconsistent num_markers fields");
                return NULL;
            }
            seq_no = GETJOCTET(marker->data[12]);

            /* Some third-party tools produce images with profile chunk
             * numeration started from zero. It is inconsistent with ICC
             * spec, but seems to be recognized by majority of image
             * processing tools, so we should be more tolerant to this
             * departure from the spec.
             */
            if (seq_no < 0 || seq_no > num_markers) {
                JNU_ThrowByName(env, "javax/imageio/IIOException",
                     "Invalid icc profile: bad sequence number");
                return NULL;
            }
            if (icc_markers[seq_no] != NULL) {
                JNU_ThrowByName(env, "javax/imageio/IIOException",
                     "Invalid icc profile: duplicate sequence numbers");
                return NULL;
            }
            icc_markers[seq_no] = marker;
            num_found_markers ++;
        }
    }

    if (num_markers == 0)
        return NULL;  // There is no profile

    if (num_markers != num_found_markers) {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
                        "Invalid icc profile: invalid number of icc markers");
        return NULL;
    }

    first = icc_markers[0] ? 0 : 1;
    last = num_found_markers + first;

    /* Check for missing markers, count total space needed.
     */
    total_length = 0;
    for (seq_no = first; seq_no < last; seq_no++) {
        unsigned int length;
        if (icc_markers[seq_no] == NULL) {
            JNU_ThrowByName(env, "javax/imageio/IIOException",
                 "Invalid icc profile: missing sequence number");
            return NULL;
        }
        /* check the data length correctness */
        length = icc_markers[seq_no]->data_length;
        if (ICC_OVERHEAD_LEN > length || length > MAX_BYTES_IN_MARKER) {
            JNU_ThrowByName(env, "javax/imageio/IIOException",
                 "Invalid icc profile: invalid data length");
            return NULL;
        }
        total_length += (length - ICC_OVERHEAD_LEN);
    }

    if (total_length <= 0) {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
              "Invalid icc profile: found only empty markers");
        return NULL;
    }

    /* Allocate a Java byte array for assembled data */

    data = (*env)->NewByteArray(env, total_length);
    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/OutOfMemoryError",
                        "Reading ICC profile");
        return NULL;
    }

    icc_data = (JOCTET *)(*env)->GetPrimitiveArrayCritical(env,
                                                           data,
                                                           NULL);
    if (icc_data == NULL) {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
                        "Unable to pin icc profile data array");
        return NULL;
    }

    /* and fill it in */
    dst_ptr = icc_data;
    for (seq_no = first; seq_no < last; seq_no++) {
        JOCTET FAR *src_ptr = icc_markers[seq_no]->data + ICC_OVERHEAD_LEN;
        unsigned int length =
            icc_markers[seq_no]->data_length - ICC_OVERHEAD_LEN;

        memcpy(dst_ptr, src_ptr, length);
        dst_ptr += length;
    }

    /* finally, unpin the array */
    (*env)->ReleasePrimitiveArrayCritical(env,
                                          data,
                                          icc_data,
                                          0);


    return data;
}

/********************* end of ICC profile support *************/

/********************* Reader JNI calls ***********************/

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initReaderIDs
    (JNIEnv *env,
     jclass cls,
     jclass ImageInputStreamClass,
     jclass qTableClass,
     jclass huffClass) {

    ImageInputStream_readID = (*env)->GetMethodID(env,
                                                  ImageInputStreamClass,
                                                  "read",
                                                  "([BII)I");
    ImageInputStream_skipBytesID = (*env)->GetMethodID(env,
                                                       ImageInputStreamClass,
                                                       "skipBytes",
                                                       "(J)J");
    JPEGImageReader_warningOccurredID = (*env)->GetMethodID(env,
                                                            cls,
                                                            "warningOccurred",
                                                            "(I)V");
    JPEGImageReader_warningWithMessageID =
        (*env)->GetMethodID(env,
                            cls,
                            "warningWithMessage",
                            "(Ljava/lang/String;)V");
    JPEGImageReader_setImageDataID = (*env)->GetMethodID(env,
                                                         cls,
                                                         "setImageData",
                                                         "(IIIII[B)V");
    JPEGImageReader_acceptPixelsID = (*env)->GetMethodID(env,
                                                         cls,
                                                         "acceptPixels",
                                                         "(IZ)V");
    JPEGImageReader_passStartedID = (*env)->GetMethodID(env,
                                                        cls,
                                                        "passStarted",
                                                        "(I)V");
    JPEGImageReader_passCompleteID = (*env)->GetMethodID(env,
                                                         cls,
                                                         "passComplete",
                                                         "()V");
    JPEGImageReader_pushBackID = (*env)->GetMethodID(env,
                                                     cls,
                                                     "pushBack",
                                                     "(I)V");
    JPEGQTable_tableID = (*env)->GetFieldID(env,
                                            qTableClass,
                                            "qTable",
                                            "[I");

    JPEGHuffmanTable_lengthsID = (*env)->GetFieldID(env,
                                                    huffClass,
                                                    "lengths",
                                                    "[S");

    JPEGHuffmanTable_valuesID = (*env)->GetFieldID(env,
                                                    huffClass,
                                                    "values",
                                                    "[S");
}

JNIEXPORT jlong JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
    (JNIEnv *env,
     jobject this) {

    imageIODataPtr ret;
    struct sun_jpeg_error_mgr *jerr;

    /* This struct contains the JPEG decompression parameters and pointers to
     * working space (which is allocated as needed by the JPEG library).
     */
    struct jpeg_decompress_struct *cinfo =
        malloc(sizeof(struct jpeg_decompress_struct));
    if (cinfo == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
        return 0;
    }

    /* We use our private extension JPEG error handler.
     */
    jerr = malloc (sizeof(struct sun_jpeg_error_mgr));
    if (jerr == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
        free(cinfo);
        return 0;
    }

    /* We set up the normal JPEG error routines, then override error_exit. */
    cinfo->err = jpeg_std_error(&(jerr->pub));
    jerr->pub.error_exit = sun_jpeg_error_exit;
    /* We need to setup our own print routines */
    jerr->pub.output_message = sun_jpeg_output_message;
    /* Now we can setjmp before every call to the library */

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error. */
        char buffer[JMSG_LENGTH_MAX];
        (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                                      buffer);
        JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        return 0;
    }

    /* Perform library initialization */
    jpeg_create_decompress(cinfo);

    // Set up to keep any APP2 markers, as these might contain ICC profile
    // data
    jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);

    /*
     * Now set up our source.
     */
    cinfo->src =
        (struct jpeg_source_mgr *) malloc (sizeof(struct jpeg_source_mgr));
    if (cinfo->src == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/OutOfMemoryError",
                        "Initializing Reader");
        imageio_dispose((j_common_ptr)cinfo);
        return 0;
    }
    cinfo->src->bytes_in_buffer = 0;
    cinfo->src->next_input_byte = NULL;
    cinfo->src->init_source = imageio_init_source;
    cinfo->src->fill_input_buffer = imageio_fill_input_buffer;
    cinfo->src->skip_input_data = imageio_skip_input_data;
    cinfo->src->resync_to_restart = jpeg_resync_to_restart; // use default
    cinfo->src->term_source = imageio_term_source;

    /* set up the association to persist for future calls */
    ret = initImageioData(env, (j_common_ptr) cinfo, this);
    if (ret == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
        imageio_dispose((j_common_ptr)cinfo);
        return 0;
    }
    return (jlong) ret;
}

/*
 * When we set a source from Java, we set up the stream in the streamBuf
 * object.  If there was an old one, it is released first.
 */

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setSource
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jobject source) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_common_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return;
    }

    cinfo = data->jpegObj;

    imageio_set_stream(env, cinfo, data, source);

    imageio_init_source((j_decompress_ptr) cinfo);
}

#define JPEG_APP1  (JPEG_APP0 + 1)  /* EXIF APP1 marker code  */

/*
 * For EXIF images, the APP1 will appear immediately after the SOI,
 * so it's safe to only look at the first marker in the list.
 * (see http://www.exif.org/Exif2-2.PDF, section 4.7, page 58)
 */
#define IS_EXIF(c) \
    (((c)->marker_list != NULL) && ((c)->marker_list->marker == JPEG_APP1))

JNIEXPORT jboolean JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jboolean clearFirst,
     jboolean reset) {

    int ret;
    int h_samp0, h_samp1, h_samp2;
    int v_samp0, v_samp1, v_samp2;
    jboolean retval = JNI_FALSE;
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_decompress_ptr cinfo;
    struct jpeg_source_mgr *src;
    sun_jpeg_error_ptr jerr;
    jbyteArray profileData = NULL;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return JNI_FALSE;
    }

    cinfo = (j_decompress_ptr) data->jpegObj;
    src = cinfo->src;

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while reading the header. */
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                                          buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        return retval;
    }

#ifdef DEBUG_IIO_JPEG
    printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo);
    printf("clearFirst is %d\n", clearFirst);
#endif

    if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
        JNU_ThrowByName(env,
                        "javax/imageio/IIOException",
                        "Array pin failed");
        return retval;
    }

    /*
     * Now clear the input buffer if the Java code has done a seek
     * on the stream since the last call, invalidating any buffer contents.
     */
    if (clearFirst) {
        clearStreamBuffer(&data->streamBuf);
        src->next_input_byte = NULL;
        src->bytes_in_buffer = 0;
    }

    ret = jpeg_read_header(cinfo, FALSE);

    if (ret == JPEG_HEADER_TABLES_ONLY) {
        retval = JNI_TRUE;
        imageio_term_source(cinfo);  // Pushback remaining buffer contents
#ifdef DEBUG_IIO_JPEG
        printf("just read tables-only image; q table 0 at %p\n",
               cinfo->quant_tbl_ptrs[0]);
#endif
        RELEASE_ARRAYS(env, data, src->next_input_byte);
    } else {
        /*
         * Now adjust the jpeg_color_space variable, which was set in
         * default_decompress_parms, to reflect our differences from IJG
         */

        switch (cinfo->jpeg_color_space) {
        default :
          break;
        case JCS_YCbCr:

            /*
             * There are several possibilities:
             *  - we got image with embeded colorspace
             *     Use it. User knows what he is doing.
             *  - we got JFIF image
             *     Must be YCbCr (see http://www.w3.org/Graphics/JPEG/jfif3.pdf, page 2)
             *  - we got EXIF image
             *     Must be YCbCr (see http://www.exif.org/Exif2-2.PDF, section 4.7, page 63)
             *  - something else
             *     Apply heuristical rules to identify actual colorspace.
             */

            if (cinfo->saw_Adobe_marker) {
                if (cinfo->Adobe_transform != 1) {
                    /*
                     * IJG guesses this is YCbCr and emits a warning
                     * We would rather not guess.  Then the user knows
                     * To read this as a Raster if at all
                     */
                    cinfo->jpeg_color_space = JCS_UNKNOWN;
                    cinfo->out_color_space = JCS_UNKNOWN;
                }
            } else if (!cinfo->saw_JFIF_marker && !IS_EXIF(cinfo)) {
                /*
                 * IJG assumes all unidentified 3-channels are YCbCr.
                 * We assume that only if the second two channels are
                 * subsampled (either horizontally or vertically).  If not,
                 * we assume RGB.
                 *
                 * 4776576: Some digital cameras output YCbCr JPEG images
                 * that do not contain a JFIF APP0 marker but are only
                 * vertically subsampled (no horizontal subsampling).
                 * We should only assume this is RGB data if the subsampling
                 * factors for the second two channels are the same as the
                 * first (check both horizontal and vertical factors).
                 */
                h_samp0 = cinfo->comp_info[0].h_samp_factor;
                h_samp1 = cinfo->comp_info[1].h_samp_factor;
                h_samp2 = cinfo->comp_info[2].h_samp_factor;

                v_samp0 = cinfo->comp_info[0].v_samp_factor;
                v_samp1 = cinfo->comp_info[1].v_samp_factor;
                v_samp2 = cinfo->comp_info[2].v_samp_factor;

                if ((h_samp1 == h_samp0) && (h_samp2 == h_samp0) &&
                    (v_samp1 == v_samp0) && (v_samp2 == v_samp0))
                {
                    cinfo->jpeg_color_space = JCS_RGB;
                    /* output is already RGB, so it stays the same */
                }
            }
            break;
#ifdef YCCALPHA
        case JCS_YCC:
            cinfo->out_color_space = JCS_YCC;
            break;
#endif
        case JCS_YCCK:
            if ((cinfo->saw_Adobe_marker) && (cinfo->Adobe_transform != 2)) {
                /*
                 * IJG guesses this is YCCK and emits a warning
                 * We would rather not guess.  Then the user knows
                 * To read this as a Raster if at all
                 */
                cinfo->jpeg_color_space = JCS_UNKNOWN;
                cinfo->out_color_space = JCS_UNKNOWN;
            }
            break;
        case JCS_CMYK:
            /*
             * IJG assumes all unidentified 4-channels are CMYK.
             * We assume that only if the second two channels are
             * not subsampled (either horizontally or vertically).
             * If they are, we assume YCCK.
             */
            h_samp0 = cinfo->comp_info[0].h_samp_factor;
            h_samp1 = cinfo->comp_info[1].h_samp_factor;
            h_samp2 = cinfo->comp_info[2].h_samp_factor;

            v_samp0 = cinfo->comp_info[0].v_samp_factor;
            v_samp1 = cinfo->comp_info[1].v_samp_factor;
            v_samp2 = cinfo->comp_info[2].v_samp_factor;

            if ((h_samp1 > h_samp0) && (h_samp2 > h_samp0) ||
                (v_samp1 > v_samp0) && (v_samp2 > v_samp0))
            {
                cinfo->jpeg_color_space = JCS_YCCK;
                /* Leave the output space as CMYK */
            }
        }
        RELEASE_ARRAYS(env, data, src->next_input_byte);

        /* read icc profile data */
        profileData = read_icc_profile(env, cinfo);

        if ((*env)->ExceptionCheck(env)) {
            return retval;
        }

        (*env)->CallVoidMethod(env, this,
                               JPEGImageReader_setImageDataID,
                               cinfo->image_width,
                               cinfo->image_height,
                               cinfo->jpeg_color_space,
                               cinfo->out_color_space,
                               cinfo->num_components,
                               profileData);
        if (reset) {
            jpeg_abort_decompress(cinfo);
        }
    }

    return retval;
}


JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setOutColorSpace
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jint code) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_decompress_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return;
    }

    cinfo = (j_decompress_ptr) data->jpegObj;

    cinfo->out_color_space = code;

}

JNIEXPORT jboolean JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jbyteArray buffer,
     jint numBands,
     jintArray srcBands,
     jintArray bandSizes,
     jint sourceXStart,
     jint sourceYStart,
     jint sourceWidth,
     jint sourceHeight,
     jint stepX,
     jint stepY,
     jobjectArray qtables,
     jobjectArray DCHuffmanTables,
     jobjectArray ACHuffmanTables,
     jint minProgressivePass,  // Counts from 0
     jint maxProgressivePass,
     jboolean wantUpdates) {


    struct jpeg_source_mgr *src;
    JSAMPROW scanLinePtr = NULL;
    jint bands[MAX_BANDS];
    int i, j;
    jint *body;
    int scanlineLimit;
    int pixelStride;
    unsigned char *in, *out, *pixelLimit;
    int targetLine;
    int skipLines, linesLeft;
    pixelBufferPtr pb;
    sun_jpeg_error_ptr jerr;
    boolean done;
    jint *bandSize;
    int maxBandValue, halfMaxBandValue;
    boolean mustScale = FALSE;
    boolean progressive = FALSE;
    boolean orderedBands = TRUE;
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_decompress_ptr cinfo;
    unsigned int numBytes;

    /* verify the inputs */

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return JNI_FALSE;
    }

    if ((buffer == NULL) || (srcBands == NULL))  {
        JNU_ThrowNullPointerException(env, 0);
        return JNI_FALSE;
    }

    cinfo = (j_decompress_ptr) data->jpegObj;

    if ((numBands < 1) ||
        (sourceXStart < 0) || (sourceXStart >= (jint)cinfo->image_width) ||
        (sourceYStart < 0) || (sourceYStart >= (jint)cinfo->image_height) ||
        (sourceWidth < 1) || (sourceWidth > (jint)cinfo->image_width) ||
        (sourceHeight < 1) || (sourceHeight > (jint)cinfo->image_height) ||
        (stepX < 1) || (stepY < 1) ||
        (minProgressivePass < 0) ||
        (maxProgressivePass < minProgressivePass))
    {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
                        "Invalid argument to native readImage");
        return JNI_FALSE;
    }

    if (stepX > cinfo->image_width) {
        stepX = cinfo->image_width;
    }
    if (stepY > cinfo->image_height) {
        stepY = cinfo->image_height;
    }

    /*
     * First get the source bands array and copy it to our local array
     * so we don't have to worry about pinning and unpinning it again.
     */

    body = (*env)->GetIntArrayElements(env, srcBands, NULL);
    if (body == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Read");
        return JNI_FALSE;
    }

    for (i = 0; i < numBands; i++) {
        bands[i] = body[i];
        if (orderedBands && (bands[i] != i)) {
            orderedBands = FALSE;
        }
    }

    (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT);

#ifdef DEBUG_IIO_JPEG
    printf("---- in reader.read ----\n");
    printf("numBands is %d\n", numBands);
    printf("bands array: ");
    for (i = 0; i < numBands; i++) {
        printf("%d ", bands[i]);
    }
    printf("\n");
    printf("jq table 0 at %p\n",
               cinfo->quant_tbl_ptrs[0]);
#endif

    data = (imageIODataPtr) cinfo->client_data;
    src = cinfo->src;

    /* Set the buffer as our PixelBuffer */
    pb = &data->pixelBuf;

    if (setPixelBuffer(env, pb, buffer) == NOT_OK) {
        return data->abortFlag;  // We already threw an out of memory exception
    }

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while reading. */
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                                          buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        if (scanLinePtr != NULL) {
            free(scanLinePtr);
            scanLinePtr = NULL;
        }
        return data->abortFlag;
    }

    if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
        JNU_ThrowByName(env,
                        "javax/imageio/IIOException",
                        "Array pin failed");
        return data->abortFlag;
    }

    // If there are no tables in our structure and table arguments aren't
    // NULL, use the table arguments.
    if ((qtables != NULL) && (cinfo->quant_tbl_ptrs[0] == NULL)) {
        (void) setQTables(env, (j_common_ptr) cinfo, qtables, TRUE);
    }

    if ((DCHuffmanTables != NULL) && (cinfo->dc_huff_tbl_ptrs[0] == NULL)) {
        setHTables(env, (j_common_ptr) cinfo,
                   DCHuffmanTables,
                   ACHuffmanTables,
                   TRUE);
    }

    progressive = jpeg_has_multiple_scans(cinfo);
    if (progressive) {
        cinfo->buffered_image = TRUE;
        cinfo->input_scan_number = minProgressivePass+1; // Java count from 0
#define MAX_JAVA_INT 2147483647 // XXX Is this defined in JNI somewhere?
        if (maxProgressivePass < MAX_JAVA_INT) {
            maxProgressivePass++; // For testing
        }
    }

    data->streamBuf.suspendable = FALSE;

    jpeg_start_decompress(cinfo);

    if (numBands !=  cinfo->output_components) {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
                        "Invalid argument to native readImage");
        return data->abortFlag;
    }


    // Allocate a 1-scanline buffer
    scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->output_components);
    if (scanLinePtr == NULL) {
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Reading JPEG Stream");
        return data->abortFlag;
    }

    // loop over progressive passes
    done = FALSE;
    while (!done) {
        if (progressive) {
            // initialize the next pass.  Note that this skips up to
            // the first interesting pass.
            jpeg_start_output(cinfo, cinfo->input_scan_number);
            if (wantUpdates) {
                (*env)->CallVoidMethod(env, this,
                                       JPEGImageReader_passStartedID,
                                       cinfo->input_scan_number-1);
            }
        } else if (wantUpdates) {
            (*env)->CallVoidMethod(env, this,
                                   JPEGImageReader_passStartedID,
                                   0);

        }

        // Skip until the first interesting line
        while ((data->abortFlag == JNI_FALSE)
               && ((jint)cinfo->output_scanline < sourceYStart)) {
            jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
        }

        scanlineLimit = sourceYStart+sourceHeight;
        pixelLimit = scanLinePtr
            +(sourceXStart+sourceWidth)*cinfo->output_components;

        pixelStride = stepX*cinfo->output_components;
        targetLine = 0;

        while ((data->abortFlag == JNI_FALSE)
               && ((jint)cinfo->output_scanline < scanlineLimit)) {

            jpeg_read_scanlines(cinfo, &scanLinePtr, 1);

            // Now mangle it into our buffer
            out = data->pixelBuf.buf.bp;

            if (orderedBands && (pixelStride == numBands)) {
                // Optimization: The component bands are ordered sequentially,
                // so we can simply use memcpy() to copy the intermediate
                // scanline buffer into the raster.
                in = scanLinePtr + (sourceXStart * cinfo->output_components);
                if (pixelLimit > in) {
                    numBytes = pixelLimit - in;
                    if (numBytes > data->pixelBuf.byteBufferLength) {
                        numBytes = data->pixelBuf.byteBufferLength;
                    }
                    memcpy(out, in, numBytes);
                }
            } else {
                numBytes = numBands;
                for (in = scanLinePtr+sourceXStart*cinfo->output_components;
                     in < pixelLimit &&
                       numBytes <= data->pixelBuf.byteBufferLength;
                     in += pixelStride) {
                    for (i = 0; i < numBands; i++) {
                        *out++ = *(in+bands[i]);
                    }
                    numBytes += numBands;
                }
            }

            // And call it back to Java
            RELEASE_ARRAYS(env, data, src->next_input_byte);
            (*env)->CallVoidMethod(env,
                                   this,
                                   JPEGImageReader_acceptPixelsID,
                                   targetLine++,
                                   progressive);

            if ((*env)->ExceptionOccurred(env)
                || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
                cinfo->err->error_exit((j_common_ptr) cinfo);
            }

            // And skip over uninteresting lines to the next subsampled line
            // Ensure we don't go past the end of the image

            // Lines to skip based on subsampling
            skipLines = stepY - 1;
            // Lines left in the image
            linesLeft =  scanlineLimit - cinfo->output_scanline;
            // Take the minimum
            if (skipLines > linesLeft) {
                skipLines = linesLeft;
            }
            for(i = 0; i < skipLines; i++) {
                jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
            }
        }
        if (progressive) {
            jpeg_finish_output(cinfo); // Increments pass counter
            // Call Java to notify pass complete
            if (jpeg_input_complete(cinfo)
                || (cinfo->input_scan_number > maxProgressivePass)) {
                done = TRUE;
            }
        } else {
            done = TRUE;
        }
        if (wantUpdates) {
            (*env)->CallVoidMethod(env, this,
                                   JPEGImageReader_passCompleteID);
        }

    }
    /*
     * We are done, but we might not have read all the lines, or all
     * the passes, so use jpeg_abort instead of jpeg_finish_decompress.
     */
    if (cinfo->output_scanline == cinfo->output_height) {
        //    if ((cinfo->output_scanline == cinfo->output_height) &&
        //(jpeg_input_complete(cinfo))) {  // We read the whole file
        jpeg_finish_decompress(cinfo);
    } else {
        jpeg_abort_decompress(cinfo);
    }

    free(scanLinePtr);

    RELEASE_ARRAYS(env, data, src->next_input_byte);

    return data->abortFlag;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead
    (JNIEnv *env,
     jobject this,
     jlong ptr) {

    imageIODataPtr data = (imageIODataPtr) ptr;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return;
    }

    imageio_abort(env, this, data);

}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetLibraryState
    (JNIEnv *env,
     jobject this,
     jlong ptr) {
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_decompress_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return;
    }

    cinfo = (j_decompress_ptr) data->jpegObj;

    jpeg_abort_decompress(cinfo);
}


JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetReader
    (JNIEnv *env,
     jobject this,
     jlong ptr) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_decompress_ptr cinfo;
    sun_jpeg_error_ptr jerr;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use reader after dispose()");
        return;
    }

    cinfo = (j_decompress_ptr) data->jpegObj;

    jerr = (sun_jpeg_error_ptr) cinfo->err;

    imageio_reset(env, (j_common_ptr) cinfo, data);

    /*
     * The tables have not been reset, and there is no way to do so
     * in IJG without leaking memory.  The only situation in which
     * this will cause a problem is if an image-only stream is read
     * with this object without initializing the correct tables first.
     * This situation, which should cause an error, might work but
     * produce garbage instead.  If the huffman tables are wrong,
     * it will fail during the decode.  If the q tables are wrong, it
     * will look strange.  This is very unlikely, so don't worry about
     * it.  To be really robust, we would keep a flag for table state
     * and consult it to catch exceptional situations.
     */

    /* above does not clean up the source, so we have to */

    /*
      We need to explicitly initialize exception handler or we may
       longjump to random address from the term_source()
     */

    if (setjmp(jerr->setjmp_buffer)) {

        /*
          We may get IOException from pushBack() here.

          However it could be legal if original input stream was closed
          earlier (for example because network connection was closed).
          Unfortunately, image inputstream API has no way to check whether
          stream is already closed or IOException was thrown because of some
          other IO problem,
          And we can not avoid call to pushBack() on closed stream for the
          same reason.

          So, for now we will silently eat this exception.

          NB: this may be changed in future when ImageInputStream API will
          become more flexible.
        */

        if ((*env)->ExceptionOccurred(env)) {
            (*env)->ExceptionClear(env);
        }
    } else {
        cinfo->src->term_source(cinfo);
    }

    cinfo->src->bytes_in_buffer = 0;
    cinfo->src->next_input_byte = NULL;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader
    (JNIEnv *env,
     jclass reader,
     jlong ptr) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_common_ptr info = destroyImageioData(env, data);

    imageio_dispose(info);
}

/********************** end of Reader *************************/

/********************** Writer Support ************************/

/********************** Destination Manager *******************/

METHODDEF(void)
/*
 * Initialize destination --- called by jpeg_start_compress
 * before any data is actually written.  The data arrays
 * must be pinned before this is called.
 */
imageio_init_destination (j_compress_ptr cinfo)
{
    struct jpeg_destination_mgr *dest = cinfo->dest;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if (sb->buf == NULL) {
        // We forgot to pin the array
        (*env)->FatalError(env, "Output buffer not pinned!");
    }

    dest->next_output_byte = sb->buf;
    dest->free_in_buffer = sb->bufferLength;
}

/*
 * Empty the output buffer --- called whenever buffer fills up.
 *
 * This routine writes the entire output buffer
 * (ignoring the current state of next_output_byte & free_in_buffer),
 * resets the pointer & count to the start of the buffer, and returns TRUE
 * indicating that the buffer has been dumped.
 */

METHODDEF(boolean)
imageio_empty_output_buffer (j_compress_ptr cinfo)
{
    struct jpeg_destination_mgr *dest = cinfo->dest;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));

    (*env)->CallVoidMethod(env,
                           sb->stream,
                           ImageOutputStream_writeID,
                           sb->hstreamBuffer,
                           0,
                           sb->bufferLength);
    if ((*env)->ExceptionOccurred(env)
        || !GET_ARRAYS(env, data,
                       (const JOCTET **)(&dest->next_output_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
    }

    dest->next_output_byte = sb->buf;
    dest->free_in_buffer = sb->bufferLength;

    return TRUE;
}

/*
 * After all of the data has been encoded there may still be some
 * more left over in some of the working buffers.  Now is the
 * time to clear them out.
 */
METHODDEF(void)
imageio_term_destination (j_compress_ptr cinfo)
{
    struct jpeg_destination_mgr *dest = cinfo->dest;
    imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
    streamBufferPtr sb = &data->streamBuf;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    /* find out how much needs to be written */
    jint datacount = sb->bufferLength - dest->free_in_buffer;

    if (datacount != 0) {
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));

        (*env)->CallVoidMethod(env,
                               sb->stream,
                               ImageOutputStream_writeID,
                               sb->hstreamBuffer,
                               0,
                               datacount);

        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data,
                           (const JOCTET **)(&dest->next_output_byte))) {
            cinfo->err->error_exit((j_common_ptr) cinfo);
        }
    }

    dest->next_output_byte = NULL;
    dest->free_in_buffer = 0;

}

/*
 * Flush the destination buffer.  This is not called by the library,
 * but by our code below.  This is the simplest implementation, though
 * certainly not the most efficient.
 */
METHODDEF(void)
imageio_flush_destination(j_compress_ptr cinfo)
{
    imageio_term_destination(cinfo);
    imageio_init_destination(cinfo);
}

/********************** end of destination manager ************/

/********************** Writer JNI calls **********************/


JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs
    (JNIEnv *env,
     jclass cls,
     jclass IOSClass,
     jclass qTableClass,
     jclass huffClass) {

    ImageOutputStream_writeID = (*env)->GetMethodID(env,
                                                    IOSClass,
                                                    "write",
                                                    "([BII)V");

    JPEGImageWriter_warningOccurredID = (*env)->GetMethodID(env,
                                                            cls,
                                                            "warningOccurred",
                                                            "(I)V");
    JPEGImageWriter_warningWithMessageID =
        (*env)->GetMethodID(env,
                            cls,
                            "warningWithMessage",
                            "(Ljava/lang/String;)V");

    JPEGImageWriter_writeMetadataID = (*env)->GetMethodID(env,
                                                          cls,
                                                          "writeMetadata",
                                                          "()V");
    JPEGImageWriter_grabPixelsID = (*env)->GetMethodID(env,
                                                       cls,
                                                       "grabPixels",
                                                       "(I)V");

    JPEGQTable_tableID = (*env)->GetFieldID(env,
                                            qTableClass,
                                            "qTable",
                                            "[I");

    JPEGHuffmanTable_lengthsID = (*env)->GetFieldID(env,
                                                    huffClass,
                                                    "lengths",
                                                    "[S");

    JPEGHuffmanTable_valuesID = (*env)->GetFieldID(env,
                                                    huffClass,
                                                    "values",
                                                    "[S");
}

JNIEXPORT jlong JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter
    (JNIEnv *env,
     jobject this) {

    imageIODataPtr ret;
    struct sun_jpeg_error_mgr *jerr;
    struct jpeg_destination_mgr *dest;

    /* This struct contains the JPEG compression parameters and pointers to
     * working space (which is allocated as needed by the JPEG library).
     */
    struct jpeg_compress_struct *cinfo =
        malloc(sizeof(struct jpeg_compress_struct));
    if (cinfo == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Writer");
        return 0;
    }

    /* We use our private extension JPEG error handler.
     */
    jerr = malloc (sizeof(struct sun_jpeg_error_mgr));
    if (jerr == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Writer");
        free(cinfo);
        return 0;
    }

    /* We set up the normal JPEG error routines, then override error_exit. */
    cinfo->err = jpeg_std_error(&(jerr->pub));
    jerr->pub.error_exit = sun_jpeg_error_exit;
    /* We need to setup our own print routines */
    jerr->pub.output_message = sun_jpeg_output_message;
    /* Now we can setjmp before every call to the library */

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error. */
        char buffer[JMSG_LENGTH_MAX];
        (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                                      buffer);
        JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        return 0;
    }

    /* Perform library initialization */
    jpeg_create_compress(cinfo);

    /* Now set up the destination  */
    dest = malloc(sizeof(struct jpeg_destination_mgr));
    if (dest == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Writer");
        imageio_dispose((j_common_ptr)cinfo);
        return 0;
    }

    dest->init_destination = imageio_init_destination;
    dest->empty_output_buffer = imageio_empty_output_buffer;
    dest->term_destination = imageio_term_destination;
    dest->next_output_byte = NULL;
    dest->free_in_buffer = 0;

    cinfo->dest = dest;

    /* set up the association to persist for future calls */
    ret = initImageioData(env, (j_common_ptr) cinfo, this);
    if (ret == NULL) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Writer");
        imageio_dispose((j_common_ptr)cinfo);
        return 0;
    }
    return (jlong) ret;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jobject destination) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_compress_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use writer after dispose()");
        return;
    }

    cinfo = (j_compress_ptr) data->jpegObj;

    imageio_set_stream(env, data->jpegObj, data, destination);


    // Don't call the init method, as that depends on pinned arrays
    cinfo->dest->next_output_byte = NULL;
    cinfo->dest->free_in_buffer = 0;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeTables
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jobjectArray qtables,
     jobjectArray DCHuffmanTables,
     jobjectArray ACHuffmanTables) {

    struct jpeg_destination_mgr *dest;
    sun_jpeg_error_ptr jerr;
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_compress_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use writer after dispose()");
        return;
    }

    cinfo = (j_compress_ptr) data->jpegObj;
    dest = cinfo->dest;

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while writing. */
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) ((j_common_ptr) cinfo,
                                          buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        return;
    }

    if (GET_ARRAYS(env, data,
                   (const JOCTET **)(&dest->next_output_byte)) == NOT_OK) {
        JNU_ThrowByName(env,
                        "javax/imageio/IIOException",
                        "Array pin failed");
        return;
    }

    jpeg_suppress_tables(cinfo, TRUE);  // Suppress writing of any current

    data->streamBuf.suspendable = FALSE;
    if (qtables != NULL) {
#ifdef DEBUG_IIO_JPEG
        printf("in writeTables: qtables not NULL\n");
#endif
        setQTables(env, (j_common_ptr) cinfo, qtables, TRUE);
    }

    if (DCHuffmanTables != NULL) {
        setHTables(env, (j_common_ptr) cinfo,
                   DCHuffmanTables, ACHuffmanTables, TRUE);
    }

    jpeg_write_tables(cinfo); // Flushes the buffer for you
    RELEASE_ARRAYS(env, data, NULL);
}

JNIEXPORT jboolean JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage
    (JNIEnv *env,
     jobject this,
     jlong ptr,
     jbyteArray buffer,
     jint inCs, jint outCs,
     jint numBands,
     jintArray bandSizes,
     jint srcWidth,
     jint destWidth, jint destHeight,
     jint stepX, jint stepY,
     jobjectArray qtables,
     jboolean writeDQT,
     jobjectArray DCHuffmanTables,
     jobjectArray ACHuffmanTables,
     jboolean writeDHT,
     jboolean optimize,
     jboolean progressive,
     jint numScans,
     jintArray scanInfo,
     jintArray componentIds,
     jintArray HsamplingFactors,
     jintArray VsamplingFactors,
     jintArray QtableSelectors,
     jboolean haveMetadata,
     jint restartInterval) {

    struct jpeg_destination_mgr *dest;
    JSAMPROW scanLinePtr;
    int i, j;
    int pixelStride;
    unsigned char *in, *out, *pixelLimit;
    int targetLine;
    pixelBufferPtr pb;
    sun_jpeg_error_ptr jerr;
    jint *ids, *hfactors, *vfactors, *qsels;
    jsize qlen, hlen;
    int *scanptr;
    jint *scanData;
    jint *bandSize;
    int maxBandValue, halfMaxBandValue;
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_compress_ptr cinfo;
    UINT8** scale = NULL;

    /* verify the inputs */

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use writer after dispose()");
        return JNI_FALSE;
    }

    if ((buffer == NULL) ||
        (qtables == NULL) ||
        // H tables can be null if optimizing
        (componentIds == NULL) ||
        (HsamplingFactors == NULL) || (VsamplingFactors == NULL) ||
        (QtableSelectors == NULL) ||
        ((numScans != 0) && (scanInfo != NULL))) {

        JNU_ThrowNullPointerException(env, 0);
        return JNI_FALSE;

    }

    if ((inCs < 0) || (inCs > JCS_YCCK) ||
        (outCs < 0) || (outCs > JCS_YCCK) ||
        (numBands < 1) || (numBands > MAX_BANDS) ||
        (srcWidth < 0) ||
        (destWidth < 0) || (destWidth > srcWidth) ||
        (destHeight < 0) ||
        (stepX < 0) || (stepY < 0))
    {
        JNU_ThrowByName(env, "javax/imageio/IIOException",
                        "Invalid argument to native writeImage");
        return JNI_FALSE;
    }

    bandSize = (*env)->GetIntArrayElements(env, bandSizes, NULL);

    for (i = 0; i < numBands; i++) {
        if (bandSize[i] != JPEG_BAND_SIZE) {
            if (scale == NULL) {
                scale = (UINT8**) calloc(numBands, sizeof(UINT8*));

                if (scale == NULL) {
                    JNU_ThrowByName( env, "java/lang/OutOfMemoryError",
                                     "Writing JPEG Stream");
                    return JNI_FALSE;
                }
            }

            maxBandValue = (1 << bandSize[i]) - 1;

            scale[i] = (UINT8*) malloc((maxBandValue + 1) * sizeof(UINT8));

            if (scale[i] == NULL) {
                JNU_ThrowByName( env, "java/lang/OutOfMemoryError",
                                 "Writing JPEG Stream");
                return JNI_FALSE;
            }

            halfMaxBandValue = maxBandValue >> 1;

            for (j = 0; j <= maxBandValue; j++) {
                scale[i][j] = (UINT8)
                    ((j*MAX_JPEG_BAND_VALUE + halfMaxBandValue)/maxBandValue);
            }
        }
    }

    (*env)->ReleaseIntArrayElements(env, bandSizes,
                                    bandSize, JNI_ABORT);

    cinfo = (j_compress_ptr) data->jpegObj;
    dest = cinfo->dest;

    /* Set the buffer as our PixelBuffer */
    pb = &data->pixelBuf;

    if (setPixelBuffer(env, pb, buffer) == NOT_OK) {
        return data->abortFlag;  // We already threw an out of memory exception
    }

    // Allocate a 1-scanline buffer
    scanLinePtr = (JSAMPROW)malloc(destWidth*numBands);
    if (scanLinePtr == NULL) {
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Writing JPEG Stream");
        return data->abortFlag;
    }

    /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
    jerr = (sun_jpeg_error_ptr) cinfo->err;

    if (setjmp(jerr->setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error
           while writing. */
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
        if (!(*env)->ExceptionOccurred(env)) {
            char buffer[JMSG_LENGTH_MAX];
            (*cinfo->err->format_message) ((j_common_ptr) cinfo,
                                          buffer);
            JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
        }
        free(scanLinePtr);
        return data->abortFlag;
    }

    // set up parameters
    cinfo->image_width = destWidth;
    cinfo->image_height = destHeight;
    cinfo->input_components = numBands;
    cinfo->in_color_space = inCs;

    jpeg_set_defaults(cinfo);

    jpeg_set_colorspace(cinfo, outCs);

    cinfo->optimize_coding = optimize;

    cinfo->write_JFIF_header = FALSE;
    cinfo->write_Adobe_marker = FALSE;
    // copy componentIds
    ids = (*env)->GetIntArrayElements(env, componentIds, NULL);
    hfactors = (*env)->GetIntArrayElements(env, HsamplingFactors, NULL);
    vfactors = (*env)->GetIntArrayElements(env, VsamplingFactors, NULL);
    qsels = (*env)->GetIntArrayElements(env, QtableSelectors, NULL);

    if ((ids == NULL) ||
        (hfactors == NULL) || (vfactors == NULL) ||
        (qsels == NULL)) {
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Writing JPEG");
        return JNI_FALSE;
    }

    for (i = 0; i < numBands; i++) {
        cinfo->comp_info[i].component_id = ids[i];
        cinfo->comp_info[i].h_samp_factor = hfactors[i];
        cinfo->comp_info[i].v_samp_factor = vfactors[i];
        cinfo->comp_info[i].quant_tbl_no = qsels[i];
    }

    (*env)->ReleaseIntArrayElements(env, componentIds,
                                    ids, JNI_ABORT);
    (*env)->ReleaseIntArrayElements(env, HsamplingFactors,
                                    hfactors, JNI_ABORT);
    (*env)->ReleaseIntArrayElements(env, VsamplingFactors,
                                    vfactors, JNI_ABORT);
    (*env)->ReleaseIntArrayElements(env, QtableSelectors,
                                    qsels, JNI_ABORT);

    jpeg_suppress_tables(cinfo, TRUE);  // Disable writing any current

    qlen = setQTables(env, (j_common_ptr) cinfo, qtables, writeDQT);

    if (!optimize) {
        // Set the h tables
        hlen = setHTables(env,
                          (j_common_ptr) cinfo,
                          DCHuffmanTables,
                          ACHuffmanTables,
                          writeDHT);
    }

    if (GET_ARRAYS(env, data,
                   (const JOCTET **)(&dest->next_output_byte)) == NOT_OK) {
        JNU_ThrowByName(env,
                        "javax/imageio/IIOException",
                        "Array pin failed");
        return data->abortFlag;
    }

    data->streamBuf.suspendable = FALSE;

    if (progressive) {
        if (numScans == 0) { // then use default scans
            jpeg_simple_progression(cinfo);
        } else {
            cinfo->num_scans = numScans;
            // Copy the scanInfo to a local array
            // The following is copied from jpeg_simple_progression:
  /* Allocate space for script.
   * We need to put it in the permanent pool in case the application performs
   * multiple compressions without changing the settings.  To avoid a memory
   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
   * object, we try to re-use previously allocated space, and we allocate
   * enough space to handle YCbCr even if initially asked for grayscale.
   */
            if (cinfo->script_space == NULL
                || cinfo->script_space_size < numScans) {
                cinfo->script_space_size = MAX(numScans, 10);
                cinfo->script_space = (jpeg_scan_info *)
                    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
                                                JPOOL_PERMANENT,
                                                cinfo->script_space_size
                                                * sizeof(jpeg_scan_info));
            }
            cinfo->scan_info = cinfo->script_space;
            scanptr = (int *) cinfo->script_space;
            scanData = (*env)->GetIntArrayElements(env, scanInfo, NULL);
            // number of jints per scan is 9
            // We avoid a memcpy to handle different size ints
            for (i = 0; i < numScans*9; i++) {
                scanptr[i] = scanData[i];
            }
            (*env)->ReleaseIntArrayElements(env, scanInfo,
                                            scanData, JNI_ABORT);

        }
    }

    cinfo->restart_interval = restartInterval;

#ifdef DEBUG_IIO_JPEG
    printf("writer setup complete, starting compressor\n");
#endif

    // start the compressor; tables must already be set
    jpeg_start_compress(cinfo, FALSE); // Leaves sent_table alone

    if (haveMetadata) {
        // Flush the buffer
        imageio_flush_destination(cinfo);
        // Call Java to write the metadata
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
        (*env)->CallVoidMethod(env,
                               this,
                               JPEGImageWriter_writeMetadataID);
        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data,
                           (const JOCTET **)(&dest->next_output_byte))) {
                cinfo->err->error_exit((j_common_ptr) cinfo);
         }
    }

    targetLine = 0;

    // for each line in destHeight
    while ((data->abortFlag == JNI_FALSE)
           && (cinfo->next_scanline < cinfo->image_height)) {
        // get the line from Java
        RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
        (*env)->CallVoidMethod(env,
                               this,
                               JPEGImageWriter_grabPixelsID,
                               targetLine);
        if ((*env)->ExceptionOccurred(env)
            || !GET_ARRAYS(env, data,
                           (const JOCTET **)(&dest->next_output_byte))) {
                cinfo->err->error_exit((j_common_ptr) cinfo);
         }

        // subsample it into our buffer

        in = data->pixelBuf.buf.bp;
        out = scanLinePtr;
        pixelLimit = in + srcWidth*numBands;
        pixelStride = numBands*stepX;
        for (; in < pixelLimit; in += pixelStride) {
            for (i = 0; i < numBands; i++) {
                if (scale !=NULL && scale[i] != NULL) {
                    *out++ = scale[i][*(in+i)];
#ifdef DEBUG_IIO_JPEG
                    if (in == data->pixelBuf.buf.bp){ // Just the first pixel
                        printf("in %d -> out %d, ", *(in+i), *(out-i-1));
                    }
#endif

#ifdef DEBUG_IIO_JPEG
                    if (in == data->pixelBuf.buf.bp){ // Just the first pixel
                        printf("\n");
                    }
#endif
                } else {
                    *out++ = *(in+i);
                }
            }
        }
        // write it out
        jpeg_write_scanlines(cinfo, (JSAMPARRAY)&scanLinePtr, 1);
        targetLine += stepY;
    }

    /*
     * We are done, but we might not have done all the lines,
     * so use jpeg_abort instead of jpeg_finish_compress.
     */
    if (cinfo->next_scanline == cinfo->image_height) {
        jpeg_finish_compress(cinfo);  // Flushes buffer with term_dest
    } else {
        jpeg_abort((j_common_ptr)cinfo);
    }

    if (scale != NULL) {
        for (i = 0; i < numBands; i++) {
            if (scale[i] != NULL) {
                free(scale[i]);
            }
        }
        free(scale);
    }

    free(scanLinePtr);
    RELEASE_ARRAYS(env, data, NULL);
    return data->abortFlag;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_abortWrite
    (JNIEnv *env,
     jobject this,
     jlong ptr) {

    imageIODataPtr data = (imageIODataPtr) ptr;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use writer after dispose()");
        return;
    }

    imageio_abort(env, this, data);
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_resetWriter
    (JNIEnv *env,
     jobject this,
     jlong ptr) {
    imageIODataPtr data = (imageIODataPtr) ptr;
    j_compress_ptr cinfo;

    if (data == NULL) {
        JNU_ThrowByName(env,
                        "java/lang/IllegalStateException",
                        "Attempting to use writer after dispose()");
        return;
    }

    cinfo = (j_compress_ptr) data->jpegObj;

    imageio_reset(env, (j_common_ptr) cinfo, data);

    /*
     * The tables have not been reset, and there is no way to do so
     * in IJG without leaking memory.  The only situation in which
     * this will cause a problem is if an image-only stream is written
     * with this object without initializing the correct tables first,
     * which should not be possible.
     */

    cinfo->dest->next_output_byte = NULL;
    cinfo->dest->free_in_buffer = 0;
}

JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_disposeWriter
    (JNIEnv *env,
     jclass writer,
     jlong ptr) {

    imageIODataPtr data = (imageIODataPtr) ptr;
    j_common_ptr info = destroyImageioData(env, data);

    imageio_dispose(info);
}
