Update to lcms 2.8 (#808)

This commit is contained in:
Matthieu Darbois 2016-08-06 13:04:56 +02:00 committed by GitHub
parent 1509ccc51f
commit 4a2a8693e5
23 changed files with 201 additions and 132 deletions

View File

@ -23,7 +23,7 @@
// //
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Version 2.8beta0 // Version 2.8
// //
#ifndef _lcms2_H #ifndef _lcms2_H
@ -656,7 +656,7 @@ typedef void* cmsHTRANSFORM;
// T: Pixeltype // T: Pixeltype
// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) // F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
// P: Planar? 0=Chunky, 1=Planar // P: Planar? 0=Chunky, 1=Planar
// X: swap 16 bps endianess? // X: swap 16 bps endianness?
// S: Do swap? ie, BGR, KYMC // S: Do swap? ie, BGR, KYMC
// E: Extra samples // E: Extra samples
// C: Channels (Samples per pixel) // C: Channels (Samples per pixel)
@ -1016,7 +1016,7 @@ CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
// Context handling -------------------------------------------------------------------------------------------------------- // Context handling --------------------------------------------------------------------------------------------------------
// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility // Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
// though using the global context is not recomended. Proper context handling makes lcms more thread-safe. // though using the global context is not recommended. Proper context handling makes lcms more thread-safe.
typedef struct _cmsContext_struct* cmsContext; typedef struct _cmsContext_struct* cmsContext;

View File

@ -128,7 +128,7 @@ struct _cms_io_handler {
const void* Buffer); const void* Buffer);
}; };
// Endianess adjust functions // Endianness adjust functions
CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word); CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word);
CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value); CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value);
CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord); CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);

View File

@ -408,74 +408,111 @@ void ComputeComponentIncrements(cmsUInt32Number Format,
// Handles extra channels copying alpha if requested by the flags // Handles extra channels copying alpha if requested by the flags
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in, void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
void* out, void* out,
cmsUInt32Number PixelsPerLine, cmsUInt32Number PixelsPerLine,
cmsUInt32Number LineCount, cmsUInt32Number LineCount,
const cmsStride* Stride) const cmsStride* Stride)
{ {
size_t i, j, k; cmsUInt32Number i, j, k;
cmsUInt32Number nExtra; cmsUInt32Number nExtra;
cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS]; cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
cmsUInt32Number SourceIncrements[cmsMAXCHANNELS]; cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS]; cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
cmsUInt32Number DestIncrements[cmsMAXCHANNELS]; cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
cmsUInt8Number* SourcePtr[cmsMAXCHANNELS]; cmsFormatterAlphaFn copyValueFn;
cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
cmsFormatterAlphaFn copyValueFn; // Make sure we need some copy
if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
return;
// Make sure we need some copy // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA)) if (p->InputFormat == p->OutputFormat && in == out)
return; return;
// Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time. // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
nExtra = T_EXTRA(p->InputFormat); nExtra = T_EXTRA(p->InputFormat);
if (nExtra != T_EXTRA(p->OutputFormat)) if (nExtra != T_EXTRA(p->OutputFormat))
return; return;
// Anything to do?
if (nExtra == 0)
return;
// Compute the increments // Anything to do?
ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements); if (nExtra == 0)
ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements); return;
// Check for conversions 8, 16, half, float, dbl
copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements)); // Compute the increments
memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements)); ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
// The loop itself // Check for conversions 8, 16, half, float, dbl
for (i = 0; i < LineCount; i++) { copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
// Prepare pointers for the loop if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
for (j = 0; j < nExtra; j++) {
SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j]; cmsUInt8Number* SourcePtr;
DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j]; cmsUInt8Number* DestPtr;
}
for (j = 0; j < PixelsPerLine; j++) { cmsUInt32Number SourceStrideIncrement = 0;
cmsUInt32Number DestStrideIncrement = 0;
for (k = 0; k < nExtra; k++) { // The loop itself
for (i = 0; i < LineCount; i++) {
copyValueFn(DestPtr[k], SourcePtr[k]); // Prepare pointers for the loop
SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
SourcePtr[k] += SourceIncrements[k]; for (j = 0; j < PixelsPerLine; j++) {
DestPtr[k] += DestIncrements[k];
}
}
for (j = 0; j < nExtra; j++) { copyValueFn(DestPtr, SourcePtr);
SourceStrideIncrements[j] += Stride->BytesPerLineIn; SourcePtr += SourceIncrements[0];
DestStrideIncrements[j] += Stride->BytesPerLineOut; DestPtr += DestIncrements[0];
} }
}
SourceStrideIncrement += Stride->BytesPerLineIn;
DestStrideIncrement += Stride->BytesPerLineOut;
}
}
else { // General case with more than one extra channel
cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
// The loop itself
for (i = 0; i < LineCount; i++) {
// Prepare pointers for the loop
for (j = 0; j < nExtra; j++) {
SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
}
for (j = 0; j < PixelsPerLine; j++) {
for (k = 0; k < nExtra; k++) {
copyValueFn(DestPtr[k], SourcePtr[k]);
SourcePtr[k] += SourceIncrements[k];
DestPtr[k] += DestIncrements[k];
}
}
for (j = 0; j < nExtra; j++) {
SourceStrideIncrements[j] += Stride->BytesPerLineIn;
DestStrideIncrements[j] += Stride->BytesPerLineOut;
}
}
}
} }

