Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/lcms2mt/src/lcms2_internal.h
Line
Count
Source (jump to first uncovered line)
1
2
//
3
//  Little Color Management System
4
//  Copyright (c) 1998-2020 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 _lcms2mt_plugin_H
31
#   include "lcms2mt_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
// CMS structures contain pointers or doubles.
62
// Some 32-bit platforms require doubles to be 8 byte aligned.
63
// For greatest flexibility allow the build to specify ptr alignment.
64
#ifndef CMS_PTR_ALIGNMENT
65
# if defined(sparc) || defined(__sparc) || defined(__sparc__) || defined(__EMSCRIPTEN__)
66
#  define CMS_PTR_ALIGNMENT 8
67
# else
68
4.92M
#  define CMS_PTR_ALIGNMENT sizeof(void *)
69
# endif
70
#endif
71
72
2.46M
#define _cmsALIGNMEM(x)  (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
73
74
// Maximum encodeable values in floating point
75
3.83G
#define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0)
76
0
#define MIN_ENCODEABLE_ab2  (-128.0)
77
0
#define MAX_ENCODEABLE_ab2  ((65535.0/256.0) - 128.0)
78
0
#define MIN_ENCODEABLE_ab4  (-128.0)
79
0
#define MAX_ENCODEABLE_ab4  (127.0)
80
81
// Maximum of channels for internal pipeline evaluation
82
1.22M
#define MAX_STAGE_CHANNELS  128
83
84
// Unused parameter warning suppression
85
85.8G
#define cmsUNUSED_PARAMETER(x) ((void)x)
86
87
// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
88
// unfortunately VisualC++ does not conform that
89
#if defined(_MSC_VER) || defined(__BORLANDC__)
90
#   define cmsINLINE __inline
91
#else
92
#   define cmsINLINE static inline
93
#endif
94
95
// Allow signed overflow, we know this is harmless in this particular context
96
#if defined(__clang__)
97
#   define CMS_NO_SANITIZE __attribute__((no_sanitize("signed-integer-overflow")))
98
#else
99
#   define CMS_NO_SANITIZE
100
#endif
101
102
// Other replacement functions
103
#ifdef _MSC_VER
104
# ifndef snprintf
105
#       define snprintf  _snprintf
106
# endif
107
# ifndef vsnprintf
108
#       define vsnprintf  _vsnprintf
109
# endif
110
111
/// Properly define some macros to accommodate
112
/// older MSVC versions.
113
# if defined(_MSC_VER) && _MSC_VER <= 1700
114
        #include <float.h>
115
        #define isnan _isnan
116
        #define isinf(x) (!_finite((x)))
117
# endif
118
119
#if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L)
120
        #if !defined(isinf)
121
        #define isinf(x) (!finite((x)))
122
        #endif
123
#endif
124
125
126
#endif
127
128
// A fast way to convert from/to 16 <-> 8 bits
129
10.1G
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
130
3.31G
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
131
132
// Code analysis is broken on asserts
133
#ifdef _MSC_VER
134
#    if (_MSC_VER >= 1500)
135
#            define _cmsAssert(a)  { assert((a)); __analysis_assume((a)); }
136
#     else
137
#            define _cmsAssert(a)   assert((a))
138
#     endif
139
#else
140
167G
#      define _cmsAssert(a)   assert((a))
141
#endif
142
143
//---------------------------------------------------------------------------------
144
145
// Determinant lower than that are assumed zero (used on matrix invert)
146
105M
#define MATRIX_DET_TOLERANCE    0.0001
147
148
//---------------------------------------------------------------------------------
149
150
// Fixed point
151
77.1G
#define FIXED_TO_INT(x)         ((x)>>16)
152
77.1G
#define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU)
153
64.1G
#define ROUND_FIXED_TO_INT(x)   (((x)+0x8000)>>16)
154
155
100G
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
Unexecuted instantiation: cmserr.c:_cmsToFixedDomain
Unexecuted instantiation: cmsio0.c:_cmsToFixedDomain
Unexecuted instantiation: cmsnamed.c:_cmsToFixedDomain
Unexecuted instantiation: cmspcs.c:_cmsToFixedDomain
Unexecuted instantiation: cmsplugin.c:_cmsToFixedDomain
Unexecuted instantiation: cmstypes.c:_cmsToFixedDomain
Unexecuted instantiation: cmsvirt.c:_cmsToFixedDomain
Unexecuted instantiation: cmswtpnt.c:_cmsToFixedDomain
Unexecuted instantiation: cmsxform.c:_cmsToFixedDomain
Unexecuted instantiation: cmsalpha.c:_cmsToFixedDomain
Unexecuted instantiation: cmscnvrt.c:_cmsToFixedDomain
Unexecuted instantiation: cmsgamma.c:_cmsToFixedDomain
Unexecuted instantiation: cmsgmt.c:_cmsToFixedDomain
Unexecuted instantiation: cmshalf.c:_cmsToFixedDomain
cmsintrp.c:_cmsToFixedDomain
Line
Count
Source
155
100G
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
Unexecuted instantiation: cmsio1.c:_cmsToFixedDomain
Unexecuted instantiation: cmslut.c:_cmsToFixedDomain
Unexecuted instantiation: cmsmtrx.c:_cmsToFixedDomain
Unexecuted instantiation: cmsopt.c:_cmsToFixedDomain
Unexecuted instantiation: cmspack.c:_cmsToFixedDomain
Unexecuted instantiation: cmssamp.c:_cmsToFixedDomain
156
0
cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
Unexecuted instantiation: cmserr.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsio0.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsnamed.c:_cmsFromFixedDomain
Unexecuted instantiation: cmspcs.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsplugin.c:_cmsFromFixedDomain
Unexecuted instantiation: cmstypes.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsvirt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmswtpnt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsxform.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsalpha.c:_cmsFromFixedDomain
Unexecuted instantiation: cmscnvrt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsgamma.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsgmt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmshalf.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsintrp.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsio1.c:_cmsFromFixedDomain
Unexecuted instantiation: cmslut.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsmtrx.c:_cmsFromFixedDomain
Unexecuted instantiation: cmsopt.c:_cmsFromFixedDomain
Unexecuted instantiation: cmspack.c:_cmsFromFixedDomain
Unexecuted instantiation: cmssamp.c:_cmsFromFixedDomain
157
158
// -----------------------------------------------------------------------------------------------------------
159
160
// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
161
// note than this only works in the range ..-32767...+32767 because
162
// mantissa is interpreted as 15.16 fixed point.
163
// The union is to avoid pointer aliasing overoptimization.
164
cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
165
117G
{
166
#ifdef CMS_DONT_USE_FAST_FLOOR
167
    return (int) floor(val);
168
#else
169
117G
    const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
170
117G
    union {
171
117G
        cmsFloat64Number val;
172
117G
        int halves[2];
173
117G
    } temp;
174
175
117G
    temp.val = val + _lcms_double2fixmagic;
176
177
#ifdef CMS_USE_BIG_ENDIAN
178
    return temp.halves[1] >> 16;
179
#else
180
117G
    return temp.halves[0] >> 16;
181
117G
#endif
182
117G
#endif
183
117G
}
Unexecuted instantiation: cmserr.c:_cmsQuickFloor
Unexecuted instantiation: cmsio0.c:_cmsQuickFloor
Unexecuted instantiation: cmsnamed.c:_cmsQuickFloor
Unexecuted instantiation: cmspcs.c:_cmsQuickFloor
Unexecuted instantiation: cmsplugin.c:_cmsQuickFloor
Unexecuted instantiation: cmstypes.c:_cmsQuickFloor
Unexecuted instantiation: cmsvirt.c:_cmsQuickFloor
Unexecuted instantiation: cmswtpnt.c:_cmsQuickFloor
Unexecuted instantiation: cmsxform.c:_cmsQuickFloor
Unexecuted instantiation: cmsalpha.c:_cmsQuickFloor
Unexecuted instantiation: cmscnvrt.c:_cmsQuickFloor
cmsgamma.c:_cmsQuickFloor
Line
Count
Source
165
57.1G
{
166
#ifdef CMS_DONT_USE_FAST_FLOOR
167
    return (int) floor(val);
168
#else
169
57.1G
    const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
170
57.1G
    union {
171
57.1G
        cmsFloat64Number val;
172
57.1G
        int halves[2];
173
57.1G
    } temp;
174
175
57.1G
    temp.val = val + _lcms_double2fixmagic;
176
177
#ifdef CMS_USE_BIG_ENDIAN
178
    return temp.halves[1] >> 16;
179
#else
180
57.1G
    return temp.halves[0] >> 16;
181
57.1G
#endif
182
57.1G
#endif
183
57.1G
}
Unexecuted instantiation: cmsgmt.c:_cmsQuickFloor
Unexecuted instantiation: cmshalf.c:_cmsQuickFloor
Unexecuted instantiation: cmsintrp.c:_cmsQuickFloor
Unexecuted instantiation: cmsio1.c:_cmsQuickFloor
cmslut.c:_cmsQuickFloor
Line
Count
Source
165
43.2G
{
166
#ifdef CMS_DONT_USE_FAST_FLOOR
167
    return (int) floor(val);
168
#else
169
43.2G
    const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
170
43.2G
    union {
171
43.2G
        cmsFloat64Number val;
172
43.2G
        int halves[2];
173
43.2G
    } temp;
174
175
43.2G
    temp.val = val + _lcms_double2fixmagic;
176
177
#ifdef CMS_USE_BIG_ENDIAN
178
    return temp.halves[1] >> 16;
179
#else
180
43.2G
    return temp.halves[0] >> 16;
181
43.2G
#endif
182
43.2G
#endif
183
43.2G
}
Unexecuted instantiation: cmsmtrx.c:_cmsQuickFloor
cmsopt.c:_cmsQuickFloor
Line
Count
Source
165
17.1G
{
166
#ifdef CMS_DONT_USE_FAST_FLOOR
167
    return (int) floor(val);
168
#else
169
17.1G
    const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
170
17.1G
    union {
171
17.1G
        cmsFloat64Number val;
172
17.1G
        int halves[2];
173
17.1G
    } temp;
174
175
17.1G
    temp.val = val + _lcms_double2fixmagic;
176
177
#ifdef CMS_USE_BIG_ENDIAN
178
    return temp.halves[1] >> 16;
179
#else
180
17.1G
    return temp.halves[0] >> 16;
181
17.1G
#endif
182
17.1G
#endif
183
17.1G
}
Unexecuted instantiation: cmspack.c:_cmsQuickFloor
Unexecuted instantiation: cmssamp.c:_cmsQuickFloor
184
185
// Fast floor restricted to 0..65535.0
186
cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
187
117G
{
188
117G
    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
189
117G
}
Unexecuted instantiation: cmserr.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsio0.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsnamed.c:_cmsQuickFloorWord
Unexecuted instantiation: cmspcs.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsplugin.c:_cmsQuickFloorWord
Unexecuted instantiation: cmstypes.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsvirt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmswtpnt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsxform.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsalpha.c:_cmsQuickFloorWord
Unexecuted instantiation: cmscnvrt.c:_cmsQuickFloorWord
cmsgamma.c:_cmsQuickFloorWord
Line
Count
Source
187
57.1G
{
188
57.1G
    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
189
57.1G
}
Unexecuted instantiation: cmsgmt.c:_cmsQuickFloorWord
Unexecuted instantiation: cmshalf.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsintrp.c:_cmsQuickFloorWord
Unexecuted instantiation: cmsio1.c:_cmsQuickFloorWord
cmslut.c:_cmsQuickFloorWord
Line
Count
Source
187
43.2G
{
188
43.2G
    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
189
43.2G
}
Unexecuted instantiation: cmsmtrx.c:_cmsQuickFloorWord
cmsopt.c:_cmsQuickFloorWord
Line
Count
Source
187
17.1G
{
188
17.1G
    return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
189
17.1G
}
Unexecuted instantiation: cmspack.c:_cmsQuickFloorWord
Unexecuted instantiation: cmssamp.c:_cmsQuickFloorWord
190
191
// Floor to word, taking care of saturation
192
cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
193
121G
{
194
121G
    d += 0.5;
195
121G
    if (d <= 0) return 0;
196
120G
    if (d >= 65535.0) return 0xffff;
197
198
117G
    return _cmsQuickFloorWord(d);
199
120G
}
Unexecuted instantiation: cmserr.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsio0.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsnamed.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmspcs.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsplugin.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmstypes.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsvirt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmswtpnt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsxform.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsalpha.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmscnvrt.c:_cmsQuickSaturateWord
cmsgamma.c:_cmsQuickSaturateWord
Line
Count
Source
193
59.1G
{
194
59.1G
    d += 0.5;
195
59.1G
    if (d <= 0) return 0;
196
58.0G
    if (d >= 65535.0) return 0xffff;
197
198
57.1G
    return _cmsQuickFloorWord(d);
199
58.0G
}
Unexecuted instantiation: cmsgmt.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmshalf.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsintrp.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmsio1.c:_cmsQuickSaturateWord
cmslut.c:_cmsQuickSaturateWord
Line
Count
Source
193
44.8G
{
194
44.8G
    d += 0.5;
195
44.8G
    if (d <= 0) return 0;
196
44.8G
    if (d >= 65535.0) return 0xffff;
197
198
43.2G
    return _cmsQuickFloorWord(d);
199
44.8G
}
Unexecuted instantiation: cmsmtrx.c:_cmsQuickSaturateWord
cmsopt.c:_cmsQuickSaturateWord
Line
Count
Source
193
17.5G
{
194
17.5G
    d += 0.5;
195
17.5G
    if (d <= 0) return 0;
196
17.5G
    if (d >= 65535.0) return 0xffff;
197
198
17.1G
    return _cmsQuickFloorWord(d);
199
17.5G
}
Unexecuted instantiation: cmspack.c:_cmsQuickSaturateWord
Unexecuted instantiation: cmssamp.c:_cmsQuickSaturateWord
200
201
// Test bed entry points---------------------------------------------------------------
202
#define CMSCHECKPOINT CMSAPI
203
204
// Pthread support --------------------------------------------------------------------
205
#ifndef CMS_NO_PTHREADS
206
207
// This is the threading support. Unfortunately, it has to be platform-dependent because
208
// windows does not support pthreads.
209
210
#ifdef CMS_IS_WINDOWS_
211
212
#define WIN32_LEAN_AND_MEAN 1
213
#include <windows.h>
214
215
216
// The locking scheme in LCMS requires a single 'top level' mutex
217
// to work. This is actually implemented on Windows as a
218
// CriticalSection, because they are lighter weight. With
219
// pthreads, this is statically inited. Unfortunately, windows
220
// can't officially statically init critical sections.
221
//
222
// We can work around this in 2 ways.
223
//
224
// 1) We can use a proper mutex purely to protect the init
225
// of the CriticalSection. This in turns requires us to protect
226
// the Mutex creation, which we can do using the snappily
227
// named InterlockedCompareExchangePointer API (present on
228
// windows XP and above).
229
//
230
// 2) In cases where we want to work on pre-Windows XP, we
231
// can use an even more horrible hack described below.
232
//
233
// So why wouldn't we always use 2)? Because not calling
234
// the init function for a critical section means it fails
235
// testing with ApplicationVerifier (and presumably similar
236
// tools).
237
//
238
// We therefore default to 1, and people who want to be able
239
// to run on pre-Windows XP boxes can build with:
240
//     CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
241
// defined. This is automatically set for builds using
242
// versions of MSVC that don't have this API available.
243
//
244
// From: http://locklessinc.com/articles/pthreads_on_windows/
245
// The pthreads API has an initialization macro that has no correspondence to anything in
246
// the windows API. By investigating the internal definition of the critical section type,
247
// one may work out how to initialize one without calling InitializeCriticalSection().
248
// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
249
// to allocate a critical section debug object, but if no memory is available, it sets
250
// the pointer to a specific value. (One would expect that value to be NULL, but it is
251
// actually (void *)-1 for some reason.) Thus we can use this special value for that
252
// pointer, and the critical section code will work.
253
254
// The other important part of the critical section type to initialize is the number
255
// of waiters. This controls whether or not the mutex is locked. Fortunately, this
256
// part of the critical section is unlikely to change. Apparently, many programs
257
// already test critical sections to see if they are locked using this value, so
258
// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
259
// section, even when they changed the underlying algorithm to be more scalable.
260
// The final parts of the critical section object are unimportant, and can be set
261
// to zero for their defaults. This yields to an initialization macro:
262
263
typedef CRITICAL_SECTION _cmsMutex;
264
265
#ifdef _MSC_VER
266
#    if (_MSC_VER >= 1800)
267
#          pragma warning(disable : 26135)
268
#    endif
269
#endif
270
271
#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
272
// If we are building with a version of MSVC smaller
273
// than 1400 (i.e. before VS2005) then we don't have
274
// the InterlockedCompareExchangePointer API, so use
275
// the old version.
276
#    ifdef _MSC_VER
277
#       if _MSC_VER < 1400
278
#          define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
279
#       endif
280
#    endif
281
#endif
282
283
#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
284
#      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
285
#else
286
#      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}
287
#endif
288
289
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
290
{
291
  EnterCriticalSection(m);
292
  return 0;
293
}
294
295
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
296
{
297
  LeaveCriticalSection(m);
298
  return 0;
299
}
300
301
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
302
{
303
  InitializeCriticalSection(m);
304
  return 0;
305
}
306
307
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
308
{
309
  DeleteCriticalSection(m);
310
  return 0;
311
}
312
313
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
314
{
315
  EnterCriticalSection(m);
316
  return 0;
317
}
318
319
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
320
{
321
  LeaveCriticalSection(m);
322
  return 0;
323
}
324
325
#else
326
327
// Rest of the wide world
328
#include <pthread.h>
329
330
#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
331
typedef pthread_mutex_t _cmsMutex;
332
333
334
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
335
0
{
336
0
  return pthread_mutex_lock(m);
337
0
}
Unexecuted instantiation: cmserr.c:_cmsLockPrimitive
Unexecuted instantiation: cmsio0.c:_cmsLockPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsLockPrimitive
Unexecuted instantiation: cmspcs.c:_cmsLockPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsLockPrimitive
Unexecuted instantiation: cmstypes.c:_cmsLockPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsLockPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsLockPrimitive
Unexecuted instantiation: cmsxform.c:_cmsLockPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsLockPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsLockPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsLockPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsLockPrimitive
Unexecuted instantiation: cmshalf.c:_cmsLockPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsLockPrimitive
Unexecuted instantiation: cmsio1.c:_cmsLockPrimitive
Unexecuted instantiation: cmslut.c:_cmsLockPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsLockPrimitive
Unexecuted instantiation: cmsopt.c:_cmsLockPrimitive
Unexecuted instantiation: cmspack.c:_cmsLockPrimitive
Unexecuted instantiation: cmssamp.c:_cmsLockPrimitive
338
339
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
340
0
{
341
0
  return pthread_mutex_unlock(m);
342
0
}
Unexecuted instantiation: cmserr.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsio0.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmspcs.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmstypes.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsxform.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmshalf.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsio1.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmslut.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmsopt.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmspack.c:_cmsUnlockPrimitive
Unexecuted instantiation: cmssamp.c:_cmsUnlockPrimitive
343
344
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
345
0
{
346
0
  return pthread_mutex_init(m, NULL);
347
0
}
Unexecuted instantiation: cmserr.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsio0.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmspcs.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmstypes.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsxform.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmshalf.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsio1.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmslut.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmsopt.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmspack.c:_cmsInitMutexPrimitive
Unexecuted instantiation: cmssamp.c:_cmsInitMutexPrimitive
348
349
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
350
0
{
351
0
  return pthread_mutex_destroy(m);
352
0
}
Unexecuted instantiation: cmserr.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsio0.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmspcs.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsplugin.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmstypes.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsxform.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmshalf.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsio1.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmslut.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmsopt.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmspack.c:_cmsDestroyMutexPrimitive
Unexecuted instantiation: cmssamp.c:_cmsDestroyMutexPrimitive
353
354
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
355
1.05G
{
356
1.05G
  return pthread_mutex_lock(m);
357
1.05G
}
Unexecuted instantiation: cmserr.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsio0.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmspcs.c:_cmsEnterCriticalSectionPrimitive
cmsplugin.c:_cmsEnterCriticalSectionPrimitive
Line
Count
Source
355
1.05G
{
356
1.05G
  return pthread_mutex_lock(m);
357
1.05G
}
Unexecuted instantiation: cmstypes.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsxform.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmshalf.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsio1.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmslut.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmsopt.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmspack.c:_cmsEnterCriticalSectionPrimitive
Unexecuted instantiation: cmssamp.c:_cmsEnterCriticalSectionPrimitive
358
359
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
360
1.05G
{
361
1.05G
  return pthread_mutex_unlock(m);
362
1.05G
}
Unexecuted instantiation: cmserr.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsio0.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsnamed.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmspcs.c:_cmsLeaveCriticalSectionPrimitive
cmsplugin.c:_cmsLeaveCriticalSectionPrimitive
Line
Count
Source
360
1.05G
{
361
1.05G
  return pthread_mutex_unlock(m);
362
1.05G
}
Unexecuted instantiation: cmstypes.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsvirt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmswtpnt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsxform.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsalpha.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmscnvrt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsgamma.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsgmt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmshalf.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsintrp.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsio1.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmslut.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsmtrx.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmsopt.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmspack.c:_cmsLeaveCriticalSectionPrimitive
Unexecuted instantiation: cmssamp.c:_cmsLeaveCriticalSectionPrimitive
363
364
#endif
365
#else
366
367
#define CMS_MUTEX_INITIALIZER 0
368
typedef int _cmsMutex;
369
370
371
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
372
{
373
    cmsUNUSED_PARAMETER(m);
374
  return 0;
375
}
376
377
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
378
{
379
    cmsUNUSED_PARAMETER(m);
380
  return 0;
381
}
382
383
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
384
{
385
    cmsUNUSED_PARAMETER(m);
386
  return 0;
387
}
388
389
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
390
{
391
    cmsUNUSED_PARAMETER(m);
392
  return 0;
393
}
394
395
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
396
{
397
    cmsUNUSED_PARAMETER(m);
398
  return 0;
399
}
400
401
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
402
{
403
    cmsUNUSED_PARAMETER(m);
404
  return 0;
405
}
406
#endif
407
408
// Plug-In registration ---------------------------------------------------------------
409
410
// Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
411
void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
412
413
// Memory management
414
cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
415
416
// Interpolation
417
cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
418
419
// Parametric curves
420
cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
421
422
// Formatters management
423
cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
424
425
// Tag type management
426
cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
427
428
// Tag management
429
cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
430
431
// Intent management
432
cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
433
434
// Multi Process elements
435
cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
436
437
// Optimization
438
cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
439
440
// Transform
441
cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
442
443
// Mutex
444
cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
445
446
// ---------------------------------------------------------------------------------------------------------
447
448
// Suballocators.
449
typedef struct _cmsSubAllocator_chunk_st {
450
451
    cmsUInt8Number* Block;
452
    cmsUInt32Number BlockSize;
453
    cmsUInt32Number Used;
454
455
    struct _cmsSubAllocator_chunk_st* next;
456
457
} _cmsSubAllocator_chunk;
458
459
460
typedef struct {
461
462
    cmsContext ContextID;
463
    _cmsSubAllocator_chunk* h;
464
465
} _cmsSubAllocator;
466
467
468
_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
469
void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
470
void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
471
void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
472
473
// ----------------------------------------------------------------------------------
474
475
// The context clients.
476
typedef enum {
477
478
    UserPtr,            // User-defined pointer
479
    Logger,
480
    AlarmCodesContext,
481
    AdaptationStateContext,
482
    MemPlugin,
483
    InterpPlugin,
484
    CurvesPlugin,
485
    FormattersPlugin,
486
    TagTypePlugin,
487
    TagPlugin,
488
    IntentPlugin,
489
    MPEPlugin,
490
    OptimizationPlugin,
491
    TransformPlugin,
492
    MutexPlugin,
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 hold 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
// ----------------------------------------------------------------------------------
729
// MLU internal representation
730
typedef struct {
731
732
    cmsUInt16Number Language;
733
    cmsUInt16Number Country;
734
735
    cmsUInt32Number StrW;       // Offset to current unicode string
736
    cmsUInt32Number Len;        // Length in bytes
737
738
} _cmsMLUentry;
739
740
struct _cms_MLU_struct {
741
742
    // The directory
743
    cmsUInt32Number  AllocatedEntries;
744
    cmsUInt32Number  UsedEntries;
745
    _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
746
747
    // The Pool
748
    cmsUInt32Number PoolSize;  // The maximum allocated size
749
    cmsUInt32Number PoolUsed;  // The used size
750
    void*  MemPool;            // Pointer to begin of memory pool
751
};
752
753
// Named color list internal representation
754
typedef struct {
755
756
    char Name[cmsMAX_PATH];
757
    cmsUInt16Number PCS[3];
758
    cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
759
760
} _cmsNAMEDCOLOR;
761
762
struct _cms_NAMEDCOLORLIST_struct {
763
764
    cmsUInt32Number nColors;
765
    cmsUInt32Number Allocated;
766
    cmsUInt32Number ColorantCount;
767
768
    char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
769
    char Suffix[33];
770
771
    _cmsNAMEDCOLOR* List;
772
};
773
774
775
// ----------------------------------------------------------------------------------
776
777
// This is the internal struct holding profile details.
778
779
// Maximum supported tags in a profile
780
8.57M
#define MAX_TABLE_TAG       100
781
782
typedef struct _cms_iccprofile_struct {
783
784
    // I/O handler
785
    cmsIOHANDLER*            IOhandler;
786
787
    // Creation time
788
    struct tm                Created;
789
790
    // Only most important items found in ICC profiles
791
    cmsUInt32Number          Version;
792
    cmsProfileClassSignature DeviceClass;
793
    cmsColorSpaceSignature   ColorSpace;
794
    cmsColorSpaceSignature   PCS;
795
    cmsUInt32Number          RenderingIntent;
796
797
    cmsUInt32Number          flags;
798
    cmsUInt32Number          manufacturer, model;
799
    cmsUInt64Number          attributes;
800
    cmsUInt32Number          creator;
801
802
    cmsProfileID             ProfileID;
803
804
    // Dictionary
805
    cmsUInt32Number          TagCount;
806
    cmsTagSignature          TagNames[MAX_TABLE_TAG];
807
    cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
808
    cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
809
    cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
810
    cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
811
    void *                   TagPtrs[MAX_TABLE_TAG];
812
    cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
813
                                                                 // depending on profile version, so we keep track of the
814
                                                                 // type handler for each tag in the list.
815
    // Special
816
    cmsBool                  IsWrite;
817
818
    // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
819
    void *                   UsrMutex;
820
821
} _cmsICCPROFILE;
822
823
// IO helpers for profiles
824
cmsBool              _cmsReadHeader(cmsContext ContextID, _cmsICCPROFILE* Icc);
825
cmsBool              _cmsWriteHeader(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
826
int                  _cmsSearchTag(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
827
828
// Tag types
829
cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
830
cmsTagTypeSignature  _cmsGetTagTrueType(cmsContext ContextID, cmsHPROFILE hProfile, cmsTagSignature sig);
831
cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
832
833
// Error logging ---------------------------------------------------------------------------------------------------------
834
835
void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
836
837
// Interpolation ---------------------------------------------------------------------------------------------------------
838
839
CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
840
cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
841
CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsContext ContextID, cmsInterpParams* p);
842
cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
843
844
// Curves ----------------------------------------------------------------------------------------------------------------
845
846
// This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
847
// In the case of table-based, Eval pointer is set to NULL
848
849
// The gamma function main structure
850
struct _cms_curve_struct {
851
852
    cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
853
854
    cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
855
    cmsCurveSegment*  Segments;      // The segments
856
    cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
857
858
    cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
859
860
    // 16 bit Table-based representation follows
861
    cmsUInt32Number    nEntries;      // Number of table elements
862
    cmsUInt16Number*   Table16;       // The table itself.
863
};
864
865
866
//  Pipelines & Stages ---------------------------------------------------------------------------------------------
867
868
// A single stage
869
struct _cmsStage_struct {
870
871
    cmsStageSignature   Type;           // Identifies the stage
872
    cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
873
874
    cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
875
    cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
876
877
    _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
878
    _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
879
    _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
880
881
    // A generic pointer to whatever memory needed by the stage
882
    void*               Data;
883
884
    // Maintains linked list (used internally)
885
    struct _cmsStage_struct* Next;
886
};
887
888
889
// Special Stages (cannot be saved)
890
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
891
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
892
cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID);
893
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
894
cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
895
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
896
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsContext ContextID, cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
897
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
898
CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
899
cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
900
cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
901
cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID);
902
cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
903
cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
904
905
906
// For curve set only
907
cmsToneCurve**  _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
908
909
struct _cmsPipeline_struct {
910
911
    cmsStage* Elements;                                // Points to elements chain
912
    cmsUInt32Number InputChannels, OutputChannels;
913
914
    // Data & evaluators
915
    void *Data;
916
917
   _cmsPipelineEval16Fn    Eval16Fn;
918
   _cmsPipelineEvalFloatFn EvalFloatFn;
919
   _cmsFreeUserDataFn      FreeDataFn;
920
   _cmsDupUserDataFn       DupDataFn;
921
922
    cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
923
};
924
925
// LUT reading & creation -------------------------------------------------------------------------------------------
926
927
// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
928
// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
929
930
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
931
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
932
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
933
934
// Special values
935
cmsBool           _cmsReadMediaWhitePoint(cmsContext ContextID, cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
936
cmsBool           _cmsReadCHAD(cmsContext ContextID, cmsMAT3* Dest, cmsHPROFILE hProfile);
937
938
// Profile linker --------------------------------------------------------------------------------------------------
939
940
// Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
941
// compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
942
// after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
943
cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
944
                              cmsUInt32Number    nProfiles,
945
                              cmsUInt32Number    TheIntents[],
946
                              cmsHPROFILE        hProfiles[],
947
                              cmsBool            BPC[],
948
                              cmsFloat64Number   AdaptationStates[],
949
                              cmsUInt32Number    dwFlags);
950
951
// Sequence --------------------------------------------------------------------------------------------------------
952
953
cmsSEQ* _cmsReadProfileSequence(cmsContext ContextID, cmsHPROFILE hProfile);
954
cmsBool _cmsWriteProfileSequence(cmsContext ContextID, cmsHPROFILE hProfile, const cmsSEQ* seq);
955
cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
956
957
958
// LUT optimization ------------------------------------------------------------------------------------------------
959
960
CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
961
962
CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
963
964
cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
965
                                      cmsUInt16Number **White,
966
                                      cmsUInt16Number **Black,
967
                                      cmsUInt32Number *nOutputs);
968
969
CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
970
                                      cmsPipeline**    Lut,
971
                                      cmsUInt32Number  Intent,
972
                                      cmsUInt32Number* InputFormat,
973
                                      cmsUInt32Number* OutputFormat,
974
                                      cmsUInt32Number* dwFlags );
975
976
cmsBool _cmsLutIsIdentity(cmsPipeline *PtrLut);
977
978
// Hi level LUT building ----------------------------------------------------------------------------------------------
979
980
cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
981
                                              cmsHPROFILE hProfiles[],
982
                                              cmsBool  BPC[],
983
                                              cmsUInt32Number Intents[],
984
                                              cmsFloat64Number AdaptationStates[],
