Skip to content
Permalink
Browse files
8261282: Lazy initialization of built-in ICC_Profile/ColorSpace class…
…es is too lazy

Reviewed-by: azvegint
  • Loading branch information
mrserb committed Feb 11, 2021
1 parent f4cfd75 commit bf47a479b91607b769c57a9bd26236fc21bc5c1f
@@ -39,8 +39,6 @@
import java.io.Serializable;
import java.lang.annotation.Native;

import sun.java2d.cmm.CMSManager;

/**
* This abstract class is used to serve as a color space tag to identify the
* specific color space of a {@code Color} object or, via a {@code ColorModel}
@@ -112,12 +110,22 @@
private final int numComponents;
private transient String [] compName = null;

// Cache of singletons for the predefined color spaces.
private static ColorSpace sRGBspace;
private static ColorSpace XYZspace;
private static ColorSpace PYCCspace;
private static ColorSpace GRAYspace;
private static ColorSpace LINEAR_RGBspace;
/**
* The lazy cache of singletons for the predefined built-in color spaces.
*/
private interface BuiltInSpace {

ColorSpace SRGB = new ICC_ColorSpace(ICC_Profile.getInstance(CS_sRGB));

ColorSpace LRGB =
new ICC_ColorSpace(ICC_Profile.getInstance(CS_LINEAR_RGB));

ColorSpace XYZ = new ICC_ColorSpace(ICC_Profile.getInstance(CS_CIEXYZ));

ColorSpace PYCC = new ICC_ColorSpace(ICC_Profile.getInstance(CS_PYCC));

ColorSpace GRAY = new ICC_ColorSpace(ICC_Profile.getInstance(CS_GRAY));
}

