8263482: Make access to the ICC color profiles data multithread-friendly
Reviewed-by: azvegint
This commit is contained in:
parent
d185655c27
commit
1a21f77971
@ -91,7 +91,19 @@ public class ICC_Profile implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = -3938515861990936766L;
|
private static final long serialVersionUID = -3938515861990936766L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementation specific CMM profile, {@code null} if this
|
||||||
|
* {@code ICC_Profile} is not activated by the {@link #cmmProfile()} method.
|
||||||
|
* This field must not be used directly and only via {@link #cmmProfile()}.
|
||||||
|
*/
|
||||||
private transient volatile Profile cmmProfile;
|
private transient volatile Profile cmmProfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores some information about {@code ICC_Profile} without causing a
|
||||||
|
* deferred profile to be loaded. Note that we can defer the loading of
|
||||||
|
* standard profiles only. If this field is null, then {@link #cmmProfile}
|
||||||
|
* should be used to access profile information.
|
||||||
|
*/
|
||||||
private transient volatile ProfileDeferralInfo deferralInfo;
|
private transient volatile ProfileDeferralInfo deferralInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -917,32 +929,37 @@ public class ICC_Profile implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates the deferred standard profiles. Implementation of this method
|
* Activates and returns the deferred standard profiles. Implementation of
|
||||||
* mimics the old behaviour when the CMMException and IOException were
|
* this method mimics the old behaviour when the {@code CMMException} and
|
||||||
* wrapped by the ProfileDataException, and the ProfileDataException itself
|
* {@code IOException} were wrapped by the {@code ProfileDataException}, and
|
||||||
* was ignored during activation.
|
* the {@code ProfileDataException} itself was ignored during activation.
|
||||||
|
*
|
||||||
|
* @return the implementation specific CMM profile, or {@code null}
|
||||||
*/
|
*/
|
||||||
private void activate() {
|
private Profile cmmProfile() {
|
||||||
if (cmmProfile == null) {
|
Profile p = cmmProfile;
|
||||||
|
if (p != null) {
|
||||||
|
return p; // one volatile read on common path
|
||||||
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (cmmProfile != null) {
|
if (cmmProfile != null) {
|
||||||
return;
|
return cmmProfile;
|
||||||
}
|
}
|
||||||
var is = getStandardProfileInputStream(deferralInfo.filename);
|
var is = getStandardProfileInputStream(deferralInfo.filename);
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
try (is) {
|
try (is) {
|
||||||
byte[] data = getProfileDataFromStream(is);
|
byte[] data = getProfileDataFromStream(is);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
cmmProfile = CMSManager.getModule().loadProfile(data);
|
p = cmmProfile = CMSManager.getModule().loadProfile(data);
|
||||||
// from now we cannot use the deferred value, drop it
|
// from now we cannot use the deferred value, drop it
|
||||||
deferralInfo = null;
|
deferralInfo = null;
|
||||||
}
|
}
|
||||||
} catch (CMMException | IOException ignore) {
|
} catch (CMMException | IOException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1006,8 +1023,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
if (info != null) {
|
if (info != null) {
|
||||||
return info.colorSpaceType;
|
return info.colorSpaceType;
|
||||||
}
|
}
|
||||||
activate();
|
return getColorSpaceType(cmmProfile());
|
||||||
return getColorSpaceType(cmmProfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getColorSpaceType(Profile p) {
|
private static int getColorSpaceType(Profile p) {
|
||||||
@ -1030,8 +1046,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
* {@code ColorSpace} class
|
* {@code ColorSpace} class
|
||||||
*/
|
*/
|
||||||
public int getPCSType() {
|
public int getPCSType() {
|
||||||
activate();
|
byte[] theHeader = getData(icSigHead);
|
||||||
byte[] theHeader = getData(cmmProfile, icSigHead);
|
|
||||||
int thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
|
int thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
|
||||||
return iccCStoJCS(thePCSSig);
|
return iccCStoJCS(thePCSSig);
|
||||||
}
|
}
|
||||||
@ -1067,8 +1082,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
* @see #setData(int, byte[])
|
* @see #setData(int, byte[])
|
||||||
*/
|
*/
|
||||||
public byte[] getData() {
|
public byte[] getData() {
|
||||||
activate();
|
return CMSManager.getModule().getProfileData(cmmProfile());
|
||||||
return CMSManager.getModule().getProfileData(cmmProfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1085,8 +1099,8 @@ public class ICC_Profile implements Serializable {
|
|||||||
* @see #setData(int, byte[])
|
* @see #setData(int, byte[])
|
||||||
*/
|
*/
|
||||||
public byte[] getData(int tagSignature) {
|
public byte[] getData(int tagSignature) {
|
||||||
activate();
|
byte[] t = getData(cmmProfile(), tagSignature);
|
||||||
return getData(cmmProfile, tagSignature);
|
return t != null ? t.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] getData(Profile p, int tagSignature) {
|
private static byte[] getData(Profile p, int tagSignature) {
|
||||||
@ -1115,8 +1129,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
* @see #getData
|
* @see #getData
|
||||||
*/
|
*/
|
||||||
public void setData(int tagSignature, byte[] tagData) {
|
public void setData(int tagSignature, byte[] tagData) {
|
||||||
activate();
|
CMSManager.getModule().setTagData(cmmProfile(), tagSignature, tagData);
|
||||||
CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1170,7 +1183,7 @@ public class ICC_Profile implements Serializable {
|
|||||||
* Returns a float array of length 3 containing the X, Y, and Z components
|
* Returns a float array of length 3 containing the X, Y, and Z components
|
||||||
* encoded in an XYZType tag.
|
* encoded in an XYZType tag.
|
||||||
*/
|
*/
|
||||||
float[] getXYZTag(int tagSignature) {
|
final float[] getXYZTag(int tagSignature) {
|
||||||
byte[] theData = getData(tagSignature);
|
byte[] theData = getData(tagSignature);
|
||||||
float[] theXYZNumber = new float[3]; /* array to return */
|
float[] theXYZNumber = new float[3]; /* array to return */
|
||||||
|
|
||||||
|
@ -33,9 +33,14 @@ import sun.security.action.GetPropertyAction;
|
|||||||
|
|
||||||
public final class CMSManager {
|
public final class CMSManager {
|
||||||
|
|
||||||
private static PCMM cmmImpl = null;
|
private static volatile PCMM cmmImpl;
|
||||||
|
|
||||||
public static synchronized PCMM getModule() {
|
public static PCMM getModule() {
|
||||||
|
PCMM loc = cmmImpl;
|
||||||
|
return loc != null ? loc : createModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized PCMM createModule() {
|
||||||
if (cmmImpl != null) {
|
if (cmmImpl != null) {
|
||||||
return cmmImpl;
|
return cmmImpl;
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,8 @@ import java.awt.color.ICC_Profile;
|
|||||||
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.Profile;
|
||||||
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
|
|
||||||
|
|
||||||
public class LCMS implements PCMM {
|
final class LCMS implements PCMM {
|
||||||
|
|
||||||
/* methods invoked from ICC_Profile */
|
/* methods invoked from ICC_Profile */
|
||||||
@Override
|
@Override
|
||||||
@ -48,54 +47,13 @@ public class LCMS implements PCMM {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long loadProfileNative(byte[] data, Object ref);
|
private static LCMSProfile getLcmsProfile(Profile p) {
|
||||||
|
|
||||||
private LCMSProfile getLcmsProfile(Profile p) {
|
|
||||||
if (p instanceof LCMSProfile) {
|
if (p instanceof LCMSProfile) {
|
||||||
return (LCMSProfile)p;
|
return (LCMSProfile)p;
|
||||||
}
|
}
|
||||||
throw new CMMException("Invalid profile: " + p);
|
throw new CMMException("Invalid profile: " + p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getProfileData(final Profile p) {
|
|
||||||
LCMSProfile lcmsProfile = getLcmsProfile(p);
|
|
||||||
synchronized (lcmsProfile) {
|
|
||||||
return getProfileDataNative(lcmsProfile.getLcmsPtr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private native byte[] getProfileDataNative(long ptr);
|
|
||||||
|
|
||||||
static native byte[] getTagNative(long profileID, int signature);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getTagData(Profile p, int tagSignature) {
|
|
||||||
final LCMSProfile lcmsProfile = getLcmsProfile(p);
|
|
||||||
synchronized (lcmsProfile) {
|
|
||||||
TagData t = lcmsProfile.getTag(tagSignature);
|
|
||||||
return t != null ? t.getData() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
|
|
||||||
final LCMSProfile profile = getLcmsProfile(p);
|
|
||||||
|
|
||||||
synchronized (profile) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes supplied data as a tag into the profile.
|
* Writes supplied data as a tag into the profile.
|
||||||
* Destroys old profile, if new one was successfully
|
* Destroys old profile, if new one was successfully
|
||||||
@ -106,10 +64,27 @@ public class LCMS implements PCMM {
|
|||||||
* Throws CMMException if operation fails, preserve old profile from
|
* Throws CMMException if operation fails, preserve old profile from
|
||||||
* destruction.
|
* destruction.
|
||||||
*/
|
*/
|
||||||
private native void setTagDataNative(long ptr, int tagSignature,
|
static native void setTagDataNative(long ptr, int tagSignature, byte[] data);
|
||||||
byte[] data);
|
static native byte[] getProfileDataNative(long ptr);
|
||||||
|
static native byte[] getTagNative(long profileID, int signature);
|
||||||
|
private static native long loadProfileNative(byte[] data, Object ref);
|
||||||
|
|
||||||
public static synchronized native LCMSProfile getProfileID(ICC_Profile profile);
|
@Override
|
||||||
|
public byte[] getProfileData(Profile p) {
|
||||||
|
return getLcmsProfile(p).getProfileData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getTagData(Profile p, int tagSignature) {
|
||||||
|
return getLcmsProfile(p).getTag(tagSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
|
||||||
|
getLcmsProfile(p).setTag(tagSignature, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static synchronized native LCMSProfile getProfileID(ICC_Profile profile);
|
||||||
|
|
||||||
/* Helper method used from LCMSColorTransfrom */
|
/* Helper method used from LCMSColorTransfrom */
|
||||||
static long createTransform(
|
static long createTransform(
|
||||||
|
@ -25,69 +25,63 @@
|
|||||||
|
|
||||||
package sun.java2d.cmm.lcms;
|
package sun.java2d.cmm.lcms;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.locks.StampedLock;
|
||||||
|
|
||||||
import sun.java2d.cmm.Profile;
|
import sun.java2d.cmm.Profile;
|
||||||
|
|
||||||
final class LCMSProfile extends Profile {
|
final class LCMSProfile extends Profile {
|
||||||
private final TagCache tagCache;
|
|
||||||
|
|
||||||
private final Object disposerReferent;
|
private final Object disposerReferent;
|
||||||
|
private final Map<Integer, byte[]> tags = new ConcurrentHashMap<>();
|
||||||
|
private final StampedLock lock = new StampedLock();
|
||||||
|
|
||||||
LCMSProfile(long ptr, Object ref) {
|
LCMSProfile(long ptr, Object ref) {
|
||||||
super(ptr);
|
super(ptr);
|
||||||
|
|
||||||
disposerReferent = ref;
|
disposerReferent = ref;
|
||||||
|
|
||||||
tagCache = new TagCache(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long getLcmsPtr() {
|
long getLcmsPtr() {
|
||||||
return this.getNativePtr();
|
return getNativePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
TagData getTag(int sig) {
|
byte[] getProfileData() {
|
||||||
return tagCache.getTag(sig);
|
long stamp = lock.readLock();
|
||||||
|
try {
|
||||||
|
return LCMS.getProfileDataNative(getNativePtr());
|
||||||
|
} finally {
|
||||||
|
lock.unlockRead(stamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearTagCache() {
|
byte[] getTag(int sig) {
|
||||||
tagCache.clear();
|
byte[] t = tags.get(sig);
|
||||||
}
|
if (t != null) {
|
||||||
|
|
||||||
private static final class TagCache {
|
|
||||||
private final LCMSProfile profile;
|
|
||||||
private final HashMap<Integer, TagData> tags = new HashMap<>();
|
|
||||||
|
|
||||||
private TagCache(LCMSProfile p) {
|
|
||||||
profile = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
private 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(tagData);
|
|
||||||
tags.put(sig, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
long stamp = lock.readLock();
|
||||||
|
try {
|
||||||
|
return tags.computeIfAbsent(sig, (key) -> {
|
||||||
|
return LCMS.getTagNative(getNativePtr(), key);
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
lock.unlockRead(stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void clear() {
|
void setTag(int tagSignature, byte[] data) {
|
||||||
|
long stamp = lock.writeLock();
|
||||||
|
try {
|
||||||
tags.clear();
|
tags.clear();
|
||||||
}
|
// Now we are going to update the profile with new tag data
|
||||||
}
|
// In some cases, we may change the pointer to the native profile.
|
||||||
|
//
|
||||||
static final class TagData {
|
// If we fail to write tag data for any reason, the old pointer
|
||||||
private final byte[] data;
|
// should be used.
|
||||||
|
LCMS.setTagDataNative(getNativePtr(), tagSignature, data);
|
||||||
TagData(byte[] data) {
|
} finally {
|
||||||
this.data = data;
|
lock.unlockWrite(stamp);
|
||||||
}
|
|
||||||
|
|
||||||
byte[] getData() {
|
|
||||||
return data.clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ void LCMS_freeTransform(JNIEnv *env, jlong ID)
|
|||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: createNativeTransform
|
* Method: createNativeTransform
|
||||||
* Signature: ([JI)J
|
* Signature: ([JIIZIZLjava/lang/Object;)J
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
|
||||||
(JNIEnv *env, jclass cls, jlongArray profileIDs, jint renderType,
|
(JNIEnv *env, jclass cls, jlongArray profileIDs, jint renderType,
|
||||||
@ -214,11 +214,11 @@ 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: loadProfileNative
|
||||||
* Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
|
* Signature: ([BLjava/lang/Object;)J
|
||||||
*/
|
*/
|
||||||
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, jobject disposerRef)
|
(JNIEnv *env, jclass cls, jbyteArray data, jobject disposerRef)
|
||||||
{
|
{
|
||||||
jbyte* dataArray;
|
jbyte* dataArray;
|
||||||
jint dataSize;
|
jint dataSize;
|
||||||
@ -278,10 +278,10 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
|
|||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: getProfileDataNative
|
* Method: getProfileDataNative
|
||||||
* Signature: (J[B)V
|
* Signature: (J)[B
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
|
JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
|
||||||
(JNIEnv *env, jobject obj, jlong id)
|
(JNIEnv *env, jclass cls, jlong id)
|
||||||
{
|
{
|
||||||
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
||||||
cmsUInt32Number pfSize = 0;
|
cmsUInt32Number pfSize = 0;
|
||||||
@ -325,11 +325,11 @@ static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jb
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: getTagData
|
* Method: getTagNative
|
||||||
* Signature: (JI[B)V
|
* Signature: (JI)[B
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
||||||
(JNIEnv *env, jobject obj, jlong id, jint tagSig)
|
(JNIEnv *env, jclass cls, jlong id, jint tagSig)
|
||||||
{
|
{
|
||||||
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
||||||
TagSignature_t sig;
|
TagSignature_t sig;
|
||||||
@ -410,11 +410,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_java2d_cmm_lcms_LCMS
|
* Class: sun_java2d_cmm_lcms_LCMS
|
||||||
* Method: setTagData
|
* Method: setTagDataNative
|
||||||
* Signature: (JI[B)V
|
* Signature: (JI[B)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
|
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
|
||||||
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
|
(JNIEnv *env, jclass cls, jlong id, jint tagSig, jbyteArray data)
|
||||||
{
|
{
|
||||||
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
||||||
cmsHPROFILE pfReplace = NULL;
|
cmsHPROFILE pfReplace = NULL;
|
||||||
@ -510,7 +510,7 @@ void releaseILData (JNIEnv *env, void* pData, jint dataType,
|
|||||||
* Signature: (Lsun/java2d/cmm/lcms/LCMSTransform;Lsun/java2d/cmm/lcms/LCMSImageLayout;Lsun/java2d/cmm/lcms/LCMSImageLayout;)V
|
* Signature: (Lsun/java2d/cmm/lcms/LCMSTransform;Lsun/java2d/cmm/lcms/LCMSImageLayout;Lsun/java2d/cmm/lcms/LCMSImageLayout;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
|
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
|
||||||
(JNIEnv *env, jclass obj, jobject trans, jobject src, jobject dst)
|
(JNIEnv *env, jclass cls, jobject trans, jobject src, jobject dst)
|
||||||
{
|
{
|
||||||
cmsHTRANSFORM sTrans = NULL;
|
cmsHTRANSFORM sTrans = NULL;
|
||||||
int srcDType, dstDType;
|
int srcDType, dstDType;
|
||||||
@ -579,50 +579,32 @@ 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;)Lsun/java2d/cmm/lcms/LCMSProfile
|
* Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobject 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)
|
||||||
{
|
{
|
||||||
jclass clsLcmsProfile;
|
|
||||||
jobject cmmProfile;
|
|
||||||
jfieldID fid;
|
|
||||||
|
|
||||||
if (pf == NULL) {
|
if (pf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass pcls = (*env)->GetObjectClass(env, pf);
|
jclass pcls = (*env)->GetObjectClass(env, pf);
|
||||||
if (pcls == NULL) {
|
if (pcls == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
jmethodID mid = (*env)->GetMethodID(env, pcls, "activate", "()V");
|
jmethodID mid = (*env)->GetMethodID(env, pcls, "cmmProfile",
|
||||||
|
"()Lsun/java2d/cmm/Profile;");
|
||||||
if (mid == NULL) {
|
if (mid == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
(*env)->CallVoidMethod(env, pf, mid);
|
jobject cmmProfile = (*env)->CallObjectMethod(env, pf, mid);
|
||||||
if ((*env)->ExceptionOccurred(env)) {
|
if ((*env)->ExceptionOccurred(env)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
jclass lcmsPCls = (*env)->FindClass(env, "sun/java2d/cmm/lcms/LCMSProfile");
|
||||||
fid = (*env)->GetFieldID(env, pcls, "cmmProfile",
|
if (lcmsPCls == NULL) {
|
||||||
"Lsun/java2d/cmm/Profile;");
|
|
||||||
if (fid == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if ((*env)->IsInstanceOf(env, cmmProfile, lcmsPCls)) {
|
||||||
clsLcmsProfile = (*env)->FindClass(env,
|
|
||||||
"sun/java2d/cmm/lcms/LCMSProfile");
|
|
||||||
if (clsLcmsProfile == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmmProfile = (*env)->GetObjectField (env, pf, fid);
|
|
||||||
|
|
||||||
if (JNU_IsNull(env, cmmProfile)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) {
|
|
||||||
return cmmProfile;
|
return cmmProfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user