7043064: sun/java2d/cmm/ tests failed against RI b141 & b138-nightly
Reviewed-by: prr, vadim
This commit is contained in:
parent
24f306c761
commit
256894796f
@ -28,9 +28,8 @@
|
|||||||
SUNWprivate_1.1 {
|
SUNWprivate_1.1 {
|
||||||
global:
|
global:
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
|
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
|
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
|
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
|
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
|
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
|
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
|
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
|
||||||
|
@ -28,9 +28,8 @@
|
|||||||
SUNWprivate_1.1 {
|
SUNWprivate_1.1 {
|
||||||
global:
|
global:
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
|
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
|
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
|
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
|
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
|
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
|
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
|
||||||
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
|
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
|
||||||
|
@ -37,6 +37,7 @@ package java.awt.color;
|
|||||||
|
|
||||||
import sun.java2d.cmm.PCMM;
|
import sun.java2d.cmm.PCMM;
|
||||||
import sun.java2d.cmm.CMSManager;
|
import sun.java2d.cmm.CMSManager;
|
||||||
|
import sun.java2d.cmm.Profile;
|
||||||
import sun.java2d.cmm.ProfileDataVerifier;
|
import sun.java2d.cmm.ProfileDataVerifier;
|
||||||
import sun.java2d.cmm.ProfileDeferralMgr;
|
import sun.java2d.cmm.ProfileDeferralMgr;
|
||||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||||
@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -3938515861990936766L;
|
private static final long serialVersionUID = -3938515861990936766L;
|
||||||
|
|
||||||
transient long ID;
|
private transient Profile cmmProfile;
|
||||||
|
|
||||||
private transient ProfileDeferralInfo deferralInfo;
|
private transient ProfileDeferralInfo deferralInfo;
|
||||||
private transient ProfileActivator profileActivator;
|
private transient ProfileActivator profileActivator;
|
||||||
@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Constructs an ICC_Profile object with a given ID.
|
* Constructs an ICC_Profile object with a given ID.
|
||||||
*/
|
*/
|
||||||
ICC_Profile(long ID) {
|
ICC_Profile(Profile p) {
|
||||||
this.ID = ID;
|
this.cmmProfile = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable {
|
|||||||
* Frees the resources associated with an ICC_Profile object.
|
* Frees the resources associated with an ICC_Profile object.
|
||||||
*/
|
*/
|
||||||
protected void finalize () {
|
protected void finalize () {
|
||||||
if (ID != 0) {
|
if (cmmProfile != null) {
|
||||||
CMSManager.getModule().freeProfile(ID);
|
CMSManager.getModule().freeProfile(cmmProfile);
|
||||||
} else if (profileActivator != null) {
|
} else if (profileActivator != null) {
|
||||||
ProfileDeferralMgr.unregisterDeferral(profileActivator);
|
ProfileDeferralMgr.unregisterDeferral(profileActivator);
|
||||||
}
|
}
|
||||||
@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
public static ICC_Profile getInstance(byte[] data) {
|
public static ICC_Profile getInstance(byte[] data) {
|
||||||
ICC_Profile thisProfile;
|
ICC_Profile thisProfile;
|
||||||
|
|
||||||
long theID;
|
Profile p = null;
|
||||||
|
|
||||||
if (ProfileDeferralMgr.deferring) {
|
if (ProfileDeferralMgr.deferring) {
|
||||||
ProfileDeferralMgr.activateProfiles();
|
ProfileDeferralMgr.activateProfiles();
|
||||||
@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable {
|
|||||||
ProfileDataVerifier.verify(data);
|
ProfileDataVerifier.verify(data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
theID = CMSManager.getModule().loadProfile(data);
|
p = CMSManager.getModule().loadProfile(data);
|
||||||
} catch (CMMException c) {
|
} catch (CMMException c) {
|
||||||
throw new IllegalArgumentException("Invalid ICC Profile Data");
|
throw new IllegalArgumentException("Invalid ICC Profile Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
|
if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) &&
|
||||||
(getData (theID, icSigMediaWhitePointTag) != null) &&
|
(getData (p, icSigMediaWhitePointTag) != null) &&
|
||||||
(getData (theID, icSigGrayTRCTag) != null)) {
|
(getData (p, icSigGrayTRCTag) != null)) {
|
||||||
thisProfile = new ICC_ProfileGray (theID);
|
thisProfile = new ICC_ProfileGray (p);
|
||||||
}
|
}
|
||||||
else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
|
else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
|
||||||
(getData (theID, icSigMediaWhitePointTag) != null) &&
|
(getData (p, icSigMediaWhitePointTag) != null) &&
|
||||||
(getData (theID, icSigRedColorantTag) != null) &&
|
(getData (p, icSigRedColorantTag) != null) &&
|
||||||
(getData (theID, icSigGreenColorantTag) != null) &&
|
(getData (p, icSigGreenColorantTag) != null) &&
|
||||||
(getData (theID, icSigBlueColorantTag) != null) &&
|
(getData (p, icSigBlueColorantTag) != null) &&
|
||||||
(getData (theID, icSigRedTRCTag) != null) &&
|
(getData (p, icSigRedTRCTag) != null) &&
|
||||||
(getData (theID, icSigGreenTRCTag) != null) &&
|
(getData (p, icSigGreenTRCTag) != null) &&
|
||||||
(getData (theID, icSigBlueTRCTag) != null)) {
|
(getData (p, icSigBlueTRCTag) != null)) {
|
||||||
thisProfile = new ICC_ProfileRGB (theID);
|
thisProfile = new ICC_ProfileRGB (p);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thisProfile = new ICC_Profile (theID);
|
thisProfile = new ICC_Profile (p);
|
||||||
}
|
}
|
||||||
} catch (CMMException c) {
|
} catch (CMMException c) {
|
||||||
thisProfile = new ICC_Profile (theID);
|
thisProfile = new ICC_Profile (p);
|
||||||
}
|
}
|
||||||
return thisProfile;
|
return thisProfile;
|
||||||
}
|
}
|
||||||
@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
fileName);
|
fileName);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ID = CMSManager.getModule().loadProfile(profileData);
|
cmmProfile = CMSManager.getModule().loadProfile(profileData);
|
||||||
} catch (CMMException c) {
|
} catch (CMMException c) {
|
||||||
ProfileDataException pde = new
|
ProfileDataException pde = new
|
||||||
ProfileDataException("Invalid ICC Profile Data" + fileName);
|
ProfileDataException("Invalid ICC Profile Data" + fileName);
|
||||||
@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable {
|
|||||||
causing a deferred profile
|
causing a deferred profile
|
||||||
to be loaded */
|
to be loaded */
|
||||||
}
|
}
|
||||||
return getColorSpaceType(ID);
|
return getColorSpaceType(cmmProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getColorSpaceType(long profileID) {
|
static int getColorSpaceType(Profile p) {
|
||||||
byte[] theHeader;
|
byte[] theHeader;
|
||||||
int theColorSpaceSig, theColorSpace;
|
int theColorSpaceSig, theColorSpace;
|
||||||
|
|
||||||
theHeader = getData(profileID, icSigHead);
|
theHeader = getData(p, icSigHead);
|
||||||
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
|
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
|
||||||
theColorSpace = iccCStoJCS (theColorSpaceSig);
|
theColorSpace = iccCStoJCS (theColorSpaceSig);
|
||||||
return theColorSpace;
|
return theColorSpace;
|
||||||
@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable {
|
|||||||
if (ProfileDeferralMgr.deferring) {
|
if (ProfileDeferralMgr.deferring) {
|
||||||
ProfileDeferralMgr.activateProfiles();
|
ProfileDeferralMgr.activateProfiles();
|
||||||
}
|
}
|
||||||
return getPCSType(ID);
|
return getPCSType(cmmProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int getPCSType(long profileID) {
|
static int getPCSType(Profile p) {
|
||||||
byte[] theHeader;
|
byte[] theHeader;
|
||||||
int thePCSSig, thePCS;
|
int thePCSSig, thePCS;
|
||||||
|
|
||||||
theHeader = getData(profileID, icSigHead);
|
theHeader = getData(p, icSigHead);
|
||||||
thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
|
thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
|
||||||
thePCS = iccCStoJCS(thePCSSig);
|
thePCS = iccCStoJCS(thePCSSig);
|
||||||
return thePCS;
|
return thePCS;
|
||||||
@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable {
|
|||||||
PCMM mdl = CMSManager.getModule();
|
PCMM mdl = CMSManager.getModule();
|
||||||
|
|
||||||
/* get the number of bytes needed for this profile */
|
/* get the number of bytes needed for this profile */
|
||||||
profileSize = mdl.getProfileSize(ID);
|
profileSize = mdl.getProfileSize(cmmProfile);
|
||||||
|
|
||||||
profileData = new byte [profileSize];
|
profileData = new byte [profileSize];
|
||||||
|
|
||||||
/* get the data for the profile */
|
/* get the data for the profile */
|
||||||
mdl.getProfileData(ID, profileData);
|
mdl.getProfileData(cmmProfile, profileData);
|
||||||
|
|
||||||
return profileData;
|
return profileData;
|
||||||
}
|
}
|
||||||
@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable {
|
|||||||
ProfileDeferralMgr.activateProfiles();
|
ProfileDeferralMgr.activateProfiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getData(ID, tagSignature);
|
return getData(cmmProfile, tagSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static byte[] getData(long profileID, int tagSignature) {
|
static byte[] getData(Profile p, int tagSignature) {
|
||||||
int tagSize;
|
int tagSize;
|
||||||
byte[] tagData;
|
byte[] tagData;
|
||||||
|
|
||||||
@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable {
|
|||||||
PCMM mdl = CMSManager.getModule();
|
PCMM mdl = CMSManager.getModule();
|
||||||
|
|
||||||
/* get the number of bytes needed for this tag */
|
/* get the number of bytes needed for this tag */
|
||||||
tagSize = mdl.getTagSize(profileID, tagSignature);
|
tagSize = mdl.getTagSize(p, tagSignature);
|
||||||
|
|
||||||
tagData = new byte[tagSize]; /* get an array for the tag */
|
tagData = new byte[tagSize]; /* get an array for the tag */
|
||||||
|
|
||||||
/* get the tag's data */
|
/* get the tag's data */
|
||||||
mdl.getTagData(profileID, tagSignature, tagData);
|
mdl.getTagData(p, tagSignature, tagData);
|
||||||
} catch(CMMException c) {
|
} catch(CMMException c) {
|
||||||
tagData = null;
|
tagData = null;
|
||||||
}
|
}
|
||||||
@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
ProfileDeferralMgr.activateProfiles();
|
ProfileDeferralMgr.activateProfiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMSManager.getModule().setTagData(ID, tagSignature, tagData);
|
CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
package java.awt.color;
|
package java.awt.color;
|
||||||
|
|
||||||
import java.awt.image.LookupTable;
|
import sun.java2d.cmm.Profile;
|
||||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,8 +76,8 @@ extends ICC_Profile {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new ICC_ProfileGray from a CMM ID.
|
* Constructs a new ICC_ProfileGray from a CMM ID.
|
||||||
*/
|
*/
|
||||||
ICC_ProfileGray(long ID) {
|
ICC_ProfileGray(Profile p) {
|
||||||
super(ID);
|
super(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
package java.awt.color;
|
package java.awt.color;
|
||||||
|
|
||||||
import java.awt.image.LookupTable;
|
import sun.java2d.cmm.Profile;
|
||||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,8 +114,8 @@ extends ICC_Profile {
|
|||||||
* @param ID The CMM ID for the profile.
|
* @param ID The CMM ID for the profile.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
ICC_ProfileRGB(long ID) {
|
ICC_ProfileRGB(Profile p) {
|
||||||
super(ID);
|
super(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,53 +104,53 @@ public class CMSManager {
|
|||||||
cName = tcmm.getClass().getName();
|
cName = tcmm.getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long loadProfile(byte[] data) {
|
public Profile loadProfile(byte[] data) {
|
||||||
System.err.print(cName + ".loadProfile");
|
System.err.print(cName + ".loadProfile");
|
||||||
long profileID = tcmm.loadProfile(data);
|
Profile p = tcmm.loadProfile(data);
|
||||||
System.err.printf("(ID=%x)\n", profileID);
|
System.err.printf("(ID=%s)\n", p.toString());
|
||||||
return profileID;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void freeProfile(long profileID) {
|
public void freeProfile(Profile p) {
|
||||||
System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
|
System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
|
||||||
tcmm.freeProfile(profileID);
|
tcmm.freeProfile(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProfileSize(long profileID) {
|
public int getProfileSize(Profile p) {
|
||||||
System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
|
System.err.print(cName + ".getProfileSize(ID=" + p + ")");
|
||||||
int size = tcmm.getProfileSize(profileID);
|
int size = tcmm.getProfileSize(p);
|
||||||
System.err.println("=" + size);
|
System.err.println("=" + size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getProfileData(long profileID, byte[] data) {
|
public void getProfileData(Profile p, byte[] data) {
|
||||||
System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
|
System.err.print(cName + ".getProfileData(ID=" + p + ") ");
|
||||||
System.err.println("requested " + data.length + " byte(s)");
|
System.err.println("requested " + data.length + " byte(s)");
|
||||||
tcmm.getProfileData(profileID, data);
|
tcmm.getProfileData(p, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTagSize(long profileID, int tagSignature) {
|
public int getTagSize(Profile p, int tagSignature) {
|
||||||
System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
|
System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
|
||||||
profileID, signatureToString(tagSignature));
|
p, signatureToString(tagSignature));
|
||||||
int size = tcmm.getTagSize(profileID, tagSignature);
|
int size = tcmm.getTagSize(p, tagSignature);
|
||||||
System.err.println("=" + size);
|
System.err.println("=" + size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getTagData(long profileID, int tagSignature,
|
public void getTagData(Profile p, int tagSignature,
|
||||||
byte[] data) {
|
byte[] data) {
|
||||||
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
|
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
|
||||||
profileID, signatureToString(tagSignature));
|
p, signatureToString(tagSignature));
|
||||||
System.err.println(" requested " + data.length + " byte(s)");
|
System.err.println(" requested " + data.length + " byte(s)");
|
||||||
tcmm.getTagData(profileID, tagSignature, data);
|
tcmm.getTagData(p, tagSignature, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTagData(long profileID, int tagSignature,
|
public void setTagData(Profile p, int tagSignature,
|
||||||
byte[] data) {
|
byte[] data) {
|
||||||
System.err.print(cName + ".setTagData(ID=" + profileID +
|
System.err.print(cName + ".setTagData(ID=" + p +
|
||||||
", TagSig=" + tagSignature + ")");
|
", TagSig=" + tagSignature + ")");
|
||||||
System.err.println(" sending " + data.length + " byte(s)");
|
System.err.println(" sending " + data.length + " byte(s)");
|
||||||
tcmm.setTagData(profileID, tagSignature, data);
|
tcmm.setTagData(p, tagSignature, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* methods for creating ColorTransforms */
|
/* methods for creating ColorTransforms */
|
||||||
|
@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile;
|
|||||||
public interface PCMM {
|
public interface PCMM {
|
||||||
|
|
||||||
/* methods invoked from ICC_Profile */
|
/* methods invoked from ICC_Profile */
|
||||||
public long loadProfile(byte[] data);
|
public Profile loadProfile(byte[] data);
|
||||||
public void freeProfile(long profileID);
|
public void freeProfile(Profile p);
|
||||||
public int getProfileSize(long profileID);
|
public int getProfileSize(Profile p);
|
||||||
public void getProfileData(long profileID, byte[] data);
|
public void getProfileData(Profile p, byte[] data);
|
||||||
public void getTagData(long profileID, int tagSignature, byte[] data);
|
public void getTagData(Profile p, int tagSignature, byte[] data);
|
||||||
public int getTagSize(long profileID, int tagSignature);
|
public int getTagSize(Profile p, int tagSignature);
|
||||||
public void setTagData(long profileID, int tagSignature, byte[] data);
|
public void setTagData(Profile p, int tagSignature, byte[] data);
|
||||||
|
|
||||||
/* methods for creating ColorTransforms */
|
/* methods for creating ColorTransforms */
|
||||||
public ColorTransform createTransform(ICC_Profile profile, int renderType,
|
public ColorTransform createTransform(ICC_Profile profile, int renderType,
|
||||||
|
43
jdk/src/share/classes/sun/java2d/cmm/Profile.java
Normal file
43
jdk/src/share/classes/sun/java2d/cmm/Profile.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.java2d.cmm;
|
||||||
|
|
||||||
|
import java.awt.color.CMMException;
|
||||||
|
|
||||||
|
public class Profile {
|
||||||
|
private final long nativePtr;
|
||||||
|
|
||||||
|
protected Profile(long ptr) {
|
||||||
|
nativePtr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final long getNativePtr() {
|
||||||
|
if (nativePtr == 0L) {
|
||||||
|
throw new CMMException("Invalid profile: ptr is null");
|
||||||
|
}
|
||||||
|
return nativePtr;
|
||||||
|
}
|
||||||
|
}
|
@ -25,96 +25,139 @@
|
|||||||
|
|
||||||
package sun.java2d.cmm.lcms;
|
package sun.java2d.cmm.lcms;
|
||||||
|
|
||||||
|
import java.awt.color.CMMException;
|
||||||
import java.awt.color.ICC_Profile;
|
import java.awt.color.ICC_Profile;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import sun.java2d.cmm.ColorTransform;
|
import sun.java2d.cmm.ColorTransform;
|
||||||
import sun.java2d.cmm.PCMM;
|
import sun.java2d.cmm.PCMM;
|
||||||
|
import sun.java2d.cmm.Profile;
|
||||||
|
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
|
||||||
|
|
||||||
public class LCMS implements PCMM {
|
public class LCMS implements PCMM {
|
||||||
|
|
||||||
/* methods invoked from ICC_Profile */
|
/* methods invoked from ICC_Profile */
|
||||||
@Override
|
@Override
|
||||||
public long loadProfile(byte[] data) {
|
public Profile loadProfile(byte[] data) {
|
||||||
long id = loadProfileNative(data);
|
final Object disposerRef = new Object();
|
||||||
|
|
||||||
if (id != 0L) {
|
final long ptr = loadProfileNative(data, disposerRef);
|
||||||
if (profiles == null) {
|
|
||||||
profiles = new HashMap<>();
|
if (ptr != 0L) {
|
||||||
}
|
return new LCMSProfile(ptr, disposerRef);
|
||||||
profiles.put(id, new TagCache(id));
|
|
||||||
}
|
}
|
||||||
return id;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long loadProfileNative(byte[] data);
|
private native long loadProfileNative(byte[] data, Object ref);
|
||||||
|
|
||||||
@Override
|
private LCMSProfile getLcmsProfile(Profile p) {
|
||||||
public void freeProfile(long profileID) {
|
if (p instanceof LCMSProfile) {
|
||||||
TagCache c = profiles.remove(profileID);
|
return (LCMSProfile)p;
|
||||||
if (c != null) {
|
|
||||||
c.clear();
|
|
||||||
}
|
}
|
||||||
if (profiles.isEmpty()) {
|
throw new CMMException("Invalid profile: " + p);
|
||||||
profiles = null;
|
|
||||||
}
|
|
||||||
freeProfileNative(profileID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private native void freeProfileNative(long profileID);
|
|
||||||
|
|
||||||
public native synchronized int getProfileSize(long profileID);
|
|
||||||
|
|
||||||
public native synchronized void getProfileData(long profileID, byte[] data);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized int getTagSize(long profileID, int tagSignature) {
|
public void freeProfile(Profile p) {
|
||||||
TagCache cache = profiles.get(profileID);
|
// we use disposer, so this method does nothing
|
||||||
|
|
||||||
if (cache == null) {
|
|
||||||
cache = new TagCache(profileID);
|
|
||||||
profiles.put(profileID, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
TagData t = cache.getTag(tagSignature);
|
|
||||||
return t == null ? 0 : t.getSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native byte[] getTagNative(long profileID, int signature);
|
@Override
|
||||||
|
public int getProfileSize(final Profile p) {
|
||||||
|
synchronized (p) {
|
||||||
|
return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int getProfileSizeNative(long ptr);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void getTagData(long profileID, int tagSignature,
|
public void getProfileData(final Profile p, byte[] data) {
|
||||||
byte[] data)
|
synchronized (p) {
|
||||||
|
getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void getProfileDataNative(long ptr, byte[] data);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTagSize(Profile p, int tagSignature) {
|
||||||
|
final LCMSProfile profile = getLcmsProfile(p);
|
||||||
|
|
||||||
|
synchronized (profile) {
|
||||||
|
TagData t = profile.getTag(tagSignature);
|
||||||
|
return t == null ? 0 : t.getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static native byte[] getTagNative(long profileID, int signature);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getTagData(Profile p, int tagSignature, byte[] data)
|
||||||
{
|
{
|
||||||
TagCache cache = profiles.get(profileID);
|
final LCMSProfile profile = getLcmsProfile(p);
|
||||||
|
|
||||||
if (cache == null) {
|
synchronized (profile) {
|
||||||
cache = new TagCache(profileID);
|
TagData t = profile.getTag(tagSignature);
|
||||||
profiles.put(profileID, cache);
|
if (t != null) {
|
||||||
}
|
t.copyDataTo(data);
|
||||||
|
}
|
||||||
TagData t = cache.getTag(tagSignature);
|
|
||||||
if (t != null) {
|
|
||||||
t.copyDataTo(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
|
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
|
||||||
TagCache cache = profiles.get(profileID);
|
final LCMSProfile profile = getLcmsProfile(p);
|
||||||
|
|
||||||
if (cache != null) {
|
synchronized (profile) {
|
||||||
cache.clear();
|
profile.clearTagCache();
|
||||||
|
|
||||||
|
// Now we are going to update the profile with new tag data
|
||||||
|
// In some cases, we may change the pointer to the native
|
||||||
|
// profile.
|
||||||
|
//
|
||||||
|
// If we fail to write tag data for any reason, the old pointer
|
||||||
|
// should be used.
|
||||||
|
setTagDataNative(profile.getLcmsPtr(),
|
||||||
|
tagSignature, data);
|
||||||
}
|
}
|
||||||
setTagDataNative(profileID, tagSignature, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private native synchronized void setTagDataNative(long profileID, int tagSignature,
|
/**
|
||||||
|
* Writes supplied data as a tag into the profile.
|
||||||
|
* Destroys old profile, if new one was successfully
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* Returns valid pointer to new profile.
|
||||||
|
*
|
||||||
|
* Throws CMMException if operation fails, preserve old profile from
|
||||||
|
* destruction.
|
||||||
|
*/
|
||||||
|
private native void setTagDataNative(long ptr, int tagSignature,
|
||||||
byte[] data);
|
byte[] data);
|
||||||
|
|
||||||
public static native long getProfileID(ICC_Profile profile);
|
public synchronized static native LCMSProfile getProfileID(ICC_Profile profile);
|
||||||
|
|
||||||
public static native long createNativeTransform(
|
/* Helper method used from LCMSColorTransfrom */
|
||||||
|
static long createTransform(
|
||||||
|
LCMSProfile[] profiles, int renderType,
|
||||||
|
int inFormatter, boolean isInIntPacked,
|
||||||
|
int outFormatter, boolean isOutIntPacked,
|
||||||
|
Object disposerRef)
|
||||||
|
{
|
||||||
|
long[] ptrs = new long[profiles.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < profiles.length; i++) {
|
||||||
|
if (profiles[i] == null) throw new CMMException("Unknown profile ID");
|
||||||
|
|
||||||
|
ptrs[i] = profiles[i].getLcmsPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createNativeTransform(ptrs, renderType, inFormatter,
|
||||||
|
isInIntPacked, outFormatter, isOutIntPacked, disposerRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long createNativeTransform(
|
||||||
long[] profileIDs, int renderType,
|
long[] profileIDs, int renderType,
|
||||||
int inFormatter, boolean isInIntPacked,
|
int inFormatter, boolean isInIntPacked,
|
||||||
int outFormatter, boolean isOutIntPacked,
|
int outFormatter, boolean isOutIntPacked,
|
||||||
@ -175,59 +218,4 @@ public class LCMS implements PCMM {
|
|||||||
|
|
||||||
return theLcms;
|
return theLcms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TagData {
|
|
||||||
private int signature;
|
|
||||||
private byte[] data;
|
|
||||||
|
|
||||||
TagData(int sig, byte[] data) {
|
|
||||||
this.signature = sig;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() {
|
|
||||||
return data.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] getData() {
|
|
||||||
return Arrays.copyOf(data, data.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void copyDataTo(byte[] dst) {
|
|
||||||
System.arraycopy(data, 0, dst, 0, data.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TagCache {
|
|
||||||
private long profileID;
|
|
||||||
private HashMap<Integer, TagData> tags;
|
|
||||||
|
|
||||||
TagCache(long id) {
|
|
||||||
profileID = id;
|
|
||||||
|
|
||||||
tags = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
TagData getTag(int sig) {
|
|
||||||
TagData t = tags.get(sig);
|
|
||||||
if (t == null) {
|
|
||||||
byte[] tagData = getTagNative(profileID, sig);
|
|
||||||
if (tagData != null) {
|
|
||||||
t = new TagData(sig, tagData);
|
|
||||||
tags.put(sig, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
tags.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HashMap<Long, TagCache> profiles;
|
|
||||||
}
|
}
|
||||||
|
109
jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java
Normal file
109
jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.java2d.cmm.lcms;
|
||||||
|
|
||||||
|
import java.awt.color.CMMException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import sun.java2d.cmm.Profile;
|
||||||
|
|
||||||
|
final class LCMSProfile extends Profile {
|
||||||
|
private final TagCache tagCache;
|
||||||
|
|
||||||
|
private final Object disposerReferent;
|
||||||
|
|
||||||
|
LCMSProfile(long ptr, Object ref) {
|
||||||
|
super(ptr);
|
||||||
|
|
||||||
|
disposerReferent = ref;
|
||||||
|
|
||||||
|
tagCache = new TagCache(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long getLcmsPtr() {
|
||||||
|
return this.getNativePtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
TagData getTag(int sig) {
|
||||||
|
return tagCache.getTag(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearTagCache() {
|
||||||
|
tagCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TagCache {
|
||||||
|
final LCMSProfile profile;
|
||||||
|
private HashMap<Integer, TagData> tags;
|
||||||
|
|
||||||
|
TagCache(LCMSProfile p) {
|
||||||
|
profile = p;
|
||||||
|
tags = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TagData getTag(int sig) {
|
||||||
|
TagData t = tags.get(sig);
|
||||||
|
if (t == null) {
|
||||||
|
byte[] tagData = LCMS.getTagNative(profile.getNativePtr(), sig);
|
||||||
|
if (tagData != null) {
|
||||||
|
t = new TagData(sig, tagData);
|
||||||
|
tags.put(sig, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
tags.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TagData {
|
||||||
|
private int signature;
|
||||||
|
private byte[] data;
|
||||||
|
|
||||||
|
TagData(int sig, byte[] data) {
|
||||||
|
this.signature = sig;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSize() {
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] getData() {
|
||||||
|
return Arrays.copyOf(data, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyDataTo(byte[] dst) {
|
||||||
|
System.arraycopy(data, 0, dst, 0, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,7 +62,7 @@ public class LCMSTransform implements ColorTransform {
|
|||||||
private boolean isOutIntPacked = false;
|
private boolean isOutIntPacked = false;
|
||||||
|
|
||||||
ICC_Profile[] profiles;
|
ICC_Profile[] profiles;
|
||||||
long [] profileIDs;
|
LCMSProfile[] lcmsProfiles;
|
||||||
int renderType;
|
int renderType;
|
||||||
int transformType;
|
int transformType;
|
||||||
|
|
||||||
@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform {
|
|||||||
/* Actually, it is not a complete transform but just part of it */
|
/* Actually, it is not a complete transform but just part of it */
|
||||||
profiles = new ICC_Profile[1];
|
profiles = new ICC_Profile[1];
|
||||||
profiles[0] = profile;
|
profiles[0] = profile;
|
||||||
profileIDs = new long[1];
|
lcmsProfiles = new LCMSProfile[1];
|
||||||
profileIDs[0] = LCMS.getProfileID(profile);
|
lcmsProfiles[0] = LCMS.getProfileID(profile);
|
||||||
this.renderType = (renderType == ColorTransform.Any)?
|
this.renderType = (renderType == ColorTransform.Any)?
|
||||||
ICC_Profile.icPerceptual : renderType;
|
ICC_Profile.icPerceptual : renderType;
|
||||||
this.transformType = transformType;
|
this.transformType = transformType;
|
||||||
@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform {
|
|||||||
size+=((LCMSTransform)transforms[i]).profiles.length;
|
size+=((LCMSTransform)transforms[i]).profiles.length;
|
||||||
}
|
}
|
||||||
profiles = new ICC_Profile[size];
|
profiles = new ICC_Profile[size];
|
||||||
profileIDs = new long[size];
|
lcmsProfiles = new LCMSProfile[size];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i=0; i < transforms.length; i++) {
|
for (int i=0; i < transforms.length; i++) {
|
||||||
LCMSTransform curTrans = (LCMSTransform)transforms[i];
|
LCMSTransform curTrans = (LCMSTransform)transforms[i];
|
||||||
System.arraycopy(curTrans.profiles, 0, profiles, j,
|
System.arraycopy(curTrans.profiles, 0, profiles, j,
|
||||||
curTrans.profiles.length);
|
curTrans.profiles.length);
|
||||||
System.arraycopy(curTrans.profileIDs, 0, profileIDs, j,
|
System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
|
||||||
curTrans.profileIDs.length);
|
curTrans.lcmsProfiles.length);
|
||||||
j += curTrans.profiles.length;
|
j += curTrans.profiles.length;
|
||||||
}
|
}
|
||||||
renderType = ((LCMSTransform)transforms[0]).renderType;
|
renderType = ((LCMSTransform)transforms[0]).renderType;
|
||||||
@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform {
|
|||||||
outFormatter = out.pixelType;
|
outFormatter = out.pixelType;
|
||||||
isOutIntPacked = out.isIntPacked;
|
isOutIntPacked = out.isIntPacked;
|
||||||
|
|
||||||
ID = LCMS.createNativeTransform(profileIDs, renderType,
|
ID = LCMS.createTransform(lcmsProfiles, renderType,
|
||||||
inFormatter, isInIntPacked,
|
inFormatter, isInIntPacked,
|
||||||
outFormatter, isOutIntPacked,
|
outFormatter, isOutIntPacked,
|
||||||
disposerReferent);
|
disposerReferent);
|
||||||
|
@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value)
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef union storeID_s { /* store SProfile stuff in a Java Long */
|
typedef struct lcmsProfile_s {
|
||||||
cmsHPROFILE pf;
|
cmsHPROFILE pf;
|
||||||
|
} lcmsProfile_t, *lcmsProfile_p;
|
||||||
|
|
||||||
|
typedef union storeID_s { /* store SProfile stuff in a Java Long */
|
||||||
|
lcmsProfile_p lcmsPf;
|
||||||
cmsHTRANSFORM xf;
|
cmsHTRANSFORM xf;
|
||||||
jobject jobj;
|
jobject jobj;
|
||||||
jlong j;
|
jlong j;
|
||||||
@ -106,7 +110,6 @@ typedef union {
|
|||||||
jint j;
|
jint j;
|
||||||
} TagSignature_t, *TagSignature_p;
|
} TagSignature_t, *TagSignature_p;
|
||||||
|
|
||||||
static jfieldID Trans_profileIDs_fID;
|
|
||||||
static jfieldID Trans_renderType_fID;
|
static jfieldID Trans_renderType_fID;
|
||||||
static jfieldID Trans_ID_fID;
|
static jfieldID Trans_ID_fID;
|
||||||
static jfieldID IL_isIntPacked_fID;
|
static jfieldID IL_isIntPacked_fID;
|
||||||
@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID;
|
|||||||
static jfieldID IL_width_fID;
|
static jfieldID IL_width_fID;
|
||||||
static jfieldID IL_height_fID;
|
static jfieldID IL_height_fID;
|
||||||
static jfieldID IL_imageAtOnce_fID;
|
static jfieldID IL_imageAtOnce_fID;
|
||||||
static jfieldID PF_ID_fID;
|
|
||||||
|
|
||||||
JavaVM *javaVM;
|
JavaVM *javaVM;
|
||||||
|
|
||||||
@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
|
|||||||
return JNI_VERSION_1_6;
|
return JNI_VERSION_1_6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LCMS_freeProfile(JNIEnv *env, jlong ptr) {
|
||||||
|
storeID_t sProfile;
|
||||||
|
sProfile.j = ptr;
|
||||||
|
|
||||||
|
if (sProfile.lcmsPf != NULL) {
|
||||||
|
if (sProfile.lcmsPf->pf != NULL) {
|
||||||
|
cmsCloseProfile(sProfile.lcmsPf->pf);
|
||||||
|
}
|
||||||
|
free(sProfile.lcmsPf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LCMS_freeTransform(JNIEnv *env, jlong ID)
|
void LCMS_freeTransform(JNIEnv *env, jlong ID)
|
||||||
{
|
{
|
||||||
storeID_t sTrans;
|
storeID_t sTrans;
|
||||||
@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
|||||||
jlong* ids;
|
jlong* ids;
|
||||||
|
|
||||||
size = (*env)->GetArrayLength (env, profileIDs);
|
size = (*env)->GetArrayLength (env, profileIDs);
|
||||||
ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0);
|
ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
|
||||||
|
|
||||||
#ifdef _LITTLE_ENDIAN
|
#ifdef _LITTLE_ENDIAN
|
||||||
/* Reversing data packed into int for LE archs */
|
/* Reversing data packed into int for LE archs */
|
||||||
@ -186,6 +200,8 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
|||||||
iccArray = (cmsHPROFILE*) malloc(
|
iccArray = (cmsHPROFILE*) malloc(
|
||||||
size*2*sizeof(cmsHPROFILE));
|
size*2*sizeof(cmsHPROFILE));
|
||||||
if (iccArray == NULL) {
|
if (iccArray == NULL) {
|
||||||
|
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
|
||||||
|
|
||||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
|||||||
cmsColorSpaceSignature cs;
|
cmsColorSpaceSignature cs;
|
||||||
|
|
||||||
sTrans.j = ids[i];
|
sTrans.j = ids[i];
|
||||||
icc = sTrans.pf;
|
icc = sTrans.lcmsPf->pf;
|
||||||
iccArray[j++] = icc;
|
iccArray[j++] = icc;
|
||||||
|
|
||||||
/* Middle non-abstract profiles should be doubled before passing to
|
/* Middle non-abstract profiles should be doubled before passing to
|
||||||
@ -215,13 +231,15 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
|||||||
sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j,
|
sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j,
|
||||||
inFormatter, outFormatter, renderType, 0);
|
inFormatter, outFormatter, renderType, 0);
|
||||||
|
|
||||||
(*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0);
|
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
|
||||||
|
|
||||||
if (sTrans.xf == NULL) {
|
if (sTrans.xf == NULL) {
|
||||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
|
||||||
"sTrans.xf == NULL");
|
"sTrans.xf == NULL");
|
||||||
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
if ((*env)->ExceptionOccurred(env) == NULL) {
|
||||||
"Cannot get color transform");
|
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
||||||
|
"Cannot get color transform");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
|
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
|
||||||
}
|
}
|
||||||
@ -236,20 +254,23 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
|||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: loadProfile
|
* Method: loadProfile
|
||||||
* Signature: ([B)J
|
* Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
|
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
|
||||||
(JNIEnv *env, jobject obj, jbyteArray data)
|
(JNIEnv *env, jobject obj, jbyteArray data, jobject disposerRef)
|
||||||
{
|
{
|
||||||
jbyte* dataArray;
|
jbyte* dataArray;
|
||||||
jint dataSize;
|
jint dataSize;
|
||||||
storeID_t sProf;
|
storeID_t sProf;
|
||||||
|
cmsHPROFILE pf;
|
||||||
|
|
||||||
if (JNU_IsNull(env, data)) {
|
if (JNU_IsNull(env, data)) {
|
||||||
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sProf.j = 0L;
|
||||||
|
|
||||||
dataArray = (*env)->GetByteArrayElements (env, data, 0);
|
dataArray = (*env)->GetByteArrayElements (env, data, 0);
|
||||||
dataSize = (*env)->GetArrayLength (env, data);
|
dataSize = (*env)->GetArrayLength (env, data);
|
||||||
|
|
||||||
@ -258,22 +279,37 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
|
|||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
|
pf = cmsOpenProfileFromMem((const void *)dataArray,
|
||||||
(cmsUInt32Number) dataSize);
|
(cmsUInt32Number) dataSize);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
||||||
|
|
||||||
if (sProf.pf == NULL) {
|
if (pf == NULL) {
|
||||||
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
||||||
} else {
|
} else {
|
||||||
/* Sanity check: try to save the profile in order
|
/* Sanity check: try to save the profile in order
|
||||||
* to force basic validation.
|
* to force basic validation.
|
||||||
*/
|
*/
|
||||||
cmsUInt32Number pfSize = 0;
|
cmsUInt32Number pfSize = 0;
|
||||||
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
|
if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
|
||||||
pfSize < sizeof(cmsICCHeader))
|
pfSize < sizeof(cmsICCHeader))
|
||||||
{
|
{
|
||||||
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
|
||||||
|
|
||||||
|
cmsCloseProfile(pf);
|
||||||
|
pf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pf != NULL) {
|
||||||
|
// create profile holder
|
||||||
|
sProf.lcmsPf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t));
|
||||||
|
if (sProf.lcmsPf != NULL) {
|
||||||
|
// register the disposer record
|
||||||
|
sProf.lcmsPf->pf = pf;
|
||||||
|
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sProf.j);
|
||||||
|
} else {
|
||||||
|
cmsCloseProfile(pf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,37 +318,17 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: freeProfile
|
* Method: getProfileSizeNative
|
||||||
* Signature: (J)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
|
|
||||||
(JNIEnv *env, jobject obj, jlong id)
|
|
||||||
{
|
|
||||||
storeID_t sProf;
|
|
||||||
|
|
||||||
sProf.j = id;
|
|
||||||
if (cmsCloseProfile(sProf.pf) == 0) {
|
|
||||||
J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
|
|
||||||
"== 0", id);
|
|
||||||
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
|
||||||
"Cannot close profile");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
|
||||||
* Method: getProfileSize
|
|
||||||
* Signature: (J)I
|
* Signature: (J)I
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
|
JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative
|
||||||
(JNIEnv *env, jobject obj, jlong id)
|
(JNIEnv *env, jobject obj, jlong id)
|
||||||
{
|
{
|
||||||
storeID_t sProf;
|
storeID_t sProf;
|
||||||
cmsUInt32Number pfSize = 0;
|
cmsUInt32Number pfSize = 0;
|
||||||
sProf.j = id;
|
sProf.j = id;
|
||||||
|
|
||||||
if (cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
|
if (cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
|
||||||
return (jint)pfSize;
|
return (jint)pfSize;
|
||||||
} else {
|
} else {
|
||||||
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
||||||
@ -323,10 +339,10 @@ JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: getProfileData
|
* Method: getProfileDataNative
|
||||||
* Signature: (J[B)V
|
* Signature: (J[B)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
|
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
|
||||||
(JNIEnv *env, jobject obj, jlong id, jbyteArray data)
|
(JNIEnv *env, jobject obj, jlong id, jbyteArray data)
|
||||||
{
|
{
|
||||||
storeID_t sProf;
|
storeID_t sProf;
|
||||||
@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
|
|||||||
sProf.j = id;
|
sProf.j = id;
|
||||||
|
|
||||||
// determine actual profile size
|
// determine actual profile size
|
||||||
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) {
|
if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) {
|
||||||
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
||||||
"Can not access specified profile.");
|
"Can not access specified profile.");
|
||||||
return;
|
return;
|
||||||
@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
|
|||||||
|
|
||||||
dataArray = (*env)->GetByteArrayElements (env, data, 0);
|
dataArray = (*env)->GetByteArrayElements (env, data, 0);
|
||||||
|
|
||||||
status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize);
|
status = cmsSaveProfileToMem(sProf.lcmsPf->pf, dataArray, &pfSize);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
||||||
|
|
||||||
@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
|
|||||||
/* Get profile header info */
|
/* Get profile header info */
|
||||||
static cmsBool _getHeaderInfo(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 _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
|
||||||
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
|
static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -412,7 +428,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
|
status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
||||||
|
|
||||||
@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmsIsTag(sProf.pf, sig.cms)) {
|
if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) {
|
||||||
tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
|
tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
JNU_ThrowByName(env, "java/awt/color/CMMException",
|
||||||
"ICC profile tag not found");
|
"ICC profile tag not found");
|
||||||
@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
|
bufSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
|
||||||
|
|
||||||
@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
|
|||||||
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
|
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
|
||||||
{
|
{
|
||||||
storeID_t sProf;
|
storeID_t sProf;
|
||||||
|
cmsHPROFILE pfReplace = NULL;
|
||||||
|
|
||||||
TagSignature_t sig;
|
TagSignature_t sig;
|
||||||
cmsBool status;
|
cmsBool status = FALSE;
|
||||||
jbyte* dataArray;
|
jbyte* dataArray;
|
||||||
int tagSize;
|
int tagSize;
|
||||||
|
|
||||||
@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tagSig == SigHead) {
|
if (tagSig == SigHead) {
|
||||||
status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
|
status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize);
|
||||||
} else {
|
} else {
|
||||||
status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize);
|
/*
|
||||||
|
* 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.lcmsPf->pf, sig.cms, dataArray, tagSize);
|
||||||
|
status = (pfReplace != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
|
(*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
|
JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
|
||||||
|
} else if (pfReplace != NULL) {
|
||||||
|
cmsCloseProfile(sProf.lcmsPf->pf);
|
||||||
|
sProf.lcmsPf->pf = pfReplace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,12 +651,27 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
|
|||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: getProfileID
|
* Method: getProfileID
|
||||||
* Signature: (Ljava/awt/color/ICC_Profile;)J
|
* Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
|
JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
|
||||||
(JNIEnv *env, jclass cls, jobject pf)
|
(JNIEnv *env, jclass cls, jobject pf)
|
||||||
{
|
{
|
||||||
return (*env)->GetLongField (env, pf, PF_ID_fID);
|
jfieldID fid = (*env)->GetFieldID (env,
|
||||||
|
(*env)->GetObjectClass(env, pf),
|
||||||
|
"cmmProfile", "Lsun/java2d/cmm/Profile;");
|
||||||
|
|
||||||
|
jclass clsLcmsProfile = (*env)->FindClass(env,
|
||||||
|
"sun/java2d/cmm/lcms/LCMSProfile");
|
||||||
|
|
||||||
|
jobject cmmProfile = (*env)->GetObjectField (env, pf, fid);
|
||||||
|
|
||||||
|
if (JNU_IsNull(env, cmmProfile)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) {
|
||||||
|
return cmmProfile;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -644,7 +686,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
|
|||||||
* corresponding classes to avoid problems with invalidating ids by class
|
* corresponding classes to avoid problems with invalidating ids by class
|
||||||
* unloading
|
* unloading
|
||||||
*/
|
*/
|
||||||
Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
|
|
||||||
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
|
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
|
||||||
Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
|
Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
|
||||||
|
|
||||||
@ -658,8 +699,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
|
|||||||
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
|
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
|
||||||
IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
|
IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
|
||||||
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
|
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
|
||||||
|
|
||||||
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
|
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
|
||||||
@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
|
/* Returns new profile handler, if it was created successfully,
|
||||||
cmsTagSignature sig,
|
NULL otherwise.
|
||||||
|
*/
|
||||||
|
static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
|
||||||
|
const cmsTagSignature sig,
|
||||||
jbyte *pData, jint size)
|
jbyte *pData, jint size)
|
||||||
{
|
{
|
||||||
cmsBool status;
|
|
||||||
cmsUInt32Number pfSize = 0;
|
cmsUInt32Number pfSize = 0;
|
||||||
cmsUInt8Number* pfBuffer = NULL;
|
const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
|
||||||
|
cmsInt32Number i;
|
||||||
|
cmsHPROFILE pfSanity = NULL;
|
||||||
|
|
||||||
|
cmsICCHeader hdr = { 0 };
|
||||||
|
|
||||||
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
|
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
|
||||||
if (NULL != p) {
|
|
||||||
cmsICCHeader hdr = { 0 };
|
|
||||||
|
|
||||||
/* Populate the placeholder's header according to target profile */
|
if (NULL == p) {
|
||||||
hdr.flags = cmsGetHeaderFlags(pfTarget);
|
return NULL;
|
||||||
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);
|
// Populate the placeholder's header according to target profile
|
||||||
cmsSetHeaderManufacturer(p, hdr.manufacturer);
|
hdr.flags = cmsGetHeaderFlags(pfTarget);
|
||||||
cmsSetHeaderModel(p, hdr.model);
|
hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
|
||||||
cmsSetHeaderAttributes(p, hdr.attributes);
|
hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
|
||||||
cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
|
hdr.model = cmsGetHeaderModel(pfTarget);
|
||||||
cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
|
hdr.pcs = cmsGetPCS(pfTarget);
|
||||||
cmsSetPCS(p, hdr.pcs);
|
hdr.colorSpace = cmsGetColorSpace(pfTarget);
|
||||||
cmsSetColorSpace(p, hdr.colorSpace);
|
hdr.deviceClass = cmsGetDeviceClass(pfTarget);
|
||||||
cmsSetDeviceClass(p, hdr.deviceClass);
|
hdr.version = cmsGetEncodedICCversion(pfTarget);
|
||||||
cmsSetEncodedICCversion(p, hdr.version);
|
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)) {
|
// now write the user supplied tag
|
||||||
if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
|
if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
|
||||||
pfBuffer = malloc(pfSize);
|
cmsCloseProfile(p);
|
||||||
if (pfBuffer != NULL) {
|
return NULL;
|
||||||
/* load raw profile data into the buffer */
|
}
|
||||||
if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) {
|
|
||||||
free(pfBuffer);
|
// copy tags from the original profile
|
||||||
pfBuffer = NULL;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmsCloseProfile(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfBuffer == NULL) {
|
if (!isTagReady) {
|
||||||
return FALSE;
|
cmsCloseProfile(p);
|
||||||
}
|
return NULL;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 6476665 6523403 6733501 7042594
|
* @bug 6476665 6523403 6733501 7042594 7043064
|
||||||
* @summary Verifies reading and writing profiles and tags of the standard color
|
* @summary Verifies reading and writing profiles and tags of the standard color
|
||||||
* spaces
|
* spaces
|
||||||
* @run main ReadWriteProfileTest
|
* @run main ReadWriteProfileTest
|
||||||
@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable {
|
|||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
for (int i = 0; i < cspaces.length; i++) {
|
for (int i = 0; i < cspaces.length; i++) {
|
||||||
|
System.out.println("Profile: " + csNames[i]);
|
||||||
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
|
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
|
||||||
byte [] data = pf.getData();
|
byte [] data = pf.getData();
|
||||||
pf = ICC_Profile.getInstance(data);
|
pf = ICC_Profile.getInstance(data);
|
||||||
@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int tagSig : tags[i].keySet()) {
|
for (int tagSig : tags[i].keySet()) {
|
||||||
|
String signature = SigToString(tagSig);
|
||||||
|
System.out.printf("Tag: %s\n", signature);
|
||||||
|
System.out.flush();
|
||||||
|
|
||||||
byte [] tagData = pf.getData(tagSig);
|
byte [] tagData = pf.getData(tagSig);
|
||||||
byte [] empty = new byte[tagData.length];
|
byte [] empty = new byte[tagData.length];
|
||||||
boolean emptyDataRejected = false;
|
boolean emptyDataRejected = false;
|
||||||
@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable {
|
|||||||
throw new
|
throw new
|
||||||
RuntimeException("Test failed: empty tag data was not rejected.");
|
RuntimeException("Test failed: empty tag data was not rejected.");
|
||||||
}
|
}
|
||||||
pf.setData(tagSig, tagData);
|
try {
|
||||||
|
pf.setData(tagSig, tagData);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// let's ignore this exception for Kodak proprietary tags
|
||||||
|
if (isKodakExtention(signature)) {
|
||||||
|
System.out.println("Ignore Kodak tag: " + signature);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Test failed!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
byte [] tagData1 = pf.getData(tagSig);
|
byte [] tagData1 = pf.getData(tagSig);
|
||||||
|
|
||||||
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
|
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
|
||||||
{
|
{
|
||||||
System.err.println("Incorrect result of getData(int) with" +
|
System.err.println("Incorrect result of getData(int) with" +
|
||||||
" tag " +
|
" tag " +
|
||||||
Integer.toHexString(tagSig) +
|
SigToString(tagSig) +
|
||||||
" of " + csNames[i] + " profile");
|
" of " + csNames[i] + " profile");
|
||||||
|
|
||||||
throw new RuntimeException("Incorrect result of " +
|
throw new RuntimeException("Incorrect result of " +
|
||||||
@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isKodakExtention(String signature) {
|
||||||
|
return signature.matches("K\\d\\d\\d");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String SigToString(int tagSig ) {
|
||||||
|
return String.format("%c%c%c%c",
|
||||||
|
(char)(0xff & (tagSig >> 24)),
|
||||||
|
(char)(0xff & (tagSig >> 16)),
|
||||||
|
(char)(0xff & (tagSig >> 8)),
|
||||||
|
(char)(0xff & (tagSig)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String [] args) {
|
public static void main(String [] args) {
|
||||||
ReadWriteProfileTest test = new ReadWriteProfileTest();
|
ReadWriteProfileTest test = new ReadWriteProfileTest();
|
||||||
test.run();
|
test.run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user