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 #    endif
 292 #endif
 293 
 294 #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 295 // If we are building with a version of MSVC smaller
 296 // than 1400 (i.e. before VS2005) then we don't have
 297 // the InterlockedCompareExchangePointer API, so use
 298 // the old version.
 299 #    ifdef _MSC_VER
 300 #       if _MSC_VER < 1400
 301 #          define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 302 #       endif
 303 #    endif
 304 #endif
 305 
 306 #ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 307 #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
 308 #else
 309 #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}
 310 #endif
 311 
 312 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 313 {
 314     EnterCriticalSection(m);
 315     return 0;
 316 }
 317 
 318 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 319 {
 320     LeaveCriticalSection(m);
 321     return 0;
 322 }
 323 
 324 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 325 {
 326     InitializeCriticalSection(m);
 327     return 0;
 328 }
 329 
 330 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 331 {
 332     DeleteCriticalSection(m);
 333     return 0;
 334 }
 335 
 336 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 337 {
 338     EnterCriticalSection(m);
 339     return 0;
 340 }
 341 
 342 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 343 {
 344     LeaveCriticalSection(m);
 345     return 0;
 346 }
 347 
 348 #else
 349 
 350 // Rest of the wide world
 351 #include <pthread.h>
 352 
 353 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 354 typedef pthread_mutex_t _cmsMutex;
 355 
 356 
 357 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 358 {
 359     return pthread_mutex_lock(m);
 360 }
 361 
 362 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 363 {
 364     return pthread_mutex_unlock(m);
 365 }
 366 
 367 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 368 {
 369     return pthread_mutex_init(m, NULL);
 370 }
 371 
 372 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 373 {
 374     return pthread_mutex_destroy(m);
 375 }
 376 
 377 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 378 {
 379     return pthread_mutex_lock(m);
 380 }
 381 
 382 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 383 {
 384     return pthread_mutex_unlock(m);
 385 }
 386 
 387 #endif
 388 #else
 389 
 390 #define CMS_MUTEX_INITIALIZER 0
 391 typedef int _cmsMutex;
 392 
 393 
 394 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
 395 {
 396     cmsUNUSED_PARAMETER(m);
 397     return 0;
 398 }
 399 
 400 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
 401 {
 402     cmsUNUSED_PARAMETER(m);
 403     return 0;
 404 }
 405 
 406 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
 407 {
 408     cmsUNUSED_PARAMETER(m);
 409     return 0;
 410 }
 411 
 412 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
 413 {
 414     cmsUNUSED_PARAMETER(m);
 415     return 0;
 416 }
 417 
 418 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
 419 {
 420     cmsUNUSED_PARAMETER(m);
 421     return 0;
 422 }
 423 
 424 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
 425 {
 426     cmsUNUSED_PARAMETER(m);
 427     return 0;
 428 }
 429 #endif
 430 
 431 // Plug-In registration ---------------------------------------------------------------
 432 
 433 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
 434 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
 435 
 436 // Memory management
 437 cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 438 
 439 // Interpolation
 440 cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 441 
 442 // Parametric curves
 443 cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 444 
 445 // Formatters management
 446 cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 447 
 448 // Tag type management
 449 cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 450 
 451 // Tag management
 452 cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 453 
 454 // Intent management
 455 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 456 
 457 // Multi Process elements
 458 cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 459 
 460 // Optimization
 461 cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 462 
 463 // Transform
 464 cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 465 
 466 // Mutex
 467 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 468 
 469 // Paralellization
 470 cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 471 
 472 // ---------------------------------------------------------------------------------------------------------
 473 
 474 // Suballocators.
 475 typedef struct _cmsSubAllocator_chunk_st {
 476 
 477     cmsUInt8Number* Block;
 478     cmsUInt32Number BlockSize;
 479     cmsUInt32Number Used;
 480 
 481     struct _cmsSubAllocator_chunk_st* next;
 482 
 483 } _cmsSubAllocator_chunk;
 484 
 485 
 486 typedef struct {
 487 
 488     cmsContext ContextID;
 489     _cmsSubAllocator_chunk* h;
 490 
 491 } _cmsSubAllocator;
 492 
 493 
 494 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
 495 void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
 496 void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
 497 void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
 498 
 499 // ----------------------------------------------------------------------------------
 500 
 501 // The context clients.
 502 typedef enum {
 503 
 504     UserPtr,            // User-defined pointer
 505     Logger,
 506     AlarmCodesContext,
 507     AdaptationStateContext,
 508     MemPlugin,
 509     InterpPlugin,
 510     CurvesPlugin,
 511     FormattersPlugin,
 512     TagTypePlugin,
 513     TagPlugin,
 514     IntentPlugin,
 515     MPEPlugin,
 516     OptimizationPlugin,
 517     TransformPlugin,
 518     MutexPlugin,
 519     ParallelizationPlugin,
 520 
 521     // Last in list
 522     MemoryClientMax
 523 
 524 } _cmsMemoryClient;
 525 
 526 
 527 // Container for memory management plug-in.
 528 typedef struct {
 529 
 530     _cmsMallocFnPtrType     MallocPtr;
 531     _cmsMalloZerocFnPtrType MallocZeroPtr;
 532     _cmsFreeFnPtrType       FreePtr;
 533     _cmsReallocFnPtrType    ReallocPtr;
 534     _cmsCallocFnPtrType     CallocPtr;
 535     _cmsDupFnPtrType        DupPtr;
 536 
 537 } _cmsMemPluginChunkType;
 538 
 539 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
 540 void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
 541 
 542 // Internal structure for context
 543 struct _cmsContext_struct {
 544 
 545     struct _cmsContext_struct* Next;  // Points to next context in the new style
 546     _cmsSubAllocator* MemPool;        // The memory pool that stores context data
 547 
 548     void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
 549                                       // If NULL, then it reverts to global Context0
 550 
 551     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
 552 };
 553 
 554 // Returns a pointer to a valid context structure, including the global one if id is zero.
 555 // Verifies the magic number.
 556 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
 557 
 558 // Returns the block assigned to the specific zone.
 559 void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
 560 
 561 
 562 // Chunks of context memory by plug-in client -------------------------------------------------------
 563 
 564 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
 565 
 566 // Container for error logger -- not a plug-in
 567 typedef struct {
 568 
 569     cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
 570 
 571 } _cmsLogErrorChunkType;
 572 
 573 // The global Context0 storage for error logger
 574 extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
 575 
 576 // Allocate and init error logger container.
 577 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
 578                             const struct _cmsContext_struct* src);
 579 
 580 // Container for alarm codes -- not a plug-in
 581 typedef struct {
 582 
 583     cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
 584 
 585 } _cmsAlarmCodesChunkType;
 586 
 587 // The global Context0 storage for alarm codes
 588 extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
 589 
 590 // Allocate and init alarm codes container.
 591 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
 592                             const struct _cmsContext_struct* src);
 593 
 594 // Container for adaptation state -- not a plug-in
 595 typedef struct {
 596 
 597     cmsFloat64Number  AdaptationState;
 598 
 599 } _cmsAdaptationStateChunkType;
 600 
 601 // The global Context0 storage for adaptation state
 602 extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
 603 
 604 // Allocate and init adaptation state container.
 605 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
 606                                    const struct _cmsContext_struct* src);
 607 
 608 
 609 // The global Context0 storage for memory management
 610 extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
 611 
 612 // Allocate and init memory management container.
 613 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
 614                              const struct _cmsContext_struct* src);
 615 
 616 // Container for interpolation plug-in
 617 typedef struct {
 618 
 619     cmsInterpFnFactory Interpolators;
 620 
 621 } _cmsInterpPluginChunkType;
 622 
 623 // The global Context0 storage for interpolation plug-in
 624 extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
 625 
 626 // Allocate and init interpolation container.
 627 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
 628                                 const struct _cmsContext_struct* src);
 629 
 630 // Container for parametric curves plug-in
 631 typedef struct {
 632 
 633     struct _cmsParametricCurvesCollection_st* ParametricCurves;
 634 
 635 } _cmsCurvesPluginChunkType;
 636 
 637 // The global Context0 storage for tone curves plug-in
 638 extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
 639 
 640 // Allocate and init parametric curves container.
 641 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
 642                                                       const struct _cmsContext_struct* src);
 643 
 644 // Container for formatters plug-in
 645 typedef struct {
 646 
 647     struct _cms_formatters_factory_list* FactoryList;
 648 
 649 } _cmsFormattersPluginChunkType;
 650 
 651 // The global Context0 storage for formatters plug-in
 652 extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
 653 
 654 // Allocate and init formatters container.
 655 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
 656                                                        const struct _cmsContext_struct* src);
 657 
 658 // This chunk type is shared by TagType plug-in and MPE Plug-in
 659 typedef struct {
 660 
 661     struct _cmsTagTypeLinkedList_st* TagTypes;
 662 
 663 } _cmsTagTypePluginChunkType;
 664 
 665 
 666 // The global Context0 storage for tag types plug-in
 667 extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
 668 
 669 
 670 // The global Context0 storage for mult process elements plug-in
 671 extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
 672 
 673 // Allocate and init Tag types container.
 674 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
 675                                                         const struct _cmsContext_struct* src);
 676 // Allocate and init MPE container.
 677 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
 678                                                         const struct _cmsContext_struct* src);
 679 // Container for tag plug-in
 680 typedef struct {
 681 
 682     struct _cmsTagLinkedList_st* Tag;
 683 
 684 } _cmsTagPluginChunkType;
 685 
 686 
 687 // The global Context0 storage for tag plug-in
 688 extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
 689 
 690 // Allocate and init Tag container.
 691 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
 692                                                       const struct _cmsContext_struct* src);
 693 
 694 // Container for intents plug-in
 695 typedef struct {
 696 
 697     struct _cms_intents_list* Intents;
 698 
 699 } _cmsIntentsPluginChunkType;
 700 
 701 
 702 // The global Context0 storage for intents plug-in
 703 extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
 704 
 705 // Allocate and init intents container.
 706 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
 707                                                         const struct _cmsContext_struct* src);
 708 
 709 // Container for optimization plug-in
 710 typedef struct {
 711 
 712     struct _cmsOptimizationCollection_st* OptimizationCollection;
 713 
 714 } _cmsOptimizationPluginChunkType;
 715 
 716 
 717 // The global Context0 storage for optimizers plug-in
 718 extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
 719 
 720 // Allocate and init optimizers container.
 721 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
 722                                          const struct _cmsContext_struct* src);
 723 
 724 // Container for transform plug-in
 725 typedef struct {
 726 
 727     struct _cmsTransformCollection_st* TransformCollection;
 728 
 729 } _cmsTransformPluginChunkType;
 730 
 731 // The global Context0 storage for full-transform replacement plug-in
 732 extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
 733 
 734 // Allocate and init transform container.
 735 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
 736                                         const struct _cmsContext_struct* src);
 737 
 738 // Container for mutex plug-in
 739 typedef struct {
 740 
 741     _cmsCreateMutexFnPtrType  CreateMutexPtr;
 742     _cmsDestroyMutexFnPtrType DestroyMutexPtr;
 743     _cmsLockMutexFnPtrType    LockMutexPtr;
 744     _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
 745 
 746 } _cmsMutexPluginChunkType;
 747 
 748 // The global Context0 storage for mutex plug-in
 749 extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
 750 
 751 // Allocate and init mutex container.
 752 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
 753                                         const struct _cmsContext_struct* src);
 754 
 755 // Container for parallelization plug-in
 756 typedef struct {
 757 
 758     cmsInt32Number      MaxWorkers;       // Number of workers to do as maximum
 759     cmsInt32Number      WorkerFlags;      // reserved
 760     _cmsTransform2Fn    SchedulerFn;      // callback to setup functions
 761 
 762 } _cmsParallelizationPluginChunkType;
 763 
 764 // The global Context0 storage for parallelization plug-in
 765 extern  _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk;
 766 
 767 // Allocate parallelization container.
 768 void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx,
 769                                          const struct _cmsContext_struct* src);
 770 
 771 
 772 
 773 // ----------------------------------------------------------------------------------
 774 // MLU internal representation
 775 typedef struct {
 776 
 777     cmsUInt16Number Language;
 778     cmsUInt16Number Country;
 779 
 780     cmsUInt32Number StrW;       // Offset to current unicode string
 781     cmsUInt32Number Len;        // Length in bytes
 782 
 783 } _cmsMLUentry;
 784 
 785 struct _cms_MLU_struct {
 786 
 787     cmsContext ContextID;
 788 
 789     // The directory
 790     cmsUInt32Number  AllocatedEntries;
 791     cmsUInt32Number  UsedEntries;
 792     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
 793 
 794     // The Pool
 795     cmsUInt32Number PoolSize;  // The maximum allocated size
 796     cmsUInt32Number PoolUsed;  // The used size
 797     void*  MemPool;            // Pointer to begin of memory pool
 798 };
 799 
 800 // Named color list internal representation
 801 typedef struct {
 802 
 803     char Name[cmsMAX_PATH];
 804     cmsUInt16Number PCS[3];
 805     cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
 806 
 807 } _cmsNAMEDCOLOR;
 808 
 809 struct _cms_NAMEDCOLORLIST_struct {
 810 
 811     cmsUInt32Number nColors;
 812     cmsUInt32Number Allocated;
 813     cmsUInt32Number ColorantCount;
 814 
 815     char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
 816     char Suffix[33];
 817 
 818     _cmsNAMEDCOLOR* List;
 819 
 820     cmsContext ContextID;
 821 };
 822 
 823 
 824 // ----------------------------------------------------------------------------------
 825 
 826 // This is the internal struct holding profile details.
 827 
 828 // Maximum supported tags in a profile
 829 #define MAX_TABLE_TAG       100
 830 
 831 typedef struct _cms_iccprofile_struct {
 832 
 833     // I/O handler
 834     cmsIOHANDLER*            IOhandler;
 835 
 836     // The thread ID
 837     cmsContext               ContextID;
 838 
 839     // Creation time
 840     struct tm                Created;
 841 
 842     // Only most important items found in ICC profiles
 843     cmsUInt32Number          Version;
 844     cmsProfileClassSignature DeviceClass;
 845     cmsColorSpaceSignature   ColorSpace;
 846     cmsColorSpaceSignature   PCS;
 847     cmsUInt32Number          RenderingIntent;
 848 
 849     cmsUInt32Number          flags;
 850     cmsUInt32Number          manufacturer, model;
 851     cmsUInt64Number          attributes;
 852     cmsUInt32Number          creator;
 853 
 854     cmsProfileID             ProfileID;
 855 
 856     // Dictionary
 857     cmsUInt32Number          TagCount;
 858     cmsTagSignature          TagNames[MAX_TABLE_TAG];
 859     cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
 860     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
 861     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
 862     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
 863     void *                   TagPtrs[MAX_TABLE_TAG];
 864     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
 865                                                                  // depending on profile version, so we keep track of the
 866                                                                  // type handler for each tag in the list.
 867     // Special
 868     cmsBool                  IsWrite;
 869 
 870     // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
 871     void *                   UsrMutex;
 872 
 873 } _cmsICCPROFILE;
 874 
 875 // IO helpers for profiles
 876 cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc);
 877 cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
 878 int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
 879 
 880 // Tag types
 881 cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
 882 cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
 883 cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
 884 
 885 // Error logging ---------------------------------------------------------------------------------------------------------
 886 
 887 void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
 888 
 889 // Interpolation ---------------------------------------------------------------------------------------------------------
 890 
 891 CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
 892 cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
 893 CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
 894 cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
 895 
 896 // Curves ----------------------------------------------------------------------------------------------------------------
 897 
 898 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
 899 // In the case of table-based, Eval pointer is set to NULL
 900 
 901 // The gamma function main structure
 902 struct _cms_curve_struct {
 903 
 904     cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
 905 
 906     cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
 907     cmsCurveSegment*  Segments;      // The segments
 908     cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
 909 
 910     cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
 911 
 912     // 16 bit Table-based representation follows
 913     cmsUInt32Number    nEntries;      // Number of table elements
 914     cmsUInt16Number*   Table16;       // The table itself.
 915 };
 916 
 917 
 918 //  Pipelines & Stages ---------------------------------------------------------------------------------------------
 919 
 920 // A single stage
 921 struct _cmsStage_struct {
 922 
 923     cmsContext          ContextID;
 924 
 925     cmsStageSignature   Type;           // Identifies the stage
 926     cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
 927 
 928     cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
 929     cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
 930 
 931     _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
 932     _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
 933     _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
 934 
 935     // A generic pointer to whatever memory needed by the stage
 936     void*               Data;
 937 
 938     // Maintains linked list (used internally)
 939     struct _cmsStage_struct* Next;
 940 };
 941 
 942 
 943 // Special Stages (cannot be saved)
 944 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
 945 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
 946 cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID);
 947 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
 948 cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
 949 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
 950 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
 951 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
 952 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
 953 cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
 954 cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
 955 cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID);
 956 cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
 957 cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
 958 
 959 
 960 // For curve set only
 961 cmsToneCurve**  _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
 962 
 963 struct _cmsPipeline_struct {
 964 
 965     cmsStage* Elements;                                // Points to elements chain
 966     cmsUInt32Number InputChannels, OutputChannels;
 967 
 968     // Data & evaluators
 969     void *Data;
 970 
 971    _cmsPipelineEval16Fn    Eval16Fn;
 972    _cmsPipelineEvalFloatFn EvalFloatFn;
 973    _cmsFreeUserDataFn      FreeDataFn;
 974    _cmsDupUserDataFn       DupDataFn;
 975 
 976     cmsContext ContextID;            // Environment
 977 
 978     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
 979 };
 980 
 981 // LUT reading & creation -------------------------------------------------------------------------------------------
 982 
 983 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
 984 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
 985 
 986 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 987 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 988 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
 989 
 990 // Special values
 991 cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
 992 cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
 993 
 994 // Profile linker --------------------------------------------------------------------------------------------------
 995 
 996 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
 997 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
 998 // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
 999 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
