/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

// This file is available under and governed by the GNU General Public
// License version 2 only, as published by the Free Software Foundation.
// However, the following notice accompanied the original version of this
// file:
//
//---------------------------------------------------------------------------------
//
//  Little Color Management System
//  Copyright (c) 1998-2024 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 read/ 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)
{
    union typeConverter {
        cmsUInt32Number integer;
        cmsFloat32Number floating_point;
    } tmp;

    _cmsAssert(io != NULL);

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

    if (n != NULL) {

        tmp.integer = _cmsAdjustEndianess32(tmp.integer);
        *n = tmp.floating_point;

        // Safeguard which covers against absurd values
        if (*n > 1E+20 || *n < -1E+20) return FALSE;

        #if defined(_MSC_VER) && _MSC_VER < 1800
           return TRUE;
        #elif defined (__BORLANDC__)
           return TRUE;
        #elif !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L)
           return TRUE;
        #else

           // fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards)
           return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
        #endif
    }

    return TRUE;
}


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((cmsS15Fixed16Number) _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((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.X));
        XYZ->Y = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Y));
        XYZ->Z = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) 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)
{
    union typeConverter {
        cmsUInt32Number integer;
        cmsFloat32Number floating_point;
    } tmp;

    tmp.floating_point = n;
    tmp.integer = _cmsAdjustEndianess32(tmp.integer);
    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp.integer) != 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((cmsUInt32Number) _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 = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->X));
    xyz.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Y));
    xyz.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Z));

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

// from Fixed point 8.8 to double
cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
{
    return fixed8 / 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)
{
    return fix32 / 65536.0;
}

// 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;
    cmsUInt8Number* ptr;

    _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
    }

    // setlocale may be active, no commas are needed in PS generator
    // and PS generator is our only client
    for (ptr = Buffer; *ptr; ptr++)
    {
        if (*ptr == ',') *ptr = '.';
    }

    rc = io ->Write(io, (cmsUInt32Number) 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;

                case cmsPluginParalellizationSig:
                    if (!_cmsRegisterParallelizationPlugin(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,
        &_cmsParallelizationPluginChunk  //  ParallelizationPlugin
    },

    { 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;


// Make sure context is initialized (needed on windows)
static
cmsBool InitContextMutex(void)
{
    // See the comments regarding locking in lcms2_internal.h
    // for an explanation of why we need the following code.
#ifndef CMS_NO_PTHREADS
#ifdef CMS_IS_WINDOWS_
#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT

    static cmsBool already_initialized = FALSE;

    if (!already_initialized)
    {
        static HANDLE _cmsWindowsInitMutex = NULL;
        static volatile HANDLE* mutex = &_cmsWindowsInitMutex;

        if (*mutex == NULL)
        {
            HANDLE p = CreateMutex(NULL, FALSE, NULL);
            if (p && InterlockedCompareExchangePointer((void**)mutex, (void*)p, NULL) != NULL)
                CloseHandle(p);
        }
        if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
        {
            cmsSignalError(0, cmsERROR_INTERNAL, "Mutex lock failed");
            return FALSE;
        }
        if (((void**)&_cmsContextPoolHeadMutex)[0] == NULL)
            InitializeCriticalSection(&_cmsContextPoolHeadMutex);
        if (*mutex == NULL || !ReleaseMutex(*mutex))
        {
            cmsSignalError(0, cmsERROR_INTERNAL, "Mutex unlock failed");
            return FALSE;
        }
        already_initialized = TRUE;
    }
#endif
#endif
#endif

    return TRUE;
}



// 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;

    InitContextMutex();

    // Search
    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);

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

            // Found it?
        if (id == ctx)
        {
            _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
            return ctx; // New-style context
        }
    }

    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
    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);
    _cmsRegisterParallelizationPlugin(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;

    if (!InitContextMutex()) return NULL;

    _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 22 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);
    _cmsAllocParallelizationPluginChunk(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

    if (!InitContextMutex()) return NULL;

    // Setup default memory allocators
    if (ContextID == NULL)
        _cmsInstallAllocFunctions(NULL, &ctx->DefaultMemoryManager);
    else
        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);
    _cmsAllocParallelizationPluginChunk(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;
}


// 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) {

        cmsUnregisterPlugins();
        if (globalContext.MemPool != NULL)
            _cmsSubAllocDestroy(globalContext.MemPool);
        globalContext.MemPool = NULL;
    }
    else {

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


        InitContextMutex();

        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);
}


// Use context mutex to provide thread-safe time
cmsBool _cmsGetTime(struct tm* ptr_time)
{
    struct tm* t;
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
    struct tm tm;
#endif

    time_t now = time(NULL);

#ifdef HAVE_GMTIME_R
    t = gmtime_r(&now, &tm);
#elif defined(HAVE_GMTIME_S)
    t = gmtime_s(&tm, &now) == 0 ? &tm : NULL;
#else
    if (!InitContextMutex()) return FALSE;

    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
    t = gmtime(&now);
    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
#endif

    if (t == NULL)
        return FALSE;
    else {
        *ptr_time = *t;
        return TRUE;
    }
}
