Coverage Report

Created: 2025-08-12 07:37

/src/Little-CMS/src/lcms2_internal.h
Line
Count
Source (jump to first uncovered line)
1
2
//
3
//  Little Color Management System
4
//  Copyright (c) 1998-2024 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
0
#define MAX_STAGE_CHANNELS  128
79
80
// Unused parameter warning suppression
81
294k
#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
1.01M
#      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: cmserr.c:_cmsToFixedDomain
Unexecuted instantiation: cmsgamma.c:_cmsToFixedDomain
Unexecuted instantiation: cmsintrp.c:_cmsToFixedDomain
Unexecuted instantiation: cmsio0.c:_cmsToFixedDomain
Unexecuted instantiation: cmsio1.c:_cmsToFixedDomain
Unexecuted instantiation: cmslut.c:_cmsToFixedDomain
Unexecuted instantiation: cmsplugin.c:_cmsToFixedDomain
Unexecuted instantiation: cmscnvrt.c:_cmsToFixedDomain
Unexecuted instantiation: cmsgmt.c:_cmsToFixedDomain
Unexecuted instantiation: cmsmtrx.c:_cmsToFixedDomain
Unexecuted instantiation: cmspack.c:_cmsToFixedDomain
Unexecuted instantiation: cmspcs.c:_cmsToFixedDomain
Unexecuted instantiation: cmswtpnt.c:_cmsToFixedDomain
Unexecuted instantiation: cmsxform.c:_cmsToFixedDomain
Unexecuted instantiation: cmssamp.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
152
0
cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
Unexecuted instantiation: cmserr.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsgamma.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsintrp.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsio0.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsio1.c:_cmsFromFixedDomain
Unexecuted instantiation: cmslut.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsplugin.c:_cmsFromFixedDomain
Unexecuted instantiation: cmscnvrt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsgmt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsmtrx.c:_cmsFromFixedDomain
Unexecuted instantiation: cmspack.c:_cmsFromFixedDomain
Unexecuted instantiation: cmspcs.c:_cmsFromFixedDomain
Unexecuted instantiation: cmswtpnt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsxform.c:_cmsFromFixedDomain
Unexecuted instantiation: cmssamp.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
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
0
{
162
#ifdef CMS_DONT_USE_FAST_FLOOR
163
    return (int) floor(val);
164
#else
165
0
    const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
166
0
    union {
167
0
        cmsFloat64Number val;
168
0
        int halves[2];
169
0
    } temp;
170
171
0
    temp.val = val + _lcms_double2fixmagic;
172
173
#ifdef CMS_USE_BIG_ENDIAN
174
    return temp.halves[1] >> 16;
175
#else
176
0
    return temp.halves[0] >> 16;
177
0
#endif
178
0
#endif
179
0
}
Unexecuted instantiation: cmserr.c:_cmsQuickFloor
Unexecuted instantiation: cmsgamma.c:_cmsQuickFloor
Unexecuted instantiation: cmsintrp.c:_cmsQuickFloor
Unexecuted instantiation: cmsio0.c:_cmsQuickFloor
Unexecuted instantiation: cmsio1.c:_cmsQuickFloor
Unexecuted instantiation: cmslut.c:_cmsQuickFloor
Unexecuted instantiation: cmsplugin.c:_cmsQuickFloor
Unexecuted instantiation: cmscnvrt.c:_cmsQuickFloor
Unexecuted instantiation: cmsgmt.c:_cmsQuickFloor
Unexecuted instantiation: cmsmtrx.c:_cmsQuickFloor
Unexecuted instantiation: cmspack.c:_cmsQuickFloor
Unexecuted instantiation: cmspcs.c:_cmsQuickFloor
Unexecuted instantiation: cmswtpnt.c:_cmsQuickFloor
Unexecuted instantiation: cmsxform.c:_cmsQuickFloor
Unexecuted instantiation: cmssamp.c:_cmsQuickFloor
Unexecuted instantiation: cmsnamed.c:_cmsQuickFloor
Unexecuted instantiation: cmsvirt.c:_cmsQuickFloor
Unexecuted instantiation: cmstypes.c:_cmsQuickFloor
Unexecuted instantiation: cmsopt.c:_cmsQuickFloor
Unexecuted instantiation: cmshalf.c:_cmsQuickFloor
Unexecuted instantiation: cmsalpha.c:_cmsQuickFloor
180
181
// Fast floor restricted to 0..65535.0
182
cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
183
0
{
184
0
    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
185
0
}
Unexecuted instantiation: cmserr.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsgamma.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsintrp.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsio0.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsio1.c:_cmsQuickFloorWord
Unexecuted instantiation: cmslut.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsplugin.c:_cmsQuickFloorWord
Unexecuted instantiation: cmscnvrt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsgmt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsmtrx.c:_cmsQuickFloorWord
Unexecuted instantiation: cmspack.c:_cmsQuickFloorWord
Unexecuted instantiation: cmspcs.c:_cmsQuickFloorWord
Unexecuted instantiation: cmswtpnt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsxform.c:_cmsQuickFloorWord
Unexecuted instantiation: cmssamp.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsnamed.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsvirt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmstypes.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsopt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmshalf.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsalpha.c:_cmsQuickFloorWord
186
187
// Floor to word, taking care of saturation
188
cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
189
0
{
190
0
    d += 0.5;
191
0
    if (d <= 0) return 0;
192
0
    if (d >= 65535.0) return 0xffff;
193
194
0
    return _cmsQuickFloorWord(d);
195
0
}
Unexecuted instantiation: cmserr.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsgamma.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsintrp.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsio0.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsio1.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmslut.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsplugin.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmscnvrt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsgmt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsmtrx.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmspack.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmspcs.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmswtpnt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsxform.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmssamp.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsnamed.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsvirt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmstypes.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsopt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmshalf.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsalpha.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
52.5k
{
332
52.5k
    return pthread_mutex_lock(m);
333
52.5k
}
cmserr.c:_cmsLockPrimitive
Line
Count
Source
331
52.5k
{
332
52.5k
    return pthread_mutex_lock(m);
333
52.5k
}
Unexecuted instantiation: cmsgamma.c:_cmsLockPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsLockPrimitive
Unexecuted instantiation: cmsio0.c:_cmsLockPrimitive
Unexecuted instantiation: cmsio1.c:_cmsLockPrimitive
Unexecuted instantiation: cmslut.c:_cmsLockPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsLockPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsLockPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsLockPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsLockPrimitive
Unexecuted instantiation: cmspack.c:_cmsLockPrimitive
Unexecuted instantiation: cmspcs.c:_cmsLockPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsLockPrimitive
Unexecuted instantiation: cmsxform.c:_cmsLockPrimitive
Unexecuted instantiation: cmssamp.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
334
335
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
336
52.5k
{
337
52.5k
    return pthread_mutex_unlock(m);
338
52.5k
}
cmserr.c:_cmsUnlockPrimitive
Line
Count
Source
336
52.5k
{
337
52.5k
    return pthread_mutex_unlock(m);
338
52.5k
}
Unexecuted instantiation: cmsgamma.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsio0.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsio1.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmslut.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmspack.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmspcs.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsxform.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmssamp.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
339
    
340
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
341
19.7k
{
342
19.7k
    return pthread_mutex_init(m, NULL);
343
19.7k
}
cmserr.c:_cmsInitMutexPrimitive
Line
Count
Source
341
19.7k
{
342
19.7k
    return pthread_mutex_init(m, NULL);
343
19.7k
}
Unexecuted instantiation: cmsgamma.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsio0.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsio1.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmslut.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmspack.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmspcs.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsxform.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmssamp.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
344
345
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
346
19.7k
{
347
19.7k
    return pthread_mutex_destroy(m);
348
19.7k
}
cmserr.c:_cmsDestroyMutexPrimitive
Line
Count
Source
346
19.7k
{
347
19.7k
    return pthread_mutex_destroy(m);
348
19.7k
}
Unexecuted instantiation: cmsgamma.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsio0.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsio1.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmslut.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmspack.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmspcs.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsxform.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmssamp.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
349
350
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
351
0
{
352
0
    return pthread_mutex_lock(m);
353
0
}
Unexecuted instantiation: cmserr.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsio0.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsio1.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmslut.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmspack.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmspcs.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsxform.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmssamp.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
354
355
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
356
0
{
357
0
    return pthread_mutex_unlock(m);
358
0
}
Unexecuted instantiation: cmserr.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsio0.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsio1.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmslut.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmspack.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmspcs.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsxform.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmssamp.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
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
// ---------------------------------------------------------------------------------------------------------
446
447
// Suballocators. 
448
typedef struct _cmsSubAllocator_chunk_st {
449
450
    cmsUInt8Number* Block;
451
    cmsUInt32Number BlockSize;
452
    cmsUInt32Number Used;
453
454
    struct _cmsSubAllocator_chunk_st* next;
455
456
} _cmsSubAllocator_chunk;
457
458
459
typedef struct {
460
461
    cmsContext ContextID;
462
    _cmsSubAllocator_chunk* h;
463
464
} _cmsSubAllocator;
465
466
467
_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
468
void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
469
void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
470
void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
471
472
// ----------------------------------------------------------------------------------
473
474
// The context clients. 
475
typedef enum {
476
477
    UserPtr,            // User-defined pointer
478
    Logger,
479
    AlarmCodesContext,
480
    AdaptationStateContext, 
481
    MemPlugin,
482
    InterpPlugin,
483
    CurvesPlugin,
484
    FormattersPlugin,
485
    TagTypePlugin,
486
    TagPlugin,
487
    IntentPlugin,
488
    MPEPlugin,
489
    OptimizationPlugin,
490
    TransformPlugin,
491
    MutexPlugin,
492
    ParallelizationPlugin,
493
494
    // Last in list
495
    MemoryClientMax
496
497
} _cmsMemoryClient;
498
499
500
// Container for memory management plug-in.
501
typedef struct {
502
503
    _cmsMallocFnPtrType     MallocPtr;    
504
    _cmsMalloZerocFnPtrType MallocZeroPtr;
505
    _cmsFreeFnPtrType       FreePtr;
506
    _cmsReallocFnPtrType    ReallocPtr;
507
    _cmsCallocFnPtrType     CallocPtr;
508
    _cmsDupFnPtrType        DupPtr;
509
510
} _cmsMemPluginChunkType;
511
512
// Copy memory management function pointers from plug-in to chunk, taking care of missing routines
513
void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
514
515
// Internal structure for context
516
struct _cmsContext_struct {
517
    
518
    struct _cmsContext_struct* Next;  // Points to next context in the new style
519
    _cmsSubAllocator* MemPool;        // The memory pool that stores context data
520
    
521
    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is held in the suballocator.
522
                                      // If NULL, then it reverts to global Context0
523
524
    _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
525
};
526
527
// Returns a pointer to a valid context structure, including the global one if id is zero. 
528
// Verifies the magic number.
529
struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
530
531
// Returns the block assigned to the specific zone. 
532
void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
533
534
535
// Chunks of context memory by plug-in client -------------------------------------------------------
536
537
// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
538
539
// Container for error logger -- not a plug-in
540
typedef struct {
541
542
    cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
543
544
} _cmsLogErrorChunkType;
545
546
// The global Context0 storage for error logger
547
extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
548
549
// Allocate and init error logger container. 
550
void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, 
551
                            const struct _cmsContext_struct* src);
