src/share/native/sun/java2d/cmm/lcms/LCMS.c

Print this page

        

@@ -115,10 +115,11 @@
 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;
 static jfieldID PF_ID_fID;
 
 JavaVM *javaVM;
 
 void errorHandler(cmsContext ContextID, cmsUInt32Number errorCode,

@@ -235,11 +236,11 @@
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
  * Method:    loadProfile
  * Signature: ([B)J
  */
-JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile
+JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
   (JNIEnv *env, jobject obj, jbyteArray data)
 {
     jbyte* dataArray;
     jint dataSize;
     storeID_t sProf;

@@ -282,11 +283,11 @@
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
  * Method:    freeProfile
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
   (JNIEnv *env, jobject obj, jlong id)
 {
     storeID_t sProf;
 
     sProf.j = id;

@@ -401,32 +402,35 @@
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
  * Method:    getTagData
  * Signature: (JI[B)V
  */
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
-  (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
+JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
+  (JNIEnv *env, jobject obj, jlong id, jint tagSig)
 {
     storeID_t sProf;
     TagSignature_t sig;
     cmsInt32Number tagSize;
 
-    jbyte* dataArray;
+    jbyte* dataArray = NULL;
+    jbyteArray data = NULL;
+
     jint bufSize;
 
     sProf.j = id;
     sig.j = tagSig;
 
     if (tagSig == SigHead) {
         cmsBool status;
 
-        bufSize =(*env)->GetArrayLength(env, data);
+        // allocate java array
+        data = (*env)->NewByteArray(env, sizeof(cmsICCHeader));
 
-        if (bufSize < sizeof(cmsICCHeader)) {
+        if (data == NULL) {
            JNU_ThrowByName(env, "java/awt/color/CMMException",
-                            "Insufficient buffer capacity");
-           return;
+                            "Unable to allocate buffer");
+            return NULL;
         }
 
         dataArray = (*env)->GetByteArrayElements (env, data, 0);
 
         if (dataArray == NULL) {

@@ -440,57 +444,58 @@
         (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
 
         if (!status) {
             JNU_ThrowByName(env, "java/awt/color/CMMException",
                             "ICC Profile header not found");
+            return NULL;
         }
 
-        return;
+        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;
+        return NULL;
     }
 
-    // verify data buffer capacity
-    bufSize = (*env)->GetArrayLength(env, data);
-
-    if (tagSize < 0 || 0 > bufSize || tagSize > bufSize) {
+    // allocate java array
+    data = (*env)->NewByteArray(env, tagSize);
+    if (data == NULL) {
         JNU_ThrowByName(env, "java/awt/color/CMMException",
-                        "Insufficient buffer capacity.");
-        return;
+                        "Unable to allocate buffer");
+        return NULL;
     }
 
     dataArray = (*env)->GetByteArrayElements (env, data, 0);
 
     if (dataArray == NULL) {
         JNU_ThrowByName(env, "java/awt/color/CMMException",
                         "Unable to get buffer");
-        return;
+        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;
+    return data;
 }
 
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
  * Method:    setTagData
  * Signature: (JI[B)V
  */
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
   (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
 {
     storeID_t sProf;
     TagSignature_t sig;
     cmsBool status;

@@ -584,18 +589,22 @@
     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.j = (*env)->GetLongField (env, trans, Trans_ID_fID);
 
     if (sTrans.xf == NULL) {
         J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_colorConvert: transform == NULL");
         JNU_ThrowByName(env, "java/awt/color/CMMException",

@@ -623,15 +632,19 @@
     }
 
     inputRow = (char*)inputBuffer + srcOffset;
     outputRow = (char*)outputBuffer + dstOffset;
 
+    if (srcAtOnce && dstAtOnce) {
+        cmsDoTransform(sTrans.xf, inputRow, outputRow, width * height);
+    } else {
     for (i = 0; i < height; i++) {
         cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
         inputRow += srcNextRowOffset;
         outputRow += dstNextRowOffset;
     }
+    }
 
     releaseILData(env, inputBuffer, srcDType, srcData);
     releaseILData(env, outputBuffer, dstDType, dstData);
 }
 

@@ -668,10 +681,11 @@
     IL_dataArray_fID = (*env)->GetFieldID(env, IL, "dataArray",
                                           "Ljava/lang/Object;");
     IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
     IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
     IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
+    IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
     IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
 
     PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
 }