11/*
2- * Copyright (c) 1997, 2021 , 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
@@ -751,6 +751,7 @@ private interface BuiltInProfile {
751751 */
752752 public static final int icXYZNumberX = 8 ;
753753
754+ private static final int HEADER_SIZE = 128 ;
754755
755756 /**
756757 * Constructs an {@code ICC_Profile} object with a given ID.
@@ -799,10 +800,15 @@ public static ICC_Profile getInstance(byte[] data) {
799800 ProfileDataVerifier .verify (data );
800801 Profile p ;
801802 try {
803+ byte [] theHeader = new byte [HEADER_SIZE ];
804+ System .arraycopy (data , 0 , theHeader , 0 , HEADER_SIZE );
805+ verifyHeader (theHeader );
806+
802807 p = CMSManager .getModule ().loadProfile (data );
803808 } catch (CMMException c ) {
804809 throw new IllegalArgumentException ("Invalid ICC Profile Data" );
805810 }
811+
806812 try {
807813 if (getColorSpaceType (p ) == ColorSpace .TYPE_GRAY
808814 && getData (p , icSigMediaWhitePointTag ) != null
@@ -991,6 +997,10 @@ public int getProfileClass() {
991997 return info .profileClass ;
992998 }
993999 byte [] theHeader = getData (icSigHead );
1000+ return getProfileClass (theHeader );
1001+ }
1002+
1003+ private static int getProfileClass (byte [] theHeader ) {
9941004 int theClassSig = intFromBigEndian (theHeader , icHdrDeviceClass );
9951005 return switch (theClassSig ) {
9961006 case icSigInputClass -> CLASS_INPUT ;
@@ -1032,6 +1042,11 @@ private static int getColorSpaceType(Profile p) {
10321042 return iccCStoJCS (theColorSpaceSig );
10331043 }
10341044
1045+ private static int getColorSpaceType (byte [] theHeader ) {
1046+ int theColorSpaceSig = intFromBigEndian (theHeader , icHdrColorSpace );
1047+ return iccCStoJCS (theColorSpaceSig );
1048+ }
1049+
10351050 /**
10361051 * Returns the color space type of the Profile Connection Space (PCS).
10371052 * Returns one of the color space type constants defined by the ColorSpace
@@ -1051,6 +1066,21 @@ public int getPCSType() {
10511066 return iccCStoJCS (thePCSSig );
10521067 }
10531068
1069+ private static int getPCSType (byte [] theHeader ) {
1070+ int thePCSSig = intFromBigEndian (theHeader , icHdrPcs );
1071+ int theDeviceClass = intFromBigEndian (theHeader , icHdrDeviceClass );
1072+
1073+ if (theDeviceClass == icSigLinkClass ) {
1074+ return iccCStoJCS (thePCSSig );
1075+ } else {
1076+ return switch (thePCSSig ) {
1077+ case icSigXYZData -> ColorSpace .TYPE_XYZ ;
1078+ case icSigLabData -> ColorSpace .TYPE_Lab ;
1079+ default -> throw new IllegalArgumentException ("Unexpected PCS type" );
1080+ };
1081+ }
1082+ }
1083+
10541084 /**
10551085 * Write this {@code ICC_Profile} to a file.
10561086 *
@@ -1129,9 +1159,42 @@ private static byte[] getData(Profile p, int tagSignature) {
11291159 * @see #getData
11301160 */
11311161 public void setData (int tagSignature , byte [] tagData ) {
1162+ if (tagSignature == ICC_Profile .icSigHead ) {
1163+ verifyHeader (tagData );
1164+ }
11321165 CMSManager .getModule ().setTagData (cmmProfile (), tagSignature , tagData );
11331166 }
11341167
1168+ private static void verifyHeader (byte [] data ) {
1169+ if (data == null || data .length < HEADER_SIZE ) {
1170+ throw new IllegalArgumentException ("Invalid header data" );
1171+ }
1172+ getProfileClass (data );
1173+ getColorSpaceType (data );
1174+ getPCSType (data );
1175+ checkRenderingIntent (data );
1176+ }
1177+
1178+ private static boolean checkRenderingIntent (byte [] header ) {
1179+ int index = ICC_Profile .icHdrRenderingIntent ;
1180+
1181+ /* According to ICC spec, only the least-significant 16 bits shall be
1182+ * used to encode the rendering intent. The most significant 16 bits
1183+ * shall be set to zero. Thus, we are ignoring two most significant
1184+ * bytes here. Please refer ICC Spec Document for more details.
1185+ */
1186+ int renderingIntent = ((header [index +2 ] & 0xff ) << 8 ) |
1187+ (header [index +3 ] & 0xff );
1188+
1189+ switch (renderingIntent ) {
1190+ case icPerceptual , icMediaRelativeColorimetric ,
1191+ icSaturation , icAbsoluteColorimetric -> {
1192+ return true ;
1193+ }
1194+ default -> throw new IllegalArgumentException ("Unknown Rendering Intent" );
1195+ }
1196+ }
1197+
11351198 /**
11361199 * Returns the number of color components in the "input" color space of this
11371200 * profile. For example if the color space type of this profile is
0 commit comments