📄 icc_profile.java
字号:
* 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -