Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/lcms2/src/lcms2_internal.h
4391 views
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
#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
# define CMS_PTR_ALIGNMENT sizeof(void *)
66
#endif
67
68
#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
69
70
// Maximum encodeable values in floating point
71
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
72
#define MIN_ENCODEABLE_ab2 (-128.0)
73
#define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
74
#define MIN_ENCODEABLE_ab4 (-128.0)
75
#define MAX_ENCODEABLE_ab4 (127.0)
76
77
// Maximum of channels for internal pipeline evaluation
78
#define MAX_STAGE_CHANNELS 128
79
80
// Unused parameter warning suppression
81
#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
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
126
#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
# define _cmsAssert(a) assert((a))
137
#endif
138
139
//---------------------------------------------------------------------------------
140
141
// Determinant lower than that are assumed zero (used on matrix invert)
142
#define MATRIX_DET_TOLERANCE 0.0001
143
144
//---------------------------------------------------------------------------------
145
146
// Fixed point
147
#define FIXED_TO_INT(x) ((x)>>16)
148
#define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
149
#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
150
151
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
152
cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
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
{
162
#ifdef CMS_DONT_USE_FAST_FLOOR
163
return (int) floor(val);
164
#else
165
const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
166
union {
167
cmsFloat64Number val;
168
int halves[2];
169
} temp;
170
171
temp.val = val + _lcms_double2fixmagic;
172
173
#ifdef CMS_USE_BIG_ENDIAN
174
return temp.halves[1] >> 16;
175
#else
176
return temp.halves[0] >> 16;
177
#endif
178
#endif
179
}
180
181
// Fast floor restricted to 0..65535.0
182
cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
183
{
184
return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
185
}
186
187
// Floor to word, taking care of saturation
188
cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
189
{
190
d += 0.5;
191
if (d <= 0) return 0;
192
if (d >= 65535.0) return 0xffff;
193
194
return _cmsQuickFloorWord(d);
195
}
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
{
332
return pthread_mutex_lock(m);
333
}
334
335
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
336
{
337
return pthread_mutex_unlock(m);
338
}
339
340
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
341
{
342
return pthread_mutex_init(m, NULL);
343
}
344
345
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
346
{
347
return pthread_mutex_destroy(m);
348
}
349
350
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
351
{
352
return pthread_mutex_lock(m);
353
}
354
355
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
356
{
357
return pthread_mutex_unlock(m);
358
}
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
#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
#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
1158
1159