1 
2 //
3 //  Little Color Management System
4 //  Copyright (c) 1998-2020 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 _lcms2mt_plugin_H
31 #   include "lcms2mt_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 #else
116 #  if !defined(HAVE_ISINF)
117 #    if !defined(isinf)
118 #       define isinf(x) (!finite((x)))
119 #    endif
120 #  endif
121 #endif
122 
123 // A fast way to convert from/to 16 <-> 8 bits
124 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
125 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
126 
127 // Code analysis is broken on asserts
128 #ifdef _MSC_VER
129 #    if (_MSC_VER >= 1500)
130 #            define _cmsAssert(a)  { assert((a)); __analysis_assume((a)); }
131 #     else
132 #            define _cmsAssert(a)   assert((a))
133 #     endif
134 #else
135 #      define _cmsAssert(a)   assert((a))
136 #endif
137 
138 //---------------------------------------------------------------------------------
139 
140 // Determinant lower than that are assumed zero (used on matrix invert)
141 #define MATRIX_DET_TOLERANCE    0.0001
142 
143 //---------------------------------------------------------------------------------
144 
145 // Fixed point
146 #define FIXED_TO_INT(x)         ((x)>>16)
147 #define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU)
148 #define ROUND_FIXED_TO_INT(x)   (((x)+0x8000)>>16)
149 
_cmsToFixedDomain(int a)150 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
_cmsFromFixedDomain(cmsS15Fixed16Number a)151 cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
152 
153 // -----------------------------------------------------------------------------------------------------------
154 
155 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
156 // note than this only works in the range ..-32767...+32767 because
157 // mantissa is interpreted as 15.16 fixed point.
158 // The union is to avoid pointer aliasing overoptimization.
_cmsQuickFloor(cmsFloat64Number val)159 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
160 {
161 #ifdef CMS_DONT_USE_FAST_FLOOR
162     return (int) floor(val);
163 #else
164     const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
165     union {
166         cmsFloat64Number val;
167         int halves[2];
168     } temp;
169 
170     temp.val = val + _lcms_double2fixmagic;
171 
172 #ifdef CMS_USE_BIG_ENDIAN
173     return temp.halves[1] >> 16;
174 #else
175     return temp.halves[0] >> 16;
176 #endif
177 #endif
178 }
179 
180 // Fast floor restricted to 0..65535.0
_cmsQuickFloorWord(cmsFloat64Number d)181 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
182 {
183     return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
184 }
185 
186 // Floor to word, taking care of saturation
_cmsQuickSaturateWord(cmsFloat64Number d)187 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
188 {
189     d += 0.5;
190     if (d <= 0) return 0;
191     if (d >= 65535.0) return 0xffff;
192 
193     return _cmsQuickFloorWord(d);
194 }
195 
196 // Test bed entry points---------------------------------------------------------------
197 #define CMSCHECKPOINT CMSAPI
198 
199 // Pthread support --------------------------------------------------------------------
200 #ifndef CMS_NO_PTHREADS
201 
202 // This is the threading support. Unfortunately, it has to be platform-dependent because
203 // windows does not support pthreads.
204 
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 // ---------------------------------------------------------------------------------------------------------
442 
443 // Suballocators.
444 typedef struct _cmsSubAllocator_chunk_st {
445 
446     cmsUInt8Number* Block;
447     cmsUInt32Number BlockSize;
448     cmsUInt32Number Used;
449 
450     struct _cmsSubAllocator_chunk_st* next;
451 
452 } _cmsSubAllocator_chunk;
453 
454 
455 typedef struct {
456 
457     cmsContext ContextID;
458     _cmsSubAllocator_chunk* h;
459 
460 } _cmsSubAllocator;
461 
462 
463 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
464 void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
465 void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
466 void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
467 
468 // ----------------------------------------------------------------------------------
469 
470 // The context clients.
471 typedef enum {
472 
473     UserPtr,            // User-defined pointer
474     Logger,
475     AlarmCodesContext,
476     AdaptationStateContext,
477     MemPlugin,
478     InterpPlugin,
479     CurvesPlugin,
480     FormattersPlugin,
481     TagTypePlugin,
482     TagPlugin,
483     IntentPlugin,
484     MPEPlugin,
485     OptimizationPlugin,
486     TransformPlugin,
487     MutexPlugin,
488 
489     // Last in list
490     MemoryClientMax
491 
492 } _cmsMemoryClient;
493 
494 
495 // Container for memory management plug-in.
496 typedef struct {
497 
498     _cmsMallocFnPtrType     MallocPtr;
499     _cmsMalloZerocFnPtrType MallocZeroPtr;
500     _cmsFreeFnPtrType       FreePtr;
501     _cmsReallocFnPtrType    ReallocPtr;
502     _cmsCallocFnPtrType     CallocPtr;
503     _cmsDupFnPtrType        DupPtr;
504 
505 } _cmsMemPluginChunkType;
506 
507 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
508 void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
509 
510 // Internal structure for context
511 struct _cmsContext_struct {
512 
513     struct _cmsContext_struct* Next;  // Points to next context in the new style
514     _cmsSubAllocator* MemPool;        // The memory pool that stores context data
515 
516     void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
517                                       // If NULL, then it reverts to global Context0
518 
519     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
520 };
521 
522 // Returns a pointer to a valid context structure, including the global one if id is zero.
523 // Verifies the magic number.
524 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
525 
526 // Returns the block assigned to the specific zone.
527 void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
528 
529 
530 // Chunks of context memory by plug-in client -------------------------------------------------------
531 
532 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
533 
534 // Container for error logger -- not a plug-in
535 typedef struct {
536 
537     cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
538 
539 } _cmsLogErrorChunkType;
540 
541 // The global Context0 storage for error logger
542 extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
543 
544 // Allocate and init error logger container.
545 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
546                             const struct _cmsContext_struct* src);
547 
548 // Container for alarm codes -- not a plug-in
549 typedef struct {
550 
551     cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
552 
553 } _cmsAlarmCodesChunkType;
554 
555 // The global Context0 storage for alarm codes
556 extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
557 
558 // Allocate and init alarm codes container.
559 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
560                             const struct _cmsContext_struct* src);
561 
562 // Container for adaptation state -- not a plug-in
563 typedef struct {
564 
565     cmsFloat64Number  AdaptationState;
566 
567 } _cmsAdaptationStateChunkType;
568 
569 // The global Context0 storage for adaptation state
570 extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
571 
572 // Allocate and init adaptation state container.
573 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
574                                    const struct _cmsContext_struct* src);
575 
576 
577 // The global Context0 storage for memory management
578 extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
579 
580 // Allocate and init memory management container.
581 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
582                              const struct _cmsContext_struct* src);
583 
584 // Container for interpolation plug-in
585 typedef struct {
586 
587     cmsInterpFnFactory Interpolators;
588 
589 } _cmsInterpPluginChunkType;
590 
591 // The global Context0 storage for interpolation plug-in
592 extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
593 
594 // Allocate and init interpolation container.
595 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
596                                 const struct _cmsContext_struct* src);
597 
598 // Container for parametric curves plug-in
599 typedef struct {
600 
601     struct _cmsParametricCurvesCollection_st* ParametricCurves;
602 
603 } _cmsCurvesPluginChunkType;
604 
605 // The global Context0 storage for tone curves plug-in
606 extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
607 
608 // Allocate and init parametric curves container.
609 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
610                                                       const struct _cmsContext_struct* src);
611 
612 // Container for formatters plug-in
613 typedef struct {
614 
615     struct _cms_formatters_factory_list* FactoryList;
616 
617 } _cmsFormattersPluginChunkType;
618 
619 // The global Context0 storage for formatters plug-in
620 extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
621 
622 // Allocate and init formatters container.
623 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
624                                                        const struct _cmsContext_struct* src);
625 
626 // This chunk type is shared by TagType plug-in and MPE Plug-in
627 typedef struct {
628 
629     struct _cmsTagTypeLinkedList_st* TagTypes;
630 
631 } _cmsTagTypePluginChunkType;
632 
633 
634 // The global Context0 storage for tag types plug-in
635 extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
636 
637 
638 // The global Context0 storage for mult process elements plug-in
639 extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
640 
641 // Allocate and init Tag types container.
642 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
643                                                         const struct _cmsContext_struct* src);
644 // Allocate and init MPE container.
645 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
646                                                         const struct _cmsContext_struct* src);
647 // Container for tag plug-in
648 typedef struct {
649 
650     struct _cmsTagLinkedList_st* Tag;
651 
652 } _cmsTagPluginChunkType;
653 
654 
655 // The global Context0 storage for tag plug-in
656 extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
657 
658 // Allocate and init Tag container.
659 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
660                                                       const struct _cmsContext_struct* src);
661 
662 // Container for intents plug-in
663 typedef struct {
664 
665     struct _cms_intents_list* Intents;
666 
667 } _cmsIntentsPluginChunkType;
668 
669 
670 // The global Context0 storage for intents plug-in
671 extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
672 
673 // Allocate and init intents container.
674 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
675                                                         const struct _cmsContext_struct* src);
676 
677 // Container for optimization plug-in
678 typedef struct {
679 
680     struct _cmsOptimizationCollection_st* OptimizationCollection;
681 
682 } _cmsOptimizationPluginChunkType;
683 
684 
685 // The global Context0 storage for optimizers plug-in
686 extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
687 
688 // Allocate and init optimizers container.
689 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
690                                          const struct _cmsContext_struct* src);
691 
692 // Container for transform plug-in
693 typedef struct {
694 
695     struct _cmsTransformCollection_st* TransformCollection;
696 
697 } _cmsTransformPluginChunkType;
698 
699 // The global Context0 storage for full-transform replacement plug-in
700 extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
701 
702 // Allocate and init transform container.
703 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
704                                         const struct _cmsContext_struct* src);
705 
706 // Container for mutex plug-in
707 typedef struct {
708 
709     _cmsCreateMutexFnPtrType  CreateMutexPtr;
710     _cmsDestroyMutexFnPtrType DestroyMutexPtr;
711     _cmsLockMutexFnPtrType    LockMutexPtr;
712     _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
713 
714 } _cmsMutexPluginChunkType;
715 
716 // The global Context0 storage for mutex plug-in
717 extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
718 
719 // Allocate and init mutex container.
720 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
721                                         const struct _cmsContext_struct* src);
722 
723 // ----------------------------------------------------------------------------------
724 // MLU internal representation
725 typedef struct {
726 
727     cmsUInt16Number Language;
728     cmsUInt16Number Country;
729 
730     cmsUInt32Number StrW;       // Offset to current unicode string
731     cmsUInt32Number Len;        // Length in bytes
732 
733 } _cmsMLUentry;
734 
735 struct _cms_MLU_struct {
736 
737     // The directory
738     cmsUInt32Number  AllocatedEntries;
739     cmsUInt32Number  UsedEntries;
740     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
741 
742     // The Pool
743     cmsUInt32Number PoolSize;  // The maximum allocated size
744     cmsUInt32Number PoolUsed;  // The used size
745     void*  MemPool;            // Pointer to begin of memory pool
746 };
747 
748 // Named color list internal representation
749 typedef struct {
750 
751     char Name[cmsMAX_PATH];
752     cmsUInt16Number PCS[3];
753     cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
754 
755 } _cmsNAMEDCOLOR;
756 
757 struct _cms_NAMEDCOLORLIST_struct {
758 
759     cmsUInt32Number nColors;
760     cmsUInt32Number Allocated;
761     cmsUInt32Number ColorantCount;
762 
763     char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
764     char Suffix[33];
765 
766     _cmsNAMEDCOLOR* List;
767 };
768 
769 
770 // ----------------------------------------------------------------------------------
771 
772 // This is the internal struct holding profile details.
773 
774 // Maximum supported tags in a profile
775 #define MAX_TABLE_TAG       100
776 
777 typedef struct _cms_iccprofile_struct {
778 
779     // I/O handler
780     cmsIOHANDLER*            IOhandler;
781 
782     // Creation time
783     struct tm                Created;
784 
785     // Only most important items found in ICC profiles
786     cmsUInt32Number          Version;
787     cmsProfileClassSignature DeviceClass;
788     cmsColorSpaceSignature   ColorSpace;
789     cmsColorSpaceSignature   PCS;
790     cmsUInt32Number          RenderingIntent;
791 
792     cmsUInt32Number          flags;
793     cmsUInt32Number          manufacturer, model;
794     cmsUInt64Number          attributes;
795     cmsUInt32Number          creator;
796 
797     cmsProfileID             ProfileID;
798 
799     // Dictionary
800     cmsUInt32Number          TagCount;
801     cmsTagSignature          TagNames[MAX_TABLE_TAG];
802     cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
803     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
804     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
805     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
806     void *                   TagPtrs[MAX_TABLE_TAG];
807     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
808                                                                  // depending on profile version, so we keep track of the
809                                                                  // type handler for each tag in the list.
810     // Special
811     cmsBool                  IsWrite;
812 
813     // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
814     void *                   UsrMutex;
815 
816 } _cmsICCPROFILE;
817 
818 // IO helpers for profiles
819 cmsBool              _cmsReadHeader(cmsContext ContextID, _cmsICCPROFILE* Icc);
820 cmsBool              _cmsWriteHeader(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
821 int                  _cmsSearchTag(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
822 
823 // Tag types
824 cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
825 cmsTagTypeSignature  _cmsGetTagTrueType(cmsContext ContextID, cmsHPROFILE hProfile, cmsTagSignature sig);
826 cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
827 
828 // Error logging ---------------------------------------------------------------------------------------------------------
829 
830 void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
831 
832 // Interpolation ---------------------------------------------------------------------------------------------------------
833 
834 CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
835 cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
836 CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsContext ContextID, cmsInterpParams* p);
837 cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
838 
839 // Curves ----------------------------------------------------------------------------------------------------------------
840 
841 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
842 // In the case of table-based, Eval pointer is set to NULL
843 
844 // The gamma function main structure
845 struct _cms_curve_struct {
846 
847     cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
848 
849     cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
850     cmsCurveSegment*  Segments;      // The segments
851     cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
852 
853     cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
854 
855     // 16 bit Table-based representation follows
856     cmsUInt32Number    nEntries;      // Number of table elements
857     cmsUInt16Number*   Table16;       // The table itself.
858 };
859 
860 
861 //  Pipelines & Stages ---------------------------------------------------------------------------------------------
862 
863 // A single stage
864 struct _cmsStage_struct {
865 
866     cmsStageSignature   Type;           // Identifies the stage
867     cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
868 
869     cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
870     cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
871 
872     _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
873     _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
874     _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
875 
876     // A generic pointer to whatever memory needed by the stage
877     void*               Data;
878 
879     // Maintains linked list (used internally)
880     struct _cmsStage_struct* Next;
881 };
882 
883 
884 // Special Stages (cannot be saved)
885 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
886 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
887 cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID);
888 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
889 cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
890 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
891 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsContext ContextID, cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
892 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
893 CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
894 cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
895 cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
896 cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID);
897 cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
898 cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
899 
900 
901 // For curve set only
902 cmsToneCurve**     _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
903 
904 
905 // Pipeline Evaluator (in floating point)
906 typedef void (* _cmsPipelineEvalFloatFn)(cmsContext ContextID, const cmsFloat32Number In[],
907                                          cmsFloat32Number Out[],
908                                          const void* Data);
909 
910 struct _cmsPipeline_struct {
911 
912     cmsStage* Elements;                                // Points to elements chain
913     cmsUInt32Number InputChannels, OutputChannels;
914 
915     // Data & evaluators
916     void *Data;
917 
918    _cmsOPTeval16Fn         Eval16Fn;
919    _cmsPipelineEvalFloatFn EvalFloatFn;
920    _cmsFreeUserDataFn      FreeDataFn;
921    _cmsDupUserDataFn       DupDataFn;
922 
923     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
924 };
925 
926 // LUT reading & creation -------------------------------------------------------------------------------------------
927 
928 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
929 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
930 
931 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
932 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
933 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
934 
935 // Special values
936 cmsBool           _cmsReadMediaWhitePoint(cmsContext ContextID, cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
937 cmsBool           _cmsReadCHAD(cmsContext ContextID, cmsMAT3* Dest, cmsHPROFILE hProfile);
938 
939 // Profile linker --------------------------------------------------------------------------------------------------
940 
941 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
942 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
943 // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
944 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
945                               cmsUInt32Number    nProfiles,
946                               cmsUInt32Number    TheIntents[],
947                               cmsHPROFILE        hProfiles[],
948                               cmsBool            BPC[],
949                               cmsFloat64Number   AdaptationStates[],
950                               cmsUInt32Number    dwFlags);
951 
952 // Sequence --------------------------------------------------------------------------------------------------------
953 
954 cmsSEQ* _cmsReadProfileSequence(cmsContext ContextID, cmsHPROFILE hProfile);
955 cmsBool _cmsWriteProfileSequence(cmsContext ContextID, cmsHPROFILE hProfile, const cmsSEQ* seq);
956 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
957 
958 
959 // LUT optimization ------------------------------------------------------------------------------------------------
960 
961 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
962 cmsUInt32Number  _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
963 
964 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
965                                       cmsUInt16Number **White,
966                                       cmsUInt16Number **Black,
967                                       cmsUInt32Number *nOutputs);
968 
969 cmsBool          _cmsOptimizePipeline(cmsContext ContextID,
970                                       cmsPipeline**    Lut,
971                                       cmsUInt32Number  Intent,
972                                       cmsUInt32Number* InputFormat,
973                                       cmsUInt32Number* OutputFormat,
974                                       cmsUInt32Number* dwFlags );
975 
976 cmsBool _cmsLutIsIdentity(cmsPipeline *PtrLut);
977 
978 // Hi level LUT building ----------------------------------------------------------------------------------------------
979 
980 cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
981                                               cmsHPROFILE hProfiles[],
982                                               cmsBool  BPC[],
983                                               cmsUInt32Number Intents[],
984                                               cmsFloat64Number AdaptationStates[],
985                                               cmsUInt32Number nGamutPCSposition,
986                                               cmsHPROFILE hGamut);
987 
988 
989 // Formatters ------------------------------------------------------------------------------------------------------------
990 
991 #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
992 
993 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
994 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
995 
996 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
997                                                       cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
998                                                       cmsFormatterDirection Dir,
999                                                       cmsUInt32Number dwFlags);
1000 
1001 
1002 #ifndef CMS_NO_HALF_SUPPORT
1003 
1004 // Half float
1005 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1006 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1007 
1008 #endif
1009 
1010 // Transform logic ------------------------------------------------------------------------------------------------------
1011 
1012 struct _cmstransform_struct;
1013 
1014 typedef struct {
1015 
1016     // 1-pixel cache (16 bits only)
1017     cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1018     cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1019 
1020 } _cmsCACHE;
1021 
1022 
1023 
1024 // Transformation
1025 typedef struct _cmstransform_core {
1026 
1027     cmsUInt32Number refs;
1028 
1029     // A Pipeline holding the full (optimized) transform
1030     cmsPipeline* Lut;
1031 
1032     // A Pipeline holding the gamut check. It goes from the input space to bilevel
1033     cmsPipeline* GamutCheck;
1034 
1035     // Colorant tables
1036     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1037     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1038 
1039     // Informational only
1040     cmsColorSpaceSignature EntryColorSpace;
1041     cmsColorSpaceSignature ExitColorSpace;
1042 
1043     // White points (informative only)
1044     cmsCIEXYZ EntryWhitePoint;
1045     cmsCIEXYZ ExitWhitePoint;
1046 
1047     // Profiles used to create the transform
1048     cmsSEQ* Sequence;
1049 
1050     cmsUInt32Number  dwOriginalFlags;
1051     cmsFloat64Number AdaptationState;
1052 
1053     // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1054     cmsUInt32Number RenderingIntent;
1055 
1056     // A user-defined pointer that can be used to store data for transform plug-ins
1057     void* UserData;
1058     _cmsFreeUserDataFn FreeUserData;
1059 
1060 } _cmsTRANSFORMCORE;
1061 
1062 typedef struct _cmstransform_struct {
1063 
1064     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1065 
1066     // Points to transform code
1067     _cmsTransform2Fn xform;
1068 
1069     // Formatters, cannot be embedded into LUT because cache
1070     cmsFormatter16 FromInput;
1071     cmsFormatter16 ToOutput;
1072 
1073     cmsFormatterFloat FromInputFloat;
1074     cmsFormatterFloat ToOutputFloat;
1075 
1076     // 1-pixel cache seed for zero as input (16 bits, read only)
1077     _cmsCACHE Cache;
1078 
1079     // A way to provide backwards compatibility with full xform plugins
1080     _cmsTransformFn OldXform;
1081 
1082     _cmsTRANSFORMCORE *core;
1083 } _cmsTRANSFORM;
1084 
1085 // Copies extra channels from input to output if the original flags in the transform structure
1086 // instructs to do so. This function is called on all standard transform functions.
1087 void _cmsHandleExtraChannels(cmsContext ContextID, _cmsTRANSFORM* p, const void* in,
1088                              void* out,
1089                              cmsUInt32Number PixelsPerLine,
1090                              cmsUInt32Number LineCount,
1091                              const cmsStride* Stride);
1092 
1093 // -----------------------------------------------------------------------------------------------------------------------
1094 
1095 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1096                             cmsUInt32Number        nProfiles,
1097                             cmsUInt32Number        InputFormat,
1098                             cmsUInt32Number        OutputFormat,
1099                             const cmsUInt32Number  Intents[],
1100                             const cmsHPROFILE      hProfiles[],
1101                             const cmsBool          BPC[],
1102                             const cmsFloat64Number AdaptationStates[],
1103                             cmsUInt32Number        dwFlags);
1104 
1105 
1106 cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1107                             cmsUInt32Number        nPoints,
1108                             cmsUInt32Number        nProfiles,
1109                             const cmsUInt32Number  Intents[],
1110                             const cmsHPROFILE      hProfiles[],
1111                             const cmsBool          BPC[],
1112                             const cmsFloat64Number AdaptationStates[],
1113                             cmsUInt32Number        dwFlags);
1114 
1115 cmsBool   _cmsAdaptationMatrix(cmsContext ContextID, cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1116 
1117 cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsContext ContextID, cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1118 
1119 void _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number flags);
1120 
1121 cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta);
1122 
1123 #define _lcms_internal_H
1124 #endif
1125