mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 10:23:28 +00:00
8358623: Avoid unnecessary data copying in ICC_Profile
Reviewed-by: honkar, prr
This commit is contained in:
parent
39c9de2ace
commit
ec3bb93d79
@ -799,31 +799,19 @@ public sealed class ICC_Profile implements Serializable
|
||||
*/
|
||||
public static ICC_Profile getInstance(byte[] data) {
|
||||
ProfileDataVerifier.verify(data);
|
||||
verifyHeader(data);
|
||||
Profile p;
|
||||
try {
|
||||
byte[] theHeader = new byte[HEADER_SIZE];
|
||||
System.arraycopy(data, 0, theHeader, 0, HEADER_SIZE);
|
||||
verifyHeader(theHeader);
|
||||
|
||||
p = CMSManager.getModule().loadProfile(data);
|
||||
} catch (CMMException c) {
|
||||
throw new IllegalArgumentException("Invalid ICC Profile Data");
|
||||
}
|
||||
|
||||
try {
|
||||
if (getColorSpaceType(data) == ColorSpace.TYPE_GRAY
|
||||
&& getData(p, icSigMediaWhitePointTag) != null
|
||||
&& getData(p, icSigGrayTRCTag) != null) {
|
||||
int type = getColorSpaceType(data);
|
||||
if (type == ColorSpace.TYPE_GRAY) {
|
||||
return new ICC_ProfileGray(p);
|
||||
}
|
||||
if (getColorSpaceType(data) == ColorSpace.TYPE_RGB
|
||||
&& getData(p, icSigMediaWhitePointTag) != null
|
||||
&& getData(p, icSigRedColorantTag) != null
|
||||
&& getData(p, icSigGreenColorantTag) != null
|
||||
&& getData(p, icSigBlueColorantTag) != null
|
||||
&& getData(p, icSigRedTRCTag) != null
|
||||
&& getData(p, icSigGreenTRCTag) != null
|
||||
&& getData(p, icSigBlueTRCTag) != null) {
|
||||
} else if (type == ColorSpace.TYPE_RGB) {
|
||||
return new ICC_ProfileRGB(p);
|
||||
}
|
||||
} catch (CMMException c) {
|
||||
@ -969,7 +957,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* @return the major version of the profile
|
||||
*/
|
||||
public int getMajorVersion() {
|
||||
return getData(icSigHead)[8];
|
||||
return getData(cmmProfile(), icSigHead)[8];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -978,7 +966,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* @return the minor version of the profile
|
||||
*/
|
||||
public int getMinorVersion() {
|
||||
return getData(icSigHead)[9];
|
||||
return getData(cmmProfile(), icSigHead)[9];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -991,12 +979,12 @@ public sealed class ICC_Profile implements Serializable
|
||||
if (info != null) {
|
||||
return info.profileClass;
|
||||
}
|
||||
byte[] theHeader = getData(icSigHead);
|
||||
byte[] theHeader = getData(cmmProfile(), icSigHead);
|
||||
return getProfileClass(theHeader);
|
||||
}
|
||||
|
||||
private static int getProfileClass(byte[] theHeader) {
|
||||
int theClassSig = intFromBigEndian(theHeader, icHdrDeviceClass);
|
||||
private static int getProfileClass(byte[] data) {
|
||||
int theClassSig = intFromBigEndian(data, icHdrDeviceClass);
|
||||
return switch (theClassSig) {
|
||||
case icSigInputClass -> CLASS_INPUT;
|
||||
case icSigDisplayClass -> CLASS_DISPLAY;
|
||||
@ -1032,8 +1020,8 @@ public sealed class ICC_Profile implements Serializable
|
||||
return getColorSpaceType(theHeader);
|
||||
}
|
||||
|
||||
private static int getColorSpaceType(byte[] theHeader) {
|
||||
int theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
|
||||
private static int getColorSpaceType(byte[] data) {
|
||||
int theColorSpaceSig = intFromBigEndian(data, icHdrColorSpace);
|
||||
return iccCStoJCS(theColorSpaceSig);
|
||||
}
|
||||
|
||||
@ -1051,13 +1039,13 @@ public sealed class ICC_Profile implements Serializable
|
||||
* {@code ColorSpace} class
|
||||
*/
|
||||
public int getPCSType() {
|
||||
byte[] theHeader = getData(icSigHead);
|
||||
byte[] theHeader = getData(cmmProfile(), icSigHead);
|
||||
return getPCSType(theHeader);
|
||||
}
|
||||
|
||||
private static int getPCSType(byte[] theHeader) {
|
||||
int thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
|
||||
int theDeviceClass = intFromBigEndian(theHeader, icHdrDeviceClass);
|
||||
private static int getPCSType(byte[] data) {
|
||||
int thePCSSig = intFromBigEndian(data, icHdrPcs);
|
||||
int theDeviceClass = intFromBigEndian(data, icHdrDeviceClass);
|
||||
|
||||
if (theDeviceClass == icSigLinkClass) {
|
||||
return iccCStoJCS(thePCSSig);
|
||||
@ -1120,18 +1108,27 @@ public sealed class ICC_Profile implements Serializable
|
||||
* @see #setData(int, byte[])
|
||||
*/
|
||||
public byte[] getData(int tagSignature) {
|
||||
byte[] t = getData(cmmProfile(), tagSignature);
|
||||
return t != null ? t.clone() : null;
|
||||
}
|
||||
|
||||
private static byte[] getData(Profile p, int tagSignature) {
|
||||
try {
|
||||
return CMSManager.getModule().getTagData(p, tagSignature);
|
||||
return getData(cmmProfile(), tagSignature).clone();
|
||||
} catch (CMMException c) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a particular tagged data element from the profile as a non-null
|
||||
* byte array. The returned byte array is not cloned. It must not be exposed
|
||||
* to or used by public APIs. It is intended strictly for internal use only.
|
||||
*
|
||||
* @param p the CMM profile from which to retrieve the tag data
|
||||
* @param tagSignature the ICC tag signature for the data to retrieve
|
||||
* @return a non-null byte array containing the tag data
|
||||
* @throws CMMException if the specified tag doesn't exist
|
||||
*/
|
||||
static byte[] getData(Profile p, int tagSignature) {
|
||||
return CMSManager.getModule().getTagData(p, tagSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a particular tagged data element in the profile from a byte array.
|
||||
* The array should contain data in a format, corresponded to the
|
||||
@ -1183,7 +1180,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
checkRenderingIntent(data);
|
||||
}
|
||||
|
||||
private static void checkRenderingIntent(byte[] header) {
|
||||
private static void checkRenderingIntent(byte[] data) {
|
||||
int index = ICC_Profile.icHdrRenderingIntent;
|
||||
/*
|
||||
* ICC spec: only the least-significant 16 bits encode the rendering
|
||||
@ -1191,7 +1188,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* https://www.color.org/specification/ICC.1-2022-05.pdf, section 7.2.15
|
||||
*/
|
||||
// Extract 16-bit unsigned rendering intent (0–65535)
|
||||
int intent = (header[index + 2] & 0xff) << 8 | header[index + 3] & 0xff;
|
||||
int intent = (data[index + 2] & 0xff) << 8 | data[index + 3] & 0xff;
|
||||
// Only check upper bound since intent can't be negative
|
||||
if (intent > icICCAbsoluteColorimetric) {
|
||||
throw new IllegalArgumentException(
|
||||
@ -1212,7 +1209,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
if (info != null) {
|
||||
return info.numComponents;
|
||||
}
|
||||
byte[] theHeader = getData(icSigHead);
|
||||
byte[] theHeader = getData(cmmProfile(), icSigHead);
|
||||
int theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
|
||||
return switch (theColorSpaceSig) {
|
||||
case icSigGrayData -> 1;
|
||||
@ -1251,7 +1248,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* encoded in an XYZType tag.
|
||||
*/
|
||||
final float[] getXYZTag(int tagSignature) {
|
||||
byte[] theData = getData(tagSignature);
|
||||
byte[] theData = getData(cmmProfile(), tagSignature);
|
||||
float[] theXYZNumber = new float[3]; /* array to return */
|
||||
|
||||
/* convert s15Fixed16Number to float */
|
||||
@ -1275,7 +1272,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* single gamma value
|
||||
*/
|
||||
float getGamma(int tagSignature) {
|
||||
byte[] theTRCData = getData(tagSignature);
|
||||
byte[] theTRCData = getData(cmmProfile(), tagSignature);
|
||||
if (intFromBigEndian(theTRCData, icCurveCount) != 1) {
|
||||
throw new ProfileDataException("TRC is not a gamma");
|
||||
}
|
||||
@ -1306,7 +1303,7 @@ public sealed class ICC_Profile implements Serializable
|
||||
* table
|
||||
*/
|
||||
short[] getTRC(int tagSignature) {
|
||||
byte[] theTRCData = getData(tagSignature);
|
||||
byte[] theTRCData = getData(cmmProfile(), tagSignature);
|
||||
int nElements = intFromBigEndian(theTRCData, icCurveCount);
|
||||
if (nElements == 1) {
|
||||
throw new ProfileDataException("TRC is not a table");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,10 +74,15 @@ public final class ICC_ProfileGray extends ICC_Profile {
|
||||
private static final long serialVersionUID = -1124721290732002649L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ICC_ProfileGray} from a CMM ID.
|
||||
* Constructs a new {@code ICC_ProfileGray} from the specified CMM profile.
|
||||
*
|
||||
* @param p the CMM profile used to create this ICC profile
|
||||
* @throws CMMException if the required tags are missing
|
||||
*/
|
||||
ICC_ProfileGray(Profile p) {
|
||||
super(p);
|
||||
getData(p, icSigMediaWhitePointTag);
|
||||
getData(p, icSigGrayTRCTag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -104,12 +104,20 @@ public final class ICC_ProfileRGB extends ICC_Profile {
|
||||
public static final int BLUECOMPONENT = 2;
|
||||
|
||||
/**
|
||||
* Constructs an new {@code ICC_ProfileRGB} from a CMM ID.
|
||||
* Constructs a new {@code ICC_ProfileRGB} from the specified CMM profile.
|
||||
*
|
||||
* @param p the CMM ID for the profile.
|
||||
* @param p the CMM profile used to create this ICC profile
|
||||
* @throws CMMException if the required tags are missing
|
||||
*/
|
||||
ICC_ProfileRGB(Profile p) {
|
||||
super(p);
|
||||
getData(p, icSigMediaWhitePointTag);
|
||||
getData(p, icSigRedColorantTag);
|
||||
getData(p, icSigGreenColorantTag);
|
||||
getData(p, icSigBlueColorantTag);
|
||||
getData(p, icSigRedTRCTag);
|
||||
getData(p, icSigGreenTRCTag);
|
||||
getData(p, icSigBlueTRCTag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
61
test/jdk/java/awt/color/ICC_Profile/CheckVersions.java
Normal file
61
test/jdk/java/awt/color/ICC_Profile/CheckVersions.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8358623
|
||||
* @summary Verifies ICC profile version of built-in color spaces
|
||||
*/
|
||||
public final class CheckVersions {
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(ColorSpace.CS_CIEXYZ, 2, 3, 0);
|
||||
test(ColorSpace.CS_GRAY, 2, 3, 0);
|
||||
test(ColorSpace.CS_LINEAR_RGB, 2, 3, 0);
|
||||
test(ColorSpace.CS_PYCC, 4, 0, 0);
|
||||
test(ColorSpace.CS_sRGB, 2, 3, 0);
|
||||
}
|
||||
|
||||
private static void test(int cs, int expMajor, int expMinor, int expPatch) {
|
||||
ICC_Profile profile = ICC_Profile.getInstance(cs);
|
||||
|
||||
int major = profile.getMajorVersion();
|
||||
int minorRaw = profile.getMinorVersion();
|
||||
int minor = (minorRaw >> 4) & 0x0F;
|
||||
int patch = minorRaw & 0x0F;
|
||||
|
||||
if (major != expMajor || minor != expMinor || patch != expPatch) {
|
||||
System.err.println("Expected major: " + expMajor);
|
||||
System.err.println("Expected minor: " + expMinor);
|
||||
System.err.println("Expected patch: " + expPatch);
|
||||
|
||||
System.err.println("Actual major: " + major);
|
||||
System.err.println("Actual minor: " + minor);
|
||||
System.err.println("Actual patch: " + patch);
|
||||
throw new RuntimeException("Test failed for ColorSpace: " + cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user