985
                                              cmsUInt32Number nGamutPCSposition,
986
                                              cmsHPROFILE hGamut);
987
988
989
// Formatters ------------------------------------------------------------------------------------------------------------
990
991
1.25M
#define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
992
993
cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
994
cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
995
996
CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
997
                                                      cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
998
                                                      cmsFormatterDirection Dir,
999
                                                      cmsUInt32Number dwFlags);
1000
1001
1002
#ifndef CMS_NO_HALF_SUPPORT
1003
1004
// Half float
1005
CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1006
CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1007
1008
#endif
1009
1010
// Transform logic ------------------------------------------------------------------------------------------------------
1011
1012
struct _cmstransform_struct;
1013
1014
typedef struct {
1015
1016
    // 1-pixel cache (16 bits only)
1017
    cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1018
    cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1019
1020
} _cmsCACHE;
1021
1022
1023
1024
// Transformation
1025
typedef struct _cmstransform_core {
1026
1027
    cmsUInt32Number refs;
1028
1029
    // A Pipeline holding the full (optimized) transform
1030
    cmsPipeline* Lut;
1031
1032
    // A Pipeline holding the gamut check. It goes from the input space to bilevel
1033
    cmsPipeline* GamutCheck;
1034
1035
    // Colorant tables
1036
    cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
1037
    cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
1038
1039
    // Informational only
1040
    cmsColorSpaceSignature EntryColorSpace;
1041
    cmsColorSpaceSignature ExitColorSpace;
1042
1043
    // White points (informative only)
1044
    cmsCIEXYZ EntryWhitePoint;
1045
    cmsCIEXYZ ExitWhitePoint;
1046
1047
    // Profiles used to create the transform
1048
    cmsSEQ* Sequence;
1049
1050
    cmsUInt32Number  dwOriginalFlags;
1051
    cmsFloat64Number AdaptationState;
1052
1053
    // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1054
    cmsUInt32Number RenderingIntent;
1055
1056
    // A user-defined pointer that can be used to store data for transform plug-ins
1057
    void* UserData;
1058
    _cmsFreeUserDataFn FreeUserData;
1059
1060
} _cmsTRANSFORMCORE;
1061
1062
typedef struct _cmstransform_struct {
1063
1064
    cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1065
1066
    // Points to transform code
1067
    _cmsTransform2Fn xform;
1068
1069
    // Formatters, cannot be embedded into LUT because cache
1070
    cmsFormatter16 FromInput;
1071
    cmsFormatter16 ToOutput;
1072
1073
    cmsFormatterFloat FromInputFloat;
1074
    cmsFormatterFloat ToOutputFloat;
1075
1076
    // 1-pixel cache seed for zero as input (16 bits, read only)
1077
    _cmsCACHE Cache;
1078
1079
    // A way to provide backwards compatibility with full xform plugins
1080
    _cmsTransformFn OldXform;
1081
1082
    _cmsTRANSFORMCORE *core;
1083
} _cmsTRANSFORM;
1084
1085
// Copies extra channels from input to output if the original flags in the transform structure
1086
// instructs to do so. This function is called on all standard transform functions.
1087
void _cmsHandleExtraChannels(cmsContext ContextID, _cmsTRANSFORM* p, const void* in,
1088
                             void* out,
1089
                             cmsUInt32Number PixelsPerLine,
1090
                             cmsUInt32Number LineCount,
1091
                             const cmsStride* Stride);
