//---------------------------------------------------------------------------------
//
//  Little Color Management System
//  Copyright (c) 1998-2016 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.
//
//---------------------------------------------------------------------------------
//

#include "lcms2_internal.h"


// ----------------------------------------------------------------------------------
// Encoding & Decoding support functions
// ----------------------------------------------------------------------------------

//      Little-Endian to Big-Endian

// Adjust a word value after being readed/ before being written from/to an ICC profile
cmsUInt16Number CMSEXPORT  _cmsAdjustEndianess16(cmsUInt16Number Word)
{
#ifndef CMS_USE_BIG_ENDIAN

    cmsUInt8Number* pByte = (cmsUInt8Number*) &Word;
    cmsUInt8Number tmp;

    tmp = pByte[0];
    pByte[0] = pByte[1];
    pByte[1] = tmp;
#endif

    return Word;
}


// Transports to properly encoded values - note that icc profiles does use big endian notation.

// 1 2 3 4
// 4 3 2 1

cmsUInt32Number CMSEXPORT  _cmsAdjustEndianess32(cmsUInt32Number DWord)
{
#ifndef CMS_USE_BIG_ENDIAN

    cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
    cmsUInt8Number temp1;
    cmsUInt8Number temp2;

    temp1 = *pByte++;
    temp2 = *pByte++;
    *(pByte-1) = *pByte;
    *pByte++ = temp2;
    *(pByte-3) = *pByte;
    *pByte = temp1;
#endif
    return DWord;
}

// 1 2 3 4 5 6 7 8
// 8 7 6 5 4 3 2 1

void CMSEXPORT  _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
{

#ifndef CMS_USE_BIG_ENDIAN

    cmsUInt8Number* pIn  = (cmsUInt8Number*) QWord;
    cmsUInt8Number* pOut = (cmsUInt8Number*) Result;

    _cmsAssert(Result != NULL);

    pOut[7] = pIn[0];
    pOut[6] = pIn[1];
    pOut[5] = pIn[2];
    pOut[4] = pIn[3];
    pOut[3] = pIn[4];
    pOut[2] = pIn[5];
    pOut[1] = pIn[6];
    pOut[0] = pIn[7];

#else
    _cmsAssert(Result != NULL);

#  ifdef CMS_DONT_USE_INT64
    (*Result)[0] = QWord[0];
    (*Result)[1] = QWord[1];
#  else
    *Result = *QWord;
#  endif
#endif
}

// Auxiliary -- read 8, 16 and 32-bit numbers
cmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
{
    cmsUInt8Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
            return FALSE;

    if (n != NULL) *n = tmp;
    return TRUE;
}

cmsBool CMSEXPORT  _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
{
    cmsUInt16Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
            return FALSE;

    if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
    return TRUE;
}

cmsBool CMSEXPORT  _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array)
{
    cmsUInt32Number i;

    _cmsAssert(io != NULL);

    for (i=0; i < n; i++) {

        if (Array != NULL) {
            if (!_cmsReadUInt16Number(io, Array + i)) return FALSE;
        }
        else {
            if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
        }

    }
    return TRUE;
}

cmsBool CMSEXPORT  _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
            return FALSE;

    if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
    return TRUE;
}

cmsBool CMSEXPORT  _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
            return FALSE;

    if (n != NULL) {

        tmp = _cmsAdjustEndianess32(tmp);
        *n = *(cmsFloat32Number*) (void*) &tmp;
        if (isnan(*n))
            return FALSE;
    }

    // fpclassify() required by C99
    return (fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL);
}


cmsBool CMSEXPORT   _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
{
    cmsUInt64Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
            return FALSE;

    if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
    return TRUE;
}


cmsBool CMSEXPORT  _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
            return FALSE;

    if (n != NULL) {
        *n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
    }

    return TRUE;
}


