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 
_cmsToFixedDomain(int a)180 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
_cmsFromFixedDomain(cmsS15Fixed16Number a)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.
_cmsQuickFloor(cmsFloat64Number val)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
_cmsQuickFloorWord(cmsFloat64Number d)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
_cmsQuickSaturateWord(cmsFloat64Number d)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 
_cmsLockPrimitive(_cmsMutex * m)313 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
314 {
315         EnterCriticalSection(m);
316         return 0;
317 }
318 
_cmsUnlockPrimitive(_cmsMutex * m)319 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
320 {
321         LeaveCriticalSection(m);
322         return 0;
323 }
324 
_cmsInitMutexPrimitive(_cmsMutex * m)325 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
326 {
327         InitializeCriticalSection(m);
328         return 0;
329 }
330 
_cmsDestroyMutexPrimitive(_cmsMutex * m)331 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
332 {
333         DeleteCriticalSection(m);
334         return 0;
335 }
336 
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)337 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
338 {
339         EnterCriticalSection(m);
340         return 0;
341 }
342 
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)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 
_cmsLockPrimitive(_cmsMutex * m)358 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
359 {
360         return pthread_mutex_lock(m);
361 }
362 
_cmsUnlockPrimitive(_cmsMutex * m)363 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
364 {
365         return pthread_mutex_unlock(m);
366 }
367 
_cmsInitMutexPrimitive(_cmsMutex * m)368 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
369 {
370         return pthread_mutex_init(m, NULL);
371 }
372 
_cmsDestroyMutexPrimitive(_cmsMutex * m)373 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
374 {
375         return pthread_mutex_destroy(m);
376 }
377 
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)378 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
379 {
380         return pthread_mutex_lock(m);
381 }
382 
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)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 
_cmsLockPrimitive(_cmsMutex * m)395 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
396 {
397     cmsUNUSED_PARAMETER(m);
398         return 0;
399 }
400 
_cmsUnlockPrimitive(_cmsMutex * m)401 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
402 {
403     cmsUNUSED_PARAMETER(m);
404         return 0;
405 }
406 
_cmsInitMutexPrimitive(_cmsMutex * m)407 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
408 {
409     cmsUNUSED_PARAMETER(m);
410         return 0;
411 }
412 
_cmsDestroyMutexPrimitive(_cmsMutex * m)413 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
414 {
415     cmsUNUSED_PARAMETER(m);
416         return 0;
417 }
418 
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)419 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
420 {
421     cmsUNUSED_PARAMETER(m);
422         return 0;
423 }
424 
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)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 struct _cmsPipeline_struct {
943 
944     cmsStage* Elements;                                // Points to elements chain
945     cmsUInt32Number InputChannels, OutputChannels;
946 
947     // Data & evaluators
948     void *Data;
949 
950    _cmsPipelineEval16Fn    Eval16Fn;
951    _cmsPipelineEvalFloatFn EvalFloatFn;
952    _cmsFreeUserDataFn      FreeDataFn;
953    _cmsDupUserDataFn       DupDataFn;
954 
955     cmsContext ContextID;            // Environment
956 
957     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
958 };
959 
960 // LUT reading & creation -------------------------------------------------------------------------------------------
961 
962 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
963 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
964 
965 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
966 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
967 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
968 
969 // Special values
970 cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
971 cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
972 
973 // Profile linker --------------------------------------------------------------------------------------------------
974 
975 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
976 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
977 // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
978 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
979                               cmsUInt32Number    nProfiles,
980                               cmsUInt32Number    TheIntents[],
981                               cmsHPROFILE        hProfiles[],
982                               cmsBool            BPC[],
983                               cmsFloat64Number   AdaptationStates[],
984                               cmsUInt32Number    dwFlags);
985 
986 // Sequence --------------------------------------------------------------------------------------------------------
987 
988 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
989 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
990 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
991 
992 
993 // LUT optimization ------------------------------------------------------------------------------------------------
994 
995 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
996 
997 CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
998 
999 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
1000                                       cmsUInt16Number **White,
1001                                       cmsUInt16Number **Black,
1002                                       cmsUInt32Number *nOutputs);
1003 
1004 CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
1005                                       cmsPipeline**    Lut,
1006                                       cmsUInt32Number  Intent,
1007                                       cmsUInt32Number* InputFormat,
1008                                       cmsUInt32Number* OutputFormat,
1009                                       cmsUInt32Number* dwFlags );
1010 
1011 
1012 // Hi level LUT building ----------------------------------------------------------------------------------------------
1013 
1014 cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
1015                                               cmsHPROFILE hProfiles[],
1016                                               cmsBool  BPC[],
1017                                               cmsUInt32Number Intents[],
1018                                               cmsFloat64Number AdaptationStates[],
1019                                               cmsUInt32Number nGamutPCSposition,
1020                                               cmsHPROFILE hGamut);
1021 
1022 
1023 // Formatters ------------------------------------------------------------------------------------------------------------
1024 
1025 #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
1026 
1027 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
1028 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
1029 
1030 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
1031                                                       cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
1032                                                       cmsFormatterDirection Dir,
1033                                                       cmsUInt32Number dwFlags);
1034 
1035 
1036 #ifndef CMS_NO_HALF_SUPPORT
1037 
1038 // Half float
1039 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1040 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1041 
1042 #endif
1043 
1044 // Transform logic ------------------------------------------------------------------------------------------------------
1045 
1046 struct _cmstransform_struct;
1047 
1048 typedef struct {
1049 
1050     // 1-pixel cache (16 bits only)
1051     cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1052     cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1053 
1054 } _cmsCACHE;
1055 
1056 
1057 
1058 // Transformation
1059 typedef struct _cmstransform_struct {
1060 
1061     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1062 
1063     // Points to transform code
1064     _cmsTransform2Fn xform;
1065 
1066     // Formatters, cannot be embedded into LUT because cache
1067     cmsFormatter16 FromInput;
1068     cmsFormatter16 ToOutput;
1069 
1070     cmsFormatterFloat FromInputFloat;
1071     cmsFormatterFloat ToOutputFloat;
1072 
1073     // 1-pixel cache seed for zero as input (16 bits, read only)
1074     _cmsCACHE Cache;
1075 
1076     // A Pipeline holding the full (optimized) transform
1077     cmsPipeline* Lut;
1078 
1079     // A Pipeline holding the gamut check. It goes from the input space to bilevel
1080     cmsPipeline* GamutCheck;
1081 
1082     // Colorant tables
1083     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1084     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1085 
1086     // Informational only
1087     cmsColorSpaceSignature EntryColorSpace;
1088     cmsColorSpaceSignature ExitColorSpace;
1089 
1090     // White points (informative only)
1091     cmsCIEXYZ EntryWhitePoint;
1092     cmsCIEXYZ ExitWhitePoint;
1093 
1094     // Profiles used to create the transform
1095     cmsSEQ* Sequence;
1096 
1097     cmsUInt32Number  dwOriginalFlags;
1098     cmsFloat64Number AdaptationState;
1099 
1100     // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1101     cmsUInt32Number RenderingIntent;
1102 
1103     // An id that uniquely identifies the running context. May be null.
1104     cmsContext ContextID;
1105 
1106     // A user-defined pointer that can be used to store data for transform plug-ins
1107     void* UserData;
1108     _cmsFreeUserDataFn FreeUserData;
1109 
1110     // A way to provide backwards compatibility with full xform plugins
1111     _cmsTransformFn OldXform;
1112 
1113 } _cmsTRANSFORM;
1114 
1115 // Copies extra channels from input to output if the original flags in the transform structure
1116 // instructs to do so. This function is called on all standard transform functions.
1117 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1118                              void* out,
1119                              cmsUInt32Number PixelsPerLine,
1120                              cmsUInt32Number LineCount,
1121                              const cmsStride* Stride);
1122 
1123 // -----------------------------------------------------------------------------------------------------------------------
1124 
1125 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1126                             cmsUInt32Number        nProfiles,
1127                             cmsUInt32Number        InputFormat,
1128                             cmsUInt32Number        OutputFormat,
1129                             const cmsUInt32Number  Intents[],
1130                             const cmsHPROFILE      hProfiles[],
1131                             const cmsBool          BPC[],
1132                             const cmsFloat64Number AdaptationStates[],
1133                             cmsUInt32Number        dwFlags);
1134 
1135 
1136 cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1137                             cmsUInt32Number        nPoints,
1138                             cmsUInt32Number        nProfiles,
1139                             const cmsUInt32Number  Intents[],
1140                             const cmsHPROFILE      hProfiles[],
1141                             const cmsBool          BPC[],
1142                             const cmsFloat64Number AdaptationStates[],
1143                             cmsUInt32Number        dwFlags);
1144 
1145 cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1146 
1147 cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1148 
1149 
1150 #define _lcms_internal_H
1151 #endif
1152