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

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "sun_java2d_cmm_lcms_LCMS.h"
#include "jni_util.h"
#include "Trace.h"
#include "Disposer.h"
#include "lcms2.h"
#include "jlong.h"


#define ALIGNLONG(x) (((x)+3) & ~(3))         // Aligns to DWORD boundary

#ifdef USE_BIG_ENDIAN
#define AdjustEndianess32(a)
#else

static
void AdjustEndianess32(cmsUInt8Number *pByte)
{
    cmsUInt8Number temp1;
    cmsUInt8Number temp2;

    temp1 = *pByte++;
    temp2 = *pByte++;
    *(pByte-1) = *pByte;
    *pByte++ = temp2;
    *(pByte-3) = *pByte;
    *pByte = temp1;
}

#endif

// Transports to properly encoded values - note that icc profiles does use
// big endian notation.

static
cmsInt32Number TransportValue32(cmsInt32Number Value)
{
    cmsInt32Number Temp = Value;

    AdjustEndianess32((cmsUInt8Number*) &Temp);
    return Temp;
}

#define SigMake(a,b,c,d) \
                    ( ( ((int) ((unsigned char) (a))) << 24) | \
                      ( ((int) ((unsigned char) (b))) << 16) | \
                      ( ((int) ((unsigned char) (c))) <<  8) | \
                          (int) ((unsigned char) (d)))

#define TagIdConst(a, b, c, d) \
                ((int) SigMake ((a), (b), (c), (d)))

#define SigHead TagIdConst('h','e','a','d')

#define DT_BYTE     0
#define DT_SHORT    1
#define DT_INT      2
#define DT_DOUBLE   3

/* Default temp profile list size */
#define DF_ICC_BUF_SIZE 32

#define ERR_MSG_SIZE 256

#ifdef _MSC_VER
# ifndef snprintf
#       define snprintf  _snprintf
# endif
#endif

typedef struct lcmsProfile_s {
    cmsHPROFILE pf;
} lcmsProfile_t, *lcmsProfile_p;

typedef union {
    cmsTagSignature cms;
    jint j;
} TagSignature_t, *TagSignature_p;

static jfieldID Trans_renderType_fID;
static jfieldID Trans_ID_fID;
static jfieldID IL_isIntPacked_fID;
static jfieldID IL_dataType_fID;
static jfieldID IL_pixelType_fID;
static jfieldID IL_dataArray_fID;
static jfieldID IL_offset_fID;
static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
static jfieldID IL_imageAtOnce_fID;

JavaVM *javaVM;

void errorHandler(cmsContext ContextID, cmsUInt32Number errorCode,
                  const char *errorText) {
    JNIEnv *env;
    char errMsg[ERR_MSG_SIZE];

    int count = snprintf(errMsg, ERR_MSG_SIZE,
                          "LCMS error %d: %s", errorCode, errorText);
    if (count < 0 || count >= ERR_MSG_SIZE) {
        count = ERR_MSG_SIZE - 1;
    }
    errMsg[count] = 0;

    (*javaVM)->AttachCurrentThread(javaVM, (void**)&env, NULL);
    JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    javaVM = jvm;

    cmsSetLogErrorHandler(errorHandler);
    return JNI_VERSION_1_6;
}

void LCMS_freeProfile(JNIEnv *env, jlong ptr) {
    lcmsProfile_p p = (lcmsProfile_p)jlong_to_ptr(ptr);

    if (p != NULL) {
        if (p->pf != NULL) {
            cmsCloseProfile(p->pf);
        }
        free(p);
    }
}