552
553
// Container for alarm codes -- not a plug-in
554
typedef struct {
555
   
556
    cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
557
558
} _cmsAlarmCodesChunkType;
559
560
// The global Context0 storage for alarm codes
561
extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
562
563
// Allocate and init alarm codes container. 
564
void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, 
565
                            const struct _cmsContext_struct* src);
566
567
// Container for adaptation state -- not a plug-in
568
typedef struct {
569
    
570
    cmsFloat64Number  AdaptationState;
571
572
} _cmsAdaptationStateChunkType;
573
574
// The global Context0 storage for adaptation state
575
extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
576
577
// Allocate and init adaptation state container.
578
void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, 
579
                                   const struct _cmsContext_struct* src);
580
581
582
// The global Context0 storage for memory management
583
extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
584
585
// Allocate and init memory management container.
586
void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, 
587
                             const struct _cmsContext_struct* src);
588
589
// Container for interpolation plug-in
590
typedef struct {
591
592
    cmsInterpFnFactory Interpolators;
593
594
} _cmsInterpPluginChunkType;
595
596
// The global Context0 storage for interpolation plug-in
597
extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
598
599
// Allocate and init interpolation container.
600
void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, 
601
                                const struct _cmsContext_struct* src);
602
603
// Container for parametric curves plug-in
604
typedef struct {
605
606
    struct _cmsParametricCurvesCollection_st* ParametricCurves;
607
608
} _cmsCurvesPluginChunkType;
609
610
// The global Context0 storage for tone curves plug-in
611
extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
612
613
// Allocate and init parametric curves container.
614
void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, 
615
                                                      const struct _cmsContext_struct* src);
