mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-02 13:53:37 +00:00
lcms2: Import upstream release 2.14.
This commit is contained in:
parent
cfe8ee571d
commit
fd3017ff5b
|
@ -23,7 +23,7 @@
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Version 2.13.1
|
// Version 2.14
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _lcms2_H
|
#ifndef _lcms2_H
|
||||||
|
@ -81,7 +81,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Version/release
|
// Version/release
|
||||||
#define LCMS_VERSION 2131
|
#define LCMS_VERSION 2140
|
||||||
|
|
||||||
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
||||||
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
||||||
|
@ -152,7 +152,7 @@ typedef double cmsFloat64Number;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Handle "register" keyword
|
// Handle "register" keyword
|
||||||
#if defined(CMS_NO_REGISTER_KEYWORD) && !defined(CMS_DLL) && !defined(CMS_DLL_BUILD)
|
#if defined(CMS_NO_REGISTER_KEYWORD)
|
||||||
# define CMSREGISTER
|
# define CMSREGISTER
|
||||||
#else
|
#else
|
||||||
# define CMSREGISTER register
|
# define CMSREGISTER register
|
||||||
|
@ -290,6 +290,7 @@ typedef int cmsBool;
|
||||||
// Base ICC type definitions
|
// Base ICC type definitions
|
||||||
typedef enum {
|
typedef enum {
|
||||||
cmsSigChromaticityType = 0x6368726D, // 'chrm'
|
cmsSigChromaticityType = 0x6368726D, // 'chrm'
|
||||||
|
cmsSigcicpType = 0x63696370, // 'cicp'
|
||||||
cmsSigColorantOrderType = 0x636C726F, // 'clro'
|
cmsSigColorantOrderType = 0x636C726F, // 'clro'
|
||||||
cmsSigColorantTableType = 0x636C7274, // 'clrt'
|
cmsSigColorantTableType = 0x636C7274, // 'clrt'
|
||||||
cmsSigCrdInfoType = 0x63726469, // 'crdi'
|
cmsSigCrdInfoType = 0x63726469, // 'crdi'
|
||||||
|
@ -401,6 +402,7 @@ typedef enum {
|
||||||
cmsSigViewingConditionsTag = 0x76696577, // 'view'
|
cmsSigViewingConditionsTag = 0x76696577, // 'view'
|
||||||
cmsSigVcgtTag = 0x76636774, // 'vcgt'
|
cmsSigVcgtTag = 0x76636774, // 'vcgt'
|
||||||
cmsSigMetaTag = 0x6D657461, // 'meta'
|
cmsSigMetaTag = 0x6D657461, // 'meta'
|
||||||
|
cmsSigcicpTag = 0x63696370, // 'cicp'
|
||||||
cmsSigArgyllArtsTag = 0x61727473 // 'arts'
|
cmsSigArgyllArtsTag = 0x61727473 // 'arts'
|
||||||
|
|
||||||
} cmsTagSignature;
|
} cmsTagSignature;
|
||||||
|
@ -1038,6 +1040,16 @@ typedef struct {
|
||||||
|
|
||||||
} cmsICCViewingConditions;
|
} cmsICCViewingConditions;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
cmsUInt8Number ColourPrimaries; // Recommendation ITU-T H.273
|
||||||
|
cmsUInt8Number TransferCharacteristics; // (ISO/IEC 23091-2)
|
||||||
|
cmsUInt8Number MatrixCoefficients;
|
||||||
|
cmsUInt8Number VideoFullRangeFlag;
|
||||||
|
|
||||||
|
} cmsVideoSignalType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get LittleCMS version (for shared objects) -----------------------------------------------------------------------------
|
// Get LittleCMS version (for shared objects) -----------------------------------------------------------------------------
|
||||||
|
|
||||||
CMSAPI int CMSEXPORT cmsGetEncodedCMMversion(void);
|
CMSAPI int CMSEXPORT cmsGetEncodedCMMversion(void);
|
||||||
|
@ -1520,8 +1532,12 @@ CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Numb
|
||||||
CMSAPI cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation);
|
CMSAPI cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation);
|
||||||
CMSAPI int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace);
|
CMSAPI int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace);
|
||||||
|
|
||||||
|
// Deprecated, use cmsChannelsOfColorSpace instead
|
||||||
CMSAPI cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace);
|
CMSAPI cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace);
|
||||||
|
|
||||||
|
// Get number of channels of color space or -1 if color space is not listed/supported
|
||||||
|
CMSAPI cmsInt32Number CMSEXPORT cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace);
|
||||||
|
|
||||||
// Build a suitable formatter for the colorspace of this profile. nBytes=1 means 8 bits, nBytes=2 means 16 bits.
|
// Build a suitable formatter for the colorspace of this profile. nBytes=1 means 8 bits, nBytes=2 means 16 bits.
|
||||||
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
|
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
|
||||||
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
|
CMSAPI cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat);
|
||||||
|
|
|
@ -209,6 +209,7 @@ typedef void* (* _cmsDupUserDataFn)(cmsContext ContextID, const void* Data);
|
||||||
#define cmsPluginOptimizationSig 0x6F707448 // 'optH'
|
#define cmsPluginOptimizationSig 0x6F707448 // 'optH'
|
||||||
#define cmsPluginTransformSig 0x7A666D48 // 'xfmH'
|
#define cmsPluginTransformSig 0x7A666D48 // 'xfmH'
|
||||||
#define cmsPluginMutexSig 0x6D747A48 // 'mtxH'
|
#define cmsPluginMutexSig 0x6D747A48 // 'mtxH'
|
||||||
|
#define cmsPluginParalellizationSig 0x70726C48 // 'prlH
|
||||||
|
|
||||||
typedef struct _cmsPluginBaseStruct {
|
typedef struct _cmsPluginBaseStruct {
|
||||||
|
|
||||||
|
@ -596,7 +597,7 @@ typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo, //
|
||||||
const void* InputBuffer,
|
const void* InputBuffer,
|
||||||
void* OutputBuffer,
|
void* OutputBuffer,
|
||||||
cmsUInt32Number Size,
|
cmsUInt32Number Size,
|
||||||
cmsUInt32Number Stride); // Stride in bytes to the next plana in planar formats
|
cmsUInt32Number Stride); // Stride in bytes to the next plane in planar formats
|
||||||
|
|
||||||
|
|
||||||
typedef void (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo,
|
typedef void (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo,
|
||||||
|
@ -669,6 +670,25 @@ CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx);
|
||||||
CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx);
|
CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx);
|
||||||
CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx);
|
CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
// Parallelization
|
||||||
|
|
||||||
|
CMSAPI _cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo);
|
||||||
|
CMSAPI cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo);
|
||||||
|
CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo);
|
||||||
|
|
||||||
|
// Let's plug-in to guess the best number of workers
|
||||||
|
#define CMS_GUESS_MAX_WORKERS -1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
cmsPluginBase base;
|
||||||
|
|
||||||
|
cmsInt32Number MaxWorkers; // Number of starts to do as maximum
|
||||||
|
cmsUInt32Number WorkerFlags; // Reserved
|
||||||
|
_cmsTransform2Fn SchedulerFn; // callback to setup functions
|
||||||
|
|
||||||
|
} cmsPluginParalellization;
|
||||||
|
|
||||||
|
|
||||||
#ifndef CMS_USE_CPP_API
|
#ifndef CMS_USE_CPP_API
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
|
|
|
@ -386,7 +386,7 @@ cmsBool ComputeConversion(cmsUInt32Number i,
|
||||||
|
|
||||||
if (BPC) {
|
if (BPC) {
|
||||||
|
|
||||||
cmsCIEXYZ BlackPointIn, BlackPointOut;
|
cmsCIEXYZ BlackPointIn = { 0, 0, 0}, BlackPointOut = { 0, 0, 0 };
|
||||||
|
|
||||||
cmsDetectBlackPoint(&BlackPointIn, hProfiles[i-1], Intent, 0);
|
cmsDetectBlackPoint(&BlackPointIn, hProfiles[i-1], Intent, 0);
|
||||||
cmsDetectDestinationBlackPoint(&BlackPointOut, hProfiles[i], Intent, 0);
|
cmsDetectDestinationBlackPoint(&BlackPointOut, hProfiles[i], Intent, 0);
|
||||||
|
@ -630,7 +630,7 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
|
||||||
ColorSpaceOut == cmsSigRgbData ||
|
ColorSpaceOut == cmsSigRgbData ||
|
||||||
ColorSpaceOut == cmsSigCmykData) {
|
ColorSpaceOut == cmsSigCmykData) {
|
||||||
|
|
||||||
cmsStage* clip = _cmsStageClipNegatives(Result->ContextID, cmsChannelsOf(ColorSpaceOut));
|
cmsStage* clip = _cmsStageClipNegatives(Result->ContextID, cmsChannelsOfColorSpace(ColorSpaceOut));
|
||||||
if (clip == NULL) goto Error;
|
if (clip == NULL) goto Error;
|
||||||
|
|
||||||
if (!cmsPipelineInsertStage(Result, cmsAT_END, clip))
|
if (!cmsPipelineInsertStage(Result, cmsAT_END, clip))
|
||||||
|
|
|
@ -613,7 +613,6 @@ cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data)
|
||||||
if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL ||
|
if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL ||
|
||||||
Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE;
|
Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE;
|
||||||
|
|
||||||
|
|
||||||
ctx->CreateMutexPtr = Plugin->CreateMutexPtr;
|
ctx->CreateMutexPtr = Plugin->CreateMutexPtr;
|
||||||
ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr;
|
ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr;
|
||||||
ctx ->LockMutexPtr = Plugin ->LockMutexPtr;
|
ctx ->LockMutexPtr = Plugin ->LockMutexPtr;
|
||||||
|
@ -661,3 +660,46 @@ void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx)
|
||||||
ptr ->UnlockMutexPtr(ContextID, mtx);
|
ptr ->UnlockMutexPtr(ContextID, mtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The global Context0 storage for parallelization plug-in
|
||||||
|
_cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk = { 0 };
|
||||||
|
|
||||||
|
// Allocate parallelization container.
|
||||||
|
void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx,
|
||||||
|
const struct _cmsContext_struct* src)
|
||||||
|
{
|
||||||
|
if (src != NULL) {
|
||||||
|
void* from = src->chunks[ParallelizationPlugin];
|
||||||
|
ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, from, sizeof(_cmsParallelizationPluginChunkType));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_cmsParallelizationPluginChunkType ParallelizationPluginChunk = { 0 };
|
||||||
|
ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &ParallelizationPluginChunk, sizeof(_cmsParallelizationPluginChunkType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register parallel processing
|
||||||
|
cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Data)
|
||||||
|
{
|
||||||
|
cmsPluginParalellization* Plugin = (cmsPluginParalellization*)Data;
|
||||||
|
_cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(ContextID, ParallelizationPlugin);
|
||||||
|
|
||||||
|
if (Data == NULL) {
|
||||||
|
|
||||||
|
// No parallelization routines
|
||||||
|
ctx->MaxWorkers = 0;
|
||||||
|
ctx->WorkerFlags = 0;
|
||||||
|
ctx->SchedulerFn = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// callback is required
|
||||||
|
if (Plugin->SchedulerFn == NULL) return FALSE;
|
||||||
|
|
||||||
|
ctx->MaxWorkers = Plugin->MaxWorkers;
|
||||||
|
ctx->WorkerFlags = Plugin->WorkerFlags;
|
||||||
|
ctx->SchedulerFn = Plugin->SchedulerFn;
|
||||||
|
|
||||||
|
// All is ok
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -427,8 +427,8 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||||
|
|
||||||
|
|
||||||
// IEC 61966-3
|
// IEC 61966-3
|
||||||
// Y = (aX + b)^Gamma | X <= -b/a
|
// Y = (aX + b)^Gamma + c | X <= -b/a
|
||||||
// Y = c | else
|
// Y = c | else
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||||
|
@ -462,7 +462,8 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||||
// X=-b/a | (Y<c)
|
// X=-b/a | (Y<c)
|
||||||
case -3:
|
case -3:
|
||||||
{
|
{
|
||||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||||
|
fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||||
{
|
{
|
||||||
Val = 0;
|
Val = 0;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +602,8 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||||
// ((Y - c) ^1/Gamma - b) / a
|
// ((Y - c) ^1/Gamma - b) / a
|
||||||
case -6:
|
case -6:
|
||||||
{
|
{
|
||||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||||
|
fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||||
{
|
{
|
||||||
Val = 0;
|
Val = 0;
|
||||||
}
|
}
|
||||||
|
@ -1473,6 +1475,9 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Num
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need enough valid samples
|
||||||
|
if (n <= 1) return -1.0;
|
||||||
|
|
||||||
// Take a look on SD to see if gamma isn't exponential at all
|
// Take a look on SD to see if gamma isn't exponential at all
|
||||||
Std = sqrt((n * sum2 - sum * sum) / (n*(n-1)));
|
Std = sqrt((n * sum2 - sum * sum) / (n*(n-1)));
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,8 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||||
cmsStage* CLUT;
|
cmsStage* CLUT;
|
||||||
cmsUInt32Number dwFormat;
|
cmsUInt32Number dwFormat;
|
||||||
GAMUTCHAIN Chain;
|
GAMUTCHAIN Chain;
|
||||||
cmsUInt32Number nChannels, nGridpoints;
|
cmsUInt32Number nGridpoints;
|
||||||
|
cmsInt32Number nChannels;
|
||||||
cmsColorSpaceSignature ColorSpace;
|
cmsColorSpaceSignature ColorSpace;
|
||||||
cmsUInt32Number i;
|
cmsUInt32Number i;
|
||||||
cmsHPROFILE ProfileList[256];
|
cmsHPROFILE ProfileList[256];
|
||||||
|
@ -346,8 +347,7 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||||
|
|
||||||
|
|
||||||
ColorSpace = cmsGetColorSpace(hGamut);
|
ColorSpace = cmsGetColorSpace(hGamut);
|
||||||
|
nChannels = cmsChannelsOfColorSpace(ColorSpace);
|
||||||
nChannels = cmsChannelsOf(ColorSpace);
|
|
||||||
nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
|
nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
|
||||||
dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2));
|
dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2));
|
||||||
|
|
||||||
|
@ -472,6 +472,9 @@ cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile)
|
||||||
// Create a fake formatter for result
|
// Create a fake formatter for result
|
||||||
dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE);
|
dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE);
|
||||||
|
|
||||||
|
// Unsupported color space?
|
||||||
|
if (dwFormatter == 0) return 0;
|
||||||
|
|
||||||
bp.nOutputChans = T_CHANNELS(dwFormatter);
|
bp.nOutputChans = T_CHANNELS(dwFormatter);
|
||||||
bp.MaxTAC = 0; // Initial TAC is 0
|
bp.MaxTAC = 0; // Initial TAC is 0
|
||||||
|
|
||||||
|
@ -619,6 +622,8 @@ cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsHPROFILE hProfile, cmsFlo
|
||||||
|
|
||||||
ContextID = cmsGetProfileContextID(hProfile);
|
ContextID = cmsGetProfileContextID(hProfile);
|
||||||
hXYZ = cmsCreateXYZProfileTHR(ContextID);
|
hXYZ = cmsCreateXYZProfileTHR(ContextID);
|
||||||
|
if (hXYZ == NULL)
|
||||||
|
return -1;
|
||||||
xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_RGB_16, hXYZ, TYPE_XYZ_DBL,
|
xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_RGB_16, hXYZ, TYPE_XYZ_DBL,
|
||||||
INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE);
|
INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE);
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ static const cmsUInt32Number Mantissa[2048] = {
|
||||||
0x387fc000, 0x387fe000
|
0x387fc000, 0x387fe000
|
||||||
};
|
};
|
||||||
|
|
||||||
static cmsUInt16Number Offset[64] = {
|
static const cmsUInt16Number Offset[64] = {
|
||||||
0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||||
|
|
|
@ -375,6 +375,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
||||||
cmsIOHANDLER* iohandler = NULL;
|
cmsIOHANDLER* iohandler = NULL;
|
||||||
FILE* fm = NULL;
|
FILE* fm = NULL;
|
||||||
cmsInt32Number fileLen;
|
cmsInt32Number fileLen;
|
||||||
|
char mode[4] = { 0,0,0,0 };
|
||||||
|
|
||||||
_cmsAssert(FileName != NULL);
|
_cmsAssert(FileName != NULL);
|
||||||
_cmsAssert(AccessMode != NULL);
|
_cmsAssert(AccessMode != NULL);
|
||||||
|
@ -382,16 +383,49 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
||||||
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
|
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
|
||||||
if (iohandler == NULL) return NULL;
|
if (iohandler == NULL) return NULL;
|
||||||
|
|
||||||
switch (*AccessMode) {
|
// Validate access mode
|
||||||
|
while (*AccessMode) {
|
||||||
|
|
||||||
|
switch (*AccessMode)
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
case 'w':
|
||||||
|
|
||||||
|
if (mode[0] == 0) {
|
||||||
|
mode[0] = *AccessMode;
|
||||||
|
mode[1] = 'b';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_cmsFree(ContextID, iohandler);
|
||||||
|
cmsSignalError(ContextID, cmsERROR_FILE, "Access mode already specified '%c'", *AccessMode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Close on exec. Not all runtime supports that. Up to the caller to decide.
|
||||||
|
case 'e':
|
||||||
|
mode[2] = 'e';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_cmsFree(ContextID, iohandler);
|
||||||
|
cmsSignalError(ContextID, cmsERROR_FILE, "Wrong access mode '%c'", *AccessMode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessMode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode[0]) {
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
fm = fopen(FileName, "rb");
|
fm = fopen(FileName, mode);
|
||||||
if (fm == NULL) {
|
if (fm == NULL) {
|
||||||
_cmsFree(ContextID, iohandler);
|
_cmsFree(ContextID, iohandler);
|
||||||
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
|
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fileLen = cmsfilelength(fm);
|
fileLen = (cmsInt32Number)cmsfilelength(fm);
|
||||||
if (fileLen < 0)
|
if (fileLen < 0)
|
||||||
{
|
{
|
||||||
fclose(fm);
|
fclose(fm);
|
||||||
|
@ -399,12 +433,11 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
||||||
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
|
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
|
iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
fm = fopen(FileName, "wb");
|
fm = fopen(FileName, mode);
|
||||||
if (fm == NULL) {
|
if (fm == NULL) {
|
||||||
_cmsFree(ContextID, iohandler);
|
_cmsFree(ContextID, iohandler);
|
||||||
cmsSignalError(ContextID, cmsERROR_FILE, "Couldn't create '%s'", FileName);
|
cmsSignalError(ContextID, cmsERROR_FILE, "Couldn't create '%s'", FileName);
|
||||||
|
@ -414,8 +447,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_cmsFree(ContextID, iohandler);
|
_cmsFree(ContextID, iohandler); // Would never reach
|
||||||
cmsSignalError(ContextID, cmsERROR_FILE, "Unknown access mode '%c'", *AccessMode);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +474,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* S
|
||||||
cmsIOHANDLER* iohandler = NULL;
|
cmsIOHANDLER* iohandler = NULL;
|
||||||
cmsInt32Number fileSize;
|
cmsInt32Number fileSize;
|
||||||
|
|
||||||
fileSize = cmsfilelength(Stream);
|
fileSize = (cmsInt32Number)cmsfilelength(Stream);
|
||||||
if (fileSize < 0)
|
if (fileSize < 0)
|
||||||
{
|
{
|
||||||
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
|
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
|
||||||
|
@ -499,6 +531,9 @@ cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
|
||||||
// Set default version
|
// Set default version
|
||||||
Icc ->Version = 0x02100000;
|
Icc ->Version = 0x02100000;
|
||||||
|
|
||||||
|
// Set default device class
|
||||||
|
Icc->DeviceClass = cmsSigDisplayClass;
|
||||||
|
|
||||||
// Set creation date/time
|
// Set creation date/time
|
||||||
if (!_cmsGetTime(&Icc->Created))
|
if (!_cmsGetTime(&Icc->Created))
|
||||||
goto Error;
|
goto Error;
|
||||||
|
@ -657,6 +692,27 @@ cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||||
return _cmsSearchTag(Icc, sig, FALSE) >= 0;
|
return _cmsSearchTag(Icc, sig, FALSE) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Checks for link compatibility
|
||||||
|
static
|
||||||
|
cmsBool CompatibleTypes(const cmsTagDescriptor* desc1, const cmsTagDescriptor* desc2)
|
||||||
|
{
|
||||||
|
cmsUInt32Number i;
|
||||||
|
|
||||||
|
if (desc1 == NULL || desc2 == NULL) return FALSE;
|
||||||
|
|
||||||
|
if (desc1->nSupportedTypes != desc2->nSupportedTypes) return FALSE;
|
||||||
|
if (desc1->ElemCount != desc2->ElemCount) return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < desc1->nSupportedTypes; i++)
|
||||||
|
{
|
||||||
|
if (desc1->SupportedTypes[i] != desc2->SupportedTypes[i]) return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Enforces that the profile version is per. spec.
|
// Enforces that the profile version is per. spec.
|
||||||
// Operates on the big endian bytes from the profile.
|
// Operates on the big endian bytes from the profile.
|
||||||
// Called before converting to platform endianness.
|
// Called before converting to platform endianness.
|
||||||
|
@ -682,6 +738,29 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
|
||||||
return DWord;
|
return DWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check device class
|
||||||
|
static
|
||||||
|
cmsBool validDeviceClass(cmsProfileClassSignature cl)
|
||||||
|
{
|
||||||
|
if ((int)cl == 0) return TRUE; // We allow zero because older lcms versions defaulted to that.
|
||||||
|
|
||||||
|
switch (cl)
|
||||||
|
{
|
||||||
|
case cmsSigInputClass:
|
||||||
|
case cmsSigDisplayClass:
|
||||||
|
case cmsSigOutputClass:
|
||||||
|
case cmsSigLinkClass:
|
||||||
|
case cmsSigAbstractClass:
|
||||||
|
case cmsSigColorSpaceClass:
|
||||||
|
case cmsSigNamedColorClass:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Read profile header and validate it
|
// Read profile header and validate it
|
||||||
cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
||||||
{
|
{
|
||||||
|
@ -718,6 +797,16 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
||||||
_cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes);
|
_cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes);
|
||||||
Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version));
|
Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version));
|
||||||
|
|
||||||
|
if (Icc->Version > 0x5000000) {
|
||||||
|
cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported profile version '0x%x'", Icc->Version);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validDeviceClass(Icc->DeviceClass)) {
|
||||||
|
cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported device class '0x%x'", Icc->DeviceClass);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Get size as reported in header
|
// Get size as reported in header
|
||||||
HeaderSize = _cmsAdjustEndianess32(Header.size);
|
HeaderSize = _cmsAdjustEndianess32(Header.size);
|
||||||
|
|
||||||
|
@ -751,6 +840,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
||||||
if (!_cmsReadUInt32Number(io, &Tag.size)) return FALSE;
|
if (!_cmsReadUInt32Number(io, &Tag.size)) return FALSE;
|
||||||
|
|
||||||
// Perform some sanity check. Offset + size should fall inside file.
|
// Perform some sanity check. Offset + size should fall inside file.
|
||||||
|
if (Tag.size == 0 || Tag.offset == 0) continue;
|
||||||
if (Tag.offset + Tag.size > HeaderSize ||
|
if (Tag.offset + Tag.size > HeaderSize ||
|
||||||
Tag.offset + Tag.size < Tag.offset)
|
Tag.offset + Tag.size < Tag.offset)
|
||||||
continue;
|
continue;
|
||||||
|
@ -765,7 +855,12 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
||||||
if ((Icc ->TagOffsets[j] == Tag.offset) &&
|
if ((Icc ->TagOffsets[j] == Tag.offset) &&
|
||||||
(Icc ->TagSizes[j] == Tag.size)) {
|
(Icc ->TagSizes[j] == Tag.size)) {
|
||||||
|
|
||||||
Icc ->TagLinked[Icc ->TagCount] = Icc ->TagNames[j];
|
// Check types.
|
||||||
|
if (CompatibleTypes(_cmsGetTagDescriptor(Icc->ContextID, Icc->TagNames[j]),
|
||||||
|
_cmsGetTagDescriptor(Icc->ContextID, Tag.sig))) {
|
||||||
|
|
||||||
|
Icc->TagLinked[Icc->TagCount] = Icc->TagNames[j];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -773,6 +868,19 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
||||||
Icc ->TagCount++;
|
Icc ->TagCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < Icc->TagCount; i++) {
|
||||||
|
for (j = 0; j < Icc->TagCount; j++) {
|
||||||
|
|
||||||
|
// Tags cannot be duplicate
|
||||||
|
if ((i != j) && (Icc->TagNames[i] == Icc->TagNames[j])) {
|
||||||
|
cmsSignalError(Icc->ContextID, cmsERROR_RANGE, "Duplicate tag found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1558,6 +1666,13 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||||
if (TagSize < 8) goto Error;
|
if (TagSize < 8) goto Error;
|
||||||
|
|
||||||
io = Icc ->IOhandler;
|
io = Icc ->IOhandler;
|
||||||
|
|
||||||
|
if (io == NULL) { // This is a built-in profile that has been manipulated, abort early
|
||||||
|
|
||||||
|
cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted built-in profile.");
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
// Seek to its location
|
// Seek to its location
|
||||||
if (!io -> Seek(io, Offset))
|
if (!io -> Seek(io, Offset))
|
||||||
goto Error;
|
goto Error;
|
||||||
|
@ -1769,11 +1884,9 @@ Error:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and write raw data. The only way those function would work and keep consistence with normal read and write
|
// Read and write raw data. Read/Write Raw/cooked pairs try to maintain consistency within the pair. Some sequences
|
||||||
// is to do an additional step of serialization. That means, readRaw would issue a normal read and then convert the obtained
|
// raw/cooked would work, but at a cost. Data "cooked" may be converted to "raw" by using the "write" serialization logic.
|
||||||
// data to raw bytes by using the "write" serialization logic. And vice-versa. I know this may end in situations where
|
// In general it is better to avoid mixing pairs.
|
||||||
// raw data written does not exactly correspond with the raw data proposed to cmsWriteRaw data, but this approach allows
|
|
||||||
// to write a tag as raw data and the read it as handled.
|
|
||||||
|
|
||||||
cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize)
|
cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize)
|
||||||
{
|
{
|
||||||
|
@ -1787,9 +1900,13 @@ cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature si
|
||||||
cmsUInt32Number rc;
|
cmsUInt32Number rc;
|
||||||
cmsUInt32Number Offset, TagSize;
|
cmsUInt32Number Offset, TagSize;
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (data != NULL && BufferSize == 0) return 0;
|
||||||
|
|
||||||
if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
|
if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
|
||||||
|
|
||||||
// Search for given tag in ICC profile directory
|
// Search for given tag in ICC profile directory
|
||||||
|
|
||||||
i = _cmsSearchTag(Icc, sig, TRUE);
|
i = _cmsSearchTag(Icc, sig, TRUE);
|
||||||
if (i < 0) goto Error; // Not found,
|
if (i < 0) goto Error; // Not found,
|
||||||
|
|
||||||
|
@ -1801,10 +1918,11 @@ cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature si
|
||||||
TagSize = Icc ->TagSizes[i];
|
TagSize = Icc ->TagSizes[i];
|
||||||
|
|
||||||
// read the data directly, don't keep copy
|
// read the data directly, don't keep copy
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
|
|
||||||
if (BufferSize < TagSize)
|
if (BufferSize < TagSize)
|
||||||
TagSize = BufferSize;
|
goto Error;
|
||||||
|
|
||||||
if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
|
if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
|
||||||
if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
|
if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
|
||||||
|
@ -1819,13 +1937,14 @@ cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature si
|
||||||
|
|
||||||
// The data has been already read, or written. But wait!, maybe the user chose to save as
|
// The data has been already read, or written. But wait!, maybe the user chose to save as
|
||||||
// raw data. In this case, return the raw data directly
|
// raw data. In this case, return the raw data directly
|
||||||
|
|
||||||
if (Icc ->TagSaveAsRaw[i]) {
|
if (Icc ->TagSaveAsRaw[i]) {
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
|
|
||||||
TagSize = Icc ->TagSizes[i];
|
TagSize = Icc ->TagSizes[i];
|
||||||
if (BufferSize < TagSize)
|
if (BufferSize < TagSize)
|
||||||
TagSize = BufferSize;
|
goto Error;
|
||||||
|
|
||||||
memmove(data, Icc ->TagPtrs[i], TagSize);
|
memmove(data, Icc ->TagPtrs[i], TagSize);
|
||||||
|
|
||||||
|
@ -1838,7 +1957,7 @@ cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature si
|
||||||
}
|
}
|
||||||
|
|
||||||
// Already read, or previously set by cmsWriteTag(). We need to serialize that
|
// Already read, or previously set by cmsWriteTag(). We need to serialize that
|
||||||
// data to raw in order to maintain consistency.
|
// data to raw to get something that makes sense
|
||||||
|
|
||||||
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
|
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
|
||||||
Object = cmsReadTag(hProfile, sig);
|
Object = cmsReadTag(hProfile, sig);
|
||||||
|
|
|
@ -322,10 +322,8 @@ cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number In
|
||||||
if (nc == NULL) return NULL;
|
if (nc == NULL) return NULL;
|
||||||
|
|
||||||
Lut = cmsPipelineAlloc(ContextID, 0, 0);
|
Lut = cmsPipelineAlloc(ContextID, 0, 0);
|
||||||
if (Lut == NULL) {
|
if (Lut == NULL)
|
||||||
cmsFreeNamedColorList(nc);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) ||
|
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) ||
|
||||||
!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) {
|
!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) {
|
||||||
|
@ -740,7 +738,6 @@ cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Numb
|
||||||
return Lut;
|
return Lut;
|
||||||
Error:
|
Error:
|
||||||
cmsPipelineFree(Lut);
|
cmsPipelineFree(Lut);
|
||||||
cmsFreeNamedColorList(nc);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,7 +467,7 @@ cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
|
||||||
for (rv = 1; b > 0; b--) {
|
for (rv = 1; b > 0; b--) {
|
||||||
|
|
||||||
dim = Dims[b-1];
|
dim = Dims[b-1];
|
||||||
if (dim == 0) return 0; // Error
|
if (dim <= 1) return 0; // Error
|
||||||
|
|
||||||
rv *= dim;
|
rv *= dim;
|
||||||
|
|
||||||
|
|
|
@ -542,8 +542,12 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||||
// Allocate a list for n elements
|
// Allocate a list for n elements
|
||||||
cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUInt32Number n, cmsUInt32Number ColorantCount, const char* Prefix, const char* Suffix)
|
cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUInt32Number n, cmsUInt32Number ColorantCount, const char* Prefix, const char* Suffix)
|
||||||
{
|
{
|
||||||
cmsNAMEDCOLORLIST* v = (cmsNAMEDCOLORLIST*) _cmsMallocZero(ContextID, sizeof(cmsNAMEDCOLORLIST));
|
cmsNAMEDCOLORLIST* v;
|
||||||
|
|
||||||
|
if (ColorantCount > cmsMAXCHANNELS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
v = (cmsNAMEDCOLORLIST*)_cmsMallocZero(ContextID, sizeof(cmsNAMEDCOLORLIST));
|
||||||
if (v == NULL) return NULL;
|
if (v == NULL) return NULL;
|
||||||
|
|
||||||
v ->List = NULL;
|
v ->List = NULL;
|
||||||
|
|
|
@ -1517,10 +1517,10 @@ void* DupMatShaper(cmsContext ContextID, const void* Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A fast matrix-shaper evaluator for 8 bits. This is a bit ticky since I'm using 1.14 signed fixed point
|
// A fast matrix-shaper evaluator for 8 bits. This is a bit tricky since I'm using 1.14 signed fixed point
|
||||||
// to accomplish some performance. Actually it takes 256x3 16 bits tables and 16385 x 3 tables of 8 bits,
|
// to accomplish some performance. Actually it takes 256x3 16 bits tables and 16385 x 3 tables of 8 bits,
|
||||||
// in total about 50K, and the performance boost is huge!
|
// in total about 50K, and the performance boost is huge!
|
||||||
static
|
static CMS_NO_SANITIZE
|
||||||
void MatShaperEval16(CMSREGISTER const cmsUInt16Number In[],
|
void MatShaperEval16(CMSREGISTER const cmsUInt16Number In[],
|
||||||
CMSREGISTER cmsUInt16Number Out[],
|
CMSREGISTER cmsUInt16Number Out[],
|
||||||
CMSREGISTER const void* D)
|
CMSREGISTER const void* D)
|
||||||
|
|
|
@ -592,8 +592,11 @@ cmsUInt8Number* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
v = CHANGE_ENDIAN(v);
|
v = CHANGE_ENDIAN(v);
|
||||||
|
|
||||||
v = (v << 16) / alpha_factor;
|
if (alpha_factor > 0) {
|
||||||
if (v > 0xffff) v = 0xffff;
|
|
||||||
|
v = (v << 16) / alpha_factor;
|
||||||
|
if (v > 0xffff) v = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
|
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
|
||||||
|
|
||||||
|
@ -674,8 +677,11 @@ cmsUInt8Number* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
v = CHANGE_ENDIAN(v);
|
v = CHANGE_ENDIAN(v);
|
||||||
|
|
||||||
v = (v << 16) / alpha_factor;
|
if (alpha_factor > 0) {
|
||||||
if (v > 0xffff) v = 0xffff;
|
|
||||||
|
v = (v << 16) / alpha_factor;
|
||||||
|
if (v > 0xffff) v = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
|
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
|
||||||
|
|
||||||
|
@ -3799,6 +3805,11 @@ cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
|
||||||
_cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
|
_cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
|
||||||
cmsFormattersFactoryList* f;
|
cmsFormattersFactoryList* f;
|
||||||
|
|
||||||
|
if (T_CHANNELS(Type) == 0) {
|
||||||
|
static const cmsFormatter nullFormatter = { 0 };
|
||||||
|
return nullFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
|
for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
|
||||||
|
|
||||||
cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
|
cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
|
||||||
|
@ -3833,9 +3844,12 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil
|
||||||
|
|
||||||
cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
|
cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
|
||||||
cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
|
cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
|
||||||
cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
|
cmsInt32Number nOutputChans = cmsChannelsOfColorSpace(ColorSpace);
|
||||||
cmsUInt32Number Float = lIsFloat ? 1U : 0;
|
cmsUInt32Number Float = lIsFloat ? 1U : 0;
|
||||||
|
|
||||||
|
// Unsupported color space?
|
||||||
|
if (nOutputChans < 0) return 0;
|
||||||
|
|
||||||
// Create a fake formatter for result
|
// Create a fake formatter for result
|
||||||
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
|
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
|
||||||
}
|
}
|
||||||
|
@ -3850,6 +3864,9 @@ cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsU
|
||||||
cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
|
cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
|
||||||
cmsUInt32Number Float = lIsFloat ? 1U : 0;
|
cmsUInt32Number Float = lIsFloat ? 1U : 0;
|
||||||
|
|
||||||
|
// Unsupported color space?
|
||||||
|
if (nOutputChans < 0) return 0;
|
||||||
|
|
||||||
// Create a fake formatter for result
|
// Create a fake formatter for result
|
||||||
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
|
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
|
||||||
}
|
}
|
||||||
|
|
|
@ -874,7 +874,7 @@ int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
cmsInt32Number CMSEXPORT cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace)
|
||||||
{
|
{
|
||||||
switch (ColorSpace) {
|
switch (ColorSpace) {
|
||||||
|
|
||||||
|
@ -935,6 +935,16 @@ cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
||||||
case cmsSigMCHFData:
|
case cmsSigMCHFData:
|
||||||
case cmsSig15colorData: return 15;
|
case cmsSig15colorData: return 15;
|
||||||
|
|
||||||
default: return 3;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Provided for compatibility only
|
||||||
|
*/
|
||||||
|
cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
||||||
|
{
|
||||||
|
int n = cmsChannelsOfColorSpace(ColorSpace);
|
||||||
|
if (n < 0) return 3;
|
||||||
|
return (cmsUInt32Number)n;
|
||||||
|
}
|
|
@ -168,17 +168,20 @@ cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
|
||||||
|
|
||||||
cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
||||||
{
|
{
|
||||||
cmsUInt32Number tmp;
|
union typeConverter {
|
||||||
|
cmsUInt32Number integer;
|
||||||
|
cmsFloat32Number floating_point;
|
||||||
|
} tmp;
|
||||||
|
|
||||||
_cmsAssert(io != NULL);
|
_cmsAssert(io != NULL);
|
||||||
|
|
||||||
if (io->Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
if (io->Read(io, &tmp.integer, sizeof(cmsUInt32Number), 1) != 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (n != NULL) {
|
if (n != NULL) {
|
||||||
|
|
||||||
tmp = _cmsAdjustEndianess32(tmp);
|
tmp.integer = _cmsAdjustEndianess32(tmp.integer);
|
||||||
*n = *(cmsFloat32Number*)(void*)&tmp;
|
*n = tmp.floating_point;
|
||||||
|
|
||||||
// Safeguard which covers against absurd values
|
// Safeguard which covers against absurd values
|
||||||
if (*n > 1E+20 || *n < -1E+20) return FALSE;
|
if (*n > 1E+20 || *n < -1E+20) return FALSE;
|
||||||
|
@ -305,13 +308,14 @@ cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
|
||||||
|
|
||||||
cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
||||||
{
|
{
|
||||||
cmsUInt32Number tmp;
|
union typeConverter {
|
||||||
|
cmsUInt32Number integer;
|
||||||
|
cmsFloat32Number floating_point;
|
||||||
|
} tmp;
|
||||||
|
|
||||||
_cmsAssert(io != NULL);
|
tmp.floating_point = n;
|
||||||
|
tmp.integer = _cmsAdjustEndianess32(tmp.integer);
|
||||||
tmp = *(cmsUInt32Number*) (void*) &n;
|
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp.integer) != 1)
|
||||||
tmp = _cmsAdjustEndianess32(tmp);
|
|
||||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -621,6 +625,10 @@ cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
|
||||||
if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
|
if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmsPluginParalellizationSig:
|
||||||
|
if (!_cmsRegisterParallelizationPlugin(id, Plugin)) return FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -643,24 +651,25 @@ void CMSEXPORT cmsUnregisterPlugins(void)
|
||||||
// pointers structure. All global vars are referenced here.
|
// pointers structure. All global vars are referenced here.
|
||||||
static struct _cmsContext_struct globalContext = {
|
static struct _cmsContext_struct globalContext = {
|
||||||
|
|
||||||
NULL, // Not in the linked list
|
NULL, // Not in the linked list
|
||||||
NULL, // No suballocator
|
NULL, // No suballocator
|
||||||
{
|
{
|
||||||
NULL, // UserPtr,
|
NULL, // UserPtr,
|
||||||
&_cmsLogErrorChunk, // Logger,
|
&_cmsLogErrorChunk, // Logger,
|
||||||
&_cmsAlarmCodesChunk, // AlarmCodes,
|
&_cmsAlarmCodesChunk, // AlarmCodes,
|
||||||
&_cmsAdaptationStateChunk, // AdaptationState,
|
&_cmsAdaptationStateChunk, // AdaptationState,
|
||||||
&_cmsMemPluginChunk, // MemPlugin,
|
&_cmsMemPluginChunk, // MemPlugin,
|
||||||
&_cmsInterpPluginChunk, // InterpPlugin,
|
&_cmsInterpPluginChunk, // InterpPlugin,
|
||||||
&_cmsCurvesPluginChunk, // CurvesPlugin,
|
&_cmsCurvesPluginChunk, // CurvesPlugin,
|
||||||
&_cmsFormattersPluginChunk, // FormattersPlugin,
|
&_cmsFormattersPluginChunk, // FormattersPlugin,
|
||||||
&_cmsTagTypePluginChunk, // TagTypePlugin,
|
&_cmsTagTypePluginChunk, // TagTypePlugin,
|
||||||
&_cmsTagPluginChunk, // TagPlugin,
|
&_cmsTagPluginChunk, // TagPlugin,
|
||||||
&_cmsIntentsPluginChunk, // IntentPlugin,
|
&_cmsIntentsPluginChunk, // IntentPlugin,
|
||||||
&_cmsMPETypePluginChunk, // MPEPlugin,
|
&_cmsMPETypePluginChunk, // MPEPlugin,
|
||||||
&_cmsOptimizationPluginChunk, // OptimizationPlugin,
|
&_cmsOptimizationPluginChunk, // OptimizationPlugin,
|
||||||
&_cmsTransformPluginChunk, // TransformPlugin,
|
&_cmsTransformPluginChunk, // TransformPlugin,
|
||||||
&_cmsMutexPluginChunk // MutexPlugin
|
&_cmsMutexPluginChunk, // MutexPlugin,
|
||||||
|
&_cmsParallelizationPluginChunk // ParallelizationPlugin
|
||||||
},
|
},
|
||||||
|
|
||||||
{ NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
|
{ NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
|
||||||
|
@ -787,6 +796,8 @@ void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
|
||||||
// identify which plug-in to unregister.
|
// identify which plug-in to unregister.
|
||||||
void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
|
void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
|
||||||
{
|
{
|
||||||
|
struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
|
||||||
|
|
||||||
_cmsRegisterMemHandlerPlugin(ContextID, NULL);
|
_cmsRegisterMemHandlerPlugin(ContextID, NULL);
|
||||||
_cmsRegisterInterpPlugin(ContextID, NULL);
|
_cmsRegisterInterpPlugin(ContextID, NULL);
|
||||||
_cmsRegisterTagTypePlugin(ContextID, NULL);
|
_cmsRegisterTagTypePlugin(ContextID, NULL);
|
||||||
|
@ -798,6 +809,11 @@ void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
|
||||||
_cmsRegisterOptimizationPlugin(ContextID, NULL);
|
_cmsRegisterOptimizationPlugin(ContextID, NULL);
|
||||||
_cmsRegisterTransformPlugin(ContextID, NULL);
|
_cmsRegisterTransformPlugin(ContextID, NULL);
|
||||||
_cmsRegisterMutexPlugin(ContextID, NULL);
|
_cmsRegisterMutexPlugin(ContextID, NULL);
|
||||||
|
_cmsRegisterParallelizationPlugin(ContextID, NULL);
|
||||||
|
|
||||||
|
if (ctx->MemPool != NULL)
|
||||||
|
_cmsSubAllocDestroy(ctx->MemPool);
|
||||||
|
ctx->MemPool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -881,6 +897,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
|
||||||
_cmsAllocOptimizationPluginChunk(ctx, NULL);
|
_cmsAllocOptimizationPluginChunk(ctx, NULL);
|
||||||
_cmsAllocTransformPluginChunk(ctx, NULL);
|
_cmsAllocTransformPluginChunk(ctx, NULL);
|
||||||
_cmsAllocMutexPluginChunk(ctx, NULL);
|
_cmsAllocMutexPluginChunk(ctx, NULL);
|
||||||
|
_cmsAllocParallelizationPluginChunk(ctx, NULL);
|
||||||
|
|
||||||
// Setup the plug-ins
|
// Setup the plug-ins
|
||||||
if (!cmsPluginTHR(ctx, Plugin)) {
|
if (!cmsPluginTHR(ctx, Plugin)) {
|
||||||
|
@ -944,6 +961,7 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
|
||||||
_cmsAllocOptimizationPluginChunk(ctx, src);
|
_cmsAllocOptimizationPluginChunk(ctx, src);
|
||||||
_cmsAllocTransformPluginChunk(ctx, src);
|
_cmsAllocTransformPluginChunk(ctx, src);
|
||||||
_cmsAllocMutexPluginChunk(ctx, src);
|
_cmsAllocMutexPluginChunk(ctx, src);
|
||||||
|
_cmsAllocParallelizationPluginChunk(ctx, src);
|
||||||
|
|
||||||
// Make sure no one failed
|
// Make sure no one failed
|
||||||
for (i=Logger; i < MemoryClientMax; i++) {
|
for (i=Logger; i < MemoryClientMax; i++) {
|
||||||
|
|
|
@ -126,6 +126,7 @@ cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||||
// Force it to be neutral, clip to max. L* of 50
|
// Force it to be neutral, clip to max. L* of 50
|
||||||
Lab.a = Lab.b = 0;
|
Lab.a = Lab.b = 0;
|
||||||
if (Lab.L > 50) Lab.L = 50;
|
if (Lab.L > 50) Lab.L = 50;
|
||||||
|
if (Lab.L < 0) Lab.L = 0;
|
||||||
|
|
||||||
// Free the resources
|
// Free the resources
|
||||||
cmsDeleteTransform(xform);
|
cmsDeleteTransform(xform);
|
||||||
|
@ -322,6 +323,7 @@ cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[]
|
||||||
|
|
||||||
if (fabs(a) < 1.0E-10) {
|
if (fabs(a) < 1.0E-10) {
|
||||||
|
|
||||||
|
if (fabs(b) < 1.0E-10) return 0;
|
||||||
return cmsmin(0, cmsmax(50, -c/b ));
|
return cmsmin(0, cmsmax(50, -c/b ));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -332,7 +334,11 @@ cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[]
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
double rt = (-b + sqrt(d)) / (2.0 * a);
|
double rt;
|
||||||
|
|
||||||
|
if (fabs(a) < 1.0E-10) return 0;
|
||||||
|
|
||||||
|
rt = (-b + sqrt(d)) / (2.0 * a);
|
||||||
|
|
||||||
return cmsmax(0, cmsmin(50, rt));
|
return cmsmax(0, cmsmin(50, rt));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1550,7 +1550,10 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
|
||||||
Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag);
|
Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag);
|
||||||
if (Block == NULL) goto Error;
|
if (Block == NULL) goto Error;
|
||||||
NumOfWchar = SizeOfTag / sizeof(wchar_t);
|
NumOfWchar = SizeOfTag / sizeof(wchar_t);
|
||||||
if (!_cmsReadWCharArray(io, NumOfWchar, Block)) goto Error;
|
if (!_cmsReadWCharArray(io, NumOfWchar, Block)) {
|
||||||
|
_cmsFree(self->ContextID, Block);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mlu ->MemPool = Block;
|
mlu ->MemPool = Block;
|
||||||
|
@ -1935,26 +1938,34 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||||
|
|
||||||
// That should be all
|
// That should be all
|
||||||
if (mpe != NULL) {
|
if (mpe != NULL) {
|
||||||
cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT8");
|
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT8");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clut == NULL)
|
if (clut == NULL)
|
||||||
clutPoints = 0;
|
clutPoints = 0;
|
||||||
else
|
else {
|
||||||
clutPoints = clut->Params->nSamples[0];
|
// Lut8 only allows same CLUT points in all dimensions
|
||||||
|
clutPoints = clut->Params->nSamples[0];
|
||||||
|
for (i = 1; i < cmsPipelineInputChannels(NewLUT); i++) {
|
||||||
|
if (clut->Params->nSamples[i] != clutPoints) {
|
||||||
|
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT with different samples per dimension not suitable to be saved as LUT16");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->InputChannels)) return FALSE;
|
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number)cmsPipelineInputChannels(NewLUT))) return FALSE;
|
||||||
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->OutputChannels)) return FALSE;
|
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number)cmsPipelineOutputChannels(NewLUT))) return FALSE;
|
||||||
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE;
|
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE;
|
||||||
if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding
|
if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding
|
||||||
|
|
||||||
if (MatMPE != NULL) {
|
if (MatMPE != NULL) {
|
||||||
|
|
||||||
for (i = 0; i < 9; i++)
|
for (i = 0; i < 9; i++)
|
||||||
{
|
{
|
||||||
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
|
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
@ -2072,10 +2083,10 @@ cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCu
|
||||||
|
|
||||||
_cmsAssert(Tables != NULL);
|
_cmsAssert(Tables != NULL);
|
||||||
|
|
||||||
nEntries = Tables->TheCurves[0]->nEntries;
|
|
||||||
|
|
||||||
for (i=0; i < Tables ->nCurves; i++) {
|
for (i=0; i < Tables ->nCurves; i++) {
|
||||||
|
|
||||||
|
nEntries = Tables->TheCurves[i]->nEntries;
|
||||||
|
|
||||||
for (j=0; j < nEntries; j++) {
|
for (j=0; j < nEntries; j++) {
|
||||||
|
|
||||||
val = Tables->TheCurves[i]->Table16[j];
|
val = Tables->TheCurves[i]->Table16[j];
|
||||||
|
@ -2218,7 +2229,7 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||||
|
|
||||||
// That should be all
|
// That should be all
|
||||||
if (mpe != NULL) {
|
if (mpe != NULL) {
|
||||||
cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT16");
|
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT16");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2227,8 +2238,16 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||||
|
|
||||||
if (clut == NULL)
|
if (clut == NULL)
|
||||||
clutPoints = 0;
|
clutPoints = 0;
|
||||||
else
|
else {
|
||||||
clutPoints = clut->Params->nSamples[0];
|
// Lut16 only allows same CLUT points in all dimensions
|
||||||
|
clutPoints = clut->Params->nSamples[0];
|
||||||
|
for (i = 1; i < InputChannels; i++) {
|
||||||
|
if (clut->Params->nSamples[i] != clutPoints) {
|
||||||
|
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT with different samples per dimension not suitable to be saved as LUT16");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) InputChannels)) return FALSE;
|
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) InputChannels)) return FALSE;
|
||||||
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) OutputChannels)) return FALSE;
|
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) OutputChannels)) return FALSE;
|
||||||
|
@ -2237,10 +2256,10 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||||
|
|
||||||
if (MatMPE != NULL) {
|
if (MatMPE != NULL) {
|
||||||
|
|
||||||
for (i = 0; i < 9; i++)
|
for (i = 0; i < 9; i++)
|
||||||
{
|
{
|
||||||
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
|
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2586,31 +2605,31 @@ Error:
|
||||||
static
|
static
|
||||||
cmsBool WriteMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsStage* mpe)
|
cmsBool WriteMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsStage* mpe)
|
||||||
{
|
{
|
||||||
cmsUInt32Number i, n;
|
cmsUInt32Number i, n;
|
||||||
|
|
||||||
_cmsStageMatrixData* m = (_cmsStageMatrixData*) mpe -> Data;
|
_cmsStageMatrixData* m = (_cmsStageMatrixData*) mpe -> Data;
|
||||||
|
|
||||||
n = mpe->InputChannels * mpe->OutputChannels;
|
n = mpe->InputChannels * mpe->OutputChannels;
|
||||||
|
|
||||||
// Write the Matrix
|
// Write the Matrix
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
if (!_cmsWrite15Fixed16Number(io, m->Double[i])) return FALSE;
|
if (!_cmsWrite15Fixed16Number(io, m->Double[i])) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->Offset != NULL) {
|
if (m->Offset != NULL) {
|
||||||
|
|
||||||
for (i = 0; i < mpe->OutputChannels; i++)
|
for (i = 0; i < mpe->OutputChannels; i++)
|
||||||
{
|
{
|
||||||
if (!_cmsWrite15Fixed16Number(io, m->Offset[i])) return FALSE;
|
if (!_cmsWrite15Fixed16Number(io, m->Offset[i])) return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < mpe->OutputChannels; i++)
|
for (i = 0; i < mpe->OutputChannels; i++)
|
||||||
{
|
{
|
||||||
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
|
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -3141,7 +3160,6 @@ void Type_ColorantTable_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||||
static
|
static
|
||||||
void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
|
void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
|
||||||
{
|
{
|
||||||
|
|
||||||
cmsUInt32Number vendorFlag; // Bottom 16 bits for ICC use
|
cmsUInt32Number vendorFlag; // Bottom 16 bits for ICC use
|
||||||
cmsUInt32Number count; // Count of named colors
|
cmsUInt32Number count; // Count of named colors
|
||||||
cmsUInt32Number nDeviceCoords; // Num of device coordinates
|
cmsUInt32Number nDeviceCoords; // Num of device coordinates
|
||||||
|
@ -3471,7 +3489,6 @@ void *Type_ProfileSequenceId_Read(struct _cms_typehandler_struct* self, cmsIOHAN
|
||||||
|
|
||||||
// Get table count
|
// Get table count
|
||||||
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
|
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
|
||||||
SizeOfTag -= sizeof(cmsUInt32Number);
|
|
||||||
|
|
||||||
// Allocate an empty structure
|
// Allocate an empty structure
|
||||||
OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count);
|
OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count);
|
||||||
|
@ -3489,6 +3506,7 @@ void *Type_ProfileSequenceId_Read(struct _cms_typehandler_struct* self, cmsIOHAN
|
||||||
*nItems = 1;
|
*nItems = 1;
|
||||||
return OutSeq;
|
return OutSeq;
|
||||||
|
|
||||||
|
cmsUNUSED_PARAMETER(SizeOfTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3706,7 +3724,7 @@ country varies for each element:
|
||||||
|
|
||||||
// Auxiliary, read an string specified as count + string
|
// Auxiliary, read an string specified as count + string
|
||||||
static
|
static
|
||||||
cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
|
cmsBool ReadCountAndString(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
|
||||||
{
|
{
|
||||||
cmsUInt32Number Count;
|
cmsUInt32Number Count;
|
||||||
char* Text;
|
char* Text;
|
||||||
|
@ -3736,7 +3754,7 @@ cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
cmsBool WriteCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, const char* Section)
|
cmsBool WriteCountAndString(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, const char* Section)
|
||||||
{
|
{
|
||||||
cmsUInt32Number TextSize;
|
cmsUInt32Number TextSize;
|
||||||
char* Text;
|
char* Text;
|
||||||
|
@ -3760,11 +3778,11 @@ void *Type_CrdInfo_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||||
cmsMLU* mlu = cmsMLUalloc(self ->ContextID, 5);
|
cmsMLU* mlu = cmsMLUalloc(self ->ContextID, 5);
|
||||||
|
|
||||||
*nItems = 0;
|
*nItems = 0;
|
||||||
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "nm")) goto Error;
|
if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "nm")) goto Error;
|
||||||
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#0")) goto Error;
|
if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#0")) goto Error;
|
||||||
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#1")) goto Error;
|
if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#1")) goto Error;
|
||||||
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#2")) goto Error;
|
if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#2")) goto Error;
|
||||||
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#3")) goto Error;
|
if (!ReadCountAndString(self, io, mlu, &SizeOfTag, "#3")) goto Error;
|
||||||
|
|
||||||
*nItems = 1;
|
*nItems = 1;
|
||||||
return (void*) mlu;
|
return (void*) mlu;
|
||||||
|
@ -3781,11 +3799,11 @@ cmsBool Type_CrdInfo_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER*
|
||||||
|
|
||||||
cmsMLU* mlu = (cmsMLU*) Ptr;
|
cmsMLU* mlu = (cmsMLU*) Ptr;
|
||||||
|
|
||||||
if (!WriteCountAndSting(self, io, mlu, "nm")) goto Error;
|
if (!WriteCountAndString(self, io, mlu, "nm")) goto Error;
|
||||||
if (!WriteCountAndSting(self, io, mlu, "#0")) goto Error;
|
if (!WriteCountAndString(self, io, mlu, "#0")) goto Error;
|
||||||
if (!WriteCountAndSting(self, io, mlu, "#1")) goto Error;
|
if (!WriteCountAndString(self, io, mlu, "#1")) goto Error;
|
||||||
if (!WriteCountAndSting(self, io, mlu, "#2")) goto Error;
|
if (!WriteCountAndString(self, io, mlu, "#2")) goto Error;
|
||||||
if (!WriteCountAndSting(self, io, mlu, "#3")) goto Error;
|
if (!WriteCountAndString(self, io, mlu, "#3")) goto Error;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -5383,6 +5401,64 @@ void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||||
cmsUNUSED_PARAMETER(self);
|
cmsUNUSED_PARAMETER(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cicp VideoSignalType
|
||||||
|
|
||||||
|
static
|
||||||
|
void* Type_VideoSignal_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
|
||||||
|
{
|
||||||
|
cmsVideoSignalType* cicp = NULL;
|
||||||
|
|
||||||
|
if (SizeOfTag != 8) return NULL;
|
||||||
|
|
||||||
|
if (!_cmsReadUInt32Number(io, NULL)) return NULL;
|
||||||
|
|
||||||
|
cicp = (cmsVideoSignalType*)_cmsCalloc(self->ContextID, 1, sizeof(cmsVideoSignalType));
|
||||||
|
if (cicp == NULL) return NULL;
|
||||||
|
|
||||||
|
if (!_cmsReadUInt8Number(io, &cicp->ColourPrimaries)) goto Error;
|
||||||
|
if (!_cmsReadUInt8Number(io, &cicp->TransferCharacteristics)) goto Error;
|
||||||
|
if (!_cmsReadUInt8Number(io, &cicp->MatrixCoefficients)) goto Error;
|
||||||
|
if (!_cmsReadUInt8Number(io, &cicp->VideoFullRangeFlag)) goto Error;
|
||||||
|
|
||||||
|
// Success
|
||||||
|
*nItems = 1;
|
||||||
|
return cicp;
|
||||||
|
|
||||||
|
Error:
|
||||||
|
if (cicp != NULL) _cmsFree(self->ContextID, cicp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
cmsBool Type_VideoSignal_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||||
|
{
|
||||||
|
cmsVideoSignalType* cicp = (cmsVideoSignalType*)Ptr;
|
||||||
|
|
||||||
|
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
|
||||||
|
if (!_cmsWriteUInt8Number(io, cicp->ColourPrimaries)) return FALSE;
|
||||||
|
if (!_cmsWriteUInt8Number(io, cicp->TransferCharacteristics)) return FALSE;
|
||||||
|
if (!_cmsWriteUInt8Number(io, cicp->MatrixCoefficients)) return FALSE;
|
||||||
|
if (!_cmsWriteUInt8Number(io, cicp->VideoFullRangeFlag)) return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
cmsUNUSED_PARAMETER(self);
|
||||||
|
cmsUNUSED_PARAMETER(nItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Type_VideoSignal_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
|
||||||
|
{
|
||||||
|
return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsVideoSignalType));
|
||||||
|
|
||||||
|
cmsUNUSED_PARAMETER(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void Type_VideoSignal_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||||
|
{
|
||||||
|
_cmsFree(self->ContextID, Ptr);
|
||||||
|
}
|
||||||
|
|
||||||
// ********************************************************************************
|
// ********************************************************************************
|
||||||
// Type support main routines
|
// Type support main routines
|
||||||
|
@ -5422,6 +5498,7 @@ static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
|
||||||
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] },
|
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] },
|
||||||
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
|
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
|
||||||
{TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
|
{TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
|
||||||
|
{TYPE_HANDLER(cmsSigcicpType, VideoSignal), (_cmsTagTypeLinkedList*) &SupportedTagTypes[31] },
|
||||||
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
|
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5616,6 +5693,8 @@ static _cmsTagLinkedList SupportedTags[] = {
|
||||||
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
|
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
|
||||||
|
|
||||||
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
|
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
|
||||||
|
{ cmsSigcicpTag, { 1, 1, { cmsSigcicpType}, NULL }, &SupportedTags[64]},
|
||||||
|
|
||||||
{ cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
|
{ cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,7 +114,7 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||||
if (!hICC) // can't allocate
|
if (!hICC) // can't allocate
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hICC, 4.3);
|
cmsSetProfileVersion(hICC, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
||||||
cmsSetColorSpace(hICC, cmsSigRgbData);
|
cmsSetColorSpace(hICC, cmsSigRgbData);
|
||||||
|
@ -235,7 +235,7 @@ cmsHPROFILE CMSEXPORT cmsCreateGrayProfileTHR(cmsContext ContextID,
|
||||||
if (!hICC) // can't allocate
|
if (!hICC) // can't allocate
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hICC, 4.3);
|
cmsSetProfileVersion(hICC, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
||||||
cmsSetColorSpace(hICC, cmsSigGrayData);
|
cmsSetColorSpace(hICC, cmsSigGrayData);
|
||||||
|
@ -291,13 +291,13 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||||
{
|
{
|
||||||
cmsHPROFILE hICC;
|
cmsHPROFILE hICC;
|
||||||
cmsPipeline* Pipeline;
|
cmsPipeline* Pipeline;
|
||||||
cmsUInt32Number nChannels;
|
cmsInt32Number nChannels;
|
||||||
|
|
||||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||||
if (!hICC)
|
if (!hICC)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hICC, 4.3);
|
cmsSetProfileVersion(hICC, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
||||||
cmsSetColorSpace(hICC, ColorSpace);
|
cmsSetColorSpace(hICC, ColorSpace);
|
||||||
|
@ -306,7 +306,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||||
|
|
||||||
// Set up channels
|
// Set up channels
|
||||||
nChannels = cmsChannelsOf(ColorSpace);
|
nChannels = cmsChannelsOfColorSpace(ColorSpace);
|
||||||
|
|
||||||
// Creates a Pipeline with prelinearization step only
|
// Creates a Pipeline with prelinearization step only
|
||||||
Pipeline = cmsPipelineAlloc(ContextID, nChannels, nChannels);
|
Pipeline = cmsPipelineAlloc(ContextID, nChannels, nChannels);
|
||||||
|
@ -397,7 +397,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||||
cmsHPROFILE hICC;
|
cmsHPROFILE hICC;
|
||||||
cmsPipeline* LUT;
|
cmsPipeline* LUT;
|
||||||
cmsStage* CLUT;
|
cmsStage* CLUT;
|
||||||
cmsUInt32Number nChannels;
|
cmsInt32Number nChannels;
|
||||||
|
|
||||||
if (ColorSpace != cmsSigCmykData) {
|
if (ColorSpace != cmsSigCmykData) {
|
||||||
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
|
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
|
||||||
|
@ -416,7 +416,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||||
if (!hICC) // can't allocate
|
if (!hICC) // can't allocate
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hICC, 4.3);
|
cmsSetProfileVersion(hICC, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
||||||
cmsSetColorSpace(hICC, ColorSpace);
|
cmsSetColorSpace(hICC, ColorSpace);
|
||||||
|
@ -526,7 +526,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLab4ProfileTHR(cmsContext ContextID, const cmsCIE
|
||||||
hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
|
hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
|
||||||
if (hProfile == NULL) return NULL;
|
if (hProfile == NULL) return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hProfile, 4.3);
|
cmsSetProfileVersion(hProfile, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
||||||
cmsSetColorSpace(hProfile, cmsSigLabData);
|
cmsSetColorSpace(hProfile, cmsSigLabData);
|
||||||
|
@ -572,7 +572,7 @@ cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID)
|
||||||
hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL);
|
hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL);
|
||||||
if (hProfile == NULL) return NULL;
|
if (hProfile == NULL) return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hProfile, 4.3);
|
cmsSetProfileVersion(hProfile, 4.4);
|
||||||
|
|
||||||
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
||||||
cmsSetColorSpace(hProfile, cmsSigXYZData);
|
cmsSetColorSpace(hProfile, cmsSigXYZData);
|
||||||
|
@ -839,7 +839,7 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||||
if (!hProfile) // can't allocate
|
if (!hProfile) // can't allocate
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmsSetProfileVersion(hProfile, 4.3);
|
cmsSetProfileVersion(hProfile, 4.4);
|
||||||
|
|
||||||
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
|
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
|
||||||
// Make sure we have proper formatters
|
// Make sure we have proper formatters
|
||||||
cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX,
|
cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX,
|
||||||
FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace))
|
FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace))
|
||||||
| BYTES_SH(2) | CHANNELS_SH(cmsChannelsOf(v ->ExitColorSpace)));
|
| BYTES_SH(2) | CHANNELS_SH(cmsChannelsOfColorSpace(v ->ExitColorSpace)));
|
||||||
|
|
||||||
// Apply the transfor to colorants.
|
// Apply the transfor to colorants.
|
||||||
for (i=0; i < nColors; i++) {
|
for (i=0; i < nColors; i++) {
|
||||||
|
@ -1062,8 +1062,9 @@ const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTa
|
||||||
cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
|
cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
|
||||||
{
|
{
|
||||||
cmsHPROFILE hProfile = NULL;
|
cmsHPROFILE hProfile = NULL;
|
||||||
cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut;
|
cmsUInt32Number FrmIn, FrmOut;
|
||||||
int ColorSpaceBitsIn, ColorSpaceBitsOut;
|
cmsInt32Number ChansIn, ChansOut;
|
||||||
|
int ColorSpaceBitsIn, ColorSpaceBitsOut;
|
||||||
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
||||||
cmsPipeline* LUT = NULL;
|
cmsPipeline* LUT = NULL;
|
||||||
cmsStage* mpe;
|
cmsStage* mpe;
|
||||||
|
@ -1114,8 +1115,8 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||||
|
|
||||||
// Optimize the LUT and precalculate a devicelink
|
// Optimize the LUT and precalculate a devicelink
|
||||||
|
|
||||||
ChansIn = cmsChannelsOf(xform -> EntryColorSpace);
|
ChansIn = cmsChannelsOfColorSpace(xform -> EntryColorSpace);
|
||||||
ChansOut = cmsChannelsOf(xform -> ExitColorSpace);
|
ChansOut = cmsChannelsOfColorSpace(xform -> ExitColorSpace);
|
||||||
|
|
||||||
ColorSpaceBitsIn = _cmsLCMScolorSpace(xform -> EntryColorSpace);
|
ColorSpaceBitsIn = _cmsLCMScolorSpace(xform -> EntryColorSpace);
|
||||||
ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace);
|
ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace);
|
||||||
|
|
|
@ -781,6 +781,73 @@ cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMM
|
||||||
return CMMcargo->dwOriginalFlags;
|
return CMMcargo->dwOriginalFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the worker callback for parallelization plug-ins
|
||||||
|
_cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo)
|
||||||
|
{
|
||||||
|
_cmsAssert(CMMcargo != NULL);
|
||||||
|
return CMMcargo->Worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This field holds maximum number of workers or -1 to auto
|
||||||
|
cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo)
|
||||||
|
{
|
||||||
|
_cmsAssert(CMMcargo != NULL);
|
||||||
|
return CMMcargo->MaxWorkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This field is actually unused and reserved
|
||||||
|
cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo)
|
||||||
|
{
|
||||||
|
_cmsAssert(CMMcargo != NULL);
|
||||||
|
return CMMcargo->WorkerFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the case there is a parallelization plug-in, let it to do its job
|
||||||
|
static
|
||||||
|
void ParalellizeIfSuitable(_cmsTRANSFORM* p)
|
||||||
|
{
|
||||||
|
_cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(p->ContextID, ParallelizationPlugin);
|
||||||
|
|
||||||
|
_cmsAssert(p != NULL);
|
||||||
|
if (ctx != NULL && ctx->SchedulerFn != NULL) {
|
||||||
|
|
||||||
|
p->Worker = p->xform;
|
||||||
|
p->xform = ctx->SchedulerFn;
|
||||||
|
p->MaxWorkers = ctx->MaxWorkers;
|
||||||
|
p->WorkerFlags = ctx->WorkerFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty unroll to avoid a check with NULL on cmsDoTransform()
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
cmsUInt8Number* UnrollNothing(CMSREGISTER _cmsTRANSFORM* info,
|
||||||
|
CMSREGISTER cmsUInt16Number wIn[],
|
||||||
|
CMSREGISTER cmsUInt8Number* accum,
|
||||||
|
CMSREGISTER cmsUInt32Number Stride)
|
||||||
|
{
|
||||||
|
return accum;
|
||||||
|
|
||||||
|
cmsUNUSED_PARAMETER(info);
|
||||||
|
cmsUNUSED_PARAMETER(wIn);
|
||||||
|
cmsUNUSED_PARAMETER(Stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
cmsUInt8Number* PackNothing(CMSREGISTER _cmsTRANSFORM* info,
|
||||||
|
CMSREGISTER cmsUInt16Number wOut[],
|
||||||
|
CMSREGISTER cmsUInt8Number* output,
|
||||||
|
CMSREGISTER cmsUInt32Number Stride)
|
||||||
|
{
|
||||||
|
return output;
|
||||||
|
|
||||||
|
cmsUNUSED_PARAMETER(info);
|
||||||
|
cmsUNUSED_PARAMETER(wOut);
|
||||||
|
cmsUNUSED_PARAMETER(Stride);
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
|
// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
|
||||||
// for separated transforms. If this is the case,
|
// for separated transforms. If this is the case,
|
||||||
static
|
static
|
||||||
|
@ -836,6 +903,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||||
p->xform = _cmsTransform2toTransformAdaptor;
|
p->xform = _cmsTransform2toTransformAdaptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParalellizeIfSuitable(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,8 +940,10 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
// Formats are intended to be changed before use
|
||||||
if (*InputFormat == 0 && *OutputFormat == 0) {
|
if (*InputFormat == 0 && *OutputFormat == 0) {
|
||||||
p ->FromInput = p ->ToOutput = NULL;
|
p->FromInput = UnrollNothing;
|
||||||
|
p->ToOutput = PackNothing;
|
||||||
*dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
*dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -890,7 +960,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BytesPerPixelInput = T_BYTES(p ->InputFormat);
|
BytesPerPixelInput = T_BYTES(*InputFormat);
|
||||||
if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2)
|
if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2)
|
||||||
*dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
*dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
||||||
|
|
||||||
|
@ -924,6 +994,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||||
p ->dwOriginalFlags = *dwFlags;
|
p ->dwOriginalFlags = *dwFlags;
|
||||||
p ->ContextID = ContextID;
|
p ->ContextID = ContextID;
|
||||||
p ->UserData = NULL;
|
p ->UserData = NULL;
|
||||||
|
ParalellizeIfSuitable(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,8 +1169,8 @@ cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check channel count
|
// Check channel count
|
||||||
if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) ||
|
if ((cmsChannelsOfColorSpace(EntryColorSpace) != (cmsInt32Number) cmsPipelineInputChannels(Lut)) ||
|
||||||
(cmsChannelsOf(ExitColorSpace) != cmsPipelineOutputChannels(Lut))) {
|
(cmsChannelsOfColorSpace(ExitColorSpace) != (cmsInt32Number) cmsPipelineOutputChannels(Lut))) {
|
||||||
cmsPipelineFree(Lut);
|
cmsPipelineFree(Lut);
|
||||||
cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
|
cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -283,38 +283,38 @@ typedef CRITICAL_SECTION _cmsMutex;
|
||||||
|
|
||||||
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(m);
|
EnterCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
LeaveCriticalSection(m);
|
LeaveCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(m);
|
InitializeCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
DeleteCriticalSection(m);
|
DeleteCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(m);
|
EnterCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
LeaveCriticalSection(m);
|
LeaveCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -328,32 +328,32 @@ typedef pthread_mutex_t _cmsMutex;
|
||||||
|
|
||||||
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_lock(m);
|
return pthread_mutex_lock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_unlock(m);
|
return pthread_mutex_unlock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_init(m, NULL);
|
return pthread_mutex_init(m, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_destroy(m);
|
return pthread_mutex_destroy(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_lock(m);
|
return pthread_mutex_lock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
return pthread_mutex_unlock(m);
|
return pthread_mutex_unlock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -366,37 +366,37 @@ typedef int _cmsMutex;
|
||||||
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
||||||
{
|
{
|
||||||
cmsUNUSED_PARAMETER(m);
|
cmsUNUSED_PARAMETER(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -438,6 +438,9 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin
|
||||||
// Mutex
|
// Mutex
|
||||||
cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
||||||
|
|
||||||
|
// Paralellization
|
||||||
|
cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Suballocators.
|
// Suballocators.
|
||||||
|
@ -485,6 +488,7 @@ typedef enum {
|
||||||
OptimizationPlugin,
|
OptimizationPlugin,
|
||||||
TransformPlugin,
|
TransformPlugin,
|
||||||
MutexPlugin,
|
MutexPlugin,
|
||||||
|
ParallelizationPlugin,
|
||||||
|
|
||||||
// Last in list
|
// Last in list
|
||||||
MemoryClientMax
|
MemoryClientMax
|
||||||
|
@ -720,6 +724,24 @@ extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
|
||||||
void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
|
void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
|
||||||
const struct _cmsContext_struct* src);
|
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
|
// MLU internal representation
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1081,6 +1103,11 @@ typedef struct _cmstransform_struct {
|
||||||
// A way to provide backwards compatibility with full xform plugins
|
// A way to provide backwards compatibility with full xform plugins
|
||||||
_cmsTransformFn OldXform;
|
_cmsTransformFn OldXform;
|
||||||
|
|
||||||
|
// A one-worker transform entry for parallelization
|
||||||
|
_cmsTransform2Fn Worker;
|
||||||
|
cmsInt32Number MaxWorkers;
|
||||||
|
cmsUInt32Number WorkerFlags;
|
||||||
|
|
||||||
} _cmsTRANSFORM;
|
} _cmsTRANSFORM;
|
||||||
|
|
||||||
// Copies extra channels from input to output if the original flags in the transform structure
|
// Copies extra channels from input to output if the original flags in the transform structure
|
||||||
|
|
Loading…
Reference in a new issue