Update to lcms 2.8 (#808)
This commit is contained in:
parent
1509ccc51f
commit
4a2a8693e5
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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[],
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue