- /*
 - * @(#)ICC_Profile.java 1.23 00/02/02
 - *
 - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
 - *
 - * This software is the proprietary information of Sun Microsystems, Inc.
 - * Use is subject to license terms.
 - *
 - */
 - /**********************************************************************
 - **********************************************************************
 - **********************************************************************
 - *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
 - *** As an unpublished work pursuant to Title 17 of the United ***
 - *** States Code. All rights reserved. ***
 - **********************************************************************
 - **********************************************************************
 - **********************************************************************/
 - package java.awt.color;
 - import sun.awt.color.CMM;
 - import sun.awt.color.ProfileDeferralMgr;
 - import sun.awt.color.ProfileDeferralInfo;
 - import sun.awt.color.ProfileActivator;
 - 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.util.StringTokenizer;
 - /**
 - * A representation of color profile data for device independent and
 - * device dependent color spaces based on the International Color
 - * Consortium Specification ICC.1:1998-09, File Format for Color Profiles,
 - * September 1998, and the addendum ICC.1A:1999-04, April 1999, to that
 - * specification (see <A href="http://www.color.org"> http://www.color.org</A>).
 - * <p>
 - * An ICC_ColorSpace object can be constructed from an appropriate
 - * ICC_Profile.
 - * Typically, an ICC_ColorSpace would be associated with an ICC
 - * Profile which is either an input, display, or output profile (see
 - * the ICC specification). There are also device link, abstract,
 - * color space conversion, and named color profiles. These are less
 - * useful for tagging a color or image, but are useful for other
 - * purposes (in particular device link profiles can provide improved
 - * performance for converting from one device's color space to
 - * another's).
 - * <p>
 - * ICC Profiles represent transformations from the color space of
 - * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
 - * Profiles of interest for tagging images or colors have a PCS
 - * which is one of the two specific device independent
 - * spaces (one CIEXYZ space and one CIELab space) defined in the
 - * ICC Profile Format Specification. Most profiles of interest
 - * either have invertible transformations or explicitly specify
 - * transformations going both directions.
 - * <p>
 - * @version 10 Feb 1997
 - * @see ICC_ColorSpace
 - */
 - public class ICC_Profile implements Serializable {
 - transient long ID;
 - private transient ProfileDeferralInfo deferralInfo;
 - private transient ProfileActivator profileActivator;
 - // Registry of singleton profile objects for specific color spaces
 - // defined in the ColorSpace class (e.g. CS_sRGB), see
 - // getInstance(int cspace) factory method.
 - private static ICC_Profile sRGBprofile;
 - private static ICC_Profile XYZprofile;
 - private static ICC_Profile PYCCprofile;
 - private static ICC_Profile GRAYprofile;
 - private static ICC_Profile LINEAR_RGBprofile;
 - /**
 - * Profile class is input.
 - */
 - public static final int CLASS_INPUT = 0;
 - /**
 - * Profile class is display.
 - */
 - public static final int CLASS_DISPLAY = 1;
 - /**
 - * Profile class is output.
 - */
 - public static final int CLASS_OUTPUT = 2;
 - /**
 - * Profile class is device link.
 - */
 - public static final int CLASS_DEVICELINK = 3;
 - /**
 - * Profile class is color space conversion.
 - */
 - public static final int CLASS_COLORSPACECONVERSION = 4;
 - /**
 - * Profile class is abstract.
 - */
 - public static final int CLASS_ABSTRACT = 5;
 - /**
 - * Profile class is named color.
 - */
 - public static final int CLASS_NAMEDCOLOR = 6;
 - /**
 - * ICC Profile Color Space Type Signature: 'XYZ '.
 - */
 - public static final int icSigXYZData = 0x58595A20; /* 'XYZ ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'Lab '.
 - */
 - public static final int icSigLabData = 0x4C616220; /* 'Lab ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'Luv '.
 - */
 - public static final int icSigLuvData = 0x4C757620; /* 'Luv ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'YCbr'.
 - */
 - public static final int icSigYCbCrData = 0x59436272; /* 'YCbr' */
 - /**
 - * ICC Profile Color Space Type Signature: 'Yxy '.
 - */
 - public static final int icSigYxyData = 0x59787920; /* 'Yxy ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'RGB '.
 - */
 - public static final int icSigRgbData = 0x52474220; /* 'RGB ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'GRAY'.
 - */
 - public static final int icSigGrayData = 0x47524159; /* 'GRAY' */
 - /**
 - * ICC Profile Color Space Type Signature: 'HSV'.
 - */
 - public static final int icSigHsvData = 0x48535620; /* 'HSV ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'HLS'.
 - */
 - public static final int icSigHlsData = 0x484C5320; /* 'HLS ' */
 - /**
 - * ICC Profile Color Space Type Signature: 'CMYK'.
 - */
 - public static final int icSigCmykData = 0x434D594B; /* 'CMYK' */
 - /**
 - * ICC Profile Color Space Type Signature: 'CMY '.
 - */
 - public static final int icSigCmyData = 0x434D5920; /* 'CMY ' */
 - /**
 - * ICC Profile Color Space Type Signature: '2CLR'.
 - */
 - public static final int icSigSpace2CLR = 0x32434C52; /* '2CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '3CLR'.
 - */
 - public static final int icSigSpace3CLR = 0x33434C52; /* '3CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '4CLR'.
 - */
 - public static final int icSigSpace4CLR = 0x34434C52; /* '4CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '5CLR'.
 - */
 - public static final int icSigSpace5CLR = 0x35434C52; /* '5CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '6CLR'.
 - */
 - public static final int icSigSpace6CLR = 0x36434C52; /* '6CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '7CLR'.
 - */
 - public static final int icSigSpace7CLR = 0x37434C52; /* '7CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '8CLR'.
 - */
 - public static final int icSigSpace8CLR = 0x38434C52; /* '8CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: '9CLR'.
 - */
 - public static final int icSigSpace9CLR = 0x39434C52; /* '9CLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'ACLR'.
 - */
 - public static final int icSigSpaceACLR = 0x41434C52; /* 'ACLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'BCLR'.
 - */
 - public static final int icSigSpaceBCLR = 0x42434C52; /* 'BCLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'CCLR'.
 - */
 - public static final int icSigSpaceCCLR = 0x43434C52; /* 'CCLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'DCLR'.
 - */
 - public static final int icSigSpaceDCLR = 0x44434C52; /* 'DCLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'ECLR'.
 - */
 - public static final int icSigSpaceECLR = 0x45434C52; /* 'ECLR' */
 - /**
 - * ICC Profile Color Space Type Signature: 'FCLR'.
 - */
 - public static final int icSigSpaceFCLR = 0x46434C52; /* 'FCLR' */
 - /**
 - * ICC Profile Class Signature: 'scnr'.
 - */
 - public static final int icSigInputClass = 0x73636E72; /* 'scnr' */
 - /**
 - * ICC Profile Class Signature: 'mntr'.
 - */
 - public static final int icSigDisplayClass = 0x6D6E7472; /* 'mntr' */
 - /**
 - * ICC Profile Class Signature: 'prtr'.
 - */
 - public static final int icSigOutputClass = 0x70727472; /* 'prtr' */
 - /**
 - * ICC Profile Class Signature: 'link'.
 - */
 - public static final int icSigLinkClass = 0x6C696E6B; /* 'link' */
 - /**
 - * ICC Profile Class Signature: 'abst'.
 - */
 - public static final int icSigAbstractClass = 0x61627374; /* 'abst' */
 - /**
 - * ICC Profile Class Signature: 'spac'.
 - */
 - public static final int icSigColorSpaceClass = 0x73706163; /* 'spac' */
 - /**
 - * ICC Profile Class Signature: 'nmcl'.
 - */
 - public static final int icSigNamedColorClass = 0x6e6d636c; /* 'nmcl' */
 - /**
 - * ICC Profile Rendering Intent: Perceptual.
 - */
 - public static final int icPerceptual = 0;
 - /**
 - * ICC Profile Rendering Intent: RelativeColorimetric.
 - */
 - public static final int icRelativeColorimetric = 1;
 - /**
 - * ICC Profile Rendering Intent: Saturation.
 - */
 - public static final int icSaturation = 2;
 - /**
 - * ICC Profile Rendering Intent: AbsoluteColorimetric.
 - */
 - public static final int icAbsoluteColorimetric = 3;
 - /**
 - * ICC Profile Tag Signature: 'head' - special.
 - */
 - public static final int icSigHead = 0x68656164; /* 'head' - special */
 - /**
 - * ICC Profile Tag Signature: 'A2B0'.
 - */
 - public static final int icSigAToB0Tag = 0x41324230; /* 'A2B0' */
 - /**
 - * ICC Profile Tag Signature: 'A2B1'.
 - */
 - public static final int icSigAToB1Tag = 0x41324231; /* 'A2B1' */
 - /**
 - * ICC Profile Tag Signature: 'A2B2'.
 - */
 - public static final int icSigAToB2Tag = 0x41324232; /* 'A2B2' */
 - /**
 - * ICC Profile Tag Signature: 'bXYZ'.
 - */
 - public static final int icSigBlueColorantTag = 0x6258595A; /* 'bXYZ' */
 - /**
 - * ICC Profile Tag Signature: 'bTRC'.
 - */
 - public static final int icSigBlueTRCTag = 0x62545243; /* 'bTRC' */
 - /**
 - * ICC Profile Tag Signature: 'B2A0'.
 - */
 - public static final int icSigBToA0Tag = 0x42324130; /* 'B2A0' */
 - /**
 - * ICC Profile Tag Signature: 'B2A1'.
 - */
 - public static final int icSigBToA1Tag = 0x42324131; /* 'B2A1' */
 - /**
 - * ICC Profile Tag Signature: 'B2A2'.
 - */
 - public static final int icSigBToA2Tag = 0x42324132; /* 'B2A2' */
 - /**
 - * ICC Profile Tag Signature: 'calt'.
 - */
 - public static final int icSigCalibrationDateTimeTag = 0x63616C74;
 - /* 'calt' */
 - /**
 - * ICC Profile Tag Signature: 'targ'.
 - */
 - public static final int icSigCharTargetTag = 0x74617267; /* 'targ' */
 - /**
 - * ICC Profile Tag Signature: 'cprt'.
 - */
 - public static final int icSigCopyrightTag = 0x63707274; /* 'cprt' */
 - /**
 - * ICC Profile Tag Signature: 'crdi'.
 - */
 - public static final int icSigCrdInfoTag = 0x63726469; /* 'crdi' */
 - /**
 - * ICC Profile Tag Signature: 'dmnd'.
 - */
 - public static final int icSigDeviceMfgDescTag = 0x646D6E64; /* 'dmnd' */
 - /**
 - * ICC Profile Tag Signature: 'dmdd'.
 - */
 - public static final int icSigDeviceModelDescTag = 0x646D6464; /* 'dmdd' */
 - /**
 - * ICC Profile Tag Signature: 'devs'.
 - */
 - public static final int icSigDeviceSettingsTag = 0x64657673; /* 'devs' */
 - /**
 - * ICC Profile Tag Signature: 'gamt'.
 - */
 - public static final int icSigGamutTag = 0x67616D74; /* 'gamt' */
 - /**
 - * ICC Profile Tag Signature: 'kTRC'.
 - */
 - public static final int icSigGrayTRCTag = 0x6b545243; /* 'kTRC' */
 - /**
 - * ICC Profile Tag Signature: 'gXYZ'.
 - */
 - public static final int icSigGreenColorantTag = 0x6758595A; /* 'gXYZ' */
 - /**
 - * ICC Profile Tag Signature: 'gTRC'.
 - */
 - public static final int icSigGreenTRCTag = 0x67545243; /* 'gTRC' */
 - /**
 - * ICC Profile Tag Signature: 'lumi'.
 - */
 - public static final int icSigLuminanceTag = 0x6C756d69; /* 'lumi' */
 - /**
 - * ICC Profile Tag Signature: 'meas'.
 - */
 - public static final int icSigMeasurementTag = 0x6D656173; /* 'meas' */
 - /**
 - * ICC Profile Tag Signature: 'bkpt'.
 - */
 - public static final int icSigMediaBlackPointTag = 0x626B7074; /* 'bkpt' */
 - /**
 - * ICC Profile Tag Signature: 'wtpt'.
 - */
 - public static final int icSigMediaWhitePointTag = 0x77747074; /* 'wtpt' */
 - /**
 - * ICC Profile Tag Signature: 'ncl2'.
 - */
 - public static final int icSigNamedColor2Tag = 0x6E636C32; /* 'ncl2' */
 - /**
 - * ICC Profile Tag Signature: 'resp'.
 - */
 - public static final int icSigOutputResponseTag = 0x72657370; /* 'resp' */
 - /**
 - * ICC Profile Tag Signature: 'pre0'.
 - */
 - public static final int icSigPreview0Tag = 0x70726530; /* 'pre0' */
 - /**
 - * ICC Profile Tag Signature: 'pre1'.
 - */
 - public static final int icSigPreview1Tag = 0x70726531; /* 'pre1' */
 - /**
 - * ICC Profile Tag Signature: 'pre2'.
 - */
 - public static final int icSigPreview2Tag = 0x70726532; /* 'pre2' */
 - /**
 - * ICC Profile Tag Signature: 'desc'.
 - */
 - public static final int icSigProfileDescriptionTag = 0x64657363;
 - /* 'desc' */
 - /**
 - * ICC Profile Tag Signature: 'pseq'.
 - */
 - public static final int icSigProfileSequenceDescTag = 0x70736571;
 - /* 'pseq' */
 - /**
 - * ICC Profile Tag Signature: 'psd0'.
 - */
 - public static final int icSigPs2CRD0Tag = 0x70736430; /* 'psd0' */
 - /**
 - * ICC Profile Tag Signature: 'psd1'.
 - */
 - public static final int icSigPs2CRD1Tag = 0x70736431; /* 'psd1' */
 - /**
 - * ICC Profile Tag Signature: 'psd2'.
 - */
 - public static final int icSigPs2CRD2Tag = 0x70736432; /* 'psd2' */
 - /**
 - * ICC Profile Tag Signature: 'psd3'.
 - */
 - public static final int icSigPs2CRD3Tag = 0x70736433; /* 'psd3' */
 - /**
 - * ICC Profile Tag Signature: 'ps2s'.
 - */
 - public static final int icSigPs2CSATag = 0x70733273; /* 'ps2s' */
 - /**
 - * ICC Profile Tag Signature: 'ps2i'.
 - */
 - public static final int icSigPs2RenderingIntentTag = 0x70733269;
 - /* 'ps2i' */
 - /**
 - * ICC Profile Tag Signature: 'rXYZ'.
 - */
 - public static final int icSigRedColorantTag = 0x7258595A; /* 'rXYZ' */
 - /**
 - * ICC Profile Tag Signature: 'rTRC'.
 - */
 - public static final int icSigRedTRCTag = 0x72545243; /* 'rTRC' */
 - /**
 - * ICC Profile Tag Signature: 'scrd'.
 - */
 - public static final int icSigScreeningDescTag = 0x73637264; /* 'scrd' */
 - /**
 - * ICC Profile Tag Signature: 'scrn'.
 - */
 - public static final int icSigScreeningTag = 0x7363726E; /* 'scrn' */
 - /**
 - * ICC Profile Tag Signature: 'tech'.
 - */
 - public static final int icSigTechnologyTag = 0x74656368; /* 'tech' */
 - /**
 - * ICC Profile Tag Signature: 'bfd '.
 - */
 - public static final int icSigUcrBgTag = 0x62666420; /* 'bfd ' */
 - /**
 - * ICC Profile Tag Signature: 'vued'.
 - */
 - public static final int icSigViewingCondDescTag = 0x76756564; /* 'vued' */
 - /**
 - * ICC Profile Tag Signature: 'view'.
 - */
 - public static final int icSigViewingConditionsTag = 0x76696577;/* 'view' */
 - /**
 - * ICC Profile Tag Signature: 'chrm'.
 - */
 - public static final int icSigChromaticityTag = 0x6368726d; /* 'chrm' */
 - /**
 - * ICC Profile Header Location: profile size in bytes.
 - */
 - public static final int icHdrSize = 0; /* Profile size in bytes */
 - /**
 - * ICC Profile Header Location: CMM for this profile.
 - */
 - public static final int icHdrCmmId = 4; /* CMM for this profile */
 - /**
 - * ICC Profile Header Location: format version number.
 - */
 - public static final int icHdrVersion = 8; /* Format version number */
 - /**
 - * ICC Profile Header Location: type of profile.
 - */
 - public static final int icHdrDeviceClass = 12; /* Type of profile */
 - /**
 - * ICC Profile Header Location: color space of data.
 - */
 - public static final int icHdrColorSpace = 16; /* Color space of data */
 - /**
 - * ICC Profile Header Location: PCS - XYZ or Lab only.
 - */
 - public static final int icHdrPcs = 20; /* PCS - XYZ or Lab only */
 - /**
 - * ICC Profile Header Location: date profile was created.
 - */
 - public static final int icHdrDate = 24; /* Date profile was created */
 - /**
 - * ICC Profile Header Location: icMagicNumber.
 - */
 - public static final int icHdrMagic = 36; /* icMagicNumber */
 - /**
 - * ICC Profile Header Location: primary platform.
 - */
 - public static final int icHdrPlatform = 40; /* Primary Platform */
 - /**
 - * ICC Profile Header Location: various bit settings.
 - */
 - public static final int icHdrFlags = 44; /* Various bit settings */
 - /**
 - * ICC Profile Header Location: device manufacturer.
 - */
 - public static final int icHdrManufacturer = 48; /* Device manufacturer */
 - /**
 - * ICC Profile Header Location: device model number.
 - */
 - public static final int icHdrModel = 52; /* Device model number */
 - /**
 - * ICC Profile Header Location: device attributes.
 - */
 - public static final int icHdrAttributes = 56; /* Device attributes */
 - /**
 - * ICC Profile Header Location: rendering intent.
 - */
 - public static final int icHdrRenderingIntent = 64; /* Rendering intent */
 - /**
 - * ICC Profile Header Location: profile illuminant.
 - */
 - public static final int icHdrIlluminant = 68; /* Profile illuminant */
 - /**
 - * ICC Profile Header Location: profile creator.
 - */
 - public static final int icHdrCreator = 80; /* Profile creator */
 - /**
 - * ICC Profile Constant: tag type signaturE.
 - */
 - public static final int icTagType = 0; /* tag type signature */
 - /**
 - * ICC Profile Constant: reserved.
 - */
 - public static final int icTagReserved = 4; /* reserved */
 - /**
 - * ICC Profile Constant: curveType count.
 - */
 - public static final int icCurveCount = 8; /* curveType count */
 - /**
 - * ICC Profile Constant: curveType data.
 - */
 - public static final int icCurveData = 12; /* curveType data */
 - /**
 - * ICC Profile Constant: XYZNumber X.
 - */
 - public static final int icXYZNumberX = 8; /* XYZNumber X */
 - /**
 - * Constructs an ICC_Profile object with a given ID.
 - */
 - ICC_Profile(long ID) {
 - this.ID = ID;
 - }
 - /**
 - * Constructs an ICC_Profile object whose loading will be deferred.
 - * The ID will be 0 until the profile is loaded.
 - */
 - ICC_Profile(ProfileDeferralInfo pdi) {
 - this.deferralInfo = pdi;
 - this.profileActivator = new ProfileActivator() {
 - public void activate() {
 - activateDeferredProfile();
 - }
 - };
 - ProfileDeferralMgr.registerDeferral(this.profileActivator);
 - }
 - /**
 - * Frees the resources associated with an ICC_Profile object.
 - */
 - protected void finalize () {
 - if (ID != 0) {
 - CMM.checkStatus(CMM.cmmFreeProfile(ID));
 - } else if (profileActivator != null) {
 - ProfileDeferralMgr.unregisterDeferral(profileActivator);
 - }
 - }
 - /**
 - * Constructs an ICC_Profile object corresponding to the data in
 - * a byte array. Throws an IllegalArgumentException if the data
 - * does not correspond to a valid ICC Profile.
 - */
 - public static ICC_Profile getInstance(byte[] data) {
 - ICC_Profile thisProfile;
 - long[] theID = new long [1];
 - if (ProfileDeferralMgr.deferring) {
 - ProfileDeferralMgr.activateProfiles();
 - }
 - try {
 - CMM.checkStatus(CMM.cmmLoadProfile(data, theID));
 - } catch (CMMException c) {
 - throw new IllegalArgumentException("Invalid ICC Profile Data");
 - }
 - try {
 - if ((getColorSpaceType (theID[0]) == ColorSpace.TYPE_GRAY) &&
 - (getData (theID[0], icSigMediaWhitePointTag) != null) &&
 - (getData (theID[0], icSigGrayTRCTag) != null)) {
 - thisProfile = new ICC_ProfileGray (theID[0]);
 - }
 - else if ((getColorSpaceType (theID[0]) == ColorSpace.TYPE_RGB) &&
 - (getData (theID[0], icSigMediaWhitePointTag) != null) &&
 - (getData (theID[0], icSigRedColorantTag) != null) &&
 - (getData (theID[0], icSigGreenColorantTag) != null) &&
 - (getData (theID[0], icSigBlueColorantTag) != null) &&
 - (getData (theID[0], icSigRedTRCTag) != null) &&
 - (getData (theID[0], icSigGreenTRCTag) != null) &&
 - (getData (theID[0], icSigBlueTRCTag) != null)) {
 - thisProfile = new ICC_ProfileRGB (theID[0]);
 - }
 - else {
 - thisProfile = new ICC_Profile (theID[0]);
 - }
 - } catch (CMMException c) {
 - thisProfile = new ICC_Profile (theID[0]);
 - }
 - return thisProfile;
 - }
 - /**
 - * Constructs an ICC_Profile corresponding to one of the specific color
 - * spaces defined by the ColorSpace class (for example CS_sRGB).
 - * Throws an IllegalArgumentException if cspace is not one of the
 - * defined color spaces.
 - */
 - public static ICC_Profile getInstance (int cspace)
 - {
 - ICC_Profile thisProfile = null;
 - String fileName;
 - try {
 - switch (cspace) {
 - case ColorSpace.CS_sRGB:
 - if (sRGBprofile == null) {
 - sRGBprofile = getDeferredInstance(
 - new ProfileDeferralInfo("sRGB.pf", ColorSpace.TYPE_RGB,
 - 3, CLASS_DISPLAY));
 - }
 - thisProfile = sRGBprofile;
 - break;
 - case ColorSpace.CS_CIEXYZ:
 - if (XYZprofile == null) {
 - XYZprofile = getInstance ("CIEXYZ.pf");
 - }
 - thisProfile = XYZprofile;
 - break;
 - case ColorSpace.CS_PYCC:
 - if (PYCCprofile == null) {
 - PYCCprofile = getInstance ("PYCC.pf");
 - }
 - thisProfile = PYCCprofile;
 - break;
 - case ColorSpace.CS_GRAY:
 - if (GRAYprofile == null) {
 - GRAYprofile = getInstance ("GRAY.pf");
 - }
 - thisProfile = GRAYprofile;
 - break;
 - case ColorSpace.CS_LINEAR_RGB:
 - if (LINEAR_RGBprofile == null) {
 - LINEAR_RGBprofile = getInstance ("LINEAR_RGB.pf");
 - }
 - thisProfile = LINEAR_RGBprofile;
 - break;
 - default:
 - throw new IllegalArgumentException("Unknown color space");
 - }
 - } catch (IOException e) {
 - throw new IllegalArgumentException("Can't load standard profile");
 - }
 - return thisProfile;
 - }
 - /**
 - * Constructs an ICC_Profile corresponding to the data in a file.
 - * fileName may be an absolute or a relative file specification.
 - * Relative file names are looked for in several places: first, relative
 - * to any directories specified by the java.iccprofile.path property;
 - * second, relative to any directories specified by the java.class.path
 - * property; finally, in a directory used to store profiles always
 - * available, such as the profile for sRGB. Built-in profiles use .pf as
 - * the file name extension for profiles, e.g. sRGB.pf.
 - * This method throws an IOException if the specified file cannot be
 - * opened or if an I/O error occurs while reading the file. It throws
 - * an IllegalArgumentException if the file does not contain valid ICC
 - * Profile data.
 - */
 - public static ICC_Profile getInstance(String fileName) throws IOException {
 - ICC_Profile thisProfile;
 - FileInputStream fis;
 - if ((fis = openProfile(fileName)) == null) {
 - throw new IOException("Cannot open file " + fileName);
 - }
 - thisProfile = getInstance(fis);
 - fis.close(); /* close the file */
 - return thisProfile;
 - }
 - /**
 - * Constructs an ICC_Profile corresponding to the data in an InputStream.
 - * This method throws an IllegalArgumentException if the stream does not
 - * contain valid ICC Profile data. It throws an IOException if an I/O
 - * error occurs while reading the stream.
 - */
 - public static ICC_Profile getInstance(InputStream s) throws IOException {
 - byte profileData[];
 - if (s instanceof ProfileDeferralInfo) {
 - /* hack to detect profiles whose loading can be deferred */
 - return getDeferredInstance((ProfileDeferralInfo) s);
 - }
 - if ((profileData = getProfileDataFromStream(s)) == null) {
 - throw new IllegalArgumentException("Invalid ICC Profile Data");
 - }
 - return getInstance(profileData);
 - }
 - static byte[] getProfileDataFromStream(InputStream s) throws IOException {
 - byte profileData[];
 - int profileSize;
 - byte header[] = new byte[128];
 - int bytestoread = 128;
 - int bytesread = 0;
 - int n;
 - while (bytestoread != 0) {
 - if ((n = s.read(header, bytesread, bytestoread)) < 0) {
 - return null;
 - }
 - bytesread += n;
 - bytestoread -= n;
 - }
 - if (header[36] != 0x61 || header[37] != 0x63 ||
 - header[38] != 0x73 || header[39] != 0x70) {
 - return null; /* not a valid profile */
 - }
 - profileSize = ((header[0] & 0xff) << 24) |
 - ((header[1] & 0xff) << 16) |
 - ((header[2] & 0xff) << 8) |
 - (header[3] & 0xff);
 - profileData = new byte[profileSize];
 - System.arraycopy(header, 0, profileData, 0, 128);
 - bytestoread = profileSize - 128;
 - bytesread = 128;
 - while (bytestoread != 0) {
 - if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
 - return null;
 - }
 - bytesread += n;
 - bytestoread -= n;
 - }
 - return profileData;
 - }
 - /**
 - * Constructs an ICC_Profile for which the actual loading of the
 - * profile data from a file and the initialization of the CMM should
 - * be deferred as long as possible.
 - */
 - static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi)
 - throws IOException {
 - if (!ProfileDeferralMgr.deferring) {
 - return getInstance(pdi.filename);
 - }
 - if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) {
 - return new ICC_ProfileRGB(pdi);
 - } else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) {
 - return new ICC_ProfileGray(pdi);
 - } else {
 - return new ICC_Profile(pdi);
 - }
 - }
 - void activateDeferredProfile() {
 - long[] theID = new long [1];
 - byte profileData[];
 - FileInputStream fis;
 - String fileName = deferralInfo.filename;
 - profileActivator = null;
 - deferralInfo = null;
 - if ((fis = openProfile(fileName)) == null) {
 - throw new IllegalArgumentException("Cannot open file " + fileName);
 - }
 - try {
 - profileData = getProfileDataFromStream(fis);
 - fis.close(); /* close the file */
 - }
 - catch (IOException e) {
 - throw new IllegalArgumentException("Invalid ICC Profile Data" +
 - fileName);
 - }
 - if (profileData == null) {
 - throw new IllegalArgumentException("Invalid ICC Profile Data" +
 - fileName);
 - }
 - try {
 - CMM.checkStatus(CMM.cmmLoadProfile(profileData, theID));
 - } catch (CMMException c) {
 - throw new IllegalArgumentException("Invalid ICC Profile Data" +
 - fileName);
 - }
 - ID = theID[0];
 - }
 - /**
 - * Returns profile major version.
 - */
 - public int getMajorVersion() {
 - byte[] theHeader;
 - theHeader = getData(icSigHead); /* getData will activate deferred
 - profiles if necessary */
 - return (int) theHeader[8];
 - }
 - /**
 - * Returns profile minor version.
 - */
 - public int getMinorVersion() {
 - byte[] theHeader;
 - theHeader = getData(icSigHead); /* getData will activate deferred
 - profiles if necessary */
 - return (int) theHeader[9];
 - }
 - /**
 - * Returns the profile class. Returns one of the predefined profile
 - * class constants.
 - */
 - public int getProfileClass() {
 - byte[] theHeader;
 - int theClassSig, theClass;
 - if (deferralInfo != null) {
 - return deferralInfo.profileClass; /* Need to have this info for
 - ICC_ColorSpace without
 - causing a deferred profile
 - to be loaded */
 - }
 - theHeader = getData(icSigHead);
 - theClassSig = intFromBigEndian (theHeader, icHdrDeviceClass);
 - switch (theClassSig) {
 - case icSigInputClass:
 - theClass = CLASS_INPUT;
 - break;
 - case icSigDisplayClass:
 - theClass = CLASS_DISPLAY;
 - break;
 - case icSigOutputClass:
 - theClass = CLASS_OUTPUT;
 - break;
 - case icSigLinkClass:
 - theClass = CLASS_DEVICELINK;
 - break;
 - case icSigColorSpaceClass:
 - theClass = CLASS_COLORSPACECONVERSION;
 - break;
 - case icSigAbstractClass:
 - theClass = CLASS_ABSTRACT;
 - break;
 - case icSigNamedColorClass:
 - theClass = CLASS_NAMEDCOLOR;
 - break;
 - default:
 - throw new IllegalArgumentException("Unknown profile class");
 - }
 - return theClass;
 - }
 - /**
 - * Returns the color space type. Returns one of the color space type
 - * constants defined by the ColorSpace class. This is the
 - * "input" color space of the profile. The type defines the
 - * number of components of the color space and the interpretation,
 - * e.g. TYPE_RGB identifies a color space with three components - red,
 - * green, and blue. It does not define the particular color
 - * characteristics of the space, e.g. the chromaticities of the
 - * primaries.
 - */
 - public int getColorSpaceType() {
 - if (deferralInfo != null) {
 - return deferralInfo.colorSpaceType; /* Need to have this info for
 - ICC_ColorSpace without
 - causing a deferred profile
 - to be loaded */
 - }
 - return getColorSpaceType(ID);
 - }
 - static int getColorSpaceType(long profileID) {
 - byte[] theHeader;
 - int theColorSpaceSig, theColorSpace;
 - theHeader = getData(profileID, icSigHead);
 - theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
 - theColorSpace = iccCStoJCS (theColorSpaceSig);
 - return theColorSpace;
 - }
 - /**
 - * Returns the color space type of the Profile Connection Space (PCS).
 - * Returns one of the color space type constants defined by the
 - * ColorSpace class. This is the "output" color space of the
 - * profile. For an input, display, or output profile useful
 - * for tagging colors or images, this will be either TYPE_XYZ or
 - * TYPE_Lab and should be interpreted as the corresponding specific
 - * color space defined in the ICC specification. For a device
 - * link profile, this could be any of the color space type constants.
 - */
 - public int getPCSType() {
 - if (ProfileDeferralMgr.deferring) {
 - ProfileDeferralMgr.activateProfiles();
 - }
 - return getPCSType(ID);
 - }
 - static int getPCSType(long profileID) {
 - byte[] theHeader;
 - int thePCSSig, thePCS;
 - theHeader = getData(profileID, icSigHead);
 - thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
 - thePCS = iccCStoJCS(thePCSSig);
 - return thePCS;
 - }
 - /**
 - * Write this ICC_Profile to a file. Throws an IOException if the
 - * file cannot be opened for writing or if an I/O error occurs while
 - * writing the file.
 - */
 - public void write(String fileName) throws IOException {
 - FileOutputStream outputFile;
 - byte profileData[];
 - profileData = getData(); /* this will activate deferred
 - profiles if necessary */
 - outputFile = new FileOutputStream(fileName);
 - outputFile.write(profileData);
 - outputFile.close ();
 - }
 - /**
 - * Write this ICC_Profile to an OutputStream. Throws an IOException
 - * an I/O error occurs while writing the stream.
 - */
 - public void write(OutputStream s) throws IOException {
 - byte profileData[];
 - profileData = getData(); /* this will activate deferred
 - profiles if necessary */
 - s.write(profileData);
 - }
 - /**
 - * Returns a byte array corresponding to the data of this ICC_Profile.
 - */
 - public byte[] getData() {
 - int[] profileSize = new int [1];
 - byte[] profileData;
 - if (ProfileDeferralMgr.deferring) {
 - ProfileDeferralMgr.activateProfiles();
 - }
 - /* get the number of bytes needed for this profile */
 - CMM.checkStatus(CMM.cmmGetProfileSize(ID, profileSize));
 - profileData = new byte [profileSize[0]];
 - /* get the data for the profile */
 - CMM.checkStatus(CMM.cmmGetProfileData(ID, profileData));
 - return profileData;
 - }
 - /**
 - * Returns a particular tagged data element from the profile as
 - * a byte array. Elements are identified by signatures
 - * as defined in the ICC specification. The signature
 - * icSigHead can be used to get the header. This method is useful
 - * for advanced applets or applications which need to access
 - * profile data directly. Returns null if no such tag exists.
 - */
 - public byte[] getData(int tagSignature) {
 - if (ProfileDeferralMgr.deferring) {
 - ProfileDeferralMgr.activateProfiles();
 - }
 - return getData(ID, tagSignature);
 - }
 - static byte[] getData(long profileID, int tagSignature) {
 - int[] tagSize = new int [1];
 - byte[] tagData;
 - try {
 - /* get the number of bytes needed for this tag */
 - CMM.checkStatus(CMM.cmmGetTagSize(profileID, tagSignature,
 - tagSize));
 - tagData = new byte[tagSize[0]]; /* get an array for the tag */
 - /* get the tag's data */
 - CMM.checkStatus(CMM.cmmGetTagData(profileID, tagSignature,
 - tagData));
 - } catch(CMMException c) {
 - tagData = null;
 - }
 - return tagData;
 - }
 - /**
 - * Sets a particular tagged data element in the profile from
 - * a byte array. This method is useful
 - * for advanced applets or applications which need to access
 - * profile data directly.
 - */
 - public void setData(int tagSignature, byte[] tagData) {
 - if (ProfileDeferralMgr.deferring) {
 - ProfileDeferralMgr.activateProfiles();
 - }
 - CMM.checkStatus(CMM.cmmSetTagData(ID, tagSignature, tagData));
 - }
 - /**
 - * Sets the rendering intent of the profile.
 - * This is used to select the proper transform from a profile that
 - * has multiple transforms.
 - */
 - void setRenderingIntent(int renderingIntent) {
 - byte[] theHeader = getData(icSigHead);/* getData will activate deferred
 - profiles if necessary */
 - intToBigEndian (renderingIntent, theHeader, icHdrRenderingIntent);
 - /* set the rendering intent */
 - setData (icSigHead, theHeader);
 - }
 - /**
 - * Returns the rendering intent of the profile.
 - * This is used to select the proper transform from a profile that
 - * has multiple transforms. It is typically set in a source profile
 - * to select a transform from an output profile.
 - */
 - int getRenderingIntent() {
 - byte[] theHeader = getData(icSigHead);/* getData will activate deferred
 - profiles if necessary */
 - int renderingIntent = intFromBigEndian(theHeader, icHdrRenderingIntent);
 - /* set the rendering intent */
 - return renderingIntent;
 - }
 - /**
 - * Returns the number of color components in the "input" color
 - * space of this profile. For example if the color space type
 - * of this profile is TYPE_RGB, then this method will return 3.
 - */
 - public int getNumComponents() {
 - byte[] theHeader;
 - int theColorSpaceSig, theNumComponents;
 - if (deferralInfo != null) {
 - return deferralInfo.numComponents; /* Need to have this info for
 - ICC_ColorSpace without
 - causing a deferred profile
 - to be loaded */
 - }
 - theHeader = getData(icSigHead);
 - theColorSpaceSig = intFromBigEndian (theHeader, icHdrColorSpace);
 - switch (theColorSpaceSig) {
 - case icSigGrayData:
 - theNumComponents = 1;
 - break;
 - case icSigSpace2CLR:
 - theNumComponents = 2;
 - break;
 - case icSigXYZData:
 - case icSigLabData:
 - case icSigLuvData:
 - case icSigYCbCrData:
 - case icSigYxyData:
 - case icSigRgbData:
 - case icSigHsvData:
 - case icSigHlsData:
 - case icSigCmyData:
 - case icSigSpace3CLR:
 - theNumComponents = 3;
 - break;
 - case icSigCmykData:
 - case icSigSpace4CLR:
 - theNumComponents = 4;
 - break;
 - case icSigSpace5CLR:
 - theNumComponents = 5;
 - break;
 - case icSigSpace6CLR:
 - theNumComponents = 6;
 - break;
 - case icSigSpace7CLR:
 - theNumComponents = 7;
 - break;
 - case icSigSpace8CLR:
 - theNumComponents = 8;
 - break;
 - case icSigSpace9CLR:
 - theNumComponents = 9;
 - break;
 - case icSigSpaceACLR:
 - theNumComponents = 10;
 - break;
 - case icSigSpaceBCLR:
 - theNumComponents = 11;
 - break;
 - case icSigSpaceCCLR:
 - theNumComponents = 12;
 - break;
 - case icSigSpaceDCLR:
 - theNumComponents = 13;
 - break;
 - case icSigSpaceECLR:
 - theNumComponents = 14;
 - break;
 - case icSigSpaceFCLR:
 - theNumComponents = 15;
 - break;
 - default:
 - throw new ProfileDataException ("invalid ICC color space");
 - }
 - return theNumComponents;
 - }
 - /**
 - * Returns a float array of length 3 containing the X, Y, and Z
 - * components of the mediaWhitePointTag in the ICC profile.
 - */
 - float[] getMediaWhitePoint() {
 - return getXYZTag(icSigMediaWhitePointTag);
 - /* get the media white point tag */
 - }
 - /**
 - * Returns a float array of length 3 containing the X, Y, and Z
 - * components encoded in an XYZType tag.
 - */
 - float[] getXYZTag(int theTagSignature) {
 - byte[] theData;
 - float[] theXYZNumber;
 - int i1, i2, theS15Fixed16;
 - theData = getData(theTagSignature); /* get the tag data */
 - /* getData will activate deferred
 - profiles if necessary */
 - theXYZNumber = new float [3]; /* array to return */
 - /* convert s15Fixed16Number to float */
 - for (i1 = 0, i2 = icXYZNumberX; i1 < 3; i1++, i2 += 4) {
 - theS15Fixed16 = intFromBigEndian(theData, i2);
 - theXYZNumber [i1] = ((float) theS15Fixed16) / 65536.0f;
 - }
 - return theXYZNumber;
 - }
 - /**
 - * Returns a gamma value representing a tone reproduction
 - * curve (TRC). If the profile represents the TRC as a table rather
 - * than a single gamma value, then an exception is thrown. In this
 - * case the actual table can be obtained via getTRC().
 - * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
 - * icSigGreenTRCTag, or icSigBlueTRCTag.
 - * @return the gamma value as a float.
 - * @exception ProfileDataException if the profile does not specify
 - * the TRC as a single gamma value.
 - */
 - float getGamma(int theTagSignature) {
 - byte[] theTRCData;
 - float theGamma;
 - int theU8Fixed8;
 - theTRCData = getData(theTagSignature); /* get the TRC */
 - /* getData will activate deferred
 - profiles if necessary */
 - if (intFromBigEndian (theTRCData, icCurveCount) != 1) {
 - throw new ProfileDataException ("TRC is not a gamma");
 - }
 - /* convert u8Fixed8 to float */
 - theU8Fixed8 = (shortFromBigEndian(theTRCData, icCurveData)) & 0xffff;
 - theGamma = ((float) theU8Fixed8) / 256.0f;
 - return theGamma;
 - }
 - /**
 - * Returns the TRC as an array of shorts. If the profile has
 - * specified the TRC as linear (gamma = 1.0) or as a simple gamma
 - * value, this method throws an exception, and the getGamma() method
 - * should be used to get the gamma value. Otherwise the short array
 - * returned here represents a lookup table where the input Gray value
 - * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
 - * to array index 0 and value 1.0 maps to array index length-1.
 - * Interpolation may be used to generate output values for
 - * input values which do not map exactly to an index in the
 - * array. Output values also map linearly to the range [0.0, 1.0].
 - * Value 0.0 is represented by an array value of 0x0000 and
 - * value 1.0 by 0xFFFF, i.e. the values are really unsigned
 - * short values, although they are returned in a short array.
 - * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
 - * icSigGreenTRCTag, or icSigBlueTRCTag.
 - * @return a short array representing the TRC.
 - * @exception ProfileDataException if the profile does not specify
 - * the TRC as a table.
 - */
 - short[] getTRC(int theTagSignature) {
 - byte[] theTRCData;
 - short[] theTRC;
 - int i1, i2, nElements, theU8Fixed8;
 - theTRCData = getData(theTagSignature); /* get the TRC */
 - /* getData will activate deferred
 - profiles if necessary */
 - nElements = intFromBigEndian(theTRCData, icCurveCount);
 - if (nElements == 1) {
 - throw new ProfileDataException("TRC is not a table");
 - }
 - /* make the short array */
 - theTRC = new short [nElements];
 - for (i1 = 0, i2 = icCurveData; i1 < nElements; i1++, i2 += 2) {
 - theTRC[i1] = shortFromBigEndian(theTRCData, i2);
 - }
 - return theTRC;
 - }
 - /* convert an ICC color space signature into a Java color space type */
 - static int iccCStoJCS(int theColorSpaceSig) {
 - int theColorSpace;
 - switch (theColorSpaceSig) {
 - case icSigXYZData:
 - theColorSpace = ColorSpace.TYPE_XYZ;
 - break;
 - case icSigLabData:
 - theColorSpace = ColorSpace.TYPE_Lab;
 - break;
 - case icSigLuvData:
 - theColorSpace = ColorSpace.TYPE_Luv;
 - break;
 - case icSigYCbCrData:
 - theColorSpace = ColorSpace.TYPE_YCbCr;
 - break;
 - case icSigYxyData:
 - theColorSpace = ColorSpace.TYPE_Yxy;
 - break;
 - case icSigRgbData:
 - theColorSpace = ColorSpace.TYPE_RGB;
 - break;
 - case icSigGrayData:
 - theColorSpace = ColorSpace.TYPE_GRAY;
 - break;
 - case icSigHsvData:
 - theColorSpace = ColorSpace.TYPE_HSV;
 - break;
 - case icSigHlsData:
 - theColorSpace = ColorSpace.TYPE_HLS;
 - break;
 - case icSigCmykData:
 - theColorSpace = ColorSpace.TYPE_CMYK;
 - break;
 - case icSigCmyData:
 - theColorSpace = ColorSpace.TYPE_CMY;
 - break;
 - case icSigSpace2CLR:
 - theColorSpace = ColorSpace.TYPE_2CLR;
 - break;
 - case icSigSpace3CLR:
 - theColorSpace = ColorSpace.TYPE_3CLR;
 - break;
 - case icSigSpace4CLR:
 - theColorSpace = ColorSpace.TYPE_4CLR;
 - break;
 - case icSigSpace5CLR:
 - theColorSpace = ColorSpace.TYPE_5CLR;
 - break;
 - case icSigSpace6CLR:
 - theColorSpace = ColorSpace.TYPE_6CLR;
 - break;
 - case icSigSpace7CLR:
 - theColorSpace = ColorSpace.TYPE_7CLR;
 - break;
 - case icSigSpace8CLR:
 - theColorSpace = ColorSpace.TYPE_8CLR;
 - break;
 - case icSigSpace9CLR:
 - theColorSpace = ColorSpace.TYPE_9CLR;
 - break;
 - case icSigSpaceACLR:
 - theColorSpace = ColorSpace.TYPE_ACLR;
 - break;
 - case icSigSpaceBCLR:
 - theColorSpace = ColorSpace.TYPE_BCLR;
 - break;
 - case icSigSpaceCCLR:
 - theColorSpace = ColorSpace.TYPE_CCLR;
 - break;
 - case icSigSpaceDCLR:
 - theColorSpace = ColorSpace.TYPE_DCLR;
 - break;
 - case icSigSpaceECLR:
 - theColorSpace = ColorSpace.TYPE_ECLR;
 - break;
 - case icSigSpaceFCLR:
 - theColorSpace = ColorSpace.TYPE_FCLR;
 - break;
 - default:
 - throw new IllegalArgumentException ("Unknown color space");
 - }
 - return theColorSpace;
 - }
 - static int intFromBigEndian(byte[] array, int index) {
 - return (((array[index] & 0xff) << 24) |
 - ((array[index+1] & 0xff) << 16) |
 - ((array[index+2] & 0xff) << 8) |
 - (array[index+3] & 0xff));
 - }
 - static void intToBigEndian(int value, byte[] array, int index) {
 - array[index] = (byte) (value >> 24);
 - array[index+1] = (byte) (value >> 16);
 - array[index+2] = (byte) (value >> 8);
 - array[index+3] = (byte) (value);
 - }
 - static short shortFromBigEndian(byte[] array, int index) {
 - return (short) (((array[index] & 0xff) << 8) |
 - (array[index+1] & 0xff));
 - }
 - static void shortToBigEndian(short value, byte[] array, int index) {
 - array[index] = (byte) (value >> 8);
 - array[index+1] = (byte) (value);
 - }
 - /*
 - * fileName may be an absolute or a relative file specification.
 - * Relative file names are looked for in several places: first, relative
 - * to any directories specified by the java.iccprofile.path property;
 - * second, relative to any directories specified by the java.class.path
 - * property; finally, in a directory used to store profiles always
 - * available, such as a profile for sRGB. Built-in profiles use .pf as
 - * the file name extension for profiles, e.g. sRGB.pf.
 - */
 - private static FileInputStream openProfile(final String fileName) {
 - return (FileInputStream)java.security.AccessController.doPrivileged(
 - new java.security.PrivilegedAction() {
 - public Object run() {
 - return privilegedOpenProfile(fileName);
 - }
 - });
 - }
 - /*
 - * this version is called from doPrivileged in privilegedOpenProfile.
 - * the whole method is privileged!
 - */
 - private static FileInputStream privilegedOpenProfile(String fileName) {
 - FileInputStream fis = null;
 - String path, dir, fullPath;
 - try {
 - fis = new FileInputStream(fileName); /* absolute file name */
 - }
 - catch (FileNotFoundException e) {
 - }
 - if ((fis == null) &&
 - ((path = System.getProperty("java.iccprofile.path")) != null)){
 - /* try relative to java.iccprofile.path */
 - StringTokenizer st =
 - new StringTokenizer(path, File.pathSeparator);
 - while (st.hasMoreTokens() && (fis == null)) {
 - dir = st.nextToken();
 - try {
 - fullPath = dir + File.separatorChar + fileName;
 - fis = new FileInputStream(fullPath);
 - }
 - catch (FileNotFoundException e) {
 - }
 - }
 - }
 - if ((fis == null) &&
 - ((path = System.getProperty("java.class.path")) != null)) {
 - /* try relative to java.class.path */
 - StringTokenizer st =
 - new StringTokenizer(path, File.pathSeparator);
 - while (st.hasMoreTokens() && (fis == null)) {
 - dir = st.nextToken();
 - try {
 - fullPath = dir + File.separatorChar + fileName;
 - fis = new FileInputStream(fullPath);
 - }
 - catch (FileNotFoundException e) {
 - }
 - }
 - }
 - if (fis == null) { /* try the directory of built-in profiles */
 - dir = System.getProperty("java.home") +
 - File.separatorChar + "lib" + File.separatorChar + "cmm";
 - fullPath = dir + File.separatorChar + fileName;
 - try {
 - fis = new FileInputStream(fullPath);
 - }
 - catch (FileNotFoundException e) {
 - }
 - }
 - return fis;
 - }
 - /*
 - * Serialization support.
 - *
 - * Directly deserialized profiles are useless since they are not
 - * registered with CMM. We don't allow constructor to be called
 - * directly and instead have clients to call one of getInstance
 - * factory methods that will register the profile with CMM. For
 - * deserialization we implement readResolve method that will
 - * resolve the bogus deserialized profile object with one obtained
 - * with getInstance as well.
 - *
 - * There're two primary factory methods for construction of ICC
 - * profiles: getInstance(int cspace) and getInstance(byte[] data).
 - * This implementation of ICC_Profile uses the former to return a
 - * cached singleton profile object, other implementations will
 - * likely use this technique too. To preserve the singleton
 - * pattern across serialization we serialize cached singleton
 - * profiles in such a way that deserializing VM could call
 - * getInstance(int cspace) method that will resolve deserialized
 - * object into the corresponding singleton as well.
 - *
 - * Since the singletons are private to ICC_Profile the readResolve
 - * method have to be `protected' instead of `private' so that
 - * singletons that are instances of subclasses of ICC_Profile
 - * could be correctly deserialized.
 - */
 - /**
 - * Version of the format of additional serialized data in the
 - * stream. Version <code>1</code> corresponds to Java 2
 - * Platform, v1.3.
 - * @since 1.3
 - * @serial
 - */
 - private int iccProfileSerializedDataVersion = 1;
 - /**
 - * Writes default serializable fields to the stream. Writes a
 - * string and an array of bytes to the stream as additional data.
 - *
 - * @param s stream used for serialization.
 - * @throws IOException
 - * thrown by <code>ObjectInputStream</code>.
 - * @serialData
 - * The <code>String</code> is the name of one of
 - * <code>CS_<var>*</var></code> constants defined in the
 - * {@link ColorSpace} class if the profile object is a profile
 - * for a predefined color space (for example
 - * <code>"CS_sRGB"</code>). The string is <code>null</code>
 - * otherwise.
 - * <p>
 - * The <code>byte[]</code> array is the profile data for the
 - * profile. For predefined color spaces <code>null</code> is
 - * written instead of the profile data. If in the future
 - * versions of Java API new predefined color spaces will be
 - * added, future versions of this class may choose to write
 - * for new predefined color spaces not only the color space
 - * name, but the profile data as well so that older versions
 - * could still deserialize the object.
 - */
 - private void writeObject(ObjectOutputStream s)
 - throws IOException
 - {
 - s.defaultWriteObject();
 - String csName = null;
 - if (this == sRGBprofile) {
 - csName = "CS_sRGB";
 - } else if (this == XYZprofile) {
 - csName = "CS_CIEXYZ";
 - } else if (this == PYCCprofile) {
 - csName = "CS_PYCC";
 - } else if (this == GRAYprofile) {
 - csName = "CS_GRAY";
 - } else if (this == LINEAR_RGBprofile) {
 - csName = "CS_LINEAR_RGB";
 - }
 - // Future versions may choose to write profile data for new
 - // predefined color spaces as well, if any will be introduced,
 - // so that old versions that don't recognize the new CS name
 - // may fall back to constructing profile from the data.
 - byte[] data = null;
 - if (csName == null) {
 - // getData will activate deferred profile if necessary
 - data = getData();
 - }
 - s.writeObject(csName);
 - s.writeObject(data);
 - }
 - // Temporary storage used by readObject to store resolved profile
 - // (obtained with getInstance) for readResolve to return.
 - private transient ICC_Profile resolvedDeserializedProfile;
 - /**
 - * Reads default serializable fields from the stream. Reads from
 - * the stream a string and an array of bytes as additional data.
 - *
 - * @param s stream used for deserialization.
 - * @throws IOException
 - * thrown by <code>ObjectInputStream</code>.
 - * @throws ClassNotFoundException
 - * thrown by <code>ObjectInputStream</code>.
 - * @serialData
 - * The <code>String</code> is the name of one of
 - * <code>CS_<var>*</var></code> constants defined in the
 - * {@link ColorSpace} class if the profile object is a profile
 - * for a predefined color space (for example
 - * <code>"CS_sRGB"</code>). The string is <code>null</code>
 - * otherwise.
 - * <p>
 - * The <code>byte[]</code> array is the profile data for the
 - * profile. It will usually be <code>null</code> for the
 - * predefined profiles.
 - * <p>
 - * If the string is recognized as a constant name for
 - * predefined color space the object will be resolved into
 - * profile obtained with
 - * <code>getInstance(int cspace)</code> and the profile
 - * data are ignored. Otherwise the object will be resolved
 - * into profile obtained with
 - * <code>getInstance(byte[] data)</code>.
 - * @see #readResolve()
 - * @see #getInstance(int)
 - * @see #getInstance(byte[])
 - */
 - private void readObject(ObjectInputStream s)
 - throws IOException, ClassNotFoundException
 - {
 - s.defaultReadObject();
 - String csName = (String)s.readObject();
 - byte[] data = (byte[])s.readObject();
 - int cspace = 0; // ColorSpace.CS_* constant if known
 - boolean isKnownPredefinedCS = false;
 - if (csName != null) {
 - isKnownPredefinedCS = true;
 - if (csName.equals("CS_sRGB")) {
 - cspace = ColorSpace.CS_sRGB;
 - } else if (csName.equals("CS_CIEXYZ")) {
 - cspace = ColorSpace.CS_CIEXYZ;
 - } else if (csName.equals("CS_PYCC")) {
 - cspace = ColorSpace.CS_PYCC;
 - } else if (csName.equals("CS_GRAY")) {
 - cspace = ColorSpace.CS_GRAY;
 - } else if (csName.equals("CS_LINEAR_RGB")) {
 - cspace = ColorSpace.CS_LINEAR_RGB;
 - } else {
 - isKnownPredefinedCS = false;
 - }
 - }
 - if (isKnownPredefinedCS) {
 - resolvedDeserializedProfile = getInstance(cspace);
 - } else {
 - resolvedDeserializedProfile = getInstance(data);
 - }
 - }
 - /**
 - * Resolves instances being deserialized into instances registered
 - * with CMM.
 - * @return ICC_Profile object for profile registered with CMM.
 - * @throws ObjectStreamException
 - * never thrown, but mandated by the serialization spec.
 - */
 - protected Object readResolve() throws ObjectStreamException {
 - return resolvedDeserializedProfile;
 - }
 - }