616
617
// Container for formatters plug-in
618
typedef struct {
619
620
    struct _cms_formatters_factory_list* FactoryList;
621
622
} _cmsFormattersPluginChunkType;
623
624
// The global Context0 storage for formatters plug-in
625
extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
626
627
// Allocate and init formatters container.
628
void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, 
629
                                                       const struct _cmsContext_struct* src);
630
631
// This chunk type is shared by TagType plug-in and MPE Plug-in
632
typedef struct {
633
634
    struct _cmsTagTypeLinkedList_st* TagTypes;
635
636
} _cmsTagTypePluginChunkType;
637
638
639
// The global Context0 storage for tag types plug-in
640
extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
641
642
643
// The global Context0 storage for mult process elements plug-in
644
extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
645
646
// Allocate and init Tag types container.
647
void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, 
648
                                                        const struct _cmsContext_struct* src);
649
// Allocate and init MPE container.
650
void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, 
651
                                                        const struct _cmsContext_struct* src);
652
// Container for tag plug-in
653
typedef struct {
654
   
655
    struct _cmsTagLinkedList_st* Tag;
656
657
} _cmsTagPluginChunkType;
658
659
660
// The global Context0 storage for tag plug-in
661
extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
662
663
// Allocate and init Tag container.
664
void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, 
665
                                                      const struct _cmsContext_struct* src); 
666
667
// Container for intents plug-in
668
typedef struct {
669
670
    struct _cms_intents_list* Intents;
671
672
} _cmsIntentsPluginChunkType;
673
674
675
// The global Context0 storage for intents plug-in
676
extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
677
678
// Allocate and init intents container.
679
void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, 
680
                                                        const struct _cmsContext_struct* src); 
681
682
// Container for optimization plug-in
683
typedef struct {
684
685
    struct _cmsOptimizationCollection_st* OptimizationCollection;
686
687
} _cmsOptimizationPluginChunkType;
688
689
690
// The global Context0 storage for optimizers plug-in
691
extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
692
693
// Allocate and init optimizers container.
694
void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, 
695
                                         const struct _cmsContext_struct* src);
696
697
// Container for transform plug-in
698
typedef struct {
699
700
    struct _cmsTransformCollection_st* TransformCollection;
701
702
} _cmsTransformPluginChunkType;
703
704
// The global Context0 storage for full-transform replacement plug-in
705
extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
706
707
// Allocate and init transform container.
708
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, 
709
                                        const struct _cmsContext_struct* src);
710
711
// Container for mutex plug-in
712
typedef struct {
713
714
    _cmsCreateMutexFnPtrType  CreateMutexPtr;
715
    _cmsDestroyMutexFnPtrType DestroyMutexPtr;
716
    _cmsLockMutexFnPtrType    LockMutexPtr;
717
    _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
718
719
} _cmsMutexPluginChunkType;
720
721
// The global Context0 storage for mutex plug-in
722
extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
723
724
// Allocate and init mutex container.
725
void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, 
726
                                        const struct _cmsContext_struct* src);