1092
1093
// -----------------------------------------------------------------------------------------------------------------------
1094
1095
cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
1096
                            cmsUInt32Number        nProfiles,
1097
                            cmsUInt32Number        InputFormat,
1098
                            cmsUInt32Number        OutputFormat,
1099
                            const cmsUInt32Number  Intents[],
1100
                            const cmsHPROFILE      hProfiles[],
1101
                            const cmsBool          BPC[],
1102
                            const cmsFloat64Number AdaptationStates[],
1103
                            cmsUInt32Number        dwFlags);
1104
1105
1106
cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
1107
                            cmsUInt32Number        nPoints,
1108
                            cmsUInt32Number        nProfiles,
1109
                            const cmsUInt32Number  Intents[],
1110
                            const cmsHPROFILE      hProfiles[],
1111
                            const cmsBool          BPC[],
1112
                            const cmsFloat64Number AdaptationStates[],
1113
                            cmsUInt32Number        dwFlags);
1114
1115
cmsBool   _cmsAdaptationMatrix(cmsContext ContextID, cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1116
1117
cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsContext ContextID, cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1118
1119
void _cmsFindFormatter(cmsContext ContextID, _cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number flags);
1120
1121
cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta);
1122
1123
// thread-safe gettime
1124
cmsBool _cmsGetTime(struct tm* ptr_time);
1125
1126
#define _lcms_internal_H
1127
#endif