cmsBool CMSEXPORT  _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
{
    cmsEncodedXYZNumber xyz;

    _cmsAssert(io != NULL);

    if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE;

    if (XYZ != NULL) {

        XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
        XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
        XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
    }
    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
{
    _cmsAssert(io != NULL);

    if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
            return FALSE;

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
{
    cmsUInt16Number tmp;

    _cmsAssert(io != NULL);

    tmp = _cmsAdjustEndianess16(n);
    if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
            return FALSE;

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array)
{
    cmsUInt32Number i;

    _cmsAssert(io != NULL);
    _cmsAssert(Array != NULL);

    for (i=0; i < n; i++) {
        if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE;
    }

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    tmp = _cmsAdjustEndianess32(n);
    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
            return FALSE;

    return TRUE;
}


cmsBool CMSEXPORT  _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    tmp = *(cmsUInt32Number*) (void*) &n;
    tmp = _cmsAdjustEndianess32(tmp);
    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
            return FALSE;

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
{
    cmsUInt64Number tmp;

    _cmsAssert(io != NULL);

    _cmsAdjustEndianess64(&tmp, n);
    if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
            return FALSE;

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n)
{
    cmsUInt32Number tmp;

    _cmsAssert(io != NULL);

    tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
            return FALSE;

    return TRUE;
}

cmsBool CMSEXPORT  _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
{
    cmsEncodedXYZNumber xyz;

    _cmsAssert(io != NULL);
    _cmsAssert(XYZ != NULL);

    xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
    xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
    xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));

    return io -> Write(io,  sizeof(cmsEncodedXYZNumber), &xyz);
}

// from Fixed point 8.8 to double
cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
{
       cmsUInt8Number  msb, lsb;

       lsb = (cmsUInt8Number) (fixed8 & 0xff);
       msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);

       return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
}

cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
{
    cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
    return  (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
}

// from Fixed point 15.16 to double
cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
{
    cmsFloat64Number floater, sign, mid;
    int Whole, FracPart;

    sign  = (fix32 < 0 ? -1 : 1);
    fix32 = abs(fix32);

    Whole     = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
    FracPart  = (cmsUInt16Number)(fix32 & 0xffff);

    mid     = (cmsFloat64Number) FracPart / 65536.0;
    floater = (cmsFloat64Number) Whole + mid;

    return sign * floater;
}

// from double to Fixed point 15.16
cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
{
    return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
}

// Date/Time functions

void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
{

    _cmsAssert(Dest != NULL);
    _cmsAssert(Source != NULL);

    Dest->tm_sec   = _cmsAdjustEndianess16(Source->seconds);
    Dest->tm_min   = _cmsAdjustEndianess16(Source->minutes);
    Dest->tm_hour  = _cmsAdjustEndianess16(Source->hours);
    Dest->tm_mday  = _cmsAdjustEndianess16(Source->day);
    Dest->tm_mon   = _cmsAdjustEndianess16(Source->month) - 1;
    Dest->tm_year  = _cmsAdjustEndianess16(Source->year) - 1900;
    Dest->tm_wday  = -1;
    Dest->tm_yday  = -1;
    Dest->tm_isdst = 0;
}

void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source)
{
    _cmsAssert(Dest != NULL);
    _cmsAssert(Source != NULL);

    Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec);
    Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min);
    Dest->hours   = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour);
    Dest->day     = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday);
    Dest->month   = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1));
    Dest->year    = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900));
}

// Read base and return type base
cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
{
    _cmsTagBase Base;

    _cmsAssert(io != NULL);

    if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
        return (cmsTagTypeSignature) 0;

    return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
}

// Setup base marker
cmsBool  CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig)
{
    _cmsTagBase  Base;

    _cmsAssert(io != NULL);

    Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig);
    memset(&Base.reserved, 0, sizeof(Base.reserved));
    return io -> Write(io, sizeof(_cmsTagBase), &Base);
}

cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
{
    cmsUInt8Number  Buffer[4];
    cmsUInt32Number NextAligned, At;
    cmsUInt32Number BytesToNextAlignedPos;

    _cmsAssert(io != NULL);

    At = io -> Tell(io);
    NextAligned = _cmsALIGNLONG(At);
    BytesToNextAlignedPos = NextAligned - At;
    if (BytesToNextAlignedPos == 0) return TRUE;
    if (BytesToNextAlignedPos > 4)  return FALSE;

    return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1);
}

cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io)
{
    cmsUInt8Number  Buffer[4];
    cmsUInt32Number NextAligned, At;
    cmsUInt32Number BytesToNextAlignedPos;

    _cmsAssert(io != NULL);

    At = io -> Tell(io);
    NextAligned = _cmsALIGNLONG(At);
    BytesToNextAlignedPos = NextAligned - At;
    if (BytesToNextAlignedPos == 0) return TRUE;
    if (BytesToNextAlignedPos > 4)  return FALSE;

    memset(Buffer, 0, BytesToNextAlignedPos);
    return io -> Write(io, BytesToNextAlignedPos, Buffer);
}


