@@ -799,31 +799,19 @@ private interface BuiltInProfile {
799
799
*/
800
800
public static ICC_Profile getInstance (byte [] data ) {
801
801
ProfileDataVerifier .verify (data );
802
+ verifyHeader (data );
802
803
Profile p ;
803
804
try {
804
- byte [] theHeader = new byte [HEADER_SIZE ];
805
- System .arraycopy (data , 0 , theHeader , 0 , HEADER_SIZE );
806
- verifyHeader (theHeader );
807
-
808
805
p = CMSManager .getModule ().loadProfile (data );
809
806
} catch (CMMException c ) {
810
807
throw new IllegalArgumentException ("Invalid ICC Profile Data" );
811
808
}
812
809
813
810
try {
814
- if (getColorSpaceType (data ) == ColorSpace .TYPE_GRAY
815
- && getData (p , icSigMediaWhitePointTag ) != null
816
- && getData (p , icSigGrayTRCTag ) != null ) {
811
+ int type = getColorSpaceType (data );
812
+ if (type == ColorSpace .TYPE_GRAY ) {
817
813
return new ICC_ProfileGray (p );
818
- }
819
- if (getColorSpaceType (data ) == ColorSpace .TYPE_RGB
820
- && getData (p , icSigMediaWhitePointTag ) != null
821
- && getData (p , icSigRedColorantTag ) != null
822
- && getData (p , icSigGreenColorantTag ) != null
823
- && getData (p , icSigBlueColorantTag ) != null
824
- && getData (p , icSigRedTRCTag ) != null
825
- && getData (p , icSigGreenTRCTag ) != null
826
- && getData (p , icSigBlueTRCTag ) != null ) {
814
+ } else if (type == ColorSpace .TYPE_RGB ) {
827
815
return new ICC_ProfileRGB (p );
828
816
}
829
817
} catch (CMMException c ) {
@@ -969,7 +957,7 @@ private Profile cmmProfile() {
969
957
* @return the major version of the profile
970
958
*/
971
959
public int getMajorVersion () {
972
- return getData (icSigHead )[8 ];
960
+ return getData (cmmProfile (), icSigHead )[8 ];
973
961
}
974
962
975
963
/**
@@ -978,7 +966,7 @@ public int getMajorVersion() {
978
966
* @return the minor version of the profile
979
967
*/
980
968
public int getMinorVersion () {
981
- return getData (icSigHead )[9 ];
969
+ return getData (cmmProfile (), icSigHead )[9 ];
982
970
}
983
971
984
972
/**
@@ -991,12 +979,12 @@ public int getProfileClass() {
991
979
if (info != null ) {
992
980
return info .profileClass ;
993
981
}
994
- byte [] theHeader = getData (icSigHead );
982
+ byte [] theHeader = getData (cmmProfile (), icSigHead );
995
983
return getProfileClass (theHeader );
996
984
}
997
985
998
- private static int getProfileClass (byte [] theHeader ) {
999
- int theClassSig = intFromBigEndian (theHeader , icHdrDeviceClass );
986
+ private static int getProfileClass (byte [] data ) {
987
+ int theClassSig = intFromBigEndian (data , icHdrDeviceClass );
1000
988
return switch (theClassSig ) {
1001
989
case icSigInputClass -> CLASS_INPUT ;
1002
990
case icSigDisplayClass -> CLASS_DISPLAY ;
@@ -1032,8 +1020,8 @@ public int getColorSpaceType() {
1032
1020
return getColorSpaceType (theHeader );
1033
1021
}
1034
1022
1035
- private static int getColorSpaceType (byte [] theHeader ) {
1036
- int theColorSpaceSig = intFromBigEndian (theHeader , icHdrColorSpace );
1023
+ private static int getColorSpaceType (byte [] data ) {
1024
+ int theColorSpaceSig = intFromBigEndian (data , icHdrColorSpace );
1037
1025
return iccCStoJCS (theColorSpaceSig );
1038
1026
}
1039
1027
@@ -1051,13 +1039,13 @@ private static int getColorSpaceType(byte[] theHeader) {
1051
1039
* {@code ColorSpace} class
1052
1040
*/
1053
1041
public int getPCSType () {
1054
- byte [] theHeader = getData (icSigHead );
1042
+ byte [] theHeader = getData (cmmProfile (), icSigHead );
1055
1043
return getPCSType (theHeader );
1056
1044
}
1057
1045
1058
- private static int getPCSType (byte [] theHeader ) {
1059
- int thePCSSig = intFromBigEndian (theHeader , icHdrPcs );
1060
- int theDeviceClass = intFromBigEndian (theHeader , icHdrDeviceClass );
1046
+ private static int getPCSType (byte [] data ) {
1047
+ int thePCSSig = intFromBigEndian (data , icHdrPcs );
1048
+ int theDeviceClass = intFromBigEndian (data , icHdrDeviceClass );
1061
1049
1062
1050
if (theDeviceClass == icSigLinkClass ) {
1063
1051
return iccCStoJCS (thePCSSig );
@@ -1120,18 +1108,27 @@ public byte[] getData() {
1120
1108
* @see #setData(int, byte[])
1121
1109
*/
1122
1110
public byte [] getData (int tagSignature ) {
1123
- byte [] t = getData (cmmProfile (), tagSignature );
1124
- return t != null ? t .clone () : null ;
1125
- }
1126
-
1127
- private static byte [] getData (Profile p , int tagSignature ) {
1128
1111
try {
1129
- return CMSManager . getModule (). getTagData ( p , tagSignature );
1112
+ return getData ( cmmProfile () , tagSignature ). clone ( );
1130
1113
} catch (CMMException c ) {
1131
1114
return null ;
1132
1115
}
1133
1116
}
1134
1117
1118
+ /**
1119
+ * Returns a particular tagged data element from the profile as a non-null
1120
+ * byte array. The returned byte array is not cloned. It must not be exposed
1121
+ * to or used by public APIs. It is intended strictly for internal use only.
1122
+ *
1123
+ * @param p the CMM profile from which to retrieve the tag data
1124
+ * @param tagSignature the ICC tag signature for the data to retrieve
1125
+ * @return a non-null byte array containing the tag data
1126
+ * @throws CMMException if the specified tag doesn't exist
1127
+ */
1128
+ static byte [] getData (Profile p , int tagSignature ) {
1129
+ return CMSManager .getModule ().getTagData (p , tagSignature );
1130
+ }
1131
+
1135
1132
/**
1136
1133
* Sets a particular tagged data element in the profile from a byte array.
1137
1134
* The array should contain data in a format, corresponded to the
@@ -1183,15 +1180,15 @@ private static void verifyHeader(byte[] data) {
1183
1180
checkRenderingIntent (data );
1184
1181
}
1185
1182
1186
- private static void checkRenderingIntent (byte [] header ) {
1183
+ private static void checkRenderingIntent (byte [] data ) {
1187
1184
int index = ICC_Profile .icHdrRenderingIntent ;
1188
1185
/*
1189
1186
* ICC spec: only the least-significant 16 bits encode the rendering
1190
1187
* intent. The most significant 16 bits must be zero and can be ignored.
1191
1188
* https://www.color.org/specification/ICC.1-2022-05.pdf, section 7.2.15
1192
1189
*/
1193
1190
// Extract 16-bit unsigned rendering intent (0–65535)
1194
- int intent = (header [index + 2 ] & 0xff ) << 8 | header [index + 3 ] & 0xff ;
1191
+ int intent = (data [index + 2 ] & 0xff ) << 8 | data [index + 3 ] & 0xff ;
1195
1192
// Only check upper bound since intent can't be negative
1196
1193
if (intent > icICCAbsoluteColorimetric ) {
1197
1194
throw new IllegalArgumentException (
@@ -1212,7 +1209,7 @@ public int getNumComponents() {
1212
1209
if (info != null ) {
1213
1210
return info .numComponents ;
1214
1211
}
1215
- byte [] theHeader = getData (icSigHead );
1212
+ byte [] theHeader = getData (cmmProfile (), icSigHead );
1216
1213
int theColorSpaceSig = intFromBigEndian (theHeader , icHdrColorSpace );
1217
1214
return switch (theColorSpaceSig ) {
1218
1215
case icSigGrayData -> 1 ;
@@ -1251,7 +1248,7 @@ float[] getMediaWhitePoint() {
1251
1248
* encoded in an XYZType tag.
1252
1249
*/
1253
1250
final float [] getXYZTag (int tagSignature ) {
1254
- byte [] theData = getData (tagSignature );
1251
+ byte [] theData = getData (cmmProfile (), tagSignature );
1255
1252
float [] theXYZNumber = new float [3 ]; /* array to return */
1256
1253
1257
1254
/* convert s15Fixed16Number to float */
@@ -1275,7 +1272,7 @@ final float[] getXYZTag(int tagSignature) {
1275
1272
* single gamma value
1276
1273
*/
1277
1274
float getGamma (int tagSignature ) {
1278
- byte [] theTRCData = getData (tagSignature );
1275
+ byte [] theTRCData = getData (cmmProfile (), tagSignature );
1279
1276
if (intFromBigEndian (theTRCData , icCurveCount ) != 1 ) {
1280
1277
throw new ProfileDataException ("TRC is not a gamma" );
1281
1278
}
@@ -1306,7 +1303,7 @@ float getGamma(int tagSignature) {
1306
1303
* table
1307
1304
*/
1308
1305
short [] getTRC (int tagSignature ) {
1309
- byte [] theTRCData = getData (tagSignature );
1306
+ byte [] theTRCData = getData (cmmProfile (), tagSignature );
1310
1307
int nElements = intFromBigEndian (theTRCData , icCurveCount );
1311
1308
if (nElements == 1 ) {
1312
1309
throw new ProfileDataException ("TRC is not a table" );
0 commit comments