@@ -723,6 +723,7 @@ public class ICC_Profile implements Serializable {
723723 */
724724 public static final int icXYZNumberX = 8 ; /* XYZNumber X */
725725
726+ private static final int HEADER_SIZE = 128 ;
726727
727728 /**
728729 * Constructs an ICC_Profile object with a given ID.
@@ -767,6 +768,10 @@ public static ICC_Profile getInstance(byte[] data) {
767768 ProfileDataVerifier .verify (data );
768769
769770 try {
771+ byte [] theHeader = new byte [HEADER_SIZE ];
772+ System .arraycopy (data , 0 , theHeader , 0 , HEADER_SIZE );
773+ verifyHeader (theHeader );
774+
770775 p = CMSManager .getModule ().loadProfile (data );
771776 } catch (CMMException c ) {
772777 throw new IllegalArgumentException ("Invalid ICC Profile Data" );
@@ -1084,16 +1089,18 @@ public int getMinorVersion() {
10841089 * @return One of the predefined profile class constants.
10851090 */
10861091 public int getProfileClass () {
1087- byte [] theHeader ;
1088- int theClassSig , theClass ;
10891092
10901093 ProfileDeferralInfo info = deferralInfo ;
10911094 if (info != null ) {
10921095 return info .profileClass ;
10931096 }
10941097
1095- theHeader = getData (icSigHead );
1098+ byte [] theHeader = getData (icSigHead );
1099+ return getProfileClass (theHeader );
1100+ }
10961101
1102+ private static int getProfileClass (byte [] theHeader ) {
1103+ int theClassSig , theClass ;
10971104 theClassSig = intFromBigEndian (theHeader , icHdrDeviceClass );
10981105
10991106 switch (theClassSig ) {
@@ -1163,6 +1170,11 @@ static int getColorSpaceType(Profile p) {
11631170 return theColorSpace ;
11641171 }
11651172
1173+ private static int getColorSpaceType (byte [] theHeader ) {
1174+ int theColorSpaceSig = intFromBigEndian (theHeader , icHdrColorSpace );
1175+ return iccCStoJCS (theColorSpaceSig );
1176+ }
1177+
11661178 /**
11671179 * Returns the color space type of the Profile Connection Space (PCS).
11681180 * Returns one of the color space type constants defined by the
@@ -1192,6 +1204,29 @@ static int getPCSType(Profile p) {
11921204 }
11931205
11941206
1207+ private static int getPCSType (byte [] theHeader ) {
1208+ int thePCSSig = intFromBigEndian (theHeader , icHdrPcs );
1209+ int theDeviceClass = intFromBigEndian (theHeader , icHdrDeviceClass );
1210+ int thePCSType ;
1211+
1212+ if (theDeviceClass == icSigLinkClass ) {
1213+ return iccCStoJCS (thePCSSig );
1214+ } else {
1215+ switch (thePCSSig ) {
1216+ case icSigXYZData :
1217+ thePCSType = ColorSpace .TYPE_XYZ ;
1218+ break ;
1219+ case icSigLabData :
1220+ thePCSType = ColorSpace .TYPE_Lab ;
1221+ break ;
1222+ default :
1223+ throw new IllegalArgumentException ("Unexpected PCS type" );
1224+ };
1225+ }
1226+
1227+ return thePCSType ;
1228+ }
1229+
11951230 /**
11961231 * Write this ICC_Profile to a file.
11971232 *
@@ -1316,12 +1351,49 @@ static byte[] getData(Profile p, int tagSignature) {
13161351 * @see #getData
13171352 */
13181353 public void setData (int tagSignature , byte [] tagData ) {
1354+ if (tagSignature == ICC_Profile .icSigHead ) {
1355+ verifyHeader (tagData );
1356+ }
13191357
13201358 activate ();
13211359
13221360 CMSManager .getModule ().setTagData (cmmProfile , tagSignature , tagData );
13231361 }
13241362
1363+ private static void verifyHeader (byte [] data ) {
1364+ if (data == null || data .length < HEADER_SIZE ) {
1365+ throw new IllegalArgumentException ("Invalid header data" );
1366+ }
1367+ getProfileClass (data );
1368+ getColorSpaceType (data );
1369+ getPCSType (data );
1370+ checkRenderingIntent (data );
1371+ }
1372+
1373+ private static boolean checkRenderingIntent (byte [] header ) {
1374+ int index = ICC_Profile .icHdrRenderingIntent ;
1375+
1376+ /* According to ICC spec, only the least-significant 16 bits shall be
1377+ * used to encode the rendering intent. The most significant 16 bits
1378+ * shall be set to zero. Thus, we are ignoring two most significant
1379+ * bytes here. Please refer ICC Spec Document for more details.
1380+ */
1381+ int renderingIntent = ((header [index +2 ] & 0xff ) << 8 ) |
1382+ (header [index +3 ] & 0xff );
1383+
1384+ switch (renderingIntent ) {
1385+ case icPerceptual :
1386+ case icMediaRelativeColorimetric :
1387+ case icSaturation :
1388+ case icAbsoluteColorimetric :
1389+ break ;
1390+ default :
1391+ throw new IllegalArgumentException ("Unknown Rendering Intent" );
1392+ }
1393+
1394+ return true ;
1395+ }
1396+
13251397 /**
13261398 * Sets the rendering intent of the profile.
13271399 * This is used to select the proper transform from a profile that
0 commit comments