3 // Little Color Management System
4 // Copyright (c) 1998-2016 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
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 *)
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 supression
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
88 # define cmsINLINE static inline
91 // Other replacement functions
94 # define snprintf _snprintf
97 # define vsnprintf _vsnprintf
102 // A fast way to convert from/to 16 <-> 8 bits
103 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
104 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
106 // Code analysis is broken on asserts
108 # if (_MSC_VER >= 1500)
109 # define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
111 # define _cmsAssert(a) assert((a))
114 # define _cmsAssert(a) assert((a))
117 //---------------------------------------------------------------------------------
119 // Determinant lower than that are assumed zero (used on matrix invert)
120 #define MATRIX_DET_TOLERANCE 0.0001
122 //---------------------------------------------------------------------------------
125 #define FIXED_TO_INT(x) ((x)>>16)
126 #define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
127 #define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
129 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
130 cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
132 // -----------------------------------------------------------------------------------------------------------
134 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
135 // note than this only works in the range ..-32767...+32767 because
136 // mantissa is interpreted as 15.16 fixed point.
137 // The union is to avoid pointer aliasing overoptimization.
138 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
140 #ifdef CMS_DONT_USE_FAST_FLOOR
141 return (int) floor(val);
143 const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
145 cmsFloat64Number val;
149 temp.val = val + _lcms_double2fixmagic;
151 #ifdef CMS_USE_BIG_ENDIAN
152 return temp.halves[1] >> 16;
154 return temp.halves[0] >> 16;
159 // Fast floor restricted to 0..65535.0
160 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
162 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
165 // Floor to word, taking care of saturation
166 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
169 if (d <= 0) return 0;
170 if (d >= 65535.0) return 0xffff;
172 return _cmsQuickFloorWord(d);
176 // Pthread support --------------------------------------------------------------------
177 #ifndef CMS_NO_PTHREADS
179 // This is the threading support. Unfortunately, it has to be platform-dependent because
180 // windows does not support pthreads.
182 #ifdef CMS_IS_WINDOWS_
184 #define WIN32_LEAN_AND_MEAN 1
188 // From: http://locklessinc.com/articles/pthreads_on_windows/
189 // The pthreads API has an initialization macro that has no correspondence to anything in
190 // the windows API. By investigating the internal definition of the critical section type,
191 // one may work out how to initialize one without calling InitializeCriticalSection().
192 // The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
193 // to allocate a critical section debug object, but if no memory is available, it sets
194 // the pointer to a specific value. (One would expect that value to be NULL, but it is
195 // actually (void *)-1 for some reason.) Thus we can use this special value for that
196 // pointer, and the critical section code will work.
198 // The other important part of the critical section type to initialize is the number
199 // of waiters. This controls whether or not the mutex is locked. Fortunately, this
200 // part of the critical section is unlikely to change. Apparently, many programs
201 // already test critical sections to see if they are locked using this value, so
202 // Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
203 // section, even when they changed the underlying algorithm to be more scalable.
204 // The final parts of the critical section object are unimportant, and can be set
205 // to zero for their defaults. This yields to an initialization macro:
207 typedef CRITICAL_SECTION _cmsMutex;
209 #define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
212 # if (_MSC_VER >= 1800)
213 # pragma warning(disable : 26135)
217 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
219 EnterCriticalSection(m);
223 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
225 LeaveCriticalSection(m);
229 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
231 InitializeCriticalSection(m);
235 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
237 DeleteCriticalSection(m);
241 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
243 EnterCriticalSection(m);
247 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
249 LeaveCriticalSection(m);
255 // Rest of the wide world
258 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
259 typedef pthread_mutex_t _cmsMutex;
262 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
264 return pthread_mutex_lock(m);
267 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
269 return pthread_mutex_unlock(m);
272 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
274 return pthread_mutex_init(m, NULL);
277 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
279 return pthread_mutex_destroy(m);
282 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
284 return pthread_mutex_lock(m);
287 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
289 return pthread_mutex_unlock(m);
295 #define CMS_MUTEX_INITIALIZER 0
296 typedef int _cmsMutex;
299 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
301 cmsUNUSED_PARAMETER(m);
305 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
307 cmsUNUSED_PARAMETER(m);
311 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
313 cmsUNUSED_PARAMETER(m);
317 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
319 cmsUNUSED_PARAMETER(m);
323 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
325 cmsUNUSED_PARAMETER(m);
329 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
331 cmsUNUSED_PARAMETER(m);
336 // Plug-In registration ---------------------------------------------------------------
338 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
339 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
342 cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
345 cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
348 cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
350 // Formatters management
351 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
353 // Tag type management
354 cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
357 cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
360 cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
362 // Multi Process elements
363 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
366 cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
369 cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
372 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
374 // ---------------------------------------------------------------------------------------------------------
377 typedef struct _cmsSubAllocator_chunk_st {
379 cmsUInt8Number* Block;
380 cmsUInt32Number BlockSize;
381 cmsUInt32Number Used;
383 struct _cmsSubAllocator_chunk_st* next;
385 } _cmsSubAllocator_chunk;
390 cmsContext ContextID;
391 _cmsSubAllocator_chunk* h;
396 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
397 void _cmsSubAllocDestroy(_cmsSubAllocator* s);
398 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
399 void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
401 // ----------------------------------------------------------------------------------
403 // The context clients.
406 UserPtr, // User-defined pointer
409 AdaptationStateContext,
428 // Container for memory management plug-in.
431 _cmsMallocFnPtrType MallocPtr;
432 _cmsMalloZerocFnPtrType MallocZeroPtr;
433 _cmsFreeFnPtrType FreePtr;
434 _cmsReallocFnPtrType ReallocPtr;
435 _cmsCallocFnPtrType CallocPtr;
436 _cmsDupFnPtrType DupPtr;
438 } _cmsMemPluginChunkType;
440 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
441 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
443 // Internal structure for context
444 struct _cmsContext_struct {
446 struct _cmsContext_struct* Next; // Points to next context in the new style
447 _cmsSubAllocator* MemPool; // The memory pool that stores context data
449 void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
450 // If NULL, then it reverts to global Context0
452 _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden
455 // Returns a pointer to a valid context structure, including the global one if id is zero.
456 // Verifies the magic number.
457 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
459 // Returns the block assigned to the specific zone.
460 void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
463 // Chunks of context memory by plug-in client -------------------------------------------------------
465 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
467 // Container for error logger -- not a plug-in
470 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
472 } _cmsLogErrorChunkType;
474 // The global Context0 storage for error logger
475 extern _cmsLogErrorChunkType _cmsLogErrorChunk;
477 // Allocate and init error logger container.
478 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
479 const struct _cmsContext_struct* src);
481 // Container for alarm codes -- not a plug-in
484 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
486 } _cmsAlarmCodesChunkType;
488 // The global Context0 storage for alarm codes
489 extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
491 // Allocate and init alarm codes container.
492 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
493 const struct _cmsContext_struct* src);
495 // Container for adaptation state -- not a plug-in
498 cmsFloat64Number AdaptationState;
500 } _cmsAdaptationStateChunkType;
502 // The global Context0 storage for adaptation state
503 extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
505 // Allocate and init adaptation state container.
506 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
507 const struct _cmsContext_struct* src);
510 // The global Context0 storage for memory management
511 extern _cmsMemPluginChunkType _cmsMemPluginChunk;
513 // Allocate and init memory management container.
514 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
515 const struct _cmsContext_struct* src);
517 // Container for interpolation plug-in
520 cmsInterpFnFactory Interpolators;
522 } _cmsInterpPluginChunkType;
524 // The global Context0 storage for interpolation plug-in
525 extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
527 // Allocate and init interpolation container.
528 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
529 const struct _cmsContext_struct* src);
531 // Container for parametric curves plug-in
534 struct _cmsParametricCurvesCollection_st* ParametricCurves;
536 } _cmsCurvesPluginChunkType;
538 // The global Context0 storage for tone curves plug-in
539 extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
541 // Allocate and init parametric curves container.
542 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
543 const struct _cmsContext_struct* src);
545 // Container for formatters plug-in
548 struct _cms_formatters_factory_list* FactoryList;
550 } _cmsFormattersPluginChunkType;
552 // The global Context0 storage for formatters plug-in
553 extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
555 // Allocate and init formatters container.
556 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
557 const struct _cmsContext_struct* src);
559 // This chunk type is shared by TagType plug-in and MPE Plug-in
562 struct _cmsTagTypeLinkedList_st* TagTypes;
564 } _cmsTagTypePluginChunkType;
567 // The global Context0 storage for tag types plug-in
568 extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
571 // The global Context0 storage for mult process elements plug-in
572 extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
574 // Allocate and init Tag types container.
575 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
576 const struct _cmsContext_struct* src);
577 // Allocate and init MPE container.
578 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
579 const struct _cmsContext_struct* src);
580 // Container for tag plug-in
583 struct _cmsTagLinkedList_st* Tag;
585 } _cmsTagPluginChunkType;
588 // The global Context0 storage for tag plug-in
589 extern _cmsTagPluginChunkType _cmsTagPluginChunk;
591 // Allocate and init Tag container.
592 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
593 const struct _cmsContext_struct* src);
595 // Container for intents plug-in
598 struct _cms_intents_list* Intents;
600 } _cmsIntentsPluginChunkType;
603 // The global Context0 storage for intents plug-in
604 extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
606 // Allocate and init intents container.
607 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
608 const struct _cmsContext_struct* src);
610 // Container for optimization plug-in
613 struct _cmsOptimizationCollection_st* OptimizationCollection;
615 } _cmsOptimizationPluginChunkType;
618 // The global Context0 storage for optimizers plug-in
619 extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
621 // Allocate and init optimizers container.
622 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
623 const struct _cmsContext_struct* src);
625 // Container for transform plug-in
628 struct _cmsTransformCollection_st* TransformCollection;
630 } _cmsTransformPluginChunkType;
632 // The global Context0 storage for full-transform replacement plug-in
633 extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
635 // Allocate and init transform container.
636 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
637 const struct _cmsContext_struct* src);
639 // Container for mutex plug-in
642 _cmsCreateMutexFnPtrType CreateMutexPtr;
643 _cmsDestroyMutexFnPtrType DestroyMutexPtr;
644 _cmsLockMutexFnPtrType LockMutexPtr;
645 _cmsUnlockMutexFnPtrType UnlockMutexPtr;
647 } _cmsMutexPluginChunkType;
649 // The global Context0 storage for mutex plug-in
650 extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
652 // Allocate and init mutex container.
653 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
654 const struct _cmsContext_struct* src);
656 // ----------------------------------------------------------------------------------
657 // MLU internal representation
660 cmsUInt16Number Language;
661 cmsUInt16Number Country;
663 cmsUInt32Number StrW; // Offset to current unicode string
664 cmsUInt32Number Len; // Length in bytes
668 struct _cms_MLU_struct {
670 cmsContext ContextID;
673 cmsUInt32Number AllocatedEntries;
674 cmsUInt32Number UsedEntries;
675 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
678 cmsUInt32Number PoolSize; // The maximum allocated size
679 cmsUInt32Number PoolUsed; // The used size
680 void* MemPool; // Pointer to begin of memory pool
683 // Named color list internal representation
686 char Name[cmsMAX_PATH];
687 cmsUInt16Number PCS[3];
688 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
692 struct _cms_NAMEDCOLORLIST_struct {
694 cmsUInt32Number nColors;
695 cmsUInt32Number Allocated;
696 cmsUInt32Number ColorantCount;
698 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
701 _cmsNAMEDCOLOR* List;
703 cmsContext ContextID;
707 // ----------------------------------------------------------------------------------
709 // This is the internal struct holding profile details.
711 // Maximum supported tags in a profile
712 #define MAX_TABLE_TAG 100
714 typedef struct _cms_iccprofile_struct {
717 cmsIOHANDLER* IOhandler;
720 cmsContext ContextID;
725 // Only most important items found in ICC profiles
726 cmsUInt32Number Version;
727 cmsProfileClassSignature DeviceClass;
728 cmsColorSpaceSignature ColorSpace;
729 cmsColorSpaceSignature PCS;
730 cmsUInt32Number RenderingIntent;
732 cmsUInt32Number flags;
733 cmsUInt32Number manufacturer, model;
734 cmsUInt64Number attributes;
735 cmsUInt32Number creator;
737 cmsProfileID ProfileID;
740 cmsUInt32Number TagCount;
741 cmsTagSignature TagNames[MAX_TABLE_TAG];
742 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none)
743 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
744 cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
745 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
746 void * TagPtrs[MAX_TABLE_TAG];
747 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
748 // depending on profile version, so we keep track of the
749 // type handler for each tag in the list.
753 // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
758 // IO helpers for profiles
759 cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
760 cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
761 int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
764 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
765 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
766 cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
768 // Error logging ---------------------------------------------------------------------------------------------------------
770 void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
772 // Interpolation ---------------------------------------------------------------------------------------------------------
774 cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
775 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
776 void _cmsFreeInterpParams(cmsInterpParams* p);
777 cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
779 // Curves ----------------------------------------------------------------------------------------------------------------
781 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
782 // In the case of table-based, Eval pointer is set to NULL
784 // The gamma function main structure
785 struct _cms_curve_struct {
787 cmsInterpParams* InterpParams; // Private optimizations for interpolation
789 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
790 cmsCurveSegment* Segments; // The segments
791 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
793 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
795 // 16 bit Table-based representation follows
796 cmsUInt32Number nEntries; // Number of table elements
797 cmsUInt16Number* Table16; // The table itself.
801 // Pipelines & Stages ---------------------------------------------------------------------------------------------
804 struct _cmsStage_struct {
806 cmsContext ContextID;
808 cmsStageSignature Type; // Identifies the stage
809 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
811 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
812 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
814 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
815 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
816 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
818 // A generic pointer to whatever memory needed by the stage
821 // Maintains linked list (used internally)
822 struct _cmsStage_struct* Next;
826 // Special Stages (cannot be saved)
827 cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
828 cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
829 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
830 cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
831 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
832 cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
833 cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
834 cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
835 cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
836 cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
837 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
838 cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
839 cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
840 cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels);
843 // For curve set only
844 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
847 // Pipeline Evaluator (in floating point)
848 typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
849 cmsFloat32Number Out[],
852 struct _cmsPipeline_struct {
854 cmsStage* Elements; // Points to elements chain
855 cmsUInt32Number InputChannels, OutputChannels;
860 _cmsOPTeval16Fn Eval16Fn;
861 _cmsPipelineEvalFloatFn EvalFloatFn;
862 _cmsFreeUserDataFn FreeDataFn;
863 _cmsDupUserDataFn DupDataFn;
865 cmsContext ContextID; // Environment
867 cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
870 // LUT reading & creation -------------------------------------------------------------------------------------------
872 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
873 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
875 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
876 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
877 cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
880 cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
881 cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
883 // Profile linker --------------------------------------------------------------------------------------------------
885 cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
886 cmsUInt32Number nProfiles,
887 cmsUInt32Number TheIntents[],
888 cmsHPROFILE hProfiles[],
890 cmsFloat64Number AdaptationStates[],
891 cmsUInt32Number dwFlags);
893 // Sequence --------------------------------------------------------------------------------------------------------
895 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
896 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
897 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
900 // LUT optimization ------------------------------------------------------------------------------------------------
902 cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
903 int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
905 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
906 cmsUInt16Number **White,
907 cmsUInt16Number **Black,
908 cmsUInt32Number *nOutputs);
910 cmsBool _cmsOptimizePipeline(cmsContext ContextID,
913 cmsUInt32Number* InputFormat,
914 cmsUInt32Number* OutputFormat,
915 cmsUInt32Number* dwFlags );
918 // Hi level LUT building ----------------------------------------------------------------------------------------------
920 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
921 cmsHPROFILE hProfiles[],
923 cmsUInt32Number Intents[],
924 cmsFloat64Number AdaptationStates[],
925 cmsUInt32Number nGamutPCSposition,
929 // Formatters ------------------------------------------------------------------------------------------------------------
931 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
933 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
934 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
936 cmsFormatter _cmsGetFormatter(cmsContext ContextID,
937 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
938 cmsFormatterDirection Dir,
939 cmsUInt32Number dwFlags);
942 #ifndef CMS_NO_HALF_SUPPORT
945 cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
946 cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt);
950 // Transform logic ------------------------------------------------------------------------------------------------------
952 struct _cmstransform_struct;
956 // 1-pixel cache (16 bits only)
957 cmsUInt16Number CacheIn[cmsMAXCHANNELS];
958 cmsUInt16Number CacheOut[cmsMAXCHANNELS];
965 typedef struct _cmstransform_struct {
967 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
969 // Points to transform code
970 _cmsTransform2Fn xform;
972 // Formatters, cannot be embedded into LUT because cache
973 cmsFormatter16 FromInput;
974 cmsFormatter16 ToOutput;
976 cmsFormatterFloat FromInputFloat;
977 cmsFormatterFloat ToOutputFloat;
979 // 1-pixel cache seed for zero as input (16 bits, read only)
982 // A Pipeline holding the full (optimized) transform
985 // A Pipeline holding the gamut check. It goes from the input space to bilevel
986 cmsPipeline* GamutCheck;
989 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
990 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
992 // Informational only
993 cmsColorSpaceSignature EntryColorSpace;
994 cmsColorSpaceSignature ExitColorSpace;
996 // White points (informative only)
997 cmsCIEXYZ EntryWhitePoint;
998 cmsCIEXYZ ExitWhitePoint;
1000 // Profiles used to create the transform
1003 cmsUInt32Number dwOriginalFlags;
1004 cmsFloat64Number AdaptationState;
1006 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
1007 cmsUInt32Number RenderingIntent;
1009 // An id that uniquely identifies the running context. May be null.
1010 cmsContext ContextID;
1012 // A user-defined pointer that can be used to store data for transform plug-ins
1014 _cmsFreeUserDataFn FreeUserData;
1016 // A way to provide backwards compatibility with full xform plugins
1017 _cmsTransformFn OldXform;
1021 // Copies extra channels from input to output if the original flags in the transform structure
1022 // instructs to do so. This function is called on all standard transform functions.
1023 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
1025 cmsUInt32Number PixelsPerLine,
1026 cmsUInt32Number LineCount,
1027 const cmsStride* Stride);
1029 // -----------------------------------------------------------------------------------------------------------------------
1031 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
1032 cmsUInt32Number nProfiles,
1033 cmsUInt32Number InputFormat,
1034 cmsUInt32Number OutputFormat,
1035 const cmsUInt32Number Intents[],
1036 const cmsHPROFILE hProfiles[],
1037 const cmsBool BPC[],
1038 const cmsFloat64Number AdaptationStates[],
1039 cmsUInt32Number dwFlags);
1042 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
1043 cmsUInt32Number nPoints,
1044 cmsUInt32Number nProfiles,
1045 const cmsUInt32Number Intents[],
1046 const cmsHPROFILE hProfiles[],
1047 const cmsBool BPC[],
1048 const cmsFloat64Number AdaptationStates[],
1049 cmsUInt32Number dwFlags);
1051 cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
1053 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
1056 #define _lcms_internal_H