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