1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //
  31 //  Little Color Management System
  32 //  Copyright (c) 1998-2023 Marti Maria Saguer
  33 //
  34 // Permission is hereby granted, free of charge, to any person obtaining
  35 // a copy of this software and associated documentation files (the "Software"),
  36 // to deal in the Software without restriction, including without limitation
  37 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  38 // and/or sell copies of the Software, and to permit persons to whom the Software
  39 // is furnished to do so, subject to the following conditions:
  40 //
  41 // The above copyright notice and this permission notice shall be included in
  42 // all copies or substantial portions of the Software.
  43 //
  44 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  45 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  46 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  47 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  48 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  49 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  50 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  51 //
  52 //---------------------------------------------------------------------------------
  53 //
  54 
  55 #ifndef _lcms_internal_H
  56 
  57 // Include plug-in foundation
  58 #ifndef _lcms_plugin_H
  59 #   include "lcms2_plugin.h"
  60 #endif
  61 
  62 // ctype is part of C99 as per 7.1.2
  63 #include <ctype.h>
  64 
  65 // assert macro is part of C99 as per 7.2
  66 #include <assert.h>
  67 
  68 // Some needed constants
  69 #ifndef M_PI
  70 #       define M_PI        3.14159265358979323846
  71 #endif
  72 
  73 #ifndef M_LOG10E
  74 #       define M_LOG10E    0.434294481903251827651
  75 #endif
  76 
  77 // BorlandC 5.5, VC2003 are broken on that
  78 #if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER < 1400)) // 1400 == VC++ 8.0
  79 #define sinf(x) (float)sin((float)x)
  80 #define sqrtf(x) (float)sqrt((float)x)
  81 #endif
  82 
  83 
  84 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
  85 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
  86 
  87 // Alignment to memory pointer
  88 
  89 // (Ultra)SPARC with gcc requires ptr alignment of 8 bytes
  90 // even though sizeof(void *) is only four: for greatest flexibility
  91 // allow the build to specify ptr alignment.
  92 #ifndef CMS_PTR_ALIGNMENT
  93 # define CMS_PTR_ALIGNMENT sizeof(void *)
  94 #endif
  95 
  96 #define _cmsALIGNMEM(x)  (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
  97 
  98 // Maximum encodeable values in floating point
  99 #define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0)
 100 #define MIN_ENCODEABLE_ab2  (-128.0)
 101 #define MAX_ENCODEABLE_ab2  ((65535.0/256.0) - 128.0)
 102 #define MIN_ENCODEABLE_ab4  (-128.0)
 103 #define MAX_ENCODEABLE_ab4  (127.0)
 104 
 105 // Maximum of channels for internal pipeline evaluation
 106 #define MAX_STAGE_CHANNELS  128
 107 
 108 // Unused parameter warning suppression
 109 #define cmsUNUSED_PARAMETER(x) ((void)x)
 110 
 111 // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
 112 // unfortunately VisualC++ does not conform that
 113 #if defined(_MSC_VER) || defined(__BORLANDC__)
 114 #   define cmsINLINE __inline
 115 #else
 116 #   define cmsINLINE static inline
 117 #endif
 118 
 119 // Allow signed overflow, we know this is harmless in this particular context
 120 #if defined(__clang__)
 121 #   define CMS_NO_SANITIZE __attribute__((no_sanitize("signed-integer-overflow")))
 122 #else
 123 #   define CMS_NO_SANITIZE
 124 #endif
 125 
 126 // Other replacement functions
 127 #ifdef _MSC_VER
 128 # ifndef snprintf
 129 #       define snprintf  _snprintf
 130 # endif
 131 # ifndef vsnprintf
 132 #       define vsnprintf  _vsnprintf
 133 # endif
 134 
 135 /// Properly define some macros to accommodate
 136 /// older MSVC versions.
 137 # if defined(_MSC_VER) && _MSC_VER <= 1700
 138         #include <float.h>
 139         #define isnan _isnan
 140         #define isinf(x) (!_finite((x)))
 141 # endif
 142 
 143 #if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L)
 144         #if !defined(isinf)
 145         #define isinf(x) (!finite((x)))
 146         #endif
 147 #endif
 148 
 149 
 150 #endif
 151 
 152 // A fast way to convert from/to 16 <-> 8 bits
 153 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
 154 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
 155 
 156 // Code analysis is broken on asserts
 157 #ifdef _MSC_VER
 158 #    if (_MSC_VER >= 1500)
 159 #            define _cmsAssert(a)  { assert((a)); __analysis_assume((a)); }
 160 #     else
 161 #            define _cmsAssert(a)   assert((a))
 162 #     endif
 163 #else
 164 #      define _cmsAssert(a)   assert((a))
 165 #endif
 166 
 167 //---------------------------------------------------------------------------------
 168 
 169 // Determinant lower than that are assumed zero (used on matrix invert)
 170 #define MATRIX_DET_TOLERANCE    0.0001
 171 
 172 //---------------------------------------------------------------------------------
 173 
 174 // Fixed point
 175 #define FIXED_TO_INT(x)         ((x)>>16)
 176 #define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU)
 177 #define ROUND_FIXED_TO_INT(x)   (((x)+0x8000)>>16)
 178 
 179 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
 180 cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
 181 
 182 // -----------------------------------------------------------------------------------------------------------
 183 
 184 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
 185 // note than this only works in the range ..-32767...+32767 because
 186 // mantissa is interpreted as 15.16 fixed point.
 187 // The union is to avoid pointer aliasing overoptimization.
 188 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
 189 {
 190 #ifdef CMS_DONT_USE_FAST_FLOOR
 191     return (int) floor(val);
 192 #else
 193     const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
 194     union {
 195         cmsFloat64Number val;
 196         int halves[2];
 197     } temp;
 198 
 199     temp.val = val + _lcms_double2fixmagic;
 200 
 201 #ifdef CMS_USE_BIG_ENDIAN
 202     return temp.halves[1] >> 16;
 203 #else
 204     return temp.halves[0] >> 16;
 205 #endif
 206 #endif
 207 }
 208 
 209 // Fast floor restricted to 0..65535.0
 210 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
 211 {
 212     return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
 213 }
 214 
 215 // Floor to word, taking care of saturation
 216 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
 217 {
 218     d += 0.5;
 219     if (d <= 0) return 0;
 220     if (d >= 65535.0) return 0xffff;
 221 
 222     return _cmsQuickFloorWord(d);
 223 }
 224 
 225 // Test bed entry points---------------------------------------------------------------
 226 #define CMSCHECKPOINT CMSAPI
 227 
 228 // Pthread support --------------------------------------------------------------------
 229 #ifndef CMS_NO_PTHREADS
 230 
 231 // This is the threading support. Unfortunately, it has to be platform-dependent because
 232 // windows does not support pthreads.
 233 #ifdef CMS_IS_WINDOWS_
 234 
 235 #define WIN32_LEAN_AND_MEAN 1
 236 #include <windows.h>
 237 
 238 
 239 // The locking scheme in LCMS requires a single 'top level' mutex
 240 // to work. This is actually implemented on Windows as a
 241 // CriticalSection, because they are lighter weight. With
 242 // pthreads, this is statically inited. Unfortunately, windows
 243 // can't officially statically init critical sections.
 244 //
 245 // We can work around this in 2 ways.
 246 //
 247 // 1) We can use a proper mutex purely to protect the init
 248 // of the CriticalSection. This in turns requires us to protect
 249 // the Mutex creation, which we can do using the snappily
 250 // named InterlockedCompareExchangePointer API (present on
 251 // windows XP and above).
 252 //
 253 // 2) In cases where we want to work on pre-Windows XP, we
 254 // can use an even more horrible hack described below.
 255 //
 256 // So why wouldn't we always use 2)? Because not calling
 257 // the init function for a critical section means it fails
 258 // testing with ApplicationVerifier (and presumably similar
 259 // tools).
 260 //
 261 // We therefore default to 1, and people who want to be able
 262 // to run on pre-Windows XP boxes can build with:
 263 //     CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 264 // defined. This is automatically set for builds using
 265 // versions of MSVC that don't have this API available.
 266 //
 267 // From: http://locklessinc.com/articles/pthreads_on_windows/
 268 // The pthreads API has an initialization macro that has no correspondence to anything in
 269 // the windows API. By investigating the internal definition of the critical section type,
 270 // one may work out how to initialize one without calling InitializeCriticalSection().
 271 // The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
 272 // to allocate a critical section debug object, but if no memory is available, it sets
 273 // the pointer to a specific value. (One would expect that value to be NULL, but it is
 274 // actually (void *)-1 for some reason.) Thus we can use this special value for that
 275 // pointer, and the critical section code will work.
 276 
 277 // The other important part of the critical section type to initialize is the number
 278 // of waiters. This controls whether or not the mutex is locked. Fortunately, this
 279 // part of the critical section is unlikely to change. Apparently, many programs
 280 // already test critical sections to see if they are locked using this value, so
 281 // Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
 282 // section, even when they changed the underlying algorithm to be more scalable.
 283 // The final parts of the critical section object are unimportant, and can be set
 284 // to zero for their defaults. This yields to an initialization macro:
 285 
 286 typedef CRITICAL_SECTION _cmsMutex;
 287 
 288 #ifdef _MSC_VER
 289 #    if (_MSC_VER >= 1800)
 290 #          pragma warning(disable : 26135)
 291 #          pragma warning(disable : 4127)
 292 #    endif
 293 #endif
 294 
 295 #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 296 // If we are building with a version of MSVC smaller
 297 // than 1400 (i.e. before VS2005) then we don't have
 298 // the InterlockedCompareExchangePointer API, so use
 299 // the old version.
 300 #    ifdef _MSC_VER
 301 #       if _MSC_VER < 1400
 302 #          define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 303 #       endif
 304 #    endif
 305 #endif
 306 
 307 #ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 308 #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
 309 #else
 310 #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}
 311 #endif
 312 
 313 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 314 {
 315     EnterCriticalSection(m);
 316     return 0;
 317 }
 318 
 319 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 320 {
 321     LeaveCriticalSection(m);
 322     return 0;
 323 }
 324 
 325 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 326 {
 327     InitializeCriticalSection(m);
 328     return 0;
 329 }
 330 
 331 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 332 {
 333     DeleteCriticalSection(m);
 334     return 0;
 335 }
 336 
 337 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 338 {
 339     EnterCriticalSection(m);
 340     return 0;
 341 }
 342 
 343 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 344 {
 345     LeaveCriticalSection(m);
 346     return 0;
 347 }
 348 
 349 #else
 350 
 351 // Rest of the wide world
 352 #include <pthread.h>
 353 
 354 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 355 typedef pthread_mutex_t _cmsMutex;
 356 
 357 
 358 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 359 {
 360     return pthread_mutex_lock(m);
 361 }
 362 
 363 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 364 {
 365     return pthread_mutex_unlock(m);
 366 }
 367 
 368 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 369 {
 370     return pthread_mutex_init(m, NULL);
 371 }
 372 
 373 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 374 {
 375     return pthread_mutex_destroy(m);
 376 }
 377 
 378 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 379 {
 380     return pthread_mutex_lock(m);
 381 }
 382 
 383 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 384 {
 385     return pthread_mutex_unlock(m);
 386 }
 387 
 388 #endif
 389 #else
 390 
 391 #define CMS_MUTEX_INITIALIZER 0
 392 typedef int _cmsMutex;
 393 
 394 
 395 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 396 {
 397     cmsUNUSED_PARAMETER(m);
 398     return 0;
 399 }
 400 
 401 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 402 {
 403     cmsUNUSED_PARAMETER(m);
 404     return 0;
 405 }
 406 
 407 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 408 {
 409     cmsUNUSED_PARAMETER(m);
 410     return 0;
 411 }
 412 
 413 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 414 {
 415     cmsUNUSED_PARAMETER(m);
 416     return 0;
 417 }
 418 
 419 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 420 {
 421     cmsUNUSED_PARAMETER(m);
 422     return 0;
 423 }
 424 
 425 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 426 {
 427     cmsUNUSED_PARAMETER(m);
 428     return 0;
 429 }
 430 #endif
 431 
 432 // Plug-In registration ---------------------------------------------------------------
 433 
 434 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
 435 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
 436 
 437 // Memory management
 438 cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 439 
 440 // Interpolation
 441 cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 442 
 443 // Parametric curves
 444 cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 445 
 446 // Formatters management
 447 cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 448 
 449 // Tag type management
 450 cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 451 
 452 // Tag management
 453 cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 454 
 455 // Intent management
 456 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 457 
 458 // Multi Process elements
 459 cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 460 
 461 // Optimization
 462 cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 463 
 464 // Transform
 465 cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 466 
 467 // Mutex
 468 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 469 
 470 // Paralellization
 471 cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 472 
 473 // ---------------------------------------------------------------------------------------------------------
 474 
 475 // Suballocators.
 476 typedef struct _cmsSubAllocator_chunk_st {
 477 
 478     cmsUInt8Number* Block;
 479     cmsUInt32Number BlockSize;
 480     cmsUInt32Number Used;
 481 
 482     struct _cmsSubAllocator_chunk_st* next;
 483 
 484 } _cmsSubAllocator_chunk;
 485 
 486 
 487 typedef struct {
 488 
 489     cmsContext ContextID;
 490     _cmsSubAllocator_chunk* h;
 491 
 492 } _cmsSubAllocator;
 493 
 494 
 495 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
 496 void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
 497 void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
 498 void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
 499 
 500 // ----------------------------------------------------------------------------------
 501 
 502 // The context clients.
 503 typedef enum {
 504 
 505     UserPtr,            // User-defined pointer
 506     Logger,
 507     AlarmCodesContext,
 508     AdaptationStateContext,
 509     MemPlugin,
 510     InterpPlugin,
 511     CurvesPlugin,
 512     FormattersPlugin,
 513     TagTypePlugin,
 514     TagPlugin,
 515     IntentPlugin,
 516     MPEPlugin,
 517     OptimizationPlugin,
 518     TransformPlugin,
 519     MutexPlugin,
 520     ParallelizationPlugin,
 521 
 522     // Last in list
 523     MemoryClientMax
 524 
 525 } _cmsMemoryClient;
 526 
 527 
 528 // Container for memory management plug-in.
 529 typedef struct {
 530 
 531     _cmsMallocFnPtrType     MallocPtr;
 532     _cmsMalloZerocFnPtrType MallocZeroPtr;
 533     _cmsFreeFnPtrType       FreePtr;
 534     _cmsReallocFnPtrType    ReallocPtr;
 535     _cmsCallocFnPtrType     CallocPtr;
 536     _cmsDupFnPtrType        DupPtr;
 537 
 538 } _cmsMemPluginChunkType;
 539 
 540 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
 541 void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
 542 
 543 // Internal structure for context
 544 struct _cmsContext_struct {
 545 
 546     struct _cmsContext_struct* Next;  // Points to next context in the new style
 547     _cmsSubAllocator* MemPool;        // The memory pool that stores context data
 548 
 549     void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is held in the suballocator.
 550                                       // If NULL, then it reverts to global Context0
 551 
 552     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
 553 };
 554 
 555 // Returns a pointer to a valid context structure, including the global one if id is zero.
 556 // Verifies the magic number.
 557 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
 558 
 559 // Returns the block assigned to the specific zone.
 560 void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
 561 
 562 
 563 // Chunks of context memory by plug-in client -------------------------------------------------------
 564 
 565 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
 566 
 567 // Container for error logger -- not a plug-in
 568 typedef struct {
 569 
 570     cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
 571 
 572 } _cmsLogErrorChunkType;
 573 
 574 // The global Context0 storage for error logger
 575 extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
 576 
 577 // Allocate and init error logger container.
 578 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
 579                             const struct _cmsContext_struct* src);
 580 
 581 // Container for alarm codes -- not a plug-in
 582 typedef struct {
 583 
 584     cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
 585 
 586 } _cmsAlarmCodesChunkType;
 587 
 588 // The global Context0 storage for alarm codes
 589 extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
 590 
 591 // Allocate and init alarm codes container.
 592 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
 593                             const struct _cmsContext_struct* src);
 594 
 595 // Container for adaptation state -- not a plug-in
 596 typedef struct {
 597 
 598     cmsFloat64Number  AdaptationState;
 599 
 600 } _cmsAdaptationStateChunkType;
 601 
 602 // The global Context0 storage for adaptation state
 603 extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
 604 
 605 // Allocate and init adaptation state container.
 606 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
 607                                    const struct _cmsContext_struct* src);
 608 
 609 
 610 // The global Context0 storage for memory management
 611 extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
 612 
 613 // Allocate and init memory management container.
 614 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
 615                              const struct _cmsContext_struct* src);
 616 
 617 // Container for interpolation plug-in
 618 typedef struct {
 619 
 620     cmsInterpFnFactory Interpolators;
 621 
 622 } _cmsInterpPluginChunkType;
 623 
 624 // The global Context0 storage for interpolation plug-in
 625 extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
 626 
 627 // Allocate and init interpolation container.
 628 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
 629                                 const struct _cmsContext_struct* src);
 630 
 631 // Container for parametric curves plug-in
 632 typedef struct {
 633 
 634     struct _cmsParametricCurvesCollection_st* ParametricCurves;
 635 
 636 } _cmsCurvesPluginChunkType;
 637 
 638 // The global Context0 storage for tone curves plug-in
 639 extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
 640 
 641 // Allocate and init parametric curves container.
 642 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
 643                                                       const struct _cmsContext_struct* src);
 644 
 645 // Container for formatters plug-in
 646 typedef struct {
 647 
 648     struct _cms_formatters_factory_list* FactoryList;
 649 
 650 } _cmsFormattersPluginChunkType;
 651 
 652 // The global Context0 storage for formatters plug-in
 653 extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
 654 
 655 // Allocate and init formatters container.
 656 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
 657                                                        const struct _cmsContext_struct* src);
 658 
 659 // This chunk type is shared by TagType plug-in and MPE Plug-in
 660 typedef struct {
 661 
 662     struct _cmsTagTypeLinkedList_st* TagTypes;
 663 
 664 } _cmsTagTypePluginChunkType;
 665 
 666 
 667 // The global Context0 storage for tag types plug-in
 668 extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
 669 
 670 
 671 // The global Context0 storage for mult process elements plug-in
 672 extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
 673 
 674 // Allocate and init Tag types container.
 675 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
 676                                                         const struct _cmsContext_struct* src);
 677 // Allocate and init MPE container.
 678 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
 679                                                         const struct _cmsContext_struct* src);
 680 // Container for tag plug-in
 681 typedef struct {
 682 
 683     struct _cmsTagLinkedList_st* Tag;
 684 
 685 } _cmsTagPluginChunkType;
 686 
 687 
 688 // The global Context0 storage for tag plug-in
 689 extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
 690 
 691 // Allocate and init Tag container.
 692 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
 693                                                       const struct _cmsContext_struct* src);
 694 
 695 // Container for intents plug-in
 696 typedef struct {
 697 
 698     struct _cms_intents_list* Intents;
 699 
 700 } _cmsIntentsPluginChunkType;
 701 
 702 
 703 // The global Context0 storage for intents plug-in
 704 extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
 705 
 706 // Allocate and init intents container.
 707 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
 708                                                         const struct _cmsContext_struct* src);
 709 
 710 // Container for optimization plug-in
 711 typedef struct {
 712 
 713     struct _cmsOptimizationCollection_st* OptimizationCollection;
 714 
 715 } _cmsOptimizationPluginChunkType;
 716 
 717 
 718 // The global Context0 storage for optimizers plug-in
 719 extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
 720 
 721 // Allocate and init optimizers container.
 722 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
 723                                          const struct _cmsContext_struct* src);
 724 
 725 // Container for transform plug-in
 726 typedef struct {
 727 
 728     struct _cmsTransformCollection_st* TransformCollection;
 729 
 730 } _cmsTransformPluginChunkType;
 731 
 732 // The global Context0 storage for full-transform replacement plug-in
 733 extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
 734 
 735 // Allocate and init transform container.
 736 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
 737                                         const struct _cmsContext_struct* src);
 738 
 739 // Container for mutex plug-in
 740 typedef struct {
 741 
 742     _cmsCreateMutexFnPtrType  CreateMutexPtr;
 743     _cmsDestroyMutexFnPtrType DestroyMutexPtr;
 744     _cmsLockMutexFnPtrType    LockMutexPtr;
 745     _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
 746 
 747 } _cmsMutexPluginChunkType;
 748 
 749 // The global Context0 storage for mutex plug-in
 750 extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
 751 
 752 // Allocate and init mutex container.
 753 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
 754                                         const struct _cmsContext_struct* src);
 755 
 756 // Container for parallelization plug-in
 757 typedef struct {
 758 
 759     cmsInt32Number      MaxWorkers;       // Number of workers to do as maximum
 760     cmsInt32Number      WorkerFlags;      // reserved
 761     _cmsTransform2Fn    SchedulerFn;      // callback to setup functions
 762 
 763 } _cmsParallelizationPluginChunkType;
 764 
 765 // The global Context0 storage for parallelization plug-in
 766 extern  _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk;
 767 
 768 // Allocate parallelization container.
 769 void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx,
 770                                          const struct _cmsContext_struct* src);
 771 
 772 
 773 
 774 // ----------------------------------------------------------------------------------
 775 // MLU internal representation
 776 typedef struct {
 777 
 778     cmsUInt16Number Language;
 779     cmsUInt16Number Country;
 780 
 781     cmsUInt32Number StrW;       // Offset to current unicode string
 782     cmsUInt32Number Len;        // Length in bytes
 783 
 784 } _cmsMLUentry;
 785 
 786 struct _cms_MLU_struct {
 787 
 788     cmsContext ContextID;
 789 
 790     // The directory
 791     cmsUInt32Number  AllocatedEntries;
 792     cmsUInt32Number  UsedEntries;
 793     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
 794 
 795     // The Pool
 796     cmsUInt32Number PoolSize;  // The maximum allocated size
 797     cmsUInt32Number PoolUsed;  // The used size
 798     void*  MemPool;            // Pointer to begin of memory pool
 799 };
 800 
 801 // Named color list internal representation
 802 typedef struct {
 803 
 804     char Name[cmsMAX_PATH];
 805     cmsUInt16Number PCS[3];
 806     cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
 807 
 808 } _cmsNAMEDCOLOR;
 809 
 810 struct _cms_NAMEDCOLORLIST_struct {
 811 
 812     cmsUInt32Number nColors;
 813     cmsUInt32Number Allocated;
 814     cmsUInt32Number ColorantCount;
 815 
 816     char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
 817     char Suffix[33];
 818 
 819     _cmsNAMEDCOLOR* List;
 820 
 821     cmsContext ContextID;
 822 };
 823 
 824 
 825 // ----------------------------------------------------------------------------------
 826 
 827 // This is the internal struct holding profile details.
 828 
 829 // Maximum supported tags in a profile
 830 #define MAX_TABLE_TAG       100
 831 
 832 typedef struct _cms_iccprofile_struct {
 833 
 834     // I/O handler
 835     cmsIOHANDLER*            IOhandler;
 836 
 837     // The thread ID
 838     cmsContext               ContextID;
 839 
 840     // Creation time
 841     struct tm                Created;
 842 
 843     // Color management module identification
 844     cmsUInt32Number          CMM;
 845 
 846     // Only most important items found in ICC profiles
 847     cmsUInt32Number          Version;
 848     cmsProfileClassSignature DeviceClass;
 849     cmsColorSpaceSignature   ColorSpace;
 850     cmsColorSpaceSignature   PCS;
 851     cmsUInt32Number          RenderingIntent;
 852 
 853     cmsPlatformSignature     platform;
 854     cmsUInt32Number          flags;
 855     cmsUInt32Number          manufacturer, model;
 856     cmsUInt64Number          attributes;
 857     cmsUInt32Number          creator;
 858 
 859     cmsProfileID             ProfileID;
 860 
 861     // Dictionary
 862     cmsUInt32Number          TagCount;
 863     cmsTagSignature          TagNames[MAX_TABLE_TAG];
 864     cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
 865     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
 866     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
 867     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
 868     void *                   TagPtrs[MAX_TABLE_TAG];
 869     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
 870                                                                  // depending on profile version, so we keep track of the
 871                                                                  // type handler for each tag in the list.
 872     // Special
 873     cmsBool                  IsWrite;
 874 
 875     // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
 876     void *                   UsrMutex;
 877 
 878 } _cmsICCPROFILE;
 879 
 880 // IO helpers for profiles
 881 cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc);
 882 cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
 883 int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
 884 
 885 // Tag types
 886 cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
 887 cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
 888 cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
 889 
 890 // Error logging ---------------------------------------------------------------------------------------------------------
 891 
 892 void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
 893 
 894 // Interpolation ---------------------------------------------------------------------------------------------------------
 895 
 896 CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
 897 cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
 898 CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
 899 cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
 900 
 901 // Curves ----------------------------------------------------------------------------------------------------------------
 902 
 903 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
 904 // In the case of table-based, Eval pointer is set to NULL
 905 
 906 // The gamma function main structure
 907 struct _cms_curve_struct {
 908 
 909     cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
 910 
 911     cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
 912     cmsCurveSegment*  Segments;      // The segments
 913     cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
 914 
 915     cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
 916 
 917     // 16 bit Table-based representation follows
 918     cmsUInt32Number    nEntries;      // Number of table elements
 919     cmsUInt16Number*   Table16;       // The table itself.
 920 };
 921 
 922 
 923 //  Pipelines & Stages ---------------------------------------------------------------------------------------------
 924 
 925 // A single stage
 926 struct _cmsStage_struct {
 927 
 928     cmsContext          ContextID;
 929 
 930     cmsStageSignature   Type;           // Identifies the stage
 931     cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
 932 
 933     cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
 934     cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
 935 
 936     _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
 937     _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
 938     _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
 939 
 940     // A generic pointer to whatever memory needed by the stage
 941     void*               Data;
 942 
 943     // Maintains linked list (used internally)
 944     struct _cmsStage_struct* Next;
 945 };
 946 
 947 
 948 // Special Stages (cannot be saved)
 949 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
 950 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
 951 cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID);
 952 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
 953 cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
 954 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
 955 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
 956 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
 957 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
 958 cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
 959 cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
 960 cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID);
 961 cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
 962 cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
 963 
 964 
 965 // For curve set only
 966 cmsToneCurve**  _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
 967 
 968 struct _cmsPipeline_struct {
 969 
 970     cmsStage* Elements;                                // Points to elements chain
 971     cmsUInt32Number InputChannels, OutputChannels;
 972 
 973     // Data & evaluators
 974     void *Data;
 975 
 976    _cmsPipelineEval16Fn    Eval16Fn;
 977    _cmsPipelineEvalFloatFn EvalFloatFn;
 978    _cmsFreeUserDataFn      FreeDataFn;
 979    _cmsDupUserDataFn       DupDataFn;
 980 
 981     cmsContext ContextID;            // Environment
 982 
 983     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
 984 };
 985 
 986 // LUT reading & creation -------------------------------------------------------------------------------------------
 987 
 988 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
 989 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
 990 
 991 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 992 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 993 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 994 
 995 // Special values
 996 cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
 997 cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
 998 
 999 // Profile linker --------------------------------------------------------------------------------------------------
