Commit fd3017ff authored by Alexandre Julliard's avatar Alexandre Julliard

lcms2: Import upstream release 2.14.

parent cfe8ee57
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// //
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Version 2.13.1 // Version 2.14
// //
#ifndef _lcms2_H #ifndef _lcms2_H
...@@ -81,7 +81,7 @@ extern "C" { ...@@ -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; ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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); ...@@ -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, // ...@@ -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); ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 ...@@ -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] = { ...@@ -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,
......
...@@ -322,10 +322,8 @@ cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number In ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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;
}
\ No newline at end of file
...@@ -168,18 +168,21 @@ cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n) ...@@ -168,18 +168,21 @@ 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) ...@@ -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;
_cmsAssert(io != NULL); cmsFloat32Number floating_point;
} tmp;
tmp = *(cmsUInt32Number*) (void*) &n;
tmp = _cmsAdjustEndianess32(tmp); tmp.floating_point = n;
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) tmp.integer = _cmsAdjustEndianess32(tmp.integer);
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp.integer) != 1)
return FALSE; return FALSE;
return TRUE; return TRUE;
...@@ -621,6 +625,10 @@ cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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[] ...@@ -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[] ...@@ -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));
} }
......
...@@ -114,7 +114,7 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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 ...@@ -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 { ...@@ -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; ...@@ -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 { ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment