summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcms2/src/cmsxform.c236
-rw-r--r--lcms2/src/extra_xform.h330
-rw-r--r--windows/ghostscript.vcproj6
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>