1000 
1001 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
1002 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
1003 // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
1004 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
1005                               cmsUInt32Number    nProfiles,
1006                               cmsUInt32Number    TheIntents[],
1007                               cmsHPROFILE        hProfiles[],
1008                               cmsBool            BPC[],
1009                               cmsFloat64Number   AdaptationStates[],
1010                               cmsUInt32Number    dwFlags);
1011 
1012 // Sequence --------------------------------------------------------------------------------------------------------
1013 
1014 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
1015 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
1016 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
1017 
1018 
1019 // LUT optimization ------------------------------------------------------------------------------------------------
1020 
1021 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
1022 
1023 CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
1024 
1025 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
1026                                       cmsUInt16Number **White,
1027                                       cmsUInt16Number **Black,
1028                                       cmsUInt32Number *nOutputs);
1029 
1030 CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
1031                                       cmsPipeline**    Lut,
1032                                       cmsUInt32Number  Intent,
1033                                       cmsUInt32Number* InputFormat,
1034                                       cmsUInt32Number* OutputFormat,
1035                                       cmsUInt32Number* dwFlags );
1036 
1037 
1038 // Hi level LUT building ----------------------------------------------------------------------------------------------
1039 
1040 cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
1041                                               cmsHPROFILE hProfiles[],
1042                                               cmsBool  BPC[],
1043                                               cmsUInt32Number Intents[],
1044                                               cmsFloat64Number AdaptationStates[],
1045                                               cmsUInt32Number nGamutPCSposition,
1046                                               cmsHPROFILE hGamut);
1047 
1048 
1049 // Formatters ------------------------------------------------------------------------------------------------------------
1050 
1051 #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
1052 
1053 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
1054 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
1055 
1056 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
1057                                                       cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
1058                                                       cmsFormatterDirection Dir,
1059                                                       cmsUInt32Number dwFlags);
1060 
1061 
1062 #ifndef CMS_NO_HALF_SUPPORT
1063 
1064 // Half float
1065 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1066 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1067 
1068 #endif
1069 
1070 // Transform logic ------------------------------------------------------------------------------------------------------
1071 
1072 struct _cmstransform_struct;
1073 
1074 typedef struct {
1075 
1076     // 1-pixel cache (16 bits only)
1077     cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1078     cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1079 
1080 } _cmsCACHE;
1081 
1082 
1083 
1084 // Transformation
1085 typedef struct _cmstransform_struct {
1086 
1087     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1088 
1089     // Points to transform code
1090     _cmsTransform2Fn xform;
1091 
1092     // Formatters, cannot be embedded into LUT because cache
1093     cmsFormatter16 FromInput;
1094     cmsFormatter16 ToOutput;
1095 
1096     cmsFormatterFloat FromInputFloat;
1097     cmsFormatterFloat ToOutputFloat;
1098 
1099     // 1-pixel cache seed for zero as input (16 bits, read only)
1100     _cmsCACHE Cache;
1101 
1102     // A Pipeline holding the full (optimized) transform
1103     cmsPipeline* Lut;
1104 
1105     // A Pipeline holding the gamut check. It goes from the input space to bilevel
1106     cmsPipeline* GamutCheck;
1107 
1108     // Colorant tables
1109     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1110     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1111 
1112     // Informational only
1113     cmsColorSpaceSignature EntryColorSpace;
1114     cmsColorSpaceSignature ExitColorSpace;
1115 
1116     // White points (informative only)
1117     cmsCIEXYZ EntryWhitePoint;
1118     cmsCIEXYZ ExitWhitePoint;
1119 
1120     // Profiles used to create the transform
1121     cmsSEQ* Sequence;
1122 
1123     cmsUInt32Number  dwOriginalFlags;
1124     cmsFloat64Number AdaptationState;
1125 
1126     // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1127     cmsUInt32Number RenderingIntent;
1128 
1129     // An id that uniquely identifies the running context. May be null.
1130     cmsContext ContextID;
1131 
1132     // A user-defined pointer that can be used to store data for transform plug-ins
1133     void* UserData;
1134     _cmsFreeUserDataFn FreeUserData;
1135 
1136     // A way to provide backwards compatibility with full xform plugins
1137     _cmsTransformFn OldXform;
1138 
1139     // A one-worker transform entry for parallelization
1140     _cmsTransform2Fn Worker;
1141     cmsInt32Number   MaxWorkers;
1142     cmsUInt32Number  WorkerFlags;
1143 
1144 } _cmsTRANSFORM;
1145 
1146 // Copies extra channels from input to output if the original flags in the transform structure
1147 // instructs to do so. This function is called on all standard transform functions.
1148 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1149                              void* out,
1150                              cmsUInt32Number PixelsPerLine,
1151                              cmsUInt32Number LineCount,
1152                              const cmsStride* Stride);
1153 
1154 // -----------------------------------------------------------------------------------------------------------------------
1155 
1156 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1157                             cmsUInt32Number        nProfiles,
1158                             cmsUInt32Number        InputFormat,
1159                             cmsUInt32Number        OutputFormat,
1160                             const cmsUInt32Number  Intents[],
1161                             const cmsHPROFILE      hProfiles[],
1162                             const cmsBool          BPC[],
1163                             const cmsFloat64Number AdaptationStates[],
1164                             cmsUInt32Number        dwFlags);
1165 
1166 
1167 cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1168                             cmsUInt32Number        nPoints,
1169                             cmsUInt32Number        nProfiles,
1170                             const cmsUInt32Number  Intents[],
1171                             const cmsHPROFILE      hProfiles[],
1172                             const cmsBool          BPC[],
1173                             const cmsFloat64Number AdaptationStates[],
1174                             cmsUInt32Number        dwFlags);
1175 
1176 cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1177 
1178 cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1179 
1180 
1181 // thread-safe gettime
1182 cmsBool _cmsGetTime(struct tm* ptr_time);
1183 
1184 #define _lcms_internal_H
1185 #endif