/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Oleg V. Khaschansky
* @version $Revision$
*/
package java.awt.color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.StringTokenizer;
import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
import org.apache.harmony.awt.gl.color.NativeCMM;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The ICC_Profile class represents a color profile data for color spaces based
* on the International Color Consortium Specification ICC.1:2001-12, File
* Format for Color Profiles.
*
* @since Android 1.0
*/
public class ICC_Profile implements Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -3938515861990936766L;
// NOTE: Constant field values are noted in 1.5 specification.
/**
* The Constant CLASS_INPUT indicates that profile class is input.
*/
public static final int CLASS_INPUT = 0;
/**
* The Constant CLASS_DISPLAY indicates that profile class is display.
*/
public static final int CLASS_DISPLAY = 1;
/**
* The Constant CLASS_OUTPUT indicates that profile class is output.
*/
public static final int CLASS_OUTPUT = 2;
/**
* The Constant CLASS_DEVICELINK indicates that profile class is device
* link.
*/
public static final int CLASS_DEVICELINK = 3;
/**
* The Constant CLASS_COLORSPACECONVERSION indicates that profile class is
* color space conversion.
*/
public static final int CLASS_COLORSPACECONVERSION = 4;
/**
* The Constant CLASS_ABSTRACT indicates that profile class is abstract.
*/
public static final int CLASS_ABSTRACT = 5;
/**
* The Constant CLASS_NAMEDCOLOR indicates that profile class is named
* color.
*/
public static final int CLASS_NAMEDCOLOR = 6;
/**
* The Constant icSigXYZData - ICC Profile Color Space Type Signature.
*/
public static final int icSigXYZData = 1482250784;
/**
* The Constant icSigLabData - ICC Profile Color Space Type Signature.
*/
public static final int icSigLabData = 1281450528;
/**
* The Constant icSigLuvData - ICC Profile Color Space Type Signature.
*/
public static final int icSigLuvData = 1282766368;
/**
* The Constant icSigYCbCrData - ICC Profile Color Space Type Signature.
*/
public static final int icSigYCbCrData = 1497588338;
/**
* The Constant icSigYxyData - ICC Profile Color Space Type Signature.
*/
public static final int icSigYxyData = 1501067552;
/**
* The Constant icSigRgbData - ICC Profile Color Space Type Signature.
*/
public static final int icSigRgbData = 1380401696;
/**
* The Constant icSigGrayData - ICC Profile Color Space Type Signature.
*/
public static final int icSigGrayData = 1196573017;
/**
* The Constant icSigHsvData - ICC Profile Color Space Type Signature.
*/
public static final int icSigHsvData = 1213421088;
/**
* The Constant icSigHlsData - ICC Profile Color Space Type Signature.
*/
public static final int icSigHlsData = 1212961568;
/**
* The Constant icSigCmykData - ICC Profile Color Space Type Signature.
*/
public static final int icSigCmykData = 1129142603;
/**
* The Constant icSigCmyData - ICC Profile Color Space Type Signature.
*/
public static final int icSigCmyData = 1129142560;
/**
* The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace2CLR = 843271250;
/**
* The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace3CLR = 860048466;
/**
* The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace4CLR = 876825682;
/**
* The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace5CLR = 893602898;
/**
* The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace6CLR = 910380114;
/**
* The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace7CLR = 927157330;
/**
* The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace8CLR = 943934546;
/**
* The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpace9CLR = 960711762;
/**
* The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceACLR = 1094929490;
/**
* The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceBCLR = 1111706706;
/**
* The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceCCLR = 1128483922;
/**
* The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceDCLR = 1145261138;
/**
* The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceECLR = 1162038354;
/**
* The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature.
*/
public static final int icSigSpaceFCLR = 1178815570;
/**
* The Constant icSigInputClass - ICC Profile Class Signature.
*/
public static final int icSigInputClass = 1935896178;
/**
* The Constant icSigDisplayClass - ICC Profile Class Signature.
*/
public static final int icSigDisplayClass = 1835955314;
/**
* The Constant icSigOutputClass - ICC Profile Class Signature.
*/
public static final int icSigOutputClass = 1886549106;
/**
* The Constant icSigLinkClass - ICC Profile Class Signature.
*/
public static final int icSigLinkClass = 1818848875;
/**
* The Constant icSigAbstractClass - ICC Profile Class Signature.
*/
public static final int icSigAbstractClass = 1633842036;
/**
* The Constant icSigColorantOrderTag - ICC Profile Tag Signature.
*/
public static final int icSigColorantOrderTag = 1668051567;
/**
* The Constant icSigColorantTableTag - ICC Profile Tag Signature.
*/
public static final int icSigColorantTableTag = 1668051572;
/**
* The Constant icSigColorSpaceClass - ICC Profile Tag Signature.
*/
public static final int icSigColorSpaceClass = 1936744803;
/**
* The Constant icSigNamedColorClass - ICC Profile Tag Signature.
*/
public static final int icSigNamedColorClass = 1852662636;
/**
* The Constant icPerceptual - ICC Profile Rendering Intent.
*/
public static final int icPerceptual = 0;
/**
* The Constant icRelativeColorimetric - ICC Profile Rendering Intent.
*/
public static final int icRelativeColorimetric = 1;
/**
* The Constant icSaturation - ICC Profile Rendering Intent.
*/
public static final int icSaturation = 2;
/**
* The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent.
*/
public static final int icAbsoluteColorimetric = 3;
/**
* The Constant icSigHead - ICC Profile Tag Signature.
*/
public static final int icSigHead = 1751474532;
/**
* The Constant icSigAToB0Tag - ICC Profile Tag Signature.
*/
public static final int icSigAToB0Tag = 1093812784;
/**
* The Constant icSigAToB1Tag - ICC Profile Tag Signature.
*/
public static final int icSigAToB1Tag = 1093812785;
/**
* The Constant icSigAToB2Tag - ICC Profile Tag Signature.
*/
public static final int icSigAToB2Tag = 1093812786;
/**
* The Constant icSigBlueColorantTag - ICC Profile Tag Signature.
*/
public static final int icSigBlueColorantTag = 1649957210;
/**
* The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature.
*/
public static final int icSigBlueMatrixColumnTag = 1649957210;
/**
* The Constant icSigBlueTRCTag - ICC Profile Tag Signature.
*/
public static final int icSigBlueTRCTag = 1649693251;
/**
* The Constant icSigBToA0Tag - ICC Profile Tag Signature.
*/
public static final int icSigBToA0Tag = 1110589744;
/**
* The Constant icSigBToA1Tag - ICC Profile Tag Signature.
*/
public static final int icSigBToA1Tag = 1110589745;
/**
* The Constant icSigBToA2Tag - ICC Profile Tag Signature.
*/
public static final int icSigBToA2Tag = 1110589746;
/**
* The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature.
*/
public static final int icSigCalibrationDateTimeTag = 1667329140;
/**
* The Constant icSigCharTargetTag - ICC Profile Tag Signature.
*/
public static final int icSigCharTargetTag = 1952543335;
/**
* The Constant icSigCopyrightTag - ICC Profile Tag Signature.
*/
public static final int icSigCopyrightTag = 1668313716;
/**
* The Constant icSigCrdInfoTag - ICC Profile Tag Signature.
*/
public static final int icSigCrdInfoTag = 1668441193;
/**
* The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature.
*/
public static final int icSigDeviceMfgDescTag = 1684893284;
/**
* The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature.
*/
public static final int icSigDeviceModelDescTag = 1684890724;
/**
* The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature.
*/
public static final int icSigDeviceSettingsTag = 1684371059;
/**
* The Constant icSigGamutTag - ICC Profile Tag Signature.
*/
public static final int icSigGamutTag = 1734438260;
/**
* The Constant icSigGrayTRCTag - ICC Profile Tag Signature.
*/
public static final int icSigGrayTRCTag = 1800688195;
/**
* The Constant icSigGreenColorantTag - ICC Profile Tag Signature.
*/
public static final int icSigGreenColorantTag = 1733843290;
/**
* The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature.
*/
public static final int icSigGreenMatrixColumnTag = 1733843290;
/**
* The Constant icSigGreenTRCTag - ICC Profile Tag Signature.
*/
public static final int icSigGreenTRCTag = 1733579331;
/**
* The Constant icSigLuminanceTag - ICC Profile Tag Signature.
*/
public static final int icSigLuminanceTag = 1819635049;
/**
* The Constant icSigMeasurementTag - ICC Profile Tag Signature.
*/
public static final int icSigMeasurementTag = 1835360627;
/**
* The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature.
*/
public static final int icSigMediaBlackPointTag = 1651208308;
/**
* The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature.
*/
public static final int icSigMediaWhitePointTag = 2004119668;
/**
* The Constant icSigNamedColor2Tag - ICC Profile Tag Signature.
*/
public static final int icSigNamedColor2Tag = 1852009522;
/**
* The Constant icSigOutputResponseTag - ICC Profile Tag Signature.
*/
public static final int icSigOutputResponseTag = 1919251312;
/**
* The Constant icSigPreview0Tag - ICC Profile Tag Signature.
*/
public static final int icSigPreview0Tag = 1886545200;
/**
* The Constant icSigPreview1Tag - ICC Profile Tag Signature.
*/
public static final int icSigPreview1Tag = 1886545201;
/**
* The Constant icSigPreview2Tag - ICC Profile Tag Signature.
*/
public static final int icSigPreview2Tag = 1886545202;
/**
* The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature.
*/
public static final int icSigProfileDescriptionTag = 1684370275;
/**
* The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature.
*/
public static final int icSigProfileSequenceDescTag = 1886610801;
/**
* The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature.
*/
public static final int icSigPs2CRD0Tag = 1886610480;
/**
* The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature.
*/
public static final int icSigPs2CRD1Tag = 1886610481;
/**
* The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature.
*/
public static final int icSigPs2CRD2Tag = 1886610482;
/**
* The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature.
*/
public static final int icSigPs2CRD3Tag = 1886610483;
/**
* The Constant icSigPs2CSATag - ICC Profile Tag Signature.
*/
public static final int icSigPs2CSATag = 1886597747;
/**
* The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature.
*/
public static final int icSigPs2RenderingIntentTag = 1886597737;
/**
* The Constant icSigRedColorantTag - ICC Profile Tag Signature.
*/
public static final int icSigRedColorantTag = 1918392666;
/**
* The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature.
*/
public static final int icSigRedMatrixColumnTag = 1918392666;
/**
* The Constant icSigRedTRCTag - ICC Profile Tag Signature.
*/
public static final int icSigRedTRCTag = 1918128707;
/**
* The Constant icSigScreeningDescTag - ICC Profile Tag Signature.
*/
public static final int icSigScreeningDescTag = 1935897188;
/**
* The Constant icSigScreeningTag - ICC Profile Tag Signature.
*/
public static final int icSigScreeningTag = 1935897198;
/**
* The Constant icSigTechnologyTag - ICC Profile Tag Signature.
*/
public static final int icSigTechnologyTag = 1952801640;
/**
* The Constant icSigUcrBgTag - ICC Profile Tag Signature.
*/
public static final int icSigUcrBgTag = 1650877472;
/**
* The Constant icSigViewingCondDescTag - ICC Profile Tag Signature.
*/
public static final int icSigViewingCondDescTag = 1987405156;
/**
* The Constant icSigViewingConditionsTag - ICC Profile Tag Signature.
*/
public static final int icSigViewingConditionsTag = 1986618743;
/**
* The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature.
*/
public static final int icSigChromaticAdaptationTag = 1667785060;
/**
* The Constant icSigChromaticityTag - ICC Profile Tag Signature.
*/
public static final int icSigChromaticityTag = 1667789421;
/**
* The Constant icHdrSize - ICC Profile Header Location.
*/
public static final int icHdrSize = 0;
/**
* The Constant icHdrCmmId - ICC Profile Header Location.
*/
public static final int icHdrCmmId = 4;
/**
* The Constant icHdrVersion - ICC Profile Header Location.
*/
public static final int icHdrVersion = 8;
/**
* The Constant icHdrDeviceClass - ICC Profile Header Location.
*/
public static final int icHdrDeviceClass = 12;
/**
* The Constant icHdrColorSpace - ICC Profile Header Location.
*/
public static final int icHdrColorSpace = 16;
/**
* The Constant icHdrPcs - ICC Profile Header Location.
*/
public static final int icHdrPcs = 20;
/**
* The Constant icHdrDate - ICC Profile Header Location.
*/
public static final int icHdrDate = 24;
/**
* The Constant icHdrMagic - ICC Profile Header Location.
*/
public static final int icHdrMagic = 36;
/**
* The Constant icHdrPlatform - ICC Profile Header Location.
*/
public static final int icHdrPlatform = 40;
/**
* The Constant icHdrProfileID - ICC Profile Header Location.
*/
public static final int icHdrProfileID = 84;
/**
* The Constant icHdrFlags - ICC Profile Header Location.
*/
public static final int icHdrFlags = 44;
/**
* The Constant icHdrManufacturer - ICC Profile Header Location.
*/
public static final int icHdrManufacturer = 48;
/**
* The Constant icHdrModel - ICC Profile Header Location.
*/
public static final int icHdrModel = 52;
/**
* The Constant icHdrAttributes - ICC Profile Header Location.
*/
public static final int icHdrAttributes = 56;
/**
* The Constant icHdrRenderingIntent - ICC Profile Header Location.
*/
public static final int icHdrRenderingIntent = 64;
/**
* The Constant icHdrIlluminant - ICC Profile Header Location.
*/
public static final int icHdrIlluminant = 68;
/**
* The Constant icHdrCreator - ICC Profile Header Location.
*/
public static final int icHdrCreator = 80;
/**
* The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent.
*/
public static final int icICCAbsoluteColorimetric = 3;
/**
* The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent.
*/
public static final int icMediaRelativeColorimetric = 1;
/**
* The Constant icTagType - ICC Profile Constant.
*/
public static final int icTagType = 0;
/**
* The Constant icTagReserved - ICC Profile Constant.
*/
public static final int icTagReserved = 4;
/**
* The Constant icCurveCount - ICC Profile Constant.
*/
public static final int icCurveCount = 8;
/**
* The Constant icCurveData - ICC Profile Constant.
*/
public static final int icCurveData = 12;
/**
* The Constant icXYZNumberX - ICC Profile Constant.
*/
public static final int icXYZNumberX = 8;
/**
* Size of a profile header.
*/
private static final int headerSize = 128;
/**
* header magic number.
*/
private static final int headerMagicNumber = 0x61637370;
// Cache of predefined profiles
/**
* The s rgb profile.
*/
private static ICC_Profile sRGBProfile;
/**
* The xyz profile.
*/
private static ICC_Profile xyzProfile;
/**
* The gray profile.
*/
private static ICC_Profile grayProfile;
/**
* The pycc profile.
*/
private static ICC_Profile pyccProfile;
/**
* The linear rgb profile.
*/
private static ICC_Profile linearRGBProfile;
/**
* Handle to the current profile.
*/
private transient long profileHandle = 0;
/**
* If handle is used by another class this object is not responsible for
* closing profile.
*/
private transient boolean handleStolen = false;
/**
* Cached header data.
*/
private transient byte[] headerData = null;
/**
* Serialization support.
*/
private transient ICC_Profile openedProfileObject;
/**
* Instantiates a new ICC profile with the given data.
*
* @param data
* the data.
*/
private ICC_Profile(byte[] data) {
profileHandle = NativeCMM.cmmOpenProfile(data);
NativeCMM.addHandle(this, profileHandle);
}
/**
* Used to instantiate dummy ICC_ProfileStub objects.
*/
ICC_Profile() {
}
/**
* Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
*
* @param profileHandle
* - should be valid handle to opened color profile
*/
ICC_Profile(long profileHandle) {
this.profileHandle = profileHandle;
// A new object reference, need to add it.
NativeCMM.addHandle(this, profileHandle);
}
/**
* Writes the ICC_Profile to a file with the specified name.
*
* @param fileName
* the file name.
* @throws IOException
* if an I/O exception has occurred during writing or opening
* the file.
*/
public void write(String fileName) throws IOException {
FileOutputStream oStream = new FileOutputStream(fileName);
oStream.write(getData());
oStream.close();
}
/**
* Serializable implementation.
*
* @param s
* the s
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeObject(null);
s.writeObject(getData());
}
/**
* Serializable implementation.
*
* @param s
* the s
* @throws IOException
* Signals that an I/O exception has occurred.
* @throws ClassNotFoundException
* the class not found exception
*/
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
String colorSpaceStr = (String)s.readObject();
byte[] data = (byte[])s.readObject();
if (colorSpaceStr != null) {
if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
openedProfileObject = getInstance(ColorSpace.CS_sRGB);
} else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
openedProfileObject = getInstance(ColorSpace.CS_GRAY);
} else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
} else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
} else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
openedProfileObject = getInstance(ColorSpace.CS_PYCC);
} else {
openedProfileObject = ICC_Profile.getInstance(data);
}
} else {
openedProfileObject = ICC_Profile.getInstance(data);
}
}
/**
* Resolves instances being deserialized into instances registered with CMM.
*
* @return ICC_Profile object for profile registered with CMM.
* @throws ObjectStreamException
* if there is an error in the serialized files or during the
* process of reading them.
*/
protected Object readResolve() throws ObjectStreamException {
return openedProfileObject;
}
/**
* Writes the ICC_Profile to an OutputStream.
*
* @param s
* the OutputStream.
* @throws IOException
* signals that an I/O exception has occurred during writing or
* opening OutputStream.
*/
public void write(OutputStream s) throws IOException {
s.write(getData());
}
/**
* Sets a tagged data element in the profile from a byte array.
*
* @param tagSignature
* the ICC tag signature for the data element to be set.
* @param tagData
* the data to be set for the specified tag signature.
*/
public void setData(int tagSignature, byte[] tagData) {
NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
// Remove cached header data if header is modified
if (tagSignature == icSigHead) {
headerData = null;
}
}
/**
* Gets a tagged data element from the profile as a byte array. Elements are
* identified by tag signatures as defined in the ICC specification.
*
* @param tagSignature
* the ICC tag signature for the data element to get.
* @return a byte array that contains the tagged data element.
*/
public byte[] getData(int tagSignature) {
int tagSize = 0;
try {
tagSize = NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
} catch (CMMException e) {
// We'll get this exception if there's no element with
// the specified tag signature
return null;
}
byte[] data = new byte[tagSize];
NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
return data;
}
/**
* Gets a data byte array of this ICC_Profile.
*
* @return a byte array that contains the ICC Profile data.
*/
public byte[] getData() {
int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
byte[] data = new byte[profileSize];
NativeCMM.cmmGetProfile(profileHandle, data);
return data;
}
/**
* Frees the resources associated with an ICC_Profile object.
*/
@Override
protected void finalize() {
if (profileHandle != 0 && !handleStolen) {
NativeCMM.cmmCloseProfile(profileHandle);
}
// Always remove because key no more exist
// when object is destroyed
NativeCMM.removeHandle(this);
}
/**
* Gets the profile class.
*
* @return the profile class constant.
*/
public int getProfileClass() {
int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
switch (deviceClassSignature) {
case icSigColorSpaceClass:
return CLASS_COLORSPACECONVERSION;
case icSigDisplayClass:
return CLASS_DISPLAY;
case icSigOutputClass:
return CLASS_OUTPUT;
case icSigInputClass:
return CLASS_INPUT;
case icSigLinkClass:
return CLASS_DEVICELINK;
case icSigAbstractClass:
return CLASS_ABSTRACT;
case icSigNamedColorClass:
return CLASS_NAMEDCOLOR;
default:
}
// Not an ICC profile class
// awt.15F=Profile class does not comply with ICC specification
throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
}
/**
* Gets the color space type of the Profile Connection Space (PCS).
*
* @return the PCS type.
*/
public int getPCSType() {
return csFromSignature(getIntFromHeader(icHdrPcs));
}
/**
* Gets the number of components of this ICC Profile.
*
* @return the number of components of this ICC Profile.
*/
public int getNumComponents() {
switch (getIntFromHeader(icHdrColorSpace)) {
// The most common cases go first to increase speed
case icSigRgbData:
case icSigXYZData:
case icSigLabData:
return 3;
case icSigCmykData:
return 4;
// Then all other
case icSigGrayData:
return 1;
case icSigSpace2CLR:
return 2;
case icSigYCbCrData:
case icSigLuvData:
case icSigYxyData:
case icSigHlsData:
case icSigHsvData:
case icSigCmyData:
case icSigSpace3CLR:
return 3;
case icSigSpace4CLR:
return 4;
case icSigSpace5CLR:
return 5;
case icSigSpace6CLR:
return 6;
case icSigSpace7CLR:
return 7;
case icSigSpace8CLR:
return 8;
case icSigSpace9CLR:
return 9;
case icSigSpaceACLR:
return 10;
case icSigSpaceBCLR:
return 11;
case icSigSpaceCCLR:
return 12;
case icSigSpaceDCLR:
return 13;
case icSigSpaceECLR:
return 14;
case icSigSpaceFCLR:
return 15;
default:
}
// awt.160=Color space doesn't comply with ICC specification
throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
);
}
/**
* Gets the minor version of this ICC profile.
*
* @return the minor version of this ICC profile.
*/
public int getMinorVersion() {
return getByteFromHeader(icHdrVersion + 1);
}
/**
* Gets the major version of this ICC profile.
*
* @return the major version of this ICC profile.
*/
public int getMajorVersion() {
return getByteFromHeader(icHdrVersion);
}
/**
* Gets the color space type of this ICC_Profile.
*
* @return the color space type.
*/
public int getColorSpaceType() {
return csFromSignature(getIntFromHeader(icHdrColorSpace));
}
/**
* Tries to open the file at the specified path. Path entries can be divided
* by a separator character.
*
* @param path
* the path to the file.
* @param fileName
* the file name.
* @return the input stream to read the file.
*/
private static FileInputStream tryPath(String path, String fileName) {
FileInputStream fiStream = null;
if (path == null) {
return null;
}
StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
while (st.hasMoreTokens()) {
String pathEntry = st.nextToken();
try {
fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
if (fiStream != null) {
return fiStream;
}
} catch (FileNotFoundException e) {
}
}
return fiStream;
}
/**
* Gets the single instance of ICC_Profile from data in the specified file.
*
* @param fileName
* the specified name of file with ICC profile data.
* @return single instance of ICC_Profile.
* @throws IOException
* signals that an I/O error occurred while reading the file or
* the file does not exist.
*/
public static ICC_Profile getInstance(String fileName) throws IOException {
final String fName = fileName; // to use in the privileged block
FileInputStream fiStream = (FileInputStream)AccessController
.doPrivileged(new PrivilegedAction<FileInputStream>() {
public FileInputStream run() {
FileInputStream fiStream = null;
// Open absolute path
try {
fiStream = new FileInputStream(fName);
if (fiStream != null) {
return fiStream;
}
} catch (FileNotFoundException e) {
}
// Check java.iccprofile.path entries
fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
if (fiStream != null) {
return fiStream;
}
// Check java.class.path entries
fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
if (fiStream != null) {
return fiStream;
}
// Check directory with java sample profiles
String home = System.getProperty("java.home"); //$NON-NLS-1$
if (home != null) {
fiStream = tryPath(home + File.separatorChar
+ "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
);
}
return fiStream;
}
});
if (fiStream == null) {
// awt.161=Unable to open file {0}
throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
}
ICC_Profile pf = getInstance(fiStream);
fiStream.close();
return pf;
}
/**
* Gets the single instance of ICC_Profile with data in the specified
* InputStream.
*
* @param s
* the InputStream with ICC profile data.
* @return single instance of ICC_Profile.
* @throws IOException
* if an I/O exception has occurred during reading from
* InputStream.
* @throws IllegalArgumentException
* if the file does not contain valid ICC Profile data.
*/
public static ICC_Profile getInstance(InputStream s) throws IOException {
byte[] header = new byte[headerSize];
// awt.162=Invalid ICC Profile Data
String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
// Get header from the input stream
if (s.read(header) != headerSize) {
throw new IllegalArgumentException(invalidDataMessage);
}
// Check the profile data for consistency
if (ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) != headerMagicNumber) {
throw new IllegalArgumentException(invalidDataMessage);
}
// Get profile size from header, create an array for profile data
int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
byte[] profileData = new byte[profileSize];
// Copy header into it
System.arraycopy(header, 0, profileData, 0, headerSize);
// Read the profile itself
if (s.read(profileData, headerSize, profileSize - headerSize) != profileSize - headerSize) {
throw new IllegalArgumentException(invalidDataMessage);
}
return getInstance(profileData);
}
/**
* Gets the single instance of ICC_Profile from the specified data in a byte
* array.
*
* @param data
* the byte array of ICC profile.
* @return single instance of ICC_Profile from the specified data in a byte
* array.
* @throws IllegalArgumentException
* if the file does not contain valid ICC Profile data.
*/
public static ICC_Profile getInstance(byte[] data) {
ICC_Profile res = null;
try {
res = new ICC_Profile(data);
} catch (CMMException e) {
// awt.162=Invalid ICC Profile Data
throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
}
if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
try {
if (res.getColorSpaceType() == ColorSpace.TYPE_RGB
&& res.getDataSize(icSigMediaWhitePointTag) > 0
&& res.getDataSize(icSigRedColorantTag) > 0
&& res.getDataSize(icSigGreenColorantTag) > 0
&& res.getDataSize(icSigBlueColorantTag) > 0
&& res.getDataSize(icSigRedTRCTag) > 0
&& res.getDataSize(icSigGreenTRCTag) > 0
&& res.getDataSize(icSigBlueTRCTag) > 0) {
res = new ICC_ProfileRGB(res.getProfileHandle());
} else if (res.getColorSpaceType() == ColorSpace.TYPE_GRAY
&& res.getDataSize(icSigMediaWhitePointTag) > 0
&& res.getDataSize(icSigGrayTRCTag) > 0) {
res = new ICC_ProfileGray(res.getProfileHandle());
}
} catch (CMMException e) { /* return res in this case */
}
}
return res;
}
/**
* Gets the single instance of ICC_Profile with the specific color space
* defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
* CS_PYCC, CS_GRAY.
*
* @param cspace
* the type of color space defined in the ColorSpace class.
* @return single instance of ICC_Profile.
* @throws IllegalArgumentException
* is not one of the defined color space types.
*/
public static ICC_Profile getInstance(int cspace) {
try {
switch (cspace) {
case ColorSpace.CS_sRGB:
if (sRGBProfile == null) {
sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
}
return sRGBProfile;
case ColorSpace.CS_CIEXYZ:
if (xyzProfile == null) {
xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
}
return xyzProfile;
case ColorSpace.CS_GRAY:
if (grayProfile == null) {
grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
}
return grayProfile;
case ColorSpace.CS_PYCC:
if (pyccProfile == null) {
pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
}
return pyccProfile;
case ColorSpace.CS_LINEAR_RGB:
if (linearRGBProfile == null) {
linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
}
return linearRGBProfile;
}
} catch (IOException e) {
// awt.163=Can't open color profile
throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
}
// awt.164=Not a predefined color space
throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
}
/**
* Reads an integer from the profile header at the specified position.
*
* @param idx
* - offset in bytes from the beginning of the header
* @return the integer value from header
*/
private int getIntFromHeader(int idx) {
if (headerData == null) {
headerData = getData(icSigHead);
}
return ((headerData[idx] & 0xFF) << 24) | ((headerData[idx + 1] & 0xFF) << 16)
| ((headerData[idx + 2] & 0xFF) << 8) | ((headerData[idx + 3] & 0xFF));
}
/**
* Reads byte from the profile header at the specified position.
*
* @param idx
* - offset in bytes from the beginning of the header
* @return the byte from header
*/
private byte getByteFromHeader(int idx) {
if (headerData == null) {
headerData = getData(icSigHead);
}
return headerData[idx];
}
/**
* Converts ICC color space signature to the java predefined color space
* type.
*
* @param signature
* the signature
* @return the int
*/
private int csFromSignature(int signature) {
switch (signature) {
case icSigRgbData:
return ColorSpace.TYPE_RGB;
case icSigXYZData:
return ColorSpace.TYPE_XYZ;
case icSigCmykData:
return ColorSpace.TYPE_CMYK;
case icSigLabData:
return ColorSpace.TYPE_Lab;
case icSigGrayData:
return ColorSpace.TYPE_GRAY;
case icSigHlsData:
return ColorSpace.TYPE_HLS;
case icSigLuvData:
return ColorSpace.TYPE_Luv;
case icSigYCbCrData:
return ColorSpace.TYPE_YCbCr;
case icSigYxyData:
return ColorSpace.TYPE_Yxy;
case icSigHsvData:
return ColorSpace.TYPE_HSV;
case icSigCmyData:
return ColorSpace.TYPE_CMY;
case icSigSpace2CLR:
return ColorSpace.TYPE_2CLR;
case icSigSpace3CLR:
return ColorSpace.TYPE_3CLR;
case icSigSpace4CLR:
return ColorSpace.TYPE_4CLR;
case icSigSpace5CLR:
return ColorSpace.TYPE_5CLR;
case icSigSpace6CLR:
return ColorSpace.TYPE_6CLR;
case icSigSpace7CLR:
return ColorSpace.TYPE_7CLR;
case icSigSpace8CLR:
return ColorSpace.TYPE_8CLR;
case icSigSpace9CLR:
return ColorSpace.TYPE_9CLR;
case icSigSpaceACLR:
return ColorSpace.TYPE_ACLR;
case icSigSpaceBCLR:
return ColorSpace.TYPE_BCLR;
case icSigSpaceCCLR:
return ColorSpace.TYPE_CCLR;
case icSigSpaceDCLR:
return ColorSpace.TYPE_DCLR;
case icSigSpaceECLR:
return ColorSpace.TYPE_ECLR;
case icSigSpaceFCLR:
return ColorSpace.TYPE_FCLR;
default:
}
// awt.165=Color space doesn't comply with ICC specification
throw new IllegalArgumentException(Messages.getString("awt.165")); //$NON-NLS-1$
}
/**
* Gets the profile handle.
*
* @return the profile handle
*/
private long getProfileHandle() {
handleStolen = true;
return profileHandle;
}
/**
* Gets the data size.
*
* @param tagSignature
* the tag signature
* @return the data size
*/
private int getDataSize(int tagSignature) {
return NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
}
/**
* Reads XYZ value from the tag data.
*
* @param tagSignature
* the tag signature
* @return the XYZ value
*/
float[] getXYZValue(int tagSignature) {
float[] res = new float[3];
byte[] data = getData(tagSignature);
// Convert from ICC s15Fixed16Number type
// 1 (float) = 0x10000 (s15Fixed16Number),
// hence dividing by 0x10000
res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
return res;
}
/**
* Gets the media white point.
*
* @return the media white point.
*/
float[] getMediaWhitePoint() {
return getXYZValue(icSigMediaWhitePointTag);
}
/**
* If TRC is not a table returns gamma via return value and sets dataTRC to
* null. If TRC is a table returns 0 and fills dataTRC with values.
*
* @param tagSignature
* the tag signature
* @param dataTRC
* the data trc
* @return - gamma or zero if TRC is a table
*/
private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
byte[] data = getData(tagSignature);
int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
dataTRC = null;
if (trcSize == 0) {
return 1.0f;
}
if (trcSize == 1) {
// Cast from ICC u8Fixed8Number to float
return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
}
// TRC is a table
dataTRC = new short[trcSize];
for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
}
return 0;
}
/**
* Gets the gamma.
*
* @param tagSignature
* the tag signature
* @return the gamma
*/
float getGamma(int tagSignature) {
short[] dataTRC = null;
float gamma = getGammaOrTRC(tagSignature, dataTRC);
if (dataTRC == null) {
return gamma;
}
// awt.166=TRC is not a simple gamma value.
throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
}
/**
* Gets the TRC.
*
* @param tagSignature
* the tag signature
* @return the tRC
*/
short[] getTRC(int tagSignature) {
short[] dataTRC = null;
getGammaOrTRC(tagSignature, dataTRC);
if (dataTRC == null) {
// awt.167=TRC is a gamma value, not a table.
throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
}
return dataTRC;
}
}