// To deal with text streams. 2K at most
cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
{
    va_list args;
    int len;
    cmsUInt8Number Buffer[2048];
    cmsBool rc;

    _cmsAssert(io != NULL);
    _cmsAssert(frm != NULL);

    va_start(args, frm);

    len = vsnprintf((char*) Buffer, 2047, frm, args);
    if (len < 0) {
        va_end(args);
        return FALSE;   // Truncated, which is a fatal error for us
    }

    rc = io ->Write(io, len, Buffer);

    va_end(args);

    return rc;
}


// Plugin memory management -------------------------------------------------------------------------------------------------

// Specialized malloc for plug-ins, that is freed upon exit.
void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
{
    struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);

    if (ctx ->MemPool == NULL) {

        if (ContextID == NULL) {

            ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
            if (ctx->MemPool == NULL) return NULL;
        }
        else {
            cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
            return NULL;
        }
    }

    return _cmsSubAlloc(ctx->MemPool, size);
}


// Main plug-in dispatcher
cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
{
    return cmsPluginTHR(NULL, Plug_in);
}

cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
{
    cmsPluginBase* Plugin;

    for (Plugin = (cmsPluginBase*) Plug_in;
         Plugin != NULL;
         Plugin = Plugin -> Next) {

            if (Plugin -> Magic != cmsPluginMagicNumber) {
                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
                return FALSE;
            }

            if (Plugin ->ExpectedVersion > LCMS_VERSION) {
                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
                    Plugin ->ExpectedVersion, LCMS_VERSION);
                return FALSE;
            }

            switch (Plugin -> Type) {

                case cmsPluginMemHandlerSig:
                    if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginInterpolationSig:
                    if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginTagTypeSig:
                    if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginTagSig:
                    if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginFormattersSig:
                    if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginRenderingIntentSig:
                    if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginParametricCurveSig:
                    if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginMultiProcessElementSig:
                    if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginOptimizationSig:
                    if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginTransformSig:
                    if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
                    break;

                case cmsPluginMutexSig:
                    if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
                    break;

                default:
                    cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
                    return FALSE;
            }
    }

    // Keep a reference to the plug-in
    return TRUE;
}


// Revert all plug-ins to default
void CMSEXPORT cmsUnregisterPlugins(void)
{
    cmsUnregisterPluginsTHR(NULL);
}


// The Global storage for system context. This is the one and only global variable
// pointers structure. All global vars are referenced here.
static struct _cmsContext_struct globalContext = {

    NULL,                              // Not in the linked list
    NULL,                              // No suballocator
    {
        NULL,                          //  UserPtr,            
        &_cmsLogErrorChunk,            //  Logger,
        &_cmsAlarmCodesChunk,          //  AlarmCodes,
        &_cmsAdaptationStateChunk,     //  AdaptationState, 
        &_cmsMemPluginChunk,           //  MemPlugin,
        &_cmsInterpPluginChunk,        //  InterpPlugin,
        &_cmsCurvesPluginChunk,        //  CurvesPlugin,
        &_cmsFormattersPluginChunk,    //  FormattersPlugin,
        &_cmsTagTypePluginChunk,       //  TagTypePlugin,
        &_cmsTagPluginChunk,           //  TagPlugin,
        &_cmsIntentsPluginChunk,       //  IntentPlugin,
        &_cmsMPETypePluginChunk,       //  MPEPlugin,
        &_cmsOptimizationPluginChunk,  //  OptimizationPlugin,
        &_cmsTransformPluginChunk,     //  TransformPlugin,
        &_cmsMutexPluginChunk          //  MutexPlugin
    },
    
    { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
};


// The context pool (linked list head)
static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
static struct _cmsContext_struct* _cmsContextPoolHead = NULL;

// Internal, get associated pointer, with guessing. Never returns NULL.
struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
{
    struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
    struct _cmsContext_struct* ctx;


    // On 0, use global settings
    if (id == NULL) 
        return &globalContext;

    // Search
    for (ctx = _cmsContextPoolHead;
         ctx != NULL;
         ctx = ctx ->Next) {

            // Found it?
            if (id == ctx)
                return ctx; // New-style context, 
    }

    return &globalContext;
}


// Internal: get the memory area associanted with each context client
// Returns the block assigned to the specific zone. Never return NULL.
void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
{
    struct _cmsContext_struct* ctx;
    void *ptr;

    if ((int) mc < 0 || mc >= MemoryClientMax) {
        
           cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption");

           // This is catastrophic. Should never reach here
           _cmsAssert(0);

           // Reverts to global context
           return globalContext.chunks[UserPtr];
    }
    
    ctx = _cmsGetContext(ContextID);
    ptr = ctx ->chunks[mc];

    if (ptr != NULL)
        return ptr;

    // A null ptr means no special settings for that context, and this 
    // reverts to Context0 globals
    return globalContext.chunks[mc];    
}


// This function returns the given context its default pristine state,
// as no plug-ins were declared. There is no way to unregister a single 
// plug-in, as a single call to cmsPluginTHR() function may register 
// many different plug-ins simultaneously, then there is no way to 
// identify which plug-in to unregister.
void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
{
    _cmsRegisterMemHandlerPlugin(ContextID, NULL);
    _cmsRegisterInterpPlugin(ContextID, NULL);
    _cmsRegisterTagTypePlugin(ContextID, NULL);
    _cmsRegisterTagPlugin(ContextID, NULL);
    _cmsRegisterFormattersPlugin(ContextID, NULL);
    _cmsRegisterRenderingIntentPlugin(ContextID, NULL);
    _cmsRegisterParametricCurvesPlugin(ContextID, NULL);
    _cmsRegisterMultiProcessElementPlugin(ContextID, NULL);
    _cmsRegisterOptimizationPlugin(ContextID, NULL);
    _cmsRegisterTransformPlugin(ContextID, NULL);    
    _cmsRegisterMutexPlugin(ContextID, NULL);
}


// Returns the memory manager plug-in, if any, from the Plug-in bundle
static
cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle)
{
    cmsPluginBase* Plugin;

    for (Plugin = (cmsPluginBase*) PluginBundle;
        Plugin != NULL;
        Plugin = Plugin -> Next) {

            if (Plugin -> Magic == cmsPluginMagicNumber && 
                Plugin -> ExpectedVersion <= LCMS_VERSION && 
                Plugin -> Type == cmsPluginMemHandlerSig) {

                    // Found!
                    return (cmsPluginMemHandler*) Plugin;  
            }
    }

    // Nope, revert to defaults 
    return NULL;
}


// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined 
// data that will be forwarded to plug-ins and logger.
cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
{
    struct _cmsContext_struct* ctx;
    struct _cmsContext_struct  fakeContext;
        
    _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
    
    fakeContext.chunks[UserPtr]     = UserData;
    fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;

    // Create the context structure.
    ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
    if (ctx == NULL)   
        return NULL;     // Something very wrong happened!

    // Init the structure and the memory manager
    memset(ctx, 0, sizeof(struct _cmsContext_struct));

    // Keep memory manager
    memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk)); 
   
    // Maintain the linked list (with proper locking)
    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
       ctx ->Next = _cmsContextPoolHead;
       _cmsContextPoolHead = ctx;
    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);

    ctx ->chunks[UserPtr]     = UserData;
    ctx ->chunks[MemPlugin]   = &ctx->DefaultMemoryManager;
   
    // Now we can allocate the pool by using default memory manager
    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));  // default size about 32 pointers
    if (ctx ->MemPool == NULL) {

         cmsDeleteContext(ctx);
        return NULL;
    }

    _cmsAllocLogErrorChunk(ctx, NULL);
    _cmsAllocAlarmCodesChunk(ctx, NULL);
    _cmsAllocAdaptationStateChunk(ctx, NULL);
    _cmsAllocMemPluginChunk(ctx, NULL);
    _cmsAllocInterpPluginChunk(ctx, NULL);
    _cmsAllocCurvesPluginChunk(ctx, NULL);
    _cmsAllocFormattersPluginChunk(ctx, NULL);
    _cmsAllocTagTypePluginChunk(ctx, NULL);
    _cmsAllocMPETypePluginChunk(ctx, NULL);
    _cmsAllocTagPluginChunk(ctx, NULL);
    _cmsAllocIntentsPluginChunk(ctx, NULL);
    _cmsAllocOptimizationPluginChunk(ctx, NULL);
    _cmsAllocTransformPluginChunk(ctx, NULL);
    _cmsAllocMutexPluginChunk(ctx, NULL);

    // Setup the plug-ins
    if (!cmsPluginTHR(ctx, Plugin)) {
    
        cmsDeleteContext(ctx);
        return NULL;
    }

    return (cmsContext) ctx;  
}

