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