/**
* Any of the family of XYZ color spaces.
@@ -289,88 +297,24 @@ protected ColorSpace(int type, int numComponents) {
* Returns a {@code ColorSpace} representing one of the specific predefined
* color spaces.
*
* @param colorspace a specific color space identified by one of the
* predefined class constants (e.g. {@code CS_sRGB},
* {@code CS_LINEAR_RGB}, {@code CS_CIEXYZ}, {@code CS_GRAY}, or
* {@code CS_PYCC})
* @param cspace a specific color space identified by one of the predefined
* class constants (e.g. {@code CS_sRGB}, {@code CS_LINEAR_RGB},
* {@code CS_CIEXYZ}, {@code CS_GRAY}, or {@code CS_PYCC})
* @return the requested {@code ColorSpace} object
*/
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public static ColorSpace getInstance (int colorspace)
{
ColorSpace theColorSpace;

switch (colorspace) {
case CS_sRGB:
synchronized(ColorSpace.class) {
if (sRGBspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
sRGBspace = new ICC_ColorSpace (theProfile);
}

theColorSpace = sRGBspace;
public static ColorSpace getInstance(int cspace) {
return switch (cspace) {
case CS_sRGB -> BuiltInSpace.SRGB;
case CS_LINEAR_RGB -> BuiltInSpace.LRGB;
case CS_CIEXYZ -> BuiltInSpace.XYZ;
case CS_PYCC -> BuiltInSpace.PYCC;
case CS_GRAY -> BuiltInSpace.GRAY;
default -> {
throw new IllegalArgumentException("Unknown color space");
}
break;

case CS_CIEXYZ:
synchronized(ColorSpace.class) {
if (XYZspace == null) {
ICC_Profile theProfile =
ICC_Profile.getInstance (CS_CIEXYZ);
XYZspace = new ICC_ColorSpace (theProfile);
}

theColorSpace = XYZspace;
}
break;

case CS_PYCC:
synchronized(ColorSpace.class) {
if (PYCCspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
PYCCspace = new ICC_ColorSpace (theProfile);
}

theColorSpace = PYCCspace;
}
break;


case CS_GRAY:
synchronized(ColorSpace.class) {
if (GRAYspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
GRAYspace = new ICC_ColorSpace (theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.GRAYspace = GRAYspace;
}

theColorSpace = GRAYspace;
}
break;


case CS_LINEAR_RGB:
synchronized(ColorSpace.class) {
if (LINEAR_RGBspace == null) {
ICC_Profile theProfile =
ICC_Profile.getInstance(CS_LINEAR_RGB);
LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
}

theColorSpace = LINEAR_RGBspace;
}
break;


default:
throw new IllegalArgumentException ("Unknown color space");
}

return theColorSpace;
};
}

/**
@@ -380,8 +324,7 @@ public static ColorSpace getInstance (int colorspace)
* {@code false} if it is not
*/
public boolean isCS_sRGB () {
/* REMIND - make sure we know sRGBspace exists already */
return (this == sRGBspace);
return this == BuiltInSpace.SRGB;
}

/**
@@ -94,14 +94,31 @@
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
// getInstance(int cspace) factory method.
private static ICC_Profile sRGBprofile;
private static ICC_Profile XYZprofile;
private static ICC_Profile PYCCprofile;
private static ICC_Profile GRAYprofile;
private static ICC_Profile LINEAR_RGBprofile;
/**
* The lazy registry of singleton profile objects for specific built-in
* color spaces defined in the ColorSpace class (e.g. CS_sRGB),
* see getInstance(int cspace) factory method.
*/
private interface BuiltInProfile {
/*
* Deferral is only used for standard profiles. Enabling the appropriate
* access privileges is handled at a lower level.
*/
ICC_Profile SRGB = new ICC_ProfileRGB(new ProfileDeferralInfo(
"sRGB.pf", ColorSpace.TYPE_RGB, 3, CLASS_DISPLAY));

ICC_Profile LRGB = new ICC_ProfileRGB(new ProfileDeferralInfo(
"LINEAR_RGB.pf", ColorSpace.TYPE_RGB, 3, CLASS_DISPLAY));

ICC_Profile XYZ = new ICC_Profile(new ProfileDeferralInfo(
"CIEXYZ.pf", ColorSpace.TYPE_XYZ, 3, CLASS_ABSTRACT));

ICC_Profile PYCC = new ICC_Profile(new ProfileDeferralInfo(
"PYCC.pf", ColorSpace.TYPE_3CLR, 3, CLASS_COLORSPACECONVERSION));

ICC_Profile GRAY = new ICC_ProfileGray(new ProfileDeferralInfo(
"GRAY.pf", ColorSpace.TYPE_GRAY, 1, CLASS_DISPLAY));
}

/**
* Profile class is input.
@@ -818,89 +835,17 @@ else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
* @throws IllegalArgumentException If {@code cspace} is not one of the
* predefined color space types
*/
public static ICC_Profile getInstance (int cspace) {
ICC_Profile thisProfile = null;
switch (cspace) {
case ColorSpace.CS_sRGB:
synchronized(ICC_Profile.class) {
if (sRGBprofile == null) {
/*
* Deferral is only used for standard profiles.
* Enabling the appropriate access privileges is handled
* at a lower level.
*/
ProfileDeferralInfo pdi =
new ProfileDeferralInfo("sRGB.pf",
ColorSpace.TYPE_RGB, 3,
CLASS_DISPLAY);
sRGBprofile = new ICC_ProfileRGB(pdi);
}
thisProfile = sRGBprofile;
}

break;

case ColorSpace.CS_CIEXYZ:
synchronized(ICC_Profile.class) {
if (XYZprofile == null) {
ProfileDeferralInfo pdi =
new ProfileDeferralInfo("CIEXYZ.pf",
ColorSpace.TYPE_XYZ, 3,
CLASS_ABSTRACT);
XYZprofile = new ICC_Profile(pdi);
}
thisProfile = XYZprofile;
}

break;

case ColorSpace.CS_PYCC:
synchronized(ICC_Profile.class) {
if (PYCCprofile == null) {
ProfileDeferralInfo pdi =
new ProfileDeferralInfo("PYCC.pf",
ColorSpace.TYPE_3CLR, 3,
CLASS_COLORSPACECONVERSION);
PYCCprofile = new ICC_Profile(pdi);
}
thisProfile = PYCCprofile;
}

break;

case ColorSpace.CS_GRAY:
synchronized(ICC_Profile.class) {
if (GRAYprofile == null) {
ProfileDeferralInfo pdi =
new ProfileDeferralInfo("GRAY.pf",
ColorSpace.TYPE_GRAY, 1,
CLASS_DISPLAY);
GRAYprofile = new ICC_ProfileGray(pdi);
}
thisProfile = GRAYprofile;
}

break;

case ColorSpace.CS_LINEAR_RGB:
synchronized(ICC_Profile.class) {
if (LINEAR_RGBprofile == null) {
ProfileDeferralInfo pdi =
new ProfileDeferralInfo("LINEAR_RGB.pf",
ColorSpace.TYPE_RGB, 3,
CLASS_DISPLAY);
LINEAR_RGBprofile = new ICC_ProfileRGB(pdi);
}
thisProfile = LINEAR_RGBprofile;
public static ICC_Profile getInstance(int cspace) {
return switch (cspace) {
case ColorSpace.CS_sRGB -> BuiltInProfile.SRGB;
case ColorSpace.CS_LINEAR_RGB -> BuiltInProfile.LRGB;
case ColorSpace.CS_CIEXYZ -> BuiltInProfile.XYZ;
case ColorSpace.CS_PYCC -> BuiltInProfile.PYCC;
case ColorSpace.CS_GRAY -> BuiltInProfile.GRAY;
default -> {
throw new IllegalArgumentException("Unknown color space");
}

break;

default:
throw new IllegalArgumentException("Unknown color space");
}

return thisProfile;
};
}

/**
@@ -1803,15 +1748,15 @@ private void writeObject(ObjectOutputStream s)
s.defaultWriteObject();

String csName = null;
if (this == sRGBprofile) {
if (this == BuiltInProfile.SRGB) {
csName = "CS_sRGB";
} else if (this == XYZprofile) {
} else if (this == BuiltInProfile.XYZ) {
csName = "CS_CIEXYZ";
} else if (this == PYCCprofile) {
} else if (this == BuiltInProfile.PYCC) {
csName = "CS_PYCC";
} else if (this == GRAYprofile) {
} else if (this == BuiltInProfile.GRAY) {
csName = "CS_GRAY";
} else if (this == LINEAR_RGBprofile) {
} else if (this == BuiltInProfile.LRGB) {
csName = "CS_LINEAR_RGB";
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@@ -1705,15 +1705,11 @@ static int getDefaultTransferType(int pixel_bits) {
static Map<ICC_ColorSpace, short[]> lg16Toog16Map = null; // 16-bit linear to 16-bit "other" gray

static boolean isLinearRGBspace(ColorSpace cs) {
// Note: CMM.LINEAR_RGBspace will be null if the linear
// RGB space has not been created yet.
return (cs == CMSManager.LINEAR_RGBspace);
return cs == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
}

static boolean isLinearGRAYspace(ColorSpace cs) {
// Note: CMM.GRAYspace will be null if the linear
// gray space has not been created yet.
return (cs == CMSManager.GRAYspace);
return cs == ColorSpace.getInstance(ColorSpace.CS_GRAY);
}

static byte[] getLinearRGB8TosRGB8LUT() {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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
@@ -26,20 +26,12 @@
package sun.java2d.cmm;

import java.awt.color.CMMException;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.security.AccessController;

import sun.security.action.GetPropertyAction;

public class CMSManager {
public static ColorSpace GRAYspace; // These two fields allow access
public static ColorSpace LINEAR_RGBspace; // to java.awt.color.ColorSpace
// private fields from other
// packages. The fields are set
// by java.awt.color.ColorSpace
// and read by
// java.awt.image.ColorModel.
public final class CMSManager {

private static PCMM cmmImpl = null;

Loading

0 comments on commit bf47a47

Please sign in to comment.