jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 2394 404cbe399601
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
// This file is available under and governed by the GNU General Public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
// License version 2 only, as published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
// However, the following notice accompanied the original version of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
// file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
//  Little cms
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
//  Copyright (C) 1998-2006 Marti Maria
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
// Permission is hereby granted, free of charge, to any person obtaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
// a copy of this software and associated documentation files (the "Software"),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
// to deal in the Software without restriction, including without limitation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
// and/or sell copies of the Software, and to permit persons to whom the Software
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
// is furnished to do so, subject to the following conditions:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
// The above copyright notice and this permission notice shall be included in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
// all copies or substantial portions of the Software.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
#include "lcms.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
//  Pipeline of LUT. Enclosed by {} are new revision 4.0 of ICC spec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
//  [Mat] -> [L1] -> { [Mat3] -> [Ofs3] -> [L3] ->} [CLUT] { -> [L4] -> [Mat4] -> [Ofs4] } -> [L2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
//  Some of these stages would be missing. This implements the totality of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
//  combinations of old and new LUT types as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
//  Lut8 & Lut16
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
//  ============
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
//     [Mat] -> [L1] -> [CLUT] -> [L2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
//  Mat2, Ofs2, L3, L3, Mat3, Ofs3 are missing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
//  LutAToB
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
//  ========
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
//  [L1] -> [CLUT] -> [L4] -> [Mat4] -> [Ofs4] -> [L2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
//  Mat, Mat3, Ofs3, L3 are missing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
//   L1 = A curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
//   L4 = M curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
//   L2 = B curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
//  LutBToA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
//  =======
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
//  [L1] -> [Mat3] -> [Ofs3] -> [L3] -> [CLUT] -> [L2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
//  Mat, L4, Mat4, Ofs4 are missing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
//   L1 = B Curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
//   L3 = M Curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
//   L2 = A curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
//  V2&3 emulation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
//  ===============
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
//  For output, Mat is multiplied by
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
//  | 0xff00 / 0xffff      0                    0           |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
//  |        0          0xff00 / 0xffff         0           |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
//  |        0             0                0xff00 / 0xffff |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
//  For input, an additional matrix is needed at the very last end of the chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
//  | 0xffff / 0xff00      0                     0        |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
//  |        0          0xffff / 0xff00          0        |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
//  |        0             0              0xffff / 0xff00 |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
//  Which reduces to (val * 257) >> 8
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
// A couple of macros to convert between revisions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
#define FROM_V2_TO_V4(x) (((((x)<<8)+(x))+0x80)>>8)    // BY 65535 DIV 65280 ROUND
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
#define FROM_V4_TO_V2(x) ((((x)<<8)+0x80)/257)         // BY 65280 DIV 65535 ROUND
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
// Lut Creation & Destruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
LPLUT LCMSEXPORT cmsAllocLUT(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
       LPLUT NewLUT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
       NewLUT = (LPLUT) malloc(sizeof(LUT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
       if (NewLUT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
              ZeroMemory(NewLUT, sizeof(LUT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
       return NewLUT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
void LCMSEXPORT cmsFreeLUT(LPLUT Lut)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
       unsigned int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
       if (!Lut) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
       if (Lut -> T) free(Lut -> T);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
       for (i=0; i < Lut -> OutputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
              if (Lut -> L2[i]) free(Lut -> L2[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
       for (i=0; i < Lut -> InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
              if (Lut -> L1[i]) free(Lut -> L1[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
       if (Lut ->wFlags & LUT_HASTL3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            for (i=0; i < Lut -> InputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
              if (Lut -> L3[i]) free(Lut -> L3[i]);
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
       if (Lut ->wFlags & LUT_HASTL4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            for (i=0; i < Lut -> OutputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
              if (Lut -> L4[i]) free(Lut -> L4[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
       if (Lut ->CLut16params.p8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
           free(Lut ->CLut16params.p8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
       free(Lut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
LPVOID DupBlockTab(LPVOID Org, size_t size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    LPVOID mem = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    CopyMemory(mem, Org, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    return mem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
LPLUT LCMSEXPORT cmsDupLUT(LPLUT Orig)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    LPLUT NewLUT = cmsAllocLUT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    unsigned int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
       CopyMemory(NewLUT, Orig, sizeof(LUT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
       for (i=0; i < Orig ->InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            NewLUT -> L1[i] = (LPWORD) DupBlockTab((LPVOID) Orig ->L1[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                                        sizeof(WORD) * Orig ->In16params.nSamples);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
       for (i=0; i < Orig ->OutputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            NewLUT -> L2[i] = (LPWORD) DupBlockTab((LPVOID) Orig ->L2[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                                        sizeof(WORD) * Orig ->Out16params.nSamples);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
       NewLUT -> T = (LPWORD) DupBlockTab((LPVOID) Orig ->T, Orig -> Tsize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
       return NewLUT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
unsigned int UIpow(unsigned int a, unsigned int b)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        unsigned int rv = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        for (; b > 0; b--)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                rv *= a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        return rv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    DWORD nTabSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
       NewLUT -> wFlags       |= LUT_HAS3DGRID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
       NewLUT -> cLutPoints    = clutPoints;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
       NewLUT -> InputChan     = inputChan;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
       NewLUT -> OutputChan    = outputChan;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
       nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                                                NewLUT->InputChan)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                                                * sizeof(WORD));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
       NewLUT -> T = (LPWORD) malloc(nTabSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
       ZeroMemory(NewLUT -> T, nTabSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
       NewLUT ->Tsize = nTabSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
       cmsCalcCLUT16Params(NewLUT -> cLutPoints,  NewLUT -> InputChan,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                                                  NewLUT -> OutputChan,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                                                  &NewLUT -> CLut16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
       return NewLUT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nTable)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
       unsigned int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
       LPWORD PtrW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
       switch (nTable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
       case 1: NewLUT -> wFlags |= LUT_HASTL1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
               cmsCalcL16Params(Tables[0] -> nEntries, &NewLUT -> In16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
               NewLUT -> InputEntries = Tables[0] -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
               for (i=0; i < NewLUT -> InputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                     NewLUT -> L1[i] = PtrW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                     CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                                         CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
               }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
               break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
       case 2: NewLUT -> wFlags |= LUT_HASTL2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
               cmsCalcL16Params(Tables[0] -> nEntries, &NewLUT -> Out16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
               NewLUT -> OutputEntries = Tables[0] -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
               for (i=0; i < NewLUT -> OutputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                     NewLUT -> L2[i] = PtrW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                     CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                                         CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
               }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
               break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
       // 3 & 4 according ICC 4.0 spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
       case 3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
               NewLUT -> wFlags |= LUT_HASTL3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
               cmsCalcL16Params(Tables[0] -> nEntries, &NewLUT -> L3params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
               NewLUT -> L3Entries = Tables[0] -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
               for (i=0; i < NewLUT -> InputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                     NewLUT -> L3[i] = PtrW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                     CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                                         CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
               }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
               break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
       case 4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
               NewLUT -> wFlags |= LUT_HASTL4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
               cmsCalcL16Params(Tables[0] -> nEntries, &NewLUT -> L4params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
               NewLUT -> L4Entries = Tables[0] -> nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
               for (i=0; i < NewLUT -> OutputChan; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L4Entries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                     NewLUT -> L4[i] = PtrW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                     CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                                         CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
               }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
               break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
       default:;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
       return NewLUT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
// Set the LUT matrix
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
LPLUT LCMSEXPORT cmsSetMatrixLUT(LPLUT Lut, LPMAT3 M)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        MAT3toFix(&Lut ->Matrix, M);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        if (!MAT3isIdentity(&Lut->Matrix, 0.0001))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            Lut ->wFlags |= LUT_HASMATRIX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        return Lut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
// Set matrix & offset, v4 compatible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
LPLUT LCMSEXPORT cmsSetMatrixLUT4(LPLUT Lut, LPMAT3 M, LPVEC3 off, DWORD dwFlags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    WMAT3 WMat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    WVEC3 Woff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    VEC3  Zero = {{0, 0, 0}};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        MAT3toFix(&WMat, M);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        if (off == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                off = &Zero;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        VEC3toFix(&Woff, off);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        // Nop if identity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        if (MAT3isIdentity(&WMat, 0.0001) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            (Woff.n[VX] == 0 && Woff.n[VY] == 0 && Woff.n[VZ] == 0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            return Lut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        switch (dwFlags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        case LUT_HASMATRIX:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                Lut ->Matrix = WMat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                Lut ->wFlags |= LUT_HASMATRIX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        case LUT_HASMATRIX3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                Lut ->Mat3 = WMat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                Lut ->Ofs3 = Woff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                Lut ->wFlags |= LUT_HASMATRIX3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        case LUT_HASMATRIX4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                Lut ->Mat4 = WMat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                Lut ->Ofs4 = Woff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                Lut ->wFlags |= LUT_HASMATRIX4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        default:;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        return Lut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
// The full evaluator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
void LCMSEXPORT cmsEvalLUT(LPLUT Lut, WORD In[], WORD Out[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
       register unsigned int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
       WORD StageABC[MAXCHANNELS], StageLMN[MAXCHANNELS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
       // Try to speedup things on plain devicelinks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
       if (Lut ->wFlags == LUT_HAS3DGRID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            Lut ->CLut16params.Interp3D(In, Out, Lut -> T, &Lut -> CLut16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
       // Nope, evaluate whole LUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
       for (i=0; i < Lut -> InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                            StageABC[i] = In[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
       if (Lut ->wFlags & LUT_V4_OUTPUT_EMULATE_V2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
           // Clamp Lab to avoid overflow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
           if (StageABC[0] > 0xFF00)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
               StageABC[0] = 0xFF00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
           StageABC[0] = (WORD) FROM_V2_TO_V4(StageABC[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
           StageABC[1] = (WORD) FROM_V2_TO_V4(StageABC[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
           StageABC[2] = (WORD) FROM_V2_TO_V4(StageABC[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
       if (Lut ->wFlags & LUT_V2_OUTPUT_EMULATE_V4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
           StageABC[0] = (WORD) FROM_V4_TO_V2(StageABC[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
           StageABC[1] = (WORD) FROM_V4_TO_V2(StageABC[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
           StageABC[2] = (WORD) FROM_V4_TO_V2(StageABC[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
       // Matrix handling.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
       if (Lut -> wFlags & LUT_HASMATRIX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
              WVEC3 InVect, OutVect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
              // In LUT8 here comes the special gray axis fixup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
              if (Lut ->FixGrayAxes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                  StageABC[1] = _cmsClampWord(StageABC[1] - 128);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                  StageABC[2] = _cmsClampWord(StageABC[2] - 128);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
              // Matrix
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
              InVect.n[VX] = ToFixedDomain(StageABC[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
              InVect.n[VY] = ToFixedDomain(StageABC[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
              InVect.n[VZ] = ToFixedDomain(StageABC[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
              MAT3evalW(&OutVect, &Lut -> Matrix, &InVect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
              // PCS in 1Fixed15 format, adjusting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
       // First linearization
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
       if (Lut -> wFlags & LUT_HASTL1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
              for (i=0; i < Lut -> InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                                                   Lut -> L1[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                                                   &Lut -> In16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
       //  Mat3, Ofs3, L3 processing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
       if (Lut ->wFlags & LUT_HASMATRIX3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
              WVEC3 InVect, OutVect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
              InVect.n[VX] = ToFixedDomain(StageABC[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
              InVect.n[VY] = ToFixedDomain(StageABC[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
              InVect.n[VZ] = ToFixedDomain(StageABC[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
              MAT3evalW(&OutVect, &Lut -> Mat3, &InVect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
              OutVect.n[VX] += Lut ->Ofs3.n[VX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
              OutVect.n[VY] += Lut ->Ofs3.n[VY];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
              OutVect.n[VZ] += Lut ->Ofs3.n[VZ];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
       if (Lut ->wFlags & LUT_HASTL3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
             for (i=0; i < Lut -> InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                                                   Lut -> L3[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                                                   &Lut -> L3params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
       if (Lut -> wFlags & LUT_HAS3DGRID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            Lut ->CLut16params.Interp3D(StageABC, StageLMN, Lut -> T, &Lut -> CLut16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
       else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
              for (i=0; i < Lut -> InputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                            StageLMN[i] = StageABC[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
       // Mat4, Ofs4, L4 processing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
       if (Lut ->wFlags & LUT_HASTL4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            for (i=0; i < Lut -> OutputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                     StageLMN[i] = cmsLinearInterpLUT16(StageLMN[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                                                   Lut -> L4[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                                                   &Lut -> L4params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
       if (Lut ->wFlags & LUT_HASMATRIX4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
              WVEC3 InVect, OutVect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
              InVect.n[VX] = ToFixedDomain(StageLMN[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
              InVect.n[VY] = ToFixedDomain(StageLMN[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
              InVect.n[VZ] = ToFixedDomain(StageLMN[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
              MAT3evalW(&OutVect, &Lut -> Mat4, &InVect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
              OutVect.n[VX] += Lut ->Ofs4.n[VX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
              OutVect.n[VY] += Lut ->Ofs4.n[VY];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
              OutVect.n[VZ] += Lut ->Ofs4.n[VZ];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
              StageLMN[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
              StageLMN[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
              StageLMN[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
       // Last linearitzation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
       if (Lut -> wFlags & LUT_HASTL2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
              for (i=0; i < Lut -> OutputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                     Out[i] = cmsLinearInterpLUT16(StageLMN[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                                                   Lut -> L2[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                                                   &Lut -> Out16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
       else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
       for (i=0; i < Lut -> OutputChan; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
              Out[i] = StageLMN[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
       if (Lut ->wFlags & LUT_V4_INPUT_EMULATE_V2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
           Out[0] = (WORD) FROM_V4_TO_V2(Out[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
           Out[1] = (WORD) FROM_V4_TO_V2(Out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
           Out[2] = (WORD) FROM_V4_TO_V2(Out[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
       if (Lut ->wFlags & LUT_V2_INPUT_EMULATE_V4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
           Out[0] = (WORD) FROM_V2_TO_V4(Out[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
           Out[1] = (WORD) FROM_V2_TO_V4(Out[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
           Out[2] = (WORD) FROM_V2_TO_V4(Out[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
// Precomputes tables for 8-bit on input devicelink.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
LPLUT _cmsBlessLUT8(LPLUT Lut)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
   int i, j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
   WORD StageABC[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
   Fixed32 v1, v2, v3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
   LPL8PARAMS p8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
   LPL16PARAMS p = &Lut ->CLut16params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
   p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
   if (p8 == NULL) return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
  // values comes * 257, so we can safely take first byte (x << 8 + x)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
  // if there are prelinearization, is already smelted in tables
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
   for (i=0; i < 256; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
           StageABC[0] = StageABC[1] = StageABC[2] = RGB_8_TO_16(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
           if (Lut ->wFlags & LUT_HASTL1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
              for (j=0; j < 3; j++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                                                        Lut -> L1[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                                                       &Lut -> In16params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
              Lut ->wFlags &= ~LUT_HASTL1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
           }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
           v1 = ToFixedDomain(StageABC[0] * p -> Domain);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
           v2 = ToFixedDomain(StageABC[1] * p -> Domain);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
           v3 = ToFixedDomain(StageABC[2] * p -> Domain);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
           p8 ->X0[i] = p->opta3 * FIXED_TO_INT(v1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
           p8 ->Y0[i] = p->opta2 * FIXED_TO_INT(v2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
           p8 ->Z0[i] = p->opta1 * FIXED_TO_INT(v3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
           p8 ->rx[i] = (WORD) FIXED_REST_TO_INT(v1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
           p8 ->ry[i] = (WORD) FIXED_REST_TO_INT(v2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
           p8 ->rz[i] = (WORD) FIXED_REST_TO_INT(v3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
   Lut -> CLut16params.p8 = p8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
   Lut -> CLut16params.Interp3D = cmsTetrahedralInterp8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
   return Lut;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
// ----------------------------------------------------------- Reverse interpolation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
// Here's how it goes. The derivative Df(x) of the function f is the linear
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
// transformation that best approximates f near the point x. It can be represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
// by a matrix A whose entries are the partial derivatives of the components of f
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
// with respect to all the coordinates. This is know as the Jacobian
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
// The best linear approximation to f is given by the matrix equation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
// y-y0 = A (x-x0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
// So, if x0 is a good "guess" for the zero of f, then solving for the zero of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
// linear approximation will give a "better guess" for the zero of f. Thus let y=0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
// and since y0=f(x0) one can solve the above equation for x. This leads to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
// Newton's method formula:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
// xn+1 = xn - A-1 f(xn)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
// where xn+1 denotes the (n+1)-st guess, obtained from the n-th guess xn in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
// fashion described above. Iterating this will give better and better approximations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
// if you have a "good enough" initial guess.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
#define JACOBIAN_EPSILON            0.001
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
#define INVERSION_MAX_ITERATIONS    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
// Increment with reflexion on boundary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
void IncDelta(double *Val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    if (*Val < (1.0 - JACOBIAN_EPSILON))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        *Val += JACOBIAN_EPSILON;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        *Val -= JACOBIAN_EPSILON;
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
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
void ToEncoded(WORD Encoded[3], LPVEC3 Float)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    Encoded[0] = (WORD) floor(Float->n[0] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    Encoded[1] = (WORD) floor(Float->n[1] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    Encoded[2] = (WORD) floor(Float->n[2] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
void FromEncoded(LPVEC3 Float, WORD Encoded[3])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    Float->n[0] = Encoded[0] / 65535.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    Float->n[1] = Encoded[1] / 65535.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    Float->n[2] = Encoded[2] / 65535.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
// Evaluates the CLUT part of a LUT (4 -> 3 only)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
void EvalLUTdoubleKLab(LPLUT Lut, const VEC3* In, WORD FixedK, LPcmsCIELab Out)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    WORD wIn[4], wOut[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    wIn[0] = (WORD) floor(In ->n[0] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    wIn[1] = (WORD) floor(In ->n[1] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    wIn[2] = (WORD) floor(In ->n[2] * 65535.0 + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    wIn[3] = FixedK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    cmsEvalLUT(Lut, wIn, wOut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        cmsLabEncoded2Float(Out, wOut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
// Builds a Jacobian CMY->Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
void ComputeJacobianLab(LPLUT Lut, LPMAT3 Jacobian, const VEC3* Colorant, WORD K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    VEC3 ColorantD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    cmsCIELab Lab, LabD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    int  j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    EvalLUTdoubleKLab(Lut, Colorant, K, &Lab);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    for (j = 0; j < 3; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        ColorantD.n[0] = Colorant ->n[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        ColorantD.n[1] = Colorant ->n[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        ColorantD.n[2] = Colorant ->n[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        IncDelta(&ColorantD.n[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        EvalLUTdoubleKLab(Lut, &ColorantD, K, &LabD);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                Jacobian->v[0].n[j] = ((LabD.L - Lab.L) / JACOBIAN_EPSILON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                Jacobian->v[1].n[j] = ((LabD.a - Lab.a) / JACOBIAN_EPSILON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                Jacobian->v[2].n[j] = ((LabD.b - Lab.b) / JACOBIAN_EPSILON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
// Evaluate a LUT in reverse direction. It only searches on 3->3 LUT, but It
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
// can be used on CMYK -> Lab LUT to obtain black preservation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
// Target holds LabK in this case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
// x1 <- x - [J(x)]^-1 * f(x)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Result[], LPWORD Hint)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    int      i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    double     error, LastError = 1E20;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    cmsCIELab  fx, Goal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    VEC3       tmp, tmp2, x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    MAT3       Jacobian;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    WORD       FixedK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    WORD       LastResult[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    // This is our Lab goal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    cmsLabEncoded2Float(&Goal, Target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    // Special case for CMYK->Lab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    if (Lut ->InputChan == 4)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            FixedK = Target[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            FixedK = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    // Take the hint as starting point if specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
    if (Hint == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        // Begin at any point, we choose 1/3 of neutral CMY gray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        x.n[0] = x.n[1] = x.n[2] = 0.3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        FromEncoded(&x, Hint);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    // Iterate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    for (i = 0; i < INVERSION_MAX_ITERATIONS; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        // Get beginning fx
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        EvalLUTdoubleKLab(Lut, &x, FixedK, &fx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        // Compute error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        error = cmsDeltaE(&fx, &Goal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        // If not convergent, return last safe value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        if (error >= LastError)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        // Keep latest values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        LastError = error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        ToEncoded(LastResult, &x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        LastResult[3] = FixedK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        // Obtain slope
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        ComputeJacobianLab(Lut, &Jacobian, &x, FixedK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                // Solve system
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                tmp2.n[0] = fx.L - Goal.L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                tmp2.n[1] = fx.a - Goal.a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                tmp2.n[2] = fx.b - Goal.b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                if (!MAT3solve(&tmp, &Jacobian, &tmp2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        // Move our guess
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                x.n[0] -= tmp.n[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            x.n[1] -= tmp.n[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                x.n[2] -= tmp.n[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        // Some clipping....
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        VEC3saturate(&x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    Result[0] = LastResult[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    Result[1] = LastResult[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    Result[2] = LastResult[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
    Result[3] = LastResult[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
    return LastError;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
}