View File

@ -596,7 +596,7 @@ void ReadReal(cmsIT8* it8, int inum)
} }
// Parses a float number // Parses a float number
// This can not call directly atof because it uses locale dependant // This can not call directly atof because it uses locale dependent
// parsing, while CCMX files always use . as decimal separator // parsing, while CCMX files always use . as decimal separator
static static
cmsFloat64Number ParseFloatNumber(const char *Buffer) cmsFloat64Number ParseFloatNumber(const char *Buffer)
@ -1817,7 +1817,7 @@ cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number*
} }
// -------------------------------------------------------------- Higer level parsing // -------------------------------------------------------------- Higher level parsing
static static
cmsBool DataFormatSection(cmsIT8* it8) cmsBool DataFormatSection(cmsIT8* it8)
@ -2120,7 +2120,7 @@ cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
// Init usefull pointers // Init useful pointers
static static
void CookPointers(cmsIT8* it8) void CookPointers(cmsIT8* it8)

View File

@ -107,7 +107,7 @@ static cmsIntentsList DefaultIntents[] = {
}; };
// A pointer to the begining of the list // A pointer to the beginning of the list
_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL }; _cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
// Duplicates the zone of memory used by the plug-in in the new context // Duplicates the zone of memory used by the plug-in in the new context
@ -889,7 +889,7 @@ int BlackPreservingSampler(register const cmsUInt16Number In[], register cmsUInt
return TRUE; return TRUE;
} }
// Make sure to pass thru K (which now is fixed) // Make sure to pass through K (which now is fixed)
Outf[3] = LabK[3]; Outf[3] = LabK[3];
// Apply TAC if needed // Apply TAC if needed
@ -957,7 +957,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
memset(&bp, 0, sizeof(bp)); memset(&bp, 0, sizeof(bp));
// We need the input LUT of the last profile, assuming this one is responsible of // We need the input LUT of the last profile, assuming this one is responsible of
// black generation. This LUT will be seached in inverse order. // black generation. This LUT will be searched in inverse order.
bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC); bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
if (bp.LabK2cmyk == NULL) goto Cleanup; if (bp.LabK2cmyk == NULL) goto Cleanup;

View File

@ -198,7 +198,7 @@ void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsCo
} }
} }
// Auxiliar to fill memory management functions from plugin (or context 0 defaults) // Auxiliary to fill memory management functions from plugin (or context 0 defaults)
void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr) void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
{ {
if (Plugin == NULL) { if (Plugin == NULL) {
@ -430,14 +430,14 @@ void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size
// Error logging ****************************************************************** // Error logging ******************************************************************
// There is no error handling at all. When a funtion fails, it returns proper value. // There is no error handling at all. When a function fails, it returns proper value.
// For example, all create functions does return NULL on failure. Other return FALSE // For example, all create functions does return NULL on failure. Other return FALSE
// It may be interesting, for the developer, to know why the function is failing. // It may be interesting, for the developer, to know why the function is failing.
// for that reason, lcms2 does offer a logging function. This function does recive // for that reason, lcms2 does offer a logging function. This function does recive
// a ENGLISH string with some clues on what is going wrong. You can show this // a ENGLISH string with some clues on what is going wrong. You can show this
// info to the end user, or just create some sort of log. // info to the end user, or just create some sort of log.
// The logging function should NOT terminate the program, as this obviously can leave // The logging function should NOT terminate the program, as this obviously can leave
// resources. It is the programmer's responsability to check each function return code // resources. It is the programmer's responsibility to check each function return code
// to make sure it didn't fail. // to make sure it didn't fail.
// Error messages are limited to MAX_ERROR_MESSAGE_LEN // Error messages are limited to MAX_ERROR_MESSAGE_LEN

View File

@ -567,7 +567,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
return Val; return Val;
} }
// Evaluate a segmented funtion for a single value. Return -1 if no valid segment found . // Evaluate a segmented function for a single value. Return -1 if no valid segment found .
// If fn type is 0, perform an interpolation on the table // If fn type is 0, perform an interpolation on the table
static static
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R) cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)

