Switch to libcms2-2.6
This commit is contained in:
545
thirdparty/liblcms2/src/cmsplugin.c
vendored
545
thirdparty/liblcms2/src/cmsplugin.c
vendored
@@ -3,22 +3,22 @@
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -44,7 +44,7 @@ cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word)
|
||||
tmp = pByte[0];
|
||||
pByte[0] = pByte[1];
|
||||
pByte[1] = tmp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return Word;
|
||||
}
|
||||
@@ -76,12 +76,12 @@ cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number DWord)
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 8 7 6 5 4 3 2 1
|
||||
|
||||
void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord)
|
||||
void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
|
||||
{
|
||||
|
||||
|
||||
#ifndef CMS_USE_BIG_ENDIAN
|
||||
|
||||
cmsUInt8Number* pIn = (cmsUInt8Number*) &QWord;
|
||||
|
||||
cmsUInt8Number* pIn = (cmsUInt8Number*) QWord;
|
||||
cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
@@ -91,15 +91,19 @@ void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number Q
|
||||
pOut[5] = pIn[2];
|
||||
pOut[4] = pIn[3];
|
||||
pOut[3] = pIn[4];
|
||||
pOut[2] = pIn[5];
|
||||
pOut[2] = pIn[5];
|
||||
pOut[1] = pIn[6];
|
||||
pOut[0] = pIn[7];
|
||||
|
||||
#else
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
|
||||
*Result = QWord;
|
||||
# ifdef CMS_DONT_USE_INT64
|
||||
(*Result)[0] = QWord[0];
|
||||
(*Result)[1] = QWord[1];
|
||||
# else
|
||||
*Result = *QWord;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -110,8 +114,8 @@ cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = tmp;
|
||||
return TRUE;
|
||||
@@ -123,8 +127,8 @@ cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
|
||||
return TRUE;
|
||||
@@ -155,8 +159,8 @@ cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
|
||||
return TRUE;
|
||||
@@ -168,8 +172,8 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
|
||||
@@ -186,10 +190,10 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) _cmsAdjustEndianess64(n, tmp);
|
||||
if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -200,8 +204,8 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
*n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
|
||||
@@ -250,9 +254,9 @@ cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
|
||||
{
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -263,9 +267,9 @@ cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess16(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -290,9 +294,9 @@ cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -305,22 +309,22 @@ cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
||||
|
||||
tmp = *(cmsUInt32Number*) &n;
|
||||
tmp = _cmsAdjustEndianess32(tmp);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n)
|
||||
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;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -331,16 +335,16 @@ cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
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);
|
||||
|
||||
@@ -365,7 +369,7 @@ cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
|
||||
cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
|
||||
{
|
||||
cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
|
||||
return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
|
||||
return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
|
||||
}
|
||||
|
||||
// from Fixed point 15.16 to double
|
||||
@@ -386,13 +390,13 @@ cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
|
||||
return sign * floater;
|
||||
}
|
||||
|
||||
// from double to Fixed point 15.16
|
||||
// from double to Fixed point 15.16
|
||||
cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
|
||||
{
|
||||
return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
|
||||
}
|
||||
|
||||
// Date/Time functions
|
||||
// Date/Time functions
|
||||
|
||||
void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
|
||||
{
|
||||
@@ -431,7 +435,7 @@ cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
|
||||
if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
|
||||
return (cmsTagTypeSignature) 0;
|
||||
|
||||
return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
|
||||
@@ -454,7 +458,7 @@ cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
|
||||
cmsUInt8Number Buffer[4];
|
||||
cmsUInt32Number NextAligned, At;
|
||||
cmsUInt32Number BytesToNextAlignedPos;
|
||||
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
At = io -> Tell(io);
|
||||
@@ -502,7 +506,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
if (len < 0) return FALSE; // Truncated, which is a fatal error for us
|
||||
|
||||
rc = io ->Write(io, len, Buffer);
|
||||
|
||||
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
@@ -511,80 +515,102 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
|
||||
// Plugin memory management -------------------------------------------------------------------------------------------------
|
||||
|
||||
static _cmsSubAllocator* PluginPool = NULL;
|
||||
|
||||
// Specialized malloc for plug-ins, that is freed upon exit.
|
||||
void* _cmsPluginMalloc(cmsUInt32Number size)
|
||||
void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
if (PluginPool == NULL)
|
||||
PluginPool = _cmsCreateSubAlloc(0, 4*1024);
|
||||
struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
|
||||
|
||||
return _cmsSubAlloc(PluginPool, size);
|
||||
if (ctx ->MemPool == NULL) {
|
||||
|
||||
if (ContextID == NULL) {
|
||||
|
||||
ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
|
||||
}
|
||||
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;
|
||||
for (Plugin = (cmsPluginBase*) Plug_in;
|
||||
Plugin != NULL;
|
||||
Plugin = Plugin -> Next) {
|
||||
|
||||
if (Plugin -> Magic != cmsPluginMagicNumber) {
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
|
||||
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Plugin ->ExpectedVersion > LCMS_VERSION) {
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
|
||||
Plugin ->ExpectedVersion, LCMS_VERSION);
|
||||
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(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginInterpolationSig:
|
||||
if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
|
||||
case cmsPluginTagTypeSig:
|
||||
if (!_cmsRegisterTagTypePlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
|
||||
case cmsPluginTagSig:
|
||||
if (!_cmsRegisterTagPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginFormattersSig:
|
||||
if (!_cmsRegisterFormattersPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginRenderingIntentSig:
|
||||
if (!_cmsRegisterRenderingIntentPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginParametricCurveSig:
|
||||
if (!_cmsRegisterParametricCurvesPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginMultiProcessElementSig:
|
||||
if (!_cmsRegisterMultiProcessElementPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginOptimizationSig:
|
||||
if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE;
|
||||
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(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a reference to the plug-in
|
||||
@@ -595,18 +621,337 @@ cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
|
||||
// Revert all plug-ins to default
|
||||
void CMSEXPORT cmsUnregisterPlugins(void)
|
||||
{
|
||||
_cmsRegisterMemHandlerPlugin(NULL);
|
||||
_cmsRegisterInterpPlugin(NULL);
|
||||
_cmsRegisterTagTypePlugin(NULL);
|
||||
_cmsRegisterTagPlugin(NULL);
|
||||
_cmsRegisterFormattersPlugin(NULL);
|
||||
_cmsRegisterRenderingIntentPlugin(NULL);
|
||||
_cmsRegisterParametricCurvesPlugin(NULL);
|
||||
_cmsRegisterMultiProcessElementPlugin(NULL);
|
||||
_cmsRegisterOptimizationPlugin(NULL);
|
||||
|
||||
if (PluginPool != NULL)
|
||||
_cmsSubAllocDestroy(PluginPool);
|
||||
|
||||
PluginPool = NULL;
|
||||
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.
|
||||
void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
|
||||
{
|
||||
struct _cmsContext_struct* ctx;
|
||||
void *ptr;
|
||||
|
||||
if (mc < 0 || mc >= MemoryClientMax) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user