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 "../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
122cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
123cmsINLINE 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.
131cmsINLINE 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
153cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
154{
155    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
156}
157
158// Floor to word, taking care of saturation
159cmsINLINE 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
200typedef CRITICAL_SECTION _cmsMutex;
201
202#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
203
204cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
205{
206	EnterCriticalSection(m);
207	return 0;
208}
209
210cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
211{
212	LeaveCriticalSection(m);
213	return 0;
214}
215
216cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
217{
218	InitializeCriticalSection(m);
219	return 0;
220}
221
222cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
223{
224	DeleteCriticalSection(m);
225	return 0;
226}
227
228cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
229{
230	EnterCriticalSection(m);
231	return 0;
232}
233
234cmsINLINE 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
246typedef pthread_mutex_t _cmsMutex;
247
248
249cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
250{
251	return pthread_mutex_lock(m);
252}
253
254cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
255{
256	return pthread_mutex_unlock(m);
257}
258
259cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
260{
261	return pthread_mutex_init(m, NULL);
262}
263
264cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
265{
266	return pthread_mutex_destroy(m);
267}
268
269cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
270{
271	return pthread_mutex_lock(m);
272}
273
274cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
275{
276	return pthread_mutex_unlock(m);
277}
278
279#endif
280#else
281
282#define CMS_MUTEX_INITIALIZER 0
283typedef int _cmsMutex;
284
285
286cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
287{
288	return 0;
289    cmsUNUSED_PARAMETER(m);
290}
291
292cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
293{
294	return 0;
295    cmsUNUSED_PARAMETER(m);
296}
297
298cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
299{
300	return 0;
301    cmsUNUSED_PARAMETER(m);
302}
303
304cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
305{
306	return 0;
307    cmsUNUSED_PARAMETER(m);
308}
309
310cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
311{
312	return 0;
313    cmsUNUSED_PARAMETER(m);
314}
315
316cmsINLINE 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.
326void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
327
328// Memory management
329cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
330
331// Interpolation
332cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
333
334// Parametric curves
335cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
336
337// Formatters management
338cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
339
340// Tag type management
341cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
342
343// Tag management
344cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
345
346// Intent management
347cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
348
349// Multi Process elements
350cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
351
352// Optimization
353cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
354
355// Transform
356cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
357
358// Mutex
359cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
360
361// ---------------------------------------------------------------------------------------------------------
362
363// Suballocators.
364typedef 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
375typedef struct {
376
377    cmsContext ContextID;
378    _cmsSubAllocator_chunk* h;
379
380} _cmsSubAllocator;
381
382
383_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
384void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
385void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
386void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
387
388// ----------------------------------------------------------------------------------
389
390// The context clients.
391typedef 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.
416typedef 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
428void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
429
430// Internal structure for context
431struct _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.
444struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
445
446// Returns the block assigned to the specific zone.
447void*     _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
455typedef struct {
456
457    cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
458
459} _cmsLogErrorChunkType;
460
461// The global Context0 storage for error logger
462extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
463
464// Allocate and init error logger container.
465void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
466                            const struct _cmsContext_struct* src);
467
468// Container for alarm codes -- not a plug-in
469typedef struct {
470
471    cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
472
473} _cmsAlarmCodesChunkType;
474
475// The global Context0 storage for alarm codes
476extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
477
478// Allocate and init alarm codes container.
479void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
480                            const struct _cmsContext_struct* src);
481
482// Container for adaptation state -- not a plug-in
483typedef struct {
484
485    cmsFloat64Number  AdaptationState;
486
487} _cmsAdaptationStateChunkType;
488
489// The global Context0 storage for adaptation state
490extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
491
492// Allocate and init adaptation state container.
493void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
494                                   const struct _cmsContext_struct* src);
495
496
497// The global Context0 storage for memory management
498extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
499
500// Allocate and init memory management container.
501void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
502                             const struct _cmsContext_struct* src);
503
504// Container for interpolation plug-in
505typedef struct {
506
507    cmsInterpFnFactory Interpolators;
508
509} _cmsInterpPluginChunkType;
510
511// The global Context0 storage for interpolation plug-in
512extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
513
514// Allocate and init interpolation container.
515void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
516                                const struct _cmsContext_struct* src);
517
518// Container for parametric curves plug-in
519typedef struct {
520
521    struct _cmsParametricCurvesCollection_st* ParametricCurves;
522
523} _cmsCurvesPluginChunkType;
524
525// The global Context0 storage for tone curves plug-in
526extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
527
528// Allocate and init parametric curves container.
529void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
530                                                      const struct _cmsContext_struct* src);
531
532// Container for formatters plug-in
533typedef struct {
534
535    struct _cms_formatters_factory_list* FactoryList;
536
537} _cmsFormattersPluginChunkType;
538
539// The global Context0 storage for formatters plug-in
540extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
541
542// Allocate and init formatters container.
543void _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
547typedef struct {
548
549    struct _cmsTagTypeLinkedList_st* TagTypes;
550
551} _cmsTagTypePluginChunkType;
552
553
554// The global Context0 storage for tag types plug-in
555extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
556
557
558// The global Context0 storage for mult process elements plug-in
559extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
560
561// Allocate and init Tag types container.
562void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
563                                                        const struct _cmsContext_struct* src);
564// Allocate and init MPE container.
565void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
566                                                        const struct _cmsContext_struct* src);
567// Container for tag plug-in
568typedef struct {
569
570    struct _cmsTagLinkedList_st* Tag;
571
572} _cmsTagPluginChunkType;
573
574
575// The global Context0 storage for tag plug-in
576extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
577
578// Allocate and init Tag container.
579void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
580                                                      const struct _cmsContext_struct* src);
581
582// Container for intents plug-in
583typedef struct {
584
585    struct _cms_intents_list* Intents;
586
587} _cmsIntentsPluginChunkType;
588
589
590// The global Context0 storage for intents plug-in
591extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
592
593// Allocate and init intents container.
594void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
595                                                        const struct _cmsContext_struct* src);
596
597// Container for optimization plug-in
598typedef struct {
599
600    struct _cmsOptimizationCollection_st* OptimizationCollection;
601
602} _cmsOptimizationPluginChunkType;
603
604
605// The global Context0 storage for optimizers plug-in
606extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
607
608// Allocate and init optimizers container.
609void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
610                                         const struct _cmsContext_struct* src);
611
612// Container for transform plug-in
613typedef struct {
614
615    struct _cmsTransformCollection_st* TransformCollection;
616
617} _cmsTransformPluginChunkType;
618
619// The global Context0 storage for full-transform replacement plug-in
620extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
621
622// Allocate and init transform container.
623void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
624                                        const struct _cmsContext_struct* src);
625
626// Container for mutex plug-in
627typedef 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
637extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
638
639// Allocate and init mutex container.
640void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
641                                        const struct _cmsContext_struct* src);
642
643// ----------------------------------------------------------------------------------
644// MLU internal representation
645typedef 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
655struct _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
671typedef struct {
672
673    char Name[cmsMAX_PATH];
674    cmsUInt16Number PCS[3];
675    cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
676
677} _cmsNAMEDCOLOR;
678
679struct _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
701typedef 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
746cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc);
747cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
748int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
749
750// Tag types
751cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
752cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
753cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
754
755// Error logging ---------------------------------------------------------------------------------------------------------
756
757void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
758
759// Interpolation ---------------------------------------------------------------------------------------------------------
760
761cmsInterpParams*     _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
762cmsInterpParams*     _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
763void                 _cmsFreeInterpParams(cmsInterpParams* p);
764cmsBool              _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
772struct _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
791struct _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)
814cmsStage*        _cmsStageAllocLab2XYZ(cmsContext ContextID);
815cmsStage*        _cmsStageAllocXYZ2Lab(cmsContext ContextID);
816cmsStage*        _cmsStageAllocLabPrelin(cmsContext ContextID);
817cmsStage*        _cmsStageAllocLabV2ToV4(cmsContext ContextID);
818cmsStage*        _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
819cmsStage*        _cmsStageAllocLabV4ToV2(cmsContext ContextID);
820cmsStage*        _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
821cmsStage*        _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
822cmsStage*        _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
823cmsStage*        _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
824cmsStage*        _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
825cmsStage*        _cmsStageNormalizeToLabFloat(cmsContext ContextID);
826cmsStage*        _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
827
828// For curve set only
829cmsToneCurve**     _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
830
831
832// Pipeline Evaluator (in floating point)
833typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
834                                         cmsFloat32Number Out[],
835                                         const void* Data);
836
837struct _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
860cmsPipeline*      _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
861cmsPipeline*      _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
862cmsPipeline*      _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
863
864// Special values
865cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
866cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
867
868// Profile linker --------------------------------------------------------------------------------------------------
869
870cmsPipeline* _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
880cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
881cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
882cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
883
884
885// LUT optimization ------------------------------------------------------------------------------------------------
886
887cmsUInt16Number  _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
888int              _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
889
890cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
891                                      cmsUInt16Number **White,
892                                      cmsUInt16Number **Black,
893                                      cmsUInt32Number *nOutputs);
894
895cmsBool          _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
905cmsPipeline*     _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
918cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
919cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
920
921cmsFormatter    _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
930cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
931cmsUInt16Number  _cmsFloat2Half(cmsFloat32Number flt);
932
933#endif
934
935// Transform logic ------------------------------------------------------------------------------------------------------
936
937struct _cmstransform_struct;
938
939typedef 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
950typedef 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
1005cmsHTRANSFORM _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
1016cmsToneCurve* _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
1025cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1026
1027cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1028
1029
1030#define _lcms_internal_H
1031#endif
1032//<<<+++OPENSOURCE_MUST_END
1033