Save This Page
Home » openjdk-7 » java » awt » color » [javadoc | source]
    1   /*
    2    * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /**********************************************************************
   27    **********************************************************************
   28    **********************************************************************
   29    *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
   30    *** As  an unpublished  work pursuant to Title 17 of the United    ***
   31    *** States Code.  All rights reserved.                             ***
   32    **********************************************************************
   33    **********************************************************************
   34    **********************************************************************/
   35   
   36   package java.awt.color;
   37   
   38   import sun.java2d.cmm.ColorTransform;
   39   import sun.java2d.cmm.CMSManager;
   40   import sun.java2d.cmm.PCMM;
   41   
   42   
   43   /**
   44    *
   45    * The ICC_ColorSpace class is an implementation of the abstract
   46    * ColorSpace class.  This representation of
   47    * device independent and device dependent color spaces is based on the
   48    * International Color Consortium Specification ICC.1:2001-12, File Format for
   49    * Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
   50    * <p>
   51    * Typically, a Color or ColorModel would be associated with an ICC
   52    * Profile which is either an input, display, or output profile (see
   53    * the ICC specification).  There are other types of ICC Profiles, e.g.
   54    * abstract profiles, device link profiles, and named color profiles,
   55    * which do not contain information appropriate for representing the color
   56    * space of a color, image, or device (see ICC_Profile).
   57    * Attempting to create an ICC_ColorSpace object from an inappropriate ICC
   58    * Profile is an error.
   59    * <p>
   60    * ICC Profiles represent transformations from the color space of
   61    * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
   62    * Profiles of interest for tagging images or colors have a
   63    * PCS which is one of the device independent
   64    * spaces (one CIEXYZ space and two CIELab spaces) defined in the
   65    * ICC Profile Format Specification.  Most profiles of interest
   66    * either have invertible transformations or explicitly specify
   67    * transformations going both directions.  Should an ICC_ColorSpace
   68    * object be used in a way requiring a conversion from PCS to
   69    * the profile's native space and there is inadequate data to
   70    * correctly perform the conversion, the ICC_ColorSpace object will
   71    * produce output in the specified type of color space (e.g. TYPE_RGB,
   72    * TYPE_CMYK, etc.), but the specific color values of the output data
   73    * will be undefined.
   74    * <p>
   75    * The details of this class are not important for simple applets,
   76    * which draw in a default color space or manipulate and display
   77    * imported images with a known color space.  At most, such applets
   78    * would need to get one of the default color spaces via
   79    * ColorSpace.getInstance().
   80    * <p>
   81    * @see ColorSpace
   82    * @see ICC_Profile
   83    */
   84   
   85   
   86   
   87   public class ICC_ColorSpace extends ColorSpace {
   88   
   89       static final long serialVersionUID = 3455889114070431483L;
   90   
   91       private ICC_Profile    thisProfile;
   92       private float[] minVal;
   93       private float[] maxVal;
   94       private float[] diffMinMax;
   95       private float[] invDiffMinMax;
   96       private boolean needScaleInit = true;
   97   
   98       // {to,from}{RGB,CIEXYZ} methods create and cache these when needed
   99       private transient ColorTransform this2srgb;
  100       private transient ColorTransform srgb2this;
  101       private transient ColorTransform this2xyz;
  102       private transient ColorTransform xyz2this;
  103   
  104   
  105       /**
  106       * Constructs a new ICC_ColorSpace from an ICC_Profile object.
  107       * @param profile the specified ICC_Profile object
  108       * @exception IllegalArgumentException if profile is inappropriate for
  109       *            representing a ColorSpace.
  110       */
  111       public ICC_ColorSpace (ICC_Profile profile) {
  112           super (profile.getColorSpaceType(), profile.getNumComponents());
  113   
  114           int profileClass = profile.getProfileClass();
  115   
  116           /* REMIND - is NAMEDCOLOR OK? */
  117           if ((profileClass != ICC_Profile.CLASS_INPUT) &&
  118               (profileClass != ICC_Profile.CLASS_DISPLAY) &&
  119               (profileClass != ICC_Profile.CLASS_OUTPUT) &&
  120               (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
  121               (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
  122               (profileClass != ICC_Profile.CLASS_ABSTRACT)) {
  123               throw new IllegalArgumentException("Invalid profile type");
  124           }
  125   
  126           thisProfile = profile;
  127           setMinMax();
  128       }
  129   
  130       /**
  131       * Returns the ICC_Profile for this ICC_ColorSpace.
  132       * @return the ICC_Profile for this ICC_ColorSpace.
  133       */
  134       public ICC_Profile getProfile() {
  135           return thisProfile;
  136       }
  137   
  138       /**
  139        * Transforms a color value assumed to be in this ColorSpace
  140        * into a value in the default CS_sRGB color space.
  141        * <p>
  142        * This method transforms color values using algorithms designed
  143        * to produce the best perceptual match between input and output
  144        * colors.  In order to do colorimetric conversion of color values,
  145        * you should use the <code>toCIEXYZ</code>
  146        * method of this color space to first convert from the input
  147        * color space to the CS_CIEXYZ color space, and then use the
  148        * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
  149        * convert from CS_CIEXYZ to the output color space.
  150        * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
  151        * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
  152        * <p>
  153        * @param colorvalue a float array with length of at least the number
  154        *      of components in this ColorSpace.
  155        * @return a float array of length 3.
  156        * @throws ArrayIndexOutOfBoundsException if array length is not
  157        * at least the number of components in this ColorSpace.
  158        */
  159       public float[]    toRGB (float[] colorvalue) {
  160   
  161           if (this2srgb == null) {
  162               ColorTransform[] transformList = new ColorTransform [2];
  163               ICC_ColorSpace srgbCS =
  164                   (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  165               PCMM mdl = CMSManager.getModule();
  166               transformList[0] = mdl.createTransform(
  167                   thisProfile, ColorTransform.Any, ColorTransform.In);
  168               transformList[1] = mdl.createTransform(
  169                   srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
  170               this2srgb = mdl.createTransform(transformList);
  171               if (needScaleInit) {
  172                   setComponentScaling();
  173               }
  174           }
  175   
  176           int nc = this.getNumComponents();
  177           short tmp[] = new short[nc];
  178           for (int i = 0; i < nc; i++) {
  179               tmp[i] = (short)
  180                   ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
  181           }
  182           tmp = this2srgb.colorConvert(tmp, null);
  183           float[] result = new float [3];
  184           for (int i = 0; i < 3; i++) {
  185               result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
  186           }
  187           return result;
  188       }
  189   
  190       /**
  191        * Transforms a color value assumed to be in the default CS_sRGB
  192        * color space into this ColorSpace.
  193        * <p>
  194        * This method transforms color values using algorithms designed
  195        * to produce the best perceptual match between input and output
  196        * colors.  In order to do colorimetric conversion of color values,
  197        * you should use the <code>toCIEXYZ</code>
  198        * method of the CS_sRGB color space to first convert from the input
  199        * color space to the CS_CIEXYZ color space, and then use the
  200        * <code>fromCIEXYZ</code> method of this color space to
  201        * convert from CS_CIEXYZ to the output color space.
  202        * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
  203        * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
  204        * <p>
  205        * @param rgbvalue a float array with length of at least 3.
  206        * @return a float array with length equal to the number of
  207        *       components in this ColorSpace.
  208        * @throws ArrayIndexOutOfBoundsException if array length is not
  209        * at least 3.
  210        */
  211       public float[]    fromRGB(float[] rgbvalue) {
  212   
  213           if (srgb2this == null) {
  214               ColorTransform[] transformList = new ColorTransform [2];
  215               ICC_ColorSpace srgbCS =
  216                   (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  217               PCMM mdl = CMSManager.getModule();
  218               transformList[0] = mdl.createTransform(
  219                   srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
  220               transformList[1] = mdl.createTransform(
  221                   thisProfile, ColorTransform.Any, ColorTransform.Out);
  222               srgb2this = mdl.createTransform(transformList);
  223               if (needScaleInit) {
  224                   setComponentScaling();
  225               }
  226           }
  227   
  228           short tmp[] = new short[3];
  229           for (int i = 0; i < 3; i++) {
  230               tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
  231           }
  232           tmp = srgb2this.colorConvert(tmp, null);
  233           int nc = this.getNumComponents();
  234           float[] result = new float [nc];
  235           for (int i = 0; i < nc; i++) {
  236               result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
  237                           diffMinMax[i] + minVal[i];
  238           }
  239           return result;
  240       }
  241   
  242   
  243       /**
  244        * Transforms a color value assumed to be in this ColorSpace
  245        * into the CS_CIEXYZ conversion color space.
  246        * <p>
  247        * This method transforms color values using relative colorimetry,
  248        * as defined by the ICC Specification.  This
  249        * means that the XYZ values returned by this method are represented
  250        * relative to the D50 white point of the CS_CIEXYZ color space.
  251        * This representation is useful in a two-step color conversion
  252        * process in which colors are transformed from an input color
  253        * space to CS_CIEXYZ and then to an output color space.  This
  254        * representation is not the same as the XYZ values that would
  255        * be measured from the given color value by a colorimeter.
  256        * A further transformation is necessary to compute the XYZ values
  257        * that would be measured using current CIE recommended practices.
  258        * The paragraphs below explain this in more detail.
  259        * <p>
  260        * The ICC standard uses a device independent color space (DICS) as the
  261        * mechanism for converting color from one device to another device.  In
  262        * this architecture, colors are converted from the source device's color
  263        * space to the ICC DICS and then from the ICC DICS to the destination
  264        * device's color space.  The ICC standard defines device profiles which
  265        * contain transforms which will convert between a device's color space
  266        * and the ICC DICS.  The overall conversion of colors from a source
  267        * device to colors of a destination device is done by connecting the
  268        * device-to-DICS transform of the profile for the source device to the
  269        * DICS-to-device transform of the profile for the destination device.
  270        * For this reason, the ICC DICS is commonly referred to as the profile
  271        * connection space (PCS).  The color space used in the methods
  272        * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
  273        * Specification.  This is also the color space represented by
  274        * ColorSpace.CS_CIEXYZ.
  275        * <p>
  276        * The XYZ values of a color are often represented as relative to some
  277        * white point, so the actual meaning of the XYZ values cannot be known
  278        * without knowing the white point of those values.  This is known as
  279        * relative colorimetry.  The PCS uses a white point of D50, so the XYZ
  280        * values of the PCS are relative to D50.  For example, white in the PCS
  281        * will have the XYZ values of D50, which is defined to be X=.9642,
  282        * Y=1.000, and Z=0.8249.  This white point is commonly used for graphic
  283        * arts applications, but others are often used in other applications.
  284        * <p>
  285        * To quantify the color characteristics of a device such as a printer
  286        * or monitor, measurements of XYZ values for particular device colors
  287        * are typically made.  For purposes of this discussion, the term
  288        * device XYZ values is used to mean the XYZ values that would be
  289        * measured from device colors using current CIE recommended practices.
  290        * <p>
  291        * Converting between device XYZ values and the PCS XYZ values returned
  292        * by this method corresponds to converting between the device's color
  293        * space, as represented by CIE colorimetric values, and the PCS.  There
  294        * are many factors involved in this process, some of which are quite
  295        * subtle.  The most important, however, is the adjustment made to account
  296        * for differences between the device's white point and the white point of
  297        * the PCS.  There are many techniques for doing this and it is the
  298        * subject of much current research and controversy.  Some commonly used
  299        * methods are XYZ scaling, the von Kries transform, and the Bradford
  300        * transform.  The proper method to use depends upon each particular
  301        * application.
  302        * <p>
  303        * The simplest method is XYZ scaling.  In this method each device XYZ
  304        * value is  converted to a PCS XYZ value by multiplying it by the ratio
  305        * of the PCS white point (D50) to the device white point.
  306        * <pre>
  307        *
  308        * Xd, Yd, Zd are the device XYZ values
  309        * Xdw, Ydw, Zdw are the device XYZ white point values
  310        * Xp, Yp, Zp are the PCS XYZ values
  311        * Xd50, Yd50, Zd50 are the PCS XYZ white point values
  312        *
  313        * Xp = Xd * (Xd50 / Xdw)
  314        * Yp = Yd * (Yd50 / Ydw)
  315        * Zp = Zd * (Zd50 / Zdw)
  316        *
  317        * </pre>
  318        * <p>
  319        * Conversion from the PCS to the device would be done by inverting these
  320        * equations:
  321        * <pre>
  322        *
  323        * Xd = Xp * (Xdw / Xd50)
  324        * Yd = Yp * (Ydw / Yd50)
  325        * Zd = Zp * (Zdw / Zd50)
  326        *
  327        * </pre>
  328        * <p>
  329        * Note that the media white point tag in an ICC profile is not the same
  330        * as the device white point.  The media white point tag is expressed in
  331        * PCS values and is used to represent the difference between the XYZ of
  332        * device illuminant and the XYZ of the device media when measured under
  333        * that illuminant.  The device white point is expressed as the device
  334        * XYZ values corresponding to white displayed on the device.  For
  335        * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
  336        * will result in a measured device XYZ value of D65.  This will not
  337        * be the same as the media white point tag XYZ value in the ICC
  338        * profile for an sRGB device.
  339        * <p>
  340        * @param colorvalue a float array with length of at least the number
  341        *        of components in this ColorSpace.
  342        * @return a float array of length 3.
  343        * @throws ArrayIndexOutOfBoundsException if array length is not
  344        * at least the number of components in this ColorSpace.
  345        */
  346       public float[]    toCIEXYZ(float[] colorvalue) {
  347   
  348           if (this2xyz == null) {
  349               ColorTransform[] transformList = new ColorTransform [2];
  350               ICC_ColorSpace xyzCS =
  351                   (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  352               PCMM mdl = CMSManager.getModule();
  353               try {
  354                   transformList[0] = mdl.createTransform(
  355                       thisProfile, ICC_Profile.icRelativeColorimetric,
  356                       ColorTransform.In);
  357               } catch (CMMException e) {
  358                   transformList[0] = mdl.createTransform(
  359                       thisProfile, ColorTransform.Any, ColorTransform.In);
  360               }
  361               transformList[1] = mdl.createTransform(
  362                   xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
  363               this2xyz = mdl.createTransform (transformList);
  364               if (needScaleInit) {
  365                   setComponentScaling();
  366               }
  367           }
  368   
  369           int nc = this.getNumComponents();
  370           short tmp[] = new short[nc];
  371           for (int i = 0; i < nc; i++) {
  372               tmp[i] = (short)
  373                   ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
  374           }
  375           tmp = this2xyz.colorConvert(tmp, null);
  376           float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
  377           // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
  378           float[] result = new float [3];
  379           for (int i = 0; i < 3; i++) {
  380               result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
  381           }
  382           return result;
  383       }
  384   
  385   
  386       /**
  387        * Transforms a color value assumed to be in the CS_CIEXYZ conversion
  388        * color space into this ColorSpace.
  389        * <p>
  390        * This method transforms color values using relative colorimetry,
  391        * as defined by the ICC Specification.  This
  392        * means that the XYZ argument values taken by this method are represented
  393        * relative to the D50 white point of the CS_CIEXYZ color space.
  394        * This representation is useful in a two-step color conversion
  395        * process in which colors are transformed from an input color
  396        * space to CS_CIEXYZ and then to an output color space.  The color
  397        * values returned by this method are not those that would produce
  398        * the XYZ value passed to the method when measured by a colorimeter.
  399        * If you have XYZ values corresponding to measurements made using
  400        * current CIE recommended practices, they must be converted to D50
  401        * relative values before being passed to this method.
  402        * The paragraphs below explain this in more detail.
  403        * <p>
  404        * The ICC standard uses a device independent color space (DICS) as the
  405        * mechanism for converting color from one device to another device.  In
  406        * this architecture, colors are converted from the source device's color
  407        * space to the ICC DICS and then from the ICC DICS to the destination
  408        * device's color space.  The ICC standard defines device profiles which
  409        * contain transforms which will convert between a device's color space
  410        * and the ICC DICS.  The overall conversion of colors from a source
  411        * device to colors of a destination device is done by connecting the
  412        * device-to-DICS transform of the profile for the source device to the
  413        * DICS-to-device transform of the profile for the destination device.
  414        * For this reason, the ICC DICS is commonly referred to as the profile
  415        * connection space (PCS).  The color space used in the methods
  416        * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
  417        * Specification.  This is also the color space represented by
  418        * ColorSpace.CS_CIEXYZ.
  419        * <p>
  420        * The XYZ values of a color are often represented as relative to some
  421        * white point, so the actual meaning of the XYZ values cannot be known
  422        * without knowing the white point of those values.  This is known as
  423        * relative colorimetry.  The PCS uses a white point of D50, so the XYZ
  424        * values of the PCS are relative to D50.  For example, white in the PCS
  425        * will have the XYZ values of D50, which is defined to be X=.9642,
  426        * Y=1.000, and Z=0.8249.  This white point is commonly used for graphic
  427        * arts applications, but others are often used in other applications.
  428        * <p>
  429        * To quantify the color characteristics of a device such as a printer
  430        * or monitor, measurements of XYZ values for particular device colors
  431        * are typically made.  For purposes of this discussion, the term
  432        * device XYZ values is used to mean the XYZ values that would be
  433        * measured from device colors using current CIE recommended practices.
  434        * <p>
  435        * Converting between device XYZ values and the PCS XYZ values taken as
  436        * arguments by this method corresponds to converting between the device's
  437        * color space, as represented by CIE colorimetric values, and the PCS.
  438        * There are many factors involved in this process, some of which are quite
  439        * subtle.  The most important, however, is the adjustment made to account
  440        * for differences between the device's white point and the white point of
  441        * the PCS.  There are many techniques for doing this and it is the
  442        * subject of much current research and controversy.  Some commonly used
  443        * methods are XYZ scaling, the von Kries transform, and the Bradford
  444        * transform.  The proper method to use depends upon each particular
  445        * application.
  446        * <p>
  447        * The simplest method is XYZ scaling.  In this method each device XYZ
  448        * value is  converted to a PCS XYZ value by multiplying it by the ratio
  449        * of the PCS white point (D50) to the device white point.
  450        * <pre>
  451        *
  452        * Xd, Yd, Zd are the device XYZ values
  453        * Xdw, Ydw, Zdw are the device XYZ white point values
  454        * Xp, Yp, Zp are the PCS XYZ values
  455        * Xd50, Yd50, Zd50 are the PCS XYZ white point values
  456        *
  457        * Xp = Xd * (Xd50 / Xdw)
  458        * Yp = Yd * (Yd50 / Ydw)
  459        * Zp = Zd * (Zd50 / Zdw)
  460        *
  461        * </pre>
  462        * <p>
  463        * Conversion from the PCS to the device would be done by inverting these
  464        * equations:
  465        * <pre>
  466        *
  467        * Xd = Xp * (Xdw / Xd50)
  468        * Yd = Yp * (Ydw / Yd50)
  469        * Zd = Zp * (Zdw / Zd50)
  470        *
  471        * </pre>
  472        * <p>
  473        * Note that the media white point tag in an ICC profile is not the same
  474        * as the device white point.  The media white point tag is expressed in
  475        * PCS values and is used to represent the difference between the XYZ of
  476        * device illuminant and the XYZ of the device media when measured under
  477        * that illuminant.  The device white point is expressed as the device
  478        * XYZ values corresponding to white displayed on the device.  For
  479        * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
  480        * will result in a measured device XYZ value of D65.  This will not
  481        * be the same as the media white point tag XYZ value in the ICC
  482        * profile for an sRGB device.
  483        * <p>
  484        * <p>
  485        * @param colorvalue a float array with length of at least 3.
  486        * @return a float array with length equal to the number of
  487        *         components in this ColorSpace.
  488        * @throws ArrayIndexOutOfBoundsException if array length is not
  489        * at least 3.
  490        */
  491       public float[]    fromCIEXYZ(float[] colorvalue) {
  492   
  493           if (xyz2this == null) {
  494               ColorTransform[] transformList = new ColorTransform [2];
  495               ICC_ColorSpace xyzCS =
  496                   (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  497               PCMM mdl = CMSManager.getModule();
  498               transformList[0] = mdl.createTransform (
  499                   xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
  500               try {
  501                   transformList[1] = mdl.createTransform(
  502                       thisProfile, ICC_Profile.icRelativeColorimetric,
  503                       ColorTransform.Out);
  504               } catch (CMMException e) {
  505                   transformList[1] = CMSManager.getModule().createTransform(
  506                   thisProfile, ColorTransform.Any, ColorTransform.Out);
  507               }
  508               xyz2this = mdl.createTransform(transformList);
  509               if (needScaleInit) {
  510                   setComponentScaling();
  511               }
  512           }
  513   
  514           short tmp[] = new short[3];
  515           float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
  516           float factor = 65535.0f / ALMOST_TWO;
  517           // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
  518           for (int i = 0; i < 3; i++) {
  519               tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
  520           }
  521           tmp = xyz2this.colorConvert(tmp, null);
  522           int nc = this.getNumComponents();
  523           float[] result = new float [nc];
  524           for (int i = 0; i < nc; i++) {
  525               result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
  526                           diffMinMax[i] + minVal[i];
  527           }
  528           return result;
  529       }
  530   
  531       /**
  532        * Returns the minimum normalized color component value for the
  533        * specified component.  For TYPE_XYZ spaces, this method returns
  534        * minimum values of 0.0 for all components.  For TYPE_Lab spaces,
  535        * this method returns 0.0 for L and -128.0 for a and b components.
  536        * This is consistent with the encoding of the XYZ and Lab Profile
  537        * Connection Spaces in the ICC specification.  For all other types, this
  538        * method returns 0.0 for all components.  When using an ICC_ColorSpace
  539        * with a profile that requires different minimum component values,
  540        * it is necessary to subclass this class and override this method.
  541        * @param component The component index.
  542        * @return The minimum normalized component value.
  543        * @throws IllegalArgumentException if component is less than 0 or
  544        *         greater than numComponents - 1.
  545        * @since 1.4
  546        */
  547       public float getMinValue(int component) {
  548           if ((component < 0) || (component > this.getNumComponents() - 1)) {
  549               throw new IllegalArgumentException(
  550                   "Component index out of range: + component");
  551           }
  552           return minVal[component];
  553       }
  554   
  555       /**
  556        * Returns the maximum normalized color component value for the
  557        * specified component.  For TYPE_XYZ spaces, this method returns
  558        * maximum values of 1.0 + (32767.0 / 32768.0) for all components.
  559        * For TYPE_Lab spaces,
  560        * this method returns 100.0 for L and 127.0 for a and b components.
  561        * This is consistent with the encoding of the XYZ and Lab Profile
  562        * Connection Spaces in the ICC specification.  For all other types, this
  563        * method returns 1.0 for all components.  When using an ICC_ColorSpace
  564        * with a profile that requires different maximum component values,
  565        * it is necessary to subclass this class and override this method.
  566        * @param component The component index.
  567        * @return The maximum normalized component value.
  568        * @throws IllegalArgumentException if component is less than 0 or
  569        *         greater than numComponents - 1.
  570        * @since 1.4
  571        */
  572       public float getMaxValue(int component) {
  573           if ((component < 0) || (component > this.getNumComponents() - 1)) {
  574               throw new IllegalArgumentException(
  575                   "Component index out of range: + component");
  576           }
  577           return maxVal[component];
  578       }
  579   
  580       private void setMinMax() {
  581           int nc = this.getNumComponents();
  582           int type = this.getType();
  583           minVal = new float[nc];
  584           maxVal = new float[nc];
  585           if (type == ColorSpace.TYPE_Lab) {
  586               minVal[0] = 0.0f;    // L
  587               maxVal[0] = 100.0f;
  588               minVal[1] = -128.0f; // a
  589               maxVal[1] = 127.0f;
  590               minVal[2] = -128.0f; // b
  591               maxVal[2] = 127.0f;
  592           } else if (type == ColorSpace.TYPE_XYZ) {
  593               minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
  594               maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
  595           } else {
  596               for (int i = 0; i < nc; i++) {
  597                   minVal[i] = 0.0f;
  598                   maxVal[i] = 1.0f;
  599               }
  600           }
  601       }
  602   
  603       private void setComponentScaling() {
  604           int nc = this.getNumComponents();
  605           diffMinMax = new float[nc];
  606           invDiffMinMax = new float[nc];
  607           for (int i = 0; i < nc; i++) {
  608               minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
  609               maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
  610               diffMinMax[i] = maxVal[i] - minVal[i];
  611               invDiffMinMax[i] = 65535.0f / diffMinMax[i];
  612           }
  613           needScaleInit = false;
  614       }
  615   
  616   }

Save This Page
Home » openjdk-7 » java » awt » color » [javadoc | source]