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