jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c
author prr
Tue, 24 Mar 2009 09:14:02 -0700
changeset 2394 404cbe399601
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
6821031: Upgrade OpenJDK's LittleCMS version to 1.18 Reviewed-by: bae, igor
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
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
    32
//  Copyright (C) 1998-2007 Marti Maria
2
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
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
    69
LCMSBOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
2
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
    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
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    double a_p = (1 + G ) * a1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    double b_p = b1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    double C_p = sqrt( Sqr(a_p) + Sqr(b_p));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    double h_p = atan2deg(a_p, b_p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    double a_ps = (1 + G) * as;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    double b_ps = bs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    double h_ps = atan2deg(a_ps, b_ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    double meanC_p =(C_p + C_ps) / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   394
    double hps_plus_hp  = h_ps + h_p;
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   395
    double hps_minus_hp = h_ps - h_p;
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   396
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   397
    double meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 :
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   398
                            (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 :
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   399
                                                 (hps_plus_hp - 360)/2;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   401
    double delta_h = (hps_minus_hp) <= -180.000001 ?  (hps_minus_hp + 360) :
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   402
                            (hps_minus_hp) > 180 ? (hps_minus_hp - 360) :
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   403
                                                    (hps_minus_hp);
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   404
    double delta_L = (Ls - L1);
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   405
    double delta_C = (C_ps - C_p );
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
   406
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    double T = 1 - 0.17 * cos(RADIANES(meanh_p-30))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                 + 0.24 * cos(RADIANES(2*meanh_p))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                 + 0.32 * cos(RADIANES(3*meanh_p + 6))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                 - 0.2  * cos(RADIANES(4*meanh_p - 63));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    double Sl = 1 + (0.015 * Sqr((Ls + L1) /2- 50) )/ sqrt(20 + Sqr( (Ls+L1)/2 - 50) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    double Sc = 1 + 0.045 * (C_p + C_ps)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    double Sh = 1 + 0.015 * ((C_ps + C_p)/2) * T;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    double delta_ro = 30 * exp( -Sqr(((meanh_p - 275 ) / 25)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    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
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    double Rt = -sin(2 * RADIANES(delta_ro)) * Rc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    double deltaE00 = sqrt( Sqr(delta_L /(Sl * Kl)) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                            Sqr(delta_C/(Sc * Kc))  +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                            Sqr(delta_H/(Sh * Kh))  +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                            Rt*(delta_C/(Sc * Kc)) * (delta_H / (Sh * Kh)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    return deltaE00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
// Carefully,  clamp on CIELab space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                                   double bmax, double bmin)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            // Whole Luma surface to zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        if (Lab -> L < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                Lab-> L = Lab->a = Lab-> b = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            // Clamp white, DISCARD HIGHLIGHTS. This is done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            // in such way because icc spec doesn't allow the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            // use of L>100 as a highlight means.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (Lab->L > 100)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                        Lab -> L = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            // Check out gamut prism, on a, b faces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            if (Lab -> a < amin || Lab->a > amax||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                Lab -> b < bmin || Lab->b > bmax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                 cmsCIELCh LCh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                 double h, slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                 // Falls outside a, b limits. Transports to LCh space,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                 // and then do the clipping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                 if (Lab -> a == 0.0) { // Is hue exactly 90?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                        // atan will not work, so clamp here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                        Lab -> b = Lab->b < 0 ? bmin : bmax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                 cmsLab2LCh(&LCh, Lab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                 slope = Lab -> b / Lab -> a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                 h = LCh.h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                 // There are 4 zones
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                 if ((h >= 0. && h < 45.) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                     (h >= 315 && h <= 360.)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                     // clip by amax
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                     Lab -> a = amax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                     Lab -> b = amax * slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                 if (h >= 45. && h < 135)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                 {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                        // clip by bmax
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                        Lab -> b = bmax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                        Lab -> a = bmax / slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                 if (h >= 135 && h < 225) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                        // clip by amin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                        Lab -> a = amin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                        Lab -> b = amin * slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                 if (h >= 225 && h < 315) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                        // clip by bmin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                        Lab -> b = bmin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                        Lab -> a = bmin / slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                 else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                        cmsSignalError(LCMS_ERRC_ABORTED, "Invalid angle");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
// Several utilities -------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
// Translate from our colorspace to ICC representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
       switch (OurNotation) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
       case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
       case PT_GRAY: return  icSigGrayData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
       case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
       case PT_RGB:  return  icSigRgbData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
       case PT_CMY:  return  icSigCmyData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
       case PT_CMYK: return  icSigCmykData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
       case PT_YCbCr:return  icSigYCbCrData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
       case PT_YUV:  return  icSigLuvData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
       case PT_XYZ:  return  icSigXYZData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
       case PT_Lab:  return  icSigLabData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
       case PT_YUVK: return  icSigLuvKData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
       case PT_HSV:  return  icSigHsvData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
       case PT_HLS:  return  icSigHlsData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
       case PT_Yxy:  return  icSigYxyData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
       case PT_HiFi: return  icSigHexachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
       case PT_HiFi7: return icSigHeptachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
       case PT_HiFi8: return icSigOctachromeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
       case PT_HiFi9:  return icSigMCH9Data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
       case PT_HiFi10: return icSigMCHAData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
       case PT_HiFi11: return icSigMCHBData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
       case PT_HiFi12: return icSigMCHCData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
       case PT_HiFi13: return icSigMCHDData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
       case PT_HiFi14: return icSigMCHEData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
       case PT_HiFi15: return icSigMCHFData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
       default:  return icMaxEnumData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    switch (ProfileSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    case icSigGrayData: return  PT_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    case icSigRgbData:  return  PT_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    case icSigCmyData:  return  PT_CMY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    case icSigCmykData: return  PT_CMYK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    case icSigYCbCrData:return  PT_YCbCr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    case icSigLuvData:  return  PT_YUV;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    case icSigXYZData:  return  PT_XYZ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    case icSigLabData:  return  PT_Lab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    case icSigLuvKData: return  PT_YUVK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    case icSigHsvData:  return  PT_HSV;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    case icSigHlsData:  return  PT_HLS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    case icSigYxyData:  return  PT_Yxy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    case icSig6colorData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    case icSigHexachromeData: return PT_HiFi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    case icSigHeptachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    case icSig7colorData:     return PT_HiFi7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    case icSigOctachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    case icSig8colorData:     return PT_HiFi8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    case icSigMCH9Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    case icSig9colorData:     return PT_HiFi9;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    case icSigMCHAData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
    case icSig10colorData:     return PT_HiFi10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    case icSigMCHBData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    case icSig11colorData:     return PT_HiFi11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    case icSigMCHCData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    case icSig12colorData:     return PT_HiFi12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    case icSigMCHDData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    case icSig13colorData:     return PT_HiFi13;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    case icSigMCHEData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    case icSig14colorData:     return PT_HiFi14;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    case icSigMCHFData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    case icSig15colorData:     return PT_HiFi15;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    default:  return icMaxEnumData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    switch (ColorSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    case icSigGrayData: return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    case icSig2colorData:  return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    case icSigXYZData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    case icSigLabData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    case icSigLuvData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    case icSigYCbCrData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    case icSigYxyData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    case icSigRgbData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    case icSigHsvData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    case icSigHlsData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    case icSigCmyData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    case icSig3colorData:  return 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    case icSigLuvKData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    case icSigCmykData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    case icSig4colorData:  return 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    case icSigMCH5Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    case icSig5colorData:  return 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    case icSigHexachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    case icSig6colorData:  return 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    case icSigHeptachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    case icSig7colorData:  return  7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    case icSigOctachromeData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    case icSig8colorData:  return  8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    case icSigMCH9Data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    case icSig9colorData:  return  9;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    case icSigMCHAData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    case icSig10colorData: return 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    case icSigMCHBData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    case icSig11colorData: return 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    case icSigMCHCData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    case icSig12colorData: return 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    case icSigMCHDData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    case icSig13colorData: return 13;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    case icSigMCHEData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    case icSig14colorData: return 14;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    case icSigMCHFData:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    case icSig15colorData: return 15;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    default: return 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
// v2 L=100 is supposed to be placed on 0xFF00. There is no reasonable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
// number of gridpoints that would make exact match. However, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
// prelinearization of 258 entries, would map 0xFF00 on entry 257.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
// This is almost what we need, unfortunately, the rest of entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
// should be scaled by (255*257/256) and this is not exact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
// An intermediate solution would be to use 257 entries. This does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
// map 0xFF00 exactly on a node, but so close that the dE induced is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
// negligible. AND the rest of curve is exact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
void CreateLabPrelinearization(LPGAMMATABLE LabTable[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    LabTable[0] = cmsAllocGamma(257);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    LabTable[1] = cmsBuildGamma(257, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    LabTable[2] = cmsBuildGamma(257, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    // L* uses 257 entries. Entry 256 holds 0xFFFF, so, the effective range
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    // is 0..0xFF00. Last entry (257) is also collapsed to 0xFFFF
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    // From 0 to 0xFF00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    for (i=0; i < 256; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        LabTable[0]->GammaTable[i] = RGB_8_TO_16(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    // Repeat last for 0xFFFF
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    LabTable[0] ->GammaTable[256] = 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
// Used by gamut & softproofing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    cmsHTRANSFORM hInput;               // From whatever input color space. NULL for Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    cmsHTRANSFORM hForward, hReverse;   // Transforms going from Lab to colorant and back
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    double Thereshold;                  // The thereshold after which is considered out of gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
    } GAMUTCHAIN,FAR* LPGAMUTCHAIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
// This sampler does compute gamut boundaries by comparing original
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
// values with a transform going back and forth. Values above ERR_THERESHOLD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
// of maximum are considered out of gamut.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
#define ERR_THERESHOLD      5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
int GamutSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    WORD Proof[MAXCHANNELS], Check[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    WORD Proof2[MAXCHANNELS], Check2[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    cmsCIELab LabIn1, LabOut1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    cmsCIELab LabIn2, LabOut2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    double dE1, dE2, ErrorRatio;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    // Assume in-gamut by default.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    dE1 = 0.;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    dE2 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    ErrorRatio = 1.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    // Any input space? I can use In[] no matter channels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    // because is just one pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    if (t -> hInput != NULL) cmsDoTransform(t -> hInput, In, In, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    // converts from PCS to colorant. This always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    // does return in-gamut values,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    cmsDoTransform(t -> hForward, In, Proof, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    // Now, do the inverse, from colorant to PCS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    cmsDoTransform(t -> hReverse, Proof, Check, 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
    // Try again, but this time taking Check as input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    cmsDoTransform(t -> hForward, Check, Proof2,  1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    cmsDoTransform(t -> hReverse, Proof2, Check2, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    // Does the transform returns out-of-gamut?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    if (Check[0] == 0xFFFF &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        Check[1] == 0xFFFF &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        Check[2] == 0xFFFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        Out[0] = 0xFF00;            // Out of gamut!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        // Transport encoded values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        cmsLabEncoded2Float(&LabIn1,  In);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        cmsLabEncoded2Float(&LabOut1, Check);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        // Take difference of direct value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        dE1 = cmsDeltaE(&LabIn1, &LabOut1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        cmsLabEncoded2Float(&LabIn2,  Check);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        cmsLabEncoded2Float(&LabOut2, Check2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        // Take difference of converted value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        dE2 = cmsDeltaE(&LabIn2, &LabOut2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        // if dE1 is small and dE2 is small, value is likely to be in gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        if (dE1 < t->Thereshold && dE2 < t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            Out[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            // if dE1 is small and dE2 is big, undefined. Assume in gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            if (dE1 < t->Thereshold && dE2 > t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                Out[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                // dE1 is big and dE2 is small, clearly out of gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                if (dE1 > t->Thereshold && dE2 < t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                    Out[0] = (WORD) _cmsQuickFloor((dE1 - t->Thereshold) + .5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                else  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                    // dE1 is big and dE2 is also big, could be due to perceptual mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                    // so take error ratio
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                    if (dE2 == 0.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                        ErrorRatio = dE1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                        ErrorRatio = dE1 / dE2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                    if (ErrorRatio > t->Thereshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                        Out[0] = (WORD)  _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                        Out[0] = 0;
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
// Does compute a gamut LUT going back and forth across
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
// pcs -> relativ. colorimetric intent -> pcs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
// the dE obtained is then annotated on the LUT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
// values truely out of gamut, are clipped to dE = 0xFFFE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
// and values changed are supposed to be handled by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
// any gamut remapping, so, are out of gamut as well.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
// **WARNING: This algorithm does assume that gamut
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
// remapping algorithms does NOT move in-gamut colors,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
// of course, many perceptual and saturation intents does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
// not work in such way, but relativ. ones should.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
LPLUT ComputeGamutWithInput(cmsHPROFILE hInput, cmsHPROFILE hProfile, int Intent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    cmsHPROFILE hLab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    LPLUT Gamut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    DWORD dwFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    GAMUTCHAIN Chain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    int nErrState, nChannels, nGridpoints;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    LPGAMMATABLE Trans[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    icColorSpaceSignature ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    ZeroMemory(&Chain, sizeof(GAMUTCHAIN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    hLab = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    // Safeguard against early abortion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    nErrState = cmsErrorAction(LCMS_ERROR_IGNORE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    // The figure of merit. On matrix-shaper profiles, should be almost zero as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
    // the conversion is pretty exact. On LUT based profiles, different resolutions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    // of input and output CLUT may result in differences.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
    if (!cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        !cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_OUTPUT))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        Chain.Thereshold = 1.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        Chain.Thereshold = ERR_THERESHOLD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
    ColorSpace  = cmsGetColorSpace(hProfile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    // If input profile specified, create a transform from such profile to Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
    if (hInput != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        nChannels   = _cmsChannelsOf(ColorSpace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        dwFormat    = (CHANNELS_SH(nChannels)|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        Chain.hInput = cmsCreateTransform(hInput, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                                          hLab,   TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                                          Intent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                                          cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    else  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        // Input transform=NULL (Lab) Used to compute the gamut tag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        // This table will take 53 points to give some accurancy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        // 53 * 53 * 53 * 2 = 291K
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        nChannels    = 3;      // For Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        nGridpoints  = 53;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        Chain.hInput = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        dwFormat = (CHANNELS_SH(_cmsChannelsOf(ColorSpace))|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    // Does create the forward step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                                        hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    // Does create the backwards step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    Chain.hReverse = cmsCreateTransform(hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                                        hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    // Restores error handler previous state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    cmsErrorAction(nErrState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    // All ok?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    if (Chain.hForward && Chain.hReverse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    // Go on, try to compute gamut LUT from PCS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    // This consist on a single channel containing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
    // dE when doing a transform back and forth on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    // the colorimetric intent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    Gamut = cmsAllocLUT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    Gamut = cmsAlloc3DGrid(Gamut, nGridpoints, nChannels, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    // If no input, then this is a gamut tag operated by Lab,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    // so include pertinent prelinearization
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    if (hInput == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        cmsAllocLinearTable(Gamut, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    cmsSample3DGrid(Gamut, GamutSampler, (LPVOID) &Chain, Gamut ->wFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        Gamut = NULL;   // Didn't work...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    // Free all needed stuff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    if (Chain.hInput)   cmsDeleteTransform(Chain.hInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    if (Chain.hForward) cmsDeleteTransform(Chain.hForward);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
    // And return computed hull
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    return Gamut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
// Wrapper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
LPLUT _cmsComputeGamutLUT(cmsHPROFILE hProfile, int Intent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
    return ComputeGamutWithInput(NULL, hProfile, Intent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
// This routine does compute the gamut check CLUT. This CLUT goes from whatever
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
// input space to the 0 or != 0 gamut check.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
LPLUT _cmsPrecalculateGamutCheck(cmsHTRANSFORM h)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
       _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
       return ComputeGamutWithInput(p->InputProfile, p ->PreviewProfile, p->Intent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
// SoftProofing. Convert from Lab to device, then back to Lab,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
// any gamut remapping is applied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
int SoftProofSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        WORD Colorant[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        // From pcs to colorant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        cmsDoTransform(t -> hForward, In, Colorant, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        // Now, do the inverse, from colorant to pcs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        cmsDoTransform(t -> hReverse, Colorant, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
// Does return Softproofing LUT on desired intent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
LPLUT _cmsComputeSoftProofLUT(cmsHPROFILE hProfile, int nIntent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    cmsHPROFILE hLab;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    LPLUT SoftProof;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
    DWORD dwFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    GAMUTCHAIN Chain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    int nErrState;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    LPGAMMATABLE Trans[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
    // LUTs are never abs. colorimetric, is the transform who
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    // is responsible of generating white point displacement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    if (nIntent == INTENT_ABSOLUTE_COLORIMETRIC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        nIntent = INTENT_RELATIVE_COLORIMETRIC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    ZeroMemory(&Chain, sizeof(GAMUTCHAIN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    hLab = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    // ONLY 4 channels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    dwFormat = (CHANNELS_SH(4)|BYTES_SH(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    // Safeguard against early abortion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    nErrState = cmsErrorAction(LCMS_ERROR_IGNORE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    // Does create the first step
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                                        hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                                        nIntent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    // Does create the last step
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    Chain.hReverse = cmsCreateTransform(hProfile, dwFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                                        hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                                        INTENT_RELATIVE_COLORIMETRIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                                        cmsFLAGS_NOTPRECALC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    // Restores error handler previous state
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    cmsErrorAction(nErrState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    // All ok?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
    if (Chain.hForward && Chain.hReverse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    // This is Lab -> Lab, so 33 point should hold anything
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
    SoftProof = cmsAllocLUT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
    SoftProof = cmsAlloc3DGrid(SoftProof, 33, 3, 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
    CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    cmsAllocLinearTable(SoftProof, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
    cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
    cmsSample3DGrid(SoftProof, SoftProofSampler, (LPVOID) &Chain, SoftProof->wFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        SoftProof = NULL;   // Didn't work...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
    // Free all needed stuff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    if (Chain.hForward) cmsDeleteTransform(Chain.hForward);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
    if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
    return SoftProof;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
int MostlyLinear(WORD Table[], int nEntries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
       register int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
       int diff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
       for (i=5; i < nEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
           diff = abs((int) Table[i] - (int) _cmsQuantizeVal(i, nEntries));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
           if (diff > 0x0300)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                     return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
       return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
void SlopeLimiting(WORD Table[], int nEntries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
    int At = (int) floor((double) nEntries * 0.02 + 0.5);   // Cutoff at 2%
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
    double Val, Slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
    Val   = Table[At];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    Slope = Val / At;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
    for (i=0; i < At; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        Table[i] = (WORD) floor(i * Slope + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
// Check for monotonicity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
static
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1073
LCMSBOOL IsMonotonic(LPGAMMATABLE t)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    int n = t -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
    int i, last;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    last = t ->GammaTable[n-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
    for (i = n-2; i >= 0; --i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
        if (t ->GammaTable[i] > last)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
               return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                last = t ->GammaTable[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
// Check for endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
static
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1096
LCMSBOOL HasProperEndpoints(LPGAMMATABLE t)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
    if (t ->GammaTable[0] != 0) return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
    if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
    return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
#define PRELINEARIZATION_POINTS 4096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
// Fixes the gamma balancing of transform. Thanks to Mike Chaney
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
// for pointing this subtle bug.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransforms, LPLUT Grid)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
    LPGAMMATABLE Trans[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
    unsigned int t, i, v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
    int j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    WORD In[MAXCHANNELS], Out[MAXCHANNELS];
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1117
    LCMSBOOL lIsSuitable;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    _LPcmsTRANSFORM InputXForm   = (_LPcmsTRANSFORM) h[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    _LPcmsTRANSFORM OutputXForm  = (_LPcmsTRANSFORM) h[nTransforms-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
    // First space is *Lab, use our specialized curves for v2 Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
    if (InputXForm ->EntryColorSpace == icSigLabData &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
        OutputXForm->ExitColorSpace != icSigLabData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                CreateLabPrelinearization(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                cmsAllocLinearTable(Grid, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                cmsFreeGammaTriple(Trans);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1134
    // Do nothing on all but Gray/RGB to Gray/RGB transforms
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1136
    if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) ||
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1137
        ((OutputXForm->ExitColorSpace  != icSigRgbData) && (OutputXForm->ExitColorSpace  != icSigGrayData))) return;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
    for (t = 0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            Trans[t] = cmsAllocGamma(PRELINEARIZATION_POINTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
    for (i=0; i < PRELINEARIZATION_POINTS; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                v = _cmsQuantizeVal(i, PRELINEARIZATION_POINTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                for (t=0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                        In[t] = (WORD) v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                cmsDoTransform(h[0], In, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                for (j=1; j < nTransforms; j++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                        cmsDoTransform(h[j], Out, Out, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                for (t=0; t < Grid -> InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                        Trans[t] ->GammaTable[i] = Out[t];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
    // Check transfer curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
    lIsSuitable = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    for (t=0; (lIsSuitable && (t < Grid->InputChan)); t++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
        // Exclude if already linear
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
        if (MostlyLinear(Trans[t]->GammaTable, PRELINEARIZATION_POINTS))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        // Exclude if non-monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
        if (!IsMonotonic(Trans[t]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
        // Exclude if weird endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        if (!HasProperEndpoints(Trans[t]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                    lIsSuitable = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1177
        /*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        // Exclude if transfer function is not smooth enough
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        // to be modelled as a gamma function, or the gamma is reversed
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1180
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        if (cmsEstimateGamma(Trans[t]) < 1.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                    lIsSuitable = FALSE;
2394
404cbe399601 6821031: Upgrade OpenJDK's LittleCMS version to 1.18
prr
parents: 2
diff changeset
  1183
        */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
    if (lIsSuitable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
            for (t = 0; t < Grid ->InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                SlopeLimiting(Trans[t]->GammaTable, Trans[t]->nEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
    if (lIsSuitable) cmsAllocLinearTable(Grid, Trans, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
    for (t = 0; t < Grid ->InputChan; t++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                        cmsFreeGamma(Trans[t]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
// Compute K -> L* relationship. Flags may include black point compensation. In this case,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
// the relationship is assumed from the profile with BPC to a black point zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
LPGAMMATABLE ComputeKToLstar(cmsHPROFILE hProfile, int nPoints, int Intent, DWORD dwFlags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
    LPGAMMATABLE out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
    WORD cmyk[4], wLab[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
    cmsHPROFILE   hLab  = cmsCreateLabProfile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
    cmsHTRANSFORM xform = cmsCreateTransform(hProfile, TYPE_CMYK_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                                             hLab, TYPE_Lab_16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                                             Intent, (dwFlags|cmsFLAGS_NOTPRECALC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
    out = cmsAllocGamma(nPoints);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
    for (i=0; i < nPoints; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        cmyk[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
        cmyk[1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
        cmyk[2] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        cmyk[3] = _cmsQuantizeVal(i, nPoints);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
        cmsDoTransform(xform, cmyk, wLab, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
        out->GammaTable[i] = (WORD) (0xFFFF - wLab[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
    cmsDeleteTransform(xform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
    cmsCloseProfile(hLab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
    return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
// Compute Black tone curve on a CMYK -> CMYK transform. This is done by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
// using the proof direction on both profiles to find K->L* relationship
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
// then joining both curves. dwFlags may include black point compensation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
    LPGAMMATABLE in, out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
    LPGAMMATABLE KTone;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) hCMYK2CMYK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
    // Make sure CMYK -> CMYK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
    if (p -> EntryColorSpace != icSigCmykData ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
        p -> ExitColorSpace  != icSigCmykData) return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
    // Create individual curves. BPC works also as each K to L* is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
    // computed as a BPC to zero black point in case of L*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
    in  = ComputeKToLstar(p ->InputProfile,  nPoints, p->Intent, p -> dwOriginalFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
    out = ComputeKToLstar(p ->OutputProfile, nPoints, p->Intent, p -> dwOriginalFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
    // Build the relationship
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
    KTone = cmsJoinGamma(in, out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
    cmsFreeGamma(in); cmsFreeGamma(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
    // Make sure it is monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
    if (!IsMonotonic(KTone)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
        cmsFreeGamma(KTone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
    return KTone;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
}