View File

@ -27,7 +27,7 @@
#include "lcms2_internal.h" #include "lcms2_internal.h"
// Auxiliar: append a Lab identity after the given sequence of profiles // Auxiliary: append a Lab identity after the given sequence of profiles
// and return the transform. Lab profile is closed, rest of profiles are kept open. // and return the transform. Lab profile is closed, rest of profiles are kept open.
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
cmsUInt32Number nProfiles, cmsUInt32Number nProfiles,
@ -172,7 +172,7 @@ cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
} }
// Build the relationship. This effectively limits the maximum accuracy to 16 bits, but // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
// since this is used on black-preserving LUTs, we are not loosing accuracy in any case // since this is used on black-preserving LUTs, we are not losing accuracy in any case
KTone = cmsJoinToneCurve(ContextID, in, out, nPoints); KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
// Get rid of components // Get rid of components
@ -278,7 +278,7 @@ int GamutSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
} }
// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs // Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE // the dE obtained is then annotated on the LUT. Values truly out of gamut are clipped to dE = 0xFFFE
// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well. // and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
// //
// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors, // **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,

View File

@ -156,7 +156,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int
int i; int i;
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS]; cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
// Fill the auxiliar array // Fill the auxiliary array
for (i=0; i < MAX_INPUT_DIMENSIONS; i++) for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
Samples[i] = nSamples; Samples[i] = nSamples;

View File

