msdasql: Check rowset pointer before assignment in ICommandText::Execute.
[wine.git] / libs / lcms2 / src / lcms2_internal.h
blobafe51d9a4e5e9a7e81785452fd9c658fa9fdaea0
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2023 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:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
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.
24 //---------------------------------------------------------------------------------
27 #ifndef _lcms_internal_H
29 // Include plug-in foundation
30 #ifndef _lcms_plugin_H
31 # include "lcms2_plugin.h"
32 #endif
34 // ctype is part of C99 as per 7.1.2
35 #include <ctype.h>
37 // assert macro is part of C99 as per 7.2
38 #include <assert.h>
40 // Some needed constants
41 #ifndef M_PI
42 # define M_PI 3.14159265358979323846
43 #endif
45 #ifndef M_LOG10E
46 # define M_LOG10E 0.434294481903251827651
47 #endif
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
56 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
57 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
59 // Alignment to memory pointer
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
68 #define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
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)
77 // Maximum of channels for internal pipeline evaluation
78 #define MAX_STAGE_CHANNELS 128
80 // Unused parameter warning suppression
81 #define cmsUNUSED_PARAMETER(x) ((void)x)
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
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
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
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
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
122 #endif
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)
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
139 //---------------------------------------------------------------------------------
141 // Determinant lower than that are assumed zero (used on matrix invert)
142 #define MATRIX_DET_TOLERANCE 0.0001
144 //---------------------------------------------------------------------------------
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)
151 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
152 cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
154 // -----------------------------------------------------------------------------------------------------------
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)
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;
171 temp.val = val + _lcms_double2fixmagic;
173 #ifdef CMS_USE_BIG_ENDIAN
174 return temp.halves[1] >> 16;
175 #else
176 return temp.halves[0] >> 16;
177 #endif
178 #endif
181 // Fast floor restricted to 0..65535.0
182 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
184 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
187 // Floor to word, taking care of saturation
188 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
190 d += 0.5;
191 if (d <= 0) return 0;
192 if (d >= 65535.0) return 0xffff;
194 return _cmsQuickFloorWord(d);
197 // Test bed entry points---------------------------------------------------------------
198 #define CMSCHECKPOINT CMSAPI
200 // Pthread support --------------------------------------------------------------------
201 #ifndef CMS_NO_PTHREADS
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_
207 #define WIN32_LEAN_AND_MEAN 1
208 #include <windows.h>
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.
217 // We can work around this in 2 ways.
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).
225 // 2) In cases where we want to work on pre-Windows XP, we
226 // can use an even more horrible hack described below.
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).
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.
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.
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:
258 typedef CRITICAL_SECTION _cmsMutex;
260 #ifdef _MSC_VER
261 # if (_MSC_VER >= 1800)
262 # pragma warning(disable : 26135)
263 # endif
264 #endif
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
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
284 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
286 EnterCriticalSection(m);
287 return 0;
290 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
292 LeaveCriticalSection(m);
293 return 0;
296 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
298 InitializeCriticalSection(m);
299 return 0;
302 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
304 DeleteCriticalSection(m);
305 return 0;
308 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
310 EnterCriticalSection(m);
311 return 0;
314 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
316 LeaveCriticalSection(m);
317 return 0;
320 #else
322 // Rest of the wide world
323 #include <pthread.h>
325 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
326 typedef pthread_mutex_t _cmsMutex;
329 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
331 return pthread_mutex_lock(m);
334 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
336 return pthread_mutex_unlock(m);
339 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
341 return pthread_mutex_init(m, NULL);
344 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
346 return pthread_mutex_destroy(m);
349 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
351 return pthread_mutex_lock(m);
354 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
356 return pthread_mutex_unlock(m);
359 #endif
360 #else
362 #define CMS_MUTEX_INITIALIZER 0
363 typedef int _cmsMutex;
366 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
368 cmsUNUSED_PARAMETER(m);
369 return 0;
372 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
374 cmsUNUSED_PARAMETER(m);
375 return 0;
378 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
380 cmsUNUSED_PARAMETER(m);
381 return 0;
384 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
386 cmsUNUSED_PARAMETER(m);
387 return 0;
390 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
392 cmsUNUSED_PARAMETER(m);
393 return 0;
396 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
398 cmsUNUSED_PARAMETER(m);
399 return 0;
401 #endif
403 // Plug-In registration ---------------------------------------------------------------
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);
408 // Memory management
409 cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
411 // Interpolation
412 cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
414 // Parametric curves
415 cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
417 // Formatters management
418 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
420 // Tag type management
421 cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
423 // Tag management
424 cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
426 // Intent management
427 cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
429 // Multi Process elements
430 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
432 // Optimization
433 cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
435 // Transform
436 cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
438 // Mutex
439 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
441 // Paralellization
442 cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
444 // ---------------------------------------------------------------------------------------------------------
446 // Suballocators.
447 typedef struct _cmsSubAllocator_chunk_st {
449 cmsUInt8Number* Block;
450 cmsUInt32Number BlockSize;
451 cmsUInt32Number Used;
453 struct _cmsSubAllocator_chunk_st* next;
455 } _cmsSubAllocator_chunk;
458 typedef struct {
460 cmsContext ContextID;
461 _cmsSubAllocator_chunk* h;
463 } _cmsSubAllocator;
466 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
467 void _cmsSubAllocDestroy(_cmsSubAllocator* s);
468 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
469 void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
471 // ----------------------------------------------------------------------------------
473 // The context clients.
474 typedef enum {
476 UserPtr, // User-defined pointer
477 Logger,
478 AlarmCodesContext,
479 AdaptationStateContext,
480 MemPlugin,
481 InterpPlugin,
482 CurvesPlugin,
483 FormattersPlugin,
484 TagTypePlugin,
485 TagPlugin,
486 IntentPlugin,
487 MPEPlugin,
488 OptimizationPlugin,
489 TransformPlugin,
490 MutexPlugin,
491 ParallelizationPlugin,
493 // Last in list
494 MemoryClientMax
496 } _cmsMemoryClient;
499 // Container for memory management plug-in.
500 typedef struct {
502 _cmsMallocFnPtrType MallocPtr;
503 _cmsMalloZerocFnPtrType MallocZeroPtr;
504 _cmsFreeFnPtrType FreePtr;
505 _cmsReallocFnPtrType ReallocPtr;
506 _cmsCallocFnPtrType CallocPtr;
507 _cmsDupFnPtrType DupPtr;
509 } _cmsMemPluginChunkType;
511 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
512 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
514 // Internal structure for context
515 struct _cmsContext_struct {
517 struct _cmsContext_struct* Next; // Points to next context in the new style
518 _cmsSubAllocator* MemPool; // The memory pool that stores context data
520 void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
521 // If NULL, then it reverts to global Context0
523 _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden
526 // Returns a pointer to a valid context structure, including the global one if id is zero.
527 // Verifies the magic number.
528 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
530 // Returns the block assigned to the specific zone.
531 void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
534 // Chunks of context memory by plug-in client -------------------------------------------------------
536 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
538 // Container for error logger -- not a plug-in
539 typedef struct {
541 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
543 } _cmsLogErrorChunkType;
545 // The global Context0 storage for error logger
546 extern _cmsLogErrorChunkType _cmsLogErrorChunk;
548 // Allocate and init error logger container.
549 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
550 const struct _cmsContext_struct* src);
552 // Container for alarm codes -- not a plug-in
553 typedef struct {
555 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
557 } _cmsAlarmCodesChunkType;
559 // The global Context0 storage for alarm codes
560 extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
562 // Allocate and init alarm codes container.
563 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
564 const struct _cmsContext_struct* src);
566 // Container for adaptation state -- not a plug-in
567 typedef struct {
569 cmsFloat64Number AdaptationState;
571 } _cmsAdaptationStateChunkType;
573 // The global Context0 storage for adaptation state
574 extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
576 // Allocate and init adaptation state container.
577 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
578 const struct _cmsContext_struct* src);
581 // The global Context0 storage for memory management
582 extern _cmsMemPluginChunkType _cmsMemPluginChunk;
584 // Allocate and init memory management container.
585 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
586 const struct _cmsContext_struct* src);
588 // Container for interpolation plug-in
589 typedef struct {
591 cmsInterpFnFactory Interpolators;
593 } _cmsInterpPluginChunkType;
595 // The global Context0 storage for interpolation plug-in
596 extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
598 // Allocate and init interpolation container.
599 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
600 const struct _cmsContext_struct* src);
602 // Container for parametric curves plug-in
603 typedef struct {
605 struct _cmsParametricCurvesCollection_st* ParametricCurves;
607 } _cmsCurvesPluginChunkType;
609 // The global Context0 storage for tone curves plug-in
610 extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
612 // Allocate and init parametric curves container.
613 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
614 const struct _cmsContext_struct* src);
616 // Container for formatters plug-in
617 typedef struct {
619 struct _cms_formatters_factory_list* FactoryList;
621 } _cmsFormattersPluginChunkType;
623 // The global Context0 storage for formatters plug-in
624 extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
626 // Allocate and init formatters container.
627 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
628 const struct _cmsContext_struct* src);
630 // This chunk type is shared by TagType plug-in and MPE Plug-in
631 typedef struct {
633 struct _cmsTagTypeLinkedList_st* TagTypes;
635 } _cmsTagTypePluginChunkType;
638 // The global Context0 storage for tag types plug-in
639 extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
642 // The global Context0 storage for mult process elements plug-in
643 extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
645 // Allocate and init Tag types container.
646 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
647 const struct _cmsContext_struct* src);
648 // Allocate and init MPE container.
649 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
650 const struct _cmsContext_struct* src);
651 // Container for tag plug-in
652 typedef struct {
654 struct _cmsTagLinkedList_st* Tag;
656 } _cmsTagPluginChunkType;
659 // The global Context0 storage for tag plug-in
660 extern _cmsTagPluginChunkType _cmsTagPluginChunk;
662 // Allocate and init Tag container.
663 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
664 const struct _cmsContext_struct* src);
666 // Container for intents plug-in
667 typedef struct {
669 struct _cms_intents_list* Intents;
671 } _cmsIntentsPluginChunkType;
674 // The global Context0 storage for intents plug-in
675 extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
677 // Allocate and init intents container.
678 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
679 const struct _cmsContext_struct* src);
681 // Container for optimization plug-in
682 typedef struct {
684 struct _cmsOptimizationCollection_st* OptimizationCollection;
686 } _cmsOptimizationPluginChunkType;
689 // The global Context0 storage for optimizers plug-in
690 extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
692 // Allocate and init optimizers container.
693 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
694 const struct _cmsContext_struct* src);
696 // Container for transform plug-in
697 typedef struct {
699 struct _cmsTransformCollection_st* TransformCollection;
701 } _cmsTransformPluginChunkType;
703 // The global Context0 storage for full-transform replacement plug-in
704 extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
706 // Allocate and init transform container.
707 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
708 const struct _cmsContext_struct* src);
710 // Container for mutex plug-in
711 typedef struct {
713 _cmsCreateMutexFnPtrType CreateMutexPtr;
714 _cmsDestroyMutexFnPtrType DestroyMutexPtr;
715 _cmsLockMutexFnPtrType LockMutexPtr;
716 _cmsUnlockMutexFnPtrType UnlockMutexPtr;
718 } _cmsMutexPluginChunkType;
720 // The global Context0 storage for mutex plug-in
721 extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
723 // Allocate and init mutex container.
724 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
725 const struct _cmsContext_struct* src);
727 // Container for parallelization plug-in
728 typedef struct {
730 cmsInt32Number MaxWorkers; // Number of workers to do as maximum
731 cmsInt32Number WorkerFlags; // reserved
732 _cmsTransform2Fn SchedulerFn; // callback to setup functions
734 } _cmsParallelizationPluginChunkType;
736 // The global Context0 storage for parallelization plug-in
737 extern _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk;
739 // Allocate parallelization container.
740 void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx,
741 const struct _cmsContext_struct* src);
745 // ----------------------------------------------------------------------------------
746 // MLU internal representation
747 typedef struct {
749 cmsUInt16Number Language;
750 cmsUInt16Number Country;
752 cmsUInt32Number StrW; // Offset to current unicode string
753 cmsUInt32Number Len; // Length in bytes
755 } _cmsMLUentry;
757 struct _cms_MLU_struct {
759 cmsContext ContextID;
761 // The directory
762 cmsUInt32Number AllocatedEntries;
763 cmsUInt32Number UsedEntries;
764 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
766 // The Pool
767 cmsUInt32Number PoolSize; // The maximum allocated size
768 cmsUInt32Number PoolUsed; // The used size
769 void* MemPool; // Pointer to begin of memory pool
772 // Named color list internal representation
773 typedef struct {
775 char Name[cmsMAX_PATH];
776 cmsUInt16Number PCS[3];
777 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
779 } _cmsNAMEDCOLOR;
781 struct _cms_NAMEDCOLORLIST_struct {
783 cmsUInt32Number nColors;
784 cmsUInt32Number Allocated;
785 cmsUInt32Number ColorantCount;
787 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
788 char Suffix[33];
790 _cmsNAMEDCOLOR* List;
792 cmsContext ContextID;
796 // ----------------------------------------------------------------------------------
798 // This is the internal struct holding profile details.
800 // Maximum supported tags in a profile
801 #define MAX_TABLE_TAG 100
803 typedef struct _cms_iccprofile_struct {
805 // I/O handler
806 cmsIOHANDLER* IOhandler;
808 // The thread ID
809 cmsContext ContextID;
811 // Creation time
812 struct tm Created;
814 // Only most important items found in ICC profiles
815 cmsUInt32Number Version;
816 cmsProfileClassSignature DeviceClass;
817 cmsColorSpaceSignature ColorSpace;
818 cmsColorSpaceSignature PCS;
819 cmsUInt32Number RenderingIntent;
821 cmsUInt32Number flags;
822 cmsUInt32Number manufacturer, model;
823 cmsUInt64Number attributes;
824 cmsUInt32Number creator;
826 cmsProfileID ProfileID;
828 // Dictionary
829 cmsUInt32Number TagCount;
830 cmsTagSignature TagNames[MAX_TABLE_TAG];
831 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)
832 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
833 cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
834 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
835 void * TagPtrs[MAX_TABLE_TAG];
836 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
837 // depending on profile version, so we keep track of the
838 // type handler for each tag in the list.
839 // Special
840 cmsBool IsWrite;
842 // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
843 void * UsrMutex;
845 } _cmsICCPROFILE;
847 // IO helpers for profiles
848 cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
849 cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
850 int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
852 // Tag types
853 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
854 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
855 cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
857 // Error logging ---------------------------------------------------------------------------------------------------------
859 void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
861 // Interpolation ---------------------------------------------------------------------------------------------------------
863 CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
864 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
865 CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
866 cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
868 // Curves ----------------------------------------------------------------------------------------------------------------
870 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
871 // In the case of table-based, Eval pointer is set to NULL
873 // The gamma function main structure
874 struct _cms_curve_struct {
876 cmsInterpParams* InterpParams; // Private optimizations for interpolation
878 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
879 cmsCurveSegment* Segments; // The segments
880 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
882 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
884 // 16 bit Table-based representation follows
885 cmsUInt32Number nEntries; // Number of table elements
886 cmsUInt16Number* Table16; // The table itself.
890 // Pipelines & Stages ---------------------------------------------------------------------------------------------
892 // A single stage
893 struct _cmsStage_struct {
895 cmsContext ContextID;
897 cmsStageSignature Type; // Identifies the stage
898 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
900 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
901 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
903 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
904 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
905 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
907 // A generic pointer to whatever memory needed by the stage
908 void* Data;
910 // Maintains linked list (used internally)
911 struct _cmsStage_struct* Next;
915 // Special Stages (cannot be saved)
916 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
917 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
918 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
919 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
920 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
921 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
922 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
923 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
924 CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
925 cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
926 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
927 cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
928 cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
929 cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
932 // For curve set only
933 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
935 struct _cmsPipeline_struct {
937 cmsStage* Elements; // Points to elements chain
938 cmsUInt32Number InputChannels, OutputChannels;
940 // Data & evaluators
941 void *Data;
943 _cmsPipelineEval16Fn Eval16Fn;
944 _cmsPipelineEvalFloatFn EvalFloatFn;
945 _cmsFreeUserDataFn FreeDataFn;
946 _cmsDupUserDataFn DupDataFn;
948 cmsContext ContextID; // Environment
950 cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
953 // LUT reading & creation -------------------------------------------------------------------------------------------
955 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
956 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
958 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
959 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
960 CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
962 // Special values
963 cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
964 cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
966 // Profile linker --------------------------------------------------------------------------------------------------
968 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
969 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
970 // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
971 cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
972 cmsUInt32Number nProfiles,
973 cmsUInt32Number TheIntents[],
974 cmsHPROFILE hProfiles[],
975 cmsBool BPC[],
976 cmsFloat64Number AdaptationStates[],
977 cmsUInt32Number dwFlags);
979 // Sequence --------------------------------------------------------------------------------------------------------
981 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
982 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
983 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
986 // LUT optimization ------------------------------------------------------------------------------------------------
988 CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
990 CMSAPI cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
992 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
993 cmsUInt16Number **White,
994 cmsUInt16Number **Black,
995 cmsUInt32Number *nOutputs);
997 CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
998 cmsPipeline** Lut,
999 cmsUInt32Number Intent,
1000 cmsUInt32Number* InputFormat,
1001 cmsUInt32Number* OutputFormat,
1002 cmsUInt32Number* dwFlags );
1005 // Hi level LUT building ----------------------------------------------------------------------------------------------
1007 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
1008 cmsHPROFILE hProfiles[],
1009 cmsBool BPC[],
1010 cmsUInt32Number Intents[],
1011 cmsFloat64Number AdaptationStates[],
1012 cmsUInt32Number nGamutPCSposition,
1013 cmsHPROFILE hGamut);
1016 // Formatters ------------------------------------------------------------------------------------------------------------
1018 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
1020 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
1021 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
1023 CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
1024 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
1025 cmsFormatterDirection Dir,
1026 cmsUInt32Number dwFlags);
1029 #ifndef CMS_NO_HALF_SUPPORT
1031 // Half float
1032 CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
1033 CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
1035 #endif
1037 // Transform logic ------------------------------------------------------------------------------------------------------
1039 struct _cmstransform_struct;
1041 typedef struct {
1043 // 1-pixel cache (16 bits only)
1044 cmsUInt16Number CacheIn[cmsMAXCHANNELS];
1045 cmsUInt16Number CacheOut[cmsMAXCHANNELS];
1047 } _cmsCACHE;
1051 // Transformation
1052 typedef struct _cmstransform_struct {
1054 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
1056 // Points to transform code
1057 _cmsTransform2Fn xform;
1059 // Formatters, cannot be embedded into LUT because cache
1060 cmsFormatter16 FromInput;
1061 cmsFormatter16 ToOutput;
1063 cmsFormatterFloat FromInputFloat;
1064 cmsFormatterFloat ToOutputFloat;
1066 // 1-pixel cache seed for zero as input (16 bits, read only)
1067 _cmsCACHE Cache;
1069 // A Pipeline holding the full (optimized) transform
1070 cmsPipeline* Lut;
1072 // A Pipeline holding the gamut check. It goes from the input space to bilevel
1073 cmsPipeline* GamutCheck;
1075 // Colorant tables
1076 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
1077 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
1079 // Informational only
1080 cmsColorSpaceSignature EntryColorSpace;
1081 cmsColorSpaceSignature ExitColorSpace;
1083 // White points (informative only)
1084 cmsCIEXYZ EntryWhitePoint;
1085 cmsCIEXYZ ExitWhitePoint;
1087 // Profiles used to create the transform
1088 cmsSEQ* Sequence;
1090 cmsUInt32Number dwOriginalFlags;
1091 cmsFloat64Number AdaptationState;
1093 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1094 cmsUInt32Number RenderingIntent;
1096 // An id that uniquely identifies the running context. May be null.
1097 cmsContext ContextID;
1099 // A user-defined pointer that can be used to store data for transform plug-ins
1100 void* UserData;
1101 _cmsFreeUserDataFn FreeUserData;
1103 // A way to provide backwards compatibility with full xform plugins
1104 _cmsTransformFn OldXform;
1106 // A one-worker transform entry for parallelization
1107 _cmsTransform2Fn Worker;
1108 cmsInt32Number MaxWorkers;
1109 cmsUInt32Number WorkerFlags;
1111 } _cmsTRANSFORM;
1113 // Copies extra channels from input to output if the original flags in the transform structure
1114 // instructs to do so. This function is called on all standard transform functions.
1115 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1116 void* out,
1117 cmsUInt32Number PixelsPerLine,
1118 cmsUInt32Number LineCount,
1119 const cmsStride* Stride);
1121 // -----------------------------------------------------------------------------------------------------------------------
1123 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
1124 cmsUInt32Number nProfiles,
1125 cmsUInt32Number InputFormat,
1126 cmsUInt32Number OutputFormat,
1127 const cmsUInt32Number Intents[],
1128 const cmsHPROFILE hProfiles[],
1129 const cmsBool BPC[],
1130 const cmsFloat64Number AdaptationStates[],
1131 cmsUInt32Number dwFlags);
1134 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
1135 cmsUInt32Number nPoints,
1136 cmsUInt32Number nProfiles,
1137 const cmsUInt32Number Intents[],
1138 const cmsHPROFILE hProfiles[],
1139 const cmsBool BPC[],
1140 const cmsFloat64Number AdaptationStates[],
1141 cmsUInt32Number dwFlags);
1143 cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1145 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1148 // thread-safe gettime
1149 cmsBool _cmsGetTime(struct tm* ptr_time);
1151 #define _lcms_internal_H
1152 #endif