6986863: ProfileDeferralMgr throwing ConcurrentModificationException
Reviewed-by: kizune
This commit is contained in:
parent
ea2c4474be
commit
64a150c518
src/java.desktop/share
classes
java/awt
sun/java2d/cmm
native/liblcms
test/jdk/java/awt/color
@ -55,10 +55,8 @@ import java.util.StringTokenizer;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
import sun.java2d.cmm.Profile;
|
||||
import sun.java2d.cmm.ProfileActivator;
|
||||
import sun.java2d.cmm.ProfileDataVerifier;
|
||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||
import sun.java2d.cmm.ProfileDeferralMgr;
|
||||
|
||||
/**
|
||||
* A representation of color profile data for device independent and device
|
||||
@ -93,10 +91,8 @@ public class ICC_Profile implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -3938515861990936766L;
|
||||
|
||||
private transient Profile cmmProfile;
|
||||
|
||||
private transient ProfileDeferralInfo deferralInfo;
|
||||
private transient ProfileActivator profileActivator;
|
||||
private transient volatile Profile cmmProfile;
|
||||
private transient volatile ProfileDeferralInfo deferralInfo;
|
||||
|
||||
// Registry of singleton profile objects for specific color spaces
|
||||
// defined in the ColorSpace class (e.g. CS_sRGB), see
|
||||
@ -731,7 +727,7 @@ public class ICC_Profile implements Serializable {
|
||||
* Constructs an {@code ICC_Profile} object with a given ID.
|
||||
*/
|
||||
ICC_Profile(Profile p) {
|
||||
this.cmmProfile = p;
|
||||
cmmProfile = p;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -739,13 +735,7 @@ public class ICC_Profile implements Serializable {
|
||||
* The ID will be 0 until the profile is loaded.
|
||||
*/
|
||||
ICC_Profile(ProfileDeferralInfo pdi) {
|
||||
this.deferralInfo = pdi;
|
||||
this.profileActivator = new ProfileActivator() {
|
||||
public void activate() throws ProfileDataException {
|
||||
activateDeferredProfile();
|
||||
}
|
||||
};
|
||||
ProfileDeferralMgr.registerDeferral(this.profileActivator);
|
||||
deferralInfo = pdi;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -780,10 +770,6 @@ public class ICC_Profile implements Serializable {
|
||||
|
||||
Profile p = null;
|
||||
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
|
||||
ProfileDataVerifier.verify(data);
|
||||
|
||||
try {
|
||||
@ -842,11 +828,11 @@ public class ICC_Profile implements Serializable {
|
||||
* Enabling the appropriate access privileges is handled
|
||||
* at a lower level.
|
||||
*/
|
||||
ProfileDeferralInfo pInfo =
|
||||
ProfileDeferralInfo pdi =
|
||||
new ProfileDeferralInfo("sRGB.pf",
|
||||
ColorSpace.TYPE_RGB, 3,
|
||||
CLASS_DISPLAY);
|
||||
sRGBprofile = getDeferredInstance(pInfo);
|
||||
sRGBprofile = new ICC_ProfileRGB(pdi);
|
||||
}
|
||||
thisProfile = sRGBprofile;
|
||||
}
|
||||
@ -856,11 +842,11 @@ public class ICC_Profile implements Serializable {
|
||||
case ColorSpace.CS_CIEXYZ:
|
||||
synchronized(ICC_Profile.class) {
|
||||
if (XYZprofile == null) {
|
||||
ProfileDeferralInfo pInfo =
|
||||
ProfileDeferralInfo pdi =
|
||||
new ProfileDeferralInfo("CIEXYZ.pf",
|
||||
ColorSpace.TYPE_XYZ, 3,
|
||||
CLASS_ABSTRACT);
|
||||
XYZprofile = getDeferredInstance(pInfo);
|
||||
XYZprofile = new ICC_Profile(pdi);
|
||||
}
|
||||
thisProfile = XYZprofile;
|
||||
}
|
||||
@ -870,11 +856,11 @@ public class ICC_Profile implements Serializable {
|
||||
case ColorSpace.CS_PYCC:
|
||||
synchronized(ICC_Profile.class) {
|
||||
if (PYCCprofile == null) {
|
||||
ProfileDeferralInfo pInfo =
|
||||
ProfileDeferralInfo pdi =
|
||||
new ProfileDeferralInfo("PYCC.pf",
|
||||
ColorSpace.TYPE_3CLR, 3,
|
||||
CLASS_COLORSPACECONVERSION);
|
||||
PYCCprofile = getDeferredInstance(pInfo);
|
||||
PYCCprofile = new ICC_Profile(pdi);
|
||||
}
|
||||
thisProfile = PYCCprofile;
|
||||
}
|
||||
@ -884,11 +870,11 @@ public class ICC_Profile implements Serializable {
|
||||
case ColorSpace.CS_GRAY:
|
||||
synchronized(ICC_Profile.class) {
|
||||
if (GRAYprofile == null) {
|
||||
ProfileDeferralInfo pInfo =
|
||||
ProfileDeferralInfo pdi =
|
||||
new ProfileDeferralInfo("GRAY.pf",
|
||||
ColorSpace.TYPE_GRAY, 1,
|
||||
CLASS_DISPLAY);
|
||||
GRAYprofile = getDeferredInstance(pInfo);
|
||||
GRAYprofile = new ICC_ProfileGray(pdi);
|
||||
}
|
||||
thisProfile = GRAYprofile;
|
||||
}
|
||||
@ -898,11 +884,11 @@ public class ICC_Profile implements Serializable {
|
||||
case ColorSpace.CS_LINEAR_RGB:
|
||||
synchronized(ICC_Profile.class) {
|
||||
if (LINEAR_RGBprofile == null) {
|
||||
ProfileDeferralInfo pInfo =
|
||||
ProfileDeferralInfo pdi =
|
||||
new ProfileDeferralInfo("LINEAR_RGB.pf",
|
||||
ColorSpace.TYPE_RGB, 3,
|
||||
CLASS_DISPLAY);
|
||||
LINEAR_RGBprofile = getDeferredInstance(pInfo);
|
||||
LINEAR_RGBprofile = new ICC_ProfileRGB(pdi);
|
||||
}
|
||||
thisProfile = LINEAR_RGBprofile;
|
||||
}
|
||||
@ -916,26 +902,6 @@ public class ICC_Profile implements Serializable {
|
||||
return thisProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method asserts system privileges, so is used only for the standard
|
||||
* profiles.
|
||||
*/
|
||||
private static ICC_Profile getStandardProfile(final String name) {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<ICC_Profile>() {
|
||||
public ICC_Profile run() {
|
||||
ICC_Profile p = null;
|
||||
try {
|
||||
p = getInstance(name);
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't load standard profile: " + name);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code ICC_Profile} corresponding to the data in a file.
|
||||
* {@code fileName} may be an absolute or a relative file specification.
|
||||
@ -997,13 +963,7 @@ public class ICC_Profile implements Serializable {
|
||||
* Profile data
|
||||
*/
|
||||
public static ICC_Profile getInstance(InputStream s) throws IOException {
|
||||
byte[] profileData;
|
||||
|
||||
if (s instanceof ProfileDeferralInfo) {
|
||||
/* hack to detect profiles whose loading can be deferred */
|
||||
return getDeferredInstance((ProfileDeferralInfo) s);
|
||||
}
|
||||
|
||||
byte[] profileData;
|
||||
if ((profileData = getProfileDataFromStream(s)) == null) {
|
||||
throw new IllegalArgumentException("Invalid ICC Profile Data");
|
||||
}
|
||||
@ -1035,61 +995,32 @@ public class ICC_Profile implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code ICC_Profile} for which the actual loading of the
|
||||
* profile data from a file and the initialization of the CMM should be
|
||||
* deferred as long as possible. Deferral is only used for standard
|
||||
* profiles. If deferring is disabled, then getStandardProfile() ensures
|
||||
* that all of the appropriate access privileges are granted when loading
|
||||
* this profile. If deferring is enabled, then the deferred activation code
|
||||
* will take care of access privileges.
|
||||
*
|
||||
* @see #activateDeferredProfile()
|
||||
* Activates the deferred standard profiles. Implementation of this method
|
||||
* mimics the old behaviour when the CMMException and IOException were
|
||||
* wrapped by the ProfileDataException, and the ProfileDataException itself
|
||||
* was ignored during activation.
|
||||
*/
|
||||
static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi) {
|
||||
if (!ProfileDeferralMgr.deferring) {
|
||||
return getStandardProfile(pdi.filename);
|
||||
}
|
||||
if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) {
|
||||
return new ICC_ProfileRGB(pdi);
|
||||
} else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) {
|
||||
return new ICC_ProfileGray(pdi);
|
||||
} else {
|
||||
return new ICC_Profile(pdi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void activateDeferredProfile() throws ProfileDataException {
|
||||
byte[] profileData;
|
||||
final String fileName = deferralInfo.filename;
|
||||
|
||||
profileActivator = null;
|
||||
deferralInfo = null;
|
||||
InputStream is = getStandardProfileInputStream(fileName);
|
||||
if (is == null) {
|
||||
throw new ProfileDataException("Cannot open file " + fileName);
|
||||
}
|
||||
try {
|
||||
profileData = getProfileDataFromStream(is);
|
||||
is.close(); /* close the file */
|
||||
}
|
||||
catch (IOException e) {
|
||||
ProfileDataException pde = new
|
||||
ProfileDataException("Invalid ICC Profile Data" + fileName);
|
||||
pde.initCause(e);
|
||||
throw pde;
|
||||
}
|
||||
if (profileData == null) {
|
||||
throw new ProfileDataException("Invalid ICC Profile Data" +
|
||||
fileName);
|
||||
}
|
||||
try {
|
||||
cmmProfile = CMSManager.getModule().loadProfile(profileData);
|
||||
} catch (CMMException c) {
|
||||
ProfileDataException pde = new
|
||||
ProfileDataException("Invalid ICC Profile Data" + fileName);
|
||||
pde.initCause(c);
|
||||
throw pde;
|
||||
private void activate() {
|
||||
if (cmmProfile == null) {
|
||||
synchronized (this) {
|
||||
if (cmmProfile != null) {
|
||||
return;
|
||||
}
|
||||
var is = getStandardProfileInputStream(deferralInfo.filename);
|
||||
if (is == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
byte[] data = getProfileDataFromStream(is);
|
||||
if (data != null) {
|
||||
cmmProfile = CMSManager.getModule().loadProfile(data);
|
||||
// from now we cannot use the deferred value, drop it
|
||||
deferralInfo = null;
|
||||
}
|
||||
is.close(); /* close the stream */
|
||||
} catch (CMMException | IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1130,11 +1061,9 @@ public class ICC_Profile implements Serializable {
|
||||
byte[] theHeader;
|
||||
int theClassSig, theClass;
|
||||
|
||||
if (deferralInfo != null) {
|
||||
return deferralInfo.profileClass; /* Need to have this info for
|
||||
ICC_ColorSpace without
|
||||
causing a deferred profile
|
||||
to be loaded */
|
||||
ProfileDeferralInfo info = deferralInfo;
|
||||
if (info != null) {
|
||||
return info.profileClass;
|
||||
}
|
||||
|
||||
theHeader = getData(icSigHead);
|
||||
@ -1190,12 +1119,11 @@ public class ICC_Profile implements Serializable {
|
||||
* {@code ColorSpace} class
|
||||
*/
|
||||
public int getColorSpaceType() {
|
||||
if (deferralInfo != null) {
|
||||
return deferralInfo.colorSpaceType; /* Need to have this info for
|
||||
ICC_ColorSpace without
|
||||
causing a deferred profile
|
||||
to be loaded */
|
||||
ProfileDeferralInfo info = deferralInfo;
|
||||
if (info != null) {
|
||||
return info.colorSpaceType;
|
||||
}
|
||||
activate();
|
||||
return getColorSpaceType(cmmProfile);
|
||||
}
|
||||
|
||||
@ -1223,9 +1151,7 @@ public class ICC_Profile implements Serializable {
|
||||
* {@code ColorSpace} class
|
||||
*/
|
||||
public int getPCSType() {
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
activate();
|
||||
return getPCSType(cmmProfile);
|
||||
}
|
||||
|
||||
@ -1283,9 +1209,7 @@ public class ICC_Profile implements Serializable {
|
||||
int profileSize;
|
||||
byte[] profileData;
|
||||
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
activate();
|
||||
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
|
||||
@ -1315,9 +1239,7 @@ public class ICC_Profile implements Serializable {
|
||||
*/
|
||||
public byte[] getData(int tagSignature) {
|
||||
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
activate();
|
||||
|
||||
return getData(cmmProfile, tagSignature);
|
||||
}
|
||||
@ -1363,9 +1285,7 @@ public class ICC_Profile implements Serializable {
|
||||
*/
|
||||
public void setData(int tagSignature, byte[] tagData) {
|
||||
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
activate();
|
||||
|
||||
CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
|
||||
}
|
||||
@ -1417,11 +1337,9 @@ public class ICC_Profile implements Serializable {
|
||||
byte[] theHeader;
|
||||
int theColorSpaceSig, theNumComponents;
|
||||
|
||||
if (deferralInfo != null) {
|
||||
return deferralInfo.numComponents; /* Need to have this info for
|
||||
ICC_ColorSpace without
|
||||
causing a deferred profile
|
||||
to be loaded */
|
||||
ProfileDeferralInfo info = deferralInfo;
|
||||
if (info != null) {
|
||||
return info.numComponents;
|
||||
}
|
||||
theHeader = getData(icSigHead);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
@ -36,16 +36,18 @@
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.color.*;
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
import sun.java2d.cmm.ProfileDeferralMgr;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
|
||||
/**
|
||||
* This class performs a pixel-by-pixel color conversion of the data in
|
||||
@ -77,13 +79,6 @@ public class ColorConvertOp implements BufferedImageOp, RasterOp {
|
||||
boolean gotProfiles;
|
||||
float[] srcMinVals, srcMaxVals, dstMinVals, dstMaxVals;
|
||||
|
||||
/* the class initializer */
|
||||
static {
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ColorConvertOp which will convert
|
||||
* from a source color space to a destination color space.
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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.ProfileDataException;
|
||||
|
||||
/**
|
||||
* An interface to allow the ProfileDeferralMgr to activate a
|
||||
* deferred profile.
|
||||
*/
|
||||
public interface ProfileActivator {
|
||||
|
||||
/**
|
||||
* Activate a previously deferred ICC_Profile object.
|
||||
*/
|
||||
public void activate() throws ProfileDataException;
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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
|
||||
@ -25,37 +25,28 @@
|
||||
|
||||
package sun.java2d.cmm;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* A class to pass information about a profile to be loaded from
|
||||
* a file to the static getInstance(InputStream) method of
|
||||
* ICC_Profile. Loading of the profile data and initialization
|
||||
* of the CMM is to be deferred as long as possible.
|
||||
* A class to pass information about a profile to be loaded from a file to the
|
||||
* static getInstance(int cspace) method of ICC_Profile. Loading of the profile
|
||||
* data and initialization of the CMM is to be deferred as long as possible.
|
||||
*/
|
||||
public class ProfileDeferralInfo extends InputStream {
|
||||
public final class ProfileDeferralInfo {
|
||||
|
||||
public int colorSpaceType, numComponents, profileClass;
|
||||
public String filename;
|
||||
/**
|
||||
* Need to have this info for ICC_ColorSpace without causing a deferred
|
||||
* profile to be loaded.
|
||||
*/
|
||||
public final int colorSpaceType, numComponents, profileClass;
|
||||
|
||||
/**
|
||||
* The profile file name, such as "CIEXYZ.pf", "sRGB.pf", etc.
|
||||
*/
|
||||
public final String filename;
|
||||
|
||||
public ProfileDeferralInfo(String fn, int type, int ncomp, int pclass) {
|
||||
|
||||
super();
|
||||
filename = fn;
|
||||
colorSpaceType = type;
|
||||
numComponents = ncomp;
|
||||
profileClass = pclass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements the abstract read() method of InputStream.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2020, 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.ProfileDataException;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* A class to manage the deferral of CMM initialization of profile
|
||||
* data for internal ICC_Profile objects - i.e. when we "trust" that
|
||||
* the profile data is valid and we think it may not be needed. An
|
||||
* example is the sRGB profile which gets loaded by any program doing
|
||||
* graphics, but which may not be needed if the program does not need
|
||||
* high quality color conversion.
|
||||
*/
|
||||
public class ProfileDeferralMgr {
|
||||
|
||||
public static boolean deferring = true;
|
||||
private static Vector<ProfileActivator> aVector;
|
||||
|
||||
/**
|
||||
* Records a ProfileActivator object whose activate method will
|
||||
* be called if the CMM needs to be activated.
|
||||
*/
|
||||
public static void registerDeferral(ProfileActivator pa) {
|
||||
|
||||
if (!deferring) {
|
||||
return;
|
||||
}
|
||||
if (aVector == null) {
|
||||
aVector = new Vector<ProfileActivator>(3, 3);
|
||||
}
|
||||
aVector.addElement(pa);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a ProfileActivator object from the vector of ProfileActivator
|
||||
* objects whose activate method will be called if the CMM needs to be
|
||||
* activated.
|
||||
*/
|
||||
public static void activateProfiles() {
|
||||
|
||||
int i, n;
|
||||
|
||||
deferring = false;
|
||||
if (aVector == null) {
|
||||
return;
|
||||
}
|
||||
n = aVector.size();
|
||||
for (ProfileActivator pa : aVector) {
|
||||
try {
|
||||
pa.activate();
|
||||
} catch (ProfileDataException e) {
|
||||
/*
|
||||
* Ignore profile activation error for now:
|
||||
* such exception is pssible due to absence
|
||||
* or corruption of standard color profile.
|
||||
* As for now we expect all profiles should
|
||||
* be shiped with jre and presence of this
|
||||
* exception is indication of some configuration
|
||||
* problem in jre installation.
|
||||
*
|
||||
* NB: we still are greedy loading deferred profiles
|
||||
* and load them all if any of them is needed.
|
||||
* Therefore broken profile (if any) might be never used.
|
||||
* If there will be attempt to use broken profile then
|
||||
* it will result in CMMException.
|
||||
*/
|
||||
}
|
||||
}
|
||||
aVector.removeAllElements();
|
||||
aVector = null;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2021, 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
|
||||
@ -35,19 +35,19 @@
|
||||
|
||||
package sun.java2d.cmm.lcms;
|
||||
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.color.CMMException;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import sun.java2d.cmm.*;
|
||||
import sun.java2d.cmm.lcms.*;
|
||||
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
|
||||
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
|
||||
|
||||
public class LCMSTransform implements ColorTransform {
|
||||
long ID;
|
||||
@ -66,13 +66,6 @@ public class LCMSTransform implements ColorTransform {
|
||||
|
||||
private Object disposerReferent = new Object();
|
||||
|
||||
/* the class initializer */
|
||||
static {
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
public LCMSTransform(ICC_Profile profile, int renderType,
|
||||
int transformType)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2021, 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
|
||||
@ -649,9 +649,22 @@ JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
|
||||
if (pf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
fid = (*env)->GetFieldID (env,
|
||||
(*env)->GetObjectClass(env, pf),
|
||||
"cmmProfile", "Lsun/java2d/cmm/Profile;");
|
||||
|
||||
jclass pcls = (*env)->GetObjectClass(env, pf);
|
||||
if (pcls == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
jmethodID mid = (*env)->GetMethodID(env, pcls, "activate", "()V");
|
||||
if (mid == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(*env)->CallVoidMethod(env, pf, mid);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fid = (*env)->GetFieldID(env, pcls, "cmmProfile",
|
||||
"Lsun/java2d/cmm/Profile;");
|
||||
if (fid == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
72
test/jdk/java/awt/color/ICC_ProfileRGB/MTMatrixAccess.java
Normal file
72
test/jdk/java/awt/color/ICC_ProfileRGB/MTMatrixAccess.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.color.ICC_ProfileRGB;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6986863
|
||||
* @summary Verifies MT safety of ICC_ProfileRGB#getMatrix method
|
||||
*/
|
||||
public final class MTMatrixAccess {
|
||||
|
||||
private static volatile boolean failed;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test((ICC_ProfileRGB) ICC_Profile.getInstance(ColorSpace.CS_sRGB));
|
||||
test((ICC_ProfileRGB) ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB));
|
||||
}
|
||||
|
||||
private static void test(ICC_ProfileRGB rgb) throws InterruptedException {
|
||||
Thread[] threads = new Thread[100];
|
||||
CountDownLatch go = new CountDownLatch(1);
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i] = new Thread(() -> {
|
||||
try {
|
||||
go.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
rgb.getMatrix();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
failed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
go.countDown();
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
if (failed) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6986863
|
||||
* @summary Verifies MT safety of profile activation while a profile is accessed
|
||||
*/
|
||||
public final class ProfileActivationDuringPropertyAccess {
|
||||
|
||||
private static volatile boolean failed;
|
||||
private static volatile boolean end;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test(ICC_Profile.getInstance(ColorSpace.CS_sRGB));
|
||||
test(ICC_Profile.getInstance(ColorSpace.CS_GRAY));
|
||||
test(ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ));
|
||||
test(ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB));
|
||||
test(ICC_Profile.getInstance(ColorSpace.CS_PYCC));
|
||||
}
|
||||
|
||||
private static void test(ICC_Profile profile) throws Exception {
|
||||
Thread[] ts = new Thread[100];
|
||||
CountDownLatch latch = new CountDownLatch(ts.length);
|
||||
for (int i = 0; i < ts.length; i++) {
|
||||
ts[i] = new Thread(() -> {
|
||||
latch.countDown();
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
try {
|
||||
while (!end) {
|
||||
profile.getColorSpaceType(); // try use deferred info
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
failed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (Thread t : ts) {
|
||||
t.start();
|
||||
}
|
||||
Thread.sleep(1500);
|
||||
profile.getPCSType(); // activate profile
|
||||
end = true;
|
||||
for (Thread t : ts) {
|
||||
t.join();
|
||||
}
|
||||
if (failed) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user