Home | History | Annotate | Download | only in color
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 /**
     18  * @author Oleg V. Khaschansky
     19  * @version $Revision$
     20  */
     21 
     22 package java.awt.color;
     23 
     24 import java.io.File;
     25 import java.io.FileInputStream;
     26 import java.io.FileNotFoundException;
     27 import java.io.FileOutputStream;
     28 import java.io.IOException;
     29 import java.io.InputStream;
     30 import java.io.ObjectInputStream;
     31 import java.io.ObjectOutputStream;
     32 import java.io.ObjectStreamException;
     33 import java.io.OutputStream;
     34 import java.io.Serializable;
     35 import java.security.AccessController;
     36 import java.security.PrivilegedAction;
     37 import java.util.StringTokenizer;
     38 
     39 import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
     40 import org.apache.harmony.awt.gl.color.NativeCMM;
     41 import org.apache.harmony.awt.internal.nls.Messages;
     42 
     43 /**
     44  * The ICC_Profile class represents a color profile data for color spaces based
     45  * on the International Color Consortium Specification ICC.1:2001-12, File
     46  * Format for Color Profiles.
     47  *
     48  * @since Android 1.0
     49  */
     50 public class ICC_Profile implements Serializable {
     51 
     52     /**
     53      * The Constant serialVersionUID.
     54      */
     55     private static final long serialVersionUID = -3938515861990936766L;
     56 
     57     // NOTE: Constant field values are noted in 1.5 specification.
     58 
     59     /**
     60      * The Constant CLASS_INPUT indicates that profile class is input.
     61      */
     62     public static final int CLASS_INPUT = 0;
     63 
     64     /**
     65      * The Constant CLASS_DISPLAY indicates that profile class is display.
     66      */
     67     public static final int CLASS_DISPLAY = 1;
     68 
     69     /**
     70      * The Constant CLASS_OUTPUT indicates that profile class is output.
     71      */
     72     public static final int CLASS_OUTPUT = 2;
     73 
     74     /**
     75      * The Constant CLASS_DEVICELINK indicates that profile class is device
     76      * link.
     77      */
     78     public static final int CLASS_DEVICELINK = 3;
     79 
     80     /**
     81      * The Constant CLASS_COLORSPACECONVERSION indicates that profile class is
     82      * color space conversion.
     83      */
     84     public static final int CLASS_COLORSPACECONVERSION = 4;
     85 
     86     /**
     87      * The Constant CLASS_ABSTRACT indicates that profile class is abstract.
     88      */
     89     public static final int CLASS_ABSTRACT = 5;
     90 
     91     /**
     92      * The Constant CLASS_NAMEDCOLOR indicates that profile class is named
     93      * color.
     94      */
     95     public static final int CLASS_NAMEDCOLOR = 6;
     96 
     97     /**
     98      * The Constant icSigXYZData - ICC Profile Color Space Type Signature.
     99      */
    100     public static final int icSigXYZData = 1482250784;
    101 
    102     /**
    103      * The Constant icSigLabData - ICC Profile Color Space Type Signature.
    104      */
    105     public static final int icSigLabData = 1281450528;
    106 
    107     /**
    108      * The Constant icSigLuvData - ICC Profile Color Space Type Signature.
    109      */
    110     public static final int icSigLuvData = 1282766368;
    111 
    112     /**
    113      * The Constant icSigYCbCrData - ICC Profile Color Space Type Signature.
    114      */
    115     public static final int icSigYCbCrData = 1497588338;
    116 
    117     /**
    118      * The Constant icSigYxyData - ICC Profile Color Space Type Signature.
    119      */
    120     public static final int icSigYxyData = 1501067552;
    121 
    122     /**
    123      * The Constant icSigRgbData - ICC Profile Color Space Type Signature.
    124      */
    125     public static final int icSigRgbData = 1380401696;
    126 
    127     /**
    128      * The Constant icSigGrayData - ICC Profile Color Space Type Signature.
    129      */
    130     public static final int icSigGrayData = 1196573017;
    131 
    132     /**
    133      * The Constant icSigHsvData - ICC Profile Color Space Type Signature.
    134      */
    135     public static final int icSigHsvData = 1213421088;
    136 
    137     /**
    138      * The Constant icSigHlsData - ICC Profile Color Space Type Signature.
    139      */
    140     public static final int icSigHlsData = 1212961568;
    141 
    142     /**
    143      * The Constant icSigCmykData - ICC Profile Color Space Type Signature.
    144      */
    145     public static final int icSigCmykData = 1129142603;
    146 
    147     /**
    148      * The Constant icSigCmyData - ICC Profile Color Space Type Signature.
    149      */
    150     public static final int icSigCmyData = 1129142560;
    151 
    152     /**
    153      * The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature.
    154      */
    155     public static final int icSigSpace2CLR = 843271250;
    156 
    157     /**
    158      * The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature.
    159      */
    160     public static final int icSigSpace3CLR = 860048466;
    161 
    162     /**
    163      * The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature.
    164      */
    165     public static final int icSigSpace4CLR = 876825682;
    166 
    167     /**
    168      * The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature.
    169      */
    170     public static final int icSigSpace5CLR = 893602898;
    171 
    172     /**
    173      * The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature.
    174      */
    175     public static final int icSigSpace6CLR = 910380114;
    176 
    177     /**
    178      * The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature.
    179      */
    180     public static final int icSigSpace7CLR = 927157330;
    181 
    182     /**
    183      * The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature.
    184      */
    185     public static final int icSigSpace8CLR = 943934546;
    186 
    187     /**
    188      * The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature.
    189      */
    190     public static final int icSigSpace9CLR = 960711762;
    191 
    192     /**
    193      * The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature.
    194      */
    195     public static final int icSigSpaceACLR = 1094929490;
    196 
    197     /**
    198      * The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature.
    199      */
    200     public static final int icSigSpaceBCLR = 1111706706;
    201 
    202     /**
    203      * The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature.
    204      */
    205     public static final int icSigSpaceCCLR = 1128483922;
    206 
    207     /**
    208      * The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature.
    209      */
    210     public static final int icSigSpaceDCLR = 1145261138;
    211 
    212     /**
    213      * The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature.
    214      */
    215     public static final int icSigSpaceECLR = 1162038354;
    216 
    217     /**
    218      * The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature.
    219      */
    220     public static final int icSigSpaceFCLR = 1178815570;
    221 
    222     /**
    223      * The Constant icSigInputClass - ICC Profile Class Signature.
    224      */
    225     public static final int icSigInputClass = 1935896178;
    226 
    227     /**
    228      * The Constant icSigDisplayClass - ICC Profile Class Signature.
    229      */
    230     public static final int icSigDisplayClass = 1835955314;
    231 
    232     /**
    233      * The Constant icSigOutputClass - ICC Profile Class Signature.
    234      */
    235     public static final int icSigOutputClass = 1886549106;
    236 
    237     /**
    238      * The Constant icSigLinkClass - ICC Profile Class Signature.
    239      */
    240     public static final int icSigLinkClass = 1818848875;
    241 
    242     /**
    243      * The Constant icSigAbstractClass - ICC Profile Class Signature.
    244      */
    245     public static final int icSigAbstractClass = 1633842036;
    246 
    247     /**
    248      * The Constant icSigColorantOrderTag - ICC Profile Tag Signature.
    249      */
    250     public static final int icSigColorantOrderTag = 1668051567;
    251 
    252     /**
    253      * The Constant icSigColorantTableTag - ICC Profile Tag Signature.
    254      */
    255     public static final int icSigColorantTableTag = 1668051572;
    256 
    257     /**
    258      * The Constant icSigColorSpaceClass - ICC Profile Tag Signature.
    259      */
    260     public static final int icSigColorSpaceClass = 1936744803;
    261 
    262     /**
    263      * The Constant icSigNamedColorClass - ICC Profile Tag Signature.
    264      */
    265     public static final int icSigNamedColorClass = 1852662636;
    266 
    267     /**
    268      * The Constant icPerceptual - ICC Profile Rendering Intent.
    269      */
    270     public static final int icPerceptual = 0;
    271 
    272     /**
    273      * The Constant icRelativeColorimetric - ICC Profile Rendering Intent.
    274      */
    275     public static final int icRelativeColorimetric = 1;
    276 
    277     /**
    278      * The Constant icSaturation - ICC Profile Rendering Intent.
    279      */
    280     public static final int icSaturation = 2;
    281 
    282     /**
    283      * The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent.
    284      */
    285     public static final int icAbsoluteColorimetric = 3;
    286 
    287     /**
    288      * The Constant icSigHead - ICC Profile Tag Signature.
    289      */
    290     public static final int icSigHead = 1751474532;
    291 
    292     /**
    293      * The Constant icSigAToB0Tag - ICC Profile Tag Signature.
    294      */
    295     public static final int icSigAToB0Tag = 1093812784;
    296 
    297     /**
    298      * The Constant icSigAToB1Tag - ICC Profile Tag Signature.
    299      */
    300     public static final int icSigAToB1Tag = 1093812785;
    301 
    302     /**
    303      * The Constant icSigAToB2Tag - ICC Profile Tag Signature.
    304      */
    305     public static final int icSigAToB2Tag = 1093812786;
    306 
    307     /**
    308      * The Constant icSigBlueColorantTag - ICC Profile Tag Signature.
    309      */
    310     public static final int icSigBlueColorantTag = 1649957210;
    311 
    312     /**
    313      * The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature.
    314      */
    315     public static final int icSigBlueMatrixColumnTag = 1649957210;
    316 
    317     /**
    318      * The Constant icSigBlueTRCTag - ICC Profile Tag Signature.
    319      */
    320     public static final int icSigBlueTRCTag = 1649693251;
    321 
    322     /**
    323      * The Constant icSigBToA0Tag - ICC Profile Tag Signature.
    324      */
    325     public static final int icSigBToA0Tag = 1110589744;
    326 
    327     /**
    328      * The Constant icSigBToA1Tag - ICC Profile Tag Signature.
    329      */
    330     public static final int icSigBToA1Tag = 1110589745;
    331 
    332     /**
    333      * The Constant icSigBToA2Tag - ICC Profile Tag Signature.
    334      */
    335     public static final int icSigBToA2Tag = 1110589746;
    336 
    337     /**
    338      * The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature.
    339      */
    340     public static final int icSigCalibrationDateTimeTag = 1667329140;
    341 
    342     /**
    343      * The Constant icSigCharTargetTag - ICC Profile Tag Signature.
    344      */
    345     public static final int icSigCharTargetTag = 1952543335;
    346 
    347     /**
    348      * The Constant icSigCopyrightTag - ICC Profile Tag Signature.
    349      */
    350     public static final int icSigCopyrightTag = 1668313716;
    351 
    352     /**
    353      * The Constant icSigCrdInfoTag - ICC Profile Tag Signature.
    354      */
    355     public static final int icSigCrdInfoTag = 1668441193;
    356 
    357     /**
    358      * The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature.
    359      */
    360     public static final int icSigDeviceMfgDescTag = 1684893284;
    361 
    362     /**
    363      * The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature.
    364      */
    365     public static final int icSigDeviceModelDescTag = 1684890724;
    366 
    367     /**
    368      * The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature.
    369      */
    370     public static final int icSigDeviceSettingsTag = 1684371059;
    371 
    372     /**
    373      * The Constant icSigGamutTag - ICC Profile Tag Signature.
    374      */
    375     public static final int icSigGamutTag = 1734438260;
    376 
    377     /**
    378      * The Constant icSigGrayTRCTag - ICC Profile Tag Signature.
    379      */
    380     public static final int icSigGrayTRCTag = 1800688195;
    381 
    382     /**
    383      * The Constant icSigGreenColorantTag - ICC Profile Tag Signature.
    384      */
    385     public static final int icSigGreenColorantTag = 1733843290;
    386 
    387     /**
    388      * The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature.
    389      */
    390     public static final int icSigGreenMatrixColumnTag = 1733843290;
    391 
    392     /**
    393      * The Constant icSigGreenTRCTag - ICC Profile Tag Signature.
    394      */
    395     public static final int icSigGreenTRCTag = 1733579331;
    396 
    397     /**
    398      * The Constant icSigLuminanceTag - ICC Profile Tag Signature.
    399      */
    400     public static final int icSigLuminanceTag = 1819635049;
    401 
    402     /**
    403      * The Constant icSigMeasurementTag - ICC Profile Tag Signature.
    404      */
    405     public static final int icSigMeasurementTag = 1835360627;
    406 
    407     /**
    408      * The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature.
    409      */
    410     public static final int icSigMediaBlackPointTag = 1651208308;
    411 
    412     /**
    413      * The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature.
    414      */
    415     public static final int icSigMediaWhitePointTag = 2004119668;
    416 
    417     /**
    418      * The Constant icSigNamedColor2Tag - ICC Profile Tag Signature.
    419      */
    420     public static final int icSigNamedColor2Tag = 1852009522;
    421 
    422     /**
    423      * The Constant icSigOutputResponseTag - ICC Profile Tag Signature.
    424      */
    425     public static final int icSigOutputResponseTag = 1919251312;
    426 
    427     /**
    428      * The Constant icSigPreview0Tag - ICC Profile Tag Signature.
    429      */
    430     public static final int icSigPreview0Tag = 1886545200;
    431 
    432     /**
    433      * The Constant icSigPreview1Tag - ICC Profile Tag Signature.
    434      */
    435     public static final int icSigPreview1Tag = 1886545201;
    436 
    437     /**
    438      * The Constant icSigPreview2Tag - ICC Profile Tag Signature.
    439      */
    440     public static final int icSigPreview2Tag = 1886545202;
    441 
    442     /**
    443      * The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature.
    444      */
    445     public static final int icSigProfileDescriptionTag = 1684370275;
    446 
    447     /**
    448      * The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature.
    449      */
    450     public static final int icSigProfileSequenceDescTag = 1886610801;
    451 
    452     /**
    453      * The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature.
    454      */
    455     public static final int icSigPs2CRD0Tag = 1886610480;
    456 
    457     /**
    458      * The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature.
    459      */
    460     public static final int icSigPs2CRD1Tag = 1886610481;
    461 
    462     /**
    463      * The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature.
    464      */
    465     public static final int icSigPs2CRD2Tag = 1886610482;
    466 
    467     /**
    468      * The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature.
    469      */
    470     public static final int icSigPs2CRD3Tag = 1886610483;
    471 
    472     /**
    473      * The Constant icSigPs2CSATag - ICC Profile Tag Signature.
    474      */
    475     public static final int icSigPs2CSATag = 1886597747;
    476 
    477     /**
    478      * The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature.
    479      */
    480     public static final int icSigPs2RenderingIntentTag = 1886597737;
    481 
    482     /**
    483      * The Constant icSigRedColorantTag - ICC Profile Tag Signature.
    484      */
    485     public static final int icSigRedColorantTag = 1918392666;
    486 
    487     /**
    488      * The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature.
    489      */
    490     public static final int icSigRedMatrixColumnTag = 1918392666;
    491 
    492     /**
    493      * The Constant icSigRedTRCTag - ICC Profile Tag Signature.
    494      */
    495     public static final int icSigRedTRCTag = 1918128707;
    496 
    497     /**
    498      * The Constant icSigScreeningDescTag - ICC Profile Tag Signature.
    499      */
    500     public static final int icSigScreeningDescTag = 1935897188;
    501 
    502     /**
    503      * The Constant icSigScreeningTag - ICC Profile Tag Signature.
    504      */
    505     public static final int icSigScreeningTag = 1935897198;
    506 
    507     /**
    508      * The Constant icSigTechnologyTag - ICC Profile Tag Signature.
    509      */
    510     public static final int icSigTechnologyTag = 1952801640;
    511 
    512     /**
    513      * The Constant icSigUcrBgTag - ICC Profile Tag Signature.
    514      */
    515     public static final int icSigUcrBgTag = 1650877472;
    516 
    517     /**
    518      * The Constant icSigViewingCondDescTag - ICC Profile Tag Signature.
    519      */
    520     public static final int icSigViewingCondDescTag = 1987405156;
    521 
    522     /**
    523      * The Constant icSigViewingConditionsTag - ICC Profile Tag Signature.
    524      */
    525     public static final int icSigViewingConditionsTag = 1986618743;
    526 
    527     /**
    528      * The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature.
    529      */
    530     public static final int icSigChromaticAdaptationTag = 1667785060;
    531 
    532     /**
    533      * The Constant icSigChromaticityTag - ICC Profile Tag Signature.
    534      */
    535     public static final int icSigChromaticityTag = 1667789421;
    536 
    537     /**
    538      * The Constant icHdrSize - ICC Profile Header Location.
    539      */
    540     public static final int icHdrSize = 0;
    541 
    542     /**
    543      * The Constant icHdrCmmId - ICC Profile Header Location.
    544      */
    545     public static final int icHdrCmmId = 4;
    546 
    547     /**
    548      * The Constant icHdrVersion - ICC Profile Header Location.
    549      */
    550     public static final int icHdrVersion = 8;
    551 
    552     /**
    553      * The Constant icHdrDeviceClass - ICC Profile Header Location.
    554      */
    555     public static final int icHdrDeviceClass = 12;
    556 
    557     /**
    558      * The Constant icHdrColorSpace - ICC Profile Header Location.
    559      */
    560     public static final int icHdrColorSpace = 16;
    561 
    562     /**
    563      * The Constant icHdrPcs - ICC Profile Header Location.
    564      */
    565     public static final int icHdrPcs = 20;
    566 
    567     /**
    568      * The Constant icHdrDate - ICC Profile Header Location.
    569      */
    570     public static final int icHdrDate = 24;
    571 
    572     /**
    573      * The Constant icHdrMagic - ICC Profile Header Location.
    574      */
    575     public static final int icHdrMagic = 36;
    576 
    577     /**
    578      * The Constant icHdrPlatform - ICC Profile Header Location.
    579      */
    580     public static final int icHdrPlatform = 40;
    581 
    582     /**
    583      * The Constant icHdrProfileID - ICC Profile Header Location.
    584      */
    585     public static final int icHdrProfileID = 84;
    586 
    587     /**
    588      * The Constant icHdrFlags - ICC Profile Header Location.
    589      */
    590     public static final int icHdrFlags = 44;
    591 
    592     /**
    593      * The Constant icHdrManufacturer - ICC Profile Header Location.
    594      */
    595     public static final int icHdrManufacturer = 48;
    596 
    597     /**
    598      * The Constant icHdrModel - ICC Profile Header Location.
    599      */
    600     public static final int icHdrModel = 52;
    601 
    602     /**
    603      * The Constant icHdrAttributes - ICC Profile Header Location.
    604      */
    605     public static final int icHdrAttributes = 56;
    606 
    607     /**
    608      * The Constant icHdrRenderingIntent - ICC Profile Header Location.
    609      */
    610     public static final int icHdrRenderingIntent = 64;
    611 
    612     /**
    613      * The Constant icHdrIlluminant - ICC Profile Header Location.
    614      */
    615     public static final int icHdrIlluminant = 68;
    616 
    617     /**
    618      * The Constant icHdrCreator - ICC Profile Header Location.
    619      */
    620     public static final int icHdrCreator = 80;
    621 
    622     /**
    623      * The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent.
    624      */
    625     public static final int icICCAbsoluteColorimetric = 3;
    626 
    627     /**
    628      * The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent.
    629      */
    630     public static final int icMediaRelativeColorimetric = 1;
    631 
    632     /**
    633      * The Constant icTagType - ICC Profile Constant.
    634      */
    635     public static final int icTagType = 0;
    636 
    637     /**
    638      * The Constant icTagReserved - ICC Profile Constant.
    639      */
    640     public static final int icTagReserved = 4;
    641 
    642     /**
    643      * The Constant icCurveCount - ICC Profile Constant.
    644      */
    645     public static final int icCurveCount = 8;
    646 
    647     /**
    648      * The Constant icCurveData - ICC Profile Constant.
    649      */
    650     public static final int icCurveData = 12;
    651 
    652     /**
    653      * The Constant icXYZNumberX - ICC Profile Constant.
    654      */
    655     public static final int icXYZNumberX = 8;
    656 
    657     /**
    658      * Size of a profile header.
    659      */
    660     private static final int headerSize = 128;
    661 
    662     /**
    663      * header magic number.
    664      */
    665     private static final int headerMagicNumber = 0x61637370;
    666 
    667     // Cache of predefined profiles
    668     /**
    669      * The s rgb profile.
    670      */
    671     private static ICC_Profile sRGBProfile;
    672 
    673     /**
    674      * The xyz profile.
    675      */
    676     private static ICC_Profile xyzProfile;
    677 
    678     /**
    679      * The gray profile.
    680      */
    681     private static ICC_Profile grayProfile;
    682 
    683     /**
    684      * The pycc profile.
    685      */
    686     private static ICC_Profile pyccProfile;
    687 
    688     /**
    689      * The linear rgb profile.
    690      */
    691     private static ICC_Profile linearRGBProfile;
    692 
    693     /**
    694      * Handle to the current profile.
    695      */
    696     private transient long profileHandle = 0;
    697 
    698     /**
    699      * If handle is used by another class this object is not responsible for
    700      * closing profile.
    701      */
    702     private transient boolean handleStolen = false;
    703 
    704     /**
    705      * Cached header data.
    706      */
    707     private transient byte[] headerData = null;
    708 
    709     /**
    710      * Serialization support.
    711      */
    712     private transient ICC_Profile openedProfileObject;
    713 
    714     /**
    715      * Instantiates a new ICC profile with the given data.
    716      *
    717      * @param data
    718      *            the data.
    719      */
    720     private ICC_Profile(byte[] data) {
    721         profileHandle = NativeCMM.cmmOpenProfile(data);
    722         NativeCMM.addHandle(this, profileHandle);
    723     }
    724 
    725     /**
    726      * Used to instantiate dummy ICC_ProfileStub objects.
    727      */
    728     ICC_Profile() {
    729     }
    730 
    731     /**
    732      * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
    733      *
    734      * @param profileHandle
    735      *            - should be valid handle to opened color profile
    736      */
    737     ICC_Profile(long profileHandle) {
    738         this.profileHandle = profileHandle;
    739         // A new object reference, need to add it.
    740         NativeCMM.addHandle(this, profileHandle);
    741     }
    742 
    743     /**
    744      * Writes the ICC_Profile to a file with the specified name.
    745      *
    746      * @param fileName
    747      *            the file name.
    748      * @throws IOException
    749      *             if an I/O exception has occurred during writing or opening
    750      *             the file.
    751      */
    752     public void write(String fileName) throws IOException {
    753         FileOutputStream oStream = new FileOutputStream(fileName);
    754         oStream.write(getData());
    755         oStream.close();
    756     }
    757 
    758     /**
    759      * Serializable implementation.
    760      *
    761      * @param s
    762      *            the s
    763      * @throws IOException
    764      *             Signals that an I/O exception has occurred.
    765      */
    766     private void writeObject(ObjectOutputStream s) throws IOException {
    767         s.defaultWriteObject();
    768         s.writeObject(null);
    769         s.writeObject(getData());
    770     }
    771 
    772     /**
    773      * Serializable implementation.
    774      *
    775      * @param s
    776      *            the s
    777      * @throws IOException
    778      *             Signals that an I/O exception has occurred.
    779      * @throws ClassNotFoundException
    780      *             the class not found exception
    781      */
    782     private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
    783         s.defaultReadObject();
    784         String colorSpaceStr = (String)s.readObject();
    785         byte[] data = (byte[])s.readObject();
    786 
    787         if (colorSpaceStr != null) {
    788             if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
    789                 openedProfileObject = getInstance(ColorSpace.CS_sRGB);
    790             } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
    791                 openedProfileObject = getInstance(ColorSpace.CS_GRAY);
    792             } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
    793                 openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
    794             } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
    795                 openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
    796             } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
    797                 openedProfileObject = getInstance(ColorSpace.CS_PYCC);
    798             } else {
    799                 openedProfileObject = ICC_Profile.getInstance(data);
    800             }
    801         } else {
    802             openedProfileObject = ICC_Profile.getInstance(data);
    803         }
    804     }
    805 
    806     /**
    807      * Resolves instances being deserialized into instances registered with CMM.
    808      *
    809      * @return ICC_Profile object for profile registered with CMM.
    810      * @throws ObjectStreamException
    811      *             if there is an error in the serialized files or during the
    812      *             process of reading them.
    813      */
    814     protected Object readResolve() throws ObjectStreamException {
    815         return openedProfileObject;
    816     }
    817 
    818     /**
    819      * Writes the ICC_Profile to an OutputStream.
    820      *
    821      * @param s
    822      *            the OutputStream.
    823      * @throws IOException
    824      *             signals that an I/O exception has occurred during writing or
    825      *             opening OutputStream.
    826      */
    827     public void write(OutputStream s) throws IOException {
    828         s.write(getData());
    829     }
    830 
    831     /**
    832      * Sets a tagged data element in the profile from a byte array.
    833      *
    834      * @param tagSignature
    835      *            the ICC tag signature for the data element to be set.
    836      * @param tagData
    837      *            the data to be set for the specified tag signature.
    838      */
    839     public void setData(int tagSignature, byte[] tagData) {
    840         NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
    841         // Remove cached header data if header is modified
    842         if (tagSignature == icSigHead) {
    843             headerData = null;
    844         }
    845     }
    846 
    847     /**
    848      * Gets a tagged data element from the profile as a byte array. Elements are
    849      * identified by tag signatures as defined in the ICC specification.
    850      *
    851      * @param tagSignature
    852      *            the ICC tag signature for the data element to get.
    853      * @return a byte array that contains the tagged data element.
    854      */
    855     public byte[] getData(int tagSignature) {
    856         int tagSize = 0;
    857         try {
    858             tagSize = NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
    859         } catch (CMMException e) {
    860             // We'll get this exception if there's no element with
    861             // the specified tag signature
    862             return null;
    863         }
    864 
    865         byte[] data = new byte[tagSize];
    866         NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
    867         return data;
    868     }
    869 
    870     /**
    871      * Gets a data byte array of this ICC_Profile.
    872      *
    873      * @return a byte array that contains the ICC Profile data.
    874      */
    875     public byte[] getData() {
    876         int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
    877         byte[] data = new byte[profileSize];
    878         NativeCMM.cmmGetProfile(profileHandle, data);
    879         return data;
    880     }
    881 
    882     /**
    883      * Frees the resources associated with an ICC_Profile object.
    884      */
    885     @Override
    886     protected void finalize() {
    887         if (profileHandle != 0 && !handleStolen) {
    888             NativeCMM.cmmCloseProfile(profileHandle);
    889         }
    890 
    891         // Always remove because key no more exist
    892         // when object is destroyed
    893         NativeCMM.removeHandle(this);
    894     }
    895 
    896     /**
    897      * Gets the profile class.
    898      *
    899      * @return the profile class constant.
    900      */
    901     public int getProfileClass() {
    902         int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
    903 
    904         switch (deviceClassSignature) {
    905             case icSigColorSpaceClass:
    906                 return CLASS_COLORSPACECONVERSION;
    907             case icSigDisplayClass:
    908                 return CLASS_DISPLAY;
    909             case icSigOutputClass:
    910                 return CLASS_OUTPUT;
    911             case icSigInputClass:
    912                 return CLASS_INPUT;
    913             case icSigLinkClass:
    914                 return CLASS_DEVICELINK;
    915             case icSigAbstractClass:
    916                 return CLASS_ABSTRACT;
    917             case icSigNamedColorClass:
    918                 return CLASS_NAMEDCOLOR;
    919             default:
    920         }
    921 
    922         // Not an ICC profile class
    923         // awt.15F=Profile class does not comply with ICC specification
    924         throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
    925 
    926     }
    927 
    928     /**
    929      * Gets the color space type of the Profile Connection Space (PCS).
    930      *
    931      * @return the PCS type.
    932      */
    933     public int getPCSType() {
    934         return csFromSignature(getIntFromHeader(icHdrPcs));
    935     }
    936 
    937     /**
    938      * Gets the number of components of this ICC Profile.
    939      *
    940      * @return the number of components of this ICC Profile.
    941      */
    942     public int getNumComponents() {
    943         switch (getIntFromHeader(icHdrColorSpace)) {
    944             // The most common cases go first to increase speed
    945             case icSigRgbData:
    946             case icSigXYZData:
    947             case icSigLabData:
    948                 return 3;
    949             case icSigCmykData:
    950                 return 4;
    951                 // Then all other
    952             case icSigGrayData:
    953                 return 1;
    954             case icSigSpace2CLR:
    955                 return 2;
    956             case icSigYCbCrData:
    957             case icSigLuvData:
    958             case icSigYxyData:
    959             case icSigHlsData:
    960             case icSigHsvData:
    961             case icSigCmyData:
    962             case icSigSpace3CLR:
    963                 return 3;
    964             case icSigSpace4CLR:
    965                 return 4;
    966             case icSigSpace5CLR:
    967                 return 5;
    968             case icSigSpace6CLR:
    969                 return 6;
    970             case icSigSpace7CLR:
    971                 return 7;
    972             case icSigSpace8CLR:
    973                 return 8;
    974             case icSigSpace9CLR:
    975                 return 9;
    976             case icSigSpaceACLR:
    977                 return 10;
    978             case icSigSpaceBCLR:
    979                 return 11;
    980             case icSigSpaceCCLR:
    981                 return 12;
    982             case icSigSpaceDCLR:
    983                 return 13;
    984             case icSigSpaceECLR:
    985                 return 14;
    986             case icSigSpaceFCLR:
    987                 return 15;
    988             default:
    989         }
    990 
    991         // awt.160=Color space doesn't comply with ICC specification
    992         throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
    993         );
    994     }
    995 
    996     /**
    997      * Gets the minor version of this ICC profile.
    998      *
    999      * @return the minor version of this ICC profile.
   1000      */
   1001     public int getMinorVersion() {
   1002         return getByteFromHeader(icHdrVersion + 1);
   1003     }
   1004 
   1005     /**
   1006      * Gets the major version of this ICC profile.
   1007      *
   1008      * @return the major version of this ICC profile.
   1009      */
   1010     public int getMajorVersion() {
   1011         return getByteFromHeader(icHdrVersion);
   1012     }
   1013 
   1014     /**
   1015      * Gets the color space type of this ICC_Profile.
   1016      *
   1017      * @return the color space type.
   1018      */
   1019     public int getColorSpaceType() {
   1020         return csFromSignature(getIntFromHeader(icHdrColorSpace));
   1021     }
   1022 
   1023     /**
   1024      * Tries to open the file at the specified path. Path entries can be divided
   1025      * by a separator character.
   1026      *
   1027      * @param path
   1028      *            the path to the file.
   1029      * @param fileName
   1030      *            the file name.
   1031      * @return the input stream to read the file.
   1032      */
   1033     private static FileInputStream tryPath(String path, String fileName) {
   1034         FileInputStream fiStream = null;
   1035 
   1036         if (path == null) {
   1037             return null;
   1038         }
   1039 
   1040         StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
   1041 
   1042         while (st.hasMoreTokens()) {
   1043             String pathEntry = st.nextToken();
   1044             try {
   1045                 fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
   1046                 if (fiStream != null) {
   1047                     return fiStream;
   1048                 }
   1049             } catch (FileNotFoundException e) {
   1050             }
   1051         }
   1052 
   1053         return fiStream;
   1054     }
   1055 
   1056     /**
   1057      * Gets the single instance of ICC_Profile from data in the specified file.
   1058      *
   1059      * @param fileName
   1060      *            the specified name of file with ICC profile data.
   1061      * @return single instance of ICC_Profile.
   1062      * @throws IOException
   1063      *             signals that an I/O error occurred while reading the file or
   1064      *             the file does not exist.
   1065      */
   1066     public static ICC_Profile getInstance(String fileName) throws IOException {
   1067         final String fName = fileName; // to use in the privileged block
   1068 
   1069         FileInputStream fiStream = (FileInputStream)AccessController
   1070                 .doPrivileged(new PrivilegedAction<FileInputStream>() {
   1071                     public FileInputStream run() {
   1072                         FileInputStream fiStream = null;
   1073 
   1074                         // Open absolute path
   1075                         try {
   1076                             fiStream = new FileInputStream(fName);
   1077                             if (fiStream != null) {
   1078                                 return fiStream;
   1079                             }
   1080                         } catch (FileNotFoundException e) {
   1081                         }
   1082 
   1083                         // Check java.iccprofile.path entries
   1084                         fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
   1085                         if (fiStream != null) {
   1086                             return fiStream;
   1087                         }
   1088 
   1089                         // Check java.class.path entries
   1090                         fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
   1091                         if (fiStream != null) {
   1092                             return fiStream;
   1093                         }
   1094 
   1095                         // Check directory with java sample profiles
   1096                         String home = System.getProperty("java.home"); //$NON-NLS-1$
   1097                         if (home != null) {
   1098                             fiStream = tryPath(home + File.separatorChar
   1099                                     + "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
   1100                             );
   1101                         }
   1102 
   1103                         return fiStream;
   1104                     }
   1105                 });
   1106 
   1107         if (fiStream == null) {
   1108             // awt.161=Unable to open file {0}
   1109             throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
   1110         }
   1111 
   1112         ICC_Profile pf = getInstance(fiStream);
   1113         fiStream.close();
   1114         return pf;
   1115     }
   1116 
   1117     /**
   1118      * Gets the single instance of ICC_Profile with data in the specified
   1119      * InputStream.
   1120      *
   1121      * @param s
   1122      *            the InputStream with ICC profile data.
   1123      * @return single instance of ICC_Profile.
   1124      * @throws IOException
   1125      *             if an I/O exception has occurred during reading from
   1126      *             InputStream.
   1127      * @throws IllegalArgumentException
   1128      *             if the file does not contain valid ICC Profile data.
   1129      */
   1130     public static ICC_Profile getInstance(InputStream s) throws IOException {
   1131         byte[] header = new byte[headerSize];
   1132         // awt.162=Invalid ICC Profile Data
   1133         String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
   1134 
   1135         // Get header from the input stream
   1136         if (s.read(header) != headerSize) {
   1137             throw new IllegalArgumentException(invalidDataMessage);
   1138         }
   1139 
   1140         // Check the profile data for consistency
   1141         if (ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) != headerMagicNumber) {
   1142             throw new IllegalArgumentException(invalidDataMessage);
   1143         }
   1144 
   1145         // Get profile size from header, create an array for profile data
   1146         int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
   1147         byte[] profileData = new byte[profileSize];
   1148 
   1149         // Copy header into it
   1150         System.arraycopy(header, 0, profileData, 0, headerSize);
   1151 
   1152         // Read the profile itself
   1153         if (s.read(profileData, headerSize, profileSize - headerSize) != profileSize - headerSize) {
   1154             throw new IllegalArgumentException(invalidDataMessage);
   1155         }
   1156 
   1157         return getInstance(profileData);
   1158     }
   1159 
   1160     /**
   1161      * Gets the single instance of ICC_Profile from the specified data in a byte
   1162      * array.
   1163      *
   1164      * @param data
   1165      *            the byte array of ICC profile.
   1166      * @return single instance of ICC_Profile from the specified data in a byte
   1167      *         array.
   1168      * @throws IllegalArgumentException
   1169      *             if the file does not contain valid ICC Profile data.
   1170      */
   1171     public static ICC_Profile getInstance(byte[] data) {
   1172         ICC_Profile res = null;
   1173 
   1174         try {
   1175             res = new ICC_Profile(data);
   1176         } catch (CMMException e) {
   1177             // awt.162=Invalid ICC Profile Data
   1178             throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
   1179         }
   1180 
   1181         if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
   1182             try {
   1183                 if (res.getColorSpaceType() == ColorSpace.TYPE_RGB
   1184                         && res.getDataSize(icSigMediaWhitePointTag) > 0
   1185                         && res.getDataSize(icSigRedColorantTag) > 0
   1186                         && res.getDataSize(icSigGreenColorantTag) > 0
   1187                         && res.getDataSize(icSigBlueColorantTag) > 0
   1188                         && res.getDataSize(icSigRedTRCTag) > 0
   1189                         && res.getDataSize(icSigGreenTRCTag) > 0
   1190                         && res.getDataSize(icSigBlueTRCTag) > 0) {
   1191                     res = new ICC_ProfileRGB(res.getProfileHandle());
   1192                 } else if (res.getColorSpaceType() == ColorSpace.TYPE_GRAY
   1193                         && res.getDataSize(icSigMediaWhitePointTag) > 0
   1194                         && res.getDataSize(icSigGrayTRCTag) > 0) {
   1195                     res = new ICC_ProfileGray(res.getProfileHandle());
   1196                 }
   1197 
   1198             } catch (CMMException e) { /* return res in this case */
   1199             }
   1200         }
   1201 
   1202         return res;
   1203     }
   1204 
   1205     /**
   1206      * Gets the single instance of ICC_Profile with the specific color space
   1207      * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
   1208      * CS_PYCC, CS_GRAY.
   1209      *
   1210      * @param cspace
   1211      *            the type of color space defined in the ColorSpace class.
   1212      * @return single instance of ICC_Profile.
   1213      * @throws IllegalArgumentException
   1214      *             is not one of the defined color space types.
   1215      */
   1216     public static ICC_Profile getInstance(int cspace) {
   1217         try {
   1218             switch (cspace) {
   1219 
   1220                 case ColorSpace.CS_sRGB:
   1221                     if (sRGBProfile == null) {
   1222                         sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
   1223                     }
   1224                     return sRGBProfile;
   1225 
   1226                 case ColorSpace.CS_CIEXYZ:
   1227                     if (xyzProfile == null) {
   1228                         xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
   1229                     }
   1230                     return xyzProfile;
   1231 
   1232                 case ColorSpace.CS_GRAY:
   1233                     if (grayProfile == null) {
   1234                         grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
   1235                     }
   1236                     return grayProfile;
   1237 
   1238                 case ColorSpace.CS_PYCC:
   1239                     if (pyccProfile == null) {
   1240                         pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
   1241                     }
   1242                     return pyccProfile;
   1243 
   1244                 case ColorSpace.CS_LINEAR_RGB:
   1245                     if (linearRGBProfile == null) {
   1246                         linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
   1247                     }
   1248                     return linearRGBProfile;
   1249             }
   1250 
   1251         } catch (IOException e) {
   1252             // awt.163=Can't open color profile
   1253             throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
   1254         }
   1255 
   1256         // awt.164=Not a predefined color space
   1257         throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
   1258     }
   1259 
   1260     /**
   1261      * Reads an integer from the profile header at the specified position.
   1262      *
   1263      * @param idx
   1264      *            - offset in bytes from the beginning of the header
   1265      * @return the integer value from header
   1266      */
   1267     private int getIntFromHeader(int idx) {
   1268         if (headerData == null) {
   1269             headerData = getData(icSigHead);
   1270         }
   1271 
   1272         return ((headerData[idx] & 0xFF) << 24) | ((headerData[idx + 1] & 0xFF) << 16)
   1273                 | ((headerData[idx + 2] & 0xFF) << 8) | ((headerData[idx + 3] & 0xFF));
   1274     }
   1275 
   1276     /**
   1277      * Reads byte from the profile header at the specified position.
   1278      *
   1279      * @param idx
   1280      *            - offset in bytes from the beginning of the header
   1281      * @return the byte from header
   1282      */
   1283     private byte getByteFromHeader(int idx) {
   1284         if (headerData == null) {
   1285             headerData = getData(icSigHead);
   1286         }
   1287 
   1288         return headerData[idx];
   1289     }
   1290 
   1291     /**
   1292      * Converts ICC color space signature to the java predefined color space
   1293      * type.
   1294      *
   1295      * @param signature
   1296      *            the signature
   1297      * @return the int
   1298      */
   1299     private int csFromSignature(int signature) {
   1300         switch (signature) {
   1301             case icSigRgbData:
   1302                 return ColorSpace.TYPE_RGB;
   1303             case icSigXYZData:
   1304                 return ColorSpace.TYPE_XYZ;
   1305             case icSigCmykData:
   1306                 return ColorSpace.TYPE_CMYK;
   1307             case icSigLabData:
   1308                 return ColorSpace.TYPE_Lab;
   1309             case icSigGrayData:
   1310                 return ColorSpace.TYPE_GRAY;
   1311             case icSigHlsData:
   1312                 return ColorSpace.TYPE_HLS;
   1313             case icSigLuvData:
   1314                 return ColorSpace.TYPE_Luv;
   1315             case icSigYCbCrData:
   1316                 return ColorSpace.TYPE_YCbCr;
   1317             case icSigYxyData:
   1318                 return ColorSpace.TYPE_Yxy;
   1319             case icSigHsvData:
   1320                 return ColorSpace.TYPE_HSV;
   1321             case icSigCmyData:
   1322                 return ColorSpace.TYPE_CMY;
   1323             case icSigSpace2CLR:
   1324                 return ColorSpace.TYPE_2CLR;
   1325             case icSigSpace3CLR:
   1326                 return ColorSpace.TYPE_3CLR;
   1327             case icSigSpace4CLR:
   1328                 return ColorSpace.TYPE_4CLR;
   1329             case icSigSpace5CLR:
   1330                 return ColorSpace.TYPE_5CLR;
   1331             case icSigSpace6CLR:
   1332                 return ColorSpace.TYPE_6CLR;
   1333             case icSigSpace7CLR:
   1334                 return ColorSpace.TYPE_7CLR;
   1335             case icSigSpace8CLR:
   1336                 return ColorSpace.TYPE_8CLR;
   1337             case icSigSpace9CLR:
   1338                 return ColorSpace.TYPE_9CLR;
   1339             case icSigSpaceACLR:
   1340                 return ColorSpace.TYPE_ACLR;
   1341             case icSigSpaceBCLR:
   1342                 return ColorSpace.TYPE_BCLR;
   1343             case icSigSpaceCCLR:
   1344                 return ColorSpace.TYPE_CCLR;
   1345             case icSigSpaceDCLR:
   1346                 return ColorSpace.TYPE_DCLR;
   1347             case icSigSpaceECLR:
   1348                 return ColorSpace.TYPE_ECLR;
   1349             case icSigSpaceFCLR:
   1350                 return ColorSpace.TYPE_FCLR;
   1351             default:
   1352         }
   1353 
   1354         // awt.165=Color space doesn't comply with ICC specification
   1355         throw new IllegalArgumentException(Messages.getString("awt.165")); //$NON-NLS-1$
   1356     }
   1357 
   1358     /**
   1359      * Gets the profile handle.
   1360      *
   1361      * @return the profile handle
   1362      */
   1363     private long getProfileHandle() {
   1364         handleStolen = true;
   1365         return profileHandle;
   1366     }
   1367 
   1368     /**
   1369      * Gets the data size.
   1370      *
   1371      * @param tagSignature
   1372      *            the tag signature
   1373      * @return the data size
   1374      */
   1375     private int getDataSize(int tagSignature) {
   1376         return NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
   1377     }
   1378 
   1379     /**
   1380      * Reads XYZ value from the tag data.
   1381      *
   1382      * @param tagSignature
   1383      *            the tag signature
   1384      * @return the XYZ value
   1385      */
   1386     float[] getXYZValue(int tagSignature) {
   1387         float[] res = new float[3];
   1388         byte[] data = getData(tagSignature);
   1389 
   1390         // Convert from ICC s15Fixed16Number type
   1391         // 1 (float) = 0x10000 (s15Fixed16Number),
   1392         // hence dividing by 0x10000
   1393         res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
   1394         res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
   1395         res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
   1396 
   1397         return res;
   1398     }
   1399 
   1400     /**
   1401      * Gets the media white point.
   1402      *
   1403      * @return the media white point.
   1404      */
   1405     float[] getMediaWhitePoint() {
   1406         return getXYZValue(icSigMediaWhitePointTag);
   1407     }
   1408 
   1409     /**
   1410      * If TRC is not a table returns gamma via return value and sets dataTRC to
   1411      * null. If TRC is a table returns 0 and fills dataTRC with values.
   1412      *
   1413      * @param tagSignature
   1414      *            the tag signature
   1415      * @param dataTRC
   1416      *            the data trc
   1417      * @return - gamma or zero if TRC is a table
   1418      */
   1419     private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
   1420         byte[] data = getData(tagSignature);
   1421         int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
   1422 
   1423         dataTRC = null;
   1424 
   1425         if (trcSize == 0) {
   1426             return 1.0f;
   1427         }
   1428 
   1429         if (trcSize == 1) {
   1430             // Cast from ICC u8Fixed8Number to float
   1431             return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
   1432         }
   1433 
   1434         // TRC is a table
   1435         dataTRC = new short[trcSize];
   1436         for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
   1437             dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
   1438         }
   1439         return 0;
   1440     }
   1441 
   1442     /**
   1443      * Gets the gamma.
   1444      *
   1445      * @param tagSignature
   1446      *            the tag signature
   1447      * @return the gamma
   1448      */
   1449     float getGamma(int tagSignature) {
   1450         short[] dataTRC = null;
   1451         float gamma = getGammaOrTRC(tagSignature, dataTRC);
   1452 
   1453         if (dataTRC == null) {
   1454             return gamma;
   1455         }
   1456         // awt.166=TRC is not a simple gamma value.
   1457         throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
   1458     }
   1459 
   1460     /**
   1461      * Gets the TRC.
   1462      *
   1463      * @param tagSignature
   1464      *            the tag signature
   1465      * @return the tRC
   1466      */
   1467     short[] getTRC(int tagSignature) {
   1468         short[] dataTRC = null;
   1469         getGammaOrTRC(tagSignature, dataTRC);
   1470 
   1471         if (dataTRC == null) {
   1472             // awt.167=TRC is a gamma value, not a table.
   1473             throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
   1474         }
   1475         return dataTRC;
   1476     }
   1477 }
   1478