diff mupdf-source/thirdparty/lcms2/src/lcms2_internal.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mupdf-source/thirdparty/lcms2/src/lcms2_internal.h	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,1160 @@
+
+//
+//  Little Color Management System
+//  Copyright (c) 1998-2023 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 _lcms2mt_plugin_H
+#   include "lcms2mt_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
+# if defined(sparc) || defined(__sparc) || defined(__sparc__)
+#  define CMS_PTR_ALIGNMENT 8
+# else
+#  define CMS_PTR_ALIGNMENT sizeof(void *)
+# endif
+#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)
+#          pragma warning(disable : 4127)
+#    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);
+
+// Paralellization
+cmsBool _cmsRegisterParallelizationPlugin(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,
+    ParallelizationPlugin,
+
+    // 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 held 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);
+
+// Container for parallelization plug-in
+typedef struct {
+
+    cmsInt32Number      MaxWorkers;       // Number of workers to do as maximum
+    cmsInt32Number      WorkerFlags;      // reserved
+    _cmsTransform2Fn    SchedulerFn;      // callback to setup functions
+
+} _cmsParallelizationPluginChunkType;
+
+// The global Context0 storage for parallelization plug-in
+extern  _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk;
+
+// Allocate parallelization container.
+void _cmsAllocParallelizationPluginChunk(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 {
+
+    // 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;
+};
+
+
+// ----------------------------------------------------------------------------------
+
+// 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;
+
+    // Creation time
+    struct tm                Created;
+
+    // Color management module identification
+    cmsUInt32Number          CMM;
+
+    // Only most important items found in ICC profiles
+    cmsUInt32Number          Version;
+    cmsProfileClassSignature DeviceClass;
+    cmsColorSpaceSignature   ColorSpace;
+    cmsColorSpaceSignature   PCS;
+    cmsUInt32Number          RenderingIntent;
+
+    cmsPlatformSignature     platform;
+    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(cmsContext ContextID, _cmsICCPROFILE* Icc);
+cmsBool              _cmsWriteHeader(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
+int                  _cmsSearchTag(cmsContext ContextID, _cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
+
+// Tag types
+cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
+cmsTagTypeSignature  _cmsGetTagTrueType(cmsContext ContextID, 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(cmsContext ContextID, 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 {
+
+    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(cmsContext ContextID, 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);
+
+struct _cmsPipeline_struct {
+
+    cmsStage* Elements;                                // Points to elements chain
+    cmsUInt32Number InputChannels, OutputChannels;
+
+    // Data & evaluators
+    void *Data;
+
+   _cmsPipelineEval16Fn    Eval16Fn;
+   _cmsPipelineEvalFloatFn EvalFloatFn;
+   _cmsFreeUserDataFn      FreeDataFn;
+   _cmsDupUserDataFn       DupDataFn;
+
+    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(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
+CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
+CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent);
+
+// Special values
+cmsBool           _cmsReadMediaWhitePoint(cmsContext ContextID, cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
+cmsBool           _cmsReadCHAD(cmsContext ContextID, 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(cmsContext ContextID, cmsHPROFILE hProfile);
+cmsBool _cmsWriteProfileSequence(cmsContext ContextID, cmsHPROFILE hProfile, const cmsSEQ* seq);
+cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
+
+
+// LUT optimization ------------------------------------------------------------------------------------------------
+
+CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
+
+CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
+
+cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
+                                      cmsUInt16Number **White,
+                                      cmsUInt16Number **Black,
+                                      cmsUInt32Number *nOutputs);
+
+CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
+                                      cmsPipeline**    Lut,
+                                      cmsUInt32Number  Intent,
+                                      cmsUInt32Number* InputFormat,
+                                      cmsUInt32Number* OutputFormat,
+                                      cmsUInt32Number* dwFlags );
+
+cmsBool _cmsLutIsIdentity(cmsPipeline *PtrLut);
+
+// 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_core {
+
+    cmsUInt32Number refs;
+
+    // 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;
+
+    // A user-defined pointer that can be used to store data for transform plug-ins
+    void* UserData;
+    _cmsFreeUserDataFn FreeUserData;
+
+} _cmsTRANSFORMCORE;
+
+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 way to provide backwards compatibility with full xform plugins
+    _cmsTransformFn OldXform;
+
+    _cmsTRANSFORMCORE *core;
+
+    // A one-worker transform entry for parallelization
+    _cmsTransform2Fn Worker;
+    cmsInt32Number   MaxWorkers;
+    cmsUInt32Number  WorkerFlags;
+
+} _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(cmsContext ContextID, _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(cmsContext ContextID, cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
+
+cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsContext ContextID, cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
+
+void _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number flags);
+
+cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta);
+
+// thread-safe gettime
+cmsBool _cmsGetTime(struct tm* ptr_time);
+
+#define _lcms_internal_H
+#endif