11/*
2- * Copyright (c) 1997, 2013 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 1997, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
4040import sun .java2d .cmm .CMSManager ;
4141import sun .java2d .cmm .Profile ;
4242import sun .java2d .cmm .ProfileDataVerifier ;
43- import sun .java2d .cmm .ProfileDeferralMgr ;
4443import sun .java2d .cmm .ProfileDeferralInfo ;
45- import sun .java2d .cmm .ProfileActivator ;
4644import sun .misc .IOUtils ;
4745
4846import java .io .BufferedInputStream ;
5755import java .io .ObjectStreamException ;
5856import java .io .OutputStream ;
5957import java .io .Serializable ;
58+ import java .io .FilePermission ;
6059
6160import java .util .StringTokenizer ;
6261
@@ -97,10 +96,8 @@ public class ICC_Profile implements Serializable {
9796
9897 private static final long serialVersionUID = -3938515861990936766L ;
9998
100- private transient Profile cmmProfile ;
101-
102- private transient ProfileDeferralInfo deferralInfo ;
103- private transient ProfileActivator profileActivator ;
99+ private transient volatile Profile cmmProfile ;
100+ private transient volatile ProfileDeferralInfo deferralInfo ;
104101
105102 // Registry of singleton profile objects for specific color spaces
106103 // defined in the ColorSpace class (e.g. CS_sRGB), see
@@ -740,13 +737,7 @@ public class ICC_Profile implements Serializable {
740737 * The ID will be 0 until the profile is loaded.
741738 */
742739 ICC_Profile (ProfileDeferralInfo pdi ) {
743- this .deferralInfo = pdi ;
744- this .profileActivator = new ProfileActivator () {
745- public void activate () throws ProfileDataException {
746- activateDeferredProfile ();
747- }
748- };
749- ProfileDeferralMgr .registerDeferral (this .profileActivator );
740+ deferralInfo = pdi ;
750741 }
751742
752743
@@ -756,8 +747,6 @@ public void activate() throws ProfileDataException {
756747 protected void finalize () {
757748 if (cmmProfile != null ) {
758749 CMSManager .getModule ().freeProfile (cmmProfile );
759- } else if (profileActivator != null ) {
760- ProfileDeferralMgr .unregisterDeferral (profileActivator );
761750 }
762751 }
763752
@@ -775,10 +764,6 @@ public static ICC_Profile getInstance(byte[] data) {
775764
776765 Profile p = null ;
777766
778- if (ProfileDeferralMgr .deferring ) {
779- ProfileDeferralMgr .activateProfiles ();
780- }
781-
782767 ProfileDataVerifier .verify (data );
783768
784769 try {
@@ -842,11 +827,11 @@ public static ICC_Profile getInstance (int cspace) {
842827 * Enabling the appropriate access privileges is handled
843828 * at a lower level.
844829 */
845- ProfileDeferralInfo pInfo =
830+ ProfileDeferralInfo pdi =
846831 new ProfileDeferralInfo ("sRGB.pf" ,
847832 ColorSpace .TYPE_RGB , 3 ,
848833 CLASS_DISPLAY );
849- sRGBprofile = getDeferredInstance ( pInfo );
834+ sRGBprofile = new ICC_ProfileRGB ( pdi );
850835 }
851836 thisProfile = sRGBprofile ;
852837 }
@@ -856,11 +841,11 @@ public static ICC_Profile getInstance (int cspace) {
856841 case ColorSpace .CS_CIEXYZ :
857842 synchronized (ICC_Profile .class ) {
858843 if (XYZprofile == null ) {
859- ProfileDeferralInfo pInfo =
844+ ProfileDeferralInfo pdi =
860845 new ProfileDeferralInfo ("CIEXYZ.pf" ,
861846 ColorSpace .TYPE_XYZ , 3 ,
862- CLASS_DISPLAY );
863- XYZprofile = getDeferredInstance ( pInfo );
847+ CLASS_ABSTRACT );
848+ XYZprofile = new ICC_Profile ( pdi );
864849 }
865850 thisProfile = XYZprofile ;
866851 }
@@ -872,11 +857,11 @@ public static ICC_Profile getInstance (int cspace) {
872857 if (PYCCprofile == null ) {
873858 if (standardProfileExists ("PYCC.pf" ))
874859 {
875- ProfileDeferralInfo pInfo =
860+ ProfileDeferralInfo pdi =
876861 new ProfileDeferralInfo ("PYCC.pf" ,
877862 ColorSpace .TYPE_3CLR , 3 ,
878- CLASS_DISPLAY );
879- PYCCprofile = getDeferredInstance ( pInfo );
863+ CLASS_COLORSPACECONVERSION );
864+ PYCCprofile = new ICC_Profile ( pdi );
880865 } else {
881866 throw new IllegalArgumentException (
882867 "Can't load standard profile: PYCC.pf" );
@@ -890,11 +875,11 @@ public static ICC_Profile getInstance (int cspace) {
890875 case ColorSpace .CS_GRAY :
891876 synchronized (ICC_Profile .class ) {
892877 if (GRAYprofile == null ) {
893- ProfileDeferralInfo pInfo =
878+ ProfileDeferralInfo pdi =
894879 new ProfileDeferralInfo ("GRAY.pf" ,
895880 ColorSpace .TYPE_GRAY , 1 ,
896881 CLASS_DISPLAY );
897- GRAYprofile = getDeferredInstance ( pInfo );
882+ GRAYprofile = new ICC_ProfileGray ( pdi );
898883 }
899884 thisProfile = GRAYprofile ;
900885 }
@@ -904,11 +889,11 @@ public static ICC_Profile getInstance (int cspace) {
904889 case ColorSpace .CS_LINEAR_RGB :
905890 synchronized (ICC_Profile .class ) {
906891 if (LINEAR_RGBprofile == null ) {
907- ProfileDeferralInfo pInfo =
892+ ProfileDeferralInfo pdi =
908893 new ProfileDeferralInfo ("LINEAR_RGB.pf" ,
909894 ColorSpace .TYPE_RGB , 3 ,
910895 CLASS_DISPLAY );
911- LINEAR_RGBprofile = getDeferredInstance ( pInfo );
896+ LINEAR_RGBprofile = new ICC_ProfileRGB ( pdi );
912897 }
913898 thisProfile = LINEAR_RGBprofile ;
914899 }
@@ -1005,13 +990,7 @@ public static ICC_Profile getInstance(String fileName) throws IOException {
1005990 * contain valid ICC Profile data.
1006991 */
1007992 public static ICC_Profile getInstance (InputStream s ) throws IOException {
1008- byte profileData [];
1009-
1010- if (s instanceof ProfileDeferralInfo ) {
1011- /* hack to detect profiles whose loading can be deferred */
1012- return getDeferredInstance ((ProfileDeferralInfo ) s );
1013- }
1014-
993+ byte [] profileData ;
1015994 if ((profileData = getProfileDataFromStream (s )) == null ) {
1016995 throw new IllegalArgumentException ("Invalid ICC Profile Data" );
1017996 }
@@ -1044,73 +1023,32 @@ static byte[] getProfileDataFromStream(InputStream s) throws IOException {
10441023
10451024
10461025 /**
1047- * Constructs an ICC_Profile for which the actual loading of the
1048- * profile data from a file and the initialization of the CMM should
1049- * be deferred as long as possible.
1050- * Deferral is only used for standard profiles.
1051- * If deferring is disabled, then getStandardProfile() ensures
1052- * that all of the appropriate access privileges are granted
1053- * when loading this profile.
1054- * If deferring is enabled, then the deferred activation
1055- * code will take care of access privileges.
1056- * @see activateDeferredProfile()
1026+ * Activates the deferred standard profiles. Implementation of this method
1027+ * mimics the old behaviour when the CMMException and IOException were
1028+ * wrapped by the ProfileDataException, and the ProfileDataException itself
1029+ * was ignored during activation.
10571030 */
1058- static ICC_Profile getDeferredInstance (ProfileDeferralInfo pdi ) {
1059- if (!ProfileDeferralMgr .deferring ) {
1060- return getStandardProfile (pdi .filename );
1061- }
1062- if (pdi .colorSpaceType == ColorSpace .TYPE_RGB ) {
1063- return new ICC_ProfileRGB (pdi );
1064- } else if (pdi .colorSpaceType == ColorSpace .TYPE_GRAY ) {
1065- return new ICC_ProfileGray (pdi );
1066- } else {
1067- return new ICC_Profile (pdi );
1068- }
1069- }
1070-
1071-
1072- void activateDeferredProfile () throws ProfileDataException {
1073- byte profileData [];
1074- FileInputStream fis ;
1075- final String fileName = deferralInfo .filename ;
1076-
1077- profileActivator = null ;
1078- deferralInfo = null ;
1079- PrivilegedAction <FileInputStream > pa = new PrivilegedAction <FileInputStream >() {
1080- public FileInputStream run () {
1081- File f = getStandardProfileFile (fileName );
1082- if (f != null ) {
1083- try {
1084- return new FileInputStream (f );
1085- } catch (FileNotFoundException e ) {}
1031+ private void activate () {
1032+ if (cmmProfile == null ) {
1033+ synchronized (this ) {
1034+ if (cmmProfile != null ) {
1035+ return ;
1036+ }
1037+ InputStream is = getStandardProfileInputStream (deferralInfo .filename );
1038+ if (is == null ) {
1039+ return ;
1040+ }
1041+ try {
1042+ byte [] data = getProfileDataFromStream (is );
1043+ if (data != null ) {
1044+ cmmProfile = CMSManager .getModule ().loadProfile (data );
1045+ // from now we cannot use the deferred value, drop it
1046+ deferralInfo = null ;
1047+ }
1048+ is .close (); /* close the stream */
1049+ } catch (CMMException | IOException ignore ) {
10861050 }
1087- return null ;
10881051 }
1089- };
1090- if ((fis = AccessController .doPrivileged (pa )) == null ) {
1091- throw new ProfileDataException ("Cannot open file " + fileName );
1092- }
1093- try {
1094- profileData = getProfileDataFromStream (fis );
1095- fis .close (); /* close the file */
1096- }
1097- catch (IOException e ) {
1098- ProfileDataException pde = new
1099- ProfileDataException ("Invalid ICC Profile Data" + fileName );
1100- pde .initCause (e );
1101- throw pde ;
1102- }
1103- if (profileData == null ) {
1104- throw new ProfileDataException ("Invalid ICC Profile Data" +
1105- fileName );
1106- }
1107- try {
1108- cmmProfile = CMSManager .getModule ().loadProfile (profileData );
1109- } catch (CMMException c ) {
1110- ProfileDataException pde = new
1111- ProfileDataException ("Invalid ICC Profile Data" + fileName );
1112- pde .initCause (c );
1113- throw pde ;
11141052 }
11151053 }
11161054
@@ -1149,11 +1087,9 @@ public int getProfileClass() {
11491087 byte [] theHeader ;
11501088 int theClassSig , theClass ;
11511089
1152- if (deferralInfo != null ) {
1153- return deferralInfo .profileClass ; /* Need to have this info for
1154- ICC_ColorSpace without
1155- causing a deferred profile
1156- to be loaded */
1090+ ProfileDeferralInfo info = deferralInfo ;
1091+ if (info != null ) {
1092+ return info .profileClass ;
11571093 }
11581094
11591095 theHeader = getData (icSigHead );
@@ -1209,12 +1145,11 @@ public int getProfileClass() {
12091145 * <CODE>ColorSpace</CODE> class.
12101146 */
12111147 public int getColorSpaceType () {
1212- if (deferralInfo != null ) {
1213- return deferralInfo .colorSpaceType ; /* Need to have this info for
1214- ICC_ColorSpace without
1215- causing a deferred profile
1216- to be loaded */
1148+ ProfileDeferralInfo info = deferralInfo ;
1149+ if (info != null ) {
1150+ return info .colorSpaceType ;
12171151 }
1152+ activate ();
12181153 return getColorSpaceType (cmmProfile );
12191154 }
12201155
@@ -1241,9 +1176,7 @@ static int getColorSpaceType(Profile p) {
12411176 * <CODE>ColorSpace</CODE> class.
12421177 */
12431178 public int getPCSType () {
1244- if (ProfileDeferralMgr .deferring ) {
1245- ProfileDeferralMgr .activateProfiles ();
1246- }
1179+ activate ();
12471180 return getPCSType (cmmProfile );
12481181 }
12491182
@@ -1305,9 +1238,7 @@ public byte[] getData() {
13051238 int profileSize ;
13061239 byte [] profileData ;
13071240
1308- if (ProfileDeferralMgr .deferring ) {
1309- ProfileDeferralMgr .activateProfiles ();
1310- }
1241+ activate ();
13111242
13121243 PCMM mdl = CMSManager .getModule ();
13131244
@@ -1340,9 +1271,7 @@ public byte[] getData() {
13401271 */
13411272 public byte [] getData (int tagSignature ) {
13421273
1343- if (ProfileDeferralMgr .deferring ) {
1344- ProfileDeferralMgr .activateProfiles ();
1345- }
1274+ activate ();
13461275
13471276 return getData (cmmProfile , tagSignature );
13481277 }
@@ -1388,9 +1317,7 @@ static byte[] getData(Profile p, int tagSignature) {
13881317 */
13891318 public void setData (int tagSignature , byte [] tagData ) {
13901319
1391- if (ProfileDeferralMgr .deferring ) {
1392- ProfileDeferralMgr .activateProfiles ();
1393- }
1320+ activate ();
13941321
13951322 CMSManager .getModule ().setTagData (cmmProfile , tagSignature , tagData );
13961323 }
@@ -1448,11 +1375,9 @@ public int getNumComponents() {
14481375 byte [] theHeader ;
14491376 int theColorSpaceSig , theNumComponents ;
14501377
1451- if (deferralInfo != null ) {
1452- return deferralInfo .numComponents ; /* Need to have this info for
1453- ICC_ColorSpace without
1454- causing a deferred profile
1455- to be loaded */
1378+ ProfileDeferralInfo info = deferralInfo ;
1379+ if (info != null ) {
1380+ return info .numComponents ;
14561381 }
14571382 theHeader = getData (icSigHead );
14581383
@@ -1536,6 +1461,24 @@ public int getNumComponents() {
15361461 return theNumComponents ;
15371462 }
15381463
1464+ /**
1465+ * Returns a stream corresponding to a built-in profile
1466+ * specified by fileName.
1467+ * If there is no built-in profile with such name, then the method
1468+ * returns null.
1469+ */
1470+ private static InputStream getStandardProfileInputStream (String fileName ) {
1471+ return AccessController .doPrivileged (
1472+ new PrivilegedAction <InputStream >() {
1473+ public InputStream run () {
1474+ try {
1475+ return
1476+ new FileInputStream (getStandardProfileFile (fileName ));
1477+ } catch (IOException ex ) {return null ;}
1478+ }
1479+ });
1480+ }
1481+
15391482
15401483 /**
15411484 * Returns a float array of length 3 containing the X, Y, and Z
0 commit comments