1000                               cmsUInt32Number    nProfiles,
1001                               cmsUInt32Number    TheIntents[],
1002                               cmsHPROFILE        hProfiles[],
1003                               cmsBool            BPC[],
1004                               cmsFloat64Number   AdaptationStates[],
1005                               cmsUInt32Number    dwFlags);
1006 
1007 // Sequence --------------------------------------------------------------------------------------------------------
1008 
1009 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
1010 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
1011 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
1012 
1013 
1014 // LUT optimization ------------------------------------------------------------------------------------------------
1015 
1016 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
1017 
1018 CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
1019 
1020 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
1021                                       cmsUInt16Number **White,
1022                                       cmsUInt16Number **Black,
1023                                       cmsUInt32Number *nOutputs);
1024 
1025 CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
1026                                       cmsPipeline**    Lut,
1027                                       cmsUInt32Number  Intent,
1028                                       cmsUInt32Number* InputFormat,
1029                                       cmsUInt32Number* OutputFormat,
1030                                       cmsUInt32Number* dwFlags );
1031 
1032 
1033 // Hi level LUT building ----------------------------------------------------------------------------------------------
1034 
1035 cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
1036                                               cmsHPROFILE hProfiles[],
1037                                               cmsBool  BPC[],
1038                                               cmsUInt32Number Intents[],
1039                                               cmsFloat64Number AdaptationStates[],
1040                                               cmsUInt32Number nGamutPCSposition,
1041                                               cmsHPROFILE hGamut);
1042 
1043 
1044 // Formatters ------------------------------------------------------------------------------------------------------------
1045 
1046 #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
1047 
1048 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
1049 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
1050 
1051 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
1052                                                       cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
1053                                                       cmsFormatterDirection Dir,
1054                                                       cmsUInt32Number dwFlags);
1055 
1056 
1057 #ifndef CMS_NO_HALF_SUPPORT
1058 
1059 // Half float
1060 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1061 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1062 
1063 #endif
1064 
1065 // Transform logic ------------------------------------------------------------------------------------------------------
1066 
1067 struct _cmstransform_struct;
1068 
1069 typedef struct {
1070 
1071     // 1-pixel cache (16 bits only)
1072     cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1073     cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1074 
1075 } _cmsCACHE;
1076 
1077 
1078 
1079 // Transformation
1080 typedef struct _cmstransform_struct {
1081 
1082     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1083 
1084     // Points to transform code
1085     _cmsTransform2Fn xform;
1086 
1087     // Formatters, cannot be embedded into LUT because cache
1088     cmsFormatter16 FromInput;
1089     cmsFormatter16 ToOutput;
1090 
1091     cmsFormatterFloat FromInputFloat;
1092     cmsFormatterFloat ToOutputFloat;
1093 
1094     // 1-pixel cache seed for zero as input (16 bits, read only)
1095     _cmsCACHE Cache;
1096 
1097     // A Pipeline holding the full (optimized) transform
1098     cmsPipeline* Lut;
1099 
1100     // A Pipeline holding the gamut check. It goes from the input space to bilevel
1101     cmsPipeline* GamutCheck;
1102 
1103     // Colorant tables
1104     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1105     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1106 
1107     // Informational only
1108     cmsColorSpaceSignature EntryColorSpace;
1109     cmsColorSpaceSignature ExitColorSpace;
1110 
1111     // White points (informative only)
1112     cmsCIEXYZ EntryWhitePoint;
1113     cmsCIEXYZ ExitWhitePoint;
1114 
1115     // Profiles used to create the transform
1116     cmsSEQ* Sequence;
1117 
1118     cmsUInt32Number  dwOriginalFlags;
1119     cmsFloat64Number AdaptationState;
1120 
1121     // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1122     cmsUInt32Number RenderingIntent;
1123 
1124     // An id that uniquely identifies the running context. May be null.
1125     cmsContext ContextID;
1126 
1127     // A user-defined pointer that can be used to store data for transform plug-ins
1128     void* UserData;
1129     _cmsFreeUserDataFn FreeUserData;
1130 
1131     // A way to provide backwards compatibility with full xform plugins
1132     _cmsTransformFn OldXform;
1133 
1134     // A one-worker transform entry for parallelization
1135     _cmsTransform2Fn Worker;
1136     cmsInt32Number   MaxWorkers;
1137     cmsUInt32Number  WorkerFlags;
1138 
1139 } _cmsTRANSFORM;
1140 
1141 // Copies extra channels from input to output if the original flags in the transform structure
1142 // instructs to do so. This function is called on all standard transform functions.
1143 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1144                              void* out,
1145                              cmsUInt32Number PixelsPerLine,
1146                              cmsUInt32Number LineCount,
1147                              const cmsStride* Stride);
1148 
1149 // -----------------------------------------------------------------------------------------------------------------------
1150 
1151 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1152                             cmsUInt32Number        nProfiles,
1153                             cmsUInt32Number        InputFormat,
1154                             cmsUInt32Number        OutputFormat,
1155                             const cmsUInt32Number  Intents[],
1156                             const cmsHPROFILE      hProfiles[],
1157                             const cmsBool          BPC[],
1158                             const cmsFloat64Number AdaptationStates[],
1159                             cmsUInt32Number        dwFlags);
1160 
1161 
1162 cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1163                             cmsUInt32Number        nPoints,
1164                             cmsUInt32Number        nProfiles,
1165                             const cmsUInt32Number  Intents[],
1166                             const cmsHPROFILE      hProfiles[],
1167                             const cmsBool          BPC[],
1168                             const cmsFloat64Number AdaptationStates[],
1169                             cmsUInt32Number        dwFlags);
1170 
1171 cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1172 
1173 cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1174 
1175 
1176 // thread-safe gettime
1177 cmsBool _cmsGetTime(struct tm* ptr_time);
1178 
1179 #define _lcms_internal_H
1180 #endif