Coverage Report

Created: 2026-10-17 06:25

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