1
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2017 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 #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 #else
116 # if !defined(HAVE_ISINF)
117 # if !defined(isinf)
118 # define isinf(x) (!finite((x)))
119 # endif
120 # endif
121 #endif
122
123 // A fast way to convert from/to 16 <-> 8 bits
124 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
125 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
126
127 // Code analysis is broken on asserts
128 #ifdef _MSC_VER
129 # if (_MSC_VER >= 1500)
130 # define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
131 # else
132 # define _cmsAssert(a) assert((a))
133 # endif
134 #else
135 # define _cmsAssert(a) assert((a))
136 #endif
137
138 //---------------------------------------------------------------------------------
139
140 // Determinant lower than that are assumed zero (used on matrix invert)
141 #define MATRIX_DET_TOLERANCE 0.0001
142
143 //---------------------------------------------------------------------------------
144
145 // Fixed point
146 #define FIXED_TO_INT(x) ((x)>>16)
147 #define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
148 #define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
149
_cmsToFixedDomain(int a)150 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
_cmsFromFixedDomain(cmsS15Fixed16Number a)151 cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
152
153 // -----------------------------------------------------------------------------------------------------------
154
155 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
156 // note than this only works in the range ..-32767...+32767 because
157 // mantissa is interpreted as 15.16 fixed point.
158 // The union is to avoid pointer aliasing overoptimization.
_cmsQuickFloor(cmsFloat64Number val)159 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
160 {
161 #ifdef CMS_DONT_USE_FAST_FLOOR
162 return (int) floor(val);
163 #else
164 const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
165 union {
166 cmsFloat64Number val;
167 int halves[2];
168 } temp;
169
170 temp.val = val + _lcms_double2fixmagic;
171
172 #ifdef CMS_USE_BIG_ENDIAN
173 return temp.halves[1] >> 16;
174 #else
175 return temp.halves[0] >> 16;
176 #endif
177 #endif
178 }
179
180 // Fast floor restricted to 0..65535.0
_cmsQuickFloorWord(cmsFloat64Number d)181 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
182 {
183 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
184 }
185
186 // Floor to word, taking care of saturation
_cmsQuickSaturateWord(cmsFloat64Number d)187 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
188 {
189 d += 0.5;
190 if (d <= 0) return 0;
191 if (d >= 65535.0) return 0xffff;
192
193 return _cmsQuickFloorWord(d);
194 }
195
196 // Test bed entry points---------------------------------------------------------------
197 #define CMSCHECKPOINT CMSAPI
198
199 // Pthread support --------------------------------------------------------------------
200 #ifndef CMS_NO_PTHREADS
201
202 // This is the threading support. Unfortunately, it has to be platform-dependent because
203 // windows does not support pthreads.
204
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 # endif
264 #endif
265
266 #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
267 // If we are building with a version of MSVC smaller
268 // than 1400 (i.e. before VS2005) then we don't have
269 // the InterlockedCompareExchangePointer API, so use
270 // the old version.
271 # ifdef _MSC_VER
272 # if _MSC_VER < 1400
273 # define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
274 # endif
275 # endif
276 #endif
277
278 #ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
279 # define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
280 #else
281 # define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}
282 #endif
283
_cmsLockPrimitive(_cmsMutex * m)284 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
285 {
286 EnterCriticalSection(m);
287 return 0;
288 }
289
_cmsUnlockPrimitive(_cmsMutex * m)290 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
291 {
292 LeaveCriticalSection(m);
293 return 0;
294 }
295
_cmsInitMutexPrimitive(_cmsMutex * m)296 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
297 {
298 InitializeCriticalSection(m);
299 return 0;
300 }
301
_cmsDestroyMutexPrimitive(_cmsMutex * m)302 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
303 {
304 DeleteCriticalSection(m);
305 return 0;
306 }
307
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)308 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
309 {
310 EnterCriticalSection(m);
311 return 0;
312 }
313
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)314 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
315 {
316 LeaveCriticalSection(m);
317 return 0;
318 }
319
320 #else
321
322 // Rest of the wide world
323 #include <pthread.h>
324
325 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
326 typedef pthread_mutex_t _cmsMutex;
327
328
_cmsLockPrimitive(_cmsMutex * m)329 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
330 {
331 return pthread_mutex_lock(m);
332 }
333
_cmsUnlockPrimitive(_cmsMutex * m)334 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
335 {
336 return pthread_mutex_unlock(m);
337 }
338
_cmsInitMutexPrimitive(_cmsMutex * m)339 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
340 {
341 return pthread_mutex_init(m, NULL);
342 }
343
_cmsDestroyMutexPrimitive(_cmsMutex * m)344 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
345 {
346 return pthread_mutex_destroy(m);
347 }
348
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)349 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
350 {
351 return pthread_mutex_lock(m);
352 }
353
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)354 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
355 {
356 return pthread_mutex_unlock(m);
357 }
358
359 #endif
360 #else
361
362 #define CMS_MUTEX_INITIALIZER 0
363 typedef int _cmsMutex;
364
365
_cmsLockPrimitive(_cmsMutex * m)366 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
367 {
368 cmsUNUSED_PARAMETER(m);
369 return 0;
370 }
371
_cmsUnlockPrimitive(_cmsMutex * m)372 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
373 {
374 cmsUNUSED_PARAMETER(m);
375 return 0;
376 }
377
_cmsInitMutexPrimitive(_cmsMutex * m)378 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
379 {
380 cmsUNUSED_PARAMETER(m);
381 return 0;
382 }
383
_cmsDestroyMutexPrimitive(_cmsMutex * m)384 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
385 {
386 cmsUNUSED_PARAMETER(m);
387 return 0;
388 }
389
_cmsEnterCriticalSectionPrimitive(_cmsMutex * m)390 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
391 {
392 cmsUNUSED_PARAMETER(m);
393 return 0;
394 }
395
_cmsLeaveCriticalSectionPrimitive(_cmsMutex * m)396 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
397 {
398 cmsUNUSED_PARAMETER(m);
399 return 0;
400 }
401 #endif
402
403 // Plug-In registration ---------------------------------------------------------------
404
405 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
406 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
407
408 // Memory management
409 cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
410
411 // Interpolation
412 cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
413
414 // Parametric curves
415 cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
416
417 // Formatters management
418 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
419
420 // Tag type management
421 cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
422
423 // Tag management
424 cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
425
426 // Intent management
427 cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
428
429 // Multi Process elements
430 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
431
432 // Optimization
433 cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
434
435 // Transform
436 cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
437
438 // Mutex
439 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
440
441 // ---------------------------------------------------------------------------------------------------------
442
443 // Suballocators.
444 typedef struct _cmsSubAllocator_chunk_st {
445
446 cmsUInt8Number* Block;
447 cmsUInt32Number BlockSize;
448 cmsUInt32Number Used;
449
450 struct _cmsSubAllocator_chunk_st* next;
451
452 } _cmsSubAllocator_chunk;
453
454
455 typedef struct {
456
457 cmsContext ContextID;
458 _cmsSubAllocator_chunk* h;
459
460 } _cmsSubAllocator;
461
462
463 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
464 void _cmsSubAllocDestroy(_cmsSubAllocator* s);
465 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
466 void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
467
468 // ----------------------------------------------------------------------------------
469
470 // The context clients.
471 typedef enum {
472
473 UserPtr, // User-defined pointer
474 Logger,
475 AlarmCodesContext,
476 AdaptationStateContext,
477 MemPlugin,
478 InterpPlugin,
479 CurvesPlugin,
480 FormattersPlugin,
481 TagTypePlugin,
482 TagPlugin,
483 IntentPlugin,
484 MPEPlugin,
485 OptimizationPlugin,
486 TransformPlugin,
487 MutexPlugin,
488
489 // Last in list
490 MemoryClientMax
491
492 } _cmsMemoryClient;
493
494
495 // Container for memory management plug-in.
496 typedef struct {
497
498 _cmsMallocFnPtrType MallocPtr;
499 _cmsMalloZerocFnPtrType MallocZeroPtr;
500 _cmsFreeFnPtrType FreePtr;
501 _cmsReallocFnPtrType ReallocPtr;
502 _cmsCallocFnPtrType CallocPtr;
503 _cmsDupFnPtrType DupPtr;
504
505 } _cmsMemPluginChunkType;
506
507 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
508 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
509
510 // Internal structure for context
511 struct _cmsContext_struct {
512
513 struct _cmsContext_struct* Next; // Points to next context in the new style
514 _cmsSubAllocator* MemPool; // The memory pool that stores context data
515
516 void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
517 // If NULL, then it reverts to global Context0
518
519 _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden
520
521 cmsUInt32Number dwFlags; // Horrid, but safe hack
522 };
523
524 // Returns a pointer to a valid context structure, including the global one if id is zero.
525 // Verifies the magic number.
526 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
527
528 // Returns the block assigned to the specific zone.
529 void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
530
531
532 // Chunks of context memory by plug-in client -------------------------------------------------------
533
534 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
535
536 // Container for error logger -- not a plug-in
537 typedef struct {
538
539 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
540
541 } _cmsLogErrorChunkType;
542
543 // The global Context0 storage for error logger
544 extern _cmsLogErrorChunkType _cmsLogErrorChunk;
545
546 // Allocate and init error logger container.
547 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
548 const struct _cmsContext_struct* src);
549
550 // Container for alarm codes -- not a plug-in
551 typedef struct {
552
553 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
554
555 } _cmsAlarmCodesChunkType;
556
557 // The global Context0 storage for alarm codes
558 extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
559
560 // Allocate and init alarm codes container.
561 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
562 const struct _cmsContext_struct* src);
563
564 // Container for adaptation state -- not a plug-in
565 typedef struct {
566
567 cmsFloat64Number AdaptationState;
568
569 } _cmsAdaptationStateChunkType;
570
571 // The global Context0 storage for adaptation state
572 extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
573
574 // Allocate and init adaptation state container.
575 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
576 const struct _cmsContext_struct* src);
577
578
579 // The global Context0 storage for memory management
580 extern _cmsMemPluginChunkType _cmsMemPluginChunk;
581
582 // Allocate and init memory management container.
583 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
584 const struct _cmsContext_struct* src);
585
586 // Container for interpolation plug-in
587 typedef struct {
588
589 cmsInterpFnFactory Interpolators;
590
591 } _cmsInterpPluginChunkType;
592
593 // The global Context0 storage for interpolation plug-in
594 extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
595
596 // Allocate and init interpolation container.
597 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
598 const struct _cmsContext_struct* src);
599
600 // Container for parametric curves plug-in
601 typedef struct {
602
603 struct _cmsParametricCurvesCollection_st* ParametricCurves;
604
605 } _cmsCurvesPluginChunkType;
606
607 // The global Context0 storage for tone curves plug-in
608 extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
609
610 // Allocate and init parametric curves container.
611 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
612 const struct _cmsContext_struct* src);
613
614 // Container for formatters plug-in
615 typedef struct {
616
617 struct _cms_formatters_factory_list* FactoryList;
618
619 } _cmsFormattersPluginChunkType;
620
621 // The global Context0 storage for formatters plug-in
622 extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
623
624 // Allocate and init formatters container.
625 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
626 const struct _cmsContext_struct* src);
627
628 // This chunk type is shared by TagType plug-in and MPE Plug-in
629 typedef struct {
630
631 struct _cmsTagTypeLinkedList_st* TagTypes;
632
633 } _cmsTagTypePluginChunkType;
634
635
636 // The global Context0 storage for tag types plug-in
637 extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
638
639
640 // The global Context0 storage for mult process elements plug-in
641 extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
642
643 // Allocate and init Tag types container.
644 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
645 const struct _cmsContext_struct* src);
646 // Allocate and init MPE container.
647 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
648 const struct _cmsContext_struct* src);
649 // Container for tag plug-in
650 typedef struct {
651
652 struct _cmsTagLinkedList_st* Tag;
653
654 } _cmsTagPluginChunkType;
655
656
657 // The global Context0 storage for tag plug-in
658 extern _cmsTagPluginChunkType _cmsTagPluginChunk;
659
660 // Allocate and init Tag container.
661 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
662 const struct _cmsContext_struct* src);
663
664 // Container for intents plug-in
665 typedef struct {
666
667 struct _cms_intents_list* Intents;
668
669 } _cmsIntentsPluginChunkType;
670
671
672 // The global Context0 storage for intents plug-in
673 extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
674
675 // Allocate and init intents container.
676 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
677 const struct _cmsContext_struct* src);
678
679 // Container for optimization plug-in
680 typedef struct {
681
682 struct _cmsOptimizationCollection_st* OptimizationCollection;
683
684 } _cmsOptimizationPluginChunkType;
685
686
687 // The global Context0 storage for optimizers plug-in
688 extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
689
690 // Allocate and init optimizers container.
691 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
692 const struct _cmsContext_struct* src);
693
694 // Container for transform plug-in
695 typedef struct {
696
697 struct _cmsTransformCollection_st* TransformCollection;
698
699 } _cmsTransformPluginChunkType;
700
701 // The global Context0 storage for full-transform replacement plug-in
702 extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
703
704 // Allocate and init transform container.
705 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
706 const struct _cmsContext_struct* src);
707
708 // Container for mutex plug-in
709 typedef struct {
710
711 _cmsCreateMutexFnPtrType CreateMutexPtr;
712 _cmsDestroyMutexFnPtrType DestroyMutexPtr;
713 _cmsLockMutexFnPtrType LockMutexPtr;
714 _cmsUnlockMutexFnPtrType UnlockMutexPtr;
715
716 } _cmsMutexPluginChunkType;
717
718 // The global Context0 storage for mutex plug-in
719 extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
720
721 // Allocate and init mutex container.
722 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
723 const struct _cmsContext_struct* src);
724
725 // ----------------------------------------------------------------------------------
726 // MLU internal representation
727 typedef struct {
728
729 cmsUInt16Number Language;
730 cmsUInt16Number Country;
731
732 cmsUInt32Number StrW; // Offset to current unicode string
733 cmsUInt32Number Len; // Length in bytes
734
735 } _cmsMLUentry;
736
737 struct _cms_MLU_struct {
738
739 // The directory
740 cmsUInt32Number AllocatedEntries;
741 cmsUInt32Number UsedEntries;
742 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
743
744 // The Pool
745 cmsUInt32Number PoolSize; // The maximum allocated size
746 cmsUInt32Number PoolUsed; // The used size
747 void* MemPool; // Pointer to begin of memory pool
748 };
749
750 // Named color list internal representation
751 typedef struct {
752
753 char Name[cmsMAX_PATH];
754 cmsUInt16Number PCS[3];
755 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
756
757 } _cmsNAMEDCOLOR;
758
759 struct _cms_NAMEDCOLORLIST_struct {
760
761 cmsUInt32Number nColors;
762 cmsUInt32Number Allocated;
763 cmsUInt32Number ColorantCount;
764
765 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
766 char Suffix[33];
767
768 _cmsNAMEDCOLOR* List;
769 };
770
771
772 // ----------------------------------------------------------------------------------
773
774 // This is the internal struct holding profile details.
775
776 // Maximum supported tags in a profile
777 #define MAX_TABLE_TAG 100
778
779 typedef struct _cms_iccprofile_struct {
780
781 // I/O handler
782 cmsIOHANDLER* IOhandler;
783
784 // Creation time
785 struct tm Created;
786
787 // Only most important items found in ICC profiles
788 cmsUInt32Number Version;
789 cmsProfileClassSignature DeviceClass;
790 cmsColorSpaceSignature ColorSpace;
791 cmsColorSpaceSignature PCS;
792 cmsUInt32Number RenderingIntent;
793
794 cmsUInt32Number flags;
795 cmsUInt32Number manufacturer, model;
796 cmsUInt64Number attributes;
797 cmsUInt32Number creator;
798
799 cmsProfileID ProfileID;
800
801 // Dictionary
802 cmsUInt32Number TagCount;
803 cmsTagSignature TagNames[MAX_TABLE_TAG];
804 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)
805 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
806 cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
807 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
808 void * TagPtrs[MAX_TABLE_TAG];
809 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
810 // depending on profile version, so we keep track of the
811 // type handler for each tag in the list.
812 // Special
813 cmsBool IsWrite;
814
815 // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
816 void * UsrMutex;
817
818 } _cmsICCPROFILE;
819
820 // IO helpers for profiles
821 cmsBool _cmsReadHeader(cmsContext ContextID, _cmsICCPROFILE* Icc);
822 cmsBool _cmsWriteHeader(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
823 int _cmsSearchTag(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
824
825 // Tag types
826 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
827 cmsTagTypeSignature _cmsGetTagTrueType(cmsContext ContextID, cmsHPROFILE hProfile, cmsTagSignature sig);
828 cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
829
830 // Error logging ---------------------------------------------------------------------------------------------------------
831
832 void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
833
834 // Interpolation ---------------------------------------------------------------------------------------------------------
835
836 CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
837 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
838 CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsContext ContextID, cmsInterpParams* p);
839 cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
840
841 // Curves ----------------------------------------------------------------------------------------------------------------
842
843 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
844 // In the case of table-based, Eval pointer is set to NULL
845
846 // The gamma function main structure
847 struct _cms_curve_struct {
848
849 cmsInterpParams* InterpParams; // Private optimizations for interpolation
850
851 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
852 cmsCurveSegment* Segments; // The segments
853 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
854
855 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
856
857 // 16 bit Table-based representation follows
858 cmsUInt32Number nEntries; // Number of table elements
859 cmsUInt16Number* Table16; // The table itself.
860 };
861
862
863 // Pipelines & Stages ---------------------------------------------------------------------------------------------
864
865 // A single stage
866 struct _cmsStage_struct {
867
868 cmsStageSignature Type; // Identifies the stage
869 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
870
871 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
872 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
873
874 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
875 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
876 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
877
878 // A generic pointer to whatever memory needed by the stage
879 void* Data;
880
881 // Maintains linked list (used internally)
882 struct _cmsStage_struct* Next;
883 };
884
885
886 // Special Stages (cannot be saved)
887 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
888 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
889 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
890 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
891 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
892 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
893 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsContext ContextID, cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
894 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
895 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
896 cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
897 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
898 cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
899 cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
900 cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
901
902
903 // For curve set only
904 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
905
906
907 // Pipeline Evaluator (in floating point)
908 typedef void (* _cmsPipelineEvalFloatFn)(cmsContext ContextID, const cmsFloat32Number In[],
909 cmsFloat32Number Out[],
910 const void* Data);
911
912 struct _cmsPipeline_struct {
913
914 cmsStage* Elements; // Points to elements chain
915 cmsUInt32Number InputChannels, OutputChannels;
916
917 // Data & evaluators
918 void *Data;
919
920 _cmsOPTeval16Fn Eval16Fn;
921 _cmsPipelineEvalFloatFn EvalFloatFn;
922 _cmsFreeUserDataFn FreeDataFn;
923 _cmsDupUserDataFn DupDataFn;
924
925 cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
926 };
927
928 // LUT reading & creation -------------------------------------------------------------------------------------------
929
930 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
931 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
932
933 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
934 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
935 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
936
937 // Special values
938 cmsBool _cmsReadMediaWhitePoint(cmsContext ContextID, cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
939 cmsBool _cmsReadCHAD(cmsContext ContextID, cmsMAT3* Dest, cmsHPROFILE hProfile);
940
941 // Profile linker --------------------------------------------------------------------------------------------------
942
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 cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
962
963 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
964 cmsUInt16Number **White,
965 cmsUInt16Number **Black,
966 cmsUInt32Number *nOutputs);
967
968 cmsBool _cmsOptimizePipeline(cmsContext ContextID,
969 cmsPipeline** Lut,
970 cmsUInt32Number Intent,
971 cmsUInt32Number* InputFormat,
972 cmsUInt32Number* OutputFormat,
973 cmsUInt32Number* dwFlags );
974
975 cmsBool _cmsLutIsIdentity(cmsPipeline *PtrLut);
976
977 // Hi level LUT building ----------------------------------------------------------------------------------------------
978
979 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
980 cmsHPROFILE hProfiles[],
981 cmsBool BPC[],
982 cmsUInt32Number Intents[],
983 cmsFloat64Number AdaptationStates[],
984 cmsUInt32Number nGamutPCSposition,
985 cmsHPROFILE hGamut);
986
987
988 // Formatters ------------------------------------------------------------------------------------------------------------
989
990 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
991
992 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
993 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
994
995 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
996 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
997 cmsFormatterDirection Dir,
998 cmsUInt32Number dwFlags);
999
1000
1001 #ifndef CMS_NO_HALF_SUPPORT
1002
1003 // Half float
1004 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1005 CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1006
1007 #endif
1008
1009 // Transform logic ------------------------------------------------------------------------------------------------------
1010
1011 struct _cmstransform_struct;
1012
1013 typedef struct {
1014
1015 // 1-pixel cache (16 bits only)
1016 cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1017 cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1018
1019 } _cmsCACHE;
1020
1021
1022
1023 // Transformation
1024 typedef struct _cmstransform_core {
1025
1026 cmsUInt32Number refs;
1027
1028 // A Pipeline holding the full (optimized) transform
1029 cmsPipeline* Lut;
1030
1031 // A Pipeline holding the gamut check. It goes from the input space to bilevel
1032 cmsPipeline* GamutCheck;
1033
1034 // Colorant tables
1035 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
1036 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
1037
1038 // Informational only
1039 cmsColorSpaceSignature EntryColorSpace;
1040 cmsColorSpaceSignature ExitColorSpace;
1041
1042 // White points (informative only)
1043 cmsCIEXYZ EntryWhitePoint;
1044 cmsCIEXYZ ExitWhitePoint;
1045
1046 // Profiles used to create the transform
1047 cmsSEQ* Sequence;
1048
1049 cmsUInt32Number dwOriginalFlags;
1050 cmsFloat64Number AdaptationState;
1051
1052 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1053 cmsUInt32Number RenderingIntent;
1054
1055 // A user-defined pointer that can be used to store data for transform plug-ins
1056 void* UserData;
1057 _cmsFreeUserDataFn FreeUserData;
1058
1059 } _cmsTRANSFORMCORE;
1060
1061 typedef struct _cmstransform_struct {
1062
1063 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1064
1065 // Points to transform code
1066 _cmsTransform2Fn xform;
1067
1068 // Formatters, cannot be embedded into LUT because cache
1069 cmsFormatter16 FromInput;
1070 cmsFormatter16 ToOutput;
1071
1072 cmsFormatterFloat FromInputFloat;
1073 cmsFormatterFloat ToOutputFloat;
1074
1075 // 1-pixel cache seed for zero as input (16 bits, read only)
1076 _cmsCACHE Cache;
1077
1078 // A way to provide backwards compatibility with full xform plugins
1079 _cmsTransformFn OldXform;
1080
1081 _cmsTRANSFORMCORE *core;
1082 } _cmsTRANSFORM;
1083
1084 // Copies extra channels from input to output if the original flags in the transform structure
1085 // instructs to do so. This function is called on all standard transform functions.
1086 void _cmsHandleExtraChannels(cmsContext ContextID, _cmsTRANSFORM* p, const void* in,
1087 void* out,
1088 cmsUInt32Number PixelsPerLine,
1089 cmsUInt32Number LineCount,
1090 const cmsStride* Stride);
1091
1092 // -----------------------------------------------------------------------------------------------------------------------
1093
1094 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
1095 cmsUInt32Number nProfiles,
1096 cmsUInt32Number InputFormat,
1097 cmsUInt32Number OutputFormat,
1098 const cmsUInt32Number Intents[],
1099 const cmsHPROFILE hProfiles[],
1100 const cmsBool BPC[],
1101 const cmsFloat64Number AdaptationStates[],
1102 cmsUInt32Number dwFlags);
1103
1104
1105 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
1106 cmsUInt32Number nPoints,
1107 cmsUInt32Number nProfiles,
1108 const cmsUInt32Number Intents[],
1109 const cmsHPROFILE hProfiles[],
1110 const cmsBool BPC[],
1111 const cmsFloat64Number AdaptationStates[],
1112 cmsUInt32Number dwFlags);
1113
1114 cmsBool _cmsAdaptationMatrix(cmsContext ContextID, cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1115
1116 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsContext ContextID, cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1117
1118 void _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number flags);
1119
1120 cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta);
1121
1122 #define _lcms_internal_H
1123 #endif
1124