void LCMS_freeTransform(JNIEnv *env, jlong ID)
{
    cmsHTRANSFORM sTrans = jlong_to_ptr(ID);
    /* Passed ID is always valid native ref so there is no check for zero */
    cmsDeleteTransform(sTrans);
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    createNativeTransform
 * Signature: ([JI)J
 */
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
  (JNIEnv *env, jclass cls, jlongArray profileIDs, jint renderType,
   jint inFormatter, jboolean isInIntPacked,
   jint outFormatter, jboolean isOutIntPacked, jobject disposerRef)
{
    cmsHPROFILE _iccArray[DF_ICC_BUF_SIZE];
    cmsHPROFILE *iccArray = &_iccArray[0];
    cmsHTRANSFORM sTrans = NULL;
    int i, j, size;
    jlong* ids;

    size = (*env)->GetArrayLength (env, profileIDs);
    ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
    if (ids == NULL) {
        // An exception should have already been thrown.
        return 0L;
    }

#ifdef _LITTLE_ENDIAN
    /* Reversing data packed into int for LE archs */
    if (isInIntPacked) {
        inFormatter ^= DOSWAP_SH(1);
    }
    if (isOutIntPacked) {
        outFormatter ^= DOSWAP_SH(1);
    }
#endif

    if (DF_ICC_BUF_SIZE < size*2) {
        iccArray = (cmsHPROFILE*) malloc(
            size*2*sizeof(cmsHPROFILE));
        if (iccArray == NULL) {
            (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);

            J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
            return 0L;
        }
    }

    j = 0;
    for (i = 0; i < size; i++) {
        cmsColorSpaceSignature cs;
        lcmsProfile_p profilePtr = (lcmsProfile_p)jlong_to_ptr(ids[i]);
        cmsHPROFILE icc = profilePtr->pf;

        iccArray[j++] = icc;

        /* Middle non-abstract profiles should be doubled before passing to
         * the cmsCreateMultiprofileTransform function
         */

        cs = cmsGetColorSpace(icc);
        if (size > 2 && i != 0 && i != size - 1 &&
            cs != cmsSigXYZData && cs != cmsSigLabData)
        {
            iccArray[j++] = icc;
        }
    }

    sTrans = cmsCreateMultiprofileTransform(iccArray, j,
        inFormatter, outFormatter, renderType, 0);

    (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);

    if (sTrans == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
                                       "sTrans == NULL");
        if ((*env)->ExceptionOccurred(env) == NULL) {
            JNU_ThrowByName(env, "java/awt/color/CMMException",
                            "Cannot get color transform");
        }
    } else {
        Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, ptr_to_jlong(sTrans));
    }

    if (iccArray != &_iccArray[0]) {
        free(iccArray);
    }
    return ptr_to_jlong(sTrans);
}