727
728
// Container for parallelization plug-in
729
typedef struct {
730
731
    cmsInt32Number      MaxWorkers;       // Number of workers to do as maximum
732
    cmsInt32Number      WorkerFlags;      // reserved
733
    _cmsTransform2Fn    SchedulerFn;      // callback to setup functions 
734
    
735
} _cmsParallelizationPluginChunkType;
736
737
// The global Context0 storage for parallelization plug-in
738
extern  _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk;
739
740
// Allocate parallelization container.
741
void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx,
742
                                         const struct _cmsContext_struct* src);
743
744
745
746
// ----------------------------------------------------------------------------------
747
// MLU internal representation
748
typedef struct {
749
750
    cmsUInt16Number Language;
751
    cmsUInt16Number Country;
752
753
    cmsUInt32Number StrW;       // Offset to current unicode string
754
    cmsUInt32Number Len;        // Length in bytes
755
756
} _cmsMLUentry;
757
758
struct _cms_MLU_struct {
759
760
    cmsContext ContextID;
761
762
    // The directory
763
    cmsUInt32Number  AllocatedEntries;
764
    cmsUInt32Number  UsedEntries;
765
    _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
766
767
    // The Pool
768
    cmsUInt32Number PoolSize;  // The maximum allocated size
769
    cmsUInt32Number PoolUsed;  // The used size
770
    void*  MemPool;            // Pointer to begin of memory pool
771
};
772
773
// Named color list internal representation
774
typedef struct {
775
776
    char Name[cmsMAX_PATH];
777
    cmsUInt16Number PCS[3];
778
    cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
779
780
} _cmsNAMEDCOLOR;
781
782
struct _cms_NAMEDCOLORLIST_struct {
783
784
    cmsUInt32Number nColors;
785
    cmsUInt32Number Allocated;
786
    cmsUInt32Number ColorantCount;
787
788
    char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
789
    char Suffix[33];
790
791
    _cmsNAMEDCOLOR* List;
792
793
    cmsContext ContextID;
794
};
795
796
797
// ----------------------------------------------------------------------------------
798
799
// This is the internal struct holding profile details.
800
801
// Maximum supported tags in a profile
802
14.5k
#define MAX_TABLE_TAG       100
803
804
typedef struct _cms_iccprofile_struct {
805
806
    // I/O handler
807
    cmsIOHANDLER*            IOhandler;
808
809
    // The thread ID
810
    cmsContext               ContextID;
811
812
    // Creation time
813
    struct tm                Created;
814
815
    // Color management module identification
816
    cmsUInt32Number          CMM;
817
818
    // Only most important items found in ICC profiles
819
    cmsUInt32Number          Version;
820
    cmsProfileClassSignature DeviceClass;
821
    cmsColorSpaceSignature   ColorSpace;
822
    cmsColorSpaceSignature   PCS;
823
    cmsUInt32Number          RenderingIntent;
824
825
    cmsPlatformSignature     platform;
826
    cmsUInt32Number          flags;
827
    cmsUInt32Number          manufacturer, model;
828
    cmsUInt64Number          attributes;
829
    cmsUInt32Number          creator;
830
831
    cmsProfileID             ProfileID;
832
833
    // Dictionary
834
    cmsUInt32Number          TagCount;
835
    cmsTagSignature          TagNames[MAX_TABLE_TAG];
836
    cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
837
    cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
838
    cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
839
    cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
840
    void *                   TagPtrs[MAX_TABLE_TAG];
841
    cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
842
                                                                 // depending on profile version, so we keep track of the
843
                                                                 // type handler for each tag in the list.
844
    // Special
845
    cmsBool                  IsWrite;
846
847
    // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
848
    void *                   UsrMutex;
849
850
} _cmsICCPROFILE;
851
852
// IO helpers for profiles
853
cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc);
854
cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
855
int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
856
857
// Tag types
858
cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
859
cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
860
cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
861
862
// Error logging ---------------------------------------------------------------------------------------------------------
863
864
void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
865
866
// Interpolation ---------------------------------------------------------------------------------------------------------
867
868
CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
869
cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
870
CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
871
cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
872
873
// Curves ----------------------------------------------------------------------------------------------------------------
874
875
// This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
876
// In the case of table-based, Eval pointer is set to NULL
877
878
// The gamma function main structure
879
struct _cms_curve_struct {
880
881
    cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
882
883
    cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
884
    cmsCurveSegment*  Segments;      // The segments
885
    cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
886
887
    cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
888
889
    // 16 bit Table-based representation follows
890
    cmsUInt32Number    nEntries;      // Number of table elements
891
    cmsUInt16Number*   Table16;       // The table itself.
892
};
893
894
895
//  Pipelines & Stages ---------------------------------------------------------------------------------------------
896
897
// A single stage
898
struct _cmsStage_struct {
899
900
    cmsContext          ContextID;
901
902
    cmsStageSignature   Type;           // Identifies the stage
903
    cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
904
905
    cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
906
    cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
907
908
    _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
909
    _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
910
    _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
911
912
    // A generic pointer to whatever memory needed by the stage
913
    void*               Data;
914
915
    // Maintains linked list (used internally)
916
    struct _cmsStage_struct* Next;
917
};
918
919
920
// Special Stages (cannot be saved)
921
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
922
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
923
cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID);
924
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
925
cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
926
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
927
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
928
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
929
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
930
cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
931
cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
932
cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID);
933
cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
934
cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
935
936
937
// For curve set only
938
cmsToneCurve**  _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
939
940
struct _cmsPipeline_struct {
941
942
    cmsStage* Elements;                                // Points to elements chain
943
    cmsUInt32Number InputChannels, OutputChannels;
944
945
    // Data & evaluators
946
    void *Data;
947
948
   _cmsPipelineEval16Fn    Eval16Fn;
949
   _cmsPipelineEvalFloatFn EvalFloatFn;
950
   _cmsFreeUserDataFn      FreeDataFn;
951
   _cmsDupUserDataFn       DupDataFn;
952
953
    cmsContext ContextID;            // Environment
954
955
    cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
956
};
957
958
// LUT reading & creation -------------------------------------------------------------------------------------------
959
960
// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
961
// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
962
963
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
964
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
965
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
966
967
// Special values
968
cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
969
cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
970
971
// Profile linker --------------------------------------------------------------------------------------------------
972
973
// Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
974
// compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
975
// after the profile. I.e, BPC[0] refers to connetion between profile(0) and profile(1)
976
cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
977
                              cmsUInt32Number    nProfiles,
