3 // Little Color Management System
4 // Copyright (c) 1998-2014 Marti Maria Saguer
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"
34 // ctype is part of C99 as per 7.1.2
37 // assert macro is part of C99 as per 7.2
40 // Some needed constants
42 # define M_PI 3.14159265358979323846
46 # define M_LOG10E 0.434294481903251827651
49 // BorlandC 5.5, VC2003 are broken on that
50 #if defined(__BORLANDC__) || (_MSC_VER < 1400) // 1400 == VC++ 8.0
51 #define sinf(x) (float)sin((float)x)
52 #define sqrtf(x) (float)sqrt((float)x)
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
60 #define _cmsALIGNMEM(x) (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
62 // Maximum encodeable values in floating point
63 #define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
64 #define MIN_ENCODEABLE_ab2 (-128.0)
65 #define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
66 #define MIN_ENCODEABLE_ab4 (-128.0)
67 #define MAX_ENCODEABLE_ab4 (127.0)
69 // Maximum of channels for internal pipeline evaluation
70 #define MAX_STAGE_CHANNELS 128
72 // Unused parameter warning supression
73 #define cmsUNUSED_PARAMETER(x) ((void)x)
75 // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
76 // unfortunately VisualC++ does not conform that
77 #if defined(_MSC_VER) || defined(__BORLANDC__)
78 # define cmsINLINE __inline
80 # define cmsINLINE static inline
83 // Other replacement functions
86 # define snprintf _snprintf
89 # define vsnprintf _vsnprintf
94 // A fast way to convert from/to 16 <-> 8 bits
95 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
96 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
98 // Code analysis is broken on asserts
100 # if (_MSC_VER >= 1500)
101 # define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
103 # define _cmsAssert(a) assert((a))
106 # define _cmsAssert(a) assert((a))
109 //---------------------------------------------------------------------------------
111 // Determinant lower than that are assumed zero (used on matrix invert)
112 #define MATRIX_DET_TOLERANCE 0.0001
114 //---------------------------------------------------------------------------------
117 #define FIXED_TO_INT(x) ((x)>>16)
118 #define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
119 #define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
121 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
122 cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
124 // -----------------------------------------------------------------------------------------------------------
126 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
127 // note than this only works in the range ..-32767...+32767 because
128 // mantissa is interpreted as 15.16 fixed point.
129 // The union is to avoid pointer aliasing overoptimization.
130 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
132 #ifdef CMS_DONT_USE_FAST_FLOOR
133 return (int) floor(val);
135 const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
137 cmsFloat64Number val;
141 temp.val = val + _lcms_double2fixmagic;
143 #ifdef CMS_USE_BIG_ENDIAN
144 return temp.halves[1] >> 16;
146 return temp.halves[0] >> 16;
151 // Fast floor restricted to 0..65535.0
152 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
154 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
157 // Floor to word, taking care of saturation
158 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
161 if (d <= 0) return 0;
162 if (d >= 65535.0) return 0xffff;
164 return _cmsQuickFloorWord(d);
168 // Pthread support --------------------------------------------------------------------
169 #ifndef CMS_NO_PTHREADS
171 // This is the threading support. Unfortunately, it has to be platform-dependent because
172 // windows does not support pthreads.
174 #ifdef CMS_IS_WINDOWS_
176 #define WIN32_LEAN_AND_MEAN 1
180 // From: http://locklessinc.com/articles/pthreads_on_windows/
181 // The pthreads API has an initialization macro that has no correspondence to anything in
182 // the windows API. By investigating the internal definition of the critical section type,
183 // one may work out how to initialize one without calling InitializeCriticalSection().
184 // The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
185 // to allocate a critical section debug object, but if no memory is available, it sets
186 // the pointer to a specific value. (One would expect that value to be NULL, but it is
187 // actually (void *)-1 for some reason.) Thus we can use this special value for that
188 // pointer, and the critical section code will work.
190 // The other important part of the critical section type to initialize is the number
191 // of waiters. This controls whether or not the mutex is locked. Fortunately, this
192 // part of the critical section is unlikely to change. Apparently, many programs
193 // already test critical sections to see if they are locked using this value, so
194 // Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
195 // section, even when they changed the underlying algorithm to be more scalable.
196 // The final parts of the critical section object are unimportant, and can be set
197 // to zero for their defaults. This yields an initialization macro:
199 typedef CRITICAL_SECTION _cmsMutex;
201 #define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
203 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
205 EnterCriticalSection(m);
209 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
211 LeaveCriticalSection(m);
215 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
217 InitializeCriticalSection(m);
221 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
223 DeleteCriticalSection(m);
227 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
229 EnterCriticalSection(m);
233 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
235 LeaveCriticalSection(m);
241 // Rest of the wide world
244 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
245 typedef pthread_mutex_t _cmsMutex;
248 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
250 return pthread_mutex_lock(m);
253 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
255 return pthread_mutex_unlock(m);
258 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
260 return pthread_mutex_init(m, NULL);
263 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
265 return pthread_mutex_destroy(m);
268 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
270 return pthread_mutex_lock(m);
273 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
275 return pthread_mutex_unlock(m);
281 #define CMS_MUTEX_INITIALIZER 0
282 typedef int _cmsMutex;
285 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
288 cmsUNUSED_PARAMETER(m);
291 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
294 cmsUNUSED_PARAMETER(m);
297 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
300 cmsUNUSED_PARAMETER(m);
303 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
306 cmsUNUSED_PARAMETER(m);
309 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
312 cmsUNUSED_PARAMETER(m);
315 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
318 cmsUNUSED_PARAMETER(m);
322 // Plug-In registration ---------------------------------------------------------------
324 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
325 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
328 cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
331 cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
334 cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
336 // Formatters management
337 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
339 // Tag type management
340 cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
343 cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
346 cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
348 // Multi Process elements
349 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
352 cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
355 cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
358 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
360 // ---------------------------------------------------------------------------------------------------------
363 typedef struct _cmsSubAllocator_chunk_st {
365 cmsUInt8Number* Block;
366 cmsUInt32Number BlockSize;
367 cmsUInt32Number Used;
369 struct _cmsSubAllocator_chunk_st* next;
371 } _cmsSubAllocator_chunk;
376 cmsContext ContextID;
377 _cmsSubAllocator_chunk* h;
382 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
383 void _cmsSubAllocDestroy(_cmsSubAllocator* s);
384 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
385 void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
387 // ----------------------------------------------------------------------------------
389 // The context clients.
392 UserPtr, // User-defined pointer
395 AdaptationStateContext,
414 // Container for memory management plug-in.
417 _cmsMallocFnPtrType MallocPtr;
418 _cmsMalloZerocFnPtrType MallocZeroPtr;
419 _cmsFreeFnPtrType FreePtr;
420 _cmsReallocFnPtrType ReallocPtr;
421 _cmsCallocFnPtrType CallocPtr;
422 _cmsDupFnPtrType DupPtr;
424 } _cmsMemPluginChunkType;
426 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
427 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
429 // Internal structure for context
430 struct _cmsContext_struct {
432 struct _cmsContext_struct* Next; // Points to next context in the new style
433 _cmsSubAllocator* MemPool; // The memory pool that stores context data
435 void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
436 // If NULL, then it reverts to global Context0
438 _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden
441 // Returns a pointer to a valid context structure, including the global one if id is zero.
442 // Verifies the magic number.
443 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
445 // Returns the block assigned to the specific zone.
446 void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
449 // Chunks of context memory by plug-in client -------------------------------------------------------
451 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
453 // Container for error logger -- not a plug-in
456 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
458 } _cmsLogErrorChunkType;
460 // The global Context0 storage for error logger
461 extern _cmsLogErrorChunkType _cmsLogErrorChunk;
463 // Allocate and init error logger container.
464 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
465 const struct _cmsContext_struct* src);
467 // Container for alarm codes -- not a plug-in
470 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
472 } _cmsAlarmCodesChunkType;
474 // The global Context0 storage for alarm codes
475 extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
477 // Allocate and init alarm codes container.
478 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
479 const struct _cmsContext_struct* src);
481 // Container for adaptation state -- not a plug-in
484 cmsFloat64Number AdaptationState;
486 } _cmsAdaptationStateChunkType;
488 // The global Context0 storage for adaptation state
489 extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
491 // Allocate and init adaptation state container.
492 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
493 const struct _cmsContext_struct* src);
496 // The global Context0 storage for memory management
497 extern _cmsMemPluginChunkType _cmsMemPluginChunk;
499 // Allocate and init memory management container.
500 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
501 const struct _cmsContext_struct* src);
503 // Container for interpolation plug-in
506 cmsInterpFnFactory Interpolators;
508 } _cmsInterpPluginChunkType;
510 // The global Context0 storage for interpolation plug-in
511 extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
513 // Allocate and init interpolation container.
514 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
515 const struct _cmsContext_struct* src);
517 // Container for parametric curves plug-in
520 struct _cmsParametricCurvesCollection_st* ParametricCurves;
522 } _cmsCurvesPluginChunkType;
524 // The global Context0 storage for tone curves plug-in
525 extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
527 // Allocate and init parametric curves container.
528 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
529 const struct _cmsContext_struct* src);
531 // Container for formatters plug-in
534 struct _cms_formatters_factory_list* FactoryList;
536 } _cmsFormattersPluginChunkType;
538 // The global Context0 storage for formatters plug-in
539 extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
541 // Allocate and init formatters container.
542 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
543 const struct _cmsContext_struct* src);
545 // This chunk type is shared by TagType plug-in and MPE Plug-in
548 struct _cmsTagTypeLinkedList_st* TagTypes;
550 } _cmsTagTypePluginChunkType;
553 // The global Context0 storage for tag types plug-in
554 extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
557 // The global Context0 storage for mult process elements plug-in
558 extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
560 // Allocate and init Tag types container.
561 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
562 const struct _cmsContext_struct* src);
563 // Allocate and init MPE container.
564 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
565 const struct _cmsContext_struct* src);
566 // Container for tag plug-in
569 struct _cmsTagLinkedList_st* Tag;
571 } _cmsTagPluginChunkType;
574 // The global Context0 storage for tag plug-in
575 extern _cmsTagPluginChunkType _cmsTagPluginChunk;
577 // Allocate and init Tag container.
578 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
579 const struct _cmsContext_struct* src);
581 // Container for intents plug-in
584 struct _cms_intents_list* Intents;
586 } _cmsIntentsPluginChunkType;
589 // The global Context0 storage for intents plug-in
590 extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
592 // Allocate and init intents container.
593 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
594 const struct _cmsContext_struct* src);
596 // Container for optimization plug-in
599 struct _cmsOptimizationCollection_st* OptimizationCollection;
601 } _cmsOptimizationPluginChunkType;
604 // The global Context0 storage for optimizers plug-in
605 extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
607 // Allocate and init optimizers container.
608 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
609 const struct _cmsContext_struct* src);
611 // Container for transform plug-in
614 struct _cmsTransformCollection_st* TransformCollection;
616 } _cmsTransformPluginChunkType;
618 // The global Context0 storage for full-transform replacement plug-in
619 extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
621 // Allocate and init transform container.
622 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
623 const struct _cmsContext_struct* src);
625 // Container for mutex plug-in
628 _cmsCreateMutexFnPtrType CreateMutexPtr;
629 _cmsDestroyMutexFnPtrType DestroyMutexPtr;
630 _cmsLockMutexFnPtrType LockMutexPtr;
631 _cmsUnlockMutexFnPtrType UnlockMutexPtr;
633 } _cmsMutexPluginChunkType;
635 // The global Context0 storage for mutex plug-in
636 extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
638 // Allocate and init mutex container.
639 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
640 const struct _cmsContext_struct* src);
642 // ----------------------------------------------------------------------------------
643 // MLU internal representation
646 cmsUInt16Number Language;
647 cmsUInt16Number Country;
649 cmsUInt32Number StrW; // Offset to current unicode string
650 cmsUInt32Number Len; // Length in bytes
654 struct _cms_MLU_struct {
656 cmsContext ContextID;
659 int AllocatedEntries;
661 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
664 cmsUInt32Number PoolSize; // The maximum allocated size
665 cmsUInt32Number PoolUsed; // The used size
666 void* MemPool; // Pointer to begin of memory pool
669 // Named color list internal representation
672 char Name[cmsMAX_PATH];
673 cmsUInt16Number PCS[3];
674 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
678 struct _cms_NAMEDCOLORLIST_struct {
680 cmsUInt32Number nColors;
681 cmsUInt32Number Allocated;
682 cmsUInt32Number ColorantCount;
684 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
687 _cmsNAMEDCOLOR* List;
689 cmsContext ContextID;
693 // ----------------------------------------------------------------------------------
695 // This is the internal struct holding profile details.
697 // Maximum supported tags in a profile
698 #define MAX_TABLE_TAG 100
700 typedef struct _cms_iccprofile_struct {
703 cmsIOHANDLER* IOhandler;
706 cmsContext ContextID;
711 // Only most important items found in ICC profiles
712 cmsUInt32Number Version;
713 cmsProfileClassSignature DeviceClass;
714 cmsColorSpaceSignature ColorSpace;
715 cmsColorSpaceSignature PCS;
716 cmsUInt32Number RenderingIntent;
718 cmsUInt32Number flags;
719 cmsUInt32Number manufacturer, model;
720 cmsUInt64Number attributes;
721 cmsUInt32Number creator;
723 cmsProfileID ProfileID;
726 cmsUInt32Number TagCount;
727 cmsTagSignature TagNames[MAX_TABLE_TAG];
728 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none)
729 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
730 cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
731 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
732 void * TagPtrs[MAX_TABLE_TAG];
733 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
734 // depending on profile version, so we keep track of the
735 // type handler for each tag in the list.
739 // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
744 // IO helpers for profiles
745 cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
746 cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
747 int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
750 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
751 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
752 cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
754 // Error logging ---------------------------------------------------------------------------------------------------------
756 void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
758 // Interpolation ---------------------------------------------------------------------------------------------------------
760 cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
761 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
762 void _cmsFreeInterpParams(cmsInterpParams* p);
763 cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
765 // Curves ----------------------------------------------------------------------------------------------------------------
767 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
768 // In the case of table-based, Eval pointer is set to NULL
770 // The gamma function main structure
771 struct _cms_curve_struct {
773 cmsInterpParams* InterpParams; // Private optimizations for interpolation
775 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
776 cmsCurveSegment* Segments; // The segments
777 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
779 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
781 // 16 bit Table-based representation follows
782 cmsUInt32Number nEntries; // Number of table elements
783 cmsUInt16Number* Table16; // The table itself.
787 // Pipelines & Stages ---------------------------------------------------------------------------------------------
790 struct _cmsStage_struct {
792 cmsContext ContextID;
794 cmsStageSignature Type; // Identifies the stage
795 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
797 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
798 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
800 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
801 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
802 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
804 // A generic pointer to whatever memory needed by the stage
807 // Maintains linked list (used internally)
808 struct _cmsStage_struct* Next;
812 // Special Stages (cannot be saved)
813 cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
814 cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
815 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
816 cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
817 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
818 cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
819 cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
820 cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
821 cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
822 cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
823 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
824 cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
825 cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
827 // For curve set only
828 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
831 // Pipeline Evaluator (in floating point)
832 typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
833 cmsFloat32Number Out[],
836 struct _cmsPipeline_struct {
838 cmsStage* Elements; // Points to elements chain
839 cmsUInt32Number InputChannels, OutputChannels;
844 _cmsOPTeval16Fn Eval16Fn;
845 _cmsPipelineEvalFloatFn EvalFloatFn;
846 _cmsFreeUserDataFn FreeDataFn;
847 _cmsDupUserDataFn DupDataFn;
849 cmsContext ContextID; // Environment
851 cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
854 // LUT reading & creation -------------------------------------------------------------------------------------------
856 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
857 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
859 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
860 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
861 cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
864 cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
865 cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
867 // Profile linker --------------------------------------------------------------------------------------------------
869 cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
870 cmsUInt32Number nProfiles,
871 cmsUInt32Number TheIntents[],
872 cmsHPROFILE hProfiles[],
874 cmsFloat64Number AdaptationStates[],
875 cmsUInt32Number dwFlags);
877 // Sequence --------------------------------------------------------------------------------------------------------
879 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
880 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
881 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
884 // LUT optimization ------------------------------------------------------------------------------------------------
886 cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
887 int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
889 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
890 cmsUInt16Number **White,
891 cmsUInt16Number **Black,
892 cmsUInt32Number *nOutputs);
894 cmsBool _cmsOptimizePipeline(cmsContext ContextID,
897 cmsUInt32Number* InputFormat,
898 cmsUInt32Number* OutputFormat,
899 cmsUInt32Number* dwFlags );
902 // Hi level LUT building ----------------------------------------------------------------------------------------------
904 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
905 cmsHPROFILE hProfiles[],
907 cmsUInt32Number Intents[],
908 cmsFloat64Number AdaptationStates[],
909 cmsUInt32Number nGamutPCSposition,
913 // Formatters ------------------------------------------------------------------------------------------------------------
915 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
917 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
918 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
920 cmsFormatter _cmsGetFormatter(cmsContext ContextID,
921 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
922 cmsFormatterDirection Dir,
923 cmsUInt32Number dwFlags);
926 #ifndef CMS_NO_HALF_SUPPORT
929 cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
930 cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt);
934 // Transform logic ------------------------------------------------------------------------------------------------------
936 struct _cmstransform_struct;
940 // 1-pixel cache (16 bits only)
941 cmsUInt16Number CacheIn[cmsMAXCHANNELS];
942 cmsUInt16Number CacheOut[cmsMAXCHANNELS];
949 typedef struct _cmstransform_struct {
951 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
953 // Points to transform code
954 _cmsTransformFn xform;
956 // Formatters, cannot be embedded into LUT because cache
957 cmsFormatter16 FromInput;
958 cmsFormatter16 ToOutput;
960 cmsFormatterFloat FromInputFloat;
961 cmsFormatterFloat ToOutputFloat;
963 // 1-pixel cache seed for zero as input (16 bits, read only)
966 // A Pipeline holding the full (optimized) transform
969 // A Pipeline holding the gamut check. It goes from the input space to bilevel
970 cmsPipeline* GamutCheck;
973 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
974 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
976 // Informational only
977 cmsColorSpaceSignature EntryColorSpace;
978 cmsColorSpaceSignature ExitColorSpace;
980 // White points (informative only)
981 cmsCIEXYZ EntryWhitePoint;
982 cmsCIEXYZ ExitWhitePoint;
984 // Profiles used to create the transform
987 cmsUInt32Number dwOriginalFlags;
988 cmsFloat64Number AdaptationState;
990 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
991 cmsUInt32Number RenderingIntent;
993 // An id that uniquely identifies the running context. May be null.
994 cmsContext ContextID;
996 // A user-defined pointer that can be used to store data for transform plug-ins
998 _cmsFreeUserDataFn FreeUserData;
1002 // --------------------------------------------------------------------------------------------------
1004 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
1005 cmsUInt32Number nProfiles,
1006 cmsUInt32Number InputFormat,
1007 cmsUInt32Number OutputFormat,
1008 const cmsUInt32Number Intents[],
1009 const cmsHPROFILE hProfiles[],
1010 const cmsBool BPC[],
1011 const cmsFloat64Number AdaptationStates[],
1012 cmsUInt32Number dwFlags);
1015 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
1016 cmsUInt32Number nPoints,
1017 cmsUInt32Number nProfiles,
1018 const cmsUInt32Number Intents[],
1019 const cmsHPROFILE hProfiles[],
1020 const cmsBool BPC[],
1021 const cmsFloat64Number AdaptationStates[],
1022 cmsUInt32Number dwFlags);
1024 cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1026 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1029 #define _lcms_internal_H