# HG changeset patch # User lana # Date 1307233858 25200 # Node ID bbb4cef2208b7bf00324c56c51fd9cb8efa33078 # Parent e8e6cdff5995144fa9bc5894066472d2a0b43a80# Parent 8f19b165347b20f5c3b715b521535247e516d2bf Merge diff -r e8e6cdff5995 -r bbb4cef2208b src/share/classes/java/awt/color/ICC_Profile.java --- a/src/share/classes/java/awt/color/ICC_Profile.java Fri Jun 03 20:13:50 2011 -0700 +++ b/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) { diff -r e8e6cdff5995 -r bbb4cef2208b src/share/native/sun/java2d/cmm/lcms/LCMS.c --- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri Jun 03 20:13:50 2011 -0700 +++ b/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; +} diff -r e8e6cdff5995 -r bbb4cef2208b src/share/native/sun/java2d/cmm/lcms/cmsio0.c --- a/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Fri Jun 03 20:13:50 2011 -0700 +++ b/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 diff -r e8e6cdff5995 -r bbb4cef2208b test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java --- a/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Fri Jun 03 20:13:50 2011 -0700 +++ b/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); diff -r e8e6cdff5995 -r bbb4cef2208b test/sun/java2d/cmm/ProfileOp/SetDataTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 tests = new ArrayList(); + + 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!."); + } +}