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