jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c
changeset 6482 0f6a4442b29e
parent 5506 202f599c92aa
child 14300 117dc9b98a7b
equal deleted inserted replaced
6481:78d56f33c3a7 6482:0f6a4442b29e
    25 // This file is available under and governed by the GNU General Public
    25 // This file is available under and governed by the GNU General Public
    26 // License version 2 only, as published by the Free Software Foundation.
    26 // License version 2 only, as published by the Free Software Foundation.
    27 // However, the following notice accompanied the original version of this
    27 // However, the following notice accompanied the original version of this
    28 // file:
    28 // file:
    29 //
    29 //
    30 //
    30 //---------------------------------------------------------------------------------
    31 //  Little cms
    31 //
    32 //  Copyright (C) 1998-2007 Marti Maria
    32 //  Little Color Management System
       
    33 //  Copyright (c) 1998-2010 Marti Maria Saguer
    33 //
    34 //
    34 // Permission is hereby granted, free of charge, to any person obtaining
    35 // Permission is hereby granted, free of charge, to any person obtaining
    35 // a copy of this software and associated documentation files (the "Software"),
    36 // a copy of this software and associated documentation files (the "Software"),
    36 // to deal in the Software without restriction, including without limitation
    37 // to deal in the Software without restriction, including without limitation
    37 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
    38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
    46 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    47 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    48 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    49 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    50 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    51 
    52 //
    52 
    53 //---------------------------------------------------------------------------------
       
    54 //
       
    55 
       
    56 #include "lcms2_internal.h"
    53 
    57 
    54 // CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
    58 // CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
    55 
    59 
    56 #include "lcms.h"
       
    57 
       
    58 
       
    59 LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC);
       
    60 LCMSAPI void       LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel);
       
    61 LCMSAPI void       LCMSEXPORT cmsCIECAM02Forward(LCMSHANDLE hModel, LPcmsCIEXYZ pIn, LPcmsJCh pOut);
       
    62 LCMSAPI void       LCMSEXPORT cmsCIECAM02Reverse(LCMSHANDLE hModel, LPcmsJCh pIn,    LPcmsCIEXYZ pOut);
       
    63 
       
    64 
       
    65 // ---------- Implementation --------------------------------------------
    60 // ---------- Implementation --------------------------------------------
    66 
    61 
    67 typedef struct  {
    62 typedef struct  {
    68 
    63 
    69     double XYZ[3];
    64     cmsFloat64Number XYZ[3];
    70     double RGB[3];
    65     cmsFloat64Number RGB[3];
    71     double RGBc[3];
    66     cmsFloat64Number RGBc[3];
    72     double RGBp[3];
    67     cmsFloat64Number RGBp[3];
    73     double RGBpa[3];
    68     cmsFloat64Number RGBpa[3];
    74     double a, b, h, e, H, A, J, Q, s, t, C, M;
    69     cmsFloat64Number a, b, h, e, H, A, J, Q, s, t, C, M;
    75     double abC[2];
    70     cmsFloat64Number abC[2];
    76     double abs[2];
    71     cmsFloat64Number abs[2];
    77     double abM[2];
    72     cmsFloat64Number abM[2];
    78 
    73 
    79 } CAM02COLOR, *LPCAM02COLOR;
    74 } CAM02COLOR;
    80 
    75 
    81 typedef struct  {
    76 typedef struct  {
    82 
    77 
    83     CAM02COLOR adoptedWhite;
    78     CAM02COLOR adoptedWhite;
    84     double LA, Yb;
    79     cmsFloat64Number LA, Yb;
    85     double F, c, Nc;
    80     cmsFloat64Number F, c, Nc;
    86     int surround;
    81     cmsUInt32Number surround;
    87     double n, Nbb, Ncb, z, FL, D;
    82     cmsFloat64Number n, Nbb, Ncb, z, FL, D;
    88 
    83 
    89 } cmsCIECAM02, *LPcmsCIECAM02;
    84        cmsContext ContextID;
    90 
    85 
    91 
    86 } cmsCIECAM02;
    92 static
    87 
    93 double compute_n(LPcmsCIECAM02 pMod)
    88 
    94 {
    89 static
    95     return(pMod -> Yb / pMod -> adoptedWhite.XYZ[1]);
    90 cmsFloat64Number compute_n(cmsCIECAM02* pMod)
    96 }
    91 {
    97 
    92     return (pMod -> Yb / pMod -> adoptedWhite.XYZ[1]);
    98 static
    93 }
    99 double compute_z(LPcmsCIECAM02 pMod)
    94 
   100 {
    95 static
   101     return(1.48 + pow(pMod -> n, 0.5));
    96 cmsFloat64Number compute_z(cmsCIECAM02* pMod)
   102 }
    97 {
   103 
    98     return (1.48 + pow(pMod -> n, 0.5));
   104 static
    99 }
   105 double computeNbb(LPcmsCIECAM02 pMod)
   100 
   106 {
   101 static
   107     return(0.725 * pow((1.0 / pMod -> n), 0.2));
   102 cmsFloat64Number computeNbb(cmsCIECAM02* pMod)
   108 }
   103 {
   109 
   104     return (0.725 * pow((1.0 / pMod -> n), 0.2));
   110 static
   105 }
   111 double computeFL(LPcmsCIECAM02 pMod)
   106 
   112 {
   107 static
   113     double k, FL;
   108 cmsFloat64Number computeFL(cmsCIECAM02* pMod)
       
   109 {
       
   110     cmsFloat64Number k, FL;
   114 
   111 
   115     k = 1.0 / ((5.0 * pMod->LA) + 1.0);
   112     k = 1.0 / ((5.0 * pMod->LA) + 1.0);
   116     FL = 0.2 * pow(k, 4.0) * (5.0 * pMod->LA) + 0.1 *
   113     FL = 0.2 * pow(k, 4.0) * (5.0 * pMod->LA) + 0.1 *
   117         (pow((1.0 - pow(k, 4.0)), 2.0)) *
   114         (pow((1.0 - pow(k, 4.0)), 2.0)) *
   118         (pow((5.0 * pMod->LA), (1.0 / 3.0)));
   115         (pow((5.0 * pMod->LA), (1.0 / 3.0)));
   119 
   116 
   120     return FL;
   117     return FL;
   121 }
   118 }
   122 
   119 
   123 static
   120 static
   124 double computeD(LPcmsCIECAM02 pMod)
   121 cmsFloat64Number computeD(cmsCIECAM02* pMod)
   125 {
   122 {
   126     double D;
   123     cmsFloat64Number D;
   127 
   124 
   128     D = pMod->F - (1.0/3.6)*(exp(((-pMod ->LA-42) / 92.0)));
   125     D = pMod->F - (1.0/3.6)*(exp(((-pMod ->LA-42) / 92.0)));
   129 
   126 
   130     return D;
   127     return D;
   131 }
   128 }
   140 
   137 
   141     return clr;
   138     return clr;
   142 }
   139 }
   143 
   140 
   144 static
   141 static
   145 CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, LPcmsCIECAM02 pMod)
   142 CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
   146 {
   143 {
   147     int i;
   144     cmsUInt32Number i;
       
   145 
   148     for (i = 0; i < 3; i++) {
   146     for (i = 0; i < 3; i++) {
   149         clr.RGBc[i] = ((pMod -> adoptedWhite.XYZ[1] *
   147         clr.RGBc[i] = ((pMod -> adoptedWhite.XYZ[1] *
   150             (pMod->D / pMod -> adoptedWhite.RGB[i])) +
   148             (pMod->D / pMod -> adoptedWhite.RGB[i])) +
   151             (1.0 - pMod->D)) * clr.RGB[i];
   149             (1.0 - pMod->D)) * clr.RGB[i];
   152     }
   150     }
   154     return clr;
   152     return clr;
   155 }
   153 }
   156 
   154 
   157 
   155 
   158 static
   156 static
   159 CAM02COLOR CAT02toHPE (CAM02COLOR clr)
   157 CAM02COLOR CAT02toHPE(CAM02COLOR clr)
   160 {
   158 {
   161 
   159     cmsFloat64Number M[9];
   162     double M[9];
       
   163 
       
   164 
   160 
   165     M[0] =(( 0.38971 *  1.096124) + (0.68898 * 0.454369) + (-0.07868 * -0.009628));
   161     M[0] =(( 0.38971 *  1.096124) + (0.68898 * 0.454369) + (-0.07868 * -0.009628));
   166     M[1] =(( 0.38971 * -0.278869) + (0.68898 * 0.473533) + (-0.07868 * -0.005698));
   162     M[1] =(( 0.38971 * -0.278869) + (0.68898 * 0.473533) + (-0.07868 * -0.005698));
   167     M[2] =(( 0.38971 *  0.182745) + (0.68898 * 0.072098) + (-0.07868 *  1.015326));
   163     M[2] =(( 0.38971 *  0.182745) + (0.68898 * 0.072098) + (-0.07868 *  1.015326));
   168     M[3] =((-0.22981 *  1.096124) + (1.18340 * 0.454369) + ( 0.04641 * -0.009628));
   164     M[3] =((-0.22981 *  1.096124) + (1.18340 * 0.454369) + ( 0.04641 * -0.009628));
   178 
   174 
   179     return  clr;
   175     return  clr;
   180 }
   176 }
   181 
   177 
   182 static
   178 static
   183 CAM02COLOR NonlinearCompression(CAM02COLOR clr, LPcmsCIECAM02 pMod)
   179 CAM02COLOR NonlinearCompression(CAM02COLOR clr, cmsCIECAM02* pMod)
   184 {
   180 {
   185     int i;
   181     cmsUInt32Number i;
   186     double temp;
   182     cmsFloat64Number temp;
   187 
   183 
   188     for (i = 0; i < 3; i++) {
   184     for (i = 0; i < 3; i++) {
   189         if (clr.RGBp[i] < 0) {
   185         if (clr.RGBp[i] < 0) {
   190 
   186 
   191             temp = pow((-1.0 * pMod->FL * clr.RGBp[i] / 100.0), 0.42);
   187             temp = pow((-1.0 * pMod->FL * clr.RGBp[i] / 100.0), 0.42);
   202 
   198 
   203     return clr;
   199     return clr;
   204 }
   200 }
   205 
   201 
   206 static
   202 static
   207 CAM02COLOR ComputeCorrelates(CAM02COLOR clr, LPcmsCIECAM02 pMod)
   203 CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
   208 {
   204 {
   209     double a, b, temp, e, t, r2d, d2r;
   205     cmsFloat64Number a, b, temp, e, t, r2d, d2r;
   210 
   206 
   211     a = clr.RGBpa[0] - (12.0 * clr.RGBpa[1] / 11.0) + (clr.RGBpa[2] / 11.0);
   207     a = clr.RGBpa[0] - (12.0 * clr.RGBpa[1] / 11.0) + (clr.RGBpa[2] / 11.0);
   212     b = (clr.RGBpa[0] + clr.RGBpa[1] - (2.0 * clr.RGBpa[2])) / 9.0;
   208     b = (clr.RGBpa[0] + clr.RGBpa[1] - (2.0 * clr.RGBpa[2])) / 9.0;
   213 
   209 
   214     r2d = (180.0 / 3.141592654);
   210     r2d = (180.0 / 3.141592654);
   272     return clr;
   268     return clr;
   273 }
   269 }
   274 
   270 
   275 
   271 
   276 static
   272 static
   277 CAM02COLOR InverseCorrelates(CAM02COLOR clr, LPcmsCIECAM02 pMod)
   273 CAM02COLOR InverseCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
   278 {
   274 {
   279 
   275 
   280     double t, e, p1, p2, p3, p4, p5, hr, d2r;
   276     cmsFloat64Number t, e, p1, p2, p3, p4, p5, hr, d2r;
   281     d2r = 3.141592654 / 180.0;
   277     d2r = 3.141592654 / 180.0;
   282 
   278 
   283     t = pow( (clr.C / (pow((clr.J / 100.0), 0.5) *
   279     t = pow( (clr.C / (pow((clr.J / 100.0), 0.5) *
   284         (pow((1.64 - pow(0.29, pMod->n)), 0.73)))),
   280         (pow((1.64 - pow(0.29, pMod->n)), 0.73)))),
   285         (1.0 / 0.9) );
   281         (1.0 / 0.9) );
   325 
   321 
   326     return clr;
   322     return clr;
   327 }
   323 }
   328 
   324 
   329 static
   325 static
   330 CAM02COLOR InverseNonlinearity(CAM02COLOR clr, LPcmsCIECAM02 pMod)
   326 CAM02COLOR InverseNonlinearity(CAM02COLOR clr, cmsCIECAM02* pMod)
   331 {
   327 {
   332     int i;
   328     cmsUInt32Number i;
   333     double c1;
   329     cmsFloat64Number c1;
   334 
   330 
   335     for (i = 0; i < 3; i++) {
   331     for (i = 0; i < 3; i++) {
   336         if ((clr.RGBpa[i] - 0.1) < 0) c1 = -1;
   332         if ((clr.RGBpa[i] - 0.1) < 0) c1 = -1;
   337         else                               c1 = 1;
   333         else                               c1 = 1;
   338         clr.RGBp[i] = c1 * (100.0 / pMod->FL) *
   334         clr.RGBp[i] = c1 * (100.0 / pMod->FL) *
   345 }
   341 }
   346 
   342 
   347 static
   343 static
   348 CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
   344 CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
   349 {
   345 {
   350     double M[9];
   346     cmsFloat64Number M[9];
   351 
   347 
   352     M[0] = (( 0.7328 *  1.910197) + (0.4296 * 0.370950));
   348     M[0] = (( 0.7328 *  1.910197) + (0.4296 * 0.370950));
   353     M[1] = (( 0.7328 * -1.112124) + (0.4296 * 0.629054));
   349     M[1] = (( 0.7328 * -1.112124) + (0.4296 * 0.629054));
   354     M[2] = (( 0.7328 *  0.201908) + (0.4296 * 0.000008) - 0.1624);
   350     M[2] = (( 0.7328 *  0.201908) + (0.4296 * 0.000008) - 0.1624);
   355     M[3] = ((-0.7036 *  1.910197) + (1.6975 * 0.370950));
   351     M[3] = ((-0.7036 *  1.910197) + (1.6975 * 0.370950));
   360     M[8] = (( 0.0030 *  0.201908) + (0.0136 * 0.000008) + 0.9834);;
   356     M[8] = (( 0.0030 *  0.201908) + (0.0136 * 0.000008) + 0.9834);;
   361 
   357 
   362     clr.RGBc[0] = (clr.RGBp[0] * M[0]) + (clr.RGBp[1] * M[1]) + (clr.RGBp[2] * M[2]);
   358     clr.RGBc[0] = (clr.RGBp[0] * M[0]) + (clr.RGBp[1] * M[1]) + (clr.RGBp[2] * M[2]);
   363     clr.RGBc[1] = (clr.RGBp[0] * M[3]) + (clr.RGBp[1] * M[4]) + (clr.RGBp[2] * M[5]);
   359     clr.RGBc[1] = (clr.RGBp[0] * M[3]) + (clr.RGBp[1] * M[4]) + (clr.RGBp[2] * M[5]);
   364     clr.RGBc[2] = (clr.RGBp[0] * M[6]) + (clr.RGBp[1] * M[7]) + (clr.RGBp[2] * M[8]);
   360     clr.RGBc[2] = (clr.RGBp[0] * M[6]) + (clr.RGBp[1] * M[7]) + (clr.RGBp[2] * M[8]);
   365     return (clr);
   361     return clr;
   366 }
   362 }
   367 
   363 
   368 
   364 
   369 static
   365 static
   370 CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr,  LPcmsCIECAM02 pMod)
   366 CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr,  cmsCIECAM02* pMod)
   371 {
   367 {
   372     int i;
   368     cmsUInt32Number i;
   373     for (i = 0; i < 3; i++) {
   369     for (i = 0; i < 3; i++) {
   374         clr.RGB[i] = clr.RGBc[i] /
   370         clr.RGB[i] = clr.RGBc[i] /
   375             ((pMod->adoptedWhite.XYZ[1] * pMod->D / pMod->adoptedWhite.RGB[i]) + 1.0 - pMod->D);
   371             ((pMod->adoptedWhite.XYZ[1] * pMod->D / pMod->adoptedWhite.RGB[i]) + 1.0 - pMod->D);
   376     }
   372     }
   377     return(clr);
   373     return clr;
   378 }
   374 }
   379 
   375 
   380 
   376 
   381 static
   377 static
   382 CAM02COLOR CAT02toXYZ(CAM02COLOR clr)
   378 CAM02COLOR CAT02toXYZ(CAM02COLOR clr)
   383 {
   379 {
   384     clr.XYZ[0] = (clr.RGB[0] *  1.096124) + (clr.RGB[1] * -0.278869) + (clr.RGB[2] *  0.182745);
   380     clr.XYZ[0] = (clr.RGB[0] *  1.096124) + (clr.RGB[1] * -0.278869) + (clr.RGB[2] *  0.182745);
   385     clr.XYZ[1] = (clr.RGB[0] *  0.454369) + (clr.RGB[1] *  0.473533) + (clr.RGB[2] *  0.072098);
   381     clr.XYZ[1] = (clr.RGB[0] *  0.454369) + (clr.RGB[1] *  0.473533) + (clr.RGB[2] *  0.072098);
   386     clr.XYZ[2] = (clr.RGB[0] * -0.009628) + (clr.RGB[1] * -0.005698) + (clr.RGB[2] *  1.015326);
   382     clr.XYZ[2] = (clr.RGB[0] * -0.009628) + (clr.RGB[1] * -0.005698) + (clr.RGB[2] *  1.015326);
   387 
   383 
   388     return(clr);
   384     return clr;
   389 }
   385 }
   390 
   386 
   391 
   387 
   392 
   388 cmsHANDLE  CMSEXPORT cmsCIECAM02Init(cmsContext ContextID, const cmsViewingConditions* pVC)
   393 
   389 {
   394 LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
   390     cmsCIECAM02* lpMod;
   395 {
   391 
   396     LPcmsCIECAM02 lpMod;
   392     _cmsAssert(pVC != NULL);
   397 
   393 
   398 
   394     if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) {
   399    if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) {
   395         return NULL;
   400         return (LCMSHANDLE) NULL;
   396     }
   401     }
   397 
   402 
   398     lpMod ->ContextID = ContextID;
   403 
       
   404     ZeroMemory(lpMod, sizeof(cmsCIECAM02));
       
   405 
   399 
   406     lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X;
   400     lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X;
   407     lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y;
   401     lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y;
   408     lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z;
   402     lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z;
   409 
   403 
   412     lpMod -> D        = pVC ->D_value;
   406     lpMod -> D        = pVC ->D_value;
   413     lpMod -> surround = pVC ->surround;
   407     lpMod -> surround = pVC ->surround;
   414 
   408 
   415     switch (lpMod -> surround) {
   409     switch (lpMod -> surround) {
   416 
   410 
   417     case AVG_SURROUND_4:
   411 
   418         lpMod->F = 1.0;     // Not included in CAM02
   412       case CUTSHEET_SURROUND:
   419         lpMod->c = 0.69;
   413           lpMod->F = 0.8;
   420         lpMod->Nc = 1.0;
   414           lpMod->c = 0.41;
   421         break;
   415           lpMod->Nc = 0.8;
   422 
   416           break;
   423     case CUTSHEET_SURROUND:
   417 
   424         lpMod->F = 0.8;
   418       case DARK_SURROUND:
   425         lpMod->c = 0.41;
   419           lpMod -> F  = 0.8;
   426         lpMod->Nc = 0.8;
   420           lpMod -> c  = 0.525;
   427         break;
   421           lpMod -> Nc = 0.8;
   428 
   422           break;
   429     case DARK_SURROUND:
   423 
   430         lpMod -> F  = 0.8;
   424       case DIM_SURROUND:
   431         lpMod -> c  = 0.525;
   425           lpMod -> F  = 0.9;
   432         lpMod -> Nc = 0.8;
   426           lpMod -> c  = 0.59;
   433         break;
   427           lpMod -> Nc = 0.95;
   434 
   428           break;
   435 
   429 
   436     case DIM_SURROUND:
   430       default:
   437         lpMod -> F  = 0.9;
   431           // Average surround
   438         lpMod -> c  = 0.59;
   432           lpMod -> F  = 1.0;
   439         lpMod -> Nc = 0.95;
   433           lpMod -> c  = 0.69;
   440         break;
   434           lpMod -> Nc = 1.0;
   441 
       
   442     default:
       
   443         // Average surround
       
   444         lpMod -> F  = 1.0;
       
   445         lpMod -> c  = 0.69;
       
   446         lpMod -> Nc = 1.0;
       
   447     }
   435     }
   448 
   436 
   449     lpMod -> n   = compute_n(lpMod);
   437     lpMod -> n   = compute_n(lpMod);
   450     lpMod -> z   = compute_z(lpMod);
   438     lpMod -> z   = compute_z(lpMod);
   451     lpMod -> Nbb = computeNbb(lpMod);
   439     lpMod -> Nbb = computeNbb(lpMod);
   452     lpMod -> FL  = computeFL(lpMod);
   440     lpMod -> FL  = computeFL(lpMod);
   453 
   441 
   454     if (lpMod -> D == D_CALCULATE ||
   442     if (lpMod -> D == D_CALCULATE) {
   455         lpMod -> D == D_CALCULATE_DISCOUNT) {
   443         lpMod -> D   = computeD(lpMod);
   456 
       
   457     lpMod -> D   = computeD(lpMod);
       
   458     }
   444     }
   459 
   445 
   460     lpMod -> Ncb = lpMod -> Nbb;
   446     lpMod -> Ncb = lpMod -> Nbb;
   461 
   447 
   462     lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
   448     lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
   463     lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
   449     lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
   464     lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
   450     lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
   465     lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
   451     lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
   466 
   452 
   467     return (LCMSHANDLE) lpMod;
   453     return (cmsHANDLE) lpMod;
   468 
   454 
   469 }
   455 }
   470 
   456 
   471 void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel)
   457 void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel)
   472 {
   458 {
   473     LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
   459     cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
   474     if (lpMod) _cmsFree(lpMod);
   460 
   475 }
   461     if (lpMod) _cmsFree(lpMod ->ContextID, lpMod);
   476 
   462 }
   477 
   463 
   478 void LCMSEXPORT cmsCIECAM02Forward(LCMSHANDLE hModel, LPcmsCIEXYZ pIn, LPcmsJCh pOut)
   464 
       
   465 void CMSEXPORT cmsCIECAM02Forward(cmsHANDLE hModel, const cmsCIEXYZ* pIn, cmsJCh* pOut)
   479 {
   466 {
   480     CAM02COLOR clr;
   467     CAM02COLOR clr;
   481     LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
   468     cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
       
   469 
       
   470     _cmsAssert(lpMod != NULL);
       
   471     _cmsAssert(pIn != NULL);
       
   472     _cmsAssert(pOut != NULL);
   482 
   473 
   483     clr.XYZ[0] = pIn ->X;
   474     clr.XYZ[0] = pIn ->X;
   484     clr.XYZ[1] = pIn ->Y;
   475     clr.XYZ[1] = pIn ->Y;
   485     clr.XYZ[2] = pIn ->Z;
   476     clr.XYZ[2] = pIn ->Z;
   486 
   477 
   493     pOut ->J = clr.J;
   484     pOut ->J = clr.J;
   494     pOut ->C = clr.C;
   485     pOut ->C = clr.C;
   495     pOut ->h = clr.h;
   486     pOut ->h = clr.h;
   496 }
   487 }
   497 
   488 
   498 void LCMSEXPORT cmsCIECAM02Reverse(LCMSHANDLE hModel, LPcmsJCh pIn, LPcmsCIEXYZ pOut)
   489 void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ* pOut)
   499 {
   490 {
   500     CAM02COLOR clr;
   491     CAM02COLOR clr;
   501     LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
   492     cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
   502 
   493 
       
   494     _cmsAssert(lpMod != NULL);
       
   495     _cmsAssert(pIn != NULL);
       
   496     _cmsAssert(pOut != NULL);
   503 
   497 
   504     clr.J = pIn -> J;
   498     clr.J = pIn -> J;
   505     clr.C = pIn -> C;
   499     clr.C = pIn -> C;
   506     clr.h = pIn -> h;
   500     clr.h = pIn -> h;
   507 
   501 
   512     clr = CAT02toXYZ(clr);
   506     clr = CAT02toXYZ(clr);
   513 
   507 
   514     pOut ->X = clr.XYZ[0];
   508     pOut ->X = clr.XYZ[0];
   515     pOut ->Y = clr.XYZ[1];
   509     pOut ->Y = clr.XYZ[1];
   516     pOut ->Z = clr.XYZ[2];
   510     pOut ->Z = clr.XYZ[2];
   517 
   511 }
   518 }
   512 
   519