@ -324,7 +324,7 @@ cmsUInt32Number FileRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number
return nReaded; return nReaded;
} }
// Postion file pointer in the file // Position file pointer in the file
static static
cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset) cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
{ {
@ -368,6 +368,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
{ {
cmsIOHANDLER* iohandler = NULL; cmsIOHANDLER* iohandler = NULL;
FILE* fm = NULL; FILE* fm = NULL;
cmsInt32Number fileLen;
_cmsAssert(FileName != NULL); _cmsAssert(FileName != NULL);
_cmsAssert(AccessMode != NULL); _cmsAssert(AccessMode != NULL);
@ -383,8 +384,17 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
_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);
if (fileLen < 0)
{
fclose(fm);
_cmsFree(ContextID, iohandler);
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
return NULL;
} }
iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm);
iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
break; break;
case 'w': case 'w':
@ -424,6 +434,14 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream) cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
{ {
cmsIOHANDLER* iohandler = NULL; cmsIOHANDLER* iohandler = NULL;
cmsInt32Number fileSize;
fileSize = cmsfilelength(Stream);
if (fileSize < 0)
{
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
return NULL;
}
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER)); iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
if (iohandler == NULL) return NULL; if (iohandler == NULL) return NULL;
@ -431,7 +449,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* S
iohandler -> ContextID = ContextID; iohandler -> ContextID = ContextID;
iohandler -> stream = (void*) Stream; iohandler -> stream = (void*) Stream;
iohandler -> UsedSpace = 0; iohandler -> UsedSpace = 0;
iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream); iohandler -> ReportedSize = (cmsUInt32Number) fileSize;
iohandler -> PhysicalFile[0] = 0; iohandler -> PhysicalFile[0] = 0;
iohandler ->Read = FileRead; iohandler ->Read = FileRead;
@ -623,7 +641,7 @@ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
} }
// Check existance // Check existence
cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig) cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
{ {
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) (void*) hProfile; _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) (void*) hProfile;
@ -679,7 +697,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
return FALSE; return FALSE;
} }
// Adjust endianess of the used parameters // Adjust endianness of the used parameters
Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass); Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace); Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace);
Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs); Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs);
@ -797,7 +815,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
memset(&Header.reserved, 0, sizeof(Header.reserved)); memset(&Header.reserved, 0, sizeof(Header.reserved));
// Set profile ID. Endianess is always big endian // Set profile ID. Endianness is always big endian
memmove(&Header.profileID, &Icc ->ProfileID, 16); memmove(&Header.profileID, &Icc ->ProfileID, 16);
// Dump the header // Dump the header
@ -1544,7 +1562,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
LocalTypeHandler.ICCVersion = Icc ->Version; LocalTypeHandler.ICCVersion = Icc ->Version;
Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize); Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
// The tag type is supported, but something wrong happend and we cannot read the tag. // The tag type is supported, but something wrong happened and we cannot read the tag.
// let know the user about this (although it is just a warning) // let know the user about this (although it is just a warning)
if (Icc -> TagPtrs[n] == NULL) { if (Icc -> TagPtrs[n] == NULL) {

View File

@ -128,7 +128,7 @@ cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
} }
// Auxiliar, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper // Auxiliary, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
static static
cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile) cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
{ {
@ -314,7 +314,7 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
cmsTagSignature tagFloat; cmsTagSignature tagFloat;
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
// On named color, take the appropiate tag // On named color, take the appropriate tag
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
cmsPipeline* Lut; cmsPipeline* Lut;
@ -336,9 +336,9 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
return Lut; return Lut;
} }
// This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no // This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no
// matter other LUT are present and have precedence. Intent = -1 means just this. // matter other LUT are present and have precedence. Intent = -1 means just this.
if (Intent != -1) { if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
tag16 = Device2PCS16[Intent]; tag16 = Device2PCS16[Intent];
tagFloat = Device2PCSFloat[Intent]; tagFloat = Device2PCSFloat[Intent];
@ -394,7 +394,7 @@ Error:
// Check if this is a grayscale profile. // Check if this is a grayscale profile.
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
// if so, build appropiate conversion tables. // if so, build appropriate conversion tables.
// The tables are the PCS iluminant, scaled across GrayTRC // The tables are the PCS iluminant, scaled across GrayTRC
return BuildGrayInputMatrixPipeline(hProfile); return BuildGrayInputMatrixPipeline(hProfile);
} }
@ -549,7 +549,7 @@ cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFlo
if (Lut == NULL) return NULL; if (Lut == NULL) return NULL;
// If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding, // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
// and since the formatter has already accomodated to 0..1.0, we should undo this change // and since the formatter has already accommodated to 0..1.0, we should undo this change
if ( PCS == cmsSigLabData) if ( PCS == cmsSigLabData)
{ {
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
@ -590,7 +590,7 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
if (Intent != -1) { if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
tag16 = PCS2Device16[Intent]; tag16 = PCS2Device16[Intent];
tagFloat = PCS2DeviceFloat[Intent]; tagFloat = PCS2DeviceFloat[Intent];
@ -651,7 +651,7 @@ Error:
// Check if this is a grayscale profile. // Check if this is a grayscale profile.
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
// if so, build appropiate conversion tables. // if so, build appropriate conversion tables.
// The tables are the PCS iluminant, scaled across GrayTRC // The tables are the PCS iluminant, scaled across GrayTRC
return BuildGrayOutputPipeline(hProfile); return BuildGrayOutputPipeline(hProfile);
} }
@ -709,15 +709,21 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
{ {
cmsPipeline* Lut; cmsPipeline* Lut;
cmsTagTypeSignature OriginalType; cmsTagTypeSignature OriginalType;
cmsTagSignature tag16 = Device2PCS16[Intent]; cmsTagSignature tag16;
cmsTagSignature tagFloat = Device2PCSFloat[Intent]; cmsTagSignature tagFloat;
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
// On named color, take the appropiate tag if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC)
return NULL;
tag16 = Device2PCS16[Intent];
tagFloat = Device2PCSFloat[Intent];
// On named color, take the appropriate tag
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag); cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*)cmsReadTag(hProfile, cmsSigNamedColor2Tag);
if (nc == NULL) return NULL; if (nc == NULL) return NULL;
@ -733,12 +739,13 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
goto Error; goto Error;
return Lut; return Lut;
Error: Error:
cmsPipelineFree(Lut); cmsPipelineFree(Lut);
cmsFreeNamedColorList(nc); cmsFreeNamedColorList(nc);
return NULL; return NULL;
} }
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V // Floating point LUT are always V
@ -748,19 +755,19 @@ Error:
tagFloat = Device2PCSFloat[0]; tagFloat = Device2PCSFloat[0];
if (cmsIsTag(hProfile, tagFloat)) { if (cmsIsTag(hProfile, tagFloat)) {
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); return cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat));
} }
if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
tag16 = Device2PCS16[0]; tag16 = Device2PCS16[0];
if (!cmsIsTag(hProfile, tag16)) return NULL; if (!cmsIsTag(hProfile, tag16)) return NULL;
} }
// Check profile version and LUT type. Do the necessary adjustments if needed // Check profile version and LUT type. Do the necessary adjustments if needed
// Read the tag // Read the tag
Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); Lut = (cmsPipeline*)cmsReadTag(hProfile, tag16);
if (Lut == NULL) return NULL; if (Lut == NULL) return NULL;
// The profile owns the Lut, so we need to copy it // The profile owns the Lut, so we need to copy it
@ -773,7 +780,7 @@ Error:
ChangeInterpolationToTrilinear(Lut); ChangeInterpolationToTrilinear(Lut);
// After reading it, we have info about the original type // After reading it, we have info about the original type
OriginalType = _cmsGetTagTrueType(hProfile, tag16); OriginalType = _cmsGetTagTrueType(hProfile, tag16);
// We need to adjust data for Lab16 on output // We need to adjust data for Lab16 on output
if (OriginalType != cmsSigLut16Type) return Lut; if (OriginalType != cmsSigLut16Type) return Lut;
@ -781,12 +788,12 @@ Error:
// Here it is possible to get Lab on both sides // Here it is possible to get Lab on both sides
if (cmsGetColorSpace(hProfile) == cmsSigLabData) { if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
goto Error2; goto Error2;
} }
if (cmsGetPCS(hProfile) == cmsSigLabData) { if (cmsGetPCS(hProfile) == cmsSigLabData) {
if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
goto Error2; goto Error2;
} }
@ -921,7 +928,7 @@ cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
} }
// Auxiliar, read and duplicate a MLU if found. // Auxiliary, read and duplicate a MLU if found.
static static
cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig) cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
{ {

View File

@ -38,7 +38,7 @@ void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y,
r -> n[VZ] = z; r -> n[VZ] = z;
} }
// Vector substraction // Vector subtraction
void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b) void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b)
{ {
r -> n[VX] = a -> n[VX] - b -> n[VX]; r -> n[VX] = a -> n[VX] - b -> n[VX];

View File

@ -206,10 +206,10 @@ void strFrom16(char str[3], cmsUInt16Number n)
} }
// Add an ASCII entry. // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString) cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
{ {
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1; cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
wchar_t* WStr; wchar_t* WStr;
cmsBool rc; cmsBool rc;
cmsUInt16Number Lang = strTo16(LanguageCode); cmsUInt16Number Lang = strTo16(LanguageCode);
@ -243,8 +243,7 @@ cmsUInt32Number mywcslen(const wchar_t *s)
return (cmsUInt32Number)(p - s); return (cmsUInt32Number)(p - s);
} }
// Add a wide entry. Do not add any \0 terminator (ICC1v43_2010-12.pdf page 61)
// Add a wide entry
cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString) cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
{ {
cmsUInt16Number Lang = strTo16(Language); cmsUInt16Number Lang = strTo16(Language);
@ -254,7 +253,7 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char
if (mlu == NULL) return FALSE; if (mlu == NULL) return FALSE;
if (WideString == NULL) return FALSE; if (WideString == NULL) return FALSE;
len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t); len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
return AddMLUBlock(mlu, len, WideString, Lang, Cntry); return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
} }

