|  | 
 | // | 
 | //  Little Color Management System | 
 | //  Copyright (c) 1998-2020 Marti Maria Saguer | 
 | // | 
 | // Permission is hereby granted, free of charge, to any person obtaining | 
 | // a copy of this software and associated documentation files (the "Software"), | 
 | // to deal in the Software without restriction, including without limitation | 
 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
 | // and/or sell copies of the Software, and to permit persons to whom the Software | 
 | // is furnished to do so, subject to the following conditions: | 
 | // | 
 | // The above copyright notice and this permission notice shall be included in | 
 | // all copies or substantial portions of the Software. | 
 | // | 
 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO | 
 | // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | 
 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | 
 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
 | // | 
 | //--------------------------------------------------------------------------------- | 
 | // | 
 |  | 
 | #ifndef _lcms_internal_H | 
 |  | 
 | // Include plug-in foundation | 
 | #ifndef _lcms_plugin_H | 
 | #   include "third_party/lcms/include/lcms2_plugin.h" | 
 | #endif | 
 |  | 
 | // ctype is part of C99 as per 7.1.2 | 
 | #include <ctype.h> | 
 |  | 
 | // assert macro is part of C99 as per 7.2 | 
 | #include <assert.h> | 
 |  | 
 | // Some needed constants | 
 | #ifndef M_PI | 
 | #       define M_PI        3.14159265358979323846 | 
 | #endif | 
 |  | 
 | #ifndef M_LOG10E | 
 | #       define M_LOG10E    0.434294481903251827651 | 
 | #endif | 
 |  | 
 | // BorlandC 5.5, VC2003 are broken on that | 
 | #if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER < 1400)) // 1400 == VC++ 8.0 | 
 | #define sinf(x) (float)sin((float)x) | 
 | #define sqrtf(x) (float)sqrt((float)x) | 
 | #endif | 
 |  | 
 |  | 
 | // Alignment of ICC file format uses 4 bytes (cmsUInt32Number) | 
 | #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1)) | 
 |  | 
 | // Alignment to memory pointer | 
 |  | 
 | // (Ultra)SPARC with gcc requires ptr alignment of 8 bytes | 
 | // even though sizeof(void *) is only four: for greatest flexibility | 
 | // allow the build to specify ptr alignment. | 
 | #ifndef CMS_PTR_ALIGNMENT | 
 | # define CMS_PTR_ALIGNMENT sizeof(void *) | 
 | #endif | 
 |  | 
 | #define _cmsALIGNMEM(x)  (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1)) | 
 |  | 
 | // Maximum encodeable values in floating point | 
 | #define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0) | 
 | #define MIN_ENCODEABLE_ab2  (-128.0) | 
 | #define MAX_ENCODEABLE_ab2  ((65535.0/256.0) - 128.0) | 
 | #define MIN_ENCODEABLE_ab4  (-128.0) | 
 | #define MAX_ENCODEABLE_ab4  (127.0) | 
 |  | 
 | // Maximum of channels for internal pipeline evaluation | 
 | #define MAX_STAGE_CHANNELS  128 | 
 |  | 
 | // Unused parameter warning suppression | 
 | #define cmsUNUSED_PARAMETER(x) ((void)x) | 
 |  | 
 | // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). | 
 | // unfortunately VisualC++ does not conform that | 
 | #if defined(_MSC_VER) || defined(__BORLANDC__) | 
 | #   define cmsINLINE __inline | 
 | #else | 
 | #   define cmsINLINE static inline | 
 | #endif | 
 |  | 
 | // Allow signed overflow, we know this is harmless in this particular context  | 
 | #if defined(__clang__) | 
 | #   define CMS_NO_SANITIZE __attribute__((no_sanitize("signed-integer-overflow"))) | 
 | #else | 
 | #   define CMS_NO_SANITIZE  | 
 | #endif | 
 |  | 
 | // Other replacement functions | 
 | #ifdef _MSC_VER | 
 | # ifndef snprintf | 
 | #       define snprintf  _snprintf | 
 | # endif | 
 | # ifndef vsnprintf | 
 | #       define vsnprintf  _vsnprintf | 
 | # endif | 
 |  | 
 | /// Properly define some macros to accommodate | 
 | /// older MSVC versions. | 
 | # if defined(_MSC_VER) && _MSC_VER <= 1700 | 
 |         #include <float.h> | 
 |         #define isnan _isnan | 
 |         #define isinf(x) (!_finite((x))) | 
 | # endif | 
 |  | 
 | #if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L) | 
 |         #if !defined(isinf) | 
 |         #define isinf(x) (!finite((x))) | 
 |         #endif | 
 | #endif | 
 |  | 
 |  | 
 | #endif | 
 |  | 
 | // A fast way to convert from/to 16 <-> 8 bits | 
 | #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) | 
 | #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU) | 
 |  | 
 | // Code analysis is broken on asserts | 
 | #ifdef _MSC_VER | 
 | #    if (_MSC_VER >= 1500) | 
 | #            define _cmsAssert(a)  { assert((a)); __analysis_assume((a)); } | 
 | #     else | 
 | #            define _cmsAssert(a)   assert((a)) | 
 | #     endif | 
 | #else | 
 | #      define _cmsAssert(a)   assert((a)) | 
 | #endif | 
 |  | 
 | //--------------------------------------------------------------------------------- | 
 |  | 
 | // Determinant lower than that are assumed zero (used on matrix invert) | 
 | #define MATRIX_DET_TOLERANCE    0.0001 | 
 |  | 
 | //--------------------------------------------------------------------------------- | 
 |  | 
 | // Fixed point | 
 | #define FIXED_TO_INT(x)         ((x)>>16) | 
 | #define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU) | 
 | #define ROUND_FIXED_TO_INT(x)   (((x)+0x8000)>>16) | 
 |  | 
 | cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); } | 
 | cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); } | 
 |  | 
 | // ----------------------------------------------------------------------------------------------------------- | 
 |  | 
 | // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon | 
 | // note than this only works in the range ..-32767...+32767 because | 
 | // mantissa is interpreted as 15.16 fixed point. | 
 | // The union is to avoid pointer aliasing overoptimization. | 
 | cmsINLINE int _cmsQuickFloor(cmsFloat64Number val) | 
 | { | 
 | #ifdef CMS_DONT_USE_FAST_FLOOR | 
 |     return (int) floor(val); | 
 | #else | 
 |     const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor | 
 |     union { | 
 |         cmsFloat64Number val; | 
 |         int halves[2]; | 
 |     } temp; | 
 |  | 
 |     temp.val = val + _lcms_double2fixmagic; | 
 |  | 
 | #ifdef CMS_USE_BIG_ENDIAN | 
 |     return temp.halves[1] >> 16; | 
 | #else | 
 |     return temp.halves[0] >> 16; | 
 | #endif | 
 | #endif | 
 | } | 
 |  | 
 | // Fast floor restricted to 0..65535.0 | 
 | cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d) | 
 | { | 
 |     return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U; | 
 | } | 
 |  | 
 | // Floor to word, taking care of saturation | 
 | cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) | 
 | { | 
 |     d += 0.5; | 
 |     if (d <= 0) return 0; | 
 |     if (d >= 65535.0) return 0xffff; | 
 |  | 
 |     return _cmsQuickFloorWord(d); | 
 | } | 
 |  | 
 | // Test bed entry points--------------------------------------------------------------- | 
 | #define CMSCHECKPOINT CMSAPI | 
 |  | 
 | // Pthread support -------------------------------------------------------------------- | 
 | #ifndef CMS_NO_PTHREADS | 
 |  | 
 | // This is the threading support. Unfortunately, it has to be platform-dependent because  | 
 | // windows does not support pthreads.  | 
 | #ifdef CMS_IS_WINDOWS_ | 
 |  | 
 | #define WIN32_LEAN_AND_MEAN 1 | 
 | #include <windows.h> | 
 |  | 
 |  | 
 | // The locking scheme in LCMS requires a single 'top level' mutex | 
 | // to work. This is actually implemented on Windows as a | 
 | // CriticalSection, because they are lighter weight. With | 
 | // pthreads, this is statically inited. Unfortunately, windows | 
 | // can't officially statically init critical sections. | 
 | // | 
 | // We can work around this in 2 ways. | 
 | // | 
 | // 1) We can use a proper mutex purely to protect the init | 
 | // of the CriticalSection. This in turns requires us to protect | 
 | // the Mutex creation, which we can do using the snappily | 
 | // named InterlockedCompareExchangePointer API (present on | 
 | // windows XP and above). | 
 | // | 
 | // 2) In cases where we want to work on pre-Windows XP, we | 
 | // can use an even more horrible hack described below. | 
 | // | 
 | // So why wouldn't we always use 2)? Because not calling | 
 | // the init function for a critical section means it fails | 
 | // testing with ApplicationVerifier (and presumably similar | 
 | // tools). | 
 | // | 
 | // We therefore default to 1, and people who want to be able | 
 | // to run on pre-Windows XP boxes can build with: | 
 | //     CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT | 
 | // defined. This is automatically set for builds using | 
 | // versions of MSVC that don't have this API available. | 
 | // | 
 | // From: http://locklessinc.com/articles/pthreads_on_windows/ | 
 | // The pthreads API has an initialization macro that has no correspondence to anything in  | 
 | // the windows API. By investigating the internal definition of the critical section type,  | 
 | // one may work out how to initialize one without calling InitializeCriticalSection().  | 
 | // The trick here is that InitializeCriticalSection() is not allowed to fail. It tries  | 
 | // to allocate a critical section debug object, but if no memory is available, it sets  | 
 | // the pointer to a specific value. (One would expect that value to be NULL, but it is  | 
 | // actually (void *)-1 for some reason.) Thus we can use this special value for that  | 
 | // pointer, and the critical section code will work. | 
 |  | 
 | // The other important part of the critical section type to initialize is the number  | 
 | // of waiters. This controls whether or not the mutex is locked. Fortunately, this  | 
 | // part of the critical section is unlikely to change. Apparently, many programs  | 
 | // already test critical sections to see if they are locked using this value, so  | 
 | // Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical | 
 | // section, even when they changed the underlying algorithm to be more scalable.  | 
 | // The final parts of the critical section object are unimportant, and can be set  | 
 | // to zero for their defaults. This yields to an initialization macro: | 
 |  | 
 | typedef CRITICAL_SECTION _cmsMutex; | 
 |  | 
 | #ifdef _MSC_VER | 
 | #    if (_MSC_VER >= 1800) | 
 | #          pragma warning(disable : 26135) | 
 | #    endif | 
 | #endif | 
 |  | 
 | #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT | 
 | // If we are building with a version of MSVC smaller | 
 | // than 1400 (i.e. before VS2005) then we don't have | 
 | // the InterlockedCompareExchangePointer API, so use | 
 | // the old version. | 
 | #    ifdef _MSC_VER | 
 | #       if _MSC_VER < 1400 | 
 | #          define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT | 
 | #       endif | 
 | #    endif | 
 | #endif | 
 |  | 
 | #ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT | 
 | #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} | 
 | #else | 
 | #      define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0} | 
 | #endif | 
 |  | 
 | cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) | 
 | { | 
 | 	EnterCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) | 
 | { | 
 | 	LeaveCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 | 	 | 
 | cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) | 
 | { | 
 | 	InitializeCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) | 
 | { | 
 | 	DeleteCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 | 	EnterCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 | 	LeaveCriticalSection(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | #else | 
 |  | 
 | // Rest of the wide world | 
 | #include <pthread.h> | 
 |  | 
 | #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER | 
 | typedef pthread_mutex_t _cmsMutex; | 
 |  | 
 |  | 
 | cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_lock(m); | 
 | } | 
 |  | 
 | cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_unlock(m); | 
 | } | 
 | 	 | 
 | cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_init(m, NULL); | 
 | } | 
 |  | 
 | cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_destroy(m); | 
 | } | 
 |  | 
 | cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_lock(m); | 
 | } | 
 |  | 
 | cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 | 	return pthread_mutex_unlock(m); | 
 | } | 
 |  | 
 | #endif | 
 | #else | 
 |  | 
 | #define CMS_MUTEX_INITIALIZER 0 | 
 | typedef int _cmsMutex; | 
 |  | 
 |  | 
 | cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 | 	 | 
 | cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 |  | 
 | cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) | 
 | { | 
 |     cmsUNUSED_PARAMETER(m); | 
 | 	return 0; | 
 | } | 
 | #endif | 
 |  | 
 | // Plug-In registration --------------------------------------------------------------- | 
 |  | 
 | // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once. | 
 | void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); | 
 |  | 
 | // Memory management | 
 | cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Interpolation | 
 | cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Parametric curves | 
 | cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Formatters management | 
 | cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Tag type management | 
 | cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Tag management | 
 | cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Intent management | 
 | cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Multi Process elements | 
 | cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Optimization | 
 | cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Transform | 
 | cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // Mutex | 
 | cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); | 
 |  | 
 | // --------------------------------------------------------------------------------------------------------- | 
 |  | 
 | // Suballocators.  | 
 | typedef struct _cmsSubAllocator_chunk_st { | 
 |  | 
 |     cmsUInt8Number* Block; | 
 |     cmsUInt32Number BlockSize; | 
 |     cmsUInt32Number Used; | 
 |  | 
 |     struct _cmsSubAllocator_chunk_st* next; | 
 |  | 
 | } _cmsSubAllocator_chunk; | 
 |  | 
 |  | 
 | typedef struct { | 
 |  | 
 |     cmsContext ContextID; | 
 |     _cmsSubAllocator_chunk* h; | 
 |  | 
 | } _cmsSubAllocator; | 
 |  | 
 |  | 
 | _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial); | 
 | void              _cmsSubAllocDestroy(_cmsSubAllocator* s); | 
 | void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size); | 
 | void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size); | 
 |  | 
 | // ---------------------------------------------------------------------------------- | 
 |  | 
 | // The context clients.  | 
 | typedef enum { | 
 |  | 
 |     UserPtr,            // User-defined pointer | 
 |     Logger, | 
 |     AlarmCodesContext, | 
 |     AdaptationStateContext,  | 
 |     MemPlugin, | 
 |     InterpPlugin, | 
 |     CurvesPlugin, | 
 |     FormattersPlugin, | 
 |     TagTypePlugin, | 
 |     TagPlugin, | 
 |     IntentPlugin, | 
 |     MPEPlugin, | 
 |     OptimizationPlugin, | 
 |     TransformPlugin, | 
 |     MutexPlugin, | 
 |  | 
 |     // Last in list | 
 |     MemoryClientMax | 
 |  | 
 | } _cmsMemoryClient; | 
 |  | 
 |  | 
 | // Container for memory management plug-in. | 
 | typedef struct { | 
 |  | 
 |     _cmsMallocFnPtrType     MallocPtr;     | 
 |     _cmsMalloZerocFnPtrType MallocZeroPtr; | 
 |     _cmsFreeFnPtrType       FreePtr; | 
 |     _cmsReallocFnPtrType    ReallocPtr; | 
 |     _cmsCallocFnPtrType     CallocPtr; | 
 |     _cmsDupFnPtrType        DupPtr; | 
 |  | 
 | } _cmsMemPluginChunkType; | 
 |  | 
 | // Copy memory management function pointers from plug-in to chunk, taking care of missing routines | 
 | void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr); | 
 |  | 
 | // Internal structure for context | 
 | struct _cmsContext_struct { | 
 |      | 
 |     struct _cmsContext_struct* Next;  // Points to next context in the new style | 
 |     _cmsSubAllocator* MemPool;        // The memory pool that stores context data | 
 |      | 
 |     void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.  | 
 |                                       // If NULL, then it reverts to global Context0 | 
 |  | 
 |     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden | 
 | }; | 
 |  | 
 | // Returns a pointer to a valid context structure, including the global one if id is zero.  | 
 | // Verifies the magic number. | 
 | struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID); | 
 |  | 
 | // Returns the block assigned to the specific zone.  | 
 | void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc); | 
 |  | 
 |  | 
 | // Chunks of context memory by plug-in client ------------------------------------------------------- | 
 |  | 
 | // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins) | 
 |  | 
 | // Container for error logger -- not a plug-in | 
 | typedef struct { | 
 |  | 
 |     cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback | 
 |  | 
 | } _cmsLogErrorChunkType; | 
 |  | 
 | // The global Context0 storage for error logger | 
 | extern  _cmsLogErrorChunkType  _cmsLogErrorChunk; | 
 |  | 
 | // Allocate and init error logger container.  | 
 | void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,  | 
 |                             const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for alarm codes -- not a plug-in | 
 | typedef struct { | 
 |     | 
 |     cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]; | 
 |  | 
 | } _cmsAlarmCodesChunkType; | 
 |  | 
 | // The global Context0 storage for alarm codes | 
 | extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk; | 
 |  | 
 | // Allocate and init alarm codes container.  | 
 | void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,  | 
 |                             const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for adaptation state -- not a plug-in | 
 | typedef struct { | 
 |      | 
 |     cmsFloat64Number  AdaptationState; | 
 |  | 
 | } _cmsAdaptationStateChunkType; | 
 |  | 
 | // The global Context0 storage for adaptation state | 
 | extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk; | 
 |  | 
 | // Allocate and init adaptation state container. | 
 | void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,  | 
 |                                    const struct _cmsContext_struct* src); | 
 |  | 
 |  | 
 | // The global Context0 storage for memory management | 
 | extern  _cmsMemPluginChunkType _cmsMemPluginChunk; | 
 |  | 
 | // Allocate and init memory management container. | 
 | void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                              const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for interpolation plug-in | 
 | typedef struct { | 
 |  | 
 |     cmsInterpFnFactory Interpolators; | 
 |  | 
 | } _cmsInterpPluginChunkType; | 
 |  | 
 | // The global Context0 storage for interpolation plug-in | 
 | extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk; | 
 |  | 
 | // Allocate and init interpolation container. | 
 | void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                 const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for parametric curves plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cmsParametricCurvesCollection_st* ParametricCurves; | 
 |  | 
 | } _cmsCurvesPluginChunkType; | 
 |  | 
 | // The global Context0 storage for tone curves plug-in | 
 | extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk; | 
 |  | 
 | // Allocate and init parametric curves container. | 
 | void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                       const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for formatters plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cms_formatters_factory_list* FactoryList; | 
 |  | 
 | } _cmsFormattersPluginChunkType; | 
 |  | 
 | // The global Context0 storage for formatters plug-in | 
 | extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk; | 
 |  | 
 | // Allocate and init formatters container. | 
 | void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                        const struct _cmsContext_struct* src); | 
 |  | 
 | // This chunk type is shared by TagType plug-in and MPE Plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cmsTagTypeLinkedList_st* TagTypes; | 
 |  | 
 | } _cmsTagTypePluginChunkType; | 
 |  | 
 |  | 
 | // The global Context0 storage for tag types plug-in | 
 | extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk; | 
 |  | 
 |  | 
 | // The global Context0 storage for mult process elements plug-in | 
 | extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk; | 
 |  | 
 | // Allocate and init Tag types container. | 
 | void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                         const struct _cmsContext_struct* src); | 
 | // Allocate and init MPE container. | 
 | void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                         const struct _cmsContext_struct* src); | 
 | // Container for tag plug-in | 
 | typedef struct { | 
 |     | 
 |     struct _cmsTagLinkedList_st* Tag; | 
 |  | 
 | } _cmsTagPluginChunkType; | 
 |  | 
 |  | 
 | // The global Context0 storage for tag plug-in | 
 | extern  _cmsTagPluginChunkType _cmsTagPluginChunk; | 
 |  | 
 | // Allocate and init Tag container. | 
 | void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                       const struct _cmsContext_struct* src);  | 
 |  | 
 | // Container for intents plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cms_intents_list* Intents; | 
 |  | 
 | } _cmsIntentsPluginChunkType; | 
 |  | 
 |  | 
 | // The global Context0 storage for intents plug-in | 
 | extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk; | 
 |  | 
 | // Allocate and init intents container. | 
 | void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                                         const struct _cmsContext_struct* src);  | 
 |  | 
 | // Container for optimization plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cmsOptimizationCollection_st* OptimizationCollection; | 
 |  | 
 | } _cmsOptimizationPluginChunkType; | 
 |  | 
 |  | 
 | // The global Context0 storage for optimizers plug-in | 
 | extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk; | 
 |  | 
 | // Allocate and init optimizers container. | 
 | void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                          const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for transform plug-in | 
 | typedef struct { | 
 |  | 
 |     struct _cmsTransformCollection_st* TransformCollection; | 
 |  | 
 | } _cmsTransformPluginChunkType; | 
 |  | 
 | // The global Context0 storage for full-transform replacement plug-in | 
 | extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk; | 
 |  | 
 | // Allocate and init transform container. | 
 | void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                         const struct _cmsContext_struct* src); | 
 |  | 
 | // Container for mutex plug-in | 
 | typedef struct { | 
 |  | 
 |     _cmsCreateMutexFnPtrType  CreateMutexPtr; | 
 |     _cmsDestroyMutexFnPtrType DestroyMutexPtr; | 
 |     _cmsLockMutexFnPtrType    LockMutexPtr; | 
 |     _cmsUnlockMutexFnPtrType  UnlockMutexPtr; | 
 |  | 
 | } _cmsMutexPluginChunkType; | 
 |  | 
 | // The global Context0 storage for mutex plug-in | 
 | extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk; | 
 |  | 
 | // Allocate and init mutex container. | 
 | void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,  | 
 |                                         const struct _cmsContext_struct* src); | 
 |  | 
 | // ---------------------------------------------------------------------------------- | 
 | // MLU internal representation | 
 | typedef struct { | 
 |  | 
 |     cmsUInt16Number Language; | 
 |     cmsUInt16Number Country; | 
 |  | 
 |     cmsUInt32Number StrW;       // Offset to current unicode string | 
 |     cmsUInt32Number Len;        // Length in bytes | 
 |  | 
 | } _cmsMLUentry; | 
 |  | 
 | struct _cms_MLU_struct { | 
 |  | 
 |     cmsContext ContextID; | 
 |  | 
 |     // The directory | 
 |     cmsUInt32Number  AllocatedEntries; | 
 |     cmsUInt32Number  UsedEntries; | 
 |     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool | 
 |  | 
 |     // The Pool | 
 |     cmsUInt32Number PoolSize;  // The maximum allocated size | 
 |     cmsUInt32Number PoolUsed;  // The used size | 
 |     void*  MemPool;            // Pointer to begin of memory pool | 
 | }; | 
 |  | 
 | // Named color list internal representation | 
 | typedef struct { | 
 |  | 
 |     char Name[cmsMAX_PATH]; | 
 |     cmsUInt16Number PCS[3]; | 
 |     cmsUInt16Number DeviceColorant[cmsMAXCHANNELS]; | 
 |  | 
 | } _cmsNAMEDCOLOR; | 
 |  | 
 | struct _cms_NAMEDCOLORLIST_struct { | 
 |  | 
 |     cmsUInt32Number nColors; | 
 |     cmsUInt32Number Allocated; | 
 |     cmsUInt32Number ColorantCount; | 
 |  | 
 |     char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most | 
 |     char Suffix[33]; | 
 |  | 
 |     _cmsNAMEDCOLOR* List; | 
 |  | 
 |     cmsContext ContextID; | 
 | }; | 
 |  | 
 |  | 
 | // ---------------------------------------------------------------------------------- | 
 |  | 
 | // This is the internal struct holding profile details. | 
 |  | 
 | // Maximum supported tags in a profile | 
 | #define MAX_TABLE_TAG       100 | 
 |  | 
 | typedef struct _cms_iccprofile_struct { | 
 |  | 
 |     // I/O handler | 
 |     cmsIOHANDLER*            IOhandler; | 
 |  | 
 |     // The thread ID | 
 |     cmsContext               ContextID; | 
 |  | 
 |     // Creation time | 
 |     struct tm                Created; | 
 |  | 
 |     // Only most important items found in ICC profiles | 
 |     cmsUInt32Number          Version; | 
 |     cmsProfileClassSignature DeviceClass; | 
 |     cmsColorSpaceSignature   ColorSpace; | 
 |     cmsColorSpaceSignature   PCS; | 
 |     cmsUInt32Number          RenderingIntent; | 
 |  | 
 |     cmsUInt32Number          flags; | 
 |     cmsUInt32Number          manufacturer, model; | 
 |     cmsUInt64Number          attributes; | 
 |     cmsUInt32Number          creator; | 
 |  | 
 |     cmsProfileID             ProfileID; | 
 |  | 
 |     // Dictionary | 
 |     cmsUInt32Number          TagCount; | 
 |     cmsTagSignature          TagNames[MAX_TABLE_TAG]; | 
 |     cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none) | 
 |     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk | 
 |     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG]; | 
 |     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked | 
 |     void *                   TagPtrs[MAX_TABLE_TAG]; | 
 |     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types | 
 |                                                                  // depending on profile version, so we keep track of the | 
 |                                                                  // type handler for each tag in the list. | 
 |     // Special | 
 |     cmsBool                  IsWrite; | 
 |  | 
 |     // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin | 
 |     void *                   UsrMutex; | 
 |  | 
 | } _cmsICCPROFILE; | 
 |  | 
 | // IO helpers for profiles | 
 | cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc); | 
 | cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace); | 
 | int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks); | 
 |  | 
 | // Tag types | 
 | cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig); | 
 | cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig); | 
 | cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig); | 
 |  | 
 | // Error logging --------------------------------------------------------------------------------------------------------- | 
 |  | 
 | void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig); | 
 |  | 
 | // Interpolation --------------------------------------------------------------------------------------------------------- | 
 |  | 
 | CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); | 
 | cmsInterpParams*                         _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); | 
 | CMSCHECKPOINT void             CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p); | 
 | cmsBool                                  _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); | 
 |  | 
 | // Curves ---------------------------------------------------------------------------------------------------------------- | 
 |  | 
 | // This struct holds information about a segment, plus a pointer to the function that implements the evaluation. | 
 | // In the case of table-based, Eval pointer is set to NULL | 
 |  | 
 | // The gamma function main structure | 
 | struct _cms_curve_struct { | 
 |  | 
 |     cmsInterpParams*  InterpParams;  // Private optimizations for interpolation | 
 |  | 
 |     cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables | 
 |     cmsCurveSegment*  Segments;      // The segments | 
 |     cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments | 
 |  | 
 |     cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment) | 
 |  | 
 |     // 16 bit Table-based representation follows | 
 |     cmsUInt32Number    nEntries;      // Number of table elements | 
 |     cmsUInt16Number*   Table16;       // The table itself. | 
 | }; | 
 |  | 
 |  | 
 | //  Pipelines & Stages --------------------------------------------------------------------------------------------- | 
 |  | 
 | // A single stage | 
 | struct _cmsStage_struct { | 
 |  | 
 |     cmsContext          ContextID; | 
 |  | 
 |     cmsStageSignature   Type;           // Identifies the stage | 
 |     cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations) | 
 |  | 
 |     cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes | 
 |     cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes | 
 |  | 
 |     _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point) | 
 |     _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage | 
 |     _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free | 
 |  | 
 |     // A generic pointer to whatever memory needed by the stage | 
 |     void*               Data; | 
 |  | 
 |     // Maintains linked list (used internally) | 
 |     struct _cmsStage_struct* Next; | 
 | }; | 
 |  | 
 |  | 
 | // Special Stages (cannot be saved) | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageAllocLabPrelin(cmsContext ContextID); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels); | 
 | CMSCHECKPOINT cmsStage*  CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan); | 
 | cmsStage*                          _cmsStageNormalizeFromLabFloat(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageNormalizeToLabFloat(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageNormalizeToXyzFloat(cmsContext ContextID); | 
 | cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels); | 
 |  | 
 |  | 
 | // For curve set only | 
 | cmsToneCurve**     _cmsStageGetPtrToCurveSet(const cmsStage* mpe); | 
 |  | 
 |  | 
 | // Pipeline Evaluator (in floating point) | 
 | typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[], | 
 |                                          cmsFloat32Number Out[], | 
 |                                          const void* Data); | 
 |  | 
 | struct _cmsPipeline_struct { | 
 |  | 
 |     cmsStage* Elements;                                // Points to elements chain | 
 |     cmsUInt32Number InputChannels, OutputChannels; | 
 |  | 
 |     // Data & evaluators | 
 |     void *Data; | 
 |  | 
 |    _cmsOPTeval16Fn         Eval16Fn; | 
 |    _cmsPipelineEvalFloatFn EvalFloatFn; | 
 |    _cmsFreeUserDataFn      FreeDataFn; | 
 |    _cmsDupUserDataFn       DupDataFn; | 
 |  | 
 |     cmsContext ContextID;            // Environment | 
 |  | 
 |     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible | 
 | }; | 
 |  | 
 | // LUT reading & creation ------------------------------------------------------------------------------------------- | 
 |  | 
 | // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy | 
 | // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources. | 
 |  | 
 | CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); | 
 | CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); | 
 | CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); | 
 |  | 
 | // Special values | 
 | cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); | 
 | cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile); | 
 |  | 
 | // Profile linker -------------------------------------------------------------------------------------------------- | 
 |  | 
 | // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point | 
 | // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS | 
 | // after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1) | 
 | cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID, | 
 |                               cmsUInt32Number    nProfiles, | 
 |                               cmsUInt32Number    TheIntents[], | 
 |                               cmsHPROFILE        hProfiles[], | 
 |                               cmsBool            BPC[], | 
 |                               cmsFloat64Number   AdaptationStates[], | 
 |                               cmsUInt32Number    dwFlags); | 
 |  | 
 | // Sequence -------------------------------------------------------------------------------------------------------- | 
 |  | 
 | cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile); | 
 | cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq); | 
 | cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]); | 
 |  | 
 |  | 
 | // LUT optimization ------------------------------------------------------------------------------------------------ | 
 |  | 
 | CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples); | 
 |  | 
 | cmsUInt32Number  _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); | 
 |  | 
 | cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space, | 
 |                                       cmsUInt16Number **White, | 
 |                                       cmsUInt16Number **Black, | 
 |                                       cmsUInt32Number *nOutputs); | 
 |  | 
 | cmsBool          _cmsOptimizePipeline(cmsContext ContextID, | 
 |                                       cmsPipeline**    Lut, | 
 |                                       cmsUInt32Number  Intent, | 
 |                                       cmsUInt32Number* InputFormat, | 
 |                                       cmsUInt32Number* OutputFormat, | 
 |                                       cmsUInt32Number* dwFlags ); | 
 |  | 
 |  | 
 | // Hi level LUT building ---------------------------------------------------------------------------------------------- | 
 |  | 
 | cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID, | 
 |                                               cmsHPROFILE hProfiles[], | 
 |                                               cmsBool  BPC[], | 
 |                                               cmsUInt32Number Intents[], | 
 |                                               cmsFloat64Number AdaptationStates[], | 
 |                                               cmsUInt32Number nGamutPCSposition, | 
 |                                               cmsHPROFILE hGamut); | 
 |  | 
 |  | 
 | // Formatters ------------------------------------------------------------------------------------------------------------ | 
 |  | 
 | #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format | 
 |  | 
 | cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type); | 
 | cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type); | 
 |  | 
 | CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID, | 
 |                                                       cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8 | 
 |                                                       cmsFormatterDirection Dir, | 
 |                                                       cmsUInt32Number dwFlags); | 
 |  | 
 |  | 
 | #ifndef CMS_NO_HALF_SUPPORT  | 
 |  | 
 | // Half float | 
 | CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h); | 
 | CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt); | 
 |  | 
 | #endif | 
 |  | 
 | // Transform logic ------------------------------------------------------------------------------------------------------ | 
 |  | 
 | struct _cmstransform_struct; | 
 |  | 
 | typedef struct { | 
 |  | 
 |     // 1-pixel cache (16 bits only) | 
 |     cmsUInt16Number CacheIn[cmsMAXCHANNELS]; | 
 |     cmsUInt16Number CacheOut[cmsMAXCHANNELS]; | 
 |  | 
 | } _cmsCACHE; | 
 |  | 
 |  | 
 |  | 
 | // Transformation | 
 | typedef struct _cmstransform_struct { | 
 |  | 
 |     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference | 
 |  | 
 |     // Points to transform code | 
 |     _cmsTransform2Fn xform; | 
 |  | 
 |     // Formatters, cannot be embedded into LUT because cache | 
 |     cmsFormatter16 FromInput; | 
 |     cmsFormatter16 ToOutput; | 
 |  | 
 |     cmsFormatterFloat FromInputFloat; | 
 |     cmsFormatterFloat ToOutputFloat; | 
 |  | 
 |     // 1-pixel cache seed for zero as input (16 bits, read only) | 
 |     _cmsCACHE Cache; | 
 |  | 
 |     // A Pipeline holding the full (optimized) transform | 
 |     cmsPipeline* Lut; | 
 |  | 
 |     // A Pipeline holding the gamut check. It goes from the input space to bilevel | 
 |     cmsPipeline* GamutCheck; | 
 |  | 
 |     // Colorant tables | 
 |     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table | 
 |     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK) | 
 |  | 
 |     // Informational only | 
 |     cmsColorSpaceSignature EntryColorSpace; | 
 |     cmsColorSpaceSignature ExitColorSpace; | 
 |  | 
 |     // White points (informative only) | 
 |     cmsCIEXYZ EntryWhitePoint; | 
 |     cmsCIEXYZ ExitWhitePoint; | 
 |  | 
 |     // Profiles used to create the transform | 
 |     cmsSEQ* Sequence; | 
 |  | 
 |     cmsUInt32Number  dwOriginalFlags; | 
 |     cmsFloat64Number AdaptationState; | 
 |  | 
 |     // The intent of this transform. That is usually the last intent in the profilechain, but may differ | 
 |     cmsUInt32Number RenderingIntent; | 
 |  | 
 |     // An id that uniquely identifies the running context. May be null. | 
 |     cmsContext ContextID; | 
 |  | 
 |     // A user-defined pointer that can be used to store data for transform plug-ins | 
 |     void* UserData; | 
 |     _cmsFreeUserDataFn FreeUserData; | 
 |  | 
 |     // A way to provide backwards compatibility with full xform plugins | 
 |     _cmsTransformFn OldXform; | 
 |  | 
 | } _cmsTRANSFORM; | 
 |  | 
 | // Copies extra channels from input to output if the original flags in the transform structure | 
 | // instructs to do so. This function is called on all standard transform functions. | 
 | void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in, | 
 |                              void* out,  | 
 |                              cmsUInt32Number PixelsPerLine, | 
 |                              cmsUInt32Number LineCount, | 
 |                              const cmsStride* Stride); | 
 |  | 
 | // ----------------------------------------------------------------------------------------------------------------------- | 
 |  | 
 | cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID, | 
 |                             cmsUInt32Number        nProfiles, | 
 |                             cmsUInt32Number        InputFormat, | 
 |                             cmsUInt32Number        OutputFormat, | 
 |                             const cmsUInt32Number  Intents[], | 
 |                             const cmsHPROFILE      hProfiles[], | 
 |                             const cmsBool          BPC[], | 
 |                             const cmsFloat64Number AdaptationStates[], | 
 |                             cmsUInt32Number        dwFlags); | 
 |  | 
 |  | 
 | cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID, | 
 |                             cmsUInt32Number        nPoints, | 
 |                             cmsUInt32Number        nProfiles, | 
 |                             const cmsUInt32Number  Intents[], | 
 |                             const cmsHPROFILE      hProfiles[], | 
 |                             const cmsBool          BPC[], | 
 |                             const cmsFloat64Number AdaptationStates[], | 
 |                             cmsUInt32Number        dwFlags); | 
 |  | 
 | cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll); | 
 |  | 
 | cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries); | 
 |  | 
 |  | 
 | #define _lcms_internal_H | 
 | #endif |