/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    loadProfile
 * Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
 */
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
  (JNIEnv *env, jobject obj, jbyteArray data, jobject disposerRef)
{
    jbyte* dataArray;
    jint dataSize;
    lcmsProfile_p sProf = NULL;
    cmsHPROFILE pf;

    if (JNU_IsNull(env, data)) {
        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
        return 0L;
    }

    dataArray = (*env)->GetByteArrayElements (env, data, 0);
    if (dataArray == NULL) {
        // An exception should have already been thrown.
        return 0L;
    }

    dataSize = (*env)->GetArrayLength (env, data);

    pf = cmsOpenProfileFromMem((const void *)dataArray,
                                     (cmsUInt32Number) dataSize);

    (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);

    if (pf == NULL) {
        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
    } else {
        /* Sanity check: try to save the profile in order
         * to force basic validation.
         */
        cmsUInt32Number pfSize = 0;
        if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
            pfSize < sizeof(cmsICCHeader))
        {
            JNU_ThrowIllegalArgumentException(env, "Invalid profile data");

            cmsCloseProfile(pf);
            pf = NULL;
        }
    }

    if (pf != NULL) {
        // create profile holder
        sProf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t));
        if (sProf != NULL) {
            // register the disposer record
            sProf->pf = pf;
            Disposer_AddRecord(env, disposerRef, LCMS_freeProfile, ptr_to_jlong(sProf));
        } else {
            cmsCloseProfile(pf);
        }
    }

    return ptr_to_jlong(sProf);
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    getProfileSizeNative
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative
  (JNIEnv *env, jobject obj, jlong id)
{
    lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
    cmsUInt32Number pfSize = 0;

    if (cmsSaveProfileToMem(sProf->pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
        return (jint)pfSize;
    } else {
      JNU_ThrowByName(env, "java/awt/color/CMMException",
                      "Can not access specified profile.");
        return -1;
    }
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    getProfileDataNative
 * Signature: (J[B)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
  (JNIEnv *env, jobject obj, jlong id, jbyteArray data)
{
    lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
    jint size;
    jbyte* dataArray;
    cmsUInt32Number pfSize = 0;
    cmsBool status;

    // determine actual profile size
    if (!cmsSaveProfileToMem(sProf->pf, NULL, &pfSize)) {
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Can not access specified profile.");
        return;
    }

    // verify java buffer capacity
    size = (*env)->GetArrayLength(env, data);
    if (0 >= size || pfSize > (cmsUInt32Number)size) {
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Insufficient buffer capacity.");
        return;
    }

    dataArray = (*env)->GetByteArrayElements (env, data, 0);
    if (dataArray == NULL) {
        // An exception should have already been thrown.
        return;
    }

    status = cmsSaveProfileToMem(sProf->pf, dataArray, &pfSize);

    (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);

    if (!status) {
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Can not access specified profile.");
        return;
    }
}

/* Get profile header info */
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);


/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    getTagData
 * Signature: (JI[B)V
 */
JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
  (JNIEnv *env, jobject obj, jlong id, jint tagSig)
{
    lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
    TagSignature_t sig;
    cmsInt32Number tagSize;

    jbyte* dataArray = NULL;
    jbyteArray data = NULL;

    jint bufSize;

    sig.j = tagSig;

    if (tagSig == SigHead) {
        cmsBool status;

        // allocate java array
        bufSize = sizeof(cmsICCHeader);
        data = (*env)->NewByteArray(env, bufSize);

        if (data == NULL) {
            // An exception should have already been thrown.
            return NULL;
        }

        dataArray = (*env)->GetByteArrayElements (env, data, 0);

        if (dataArray == NULL) {
            // An exception should have already been thrown.
            return NULL;
        }

        status = _getHeaderInfo(sProf->pf, dataArray, bufSize);

        (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);

        if (!status) {
            JNU_ThrowByName(env, "java/awt/color/CMMException",
                            "ICC Profile header not found");
            return NULL;
        }

        return data;
    }

    if (cmsIsTag(sProf->pf, sig.cms)) {
        tagSize = cmsReadRawTag(sProf->pf, sig.cms, NULL, 0);
    } else {
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "ICC profile tag not found");
        return NULL;
    }

    // allocate java array
    data = (*env)->NewByteArray(env, tagSize);
    if (data == NULL) {
        // An exception should have already been thrown.
        return NULL;
    }

    dataArray = (*env)->GetByteArrayElements (env, data, 0);

    if (dataArray == NULL) {
        // An exception should have already been thrown.
        return NULL;
    }

    bufSize = cmsReadRawTag(sProf->pf, sig.cms, dataArray, tagSize);

    (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);

    if (bufSize != tagSize) {
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Can not get tag data.");
        return NULL;
    }
    return data;
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    setTagData
 * Signature: (JI[B)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
  (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
    lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
    cmsHPROFILE pfReplace = NULL;

    TagSignature_t sig;
    cmsBool status = FALSE;
    jbyte* dataArray;
    int tagSize;

    sig.j = tagSig;

    if (JNU_IsNull(env, data)) {
        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
        return;
    }

    tagSize =(*env)->GetArrayLength(env, data);

    dataArray = (*env)->GetByteArrayElements(env, data, 0);

    if (dataArray == NULL) {
        // An exception should have already been thrown.
        return;
    }

    if (tagSig == SigHead) {
        status  = _setHeaderInfo(sProf->pf, dataArray, tagSize);
    } else {
        /*
        * New strategy for generic tags: create a place holder,
        * dump all existing tags there, dump externally supplied
        * tag, and return the new profile to the java.
        */
        pfReplace = _writeCookedTag(sProf->pf, sig.cms, dataArray, tagSize);
        status = (pfReplace != NULL);
    }

    (*env)->ReleaseByteArrayElements(env, data, dataArray, 0);

    if (!status) {
        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
    } else if (pfReplace != NULL) {
        cmsCloseProfile(sProf->pf);
        sProf->pf = pfReplace;
    }
}

void* getILData (JNIEnv *env, jobject img, jint* pDataType,
                 jobject* pDataObject) {
    void* result = NULL;
    *pDataType = (*env)->GetIntField (env, img, IL_dataType_fID);
    *pDataObject = (*env)->GetObjectField(env, img, IL_dataArray_fID);
    switch (*pDataType) {
        case DT_BYTE:
            result = (*env)->GetByteArrayElements (env, *pDataObject, 0);
            break;
        case DT_SHORT:
            result = (*env)->GetShortArrayElements (env, *pDataObject, 0);
            break;
        case DT_INT:
            result = (*env)->GetIntArrayElements (env, *pDataObject, 0);
            break;
        case DT_DOUBLE:
            result = (*env)->GetDoubleArrayElements (env, *pDataObject, 0);
            break;
    }

    return result;
}

void releaseILData (JNIEnv *env, void* pData, jint dataType,
                    jobject dataObject) {
    switch (dataType) {
        case DT_BYTE:
            (*env)->ReleaseByteArrayElements(env,dataObject,(jbyte*)pData,0);
            break;
        case DT_SHORT:
            (*env)->ReleaseShortArrayElements(env,dataObject,(jshort*)pData, 0);
            break;
        case DT_INT:
            (*env)->ReleaseIntArrayElements(env,dataObject,(jint*)pData,0);
            break;
        case DT_DOUBLE:
            (*env)->ReleaseDoubleArrayElements(env,dataObject,(jdouble*)pData,
                                               0);
            break;
    }
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    colorConvert
 * Signature: (Lsun/java2d/cmm/lcms/LCMSTransform;Lsun/java2d/cmm/lcms/LCMSImageLayout;Lsun/java2d/cmm/lcms/LCMSImageLayout;)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
  (JNIEnv *env, jclass obj, jobject trans, jobject src, jobject dst)
{
    cmsHTRANSFORM sTrans = NULL;
    int srcDType, dstDType;
    int srcOffset, srcNextRowOffset, dstOffset, dstNextRowOffset;
    int width, height, i;
    void* inputBuffer;
    void* outputBuffer;
    char* inputRow;
    char* outputRow;
    jobject srcData, dstData;
    jboolean srcAtOnce = JNI_FALSE, dstAtOnce = JNI_FALSE;

    srcOffset = (*env)->GetIntField (env, src, IL_offset_fID);
    srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID);
    dstOffset = (*env)->GetIntField (env, dst, IL_offset_fID);
    dstNextRowOffset = (*env)->GetIntField (env, dst, IL_nextRowOffset_fID);
    width = (*env)->GetIntField (env, src, IL_width_fID);
    height = (*env)->GetIntField (env, src, IL_height_fID);

    srcAtOnce = (*env)->GetBooleanField(env, src, IL_imageAtOnce_fID);
    dstAtOnce = (*env)->GetBooleanField(env, dst, IL_imageAtOnce_fID);

    sTrans = jlong_to_ptr((*env)->GetLongField (env, trans, Trans_ID_fID));

    if (sTrans == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_colorConvert: transform == NULL");
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Cannot get color transform");
        return;
    }


    inputBuffer = getILData (env, src, &srcDType, &srcData);

    if (inputBuffer == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR, "");
        // An exception should have already been thrown.
        return;
    }

    outputBuffer = getILData (env, dst, &dstDType, &dstData);

    if (outputBuffer == NULL) {
        releaseILData(env, inputBuffer, srcDType, srcData);
        // An exception should have already been thrown.
        return;
    }

    inputRow = (char*)inputBuffer + srcOffset;
    outputRow = (char*)outputBuffer + dstOffset;

    if (srcAtOnce && dstAtOnce) {
        cmsDoTransform(sTrans, inputRow, outputRow, width * height);
    } else {
        for (i = 0; i < height; i++) {
            cmsDoTransform(sTrans, inputRow, outputRow, width);
            inputRow += srcNextRowOffset;
            outputRow += dstNextRowOffset;
        }
    }

    releaseILData(env, inputBuffer, srcDType, srcData);
    releaseILData(env, outputBuffer, dstDType, dstData);
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    getProfileID
 * Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile
 */
JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
  (JNIEnv *env, jclass cls, jobject pf)
{
    jclass clsLcmsProfile;
    jobject cmmProfile;
    jfieldID fid = (*env)->GetFieldID (env,
        (*env)->GetObjectClass(env, pf),
        "cmmProfile", "Lsun/java2d/cmm/Profile;");
    if (fid == NULL) {
        return NULL;
    }

    clsLcmsProfile = (*env)->FindClass(env,
            "sun/java2d/cmm/lcms/LCMSProfile");
    if (clsLcmsProfile == NULL) {
        return NULL;
    }

    cmmProfile = (*env)->GetObjectField (env, pf, fid);

    if (JNU_IsNull(env, cmmProfile)) {
        return NULL;
    }
    if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) {
        return cmmProfile;
    }
    return NULL;
}

/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    initLCMS
 * Signature: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
  (JNIEnv *env, jclass cls, jclass Trans, jclass IL, jclass Pf)
{
    /* TODO: move initialization of the IDs to the static blocks of
     * corresponding classes to avoid problems with invalidating ids by class
     * unloading
     */
    Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
    if (Trans_renderType_fID == NULL) {
        return;
    }
    Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
    if (Trans_ID_fID == NULL) {
        return;
    }

    IL_isIntPacked_fID = (*env)->GetFieldID (env, IL, "isIntPacked", "Z");
    if (IL_isIntPacked_fID == NULL) {
        return;
    }
    IL_dataType_fID = (*env)->GetFieldID (env, IL, "dataType", "I");
    if (IL_dataType_fID == NULL) {
        return;
    }
    IL_pixelType_fID = (*env)->GetFieldID (env, IL, "pixelType", "I");
    if (IL_pixelType_fID == NULL) {
        return;
    }
    IL_dataArray_fID = (*env)->GetFieldID(env, IL, "dataArray",
                                          "Ljava/lang/Object;");
    if (IL_dataArray_fID == NULL) {
        return;
    }
    IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
    if (IL_width_fID == NULL) {
        return;
    }
    IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
    if (IL_height_fID == NULL) {
        return;
    }
    IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
    if (IL_offset_fID == NULL) {
        return;
    }
    IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
    if (IL_imageAtOnce_fID == NULL) {
        return;
    }
    IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
    if (IL_nextRowOffset_fID == NULL) {
        return;
    }
}

static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
{
  cmsUInt32Number pfSize = 0;
  cmsUInt8Number* pfBuffer = NULL;
  cmsBool status = FALSE;

  if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
      pfSize < sizeof(cmsICCHeader) ||
      bufferSize < (jint)sizeof(cmsICCHeader))
  {
    return FALSE;
  }

  pfBuffer = malloc(pfSize);
  if (pfBuffer == NULL) {
    return FALSE;
  }

  // load raw profile data into the buffer
  if (cmsSaveProfileToMem(pf, pfBuffer, &pfSize)) {
    memcpy(pBuffer, pfBuffer, sizeof(cmsICCHeader));
    status = TRUE;
  }
  free(pfBuffer);
  return status;
}

static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
{
  cmsICCHeader pfHeader;

  if (pBuffer == NULL || bufferSize < (jint)sizeof(cmsICCHeader)) {
    return FALSE;
  }

  memcpy(&pfHeader, pBuffer, sizeof(cmsICCHeader));

  // now set header fields, which we can access using the lcms2 public API
  cmsSetHeaderFlags(pf, pfHeader.flags);
  cmsSetHeaderManufacturer(pf, pfHeader.manufacturer);
  cmsSetHeaderModel(pf, pfHeader.model);
  cmsSetHeaderAttributes(pf, pfHeader.attributes);
  cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
  cmsSetHeaderRenderingIntent(pf, pfHeader.renderingIntent);
  cmsSetPCS(pf, pfHeader.pcs);
  cmsSetColorSpace(pf, pfHeader.colorSpace);
  cmsSetDeviceClass(pf, pfHeader.deviceClass);
  cmsSetEncodedICCversion(pf, pfHeader.version);

  return TRUE;
}

/* Returns new profile handler, if it was created successfully,
   NULL otherwise.
   */
static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
                               const cmsTagSignature sig,
                               jbyte *pData, jint size)
{
    cmsUInt32Number pfSize = 0;
    const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
    cmsInt32Number i;
    cmsHPROFILE pfSanity = NULL;

    cmsICCHeader hdr;

    cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);

    if (NULL == p) {
        return NULL;
    }
    memset(&hdr, 0, sizeof(cmsICCHeader));

    // Populate the placeholder's header according to target profile
    hdr.flags = cmsGetHeaderFlags(pfTarget);
    hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
    hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
    hdr.model = cmsGetHeaderModel(pfTarget);
    hdr.pcs = cmsGetPCS(pfTarget);
    hdr.colorSpace = cmsGetColorSpace(pfTarget);
    hdr.deviceClass = cmsGetDeviceClass(pfTarget);
    hdr.version = cmsGetEncodedICCversion(pfTarget);
    cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
    cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);

    cmsSetHeaderFlags(p, hdr.flags);
    cmsSetHeaderManufacturer(p, hdr.manufacturer);
    cmsSetHeaderModel(p, hdr.model);
    cmsSetHeaderAttributes(p, hdr.attributes);
    cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
    cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
    cmsSetPCS(p, hdr.pcs);
    cmsSetColorSpace(p, hdr.colorSpace);
    cmsSetDeviceClass(p, hdr.deviceClass);
    cmsSetEncodedICCversion(p, hdr.version);

    // now write the user supplied tag
    if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
        cmsCloseProfile(p);
        return NULL;
    }

    // copy tags from the original profile
    for (i = 0; i < tagCount; i++) {
        cmsBool isTagReady = FALSE;
        const cmsTagSignature s = cmsGetTagSignature(pfTarget, i);
        const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);

        if (s == sig) {
            // skip the user supplied tag
            continue;
        }

        // read raw tag from the original profile
        if (tagSize > 0) {
            cmsUInt8Number* buf = (cmsUInt8Number*)malloc(tagSize);
            if (buf != NULL) {
                if (tagSize ==  cmsReadRawTag(pfTarget, s, buf, tagSize)) {
                    // now we are ready to write the tag
                    isTagReady = cmsWriteRawTag(p, s, buf, tagSize);
                }
                free(buf);
            }
        }

        if (!isTagReady) {
            cmsCloseProfile(p);
            return NULL;
        }
    }

    // now we have all tags moved to the new profile.
    // do some sanity checks: write it to a memory buffer and read again.
    if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
        void* buf = malloc(pfSize);
        if (buf != NULL) {
            // load raw profile data into the buffer
            if (cmsSaveProfileToMem(p, buf, &pfSize)) {
                pfSanity = cmsOpenProfileFromMem(buf, pfSize);
            }
            free(buf);
        }
    }

    if (pfSanity == NULL) {
        // for some reason, we failed to save and read the updated profile
        // It likely indicates that the profile is not correct, so we report
        // a failure here.
        cmsCloseProfile(p);
        p =  NULL;
    } else {
        // do final check whether we can read and handle the the target tag.
        const void* pTag = cmsReadTag(pfSanity, sig);
        if (pTag == NULL) {
            // the tag can not be cooked
            cmsCloseProfile(p);
            p = NULL;
        }
        cmsCloseProfile(pfSanity);
        pfSanity = NULL;
    }

    return p;
}
