Merge
authorlana
Sat, 04 Jun 2011 17:30:58 -0700
changeset 9785 5445a3b7d06b
parent 9783 3c2fee00c063 (current diff)
parent 9784 3a0ebf0b855d (diff)
child 9788 6ad58e094d6d
Merge
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java	Fri Jun 03 20:13:50 2011 -0700
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java	Sat Jun 04 17:30:58 2011 -0700
@@ -1382,13 +1382,19 @@
 
     /**
      * Sets a particular tagged data element in the profile from
-     * a byte array.  This method is useful
-     * for advanced applets or applications which need to access
-     * profile data directly.
+     * a byte array. The array should contain data in a format, corresponded
+     * to the {@code tagSignature} as defined in the ICC specification, section 10.
+     * This method is useful for advanced applets or applications which need to
+     * access profile data directly.
      *
      * @param tagSignature The ICC tag signature for the data element
      * you want to set.
      * @param tagData the data to set for the specified tag signature
+     * @throws IllegalArgumentException if {@code tagSignature} is not a signature
+     *         as defined in the ICC specification.
+     * @throws IllegalArgumentException if a content of the {@code tagData}
+     *         array can not be interpreted as valid tag data, corresponding
+     *         to the {@code tagSignature}.
      * @see #getData
      */
     public void setData(int tagSignature, byte[] tagData) {
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Fri Jun 03 20:13:50 2011 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Sat Jun 04 17:30:58 2011 -0700
@@ -233,9 +233,19 @@
     jint dataSize;
     storeID_t sProf;
 
+    if (JNU_IsNull(env, data)) {
+        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
+        return 0L;
+    }
+
     dataArray = (*env)->GetByteArrayElements (env, data, 0);
     dataSize = (*env)->GetArrayLength (env, data);
 
+    if (dataArray == NULL) {
+        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
+        return 0L;
+    }
+
     sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
                                      (cmsUInt32Number) dataSize);
 
@@ -334,8 +344,9 @@
 }
 
 /* Get profile header info */
-cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
-cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
 
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
@@ -356,7 +367,7 @@
         result = sizeof(cmsICCHeader);
     } else {
       if (cmsIsTag(sProf.pf, sig.cms)) {
-            result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
+          result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
         } else {
             JNU_ThrowByName(env, "java/awt/color/CMMException",
                             "ICC profile tag not found");
@@ -468,22 +479,30 @@
     sProf.j = id;
     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) {
+        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
+        return;
+    }
+
     if (tagSig == SigHead) {
         status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
     } else {
-        status = cmsWriteRawTag(sProf.pf, sig.cms, dataArray, tagSize);
+        status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize);
     }
 
     (*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
 
     if (!status) {
-        JNU_ThrowByName(env, "java/awt/color/CMMException",
-                        "Can not write tag data.");
+        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
     }
 }
 
@@ -645,7 +664,7 @@
     PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
 }
 
-cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
+static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
 {
   cmsUInt32Number pfSize = 0;
   cmsUInt8Number* pfBuffer = NULL;
@@ -672,7 +691,7 @@
   return status;
 }
 
-cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
+static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
 {
   cmsICCHeader pfHeader = { 0 };
 
@@ -696,3 +715,77 @@
 
   return TRUE;
 }
+
+static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
+                               cmsTagSignature sig,
+                               jbyte *pData, jint size)
+{
+    cmsBool status;
+    cmsUInt32Number pfSize = 0;
+    cmsUInt8Number* pfBuffer = NULL;
+
+    cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
+    if (NULL != p) {
+        cmsICCHeader hdr = { 0 };
+
+        /* 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);
+
+
+        if (cmsWriteRawTag(p, sig, pData, size)) {
+            if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
+                pfBuffer = malloc(pfSize);
+                if (pfBuffer != NULL) {
+                    /* load raw profile data into the buffer */
+                    if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) {
+                        free(pfBuffer);
+                        pfBuffer = NULL;
+                    }
+                }
+            }
+        }
+        cmsCloseProfile(p);
+    }
+
+    if (pfBuffer == NULL) {
+        return FALSE;
+    }
+
+    /* re-open the placeholder profile */
+    p = cmsOpenProfileFromMem(pfBuffer, pfSize);
+    free(pfBuffer);
+    status = FALSE;
+
+    if (p != NULL) {
+        /* Note that pCookedTag points to internal structures of the placeholder,
+         * so this data is valid only while the placeholder is open.
+         */
+        void *pCookedTag = cmsReadTag(p, sig);
+        if (pCookedTag != NULL) {
+            status = cmsWriteTag(pfTarget, sig, pCookedTag);
+        }
+        pCookedTag = NULL;
+        cmsCloseProfile(p);
+    }
+    return status;
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	Fri Jun 03 20:13:50 2011 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	Sat Jun 04 17:30:58 2011 -0700
@@ -1636,6 +1636,11 @@
     TagDescriptor = _cmsGetTagDescriptor(sig);
 
     // Serialize