// Duplicates a context with all associated plug-ins. 
// Caller may specify an optional pointer to user-defined 
// data that will be forwarded to plug-ins and logger. 
cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
{
    int i;
    struct _cmsContext_struct* ctx;
    const struct _cmsContext_struct* src = _cmsGetContext(ContextID);

    void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr];
    
    
    ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct));
    if (ctx == NULL)   
        return NULL;     // Something very wrong happened

    // Setup default memory allocators
    memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));

    // Maintain the linked list
    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
       ctx ->Next = _cmsContextPoolHead;
       _cmsContextPoolHead = ctx;
    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);

    ctx ->chunks[UserPtr]    = userData;
    ctx ->chunks[MemPlugin]  = &ctx->DefaultMemoryManager;

    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));
    if (ctx ->MemPool == NULL) {

         cmsDeleteContext(ctx);
        return NULL;
    }

    // Allocate all required chunks.
    _cmsAllocLogErrorChunk(ctx, src);
    _cmsAllocAlarmCodesChunk(ctx, src);
    _cmsAllocAdaptationStateChunk(ctx, src);
    _cmsAllocMemPluginChunk(ctx, src);
    _cmsAllocInterpPluginChunk(ctx, src);
    _cmsAllocCurvesPluginChunk(ctx, src);
    _cmsAllocFormattersPluginChunk(ctx, src);
    _cmsAllocTagTypePluginChunk(ctx, src);
    _cmsAllocMPETypePluginChunk(ctx, src);
    _cmsAllocTagPluginChunk(ctx, src);
    _cmsAllocIntentsPluginChunk(ctx, src);
    _cmsAllocOptimizationPluginChunk(ctx, src);
    _cmsAllocTransformPluginChunk(ctx, src);
    _cmsAllocMutexPluginChunk(ctx, src);

    // Make sure no one failed
    for (i=Logger; i < MemoryClientMax; i++) {

        if (src ->chunks[i] == NULL) {
            cmsDeleteContext((cmsContext) ctx);
            return NULL;
        }
    }

    return (cmsContext) ctx;
}


/*
static
struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
{
    struct _cmsContext_struct* prev;

    // Search for previous
    for (prev = _cmsContextPoolHead; 
             prev != NULL;
             prev = prev ->Next)
    {
        if (prev ->Next == id)
            return prev;
    }

    return NULL;  // List is empty or only one element!
}
*/

// Frees any resources associated with the given context, 
// and destroys the context placeholder. 
// The ContextID can no longer be used in any THR operation.  
void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
{
    if (ContextID != NULL) {

        struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;              
        struct _cmsContext_struct  fakeContext;  
        struct _cmsContext_struct* prev;

        memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));

        fakeContext.chunks[UserPtr]     = ctx ->chunks[UserPtr];
        fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;

        // Get rid of plugins
        cmsUnregisterPluginsTHR(ContextID); 

        // Since all memory is allocated in the private pool, all what we need to do is destroy the pool
        if (ctx -> MemPool != NULL)
              _cmsSubAllocDestroy(ctx ->MemPool);
        ctx -> MemPool = NULL;

        // Maintain list
        _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
        if (_cmsContextPoolHead == ctx) { 

            _cmsContextPoolHead = ctx->Next;
        }
        else {

            // Search for previous
            for (prev = _cmsContextPoolHead; 
                 prev != NULL;
                 prev = prev ->Next)
            {
                if (prev -> Next == ctx) {
                    prev -> Next = ctx ->Next;
                    break;
                }
            }
        }
        _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);

        // free the memory block itself
        _cmsFree(&fakeContext, ctx);
    }
}

// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation
void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
{
    return _cmsContextGetClientChunk(ContextID, UserPtr);
}


