7043064: sun/java2d/cmm/ tests failed against RI b141 & b138-nightly

Reviewed-by: prr, vadim
This commit is contained in:
Andrew Brygin 2013-09-04 12:10:07 +04:00
parent 24f306c761
commit 256894796f
13 changed files with 551 additions and 309 deletions

View File

@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;

View File

@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;

View File

@ -37,6 +37,7 @@ package java.awt.color;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable {
private static final long serialVersionUID = -3938515861990936766L;
transient long ID;
private transient Profile cmmProfile;
private transient ProfileDeferralInfo deferralInfo;
private transient ProfileActivator profileActivator;
@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable {
/**
* Constructs an ICC_Profile object with a given ID.
*/
ICC_Profile(long ID) {
this.ID = ID;
ICC_Profile(Profile p) {
this.cmmProfile = p;
}
@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable {
* Frees the resources associated with an ICC_Profile object.
*/
protected void finalize () {
if (ID != 0) {
CMSManager.getModule().freeProfile(ID);
if (cmmProfile != null) {
CMSManager.getModule().freeProfile(cmmProfile);
} else if (profileActivator != null) {
ProfileDeferralMgr.unregisterDeferral(profileActivator);
}
@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable {
public static ICC_Profile getInstance(byte[] data) {
ICC_Profile thisProfile;
long theID;
Profile p = null;
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable {
ProfileDataVerifier.verify(data);
try {
theID = CMSManager.getModule().loadProfile(data);
p = CMSManager.getModule().loadProfile(data);
} catch (CMMException c) {
throw new IllegalArgumentException("Invalid ICC Profile Data");
}
try {
if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
(getData (theID, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigGrayTRCTag) != null)) {
thisProfile = new ICC_ProfileGray (theID);
if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) &&
(getData (p, icSigMediaWhitePointTag) != null) &&
(getData (p, icSigGrayTRCTag) != null)) {
thisProfile = new ICC_ProfileGray (p);
}
else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
(getData (theID, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigRedColorantTag) != null) &&
(getData (theID, icSigGreenColorantTag) != null) &&
(getData (theID, icSigBlueColorantTag) != null) &&
(getData (theID, icSigRedTRCTag) != null) &&
(getData (theID, icSigGreenTRCTag) != null) &&
(getData (theID, icSigBlueTRCTag) != null)) {
thisProfile = new ICC_ProfileRGB (theID);
else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
(getData (p, icSigMediaWhitePointTag) != null) &&
(getData (p, icSigRedColorantTag) != null) &&
(getData (p, icSigGreenColorantTag) != null) &&
(getData (p, icSigBlueColorantTag) != null) &&
(getData (p, icSigRedTRCTag) != null) &&
(getData (p, icSigGreenTRCTag) != null) &&
(getData (p, icSigBlueTRCTag) != null)) {
thisProfile = new ICC_ProfileRGB (p);
}
else {
thisProfile = new ICC_Profile (theID);
thisProfile = new ICC_Profile (p);
}
} catch (CMMException c) {
thisProfile = new ICC_Profile (theID);
thisProfile = new ICC_Profile (p);
}
return thisProfile;
}
@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable {
fileName);
}
try {
ID = CMSManager.getModule().loadProfile(profileData);
cmmProfile = CMSManager.getModule().loadProfile(profileData);
} catch (CMMException c) {
ProfileDataException pde = new
ProfileDataException("Invalid ICC Profile Data" + fileName);
@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable {
causing a deferred profile
to be loaded */
}
return getColorSpaceType(ID);
return getColorSpaceType(cmmProfile);
}
static int getColorSpaceType(long profileID) {
static int getColorSpaceType(Profile p) {
byte[] theHeader;
int theColorSpaceSig, theColorSpace;
theHeader = getData(profileID, icSigHead);
theHeader = getData(p, icSigHead);
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
theColorSpace = iccCStoJCS (theColorSpaceSig);
return theColorSpace;
@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable {
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
}
return getPCSType(ID);
return getPCSType(cmmProfile);
}
static int getPCSType(long profileID) {
static int getPCSType(Profile p) {
byte[] theHeader;
int thePCSSig, thePCS;
theHeader = getData(profileID, icSigHead);
theHeader = getData(p, icSigHead);
thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
thePCS = iccCStoJCS(thePCSSig);
return thePCS;
@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this profile */
profileSize = mdl.getProfileSize(ID);
profileSize = mdl.getProfileSize(cmmProfile);
profileData = new byte [profileSize];
/* get the data for the profile */
mdl.getProfileData(ID, profileData);
mdl.getProfileData(cmmProfile, profileData);
return profileData;
}
@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable {
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;
byte[] tagData;
@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* 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 */
/* get the tag's data */
mdl.getTagData(profileID, tagSignature, tagData);
mdl.getTagData(p, tagSignature, tagData);
} catch(CMMException c) {
tagData = null;
}
@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
CMSManager.getModule().setTagData(ID, tagSignature, tagData);
CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
}
/**

View File

@ -35,7 +35,7 @@
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
@ -76,8 +76,8 @@ extends ICC_Profile {
/**
* Constructs a new ICC_ProfileGray from a CMM ID.
*/
ICC_ProfileGray(long ID) {
super(ID);
ICC_ProfileGray(Profile p) {
super(p);
}
/**

View File

@ -35,7 +35,7 @@
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
@ -114,8 +114,8 @@ extends ICC_Profile {
* @param ID The CMM ID for the profile.
*
*/
ICC_ProfileRGB(long ID) {
super(ID);
ICC_ProfileRGB(Profile p) {
super(p);
}
/**

View File

@ -104,53 +104,53 @@ public class CMSManager {
cName = tcmm.getClass().getName();
}
public long loadProfile(byte[] data) {
public Profile loadProfile(byte[] data) {
System.err.print(cName + ".loadProfile");
long profileID = tcmm.loadProfile(data);
System.err.printf("(ID=%x)\n", profileID);
return profileID;
Profile p = tcmm.loadProfile(data);
System.err.printf("(ID=%s)\n", p.toString());
return p;
}
public void freeProfile(long profileID) {
System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
tcmm.freeProfile(profileID);
public void freeProfile(Profile p) {
System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
tcmm.freeProfile(p);
}
public int getProfileSize(long profileID) {
System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
int size = tcmm.getProfileSize(profileID);
public int getProfileSize(Profile p) {
System.err.print(cName + ".getProfileSize(ID=" + p + ")");
int size = tcmm.getProfileSize(p);
System.err.println("=" + size);
return size;
}
public void getProfileData(long profileID, byte[] data) {
System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
public void getProfileData(Profile p, byte[] data) {
System.err.print(cName + ".getProfileData(ID=" + p + ") ");
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)",
profileID, signatureToString(tagSignature));
int size = tcmm.getTagSize(profileID, tagSignature);
p, signatureToString(tagSignature));
int size = tcmm.getTagSize(p, tagSignature);
System.err.println("=" + size);
return size;
}
public void getTagData(long profileID, int tagSignature,
public void getTagData(Profile p, int tagSignature,
byte[] data) {
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
profileID, signatureToString(tagSignature));
p, signatureToString(tagSignature));
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) {
System.err.print(cName + ".setTagData(ID=" + profileID +
System.err.print(cName + ".setTagData(ID=" + p +
", TagSig=" + tagSignature + ")");
System.err.println(" sending " + data.length + " byte(s)");
tcmm.setTagData(profileID, tagSignature, data);
tcmm.setTagData(p, tagSignature, data);
}
/* methods for creating ColorTransforms */

View File

@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile;
public interface PCMM {
/* methods invoked from ICC_Profile */
public long loadProfile(byte[] data);
public void freeProfile(long profileID);
public int getProfileSize(long profileID);
public void getProfileData(long profileID, byte[] data);
public void getTagData(long profileID, int tagSignature, byte[] data);
public int getTagSize(long profileID, int tagSignature);
public void setTagData(long profileID, int tagSignature, byte[] data);
public Profile loadProfile(byte[] data);
public void freeProfile(Profile p);
public int getProfileSize(Profile p);
public void getProfileData(Profile p, byte[] data);
public void getTagData(Profile p, int tagSignature, byte[] data);
public int getTagSize(Profile p, int tagSignature);
public void setTagData(Profile p, int tagSignature, byte[] data);
/* methods for creating ColorTransforms */
public ColorTransform createTransform(ICC_Profile profile, int renderType,

View 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;
}
}

View File

@ -25,96 +25,139 @@
package sun.java2d.cmm.lcms;
import java.awt.color.CMMException;
import java.awt.color.ICC_Profile;
import java.util.Arrays;
import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
@Override
public long loadProfile(byte[] data) {
long id = loadProfileNative(data);
public Profile loadProfile(byte[] data) {
final Object disposerRef = new Object();
if (id != 0L) {
if (profiles == null) {
profiles = new HashMap<>();
}
profiles.put(id, new TagCache(id));
final long ptr = loadProfileNative(data, disposerRef);
if (ptr != 0L) {
return new LCMSProfile(ptr, disposerRef);
}
return id;
return null;
}
private native long loadProfileNative(byte[] data);
private native long loadProfileNative(byte[] data, Object ref);
@Override
public void freeProfile(long profileID) {
TagCache c = profiles.remove(profileID);
if (c != null) {
c.clear();
private LCMSProfile getLcmsProfile(Profile p) {
if (p instanceof LCMSProfile) {
return (LCMSProfile)p;
}
if (profiles.isEmpty()) {
profiles = null;
}
freeProfileNative(profileID);
throw new CMMException("Invalid profile: " + p);
}
private native void freeProfileNative(long profileID);
public native synchronized int getProfileSize(long profileID);
public native synchronized void getProfileData(long profileID, byte[] data);
@Override
public synchronized int getTagSize(long profileID, int tagSignature) {
TagCache cache = profiles.get(profileID);
if (cache == null) {
cache = new TagCache(profileID);
profiles.put(profileID, cache);
}
TagData t = cache.getTag(tagSignature);
return t == null ? 0 : t.getSize();
public void freeProfile(Profile p) {
// we use disposer, so this method does nothing
}
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
public synchronized void getTagData(long profileID, int tagSignature,
byte[] data)
public void getProfileData(final Profile p, 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) {
cache = new TagCache(profileID);
profiles.put(profileID, cache);
}
TagData t = cache.getTag(tagSignature);
if (t != null) {
t.copyDataTo(data);
synchronized (profile) {
TagData t = profile.getTag(tagSignature);
if (t != null) {
t.copyDataTo(data);
}
}
}
@Override
public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
TagCache cache = profiles.get(profileID);
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
final LCMSProfile profile = getLcmsProfile(p);
if (cache != null) {
cache.clear();
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);
}
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);
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,
int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked,
@ -175,59 +218,4 @@ public class LCMS implements PCMM {
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;
}

View 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;
}
}
}

View File

@ -62,7 +62,7 @@ public class LCMSTransform implements ColorTransform {
private boolean isOutIntPacked = false;
ICC_Profile[] profiles;
long [] profileIDs;
LCMSProfile[] lcmsProfiles;
int renderType;
int transformType;
@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform {
/* Actually, it is not a complete transform but just part of it */
profiles = new ICC_Profile[1];
profiles[0] = profile;
profileIDs = new long[1];
profileIDs[0] = LCMS.getProfileID(profile);
lcmsProfiles = new LCMSProfile[1];
lcmsProfiles[0] = LCMS.getProfileID(profile);
this.renderType = (renderType == ColorTransform.Any)?
ICC_Profile.icPerceptual : renderType;
this.transformType = transformType;
@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform {
size+=((LCMSTransform)transforms[i]).profiles.length;
}
profiles = new ICC_Profile[size];
profileIDs = new long[size];
lcmsProfiles = new LCMSProfile[size];
int j = 0;
for (int i=0; i < transforms.length; i++) {
LCMSTransform curTrans = (LCMSTransform)transforms[i];
System.arraycopy(curTrans.profiles, 0, profiles, j,
curTrans.profiles.length);
System.arraycopy(curTrans.profileIDs, 0, profileIDs, j,
curTrans.profileIDs.length);
System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
curTrans.lcmsProfiles.length);
j += curTrans.profiles.length;
}
renderType = ((LCMSTransform)transforms[0]).renderType;
@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform {
outFormatter = out.pixelType;
isOutIntPacked = out.isIntPacked;
ID = LCMS.createNativeTransform(profileIDs, renderType,
ID = LCMS.createTransform(lcmsProfiles, renderType,
inFormatter, isInIntPacked,
outFormatter, isOutIntPacked,
disposerReferent);

View File

@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value)
# endif
#endif
typedef union storeID_s { /* store SProfile stuff in a Java Long */
typedef struct lcmsProfile_s {
cmsHPROFILE pf;
} lcmsProfile_t, *lcmsProfile_p;
typedef union storeID_s { /* store SProfile stuff in a Java Long */
lcmsProfile_p lcmsPf;
cmsHTRANSFORM xf;
jobject jobj;
jlong j;
@ -106,7 +110,6 @@ typedef union {
jint j;
} TagSignature_t, *TagSignature_p;
static jfieldID Trans_profileIDs_fID;
static jfieldID Trans_renderType_fID;
static jfieldID Trans_ID_fID;
static jfieldID IL_isIntPacked_fID;
@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
static jfieldID IL_imageAtOnce_fID;
static jfieldID PF_ID_fID;
JavaVM *javaVM;
@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
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)
{
storeID_t sTrans;
@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
jlong* ids;
size = (*env)->GetArrayLength (env, profileIDs);
ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0);
ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
#ifdef _LITTLE_ENDIAN
/* 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(
size*2*sizeof(cmsHPROFILE));
if (iccArray == NULL) {
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
return 0L;
}
@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
cmsColorSpaceSignature cs;
sTrans.j = ids[i];
icc = sTrans.pf;
icc = sTrans.lcmsPf->pf;
iccArray[j++] = icc;
/* 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,
inFormatter, outFormatter, renderType, 0);
(*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0);
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
if (sTrans.xf == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
"sTrans.xf == NULL");
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot get color transform");
if ((*env)->ExceptionOccurred(env) == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot get color transform");
}
} else {
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
* Method: loadProfile
* Signature: ([B)J
* Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
*/
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;
jint dataSize;
storeID_t sProf;
cmsHPROFILE pf;
if (JNU_IsNull(env, data)) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
return 0L;
}
sProf.j = 0L;
dataArray = (*env)->GetByteArrayElements (env, data, 0);
dataSize = (*env)->GetArrayLength (env, data);
@ -258,22 +279,37 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
return 0L;
}
sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
pf = cmsOpenProfileFromMem((const void *)dataArray,
(cmsUInt32Number) dataSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
if (sProf.pf == NULL) {
if (pf == NULL) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
} else {
/* Sanity check: try to save the profile in order
* to force basic validation.
*/
cmsUInt32Number pfSize = 0;
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
pfSize < sizeof(cmsICCHeader))
{
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
* Method: freeProfile
* 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
* Method: getProfileSizeNative
* 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)
{
storeID_t sProf;
cmsUInt32Number pfSize = 0;
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;
} else {
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
* Method: getProfileData
* Method: getProfileDataNative
* 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)
{
storeID_t sProf;
@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
sProf.j = id;
// determine actual profile size
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) {
if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not access specified profile.");
return;
@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
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);
@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
/* Get profile header info */
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);
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;
}
status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return data;
}
if (cmsIsTag(sProf.pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0);
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found");
@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
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);
@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
storeID_t sProf;
cmsHPROFILE pfReplace = NULL;
TagSignature_t sig;
cmsBool status;
cmsBool status = FALSE;
jbyte* dataArray;
int tagSize;
@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
}
if (tagSig == SigHead) {
status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize);
} 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);
if (!status) {
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
* 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)
{
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
* unloading
*/
Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
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_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
}
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
return TRUE;
}
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
cmsTagSignature sig,
/* Returns new profile handler, if it was created successfully,
NULL otherwise.
*/
static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
const cmsTagSignature sig,
jbyte *pData, jint size)
{
cmsBool status;
cmsUInt32Number pfSize = 0;
cmsUInt8Number* pfBuffer = NULL;
const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
cmsInt32Number i;
cmsHPROFILE pfSanity = NULL;
cmsICCHeader hdr = { 0 };
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);
if (NULL == p) {
return NULL;
}
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);
// 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;
}
// now write the user supplied tag
if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
cmsCloseProfile(p);
return NULL;
}
// copy tags from the original profile
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) {
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);
if (!isTagReady) {
cmsCloseProfile(p);
return NULL;
}
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;
}

View File

@ -23,7 +23,7 @@
/**
* @test
* @bug 6476665 6523403 6733501 7042594
* @bug 6476665 6523403 6733501 7042594 7043064
* @summary Verifies reading and writing profiles and tags of the standard color
* spaces
* @run main ReadWriteProfileTest
@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable {
public void run() {
for (int i = 0; i < cspaces.length; i++) {
System.out.println("Profile: " + csNames[i]);
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData();
pf = ICC_Profile.getInstance(data);
@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable {
}
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 [] empty = new byte[tagData.length];
boolean emptyDataRejected = false;
@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable {
throw new
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);
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
{
System.err.println("Incorrect result of getData(int) with" +
" tag " +
Integer.toHexString(tagSig) +
SigToString(tagSig) +
" of " + csNames[i] + " profile");
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) {
ReadWriteProfileTest test = new ReadWriteProfileTest();
test.run();