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