jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 2394 404cbe399601
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
// This file is available under and governed by the GNU General Public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
// License version 2 only, as published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
// However, the following notice accompanied the original version of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
// file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
//  Little cms
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
//  Copyright (C) 1998-2006 Marti Maria
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
// Permission is hereby granted, free of charge, to any person obtaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
// a copy of this software and associated documentation files (the "Software"),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
// to deal in the Software without restriction, including without limitation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
// and/or sell copies of the Software, and to permit persons to whom the Software
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
// is furnished to do so, subject to the following conditions:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
// The above copyright notice and this permission notice shall be included in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
// all copies or substantial portions of the Software.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
#include "lcms.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
Gamut check by default is a catching of 0xFFFF/0xFFFF/0xFFFF PCS values, used
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
internally by lcms to hold invalid values. Matrix LUT's, operates in a way that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
unencodeable values are marked as this combination, if PCS is XYZ, this is a very
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
high value since encoding is a 1.15 fixed point, something like 1.9997, 1.9997, 1.9997
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
not a very common color after all. Lab PCS is not to be a problem, since L>100 are truely
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
undefined. There is a posibility than ICC comitee defines L>100 as a valid means
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
to use highlights, then it will be lost.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
(1.10 - Actually ICC did it, so this should be checked for full ICC 4.0 support)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
BOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
                            int *nOutputs)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
       // Only most common spaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
       static WORD RGBblack[4]  = { 0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
       static WORD RGBwhite[4]  = { 0xffff, 0xffff, 0xffff };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
       static WORD CMYKblack[4] = { 0xffff, 0xffff, 0xffff, 0xffff };   // 400% of ink
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
       static WORD CMYKwhite[4] = { 0, 0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
       static WORD LABblack[4]  = { 0, 0x8000, 0x8000 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
       static WORD LABwhite[4]  = { 0xFF00, 0x8000, 0x8000 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
       static WORD CMYblack[4]  = { 0xffff, 0xffff, 0xffff };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
       static WORD CMYwhite[4]  = { 0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
       static WORD Grayblack[4] = { 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
       static WORD GrayWhite[4] = { 0xffff };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
       switch (Space) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
       case icSigGrayData: if (White)    *White = GrayWhite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
                           if (Black)    *Black = Grayblack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                           if (nOutputs) *nOutputs = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                           return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
       case icSigRgbData:  if (White)    *White = RGBwhite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
                           if (Black)    *Black = RGBblack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
                           if (nOutputs) *nOutputs = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                           return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
       case icSigLabData:  if (White)    *White = LABwhite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                           if (Black)    *Black = LABblack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                           if (nOutputs) *nOutputs = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                           return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
       case icSigCmykData: if (White)    *White = CMYKwhite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                           if (Black)    *Black = CMYKblack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                           if (nOutputs) *nOutputs = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                           return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
       case icSigCmyData:  if (White)    *White = CMYwhite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                           if (Black)    *Black = CMYblack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                           if (nOutputs) *nOutputs = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                           return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
       default:;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
  return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
WORD *_cmsWhiteBySpace(icColorSpaceSignature Space)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
       WORD *White= NULL, *Black = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
       int Dummy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
       static WORD Default[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
       if (_cmsEndPointsBySpace(Space, &White, &Black, &Dummy))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
              return White;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
       return Default;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
WORD Clamp_L(Fixed32 in)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
       if (in == 0xFFFF) return 0xFFFFU;  // Marker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
       if (in > 0xFF00) return 0xFF00U;  // L* = 100.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
       return (WORD) in;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
#define ENCODE_AB(x) (WORD) (((x) + 128.0) * 256.0 + 0.5)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
WORD Clamp_ab(Fixed32 in)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
       if (in == 0xFFFF) return 0xFFFFU;             // Marker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
       if (in < 0) return ENCODE_AB(-128.0);         // Max negative number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
       if (in > 0xFFFF) return ENCODE_AB(+127.9961); // Max positive number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
       return (WORD) in;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
// Returns dE on two Lab values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
double LCMSEXPORT cmsDeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        double dL, da, db;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        if (Lab1 -> L < 0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            Lab2 -> L < 0) return 65536.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        if (Lab1 -> a < -200 || Lab1 -> a > 200) return 65536.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (Lab1 -> b < -200 || Lab1 -> b > 200) return 65536.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        if (Lab2 -> a < -200 || Lab2 -> a > 200) return 65536.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        if (Lab2 -> b < -200 || Lab2 -> b > 200) return 65536.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        dL = fabs(Lab1 -> L - Lab2 -> L);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        da = fabs(Lab1 -> a - Lab2 -> a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        db = fabs(Lab1 -> b - Lab2 -> b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        return pow(dL*dL + da * da + db * db, 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
// Square
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
double Sqr(double v)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    return v *  v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
// Return the CIE94 Delta E
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
double LCMSEXPORT cmsCIE94DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    cmsCIELCh LCh1, LCh2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    double dE, dL, dC, dh, dhsq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    double c12, sc, sh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    dL = fabs(Lab1 ->L - Lab2 ->L);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    cmsLab2LCh(&LCh1, Lab1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    cmsLab2LCh(&LCh2, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    dC  = fabs(LCh1.C - LCh2.C);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    dE  = cmsDeltaE(Lab1, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    dhsq = Sqr(dE) - Sqr(dL) - Sqr(dC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    if (dhsq < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        dh = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        dh = pow(dhsq, 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    c12 = sqrt(LCh1.C * LCh2.C);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    sc = 1.0 + (0.048 * c12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    sh = 1.0 + (0.014 * c12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    return sqrt(Sqr(dL)  + Sqr(dC) / Sqr(sc) + Sqr(dh) / Sqr(sh));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
// Auxiliary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
double ComputeLBFD(LPcmsCIELab Lab)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
  double yt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
  if (Lab->L > 7.996969)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        yt = (Sqr((Lab->L+16)/116)*((Lab->L+16)/116))*100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
  else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        yt = 100 * (Lab->L / 903.3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
  return (54.6 * (LOGE * (log(yt + 1.5))) - 9.6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
// bfd - gets BFD(1:1) difference between Lab1, Lab2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
double LCMSEXPORT cmsBFDdeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    double lbfd1,lbfd2,AveC,Aveh,dE,deltaL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        deltaC,deltah,dc,t,g,dh,rh,rc,rt,bfd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    cmsCIELCh LCh1, LCh2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    lbfd1 = ComputeLBFD(Lab1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    lbfd2 = ComputeLBFD(Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    deltaL = lbfd2 - lbfd1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    cmsLab2LCh(&LCh1, Lab1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    cmsLab2LCh(&LCh2, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    deltaC = LCh2.C - LCh1.C;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    AveC = (LCh1.C+LCh2.C)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    Aveh = (LCh1.h+LCh2.h)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    dE = cmsDeltaE(Lab1, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    if (Sqr(dE)>(Sqr(Lab2->L-Lab1->L)+Sqr(deltaC)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        deltah = sqrt(Sqr(dE)-Sqr(Lab2->L-Lab1->L)-Sqr(deltaC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        deltah =0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    dc   = 0.035 * AveC / (1 + 0.00365 * AveC)+0.521;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    g    = sqrt(Sqr(Sqr(AveC))/(Sqr(Sqr(AveC))+14000));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    t    = 0.627+(0.055*cos((Aveh-254)/(180/M_PI))-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        0.040*cos((2*Aveh-136)/(180/M_PI))+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        0.070*cos((3*Aveh-31)/(180/M_PI))+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        0.049*cos((4*Aveh+114)/(180/M_PI))-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        0.015*cos((5*Aveh-103)/(180/M_PI)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    dh    = dc*(g*t+1-g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    rh    = -0.260*cos((Aveh-308)/(180/M_PI))-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        0.379*cos((2*Aveh-160)/(180/M_PI))-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        0.636*cos((3*Aveh+254)/(180/M_PI))+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        0.226*cos((4*Aveh+140)/(180/M_PI))-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        0.194*cos((5*Aveh+280)/(180/M_PI));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    rc = sqrt((AveC*AveC*AveC*AveC*AveC*AveC)/((AveC*AveC*AveC*AveC*AveC*AveC)+70000000));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    rt = rh*rc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    bfd = sqrt(Sqr(deltaL)+Sqr(deltaC/dc)+Sqr(deltah/dh)+(rt*(deltaC/dc)*(deltah/dh)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    return bfd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
//  cmc - CMC(1:1) difference between Lab1, Lab2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
double LCMSEXPORT cmsCMCdeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
  double dE,dL,dC,dh,sl,sc,sh,t,f,cmc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
  cmsCIELCh LCh1, LCh2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
  if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
  cmsLab2LCh(&LCh1, Lab1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
  cmsLab2LCh(&LCh2, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
  dL = Lab2->L-Lab1->L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
  dC = LCh2.C-LCh1.C;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
  dE = cmsDeltaE(Lab1, Lab2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
  if (Sqr(dE)>(Sqr(dL)+Sqr(dC)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            dh = sqrt(Sqr(dE)-Sqr(dL)-Sqr(dC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
  else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            dh =0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
  if ((LCh1.h > 164) && (LCh1.h<345))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
      t = 0.56 + fabs(0.2 * cos(((LCh1.h + 168)/(180/M_PI))));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
  else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
      t = 0.36 + fabs(0.4 * cos(((LCh1.h + 35 )/(180/M_PI))));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
   sc  = 0.0638   * LCh1.C / (1 + 0.0131  * LCh1.C) + 0.638;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
   sl  = 0.040975 * Lab1->L /(1 + 0.01765 * Lab1->L);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
   if (Lab1->L<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
         sl = 0.511;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
   f   = sqrt((LCh1.C * LCh1.C * LCh1.C * LCh1.C)/((LCh1.C * LCh1.C * LCh1.C * LCh1.C)+1900));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
   sh  = sc*(t*f+1-f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
   cmc = sqrt(Sqr(dL/sl)+Sqr(dC/sc)+Sqr(dh/sh));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
   return cmc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
double atan2deg(double b, double a)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
   double h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
   if (a == 0 && b == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            h   = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            h = atan2(a, b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    h *= (180. / M_PI);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    while (h > 360.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        h -= 360.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    while ( h < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        h += 360.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    return h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
double RADIANES(double deg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    return (deg * M_PI) / 180.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
// dE2000 The weightings KL, KC and KH can be modified to reflect the relative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
// importance of lightness, chroma and hue in different industrial applications
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                                  double Kl, double Kc, double Kh)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    double L1  = Lab1->L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    double a1  = Lab1->a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    double b1  = Lab1->b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    double C   = sqrt( Sqr(a1) + Sqr(b1) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    double Ls = Lab2 ->L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    double as = Lab2 ->a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    double bs = Lab2 ->b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    double Cs = sqrt( Sqr(as) + Sqr(bs) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    double G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) ));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    double a_p = (1 + G ) * a1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    double b_p = b1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    double C_p = sqrt( Sqr(a_p) + Sqr(b_p));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    double h_p = atan2deg(a_p, b_p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    double a_ps = (1 + G) * as;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    double b_ps = bs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    double h_ps = atan2deg(a_ps, b_ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    double meanC_p =(C_p + C_ps) / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    double meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-360)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    double delta_h = fabs(h_p - h_ps) <= 180 ? fabs(h_p - h_ps) : 360 - fabs(h_p - h_ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    double delta_L = fabs(L1 - Ls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    double delta_C = fabs(C_p - C_ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    double T = 1 - 0.17 * cos(RADIANES(meanh_p-30))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                 + 0.24 * cos(RADIANES(2*meanh_p))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                 + 0.32 * cos(RADIANES(3*meanh_p + 6))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                 - 0.2  * cos(RADIANES(4*meanh_p - 63));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    double Sl = 1 + (0.015 * Sqr((Ls + L1) /2- 50) )/ sqrt(20 + Sqr( (Ls+L1)/2 - 50) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    double Sc = 1 + 0.045 * (C_p + C_ps)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    double Sh = 1 + 0.015 * ((C_ps + C_p)/2) * T;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    double delta_ro = 30 * exp( -Sqr(((meanh_p - 275 ) / 25)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    double Rc = 2 * sqrt(( pow(meanC_p, 7.0) )/( pow(meanC_p, 7.0) + pow(25.0, 7.0)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    double Rt = -sin(2 * RADIANES(delta_ro)) * Rc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    double deltaE00 = sqrt( Sqr(delta_L /(Sl * Kl)) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                            Sqr(delta_C/(Sc * Kc))  +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                            Sqr(delta_H/(Sh * Kh))  +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                            Rt*(delta_C/(Sc * Kc)) * (delta_H / (Sh * Kh)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    return deltaE00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
// Carefully,  clamp on CIELab space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                                   double bmax, double bmin)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            // Whole Luma surface to zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        if (Lab -> L < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                Lab-> L = Lab->a = Lab-> b = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
            // Clamp white, DISCARD HIGHLIGHTS. This is done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            // in such way because icc spec doesn't allow the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            // use of L>100 as a highlight means.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            if (Lab->L > 100)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                        Lab -> L = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            // Check out gamut prism, on a, b faces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (Lab -> a < amin || Lab->a > amax||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                Lab -> b < bmin || Lab->b > bmax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                 cmsCIELCh LCh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                 double h, slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                 // Falls outside a, b limits. Transports to LCh space,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                 // and then do the clipping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                 if (Lab -> a == 0.0) { // Is hue exactly 90?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                        // atan will not work, so clamp here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                        Lab -> b = Lab->b < 0 ? bmin : bmax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                 cmsLab2LCh(&LCh, Lab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                 slope = Lab -> b / Lab -> a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                 h = LCh.h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                 // There are 4 zones
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                 if ((h >= 0. && h < 45.) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                     (h >= 315 && h <= 360.)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                     // clip by amax
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                     Lab -> a = amax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                     Lab -> b = amax * slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                 if (h >= 45. && h < 135)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                 {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                        // clip by bmax
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                        Lab -> b = bmax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                        Lab -> a = bmax / slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                 if (h >= 135 && h < 225) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                        // clip by amin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                        Lab -> a = amin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                        Lab -> b = amin * slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                 if (h >= 225 && h < 315) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                        // clip by bmin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                        Lab -> b = bmin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                        Lab -> a = bmin / slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                        cmsSignalError(LCMS_ERRC_ABORTED, "Invalid angle");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
// Several utilities -------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
// Translate from our colorspace to ICC representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
       switch (OurNotation) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
       case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
       case PT_GRAY: return  icSigGrayData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
       case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
       case PT_RGB:  return  icSigRgbData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
       case PT_CMY:  return  icSigCmyData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
       case PT_CMYK: return  icSigCmykData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
       case PT_YCbCr:return  icSigYCbCrData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
       case PT_YUV:  return  icSigLuvData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
       case PT_XYZ:  return  icSigXYZData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
       case PT_Lab:  return  icSigLabData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
       case PT_YUVK: return  icSigLuvKData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
       case PT_HSV:  return  icSigHsvData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
       case PT_HLS:  return  icSigHlsData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
       case PT_Yxy:  return  icSigYxyData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
       case PT_HiFi: return  icSigHexachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
       case PT_HiFi7: return icSigHeptachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
       case PT_HiFi8: return icSigOctachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
       case PT_HiFi9:  return icSigMCH9Data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
       case PT_HiFi10: return icSigMCHAData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
       case PT_HiFi11: return icSigMCHBData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
       case PT_HiFi12: return icSigMCHCData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
       case PT_HiFi13: return icSigMCHDData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
       case PT_HiFi14: return icSigMCHEData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
       case PT_HiFi15: return icSigMCHFData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
       default:  return icMaxEnumData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    switch (ProfileSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    case icSigGrayData: return  PT_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
    case icSigRgbData:  return  PT_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    case icSigCmyData:  return  PT_CMY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    case icSigCmykData: return  PT_CMYK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    case icSigYCbCrData:return  PT_YCbCr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    case icSigLuvData:  return  PT_YUV;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    case icSigXYZData:  return  PT_XYZ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    case icSigLabData:  return  PT_Lab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    case icSigLuvKData: return  PT_YUVK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    case icSigHsvData:  return  PT_HSV;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    case icSigHlsData:  return  PT_HLS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    case icSigYxyData:  return  PT_Yxy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    case icSig6colorData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    case icSigHexachromeData: return PT_HiFi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    case icSigHeptachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    case icSig7colorData:     return PT_HiFi7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    case icSigOctachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    case icSig8colorData:     return PT_HiFi8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    case icSigMCH9Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    case icSig9colorData:     return PT_HiFi9;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    case icSigMCHAData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    case icSig10colorData:     return PT_HiFi10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    case icSigMCHBData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    case icSig11colorData:     return PT_HiFi11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
    case icSigMCHCData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    case icSig12colorData:     return PT_HiFi12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    case icSigMCHDData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    case icSig13colorData:     return PT_HiFi13;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    case icSigMCHEData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    case icSig14colorData:     return PT_HiFi14;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    case icSigMCHFData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    case icSig15colorData:     return PT_HiFi15;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    default:  return icMaxEnumData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    switch (ColorSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    case icSigGrayData: return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    case icSig2colorData:  return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    case icSigXYZData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    case icSigLabData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    case icSigLuvData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    case icSigYCbCrData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    case icSigYxyData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    case icSigRgbData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    case icSigHsvData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    case icSigHlsData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    case icSigCmyData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    case icSig3colorData:  return 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    case icSigLuvKData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    case icSigCmykData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    case icSig4colorData:  return 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    case icSigMCH5Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    case icSig5colorData:  return 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    case icSigHexachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    case icSig6colorData:  return 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    case icSigHeptachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    case icSig7colorData:  return  7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    case icSigOctachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    case icSig8colorData:  return  8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    case icSigMCH9Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    case icSig9colorData:  return  9;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    case icSigMCHAData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    case icSig10colorData: return 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    case icSigMCHBData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    case icSig11colorData: return 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    case icSigMCHCData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    case icSig12colorData: return 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    case icSigMCHDData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    case icSig13colorData: return 13;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    case icSigMCHEData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    case icSig14colorData: return 14;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    case icSigMCHFData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    case icSig15colorData: return 15;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    default: return 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
// v2 L=100 is supposed to be placed on 0xFF00. There is no reasonable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
// number of gridpoints that would make exact match. However, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
// prelinearization of 258 entries, would map 0xFF00 on entry 257.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
// This is almost what we need, unfortunately, the rest of entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
// should be scaled by (255*257/256) and this is not exact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
// An intermediate solution would be to use 257 entries. This does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
// map 0xFF00 exactly on a node, but so close that the dE induced is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
// negligible. AND the rest of curve is exact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
void CreateLabPrelinearization(LPGAMMATABLE LabTable[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    LabTable[0] = cmsAllocGamma(257);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    LabTable[1] = cmsBuildGamma(257, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    LabTable[2] = cmsBuildGamma(257, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    // L* uses 257 entries. Entry 256 holds 0xFFFF, so, the effective range
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    // is 0..0xFF00. Last entry (257) is also collapsed to 0xFFFF
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    // From 0 to 0xFF00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    for (i=0; i < 256; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        LabTable[0]->GammaTable[i] = RGB_8_TO_16(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    // Repeat last for 0xFFFF
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    LabTable[0] ->GammaTable[256] = 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
// Used by gamut & softproofing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    cmsHTRANSFORM hInput;               // From whatever input color space. NULL for Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    cmsHTRANSFORM hForward, hReverse;   // Transforms going from Lab to colorant and back
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    double Thereshold;                  // The thereshold after which is considered out of gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    } GAMUTCHAIN,FAR* LPGAMUTCHAIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
// This sampler does compute gamut boundaries by comparing original
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
// values with a transform going back and forth. Values above ERR_THERESHOLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
// of maximum are considered out of gamut.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
#define ERR_THERESHOLD      5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
int GamutSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
    LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    WORD Proof[MAXCHANNELS], Check[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    WORD Proof2[MAXCHANNELS], Check2[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    cmsCIELab LabIn1, LabOut1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
    cmsCIELab LabIn2, LabOut2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    double dE1, dE2, ErrorRatio;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    // Assume in-gamut by default.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    dE1 = 0.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    dE2 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    ErrorRatio = 1.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    // Any input space? I can use In[] no matter channels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    // because is just one pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    if (t -> hInput != NULL) cmsDoTransform(t -> hInput, In, In, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    // converts from PCS to colorant. This always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    // does return in-gamut values,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
    cmsDoTransform(t -> hForward, In, Proof, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
    // Now, do the inverse, from colorant to PCS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    cmsDoTransform(t -> hReverse, Proof, Check, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    // Try again, but this time taking Check as input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    cmsDoTransform(t -> hForward, Check, Proof2,  1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    cmsDoTransform(t -> hReverse, Proof2, Check2, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    // Does the transform returns out-of-gamut?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    if (Check[0] == 0xFFFF &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        Check[1] == 0xFFFF &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        Check[2] == 0xFFFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        Out[0] = 0xFF00;            // Out of gamut!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        // Transport encoded values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        cmsLabEncoded2Float(&LabIn1,  In);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        cmsLabEncoded2Float(&LabOut1, Check);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        // Take difference of direct value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        dE1 = cmsDeltaE(&LabIn1, &LabOut1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        cmsLabEncoded2Float(&LabIn2,  Check);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        cmsLabEncoded2Float(&LabOut2, Check2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        // Take difference of converted value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        dE2 = cmsDeltaE(&LabIn2, &LabOut2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        // if dE1 is small and dE2 is small, value is likely to be in gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        if (dE1 < t->Thereshold && dE2 < t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            Out[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            // if dE1 is small and dE2 is big, undefined. Assume in gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            if (dE1 < t->Thereshold && dE2 > t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                Out[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                // dE1 is big and dE2 is small, clearly out of gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                if (dE1 > t->Thereshold && dE2 < t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                    Out[0] = (WORD) _cmsQuickFloor((dE1 - t->Thereshold) + .5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                else  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                    // dE1 is big and dE2 is also big, could be due to perceptual mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                    // so take error ratio
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                    if (dE2 == 0.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                        ErrorRatio = dE1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                        ErrorRatio = dE1 / dE2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                    if (ErrorRatio > t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                        Out[0] = (WORD)  _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                        Out[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
// Does compute a gamut LUT going back and forth across
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
// pcs -> relativ. colorimetric intent -> pcs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
// the dE obtained is then annotated on the LUT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
// values truely out of gamut, are clipped to dE = 0xFFFE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
// and values changed are supposed to be handled by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
// any gamut remapping, so, are out of gamut as well.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
// **WARNING: This algorithm does assume that gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
// remapping algorithms does NOT move in-gamut colors,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
// of course, many perceptual and saturation intents does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
// not work in such way, but relativ. ones should.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
LPLUT ComputeGamutWithInput(cmsHPROFILE hInput, cmsHPROFILE hProfile, int Intent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
    cmsHPROFILE hLab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    LPLUT Gamut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
    DWORD dwFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    GAMUTCHAIN Chain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
    int nErrState, nChannels, nGridpoints;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    LPGAMMATABLE Trans[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    icColorSpaceSignature ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    ZeroMemory(&Chain, sizeof(GAMUTCHAIN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    hLab = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    // Safeguard against early abortion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    nErrState = cmsErrorAction(LCMS_ERROR_IGNORE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    // The figure of merit. On matrix-shaper profiles, should be almost zero as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    // the conversion is pretty exact. On LUT based profiles, different resolutions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    // of input and output CLUT may result in differences.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
    if (!cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        !cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_OUTPUT))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        Chain.Thereshold = 1.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        Chain.Thereshold = ERR_THERESHOLD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    ColorSpace  = cmsGetColorSpace(hProfile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
    // If input profile specified, create a transform from such profile to Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    if (hInput != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        nChannels   = _cmsChannelsOf(ColorSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        dwFormat    = (CHANNELS_SH(nChannels)|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        Chain.hInput = cmsCreateTransform(hInput, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                                          hLab,   TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                                          Intent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                                          cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    else  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        // Input transform=NULL (Lab) Used to compute the gamut tag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        // This table will take 53 points to give some accurancy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        // 53 * 53 * 53 * 2 = 291K
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
        nChannels    = 3;      // For Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        nGridpoints  = 53;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        Chain.hInput = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        dwFormat = (CHANNELS_SH(_cmsChannelsOf(ColorSpace))|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    // Does create the forward step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
    Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                                        hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    // Does create the backwards step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    Chain.hReverse = cmsCreateTransform(hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                                        hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    // Restores error handler previous state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    cmsErrorAction(nErrState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    // All ok?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    if (Chain.hForward && Chain.hReverse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
    // Go on, try to compute gamut LUT from PCS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    // This consist on a single channel containing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    // dE when doing a transform back and forth on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    // the colorimetric intent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    Gamut = cmsAllocLUT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    Gamut = cmsAlloc3DGrid(Gamut, nGridpoints, nChannels, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    // If no input, then this is a gamut tag operated by Lab,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    // so include pertinent prelinearization
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    if (hInput == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        cmsAllocLinearTable(Gamut, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    cmsSample3DGrid(Gamut, GamutSampler, (LPVOID) &Chain, Gamut ->wFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
        Gamut = NULL;   // Didn't work...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    // Free all needed stuff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    if (Chain.hInput)   cmsDeleteTransform(Chain.hInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
    if (Chain.hForward) cmsDeleteTransform(Chain.hForward);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    // And return computed hull
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    return Gamut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
// Wrapper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
LPLUT _cmsComputeGamutLUT(cmsHPROFILE hProfile, int Intent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    return ComputeGamutWithInput(NULL, hProfile, Intent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
// This routine does compute the gamut check CLUT. This CLUT goes from whatever
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
// input space to the 0 or != 0 gamut check.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
LPLUT _cmsPrecalculateGamutCheck(cmsHTRANSFORM h)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
       _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
       return ComputeGamutWithInput(p->InputProfile, p ->PreviewProfile, p->Intent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
// SoftProofing. Convert from Lab to device, then back to Lab,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
// any gamut remapping is applied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
int SoftProofSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        WORD Colorant[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        // From pcs to colorant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        cmsDoTransform(t -> hForward, In, Colorant, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        // Now, do the inverse, from colorant to pcs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        cmsDoTransform(t -> hReverse, Colorant, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
// Does return Softproofing LUT on desired intent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
LPLUT _cmsComputeSoftProofLUT(cmsHPROFILE hProfile, int nIntent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    cmsHPROFILE hLab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    LPLUT SoftProof;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    DWORD dwFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    GAMUTCHAIN Chain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    int nErrState;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    LPGAMMATABLE Trans[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    // LUTs are never abs. colorimetric, is the transform who
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    // is responsible of generating white point displacement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    if (nIntent == INTENT_ABSOLUTE_COLORIMETRIC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        nIntent = INTENT_RELATIVE_COLORIMETRIC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
    ZeroMemory(&Chain, sizeof(GAMUTCHAIN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    hLab = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    // ONLY 4 channels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    dwFormat = (CHANNELS_SH(4)|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    // Safeguard against early abortion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    nErrState = cmsErrorAction(LCMS_ERROR_IGNORE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    // Does create the first step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                                        hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                                        nIntent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    // Does create the last step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
    Chain.hReverse = cmsCreateTransform(hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                                        hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    // Restores error handler previous state
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
    cmsErrorAction(nErrState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    // All ok?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    if (Chain.hForward && Chain.hReverse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    // This is Lab -> Lab, so 33 point should hold anything
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
    SoftProof = cmsAllocLUT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    SoftProof = cmsAlloc3DGrid(SoftProof, 33, 3, 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    cmsAllocLinearTable(SoftProof, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
    cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    cmsSample3DGrid(SoftProof, SoftProofSampler, (LPVOID) &Chain, SoftProof->wFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        SoftProof = NULL;   // Didn't work...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
    // Free all needed stuff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    if (Chain.hForward) cmsDeleteTransform(Chain.hForward);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    return SoftProof;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
int MostlyLinear(WORD Table[], int nEntries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
       register int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
       int diff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
       for (i=5; i < nEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
           diff = abs((int) Table[i] - (int) _cmsQuantizeVal(i, nEntries));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
           if (diff > 0x0300)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                     return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
       return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
void SlopeLimiting(WORD Table[], int nEntries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
    int At = (int) floor((double) nEntries * 0.02 + 0.5);   // Cutoff at 2%
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
    double Val, Slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
    Val   = Table[At];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
    Slope = Val / At;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    for (i=0; i < At; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        Table[i] = (WORD) floor(i * Slope + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
// Check for monotonicity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
BOOL IsMonotonic(LPGAMMATABLE t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
    int n = t -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    int i, last;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
    last = t ->GammaTable[n-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    for (i = n-2; i >= 0; --i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        if (t ->GammaTable[i] > last)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
               return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                last = t ->GammaTable[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
// Check for endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
BOOL HasProperEndpoints(LPGAMMATABLE t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
    if (t ->GammaTable[0] != 0) return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
    if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
#define PRELINEARIZATION_POINTS 4096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
// Fixes the gamma balancing of transform. Thanks to Mike Chaney
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
// for pointing this subtle bug.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransforms, LPLUT Grid)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
    LPGAMMATABLE Trans[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
    unsigned int t, i, v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    int j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
    WORD In[MAXCHANNELS], Out[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
    BOOL lIsSuitable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
    _LPcmsTRANSFORM InputXForm   = (_LPcmsTRANSFORM) h[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
    _LPcmsTRANSFORM OutputXForm  = (_LPcmsTRANSFORM) h[nTransforms-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
    // First space is *Lab, use our specialized curves for v2 Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    if (InputXForm ->EntryColorSpace == icSigLabData &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        OutputXForm->ExitColorSpace != icSigLabData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                cmsAllocLinearTable(Grid, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
    // Do nothing on all but RGB to RGB transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    if ((InputXForm ->EntryColorSpace != icSigRgbData) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        (OutputXForm->ExitColorSpace  != icSigRgbData)) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
    for (t = 0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            Trans[t] = cmsAllocGamma(PRELINEARIZATION_POINTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
    for (i=0; i < PRELINEARIZATION_POINTS; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                v = _cmsQuantizeVal(i, PRELINEARIZATION_POINTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                for (t=0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                        In[t] = (WORD) v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                cmsDoTransform(h[0], In, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                for (j=1; j < nTransforms; j++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                        cmsDoTransform(h[j], Out, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                for (t=0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                        Trans[t] ->GammaTable[i] = Out[t];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
    // Check transfer curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
    lIsSuitable = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    for (t=0; (lIsSuitable && (t < Grid->InputChan)); t++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
        // Exclude if already linear
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        if (MostlyLinear(Trans[t]->GammaTable, PRELINEARIZATION_POINTS))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
        // Exclude if non-monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
        if (!IsMonotonic(Trans[t]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
        // Exclude if weird endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        if (!HasProperEndpoints(Trans[t]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
        // Exclude if transfer function is not smooth enough
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
        // to be modelled as a gamma function, or the gamma is reversed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        if (cmsEstimateGamma(Trans[t]) < 1.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
    if (lIsSuitable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
            for (t = 0; t < Grid ->InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                SlopeLimiting(Trans[t]->GammaTable, Trans[t]->nEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
    if (lIsSuitable) cmsAllocLinearTable(Grid, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
    for (t = 0; t < Grid ->InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                        cmsFreeGamma(Trans[t]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
// Compute K -> L* relationship. Flags may include black point compensation. In this case,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
// the relationship is assumed from the profile with BPC to a black point zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
LPGAMMATABLE ComputeKToLstar(cmsHPROFILE hProfile, int nPoints, int Intent, DWORD dwFlags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
    LPGAMMATABLE out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
    WORD cmyk[4], wLab[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
    cmsHPROFILE   hLab  = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
    cmsHTRANSFORM xform = cmsCreateTransform(hProfile, TYPE_CMYK_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                                             hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                                             Intent, (dwFlags|cmsFLAGS_NOTPRECALC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    out = cmsAllocGamma(nPoints);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
    for (i=0; i < nPoints; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
        cmyk[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        cmyk[1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
        cmyk[2] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        cmyk[3] = _cmsQuantizeVal(i, nPoints);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
        cmsDoTransform(xform, cmyk, wLab, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        out->GammaTable[i] = (WORD) (0xFFFF - wLab[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
    cmsDeleteTransform(xform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
    return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
// Compute Black tone curve on a CMYK -> CMYK transform. This is done by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
// using the proof direction on both profiles to find K->L* relationship
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
// then joining both curves. dwFlags may include black point compensation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
    LPGAMMATABLE in, out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
    LPGAMMATABLE KTone;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) hCMYK2CMYK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
    // Make sure CMYK -> CMYK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
    if (p -> EntryColorSpace != icSigCmykData ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
        p -> ExitColorSpace  != icSigCmykData) return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
    // Create individual curves. BPC works also as each K to L* is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
    // computed as a BPC to zero black point in case of L*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
    in  = ComputeKToLstar(p ->InputProfile,  nPoints, p->Intent, p -> dwOriginalFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
    out = ComputeKToLstar(p ->OutputProfile, nPoints, p->Intent, p -> dwOriginalFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
    // Build the relationship
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
    KTone = cmsJoinGamma(in, out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
    cmsFreeGamma(in); cmsFreeGamma(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
    // Make sure it is monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
    if (!IsMonotonic(KTone)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
        cmsFreeGamma(KTone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
    return KTone;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
}