978
                              cmsUInt32Number    TheIntents[],
979
                              cmsHPROFILE        hProfiles[],
980
                              cmsBool            BPC[],
981
                              cmsFloat64Number   AdaptationStates[],
982
                              cmsUInt32Number    dwFlags);
983
984
// Sequence --------------------------------------------------------------------------------------------------------
985
986
cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
987
cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
988
cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
989
990
991
// LUT optimization ------------------------------------------------------------------------------------------------
992
993
CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
994
995
CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
996
997
cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
998
                                      cmsUInt16Number **White,
999
                                      cmsUInt16Number **Black,
1000
                                      cmsUInt32Number *nOutputs);
1001
1002
CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
1003
                                      cmsPipeline**    Lut,
1004
                                      cmsUInt32Number  Intent,
1005
                                      cmsUInt32Number* InputFormat,
1006
                                      cmsUInt32Number* OutputFormat,
1007
                                      cmsUInt32Number* dwFlags );
1008
1009
1010
// Hi level LUT building ----------------------------------------------------------------------------------------------
1011
1012
cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
1013
                                              cmsHPROFILE hProfiles[],
1014
                                              cmsBool  BPC[],
1015
                                              cmsUInt32Number Intents[],
1016
                                              cmsFloat64Number AdaptationStates[],
1017
                                              cmsUInt32Number nGamutPCSposition,
1018
                                              cmsHPROFILE hGamut);
1019
1020
1021
// Formatters ------------------------------------------------------------------------------------------------------------
1022
1023
0
#define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
1024
1025
cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
1026
cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
1027
1028
CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
1029
                                                      cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
1030
                                                      cmsFormatterDirection Dir,
1031
                                                      cmsUInt32Number dwFlags);