+    if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) {
+        cmsCloseIOhandler(MemIO);
+        return 0;
+    }
+
     if (!TypeHandler ->WritePtr(TypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) return 0;
 
     // Get Size and close
--- a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java	Fri Jun 03 20:13:50 2011 -0700
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java	Sat Jun 04 17:30:58 2011 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 6476665 6523403 6733501
+ * @bug 6476665 6523403 6733501 7042594
  * @summary Verifies reading and writing profiles and tags of the standard color
  * spaces
  * @run main ReadWriteProfileTest
@@ -94,7 +94,16 @@
             for (int tagSig : tags[i].keySet()) {
                 byte [] tagData = pf.getData(tagSig);
                 byte [] empty = new byte[tagData.length];
-                pf.setData(tagSig, empty);
+                boolean emptyDataRejected = false;
+                try {
+                    pf.setData(tagSig, empty);
+                } catch (IllegalArgumentException e) {
+                    emptyDataRejected = true;
+                }
+                if (!emptyDataRejected) {
+                    throw new
+                        RuntimeException("Test failed: empty tag data was not rejected.");
+                }
                 pf.setData(tagSig, tagData);
 
                 byte [] tagData1 = pf.getData(tagSig);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/SetDataTest.java	Sat Jun 04 17:30:58 2011 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug     7042594
+ * @summary Test verifies that ICC_Profile.setData() conforms the spec.
+ *
+ * @run     main SetDataTest
+ */
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.awt.color.ICC_Profile;
+import static java.awt.color.ICC_ColorSpace.CS_GRAY;
+import static java.awt.color.ICC_Profile.icSigGrayTRCTag;
+import static java.awt.color.ICC_Profile.icSigRedTRCTag;
+import static java.awt.color.ICC_Profile.icSigGreenTRCTag;
+
+public class SetDataTest {
+
+    static class TestCase {
+
+        static ICC_Profile profile;
+        static byte[] validTRCdata;
+        static byte[] invalidTRCData;
+
+        static {
+            profile = ICC_Profile.getInstance(CS_GRAY);
+            validTRCdata = profile.getData(icSigGrayTRCTag);
+            invalidTRCData = new byte[]{0x42, 0x42, 0x42, 0x42, 1, 3, 4, 6,};
+        }
+        String desciption;
+        int signature;
+        boolean useValidData;
+        Throwable err;
+        boolean isIAEexpected;
+
+        public TestCase(String descr, int sig,
+                boolean useValidData,
+                boolean isIAEexpected) {
+            this.desciption = descr;
+            this.signature = sig;
+
+            this.useValidData = useValidData;
+            this.isIAEexpected = isIAEexpected;
+
+        }
+
+        public void doTest() {
+            System.out.println(desciption);
+            byte[] data = useValidData
+                    ? validTRCdata : invalidTRCData;
+            err = null;
+            try {
+                profile.setData(signature, data);
+            } catch (Throwable e) {
+                err = e;
+                System.out.println("Got exception: " +
+                        e.getClass().getName() + ": " +
+                        e.getMessage());
+            }
+
+            if (isIAEexpected) {
+                if (err == null) {
+                    throw new RuntimeException(
+                            "Test failed: expected exception was not thrown");
+                }
+                if (!(err instanceof IllegalArgumentException)) {
+                    throw new RuntimeException(
+                            "Unexpected exception was thrown: " +
+                            err.getMessage(), err);
+                }
+            } else {
+                if (err != null) {
+                    throw new RuntimeException(
+                            "Unexpected exception was thrown: " +
+                            err.getMessage(), err);
+                }
+            }
+            System.out.println("Testcase PASSED");
+        }
+    }
+
+    public static void main(String[] args) {
+        List<TestCase> tests = new ArrayList<TestCase>();
+
+        TestCase selfupdate = new TestCase(
+                "Selfupdate: update grayTRC with the same data.",
+                icSigGrayTRCTag, true, false);
+        tests.add(selfupdate);
+
+        TestCase newValdTag = new TestCase(
+                "Insert new valid tag",
+                icSigRedTRCTag,
+                true, false);
+        tests.add(newValdTag);
+
+        TestCase newInvalidTag = new TestCase(
+                "Insert new tag with invalid contet",
+                icSigGreenTRCTag,
+                false, true);
+        tests.add(newInvalidTag);
+
+        TestCase newUnknowInvalidTag = new TestCase(
+                "Insert new tag with invalid data and unknown signature",
+                0x41414141,
+                false, true);
+        tests.add(newUnknowInvalidTag);
+
+        TestCase newUnknownValidTag = new TestCase(
+                "Insert new tag with valid data and unknown signatiure",
+                0x41414141,
+                true, true);
+        tests.add(newUnknownValidTag);
+
+        for (TestCase t: tests) {
+            t.doTest();
+        }
+        System.out.println("Test passed!.");
+    }
+}