Save This Page
Home » openjdk-7 » java » awt » color » [javadoc | source]
    1   /*
    2    * Portions Copyright 1997-2006 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.PCMM;
   39   import sun.java2d.cmm.CMSManager;
   40   import sun.java2d.cmm.ProfileDeferralMgr;
   41   import sun.java2d.cmm.ProfileDeferralInfo;
   42   import sun.java2d.cmm.ProfileActivator;
   43   
   44   import java.io.File;
   45   import java.io.FileInputStream;
   46   import java.io.FileNotFoundException;
   47   import java.io.FileOutputStream;
   48   import java.io.IOException;
   49   import java.io.InputStream;
   50   import java.io.ObjectInputStream;
   51   import java.io.ObjectOutputStream;
   52   import java.io.ObjectStreamException;
   53   import java.io.OutputStream;
   54   import java.io.Serializable;
   55   
   56   import java.util.StringTokenizer;
   57   
   58   import java.security.AccessController;
   59   import java.security.PrivilegedAction;
   60   
   61   /**
   62    * A representation of color profile data for device independent and
   63    * device dependent color spaces based on the International Color
   64    * Consortium Specification ICC.1:2001-12, File Format for Color Profiles,
   65    * (see <A href="http://www.color.org"> http://www.color.org</A>).
   66    * <p>
   67    * An ICC_ColorSpace object can be constructed from an appropriate
   68    * ICC_Profile.
   69    * Typically, an ICC_ColorSpace would be associated with an ICC
   70    * Profile which is either an input, display, or output profile (see
   71    * the ICC specification).  There are also device link, abstract,
   72    * color space conversion, and named color profiles.  These are less
   73    * useful for tagging a color or image, but are useful for other
   74    * purposes (in particular device link profiles can provide improved
   75    * performance for converting from one device's color space to
   76    * another's).
   77    * <p>
   78    * ICC Profiles represent transformations from the color space of
   79    * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
   80    * Profiles of interest for tagging images or colors have a PCS
   81    * which is one of the two specific device independent
   82    * spaces (one CIEXYZ space and one CIELab space) defined in the
   83    * ICC Profile Format Specification.  Most profiles of interest
   84    * either have invertible transformations or explicitly specify
   85    * transformations going both directions.
   86    * <p>
   87    * @see ICC_ColorSpace
   88    */
   89   
   90   
   91   public class ICC_Profile implements Serializable {
   92   
   93       private static final long serialVersionUID = -3938515861990936766L;
   94   
   95       transient long ID;
   96   
   97       private transient ProfileDeferralInfo deferralInfo;
   98       private transient ProfileActivator profileActivator;
   99   
  100       // Registry of singleton profile objects for specific color spaces
  101       // defined in the ColorSpace class (e.g. CS_sRGB), see
  102       // getInstance(int cspace) factory method.
  103       private static ICC_Profile sRGBprofile;
  104       private static ICC_Profile XYZprofile;
  105       private static ICC_Profile PYCCprofile;
  106       private static ICC_Profile GRAYprofile;
  107       private static ICC_Profile LINEAR_RGBprofile;
  108   
  109   
  110       /**
  111        * Profile class is input.
  112        */
  113       public static final int CLASS_INPUT = 0;
  114   
  115       /**
  116        * Profile class is display.
  117        */
  118       public static final int CLASS_DISPLAY = 1;
  119   
  120       /**
  121        * Profile class is output.
  122        */
  123       public static final int CLASS_OUTPUT = 2;
  124   
  125       /**
  126        * Profile class is device link.
  127        */
  128       public static final int CLASS_DEVICELINK = 3;
  129   
  130       /**
  131        * Profile class is color space conversion.
  132        */
  133       public static final int CLASS_COLORSPACECONVERSION = 4;
  134   
  135       /**
  136        * Profile class is abstract.
  137        */
  138       public static final int CLASS_ABSTRACT = 5;
  139   
  140       /**
  141        * Profile class is named color.
  142        */
  143       public static final int CLASS_NAMEDCOLOR = 6;
  144   
  145   
  146       /**
  147        * ICC Profile Color Space Type Signature: 'XYZ '.
  148        */
  149       public static final int icSigXYZData        = 0x58595A20;    /* 'XYZ ' */
  150   
  151       /**
  152        * ICC Profile Color Space Type Signature: 'Lab '.
  153        */
  154       public static final int icSigLabData        = 0x4C616220;    /* 'Lab ' */
  155   
  156       /**
  157        * ICC Profile Color Space Type Signature: 'Luv '.
  158        */
  159       public static final int icSigLuvData        = 0x4C757620;    /* 'Luv ' */
  160   
  161       /**
  162        * ICC Profile Color Space Type Signature: 'YCbr'.
  163        */
  164       public static final int icSigYCbCrData        = 0x59436272;    /* 'YCbr' */
  165   
  166       /**
  167        * ICC Profile Color Space Type Signature: 'Yxy '.
  168        */
  169       public static final int icSigYxyData        = 0x59787920;    /* 'Yxy ' */
  170   
  171       /**
  172        * ICC Profile Color Space Type Signature: 'RGB '.
  173        */
  174       public static final int icSigRgbData        = 0x52474220;    /* 'RGB ' */
  175   
  176       /**
  177        * ICC Profile Color Space Type Signature: 'GRAY'.
  178        */
  179       public static final int icSigGrayData        = 0x47524159;    /* 'GRAY' */
  180   
  181       /**
  182        * ICC Profile Color Space Type Signature: 'HSV'.
  183        */
  184       public static final int icSigHsvData        = 0x48535620;    /* 'HSV ' */
  185   
  186       /**
  187        * ICC Profile Color Space Type Signature: 'HLS'.
  188        */
  189       public static final int icSigHlsData        = 0x484C5320;    /* 'HLS ' */
  190   
  191       /**
  192        * ICC Profile Color Space Type Signature: 'CMYK'.
  193        */
  194       public static final int icSigCmykData        = 0x434D594B;    /* 'CMYK' */
  195   
  196       /**
  197        * ICC Profile Color Space Type Signature: 'CMY '.
  198        */
  199       public static final int icSigCmyData        = 0x434D5920;    /* 'CMY ' */
  200   
  201       /**
  202        * ICC Profile Color Space Type Signature: '2CLR'.
  203        */
  204       public static final int icSigSpace2CLR        = 0x32434C52;    /* '2CLR' */
  205   
  206       /**
  207        * ICC Profile Color Space Type Signature: '3CLR'.
  208        */
  209       public static final int icSigSpace3CLR        = 0x33434C52;    /* '3CLR' */
  210   
  211       /**
  212        * ICC Profile Color Space Type Signature: '4CLR'.
  213        */
  214       public static final int icSigSpace4CLR        = 0x34434C52;    /* '4CLR' */
  215   
  216       /**
  217        * ICC Profile Color Space Type Signature: '5CLR'.
  218        */
  219       public static final int icSigSpace5CLR        = 0x35434C52;    /* '5CLR' */
  220   
  221       /**
  222        * ICC Profile Color Space Type Signature: '6CLR'.
  223        */
  224       public static final int icSigSpace6CLR        = 0x36434C52;    /* '6CLR' */
  225   
  226       /**
  227        * ICC Profile Color Space Type Signature: '7CLR'.
  228        */
  229       public static final int icSigSpace7CLR        = 0x37434C52;    /* '7CLR' */
  230   
  231       /**
  232        * ICC Profile Color Space Type Signature: '8CLR'.
  233        */
  234       public static final int icSigSpace8CLR        = 0x38434C52;    /* '8CLR' */
  235   
  236       /**
  237        * ICC Profile Color Space Type Signature: '9CLR'.
  238        */
  239       public static final int icSigSpace9CLR        = 0x39434C52;    /* '9CLR' */
  240   
  241       /**
  242        * ICC Profile Color Space Type Signature: 'ACLR'.
  243        */
  244       public static final int icSigSpaceACLR        = 0x41434C52;    /* 'ACLR' */
  245   
  246       /**
  247        * ICC Profile Color Space Type Signature: 'BCLR'.
  248        */
  249       public static final int icSigSpaceBCLR        = 0x42434C52;    /* 'BCLR' */
  250   
  251       /**
  252        * ICC Profile Color Space Type Signature: 'CCLR'.
  253        */
  254       public static final int icSigSpaceCCLR        = 0x43434C52;    /* 'CCLR' */
  255   
  256       /**
  257        * ICC Profile Color Space Type Signature: 'DCLR'.
  258        */
  259       public static final int icSigSpaceDCLR        = 0x44434C52;    /* 'DCLR' */
  260   
  261       /**
  262        * ICC Profile Color Space Type Signature: 'ECLR'.
  263        */
  264       public static final int icSigSpaceECLR        = 0x45434C52;    /* 'ECLR' */
  265   
  266       /**
  267        * ICC Profile Color Space Type Signature: 'FCLR'.
  268        */
  269       public static final int icSigSpaceFCLR        = 0x46434C52;    /* 'FCLR' */
  270   
  271   
  272       /**
  273        * ICC Profile Class Signature: 'scnr'.
  274        */
  275       public static final int icSigInputClass       = 0x73636E72;    /* 'scnr' */
  276   
  277       /**
  278        * ICC Profile Class Signature: 'mntr'.
  279        */
  280       public static final int icSigDisplayClass     = 0x6D6E7472;    /* 'mntr' */
  281   
  282       /**
  283        * ICC Profile Class Signature: 'prtr'.
  284        */
  285       public static final int icSigOutputClass      = 0x70727472;    /* 'prtr' */
  286   
  287       /**
  288        * ICC Profile Class Signature: 'link'.
  289        */
  290       public static final int icSigLinkClass        = 0x6C696E6B;    /* 'link' */
  291   
  292       /**
  293        * ICC Profile Class Signature: 'abst'.
  294        */
  295       public static final int icSigAbstractClass    = 0x61627374;    /* 'abst' */
  296   
  297       /**
  298        * ICC Profile Class Signature: 'spac'.
  299        */
  300       public static final int icSigColorSpaceClass  = 0x73706163;    /* 'spac' */
  301   
  302       /**
  303        * ICC Profile Class Signature: 'nmcl'.
  304        */
  305       public static final int icSigNamedColorClass  = 0x6e6d636c;    /* 'nmcl' */
  306   
  307   
  308       /**
  309        * ICC Profile Rendering Intent: Perceptual.
  310        */
  311       public static final int icPerceptual            = 0;
  312   
  313       /**
  314        * ICC Profile Rendering Intent: RelativeColorimetric.
  315        */
  316       public static final int icRelativeColorimetric    = 1;
  317   
  318       /**
  319        * ICC Profile Rendering Intent: Media-RelativeColorimetric.
  320        * @since 1.5
  321        */
  322       public static final int icMediaRelativeColorimetric = 1;
  323   
  324       /**
  325        * ICC Profile Rendering Intent: Saturation.
  326        */
  327       public static final int icSaturation            = 2;
  328   
  329       /**
  330        * ICC Profile Rendering Intent: AbsoluteColorimetric.
  331        */
  332       public static final int icAbsoluteColorimetric    = 3;
  333   
  334       /**
  335        * ICC Profile Rendering Intent: ICC-AbsoluteColorimetric.
  336        * @since 1.5
  337        */
  338       public static final int icICCAbsoluteColorimetric = 3;
  339   
  340   
  341       /**
  342        * ICC Profile Tag Signature: 'head' - special.
  343        */
  344       public static final int icSigHead      = 0x68656164; /* 'head' - special */
  345   
  346       /**
  347        * ICC Profile Tag Signature: 'A2B0'.
  348        */
  349       public static final int icSigAToB0Tag         = 0x41324230;    /* 'A2B0' */
  350   
  351       /**
  352        * ICC Profile Tag Signature: 'A2B1'.
  353        */
  354       public static final int icSigAToB1Tag         = 0x41324231;    /* 'A2B1' */
  355   
  356       /**
  357        * ICC Profile Tag Signature: 'A2B2'.
  358        */
  359       public static final int icSigAToB2Tag         = 0x41324232;    /* 'A2B2' */
  360   
  361       /**
  362        * ICC Profile Tag Signature: 'bXYZ'.
  363        */
  364       public static final int icSigBlueColorantTag  = 0x6258595A;    /* 'bXYZ' */
  365   
  366       /**
  367        * ICC Profile Tag Signature: 'bXYZ'.
  368        * @since 1.5
  369        */
  370       public static final int icSigBlueMatrixColumnTag = 0x6258595A; /* 'bXYZ' */
  371   
  372       /**
  373        * ICC Profile Tag Signature: 'bTRC'.
  374        */
  375       public static final int icSigBlueTRCTag       = 0x62545243;    /* 'bTRC' */
  376   
  377       /**
  378        * ICC Profile Tag Signature: 'B2A0'.
  379        */
  380       public static final int icSigBToA0Tag         = 0x42324130;    /* 'B2A0' */
  381   
  382       /**
  383        * ICC Profile Tag Signature: 'B2A1'.
  384        */
  385       public static final int icSigBToA1Tag         = 0x42324131;    /* 'B2A1' */
  386   
  387       /**
  388        * ICC Profile Tag Signature: 'B2A2'.
  389        */
  390       public static final int icSigBToA2Tag         = 0x42324132;    /* 'B2A2' */
  391   
  392       /**
  393        * ICC Profile Tag Signature: 'calt'.
  394        */
  395       public static final int icSigCalibrationDateTimeTag = 0x63616C74;
  396                                                                      /* 'calt' */
  397   
  398       /**
  399        * ICC Profile Tag Signature: 'targ'.
  400        */
  401       public static final int icSigCharTargetTag    = 0x74617267;    /* 'targ' */
  402   
  403       /**
  404        * ICC Profile Tag Signature: 'cprt'.
  405        */
  406       public static final int icSigCopyrightTag     = 0x63707274;    /* 'cprt' */
  407   
  408       /**
  409        * ICC Profile Tag Signature: 'crdi'.
  410        */
  411       public static final int icSigCrdInfoTag       = 0x63726469;    /* 'crdi' */
  412   
  413       /**
  414        * ICC Profile Tag Signature: 'dmnd'.
  415        */
  416       public static final int icSigDeviceMfgDescTag = 0x646D6E64;    /* 'dmnd' */
  417   
  418       /**
  419        * ICC Profile Tag Signature: 'dmdd'.
  420        */
  421       public static final int icSigDeviceModelDescTag = 0x646D6464;  /* 'dmdd' */
  422   
  423       /**
  424        * ICC Profile Tag Signature: 'devs'.
  425        */
  426       public static final int icSigDeviceSettingsTag =  0x64657673;  /* 'devs' */
  427   
  428       /**
  429        * ICC Profile Tag Signature: 'gamt'.
  430        */
  431       public static final int icSigGamutTag         = 0x67616D74;    /* 'gamt' */
  432   
  433       /**
  434        * ICC Profile Tag Signature: 'kTRC'.
  435        */
  436       public static final int icSigGrayTRCTag       = 0x6b545243;    /* 'kTRC' */
  437   
  438       /**
  439        * ICC Profile Tag Signature: 'gXYZ'.
  440        */
  441       public static final int icSigGreenColorantTag = 0x6758595A;    /* 'gXYZ' */
  442   
  443       /**
  444        * ICC Profile Tag Signature: 'gXYZ'.
  445        * @since 1.5
  446        */
  447       public static final int icSigGreenMatrixColumnTag = 0x6758595A;/* 'gXYZ' */
  448   
  449       /**
  450        * ICC Profile Tag Signature: 'gTRC'.
  451        */
  452       public static final int icSigGreenTRCTag      = 0x67545243;    /* 'gTRC' */
  453   
  454       /**
  455        * ICC Profile Tag Signature: 'lumi'.
  456        */
  457       public static final int icSigLuminanceTag     = 0x6C756d69;    /* 'lumi' */
  458   
  459       /**
  460        * ICC Profile Tag Signature: 'meas'.
  461        */
  462       public static final int icSigMeasurementTag   = 0x6D656173;    /* 'meas' */
  463   
  464       /**
  465        * ICC Profile Tag Signature: 'bkpt'.
  466        */
  467       public static final int icSigMediaBlackPointTag = 0x626B7074;  /* 'bkpt' */
  468   
  469       /**
  470        * ICC Profile Tag Signature: 'wtpt'.
  471        */
  472       public static final int icSigMediaWhitePointTag = 0x77747074;  /* 'wtpt' */
  473   
  474       /**
  475        * ICC Profile Tag Signature: 'ncl2'.
  476        */
  477       public static final int icSigNamedColor2Tag   = 0x6E636C32;    /* 'ncl2' */
  478   
  479       /**
  480        * ICC Profile Tag Signature: 'resp'.
  481        */
  482       public static final int icSigOutputResponseTag = 0x72657370;   /* 'resp' */
  483   
  484       /**
  485        * ICC Profile Tag Signature: 'pre0'.
  486        */
  487       public static final int icSigPreview0Tag      = 0x70726530;    /* 'pre0' */
  488   
  489       /**
  490        * ICC Profile Tag Signature: 'pre1'.
  491        */
  492       public static final int icSigPreview1Tag      = 0x70726531;    /* 'pre1' */
  493   
  494       /**
  495        * ICC Profile Tag Signature: 'pre2'.
  496        */
  497       public static final int icSigPreview2Tag      = 0x70726532;    /* 'pre2' */
  498   
  499       /**
  500        * ICC Profile Tag Signature: 'desc'.
  501        */
  502       public static final int icSigProfileDescriptionTag = 0x64657363;
  503                                                                      /* 'desc' */
  504   
  505       /**
  506        * ICC Profile Tag Signature: 'pseq'.
  507        */
  508       public static final int icSigProfileSequenceDescTag = 0x70736571;
  509                                                                      /* 'pseq' */
  510   
  511       /**
  512        * ICC Profile Tag Signature: 'psd0'.
  513        */
  514       public static final int icSigPs2CRD0Tag       = 0x70736430;    /* 'psd0' */
  515   
  516       /**
  517        * ICC Profile Tag Signature: 'psd1'.
  518        */
  519       public static final int icSigPs2CRD1Tag       = 0x70736431;    /* 'psd1' */
  520   
  521       /**
  522        * ICC Profile Tag Signature: 'psd2'.
  523        */
  524       public static final int icSigPs2CRD2Tag       = 0x70736432;    /* 'psd2' */
  525   
  526       /**
  527        * ICC Profile Tag Signature: 'psd3'.
  528        */
  529       public static final int icSigPs2CRD3Tag       = 0x70736433;    /* 'psd3' */
  530   
  531       /**
  532        * ICC Profile Tag Signature: 'ps2s'.
  533        */
  534       public static final int icSigPs2CSATag        = 0x70733273;    /* 'ps2s' */
  535   
  536       /**
  537        * ICC Profile Tag Signature: 'ps2i'.
  538        */
  539       public static final int icSigPs2RenderingIntentTag = 0x70733269;
  540                                                                      /* 'ps2i' */
  541   
  542       /**
  543        * ICC Profile Tag Signature: 'rXYZ'.
  544        */
  545       public static final int icSigRedColorantTag   = 0x7258595A;    /* 'rXYZ' */
  546   
  547       /**
  548        * ICC Profile Tag Signature: 'rXYZ'.
  549        * @since 1.5
  550        */
  551       public static final int icSigRedMatrixColumnTag = 0x7258595A;  /* 'rXYZ' */
  552   
  553       /**
  554        * ICC Profile Tag Signature: 'rTRC'.
  555        */
  556       public static final int icSigRedTRCTag        = 0x72545243;    /* 'rTRC' */
  557   
  558       /**
  559        * ICC Profile Tag Signature: 'scrd'.
  560        */
  561       public static final int icSigScreeningDescTag = 0x73637264;    /* 'scrd' */
  562   
  563       /**
  564        * ICC Profile Tag Signature: 'scrn'.
  565        */
  566       public static final int icSigScreeningTag     = 0x7363726E;    /* 'scrn' */
  567   
  568       /**
  569        * ICC Profile Tag Signature: 'tech'.
  570        */
  571       public static final int icSigTechnologyTag    = 0x74656368;    /* 'tech' */
  572   
  573       /**
  574        * ICC Profile Tag Signature: 'bfd '.
  575        */
  576       public static final int icSigUcrBgTag         = 0x62666420;    /* 'bfd ' */
  577   
  578       /**
  579        * ICC Profile Tag Signature: 'vued'.
  580        */
  581       public static final int icSigViewingCondDescTag = 0x76756564;  /* 'vued' */
  582   
  583       /**
  584        * ICC Profile Tag Signature: 'view'.
  585        */
  586       public static final int icSigViewingConditionsTag = 0x76696577;/* 'view' */
  587   
  588       /**
  589        * ICC Profile Tag Signature: 'chrm'.
  590        */
  591       public static final int icSigChromaticityTag  = 0x6368726d;    /* 'chrm' */
  592   
  593       /**
  594        * ICC Profile Tag Signature: 'chad'.
  595        * @since 1.5
  596        */
  597       public static final int icSigChromaticAdaptationTag = 0x63686164;/* 'chad' */
  598   
  599       /**
  600        * ICC Profile Tag Signature: 'clro'.
  601        * @since 1.5
  602        */
  603       public static final int icSigColorantOrderTag = 0x636C726F;    /* 'clro' */
  604   
  605       /**
  606        * ICC Profile Tag Signature: 'clrt'.
  607        * @since 1.5
  608        */
  609       public static final int icSigColorantTableTag = 0x636C7274;    /* 'clrt' */
  610   
  611   
  612       /**
  613        * ICC Profile Header Location: profile size in bytes.
  614        */
  615       public static final int icHdrSize         = 0;  /* Profile size in bytes */
  616   
  617       /**
  618        * ICC Profile Header Location: CMM for this profile.
  619        */
  620       public static final int icHdrCmmId        = 4;  /* CMM for this profile */
  621   
  622       /**
  623        * ICC Profile Header Location: format version number.
  624        */
  625       public static final int icHdrVersion      = 8;  /* Format version number */
  626   
  627       /**
  628        * ICC Profile Header Location: type of profile.
  629        */
  630       public static final int icHdrDeviceClass  = 12; /* Type of profile */
  631   
  632       /**
  633        * ICC Profile Header Location: color space of data.
  634        */
  635       public static final int icHdrColorSpace   = 16; /* Color space of data */
  636   
  637       /**
  638        * ICC Profile Header Location: PCS - XYZ or Lab only.
  639        */
  640       public static final int icHdrPcs          = 20; /* PCS - XYZ or Lab only */
  641   
  642       /**
  643        * ICC Profile Header Location: date profile was created.
  644        */
  645       public static final int icHdrDate       = 24; /* Date profile was created */
  646   
  647       /**
  648        * ICC Profile Header Location: icMagicNumber.
  649        */
  650       public static final int icHdrMagic        = 36; /* icMagicNumber */
  651   
  652       /**
  653        * ICC Profile Header Location: primary platform.
  654        */
  655       public static final int icHdrPlatform     = 40; /* Primary Platform */
  656   
  657       /**
  658        * ICC Profile Header Location: various bit settings.
  659        */
  660       public static final int icHdrFlags        = 44; /* Various bit settings */
  661   
  662       /**
  663        * ICC Profile Header Location: device manufacturer.
  664        */
  665       public static final int icHdrManufacturer = 48; /* Device manufacturer */
  666   
  667       /**
  668        * ICC Profile Header Location: device model number.
  669        */
  670       public static final int icHdrModel        = 52; /* Device model number */
  671   
  672       /**
  673        * ICC Profile Header Location: device attributes.
  674        */
  675       public static final int icHdrAttributes   = 56; /* Device attributes */
  676   
  677       /**
  678        * ICC Profile Header Location: rendering intent.
  679        */
  680       public static final int icHdrRenderingIntent = 64; /* Rendering intent */
  681   
  682       /**
  683        * ICC Profile Header Location: profile illuminant.
  684        */
  685       public static final int icHdrIlluminant   = 68; /* Profile illuminant */
  686   
  687       /**
  688        * ICC Profile Header Location: profile creator.
  689        */
  690       public static final int icHdrCreator      = 80; /* Profile creator */
  691   
  692       /**
  693        * ICC Profile Header Location: profile's ID.
  694        * @since 1.5
  695        */
  696       public static final int icHdrProfileID = 84; /* Profile's ID */
  697   
  698   
  699       /**
  700        * ICC Profile Constant: tag type signaturE.
  701        */
  702       public static final int icTagType          = 0;    /* tag type signature */
  703   
  704       /**
  705        * ICC Profile Constant: reserved.
  706        */
  707       public static final int icTagReserved      = 4;    /* reserved */
  708   
  709       /**
  710        * ICC Profile Constant: curveType count.
  711        */
  712       public static final int icCurveCount       = 8;    /* curveType count */
  713   
  714       /**
  715        * ICC Profile Constant: curveType data.
  716        */
  717       public static final int icCurveData        = 12;   /* curveType data */
  718   
  719       /**
  720        * ICC Profile Constant: XYZNumber X.
  721        */
  722       public static final int icXYZNumberX       = 8;    /* XYZNumber X */
  723   
  724   
  725       /**
  726        * Constructs an ICC_Profile object with a given ID.
  727        */
  728       ICC_Profile(long ID) {
  729           this.ID = ID;
  730       }
  731   
  732   
  733       /**
  734        * Constructs an ICC_Profile object whose loading will be deferred.
  735        * The ID will be 0 until the profile is loaded.
  736        */
  737       ICC_Profile(ProfileDeferralInfo pdi) {
  738           this.deferralInfo = pdi;
  739           this.profileActivator = new ProfileActivator() {
  740               public void activate() {
  741                   activateDeferredProfile();
  742               }
  743           };
  744           ProfileDeferralMgr.registerDeferral(this.profileActivator);
  745       }
  746   
  747   
  748       /**
  749        * Frees the resources associated with an ICC_Profile object.
  750        */
  751       protected void finalize () {
  752           if (ID != 0) {
  753               CMSManager.getModule().freeProfile(ID);
  754           } else if (profileActivator != null) {
  755               ProfileDeferralMgr.unregisterDeferral(profileActivator);
  756           }
  757       }
  758   
  759   
  760       /**
  761        * Constructs an ICC_Profile object corresponding to the data in
  762        * a byte array.  Throws an IllegalArgumentException if the data
  763        * does not correspond to a valid ICC Profile.
  764        * @param data the specified ICC Profile data
  765        * @return an <code>ICC_Profile</code> object corresponding to
  766        *          the data in the specified <code>data</code> array.
  767        */
  768       public static ICC_Profile getInstance(byte[] data) {
  769       ICC_Profile thisProfile;
  770   
  771           long theID;
  772   
  773           if (ProfileDeferralMgr.deferring) {
  774               ProfileDeferralMgr.activateProfiles();
  775           }
  776   
  777           try {
  778               theID = CMSManager.getModule().loadProfile(data);
  779           } catch (CMMException c) {
  780               throw new IllegalArgumentException("Invalid ICC Profile Data");
  781           }
  782   
  783           try {
  784               if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
  785                   (getData (theID, icSigMediaWhitePointTag) != null) &&
  786                   (getData (theID, icSigGrayTRCTag) != null)) {
  787                   thisProfile = new ICC_ProfileGray (theID);
  788               }
  789               else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
  790                   (getData (theID, icSigMediaWhitePointTag) != null) &&
  791                   (getData (theID, icSigRedColorantTag) != null) &&
  792                   (getData (theID, icSigGreenColorantTag) != null) &&
  793                   (getData (theID, icSigBlueColorantTag) != null) &&
  794                   (getData (theID, icSigRedTRCTag) != null) &&
  795                   (getData (theID, icSigGreenTRCTag) != null) &&
  796                   (getData (theID, icSigBlueTRCTag) != null)) {
  797                   thisProfile = new ICC_ProfileRGB (theID);
  798               }
  799               else {
  800                   thisProfile = new ICC_Profile (theID);
  801               }
  802           } catch (CMMException c) {
  803               thisProfile = new ICC_Profile (theID);
  804           }
  805           return thisProfile;
  806       }
  807   
  808   
  809   
  810       /**
  811        * Constructs an ICC_Profile corresponding to one of the specific color
  812        * spaces defined by the ColorSpace class (for example CS_sRGB).
  813        * Throws an IllegalArgumentException if cspace is not one of the
  814        * defined color spaces.
  815        *
  816        * @param cspace the type of color space to create a profile for.
  817        * The specified type is one of the color
  818        * space constants defined in the  <CODE>ColorSpace</CODE> class.
  819        *
  820        * @return an <code>ICC_Profile</code> object corresponding to
  821        *          the specified <code>ColorSpace</code> type.
  822        * @exception IllegalArgumentException If <CODE>cspace</CODE> is not
  823        * one of the predefined color space types.
  824        */
  825       public static ICC_Profile getInstance (int cspace) {
  826           ICC_Profile thisProfile = null;
  827           String fileName;
  828   
  829           switch (cspace) {
  830           case ColorSpace.CS_sRGB:
  831               synchronized(ICC_Profile.class) {
  832                   if (sRGBprofile == null) {
  833                       try {
  834                           /*
  835                            * Deferral is only used for standard profiles.
  836                            * Enabling the appropriate access privileges is handled
  837                            * at a lower level.
  838                            */
  839                           sRGBprofile = getDeferredInstance(
  840                               new ProfileDeferralInfo("sRGB.pf",
  841                                                       ColorSpace.TYPE_RGB,
  842                                                       3, CLASS_DISPLAY));
  843                       } catch (IOException e) {
  844                           throw new IllegalArgumentException(
  845                                 "Can't load standard profile: sRGB.pf");
  846                       }
  847                   }
  848                   thisProfile = sRGBprofile;
  849               }
  850   
  851               break;
  852   
  853           case ColorSpace.CS_CIEXYZ:
  854               synchronized(ICC_Profile.class) {
  855                   if (XYZprofile == null) {
  856                       XYZprofile = getStandardProfile("CIEXYZ.pf");
  857                   }
  858                   thisProfile = XYZprofile;
  859               }
  860   
  861               break;
  862   
  863           case ColorSpace.CS_PYCC:
  864               synchronized(ICC_Profile.class) {
  865                   if (PYCCprofile == null) {
  866                       PYCCprofile = getStandardProfile("PYCC.pf");
  867                   }
  868                   thisProfile = PYCCprofile;
  869               }
  870   
  871               break;
  872   
  873           case ColorSpace.CS_GRAY:
  874               synchronized(ICC_Profile.class) {
  875                   if (GRAYprofile == null) {
  876                       GRAYprofile = getStandardProfile("GRAY.pf");
  877                   }
  878                   thisProfile = GRAYprofile;
  879               }
  880   
  881               break;
  882   
  883           case ColorSpace.CS_LINEAR_RGB:
  884               synchronized(ICC_Profile.class) {
  885                   if (LINEAR_RGBprofile == null) {
  886                       LINEAR_RGBprofile = getStandardProfile("LINEAR_RGB.pf");
  887                   }
  888                   thisProfile = LINEAR_RGBprofile;
  889               }
  890   
  891               break;
  892   
  893           default:
  894               throw new IllegalArgumentException("Unknown color space");
  895           }
  896   
  897           return thisProfile;
  898       }
  899   
  900       /* This asserts system privileges, so is used only for the
  901        * standard profiles.
  902        */
  903       private static ICC_Profile getStandardProfile(final String name) {
  904   
  905           return (ICC_Profile) AccessController.doPrivileged(
  906               new PrivilegedAction() {
  907                    public Object run() {
  908                        ICC_Profile p = null;
  909                        try {
  910                            p = getInstance (name);
  911                        } catch (IOException ex) {
  912                            throw new IllegalArgumentException(
  913                                  "Can't load standard profile: " + name);
  914                        }
  915                        return p;
  916                    }
  917                });
  918       }
  919   
  920       /**
  921        * Constructs an ICC_Profile corresponding to the data in a file.
  922        * fileName may be an absolute or a relative file specification.
  923        * Relative file names are looked for in several places: first, relative
  924        * to any directories specified by the java.iccprofile.path property;
  925        * second, relative to any directories specified by the java.class.path
  926        * property; finally, in a directory used to store profiles always
  927        * available, such as the profile for sRGB.  Built-in profiles use .pf as
  928        * the file name extension for profiles, e.g. sRGB.pf.
  929        * This method throws an IOException if the specified file cannot be
  930        * opened or if an I/O error occurs while reading the file.  It throws
  931        * an IllegalArgumentException if the file does not contain valid ICC
  932        * Profile data.
  933        * @param fileName The file that contains the data for the profile.
  934        *
  935        * @return an <code>ICC_Profile</code> object corresponding to
  936        *          the data in the specified file.
  937        * @exception IOException If the specified file cannot be opened or
  938        * an I/O error occurs while reading the file.
  939        *
  940        * @exception IllegalArgumentException If the file does not
  941        * contain valid ICC Profile data.
  942        *
  943        * @exception SecurityException If a security manager is installed
  944        * and it does not permit read access to the given file.
  945        */
  946       public static ICC_Profile getInstance(String fileName) throws IOException {
  947       ICC_Profile thisProfile;
  948       FileInputStream fis;
  949   
  950           SecurityManager security = System.getSecurityManager();
  951           if (security != null) {
  952               security.checkRead(fileName);
  953           }
  954   
  955           if ((fis = openProfile(fileName)) == null) {
  956               throw new IOException("Cannot open file " + fileName);
  957           }
  958   
  959           thisProfile = getInstance(fis);
  960   
  961           fis.close();    /* close the file */
  962   
  963           return thisProfile;
  964       }
  965   
  966   
  967       /**
  968        * Constructs an ICC_Profile corresponding to the data in an InputStream.
  969        * This method throws an IllegalArgumentException if the stream does not
  970        * contain valid ICC Profile data.  It throws an IOException if an I/O
  971        * error occurs while reading the stream.
  972        * @param s The input stream from which to read the profile data.
  973        *
  974        * @return an <CODE>ICC_Profile</CODE> object corresponding to the
  975        *     data in the specified <code>InputStream</code>.
  976        *
  977        * @exception IOException If an I/O error occurs while reading the stream.
  978        *
  979        * @exception IllegalArgumentException If the stream does not
  980        * contain valid ICC Profile data.
  981        */
  982       public static ICC_Profile getInstance(InputStream s) throws IOException {
  983       byte profileData[];
  984   
  985           if (s instanceof ProfileDeferralInfo) {
  986               /* hack to detect profiles whose loading can be deferred */
  987               return getDeferredInstance((ProfileDeferralInfo) s);
  988           }
  989   
  990           if ((profileData = getProfileDataFromStream(s)) == null) {
  991               throw new IllegalArgumentException("Invalid ICC Profile Data");
  992           }
  993   
  994           return getInstance(profileData);
  995       }
  996   
  997   
  998       static byte[] getProfileDataFromStream(InputStream s) throws IOException {
  999       byte profileData[];
 1000       int profileSize;
 1001   
 1002           byte header[] = new byte[128];
 1003           int bytestoread = 128;
 1004           int bytesread = 0;
 1005           int n;
 1006   
 1007           while (bytestoread != 0) {
 1008               if ((n = s.read(header, bytesread, bytestoread)) < 0) {
 1009                   return null;
 1010               }
 1011               bytesread += n;
 1012               bytestoread -= n;
 1013           }
 1014           if (header[36] != 0x61 || header[37] != 0x63 ||
 1015               header[38] != 0x73 || header[39] != 0x70) {
 1016               return null;   /* not a valid profile */
 1017           }
 1018           profileSize = ((header[0] & 0xff) << 24) |
 1019                         ((header[1] & 0xff) << 16) |
 1020                         ((header[2] & 0xff) <<  8) |
 1021                          (header[3] & 0xff);
 1022           profileData = new byte[profileSize];
 1023           System.arraycopy(header, 0, profileData, 0, 128);
 1024           bytestoread = profileSize - 128;
 1025           bytesread = 128;
 1026           while (bytestoread != 0) {
 1027               if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
 1028                   return null;
 1029               }
 1030               bytesread += n;
 1031               bytestoread -= n;
 1032           }
 1033   
 1034           return profileData;
 1035       }
 1036   
 1037   
 1038       /**
 1039        * Constructs an ICC_Profile for which the actual loading of the
 1040        * profile data from a file and the initialization of the CMM should
 1041        * be deferred as long as possible.
 1042        * Deferral is only used for standard profiles.
 1043        * If deferring is disabled, then getStandardProfile() ensures
 1044        * that all of the appropriate access privileges are granted
 1045        * when loading this profile.
 1046        * If deferring is enabled, then the deferred activation
 1047        * code will take care of access privileges.
 1048        * @see activateDeferredProfile()
 1049        */
 1050       static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi)
 1051           throws IOException {
 1052   
 1053           if (!ProfileDeferralMgr.deferring) {
 1054               return getStandardProfile(pdi.filename);
 1055           }
 1056           if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) {
 1057               return new ICC_ProfileRGB(pdi);
 1058           } else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) {
 1059               return new ICC_ProfileGray(pdi);
 1060           } else {
 1061               return new ICC_Profile(pdi);
 1062           }
 1063       }
 1064   
 1065   
 1066       void activateDeferredProfile() {
 1067       byte profileData[];
 1068       FileInputStream fis;
 1069       String fileName = deferralInfo.filename;
 1070   
 1071           profileActivator = null;
 1072           deferralInfo = null;
 1073           if ((fis = openProfile(fileName)) == null) {
 1074               throw new IllegalArgumentException("Cannot open file " + fileName);
 1075           }
 1076           try {
 1077               profileData = getProfileDataFromStream(fis);
 1078               fis.close();    /* close the file */
 1079           }
 1080           catch (IOException e) {
 1081               throw new IllegalArgumentException("Invalid ICC Profile Data" +
 1082                   fileName);
 1083           }
 1084           if (profileData == null) {
 1085               throw new IllegalArgumentException("Invalid ICC Profile Data" +
 1086                   fileName);
 1087           }
 1088           try {
 1089               ID = CMSManager.getModule().loadProfile(profileData);
 1090           } catch (CMMException c) {
 1091               throw new IllegalArgumentException("Invalid ICC Profile Data" +
 1092                   fileName);
 1093           }
 1094       }
 1095   
 1096   
 1097       /**
 1098        * Returns profile major version.
 1099        * @return  The major version of the profile.
 1100        */
 1101       public int getMajorVersion() {
 1102       byte[] theHeader;
 1103   
 1104           theHeader = getData(icSigHead); /* getData will activate deferred
 1105                                              profiles if necessary */
 1106   
 1107           return (int) theHeader[8];
 1108       }
 1109   
 1110       /**
 1111        * Returns profile minor version.
 1112        * @return The minor version of the profile.
 1113        */
 1114       public int getMinorVersion() {
 1115       byte[] theHeader;
 1116   
 1117           theHeader = getData(icSigHead); /* getData will activate deferred
 1118                                              profiles if necessary */
 1119   
 1120           return (int) theHeader[9];
 1121       }
 1122   
 1123       /**
 1124        * Returns the profile class.
 1125        * @return One of the predefined profile class constants.
 1126        */
 1127       public int getProfileClass() {
 1128       byte[] theHeader;
 1129       int theClassSig, theClass;
 1130   
 1131           if (deferralInfo != null) {
 1132               return deferralInfo.profileClass; /* Need to have this info for
 1133                                                    ICC_ColorSpace without
 1134                                                    causing a deferred profile
 1135                                                    to be loaded */
 1136           }
 1137   
 1138           theHeader = getData(icSigHead);
 1139   
 1140           theClassSig = intFromBigEndian (theHeader, icHdrDeviceClass);
 1141   
 1142           switch (theClassSig) {
 1143           case icSigInputClass:
 1144               theClass = CLASS_INPUT;
 1145               break;
 1146   
 1147           case icSigDisplayClass:
 1148               theClass = CLASS_DISPLAY;
 1149               break;
 1150   
 1151           case icSigOutputClass:
 1152               theClass = CLASS_OUTPUT;
 1153               break;
 1154   
 1155           case icSigLinkClass:
 1156               theClass = CLASS_DEVICELINK;
 1157               break;
 1158   
 1159           case icSigColorSpaceClass:
 1160               theClass = CLASS_COLORSPACECONVERSION;
 1161               break;
 1162   
 1163           case icSigAbstractClass:
 1164               theClass = CLASS_ABSTRACT;
 1165               break;
 1166   
 1167           case icSigNamedColorClass:
 1168               theClass = CLASS_NAMEDCOLOR;
 1169               break;
 1170   
 1171           default:
 1172               throw new IllegalArgumentException("Unknown profile class");
 1173           }
 1174   
 1175           return theClass;
 1176       }
 1177   
 1178       /**
 1179        * Returns the color space type.  Returns one of the color space type
 1180        * constants defined by the ColorSpace class.  This is the
 1181        * "input" color space of the profile.  The type defines the
 1182        * number of components of the color space and the interpretation,
 1183        * e.g. TYPE_RGB identifies a color space with three components - red,
 1184        * green, and blue.  It does not define the particular color
 1185        * characteristics of the space, e.g. the chromaticities of the
 1186        * primaries.
 1187        * @return One of the color space type constants defined in the
 1188        * <CODE>ColorSpace</CODE> class.
 1189        */
 1190       public int getColorSpaceType() {
 1191           if (deferralInfo != null) {
 1192               return deferralInfo.colorSpaceType; /* Need to have this info for
 1193                                                      ICC_ColorSpace without
 1194                                                      causing a deferred profile
 1195                                                      to be loaded */
 1196           }
 1197           return    getColorSpaceType(ID);
 1198       }
 1199   
 1200       static int getColorSpaceType(long profileID) {
 1201       byte[] theHeader;
 1202       int theColorSpaceSig, theColorSpace;
 1203   
 1204           theHeader = getData(profileID, icSigHead);
 1205           theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
 1206           theColorSpace = iccCStoJCS (theColorSpaceSig);
 1207           return theColorSpace;
 1208       }
 1209   
 1210       /**
 1211        * Returns the color space type of the Profile Connection Space (PCS).
 1212        * Returns one of the color space type constants defined by the
 1213        * ColorSpace class.  This is the "output" color space of the
 1214        * profile.  For an input, display, or output profile useful
 1215        * for tagging colors or images, this will be either TYPE_XYZ or
 1216        * TYPE_Lab and should be interpreted as the corresponding specific
 1217        * color space defined in the ICC specification.  For a device
 1218        * link profile, this could be any of the color space type constants.
 1219        * @return One of the color space type constants defined in the
 1220        * <CODE>ColorSpace</CODE> class.
 1221        */
 1222       public int getPCSType() {
 1223           if (ProfileDeferralMgr.deferring) {
 1224               ProfileDeferralMgr.activateProfiles();
 1225           }
 1226           return getPCSType(ID);
 1227       }
 1228   
 1229   
 1230       static int getPCSType(long profileID) {
 1231       byte[] theHeader;
 1232       int thePCSSig, thePCS;
 1233   
 1234           theHeader = getData(profileID, icSigHead);
 1235           thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
 1236           thePCS = iccCStoJCS(thePCSSig);
 1237           return thePCS;
 1238       }
 1239   
 1240   
 1241       /**
 1242        * Write this ICC_Profile to a file.
 1243        *
 1244        * @param fileName The file to write the profile data to.
 1245        *
 1246        * @exception IOException If the file cannot be opened for writing
 1247        * or an I/O error occurs while writing to the file.
 1248        */
 1249       public void write(String fileName) throws IOException {
 1250       FileOutputStream outputFile;
 1251       byte profileData[];
 1252   
 1253           profileData = getData(); /* this will activate deferred
 1254                                       profiles if necessary */
 1255           outputFile = new FileOutputStream(fileName);
 1256           outputFile.write(profileData);
 1257           outputFile.close ();
 1258       }
 1259   
 1260   
 1261       /**
 1262        * Write this ICC_Profile to an OutputStream.
 1263        *
 1264        * @param s The stream to write the profile data to.
 1265        *
 1266        * @exception IOException If an I/O error occurs while writing to the
 1267        * stream.
 1268        */
 1269       public void write(OutputStream s) throws IOException {
 1270       byte profileData[];
 1271   
 1272           profileData = getData(); /* this will activate deferred
 1273                                       profiles if necessary */
 1274           s.write(profileData);
 1275       }
 1276   
 1277   
 1278       /**
 1279        * Returns a byte array corresponding to the data of this ICC_Profile.
 1280        * @return A byte array that contains the profile data.
 1281        * @see #setData(int, byte[])
 1282        */
 1283       public byte[] getData() {
 1284       int profileSize;
 1285       byte[] profileData;
 1286   
 1287           if (ProfileDeferralMgr.deferring) {
 1288               ProfileDeferralMgr.activateProfiles();
 1289           }
 1290   
 1291           PCMM mdl = CMSManager.getModule();
 1292   
 1293           /* get the number of bytes needed for this profile */
 1294           profileSize = mdl.getProfileSize(ID);
 1295   
 1296           profileData = new byte [profileSize];
 1297   
 1298           /* get the data for the profile */
 1299           mdl.getProfileData(ID, profileData);
 1300   
 1301           return profileData;
 1302       }
 1303   
 1304   
 1305       /**
 1306        * Returns a particular tagged data element from the profile as
 1307        * a byte array.  Elements are identified by signatures
 1308        * as defined in the ICC specification.  The signature
 1309        * icSigHead can be used to get the header.  This method is useful
 1310        * for advanced applets or applications which need to access
 1311        * profile data directly.
 1312        *
 1313        * @param tagSignature The ICC tag signature for the data element you
 1314        * want to get.
 1315        *
 1316        * @return A byte array that contains the tagged data element. Returns
 1317        * <code>null</code> if the specified tag doesn't exist.
 1318        * @see #setData(int, byte[])
 1319        */
 1320       public byte[] getData(int tagSignature) {
 1321   
 1322           if (ProfileDeferralMgr.deferring) {
 1323               ProfileDeferralMgr.activateProfiles();
 1324           }
 1325   
 1326           return getData(ID, tagSignature);
 1327       }
 1328   
 1329   
 1330       static byte[] getData(long profileID, int tagSignature) {
 1331       int tagSize;
 1332       byte[] tagData;
 1333   
 1334           try {
 1335               PCMM mdl = CMSManager.getModule();
 1336   
 1337               /* get the number of bytes needed for this tag */
 1338               tagSize = mdl.getTagSize(profileID, tagSignature);
 1339   
 1340               tagData = new byte[tagSize]; /* get an array for the tag */
 1341   
 1342               /* get the tag's data */
 1343               mdl.getTagData(profileID, tagSignature, tagData);
 1344           } catch(CMMException c) {
 1345               tagData = null;
 1346           }
 1347   
 1348           return tagData;
 1349       }
 1350   
 1351       /**
 1352        * Sets a particular tagged data element in the profile from
 1353        * a byte array.  This method is useful
 1354        * for advanced applets or applications which need to access
 1355        * profile data directly.
 1356        *
 1357        * @param tagSignature The ICC tag signature for the data element
 1358        * you want to set.
 1359        * @param tagData the data to set for the specified tag signature
 1360        * @see #getData
 1361        */
 1362       public void setData(int tagSignature, byte[] tagData) {
 1363   
 1364           if (ProfileDeferralMgr.deferring) {
 1365               ProfileDeferralMgr.activateProfiles();
 1366           }
 1367   
 1368           CMSManager.getModule().setTagData(ID, tagSignature, tagData);
 1369       }
 1370   
 1371       /**
 1372        * Sets the rendering intent of the profile.
 1373        * This is used to select the proper transform from a profile that
 1374        * has multiple transforms.
 1375        */
 1376       void setRenderingIntent(int renderingIntent) {
 1377           byte[] theHeader = getData(icSigHead);/* getData will activate deferred
 1378                                                    profiles if necessary */
 1379           intToBigEndian (renderingIntent, theHeader, icHdrRenderingIntent);
 1380                                                    /* set the rendering intent */
 1381           setData (icSigHead, theHeader);
 1382       }
 1383   
 1384   
 1385       /**
 1386        * Returns the rendering intent of the profile.
 1387        * This is used to select the proper transform from a profile that
 1388        * has multiple transforms.  It is typically set in a source profile
 1389        * to select a transform from an output profile.
 1390        */
 1391       int getRenderingIntent() {
 1392           byte[] theHeader = getData(icSigHead);/* getData will activate deferred
 1393                                                    profiles if necessary */
 1394   
 1395           int renderingIntent = intFromBigEndian(theHeader, icHdrRenderingIntent);
 1396                                                    /* set the rendering intent */
 1397           return renderingIntent;
 1398       }
 1399   
 1400   
 1401       /**
 1402        * Returns the number of color components in the "input" color
 1403        * space of this profile.  For example if the color space type
 1404        * of this profile is TYPE_RGB, then this method will return 3.
 1405        *
 1406        * @return The number of color components in the profile's input
 1407        * color space.
 1408        *
 1409        * @throws ProfileDataException if color space is in the profile
 1410        *         is invalid
 1411        */
 1412       public int getNumComponents() {
 1413       byte[]    theHeader;
 1414       int    theColorSpaceSig, theNumComponents;
 1415   
 1416           if (deferralInfo != null) {
 1417               return deferralInfo.numComponents; /* Need to have this info for
 1418                                                     ICC_ColorSpace without
 1419                                                     causing a deferred profile
 1420                                                     to be loaded */
 1421           }
 1422           theHeader = getData(icSigHead);
 1423   
 1424           theColorSpaceSig = intFromBigEndian (theHeader, icHdrColorSpace);
 1425   
 1426           switch (theColorSpaceSig) {
 1427           case icSigGrayData:
 1428               theNumComponents = 1;
 1429               break;
 1430   
 1431           case icSigSpace2CLR:
 1432               theNumComponents = 2;
 1433               break;
 1434   
 1435           case icSigXYZData:
 1436           case icSigLabData:
 1437           case icSigLuvData:
 1438           case icSigYCbCrData:
 1439           case icSigYxyData:
 1440           case icSigRgbData:
 1441           case icSigHsvData:
 1442           case icSigHlsData:
 1443           case icSigCmyData:
 1444           case icSigSpace3CLR:
 1445               theNumComponents = 3;
 1446               break;
 1447   
 1448           case icSigCmykData:
 1449           case icSigSpace4CLR:
 1450               theNumComponents = 4;
 1451               break;
 1452   
 1453           case icSigSpace5CLR:
 1454               theNumComponents = 5;
 1455               break;
 1456   
 1457           case icSigSpace6CLR:
 1458               theNumComponents = 6;
 1459               break;
 1460   
 1461           case icSigSpace7CLR:
 1462               theNumComponents = 7;
 1463               break;
 1464   
 1465           case icSigSpace8CLR:
 1466               theNumComponents = 8;
 1467               break;
 1468   
 1469           case icSigSpace9CLR:
 1470               theNumComponents = 9;
 1471               break;
 1472   
 1473           case icSigSpaceACLR:
 1474               theNumComponents = 10;
 1475               break;
 1476   
 1477           case icSigSpaceBCLR:
 1478               theNumComponents = 11;
 1479               break;
 1480   
 1481           case icSigSpaceCCLR:
 1482               theNumComponents = 12;
 1483               break;
 1484   
 1485           case icSigSpaceDCLR:
 1486               theNumComponents = 13;
 1487               break;
 1488   
 1489           case icSigSpaceECLR:
 1490               theNumComponents = 14;
 1491               break;
 1492   
 1493           case icSigSpaceFCLR:
 1494               theNumComponents = 15;
 1495               break;
 1496   
 1497           default:
 1498               throw new ProfileDataException ("invalid ICC color space");
 1499           }
 1500   
 1501           return theNumComponents;
 1502       }
 1503   
 1504   
 1505       /**
 1506        * Returns a float array of length 3 containing the X, Y, and Z
 1507        * components of the mediaWhitePointTag in the ICC profile.
 1508        */
 1509       float[] getMediaWhitePoint() {
 1510           return getXYZTag(icSigMediaWhitePointTag);
 1511                                              /* get the media white point tag */
 1512       }
 1513   
 1514   
 1515       /**
 1516        * Returns a float array of length 3 containing the X, Y, and Z
 1517        * components encoded in an XYZType tag.
 1518        */
 1519       float[] getXYZTag(int theTagSignature) {
 1520       byte[] theData;
 1521       float[] theXYZNumber;
 1522       int i1, i2, theS15Fixed16;
 1523   
 1524           theData = getData(theTagSignature); /* get the tag data */
 1525                                               /* getData will activate deferred
 1526                                                  profiles if necessary */
 1527   
 1528           theXYZNumber = new float [3];        /* array to return */
 1529   
 1530           /* convert s15Fixed16Number to float */
 1531           for (i1 = 0, i2 = icXYZNumberX; i1 < 3; i1++, i2 += 4) {
 1532               theS15Fixed16 = intFromBigEndian(theData, i2);
 1533               theXYZNumber [i1] = ((float) theS15Fixed16) / 65536.0f;
 1534           }
 1535           return theXYZNumber;
 1536       }
 1537   
 1538   
 1539       /**
 1540        * Returns a gamma value representing a tone reproduction
 1541        * curve (TRC).  If the profile represents the TRC as a table rather
 1542        * than a single gamma value, then an exception is thrown.  In this
 1543        * case the actual table can be obtained via getTRC().
 1544        * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
 1545        * icSigGreenTRCTag, or icSigBlueTRCTag.
 1546        * @return the gamma value as a float.
 1547        * @exception ProfileDataException if the profile does not specify
 1548        *            the TRC as a single gamma value.
 1549        */
 1550       float getGamma(int theTagSignature) {
 1551       byte[] theTRCData;
 1552       float theGamma;
 1553       int theU8Fixed8;
 1554   
 1555           theTRCData = getData(theTagSignature); /* get the TRC */
 1556                                                  /* getData will activate deferred
 1557                                                     profiles if necessary */
 1558   
 1559           if (intFromBigEndian (theTRCData, icCurveCount) != 1) {
 1560               throw new ProfileDataException ("TRC is not a gamma");
 1561           }
 1562   
 1563           /* convert u8Fixed8 to float */
 1564           theU8Fixed8 = (shortFromBigEndian(theTRCData, icCurveData)) & 0xffff;
 1565   
 1566           theGamma = ((float) theU8Fixed8) / 256.0f;
 1567   
 1568           return theGamma;
 1569       }
 1570   
 1571   
 1572       /**
 1573        * Returns the TRC as an array of shorts.  If the profile has
 1574        * specified the TRC as linear (gamma = 1.0) or as a simple gamma
 1575        * value, this method throws an exception, and the getGamma() method
 1576        * should be used to get the gamma value.  Otherwise the short array
 1577        * returned here represents a lookup table where the input Gray value
 1578        * is conceptually in the range [0.0, 1.0].  Value 0.0 maps
 1579        * to array index 0 and value 1.0 maps to array index length-1.
 1580        * Interpolation may be used to generate output values for
 1581        * input values which do not map exactly to an index in the
 1582        * array.  Output values also map linearly to the range [0.0, 1.0].
 1583        * Value 0.0 is represented by an array value of 0x0000 and
 1584        * value 1.0 by 0xFFFF, i.e. the values are really unsigned
 1585        * short values, although they are returned in a short array.
 1586        * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
 1587        * icSigGreenTRCTag, or icSigBlueTRCTag.
 1588        * @return a short array representing the TRC.
 1589        * @exception ProfileDataException if the profile does not specify
 1590        *            the TRC as a table.
 1591        */
 1592       short[] getTRC(int theTagSignature) {
 1593       byte[] theTRCData;
 1594       short[] theTRC;
 1595       int i1, i2, nElements, theU8Fixed8;
 1596   
 1597           theTRCData = getData(theTagSignature); /* get the TRC */
 1598                                                  /* getData will activate deferred
 1599                                                     profiles if necessary */
 1600   
 1601           nElements = intFromBigEndian(theTRCData, icCurveCount);
 1602   
 1603           if (nElements == 1) {
 1604               throw new ProfileDataException("TRC is not a table");
 1605           }
 1606   
 1607           /* make the short array */
 1608           theTRC = new short [nElements];
 1609   
 1610           for (i1 = 0, i2 = icCurveData; i1 < nElements; i1++, i2 += 2) {
 1611               theTRC[i1] = shortFromBigEndian(theTRCData, i2);
 1612           }
 1613   
 1614           return theTRC;
 1615       }
 1616   
 1617   
 1618       /* convert an ICC color space signature into a Java color space type */
 1619       static int iccCStoJCS(int theColorSpaceSig) {
 1620       int theColorSpace;
 1621   
 1622           switch (theColorSpaceSig) {
 1623           case icSigXYZData:
 1624               theColorSpace = ColorSpace.TYPE_XYZ;
 1625               break;
 1626   
 1627           case icSigLabData:
 1628               theColorSpace = ColorSpace.TYPE_Lab;
 1629               break;
 1630   
 1631           case icSigLuvData:
 1632               theColorSpace = ColorSpace.TYPE_Luv;
 1633               break;
 1634   
 1635           case icSigYCbCrData:
 1636               theColorSpace = ColorSpace.TYPE_YCbCr;
 1637               break;
 1638   
 1639           case icSigYxyData:
 1640               theColorSpace = ColorSpace.TYPE_Yxy;
 1641               break;
 1642   
 1643           case icSigRgbData:
 1644               theColorSpace = ColorSpace.TYPE_RGB;
 1645               break;
 1646   
 1647           case icSigGrayData:
 1648               theColorSpace = ColorSpace.TYPE_GRAY;
 1649               break;
 1650   
 1651           case icSigHsvData:
 1652               theColorSpace = ColorSpace.TYPE_HSV;
 1653               break;
 1654   
 1655           case icSigHlsData:
 1656               theColorSpace = ColorSpace.TYPE_HLS;
 1657               break;
 1658   
 1659           case icSigCmykData:
 1660               theColorSpace = ColorSpace.TYPE_CMYK;
 1661               break;
 1662   
 1663           case icSigCmyData:
 1664               theColorSpace = ColorSpace.TYPE_CMY;
 1665               break;
 1666   
 1667           case icSigSpace2CLR:
 1668               theColorSpace = ColorSpace.TYPE_2CLR;
 1669               break;
 1670   
 1671           case icSigSpace3CLR:
 1672               theColorSpace = ColorSpace.TYPE_3CLR;
 1673               break;
 1674   
 1675           case icSigSpace4CLR:
 1676               theColorSpace = ColorSpace.TYPE_4CLR;
 1677               break;
 1678   
 1679           case icSigSpace5CLR:
 1680               theColorSpace = ColorSpace.TYPE_5CLR;
 1681               break;
 1682   
 1683           case icSigSpace6CLR:
 1684               theColorSpace = ColorSpace.TYPE_6CLR;
 1685               break;
 1686   
 1687           case icSigSpace7CLR:
 1688               theColorSpace = ColorSpace.TYPE_7CLR;
 1689               break;
 1690   
 1691           case icSigSpace8CLR:
 1692               theColorSpace = ColorSpace.TYPE_8CLR;
 1693               break;
 1694   
 1695           case icSigSpace9CLR:
 1696               theColorSpace = ColorSpace.TYPE_9CLR;
 1697               break;
 1698   
 1699           case icSigSpaceACLR:
 1700               theColorSpace = ColorSpace.TYPE_ACLR;
 1701               break;
 1702   
 1703           case icSigSpaceBCLR:
 1704               theColorSpace = ColorSpace.TYPE_BCLR;
 1705               break;
 1706   
 1707           case icSigSpaceCCLR:
 1708               theColorSpace = ColorSpace.TYPE_CCLR;
 1709               break;
 1710   
 1711           case icSigSpaceDCLR:
 1712               theColorSpace = ColorSpace.TYPE_DCLR;
 1713               break;
 1714   
 1715           case icSigSpaceECLR:
 1716               theColorSpace = ColorSpace.TYPE_ECLR;
 1717               break;
 1718   
 1719           case icSigSpaceFCLR:
 1720               theColorSpace = ColorSpace.TYPE_FCLR;
 1721               break;
 1722   
 1723           default:
 1724               throw new IllegalArgumentException ("Unknown color space");
 1725           }
 1726   
 1727           return theColorSpace;
 1728       }
 1729   
 1730   
 1731       static int intFromBigEndian(byte[] array, int index) {
 1732           return (((array[index]   & 0xff) << 24) |
 1733                   ((array[index+1] & 0xff) << 16) |
 1734                   ((array[index+2] & 0xff) <<  8) |
 1735                    (array[index+3] & 0xff));
 1736       }
 1737   
 1738   
 1739       static void intToBigEndian(int value, byte[] array, int index) {
 1740               array[index]   = (byte) (value >> 24);
 1741               array[index+1] = (byte) (value >> 16);
 1742               array[index+2] = (byte) (value >>  8);
 1743               array[index+3] = (byte) (value);
 1744       }
 1745   
 1746   
 1747       static short shortFromBigEndian(byte[] array, int index) {
 1748           return (short) (((array[index]   & 0xff) << 8) |
 1749                            (array[index+1] & 0xff));
 1750       }
 1751   
 1752   
 1753       static void shortToBigEndian(short value, byte[] array, int index) {
 1754               array[index]   = (byte) (value >> 8);
 1755               array[index+1] = (byte) (value);
 1756       }
 1757   
 1758   
 1759       /*
 1760        * fileName may be an absolute or a relative file specification.
 1761        * Relative file names are looked for in several places: first, relative
 1762        * to any directories specified by the java.iccprofile.path property;
 1763        * second, relative to any directories specified by the java.class.path
 1764        * property; finally, in a directory used to store profiles always
 1765        * available, such as a profile for sRGB.  Built-in profiles use .pf as
 1766        * the file name extension for profiles, e.g. sRGB.pf.
 1767        */
 1768       private static FileInputStream openProfile(final String fileName) {
 1769           return (FileInputStream)java.security.AccessController.doPrivileged(
 1770               new java.security.PrivilegedAction() {
 1771               public Object run() {
 1772                   return privilegedOpenProfile(fileName);
 1773               }
 1774           });
 1775       }
 1776   
 1777       /*
 1778        * this version is called from doPrivileged in privilegedOpenProfile.
 1779        * the whole method is privileged!
 1780        */
 1781       private static FileInputStream privilegedOpenProfile(String fileName) {
 1782           FileInputStream fis = null;
 1783           String path, dir, fullPath;
 1784   
 1785           File f = new File(fileName); /* try absolute file name */
 1786   
 1787           if ((!f.isFile()) &&
 1788                   ((path = System.getProperty("java.iccprofile.path")) != null)){
 1789                                       /* try relative to java.iccprofile.path */
 1790                   StringTokenizer st =
 1791                       new StringTokenizer(path, File.pathSeparator);
 1792                   while (st.hasMoreTokens() && (!f.isFile())) {
 1793                       dir = st.nextToken();
 1794                           fullPath = dir + File.separatorChar + fileName;
 1795                       f = new File(fullPath);
 1796                   }
 1797               }
 1798   
 1799           if ((!f.isFile()) &&
 1800                   ((path = System.getProperty("java.class.path")) != null)) {
 1801                                       /* try relative to java.class.path */
 1802                   StringTokenizer st =
 1803                       new StringTokenizer(path, File.pathSeparator);
 1804                   while (st.hasMoreTokens() && (!f.isFile())) {
 1805                       dir = st.nextToken();
 1806                           fullPath = dir + File.separatorChar + fileName;
 1807                       f = new File(fullPath);
 1808                   }
 1809               }
 1810   
 1811           if (!f.isFile()) { /* try the directory of built-in profiles */
 1812                   dir = System.getProperty("java.home") +
 1813                       File.separatorChar + "lib" + File.separatorChar + "cmm";
 1814                   fullPath = dir + File.separatorChar + fileName;
 1815                   f = new File(fullPath);
 1816               }
 1817   
 1818           if (f.isFile()) {
 1819               try {
 1820                   fis = new FileInputStream(f);
 1821               } catch (FileNotFoundException e) {
 1822               }
 1823           }
 1824           return fis;
 1825       }
 1826   
 1827   
 1828       /*
 1829        * Serialization support.
 1830        *
 1831        * Directly deserialized profiles are useless since they are not
 1832        * registered with CMM.  We don't allow constructor to be called
 1833        * directly and instead have clients to call one of getInstance
 1834        * factory methods that will register the profile with CMM.  For
 1835        * deserialization we implement readResolve method that will
 1836        * resolve the bogus deserialized profile object with one obtained
 1837        * with getInstance as well.
 1838        *
 1839        * There're two primary factory methods for construction of ICC
 1840        * profiles: getInstance(int cspace) and getInstance(byte[] data).
 1841        * This implementation of ICC_Profile uses the former to return a
 1842        * cached singleton profile object, other implementations will
 1843        * likely use this technique too.  To preserve the singleton
 1844        * pattern across serialization we serialize cached singleton
 1845        * profiles in such a way that deserializing VM could call
 1846        * getInstance(int cspace) method that will resolve deserialized
 1847        * object into the corresponding singleton as well.
 1848        *
 1849        * Since the singletons are private to ICC_Profile the readResolve
 1850        * method have to be `protected' instead of `private' so that
 1851        * singletons that are instances of subclasses of ICC_Profile
 1852        * could be correctly deserialized.
 1853        */
 1854   
 1855   
 1856       /**
 1857        * Version of the format of additional serialized data in the
 1858        * stream.  Version&nbsp;<code>1</code> corresponds to Java&nbsp;2
 1859        * Platform,&nbsp;v1.3.
 1860        * @since 1.3
 1861        * @serial
 1862        */
 1863       private int iccProfileSerializedDataVersion = 1;
 1864   
 1865   
 1866       /**
 1867        * Writes default serializable fields to the stream.  Writes a
 1868        * string and an array of bytes to the stream as additional data.
 1869        *
 1870        * @param s stream used for serialization.
 1871        * @throws IOException
 1872        *     thrown by <code>ObjectInputStream</code>.
 1873        * @serialData
 1874        *     The <code>String</code> is the name of one of
 1875        *     <code>CS_<var>*</var></code> constants defined in the
 1876        *     {@link ColorSpace} class if the profile object is a profile
 1877        *     for a predefined color space (for example
 1878        *     <code>"CS_sRGB"</code>).  The string is <code>null</code>
 1879        *     otherwise.
 1880        *     <p>
 1881        *     The <code>byte[]</code> array is the profile data for the
 1882        *     profile.  For predefined color spaces <code>null</code> is
 1883        *     written instead of the profile data.  If in the future
 1884        *     versions of Java API new predefined color spaces will be
 1885        *     added, future versions of this class may choose to write
 1886        *     for new predefined color spaces not only the color space
 1887        *     name, but the profile data as well so that older versions
 1888        *     could still deserialize the object.
 1889        */
 1890       private void writeObject(ObjectOutputStream s)
 1891         throws IOException
 1892       {
 1893           s.defaultWriteObject();
 1894   
 1895           String csName = null;
 1896           if (this == sRGBprofile) {
 1897               csName = "CS_sRGB";
 1898           } else if (this == XYZprofile) {
 1899               csName = "CS_CIEXYZ";
 1900           } else if (this == PYCCprofile) {
 1901               csName = "CS_PYCC";
 1902           } else if (this == GRAYprofile) {
 1903               csName = "CS_GRAY";
 1904           } else if (this == LINEAR_RGBprofile) {
 1905               csName = "CS_LINEAR_RGB";
 1906           }
 1907   
 1908           // Future versions may choose to write profile data for new
 1909           // predefined color spaces as well, if any will be introduced,
 1910           // so that old versions that don't recognize the new CS name
 1911           // may fall back to constructing profile from the data.
 1912           byte[] data = null;
 1913           if (csName == null) {
 1914               // getData will activate deferred profile if necessary
 1915               data = getData();
 1916           }
 1917   
 1918           s.writeObject(csName);
 1919           s.writeObject(data);
 1920       }
 1921   
 1922       // Temporary storage used by readObject to store resolved profile
 1923       // (obtained with getInstance) for readResolve to return.
 1924       private transient ICC_Profile resolvedDeserializedProfile;
 1925   
 1926       /**
 1927        * Reads default serializable fields from the stream.  Reads from
 1928        * the stream a string and an array of bytes as additional data.
 1929        *
 1930        * @param s stream used for deserialization.
 1931        * @throws IOException
 1932        *     thrown by <code>ObjectInputStream</code>.
 1933        * @throws ClassNotFoundException
 1934        *     thrown by <code>ObjectInputStream</code>.
 1935        * @serialData
 1936        *     The <code>String</code> is the name of one of
 1937        *     <code>CS_<var>*</var></code> constants defined in the
 1938        *     {@link ColorSpace} class if the profile object is a profile
 1939        *     for a predefined color space (for example
 1940        *     <code>"CS_sRGB"</code>).  The string is <code>null</code>
 1941        *     otherwise.
 1942        *     <p>
 1943        *     The <code>byte[]</code> array is the profile data for the
 1944        *     profile.  It will usually be <code>null</code> for the
 1945        *     predefined profiles.
 1946        *     <p>
 1947        *     If the string is recognized as a constant name for
 1948        *     predefined color space the object will be resolved into
 1949        *     profile obtained with
 1950        *     <code>getInstance(int&nbsp;cspace)</code> and the profile
 1951        *     data are ignored.  Otherwise the object will be resolved
 1952        *     into profile obtained with
 1953        *     <code>getInstance(byte[]&nbsp;data)</code>.
 1954        * @see #readResolve()
 1955        * @see #getInstance(int)
 1956        * @see #getInstance(byte[])
 1957        */
 1958       private void readObject(ObjectInputStream s)
 1959         throws IOException, ClassNotFoundException
 1960       {
 1961           s.defaultReadObject();
 1962   
 1963           String csName = (String)s.readObject();
 1964           byte[] data = (byte[])s.readObject();
 1965   
 1966           int cspace = 0;         // ColorSpace.CS_* constant if known
 1967           boolean isKnownPredefinedCS = false;
 1968           if (csName != null) {
 1969               isKnownPredefinedCS = true;
 1970               if (csName.equals("CS_sRGB")) {
 1971                   cspace = ColorSpace.CS_sRGB;
 1972               } else if (csName.equals("CS_CIEXYZ")) {
 1973                   cspace = ColorSpace.CS_CIEXYZ;
 1974               } else if (csName.equals("CS_PYCC")) {
 1975                   cspace = ColorSpace.CS_PYCC;
 1976               } else if (csName.equals("CS_GRAY")) {
 1977                   cspace = ColorSpace.CS_GRAY;
 1978               } else if (csName.equals("CS_LINEAR_RGB")) {
 1979                   cspace = ColorSpace.CS_LINEAR_RGB;
 1980               } else {
 1981                   isKnownPredefinedCS = false;
 1982               }
 1983           }
 1984   
 1985           if (isKnownPredefinedCS) {
 1986               resolvedDeserializedProfile = getInstance(cspace);
 1987           } else {
 1988               resolvedDeserializedProfile = getInstance(data);
 1989           }
 1990       }
 1991   
 1992       /**
 1993        * Resolves instances being deserialized into instances registered
 1994        * with CMM.
 1995        * @return ICC_Profile object for profile registered with CMM.
 1996        * @throws ObjectStreamException
 1997        *     never thrown, but mandated by the serialization spec.
 1998        * @since 1.3
 1999        */
 2000       protected Object readResolve() throws ObjectStreamException {
 2001           return resolvedDeserializedProfile;
 2002       }
 2003   }

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