1032
1033
1034
#ifndef CMS_NO_HALF_SUPPORT 
1035
1036
// Half float
1037
CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1038
CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1039
1040
#endif
1041
1042
// Transform logic ------------------------------------------------------------------------------------------------------
1043
1044
struct _cmstransform_struct;
1045
1046
typedef struct {
1047
1048
    // 1-pixel cache (16 bits only)
1049
    cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1050
    cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1051
1052
} _cmsCACHE;
1053
1054
1055
1056
// Transformation
1057
typedef struct _cmstransform_struct {
1058
1059
    cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1060
1061
    // Points to transform code
1062
    _cmsTransform2Fn xform;
1063
1064
    // Formatters, cannot be embedded into LUT because cache
1065
    cmsFormatter16 FromInput;
1066
    cmsFormatter16 ToOutput;
1067
1068
    cmsFormatterFloat FromInputFloat;
1069
    cmsFormatterFloat ToOutputFloat;
1070
1071
    // 1-pixel cache seed for zero as input (16 bits, read only)
1072
    _cmsCACHE Cache;
1073
1074
    // A Pipeline holding the full (optimized) transform
1075
    cmsPipeline* Lut;
1076
1077
    // A Pipeline holding the gamut check. It goes from the input space to bilevel
1078
    cmsPipeline* GamutCheck;
1079
1080
    // Colorant tables
1081
    cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1082
    cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1083
1084
    // Informational only
1085
    cmsColorSpaceSignature EntryColorSpace;
1086
    cmsColorSpaceSignature ExitColorSpace;
1087
1088
    // White points (informative only)
1089
    cmsCIEXYZ EntryWhitePoint;
1090
    cmsCIEXYZ ExitWhitePoint;
1091
1092
    // Profiles used to create the transform
1093
    cmsSEQ* Sequence;
1094
1095
    cmsUInt32Number  dwOriginalFlags;
1096
    cmsFloat64Number AdaptationState;
1097
1098
    // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1099
    cmsUInt32Number RenderingIntent;
1100
1101
    // An id that uniquely identifies the running context. May be null.
1102
    cmsContext ContextID;
1103
1104
    // A user-defined pointer that can be used to store data for transform plug-ins
1105
    void* UserData;
1106
    _cmsFreeUserDataFn FreeUserData;
1107
1108
    // A way to provide backwards compatibility with full xform plugins
1109
    _cmsTransformFn OldXform;
1110
1111
    // A one-worker transform entry for parallelization 
1112
    _cmsTransform2Fn Worker;
1113
    cmsInt32Number   MaxWorkers;
1114
    cmsUInt32Number  WorkerFlags;
1115
1116
} _cmsTRANSFORM;
1117
1118
// Copies extra channels from input to output if the original flags in the transform structure
1119
// instructs to do so. This function is called on all standard transform functions.
1120
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1121
                             void* out, 
1122
                             cmsUInt32Number PixelsPerLine,
1123
                             cmsUInt32Number LineCount,
1124
                             const cmsStride* Stride);
1125
1126
// -----------------------------------------------------------------------------------------------------------------------
1127
1128
cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1129
                            cmsUInt32Number        nProfiles,
1130
                            cmsUInt32Number        InputFormat,
1131
                            cmsUInt32Number        OutputFormat,
1132
                            const cmsUInt32Number  Intents[],
1133
                            const cmsHPROFILE      hProfiles[],
1134
                            const cmsBool          BPC[],
1135
                            const cmsFloat64Number AdaptationStates[],
1136
                            cmsUInt32Number        dwFlags);
1137
1138
1139
cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1140
                            cmsUInt32Number        nPoints,
1141
                            cmsUInt32Number        nProfiles,
1142
                            const cmsUInt32Number  Intents[],
1143
                            const cmsHPROFILE      hProfiles[],
1144
                            const cmsBool          BPC[],
1145
                            const cmsFloat64Number AdaptationStates[],
1146
                            cmsUInt32Number        dwFlags);
1147
1148
cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1149
1150
cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1151
1152
1153
// thread-safe gettime
1154
cmsBool _cmsGetTime(struct tm* ptr_time);
1155
1156
#define _lcms_internal_H
1157
#endif