diff options
-rw-r--r-- | lcms2/src/cmsxform.c | 236 | ||||
-rw-r--r-- | lcms2/src/extra_xform.h | 330 | ||||
-rw-r--r-- | windows/ghostscript.vcproj | 6 |
3 files changed, 393 insertions, 179 deletions
diff --git a/lcms2/src/cmsxform.c b/lcms2/src/cmsxform.c index 4a5a4f093..b1c9d647f 100644 --- a/lcms2/src/cmsxform.c +++ b/lcms2/src/cmsxform.c @@ -376,41 +376,8 @@ void NullXFORM(_cmsTRANSFORM* p, // No gamut check, no cache, 16 bits -static -void PrecalculatedXFORM(_cmsTRANSFORM* p, - const void* in, - void* out, - cmsUInt32Number PixelsPerLine, - cmsUInt32Number LineCount, - const cmsStride* Stride) -{ - register cmsUInt8Number* accum; - register cmsUInt8Number* output; - cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; - cmsUInt32Number i, j, strideIn, strideOut; - - _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); - - strideIn = 0; - strideOut = 0; - - for (i = 0; i < LineCount; i++) { - - accum = (cmsUInt8Number*)in + strideIn; - output = (cmsUInt8Number*)out + strideOut; - - for (j = 0; j < PixelsPerLine; j++) { - - accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); - p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); - output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); - } - - strideIn += Stride->BytesPerLineIn; - strideOut += Stride->BytesPerLineOut; - } - -} +#define FUNCTION_NAME PrecalculatedXFORM +#include "extra_xform.h" // Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical. @@ -437,151 +404,53 @@ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p, } // Gamut check, No caché, 16 bits. -static -void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p, - const void* in, - void* out, - cmsUInt32Number PixelsPerLine, - cmsUInt32Number LineCount, - const cmsStride* Stride) -{ - cmsUInt8Number* accum; - cmsUInt8Number* output; - cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; - cmsUInt32Number i, j, strideIn, strideOut; - - _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); - - strideIn = 0; - strideOut = 0; - - for (i = 0; i < LineCount; i++) { - - accum = (cmsUInt8Number*)in + strideIn; - output = (cmsUInt8Number*)out + strideOut; - - for (j = 0; j < PixelsPerLine; j++) { - - accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); - TransformOnePixelWithGamutCheck(p, wIn, wOut); - output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); - } - - strideIn += Stride->BytesPerLineIn; - strideOut += Stride->BytesPerLineOut; - } -} +#define FUNCTION_NAME PrecalculatedXFORMGamutCheck +#define GAMUTCHECK +#include "extra_xform.h" // No gamut check, Caché, 16 bits, -static -void CachedXFORM(_cmsTRANSFORM* p, - const void* in, - void* out, - cmsUInt32Number PixelsPerLine, - cmsUInt32Number LineCount, - const cmsStride* Stride) -{ - cmsUInt8Number* accum; - cmsUInt8Number* output; - cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; - _cmsCACHE Cache; - cmsUInt32Number i, j, strideIn, strideOut; - - _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); - - // Empty buffers for quick memcmp - memset(wIn, 0, sizeof(wIn)); - memset(wOut, 0, sizeof(wOut)); +#define FUNCTION_NAME CachedXFORM +#define CACHED +#include "extra_xform.h" - // Get copy of zero cache - memcpy(&Cache, &p->Cache, sizeof(Cache)); - - strideIn = 0; - strideOut = 0; - - for (i = 0; i < LineCount; i++) { - - accum = (cmsUInt8Number*)in + strideIn; - output = (cmsUInt8Number*)out + strideOut; - - for (j = 0; j < PixelsPerLine; j++) { - - accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); - - if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { - - memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); - } - else { - p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); - - memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); - memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); - } - - output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); - } - - strideIn += Stride->BytesPerLineIn; - strideOut += Stride->BytesPerLineOut; - } -} // All those nice features together -static -void CachedXFORMGamutCheck(_cmsTRANSFORM* p, - const void* in, - void* out, - cmsUInt32Number PixelsPerLine, - cmsUInt32Number LineCount, - const cmsStride* Stride) -{ - cmsUInt8Number* accum; - cmsUInt8Number* output; - cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; - _cmsCACHE Cache; - cmsUInt32Number i, j, strideIn, strideOut; - - _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); - - // Empty buffers for quick memcmp - memset(wIn, 0, sizeof(wIn)); - memset(wOut, 0, sizeof(wOut)); - - // Get copy of zero cache - memcpy(&Cache, &p->Cache, sizeof(Cache)); - - strideIn = 0; - strideOut = 0; - - for (i = 0; i < LineCount; i++) { - - accum = (cmsUInt8Number*)in + strideIn; - output = (cmsUInt8Number*)out + strideOut; - - for (j = 0; j < PixelsPerLine; j++) { - - accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); - - if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { - - memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); - } - else { - TransformOnePixelWithGamutCheck(p, wIn, wOut); - - memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); - memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); - } - - output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); - } - - strideIn += Stride->BytesPerLineIn; - strideOut += Stride->BytesPerLineOut; - } -} +#define FUNCTION_NAME CachedXFORMGamutCheck +#define CACHED +#define GAMUTCHECK +#include "extra_xform.h" + +// No gamut check, Cache, 16 bits, 4 bytes +#define FUNCTION_NAME CachedXFORM4 +#define CACHED +#define INBYTES 4 +#define EXTRABYTES 0 +#include "extra_xform.h" + +// No gamut check, Cache, 16 bits, 8 bytes +#define FUNCTION_NAME CachedXFORM8 +#define CACHED +#define INBYTES 8 +#define EXTRABYTES 0 +#include "extra_xform.h" + +// Special one for common case. +#define FUNCTION_NAME CachedXFORM3to1 +#define CACHED +#define INBYTES 6 +#define EXTRABYTES 0 +#define UNPACK(T,D,S,Z) \ +do { \ + (D)[0] = FROM_8_TO_16(*(S)); (S)++; /* R */ \ + (D)[1] = FROM_8_TO_16(*(S)); (S)++; /* G */ \ + (D)[2] = FROM_8_TO_16(*(S)); (S)++; /* B */ \ +} while (0) +#define PACK(T,S,D,Z) \ +do { \ + *(D)++ = FROM_16_TO_8(*(S)); \ +} while (0); +#include "extra_xform.h" // Transform plug-ins ---------------------------------------------------------------------------------------------------- @@ -601,7 +470,7 @@ _cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL }; // Duplicates the zone of memory used by the plug-in in the new context static -void DupPluginTransformList(struct _cmsContext_struct* ctx, +void DupPluginTransformList(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) { _cmsTransformPluginChunkType newHead = { NULL }; @@ -875,9 +744,20 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, if (*dwFlags & cmsFLAGS_GAMUTCHECK) p ->xform = CachedXFORMGamutCheck; // Gamut check, caché - else - p ->xform = CachedXFORM; // No gamut check, caché - + else if ((*InputFormat & ~COLORSPACE_SH(31)) == (CHANNELS_SH(3)|BYTES_SH(1)) && + (*OutputFormat & ~COLORSPACE_SH(31)) == (CHANNELS_SH(1)|BYTES_SH(1))) + p ->xform = CachedXFORM3to1; + else if (T_EXTRA(*InputFormat) != 0) + p ->xform = CachedXFORM; // No gamut check, cach<E9> + else { + int inwords = T_CHANNELS(*InputFormat); + if (inwords <= 2) + p ->xform = CachedXFORM4; + else if (inwords <= 4) + p ->xform = CachedXFORM8; + else + p ->xform = CachedXFORM; // No gamut check, cach<E9> + } } } } diff --git a/lcms2/src/extra_xform.h b/lcms2/src/extra_xform.h new file mode 100644 index 000000000..e5885185b --- /dev/null +++ b/lcms2/src/extra_xform.h @@ -0,0 +1,330 @@ +// +// Little cms + +// Chameleonic header file to instantiate different versions of the +// transform routines. +// +// As a bare minimum the following must be defined on entry: +// FUNCTION_NAME the name of the function +// +// In addition, a range of other symbols can be optionally defined on entry +// to make the generated code more efficient. All these symbols (and +// FUNCTION_NAME) will be automatically undefined at the end of the file so +// that repeated #includes of this file are made simple. +// +// If caching is wanted, define CACHED. +// +// To reduce the amount of surplus memory checking done, set INBYTES to the +// number of bytes in an unpacked data chunk. INBYTES will only have an +// effect if CACHED or NO_UNPACK +// +// If you know the code to be used to unpack (or pack, or both) data to/from +// the simple 16 bit transform input/output format, then you can choose +// to this directly by defining UNPACK/PACK macros as follows: +// UNPACK(T,TO,FROM,SIZE) (Opt) code to unpack input data (T = Transform +// TO = buffer to unpack into, FROM = data, +// SIZE = size of data) +// PACK(T,FROM,TO,SIZE) (Opt) code to pack transformed input data +// (T = Transform, FROM = transformed data, +// TO = output buffer to pack into, +// SIZE = size of data) +// +// As an alternative to the above, if you know the function name that would +// be called, supply that in UNPACKFN and PACKFN and inlining compilers +// should hopefully do the hard work for you. +// UNPACKFN (Opt) function to unpack input data +// PACKFN (Opt) function to pack input data +// +// If the data happens to be in the correct input format anyway, we can skip +// unpacking it entirely and just use it direct. +// NO_UNPACK (Opt) if defined, transform direct from the input +// data. INBYTES must be defined. +// +// UNPACK/PACK/UNPACKFN/PACKFN/NO_UNPACK are all expected to update their +// TO pointer to point to the next pixels data. This means for cases where +// we have extra bytes, they should skip the extra bytes too! +// +// If the data happens to be in the correct output format anyway, we can skip +// packing it entirely and just transform it direct into the buffer. +// NO_PACK (Opt) if defined, transform direct to the output +// data. OUTBYTES must be defined. +// COPY_MATCHED(FROM,TO)(Opt)if defined, copy output values from FROM to +// TO. Used in the case CACHED case where the +// cache matches and we have to copy forwards. +// +// GAMUTCHECK can be predefined if a gamut check needs to be done. +// +// If there are a known number of extra bytes to be dealt with, define EXTRABYTES +// to that number (such as 0 for none). +// If you want to provide your own code for copying from input to output, define +// COPY_EXTRAS(TRANS,FROM,TO) to do so. +// If none of these are defined, we call cmsHandleExtraChannels. + +#ifdef INBYTES + // Previously, we've attempted to do 'int' based checks here, but this falls + // foul of some compilers with their strict pointer aliasing. We have the + // choice of calling memcmp (which tests using chars, so is safe), or of + // testing using the actual type. + #ifdef XFORM_FLOAT + #if INBYTES == 4 + #define COMPARE(A,B) ((A)[0] != (B)[0]) + #elif INBYTES == 8 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1])) + #elif INBYTES == 12 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2])) + #elif INBYTES == 16 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]) || ((A)[3] != (B)[3])) + #endif + #else + #if INBYTES == 2 + #define COMPARE(A,B) ((A)[0] != (B)[0]) + #elif INBYTES == 4 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1])) + #elif INBYTES == 6 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2])) + #elif INBYTES == 8 + #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]) || ((A)[3] != (B)[3])) + #endif + #endif +#else + // Otherwise, set INBYTES to be the maximum size it could possibly be. + #define INBYTES (sizeof(cmsUInt16Number)*cmsMAXCHANNELS) +#endif + +#ifndef COMPARE + #define COMPARE(A,B) memcmp((A),(B), INBYTES) +#endif + +#if defined(UNPACK) + // Nothing to do, UNPACK is already defined +#elif defined(NO_UNPACK) + #define UNPACK(T,TO,FROM,STRIDE) do { } while (0) +#elif defined(UNPACKFN) + #define UNPACK(T,TO,FROM,STRIDE) \ + do { (FROM) = UNPACKFN((T),(TO),(FROM),(STRIDE)); } while (0) +#elif defined(XFORM_FLOAT) + #define UNPACK(T,TO,FROM,STRIDE) \ + do { (FROM) = (T)->FromInputFloat((T),(TO),(FROM),(STRIDE)); } while (0) +#else + #define UNPACK(T,TO,FROM,STRIDE) \ + do { (FROM) = (T)->FromInput((T),(TO),(FROM),(STRIDE)); } while (0) +#endif + +#if defined(PACK) + // Nothing to do, PACK is already defined +#elif defined(NO_PACK) + #define PACK(T,FROM,TO,STRIDE) \ + do { (FROM) += ((OUTBYTES)/sizeof(XFORM_TYPE)); } while (0) +#elif defined(PACKFN) + #define PACK(T,FROM,TO,STRIDE) \ + do { (TO) = PACKFN((T),(FROM),(TO),(STRIDE)); } while (0) +#elif defined(XFORM_FLOAT) + #define PACK(T,FROM,TO,STRIDE) \ + do { (TO) = (T)->ToOutputFloat((T),(FROM),(TO),(STRIDE)); } while (0) +#else + #define PACK(T,FROM,TO,STRIDE) \ + do { (TO) = (T)->ToOutput((T),(FROM),(TO),(STRIDE)); } while (0) +#endif + +#if defined(NO_PACK) && !defined(COPY_MATCHED) + #if (defined(XFORM_FLOAT) && OUTBYTES == 4) || OUTBYTES == 2 + #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0]) + #elif (defined(XFORM_FLOAT) && OUTBYTES == 8) || OUTBYTES == 4 + #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1]) + #elif (defined(XFORM_FLOAT) && OUTBYTES == 12) || OUTBYTES == 6 + #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1],(TO)[2] = (FROM)[2]) + #elif (defined(XFORM_FLOAT) && OUTBYTES == 16) || OUTBYTES == 8 + #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1],(TO)[2] = (FROM)[2],(TO)[3] = (FROM)[3]) + #else + #define COPY_MATCHED(FROM,TO) memcpy((TO),(FROM),(OUTBYTES)) + #endif +#endif + +#ifdef XFORM_FLOAT + #define XFORM_TYPE cmsFloat32Number +#else + #define XFORM_TYPE cmsUInt16Number +#endif + +#ifndef COPY_EXTRAS + #ifdef EXTRABYTES + #if EXTRABYTES == 0 + #define COPY_EXTRAS(TRANS,FROM,TO) do { } while (0) + #else + #define COPY_EXTRAS(TRANS,FROM,TO) memcpy((TO),(FROM),(EXTRABYTES)) + #endif + #else + #define BULK_COPY_EXTRAS + #define COPY_EXTRAS(TRANS,FROM,TO) do { } while (0) + #endif +#endif + +static +void FUNCTION_NAME(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ +#ifndef NO_UNPACK + #ifdef XFORM_FLOAT + cmsFloat32Number wIn[cmsMAXCHANNELS*2]; + #else + cmsUInt64Number wIn[cmsMAXCHANNELS*2*sizeof(cmsUInt16Number)/sizeof(cmsUInt64Number)]; + #endif + #define wIn0 (&((XFORM_TYPE *)wIn)[0]) + #define wIn1 (&((XFORM_TYPE *)wIn)[cmsMAXCHANNELS]) +#endif + XFORM_TYPE *currIn; +#ifdef CACHED + XFORM_TYPE *prevIn; +#endif /* CACHED */ +#ifdef NO_PACK + XFORM_TYPE *wOut = (XFORM_TYPE *)out; + XFORM_TYPE *prevOut = (XFORM_TYPE *)p->Cache.CacheOut; +#else + XFORM_TYPE wOut[cmsMAXCHANNELS]; +#endif +#ifdef GAMUTCHECK + _cmsOPTeval16Fn evalGamut = p ->GamutCheck ->Eval16Fn; +#endif /* GAMUTCHECK */ +#ifdef XFORM_FLOAT + _cmsPipelineEvalFloatFn eval = p -> Lut -> EvalFloatFn; + const cmsPipeline *data = p->Lut; +#else + _cmsOPTeval16Fn eval = p ->Lut -> Eval16Fn; + void *data = p -> Lut -> Data; +#endif + cmsUInt32Number bppi = Stride->BytesPerPlaneIn; + cmsUInt32Number bppo = Stride->BytesPerPlaneOut; + + /* Silence some warnings */ + (void)bppi; + (void)bppo; + +#ifdef BULK_COPY_EXTRAS + if (p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA) + _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); +#endif + + if (PixelsPerLine == 0) + return; + +#ifdef NO_UNPACK + prevIn = (XFORM_TYPE *)p->Cache.CacheIn; +#else + #ifdef CACHED + // Empty buffers for quick memcmp + memset(wIn1, 0, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); + + // Get copy of zero cache + memcpy(wIn0, p->Cache.CacheIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); + memcpy(wOut, p->Cache.CacheOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); + + // The caller guarantees us that the cache is always valid on entry; if + // the representation is changed, the cache is reset. + prevIn = wIn0; + #endif /* CACHED */ + currIn = wIn1; +#endif + + while (LineCount-- > 0) + { + cmsUInt32Number n = PixelsPerLine; + cmsUInt8Number* accum = (cmsUInt8Number*) in; + cmsUInt8Number* output = (cmsUInt8Number*) out; +#ifdef NO_UNPACK + currIn = (XFORM_TYPE *)accum; +#endif + while (n-- > 0) { // prevIn == CacheIn, wOut = CacheOut + UNPACK(p,currIn,accum,bppi); +#ifdef CACHED + if (COMPARE(currIn, prevIn)) +#endif /* CACHED */ + { +#ifdef GAMUTCHECK + #ifdef XFORM_FLOAT + cmsFloat32Number OutOfGamut; + + // Evaluate gamut marker. + cmsPipelineEvalFloat( currIn, &OutOfGamut, p ->GamutCheck); + + // Is current color out of gamut? + if (OutOfGamut > 0.0) + // Certainly, out of gamut + for (j=0; j < cmsMAXCHANNELS; j++) + fOut[j] = -1.0; + else + #else + cmsUInt16Number wOutOfGamut; + + evalGamut(currIn, &wOutOfGamut, p->GamutCheck->Data); + if (wOutOfGamut >= 1) + /* RJW: Could be faster? copy once to a local buffer? */ + cmsGetAlarmCodes(wOut); + else + #endif /* FLOAT_XFORM */ +#endif /* GAMUTCHECK */ + eval(currIn, wOut, data); +#ifdef NO_UNPACK + #ifdef CACHED + prevIn = currIn; + #endif + currIn = (XFORM_TYPE *)(((char *)currIn) + INBYTES); +#else + #ifdef CACHED + {XFORM_TYPE *tmp = currIn; currIn = prevIn; prevIn = tmp;} // SWAP + #endif /* CACHED */ +#endif /* NO_UNPACK */ + } +#ifdef NO_PACK + else + COPY_MATCHED(prevOut,wOut); + prevOut = wOut; +#endif + PACK(p,wOut,output,bppo); + COPY_EXTRAS(p,accum,output); + } /* End x loop */ + in = (void *)((cmsUInt8Number *)in + Stride->BytesPerLineIn); + out = (void *)((cmsUInt8Number *)out + Stride->BytesPerLineOut); + } /* End y loop */ + /* The following code is only safe if we know that a given transform is + * called on one thread a time. */ +#if 0 +#ifdef CACHED +#ifdef NO_UNPACK + memcpy(p->Cache.CacheOut,prevIn,INBYTES); +#else + memcpy(p->Cache.CacheIn, prevIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); +#endif +#ifdef NO_PACK + COPY_MATCHED(prevOut,p->Cache.CacheOut); +#else + memcpy(p->Cache.CacheOut, wOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); +#endif /* NO_PACK */ +#endif /* CACHED */ +#endif +} + +#undef wIn0 +#undef wIn1 +#undef XFORM_TYPE +#undef XFORM_FLOAT + +#undef FUNCTION_NAME +#undef COMPARE +#undef INBYTES +#undef OUTBYTES +#undef UNPACK +#undef NO_UNPACK +#undef PACK +#undef NO_PACK +#undef UNPACKFN +#undef PACKFN +#undef GAMUTCHECK +#undef CACHED +#undef COPY_MATCHED +#undef EXTRABYTES +#undef COPY_EXTRAS +#undef BULK_COPY_EXTRAS diff --git a/windows/ghostscript.vcproj b/windows/ghostscript.vcproj index 0ae3848ea..ac963e73c 100644 --- a/windows/ghostscript.vcproj +++ b/windows/ghostscript.vcproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <VisualStudioProject ProjectType="Visual C++" Version="8.00" @@ -7368,6 +7368,10 @@ Name="lcms2" > <File + RelativePath="..\lcms2\src\cmsalpha.c" + > + </File> + <File RelativePath="..\lcms2\src\cmscam02.c" > </File> |