/*
 * Copyright 2000-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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
    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->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;
    }
    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;
    }
}

/*
 * 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
    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
    printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
#endif
    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);
    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);

    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);
    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);
    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
    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
      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
      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 seq_no;
    JOCTET *icc_data;
    unsigned int total_length;
#define MAX_SEQ_NO  255         // sufficient since marker numbers are bytes
    char marker_present[MAX_SEQ_NO+1];    // 1 if marker found
    unsigned int data_length[MAX_SEQ_NO+1]; // size of profile data in marker
    unsigned int data_offset[MAX_SEQ_NO+1]; // offset for data in marker
    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 = 1; seq_no <= MAX_SEQ_NO; seq_no++)
        marker_present[seq_no] = 0;

    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]);
            if (seq_no <= 0 || seq_no > num_markers) {
                JNU_ThrowByName(env, "javax/imageio/IIOException",
                     "Invalid icc profile: bad sequence number");
                return NULL;
            }
            if (marker_present[seq_no]) {
                JNU_ThrowByName(env, "javax/imageio/IIOException",
                     "Invalid icc profile: duplicate sequence numbers");
                return NULL;
            }
            marker_present[seq_no] = 1;
            data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
        }
    }

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

    /* Check for missing markers, count total space needed,
     * compute offset of each marker's part of the data.
     */

    total_length = 0;
    for (seq_no = 1; seq_no <= num_markers; seq_no++) {
        if (marker_present[seq_no] == 0) {
            JNU_ThrowByName(env, "javax/imageio/IIOException",
                 "Invalid icc profile: missing sequence number");
            return NULL;
        }
        data_offset[seq_no] = total_length;
        total_length += data_length[seq_no];
    }

    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 */
    for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
        if (marker_is_icc(marker)) {
            JOCTET FAR *src_ptr;
            JOCTET *dst_ptr;
            unsigned int length;
            seq_no = GETJOCTET(marker->data[12]);
            dst_ptr = icc_data + data_offset[seq_no];
            src_ptr = marker->data + ICC_OVERHEAD_LEN;
            length = data_length[seq_no];
            while (length--) {
                *dst_ptr++ = *src_ptr++;
            }
        }
    }

    /* 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");
        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");
        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");
        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;

    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
    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
        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);
        (*env)->CallVoidMethod(env, this,
                               JPEGImageReader_setImageDataID,
                               cinfo->image_width,
                               cinfo->image_height,
                               cinfo->jpeg_color_space,
                               cinfo->out_color_space,
                               cinfo->num_components,
                               read_icc_profile(env, cinfo));
        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;
    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;

    /* 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) || (numBands > cinfo->num_components) ||
        (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;
    }

    /*
     * 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
    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
    }

    // Allocate a 1-scanline buffer
    scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->num_components);
    if (scanLinePtr == NULL) {
        RELEASE_ARRAYS(env, data, src->next_input_byte);
        JNU_ThrowByName( env,
                         "java/lang/OutOfMemoryError",
                         "Reading 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 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);
        }
        free(scanLinePtr);
        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);

    // 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->num_components;

        pixelStride = stepX*cinfo->num_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->num_components);
                if (pixelLimit > in) {
                    memcpy(out, in, pixelLimit - in);
                }
            } else {
                for (in = scanLinePtr+sourceXStart*cinfo->num_components;
                     in < pixelLimit;
                     in += pixelStride) {
                    for (i = 0; i < numBands; i++) {
                        *out++ = *(in+bands[i]);
                    }
                }
            }

            // 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");
        free(cinfo);
        free(jerr);
        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");
        free(cinfo);
        free(jerr);
        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
        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
    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
                    if (in == data->pixelBuf.buf.bp){ // Just the first pixel
                        printf("in %d -> out %d, ", *(in+i), *(out-i-1));
                    }
#endif

#ifdef DEBUG
                    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);
}