View File

@ -529,7 +529,7 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
return TRUE; return TRUE;
} }
// Auxiliar, to see if two values are equal or very different // Auxiliary, to see if two values are equal or very different
static static
cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] ) cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
{ {
@ -537,7 +537,7 @@ cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[]
for (i=0; i < n; i++) { for (i=0; i < n; i++) {
if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremly different that the fixup should be avoided if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremely different that the fixup should be avoided
if (White1[i] != White2[i]) return FALSE; if (White1[i] != White2[i]) return FALSE;
} }
return TRUE; return TRUE;

View File

@ -81,7 +81,7 @@ typedef struct {
#define ANYFLAVOR FLAVOR_SH(1) #define ANYFLAVOR FLAVOR_SH(1)
// Supress waning about info never being used // Suppress waning about info never being used
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4100) #pragma warning(disable : 4100)

View File

@ -308,7 +308,7 @@ void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* fLa
wLab[2] = ab2Fix4(Lab.b); wLab[2] = ab2Fix4(Lab.b);
} }
// Auxiliar: convert to Radians // Auxiliary: convert to Radians
static static
cmsFloat64Number RADIANS(cmsFloat64Number deg) cmsFloat64Number RADIANS(cmsFloat64Number deg)
{ {
@ -316,7 +316,7 @@ cmsFloat64Number RADIANS(cmsFloat64Number deg)
} }
// Auxiliar: atan2 but operating in degrees and returning 0 if a==b==0 // Auxiliary: atan2 but operating in degrees and returning 0 if a==b==0
static static
cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b) cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
{ {
@ -339,7 +339,7 @@ cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
} }
// Auxiliar: Square // Auxiliary: Square
static static
cmsFloat64Number Sqr(cmsFloat64Number v) cmsFloat64Number Sqr(cmsFloat64Number v)
{ {

View File

@ -107,7 +107,7 @@ void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number*
#endif #endif
} }
// Auxiliar -- read 8, 16 and 32-bit numbers // Auxiliary -- read 8, 16 and 32-bit numbers
cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n) cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
{ {
cmsUInt8Number tmp; cmsUInt8Number tmp;
@ -172,13 +172,13 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
_cmsAssert(io != NULL); _cmsAssert(io != NULL);
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1) if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
return FALSE; return FALSE;
if (n != NULL) { if (n != NULL) {
tmp = _cmsAdjustEndianess32(tmp); tmp = _cmsAdjustEndianess32(tmp);
*n = *(cmsFloat32Number*) &tmp; *n = *(cmsFloat32Number*) (void*) &tmp;
} }
return TRUE; return TRUE;
} }
@ -289,7 +289,7 @@ cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
_cmsAssert(io != NULL); _cmsAssert(io != NULL);
tmp = *(cmsUInt32Number*) &n; tmp = *(cmsUInt32Number*) (void*) &n;
tmp = _cmsAdjustEndianess32(tmp); tmp = _cmsAdjustEndianess32(tmp);
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
return FALSE; return FALSE;
@ -485,7 +485,10 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
va_start(args, frm); va_start(args, frm);
len = vsnprintf((char*) Buffer, 2047, frm, args); len = vsnprintf((char*) Buffer, 2047, frm, args);
if (len < 0) return FALSE; // Truncated, which is a fatal error for us if (len < 0) {
va_end(args);
return FALSE; // Truncated, which is a fatal error for us
}
rc = io ->Write(io, len, Buffer); rc = io ->Write(io, len, Buffer);

