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