View File

@ -579,7 +579,7 @@ void EmitNGamma(cmsIOHANDLER* m, int n, cmsToneCurve* g[])
// //
// Each row contains Pipeline values for all but first component. So, I // Each row contains Pipeline values for all but first component. So, I
// detect row changing by keeping a copy of last value of first // detect row changing by keeping a copy of last value of first
// component. -1 is used to mark begining of whole block. // component. -1 is used to mark beginning of whole block.
static static
int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)

View File

@ -318,7 +318,7 @@ void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
} }
// Auxiliar to retrieve a pointer to the segmentr containing the Lab value // Auxiliary to retrieve a pointer to the segmentr containing the Lab value
static static
cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp) cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
{ {
@ -330,7 +330,7 @@ cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
_cmsAssert(Lab != NULL); _cmsAssert(Lab != NULL);
_cmsAssert(sp != NULL); _cmsAssert(sp != NULL);
// Center L* by substracting half of its domain, that's 50 // Center L* by subtracting half of its domain, that's 50
_cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b); _cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
// Convert to spherical coordinates // Convert to spherical coordinates

View File

@ -30,7 +30,7 @@
// This file implements every single tag and tag type as described in the ICC spec. Some types // This file implements every single tag and tag type as described in the ICC spec. Some types
// have been deprecated, like ncl and Data. There is no implementation for those types as there // have been deprecated, like ncl and Data. There is no implementation for those types as there
// are no profiles holding them. The programmer can also extend this list by defining his own types // are no profiles holding them. The programmer can also extend this list by defining his own types
// by using the appropiate plug-in. There are three types of plug ins regarding that. First type // by using the appropriate plug-in. There are three types of plug ins regarding that. First type
// allows to define new tags using any existing type. Next plug-in type allows to define new types // allows to define new tags using any existing type. Next plug-in type allows to define new types
// and the third one is very specific: allows to extend the number of elements in the multiprocessing // and the third one is very specific: allows to extend the number of elements in the multiprocessing
// elements special type. // elements special type.
@ -113,7 +113,7 @@ cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* Pl
} }
// Auxiliar to convert UTF-32 to UTF-16 in some cases // Auxiliary to convert UTF-32 to UTF-16 in some cases
static static
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array) cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
{ {
@ -129,7 +129,7 @@ cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t*
return TRUE; return TRUE;
} }
// Auxiliar to read an array of wchar_t // Auxiliary to read an array of wchar_t
static static
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
{ {
@ -160,7 +160,7 @@ typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self,
cmsUInt32Number n, cmsUInt32Number n,
cmsUInt32Number SizeOfTag); cmsUInt32Number SizeOfTag);
// Helper function to deal with position tables as decribed in ICC spec 4.3 // Helper function to deal with position tables as described in ICC spec 4.3
// A table of n elements is readed, where first comes n records containing offsets and sizes and // A table of n elements is readed, where first comes n records containing offsets and sizes and
// then a block containing the data itself. This allows to reuse same data in more than one entry // then a block containing the data itself. This allows to reuse same data in more than one entry
static static
@ -994,7 +994,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
} }
// Tell the real text len including the null terminator and padding // Tell the real text len including the null terminator and padding
len_text = strlen(Text) + 1; len_text = (cmsUInt32Number) strlen(Text) + 1;
// Compute an total tag size requirement // Compute an total tag size requirement
len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67); len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67);
len_aligned = _cmsALIGNLONG(len_tag_requirement); len_aligned = _cmsALIGNLONG(len_tag_requirement);
@ -1474,7 +1474,7 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
LargestPosition = EndOfThisString; LargestPosition = EndOfThisString;
} }
// Now read the remaining of tag and fill all strings. Substract the directory // Now read the remaining of tag and fill all strings. Subtract the directory
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number); SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
if (SizeOfTag == 0) if (SizeOfTag == 0)
{ {
@ -3609,7 +3609,7 @@ country varies for each element:
// Auxiliar, 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 ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
{ {
@ -4312,13 +4312,13 @@ Error:
static static
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{ {
cmsUInt8Number Dimensions8[16]; cmsUInt8Number Dimensions8[16]; // 16 because the spec says 16 and not max number of channels
cmsUInt32Number i; cmsUInt32Number i;
cmsStage* mpe = (cmsStage*) Ptr; cmsStage* mpe = (cmsStage*) Ptr;
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
// Check for maximum number of channels // Check for maximum number of channels supported by lcms
if (mpe -> InputChannels > 15) return FALSE; if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE;
// Only floats are supported in MPE // Only floats are supported in MPE
if (clut ->HasFloatValues == FALSE) return FALSE; if (clut ->HasFloatValues == FALSE) return FALSE;

View File

@ -1138,15 +1138,20 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
// If no way, then force CLUT that for sure can be written // If no way, then force CLUT that for sure can be written
if (AllowedLUT == NULL) { if (AllowedLUT == NULL) {
cmsStage* FirstStage;
cmsStage* LastStage;
dwFlags |= cmsFLAGS_FORCE_CLUT; dwFlags |= cmsFLAGS_FORCE_CLUT;
_cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
// Put identity curves if needed // Put identity curves if needed
if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType) FirstStage = cmsPipelineGetPtrToFirstStage(LUT);
if (FirstStage != NULL && FirstStage ->Type != cmsSigCurveSetElemType)
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn))) if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
goto Error; goto Error;
if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType) LastStage = cmsPipelineGetPtrToLastStage(LUT);
if (LastStage != NULL && LastStage ->Type != cmsSigCurveSetElemType)
if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut))) if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
goto Error; goto Error;

View File

@ -413,7 +413,7 @@ void PrecalculatedXFORM(_cmsTRANSFORM* p,
} }
// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical. // Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
static static
void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p, void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
const cmsUInt16Number wIn[], const cmsUInt16Number wIn[],

View File

@ -739,7 +739,7 @@ typedef struct _cms_iccprofile_struct {
// Dictionary // Dictionary
cmsUInt32Number TagCount; cmsUInt32Number TagCount;
cmsTagSignature TagNames[MAX_TABLE_TAG]; cmsTagSignature TagNames[MAX_TABLE_TAG];
cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none) cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)
cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
cmsUInt32Number TagOffsets[MAX_TABLE_TAG]; cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked