summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2021-09-27 11:19:24 +0200
committerThomas Deutschmann <whissi@gentoo.org>2021-10-20 18:22:47 +0200
commitcc6be9c3577168805ec34b2d396e63361012282b (patch)
tree7dc794b08a1a6a786d540516c623cb1eebfb1863 /lcms2mt/src
parentImport Ghostscript 9.54 (diff)
downloadghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.gz
ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.bz2
ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.zip
Import Ghostscript 9.55ghostscript-9.55
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'lcms2mt/src')
-rw-r--r--lcms2mt/src/Makefile.in1
-rw-r--r--lcms2mt/src/cmscgats.c21
-rw-r--r--lcms2mt/src/cmsgmt.c61
-rw-r--r--lcms2mt/src/cmsio0.c8
-rw-r--r--lcms2mt/src/cmsopt.c31
-rw-r--r--lcms2mt/src/cmsplugin.c30
-rw-r--r--lcms2mt/src/cmstypes.c4
-rw-r--r--lcms2mt/src/cmsxform.c1265
-rw-r--r--lcms2mt/src/extra_xform.h326
-rw-r--r--lcms2mt/src/lcms2_internal.h3
10 files changed, 1576 insertions, 174 deletions
diff --git a/lcms2mt/src/Makefile.in b/lcms2mt/src/Makefile.in
index 2ac60348..46235be8 100644
--- a/lcms2mt/src/Makefile.in
+++ b/lcms2mt/src/Makefile.in
@@ -272,6 +272,7 @@ LIB_ZLIB = @LIB_ZLIB@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
diff --git a/lcms2mt/src/cmscgats.c b/lcms2mt/src/cmscgats.c
index dcad06a0..87ee1db3 100644
--- a/lcms2mt/src/cmscgats.c
+++ b/lcms2mt/src/cmscgats.c
@@ -1503,6 +1503,25 @@ cmsInt32Number satoi(const char* b)
return atoi(b);
}
+// Convert to binary
+static
+const char* satob(const char* v)
+{
+ cmsUInt32Number x;
+ static char buf[33];
+ char *s = buf + 33;
+
+ if (v == NULL) return "0";
+
+ x = atoi(v);
+ *--s = 0;
+ if (!x) *--s = '0';
+ for (; x; x /= 2) *--s = '0' + x%2;
+
+ return s;
+}
+
+
static
void AllocateDataSet(cmsContext ContextID, cmsIT8* it8)
{
@@ -1689,7 +1708,7 @@ void WriteHeader(cmsContext ContextID, cmsIT8* it8, SAVESTREAM* fp)
break;
case WRITE_BINARY:
- Writef(ContextID, fp, "\t0x%B", satoi(p ->Value));
+ Writef(ContextID, fp, "\t0b%s", satob(p ->Value));
break;
case WRITE_PAIR:
diff --git a/lcms2mt/src/cmsgmt.c b/lcms2mt/src/cmsgmt.c
index e255ab9d..941e59ce 100644
--- a/lcms2mt/src/cmsgmt.c
+++ b/lcms2mt/src/cmsgmt.c
@@ -587,3 +587,64 @@ cmsBool CMSEXPORT cmsDesaturateLab(cmsContext ContextID, cmsCIELab* Lab,
return TRUE;
}
+
+// Detect whatever a given ICC profile works in linear (gamma 1.0) space
+// Actually, doing that "well" is quite hard, since every component may behave completely different.
+// Since the true point of this function is to detect suitable optimizations, I am imposing some requirements
+// that simplifies things: only RGB, and only profiles that can got in both directions.
+// The algorith obtains Y from a syntetical gray R=G=B. Then least squares fitting is used to estimate gamma.
+// For gamma close to 1.0, RGB is linear. On profiles not supported, -1 is returned.
+
+cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsContext ContextID, cmsHPROFILE hProfile, cmsFloat64Number thereshold)
+{
+ cmsHPROFILE hXYZ;
+ cmsHTRANSFORM xform;
+ cmsToneCurve* Y_curve;
+ cmsUInt16Number rgb[256][3];
+ cmsCIEXYZ XYZ[256];
+ cmsFloat32Number Y_normalized[256];
+ cmsFloat64Number gamma;
+ cmsProfileClassSignature cl;
+ int i;
+
+ if (cmsGetColorSpace(ContextID, hProfile) != cmsSigRgbData)
+ return -1;
+
+ cl = cmsGetDeviceClass(ContextID, hProfile);
+ if (cl != cmsSigInputClass && cl != cmsSigDisplayClass &&
+ cl != cmsSigOutputClass && cl != cmsSigColorSpaceClass)
+ return -1;
+
+ hXYZ = cmsCreateXYZProfile(ContextID);
+ xform = cmsCreateTransform(ContextID, hProfile, TYPE_RGB_16, hXYZ, TYPE_XYZ_DBL,
+ INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE);
+
+ if (xform == NULL) { // If not RGB or forward direction is not supported, regret with the previous error
+
+ cmsCloseProfile(ContextID, hXYZ);
+ return -1;
+ }
+
+ for (i = 0; i < 256; i++) {
+ rgb[i][0] = rgb[i][1] = rgb[i][2] = FROM_8_TO_16(i);
+ }
+
+ cmsDoTransform(ContextID, xform, rgb, XYZ, 256);
+
+ cmsDeleteTransform(ContextID, xform);
+ cmsCloseProfile(ContextID, hXYZ);
+
+ for (i = 0; i < 256; i++) {
+ Y_normalized[i] = (cmsFloat32Number) XYZ[i].Y;
+ }
+
+ Y_curve = cmsBuildTabulatedToneCurveFloat(ContextID, 256, Y_normalized);
+ if (Y_curve == NULL)
+ return -1;
+
+ gamma = cmsEstimateGamma(ContextID, Y_curve, thereshold);
+
+ cmsFreeToneCurve(ContextID, Y_curve);
+
+ return gamma;
+}
diff --git a/lcms2mt/src/cmsio0.c b/lcms2mt/src/cmsio0.c
index 83b37445..2fce03c9 100644
--- a/lcms2mt/src/cmsio0.c
+++ b/lcms2mt/src/cmsio0.c
@@ -492,7 +492,6 @@ cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsContext ContextID, cmsHPROFILE
// Creates an empty structure holding all required parameters
cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
{
- time_t now = time(NULL);
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) _cmsMallocZero(ContextID, sizeof(_cmsICCPROFILE));
if (Icc == NULL) return NULL;
@@ -504,13 +503,18 @@ cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
Icc ->Version = 0x02100000;
// Set creation date/time
- memmove(&Icc ->Created, gmtime(&now), sizeof(Icc ->Created));
+ if (!_cmsGetTime(&Icc->Created))
+ goto Error;
// Create a mutex if the user provided proper plugin. NULL otherwise
Icc ->UsrMutex = _cmsCreateMutex(ContextID);
// Return the handle
return (cmsHPROFILE) Icc;
+
+Error:
+ _cmsFree(ContextID, Icc);
+ return NULL;
}
// Return the number of tags
diff --git a/lcms2mt/src/cmsopt.c b/lcms2mt/src/cmsopt.c
index 8fca60f8..562911ec 100644
--- a/lcms2mt/src/cmsopt.c
+++ b/lcms2mt/src/cmsopt.c
@@ -648,7 +648,6 @@ cmsBool OptimizeByResampling(cmsContext ContextID, cmsPipeline** Lut, cmsUInt32N
{
cmsPipeline* Src = NULL;
cmsPipeline* Dest = NULL;
- cmsStage* mpe;
cmsStage* CLUT;
cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL;
cmsUInt32Number nGridPoints;
@@ -670,7 +669,7 @@ cmsBool OptimizeByResampling(cmsContext ContextID, cmsPipeline** Lut, cmsUInt32N
if (ColorSpace == (cmsColorSpaceSignature)0 ||
OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE;
- nGridPoints = _cmsReasonableGridpointsByColorspace(ContextID, ColorSpace, *dwFlags);
+ nGridPoints = _cmsReasonableGridpointsByColorspace(ContextID, ColorSpace, *dwFlags);
// For empty LUTs, 2 points are enough
if (cmsPipelineStageCount(ContextID, *Lut) == 0)
@@ -678,13 +677,6 @@ cmsBool OptimizeByResampling(cmsContext ContextID, cmsPipeline** Lut, cmsUInt32N
Src = *Lut;
- // Named color pipelines cannot be optimized either
- for (mpe = cmsPipelineGetPtrToFirstStage(ContextID, Src);
- mpe != NULL;
- mpe = cmsStageNext(ContextID, mpe)) {
- if (cmsStageType(ContextID, mpe) == cmsSigNamedColorElemType) return FALSE;
- }
-
// Allocate an empty LUT
Dest = cmsPipelineAlloc(ContextID, Src ->InputChannels, Src ->OutputChannels);
if (!Dest) return FALSE;
@@ -1053,7 +1045,6 @@ cmsBool OptimizeByComputingLinearization(cmsContext ContextID, cmsPipeline** Lut
cmsStage* OptimizedCLUTmpe;
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
cmsStage* OptimizedPrelinMpe;
- cmsStage* mpe;
cmsToneCurve** OptimizedPrelinCurves;
_cmsStageCLutData* OptimizedPrelinCLUT;
@@ -1074,14 +1065,6 @@ cmsBool OptimizeByComputingLinearization(cmsContext ContextID, cmsPipeline** Lut
}
OriginalLut = *Lut;
-
- // Named color pipelines cannot be optimized either
- for (mpe = cmsPipelineGetPtrToFirstStage(ContextID, OriginalLut);
- mpe != NULL;
- mpe = cmsStageNext(ContextID, mpe)) {
- if (cmsStageType(ContextID, mpe) == cmsSigNamedColorElemType) return FALSE;
- }
-
ColorSpace = _cmsICCcolorSpace(ContextID, (int) T_COLORSPACE(*InputFormat));
OutputColorSpace = _cmsICCcolorSpace(ContextID, (int) T_COLORSPACE(*OutputFormat));
@@ -1699,6 +1682,10 @@ cmsBool OptimizeMatrixShaper(cmsContext ContextID, cmsPipeline** Lut, cmsUInt32N
// Only works on 8 bit input
if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE;
+ // Does not work in the presence of premultiplied alpha, as that causes the values
+ // passed in to not actually be '8 bit' in the way that we rely on.
+ if (*dwFlags & cmsFLAGS_PREMULT) return FALSE;
+
// Seems suitable, proceed
Src = *Lut;
@@ -1926,6 +1913,7 @@ cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
_cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin);
_cmsOptimizationCollection* Opts;
cmsBool AnySuccess = FALSE;
+ cmsStage* mpe;
// A CLUT is being asked, so force this specific optimization
if (*dwFlags & cmsFLAGS_FORCE_CLUT) {
@@ -1940,6 +1928,13 @@ cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
return TRUE;
}
+ // Named color pipelines cannot be optimized
+ for (mpe = cmsPipelineGetPtrToFirstStage(ContextID, *PtrLut);
+ mpe != NULL;
+ mpe = cmsStageNext(ContextID, mpe)) {
+ if (cmsStageType(ContextID, mpe) == cmsSigNamedColorElemType) return FALSE;
+ }
+
// Try to get rid of identities and trivial conversions.
AnySuccess = PreOptimize(ContextID, *PtrLut);
diff --git a/lcms2mt/src/cmsplugin.c b/lcms2mt/src/cmsplugin.c
index 2a6e6b6b..279bcbd1 100644
--- a/lcms2mt/src/cmsplugin.c
+++ b/lcms2mt/src/cmsplugin.c
@@ -571,7 +571,7 @@ cmsBool CMSEXPORT cmsPlugin(cmsContext id, void* Plug_in)
if (Plugin ->ExpectedVersion < LCMS2MT_VERSION_MIN ||
Plugin ->ExpectedVersion > LCMS2MT_VERSION_MAX) {
- cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin version %d not in acceptable version range. LCMS2.art cannot use LCMS2 plugins!",
+ cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin version %d not in acceptable version range. LCMS2MT cannot use LCMS2 plugins!",
Plugin ->ExpectedVersion);
return FALSE;
}
@@ -1001,3 +1001,31 @@ cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta)
return refs;
}
+
+// Use context mutex to provide thread-safe time
+cmsBool _cmsGetTime(struct tm* ptr_time)
+{
+ struct tm* t;
+#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+ struct tm tm;
+#endif
+
+ time_t now = time(NULL);
+
+#ifdef HAVE_GMTIME_R
+ t = gmtime_r(&now, &tm);
+#elif defined(HAVE__GMTIME64_S)
+ t = _gmtime64_s(&tm, &now) == 0 ? &tm : NULL;
+#else
+ _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+ t = gmtime(&now);
+ _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+#endif
+
+ if (t == NULL)
+ return FALSE;
+ else {
+ *ptr_time = *t;
+ return TRUE;
+ }
+}
diff --git a/lcms2mt/src/cmstypes.c b/lcms2mt/src/cmstypes.c
index 1d8c2a38..32471b92 100644
--- a/lcms2mt/src/cmstypes.c
+++ b/lcms2mt/src/cmstypes.c
@@ -1893,7 +1893,7 @@ Error:
static
cmsBool Type_LUT8_Write(cmsContext ContextID, struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
- cmsUInt32Number j, nTabSize, i, n;
+ cmsUInt32Number j, nTabSize, i;
cmsUInt8Number val;
cmsPipeline* NewLUT = (cmsPipeline*) Ptr;
cmsStage* mpe;
@@ -1943,8 +1943,6 @@ cmsBool Type_LUT8_Write(cmsContext ContextID, struct _cms_typehandler_struct* s
if (!_cmsWriteUInt8Number(ContextID, io, (cmsUInt8Number) clutPoints)) return FALSE;
if (!_cmsWriteUInt8Number(ContextID, io, 0)) return FALSE; // Padding
- n = NewLUT->InputChannels * NewLUT->OutputChannels;
-
if (MatMPE != NULL) {
for (i = 0; i < 9; i++)
diff --git a/lcms2mt/src/cmsxform.c b/lcms2mt/src/cmsxform.c
index 2d85434e..7f4e1589 100644
--- a/lcms2mt/src/cmsxform.c
+++ b/lcms2mt/src/cmsxform.c
@@ -352,6 +352,22 @@ void NullFloatXFORM(cmsContext ContextID, _cmsTRANSFORM* p,
}
}
+cmsINLINE int mul255(cmsUInt32Number a, cmsUInt32Number b)
+{
+ /* see Jim Blinn's book "Dirty Pixels" for how this works */
+ cmsUInt32Number x = a * b + 128;
+ x += x >> 8;
+ return x >> 8;
+}
+
+cmsINLINE cmsUInt32Number mul65535(cmsUInt32Number a, cmsUInt32Number b)
+{
+ /* see Jim Blinn's book "Dirty Pixels" for how this works */
+ cmsUInt32Number x = a * b + 0x8000;
+ x += x >> 16;
+ return x >> 16;
+}
+
// 16 bit precision -----------------------------------------------------------------------------------------------------------
// Null transformation, only applies formatters. No cache
@@ -397,6 +413,11 @@ void NullXFORM(cmsContext ContextID,
#define FUNCTION_NAME PrecalculatedXFORM
#include "extra_xform.h"
+// No gamut check, no cache, 16 bits
+#define PREALPHA
+#define FUNCTION_NAME PrecalculatedXFORM_P
+#include "extra_xform.h"
+
// No gamut check, no cache, Identity transform, including pack/unpack
static
void PrecalculatedXFORMIdentity(cmsContext ContextID,
@@ -510,6 +531,12 @@ void TransformOnePixelWithGamutCheck(cmsContext ContextID, _cmsTRANSFORM* p,
#define GAMUTCHECK
#include "extra_xform.h"
+// Gamut check, No cache, 16 bits.
+#define FUNCTION_NAME PrecalculatedXFORMGamutCheck_P
+#define PREALPHA
+#define GAMUTCHECK
+#include "extra_xform.h"
+
// No gamut check, Cache, 16 bits,
#define FUNCTION_NAME CachedXFORM
#define CACHED
@@ -521,30 +548,40 @@ void TransformOnePixelWithGamutCheck(cmsContext ContextID, _cmsTRANSFORM* p,
#define GAMUTCHECK
#include "extra_xform.h"
+// All those nice features together
+#define FUNCTION_NAME CachedXFORMGamutCheck_P
+#define CACHED
+#define PREALPHA
+#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
+#define CMPBYTES 4
+#define NUMEXTRAS 0
#include "extra_xform.h"
// No gamut check, Cache, 16 bits, <= 8 bytes total
#define FUNCTION_NAME CachedXFORM8
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
+#define CMPBYTES 8
+#define NUMEXTRAS 0
#include "extra_xform.h"
// Special ones for common cases.
#define FUNCTION_NAME CachedXFORM1to1
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
} while (0)
@@ -552,13 +589,16 @@ do { \
#define FUNCTION_NAME CachedXFORM1x2to1x2
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
} while (0)
@@ -566,13 +606,16 @@ do { \
#define FUNCTION_NAME CachedXFORM1to3
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -582,13 +625,16 @@ do { \
#define FUNCTION_NAME CachedXFORM1x2to3x2
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -598,13 +644,16 @@ do { \
#define FUNCTION_NAME CachedXFORM1to4
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -615,13 +664,16 @@ do { \
#define FUNCTION_NAME CachedXFORM1x2to4x2
#define CACHED
-#define INBYTES 2
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -632,15 +684,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3to1
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
} while (0)
@@ -648,15 +703,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3x2to1x2
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
} while (0)
@@ -664,15 +722,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3to3
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -682,15 +743,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3x2to3x2
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -700,15 +764,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3to4
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -719,15 +786,18 @@ do { \
#define FUNCTION_NAME CachedXFORM3x2to4x2
#define CACHED
-#define INBYTES 6
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -738,16 +808,19 @@ do { \
#define FUNCTION_NAME CachedXFORM4to1
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
(D)[3] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
} while (0)
@@ -755,16 +828,19 @@ do { \
#define FUNCTION_NAME CachedXFORM4x2to1x2
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
} while (0)
@@ -772,16 +848,19 @@ do { \
#define FUNCTION_NAME CachedXFORM4to3
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
(D)[3] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -791,16 +870,19 @@ do { \
#define FUNCTION_NAME CachedXFORM4x2to3x2
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -810,16 +892,19 @@ do { \
#define FUNCTION_NAME CachedXFORM4to4
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = FROM_8_TO_16(*(S)); (S)++; \
(D)[1] = FROM_8_TO_16(*(S)); (S)++; \
(D)[2] = FROM_8_TO_16(*(S)); (S)++; \
(D)[3] = FROM_8_TO_16(*(S)); (S)++; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(D)++ = FROM_16_TO_8((S)[0]); \
*(D)++ = FROM_16_TO_8((S)[1]); \
@@ -830,16 +915,387 @@ do { \
#define FUNCTION_NAME CachedXFORM4x2to4x2
#define CACHED
-#define INBYTES 8
-#define EXTRABYTES 0
-#define UNPACK(CTX,T,D,S,Z) \
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 0
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[3]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+// Same again, but with alpha
+// Special ones for common cases.
+#define FUNCTION_NAME CachedXFORM1to1_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to1x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1to3_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 3
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to3x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1to4_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+ *(D)++ = FROM_16_TO_8((S)[3]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to4x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[3]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to1_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to1x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to3_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to3x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to4_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+ *(D)++ = FROM_16_TO_8((S)[3]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to4x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[3]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to1_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[3] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to1x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to3_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[3] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to3x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
+ (D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
+ *(cmsUInt16Number *)(D) = (S)[2]; (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to4_1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ (D)[0] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[1] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[2] = FROM_8_TO_16(*(S)); (S)++; \
+ (D)[3] = FROM_8_TO_16(*(S)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = FROM_16_TO_8((S)[0]); \
+ *(D)++ = FROM_16_TO_8((S)[1]); \
+ *(D)++ = FROM_16_TO_8((S)[2]); \
+ *(D)++ = FROM_16_TO_8((S)[3]); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to4x2_2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define UNPACK(CTX,T,D,S,Z,A) \
do { \
(D)[0] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[1] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[2] = *(cmsUInt16Number *)(S); (S) += 2; \
(D)[3] = *(cmsUInt16Number *)(S); (S) += 2; \
} while (0)
-#define PACK(CTX,T,S,D,Z) \
+#define PACK(CTX,T,S,D,Z,A) \
do { \
*(cmsUInt16Number *)(D) = (S)[0]; (D) += 2; \
*(cmsUInt16Number *)(D) = (S)[1]; (D) += 2; \
@@ -848,6 +1304,465 @@ do { \
} while (0)
#include "extra_xform.h"
+
+// Same again, but with premultiplied alpha
+//
+// No gamut check, Cache, 16 bits,
+#define FUNCTION_NAME CachedXFORM_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define PREALPHA
+#include "extra_xform.h"
+
+// No gamut check, Cache, 16 bits,
+#define FUNCTION_NAME CachedXFORM_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define PREALPHA
+#include "extra_xform.h"
+
+// Special ones for common cases.
+#define FUNCTION_NAME CachedXFORM1to1_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to1x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1to3_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to3x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1to4_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[3]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM1x2to4x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 1
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[3],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to1_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)((*(S) * inva)); (S)++; \
+ (D)[1] = (cmsUInt16Number)((*(S) * inva)); (S)++; \
+ (D)[2] = (cmsUInt16Number)((*(S) * inva)); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to1x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to3_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[1] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[2] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to3x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3to4_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[1] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[2] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[3]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM3x2to4x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 3
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[3],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to1_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[1] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[2] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[3] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to1x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 1
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[3] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to3_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[1] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[2] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[3] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to3x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 3
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[3] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4to4_P1
+#define CACHED
+#define INPACKEDSAMPLESIZE 1
+#define OUTPACKEDSAMPLESIZE 1
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xFFFFU / (A); \
+ (D)[0] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[1] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[2] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+ (D)[3] = (cmsUInt16Number)(*(S) * inva); (S)++; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(D)++ = mul255(FROM_16_TO_8((S)[0]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[1]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[2]),(A)); \
+ *(D)++ = mul255(FROM_16_TO_8((S)[3]),(A)); \
+} while (0)
+#include "extra_xform.h"
+
+#define FUNCTION_NAME CachedXFORM4x2to4x2_P2
+#define CACHED
+#define INPACKEDSAMPLESIZE 2
+#define OUTPACKEDSAMPLESIZE 2
+#define NUMINCHANNELS 4
+#define NUMOUTCHANNELS 4
+#define NUMEXTRAS 1
+#define PREALPHA
+#define UNPACKINCLUDESPREALPHA
+#define PACKINCLUDESPREALPHA
+#define UNPACK(CTX,T,D,S,Z,A) \
+do { \
+ cmsUInt32Number inva = 0xffff0000U / (A); \
+ (D)[0] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[1] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[2] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+ (D)[3] = (cmsUInt16Number)(((*(cmsUInt16Number *)(S)) * inva)>>16); (S) += 2; \
+} while (0)
+#define PACK(CTX,T,S,D,Z,A) \
+do { \
+ *(cmsUInt16Number *)(D) = mul65535((S)[0],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[1],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[2],A); (D) += 2; \
+ *(cmsUInt16Number *)(D) = mul65535((S)[3],A); (D) += 2; \
+} while (0)
+#include "extra_xform.h"
+
+
// Transform plug-ins ----------------------------------------------------------------------------------------------------
// List of used-defined transform factories
@@ -966,8 +1881,10 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
if (fl == NULL) return FALSE;
// Check for full xform plug-ins previous to 2.8, we would need an adapter in that case
- if (Plugin->base.ExpectedVersion < 2080-2000) {
-
+ if ((Plugin->base.ExpectedVersion <= LCMS2MT_VERSION_MAX &&
+ Plugin->base.ExpectedVersion < 2080-2000) ||
+ (Plugin->base.ExpectedVersion > LCMS2MT_VERSION_MAX &&
+ Plugin->base.ExpectedVersion < 2080)) {
fl->OldXform = TRUE;
}
else
@@ -1028,6 +1945,34 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number
p ->xform = NullXFORM;
return;
}
+ if (dwFlags & cmsFLAGS_PREMULT) {
+ if (dwFlags & cmsFLAGS_NOCACHE) {
+ if (dwFlags & cmsFLAGS_GAMUTCHECK)
+ p ->xform = PrecalculatedXFORMGamutCheck_P; // Gamut check, no cache
+ else if ((InputFormat & ~COLORSPACE_SH(31)) == (OutputFormat & ~COLORSPACE_SH(31)) &&
+ _cmsLutIsIdentity(p->core->Lut)) {
+ if (T_PLANAR(InputFormat))
+ p ->xform = PrecalculatedXFORMIdentityPlanar;
+ else
+ p ->xform = PrecalculatedXFORMIdentity;
+ } else
+ p ->xform = PrecalculatedXFORM_P; // No cache, no gamut check
+ return;
+ }
+ if (dwFlags & cmsFLAGS_GAMUTCHECK) {
+ p ->xform = CachedXFORMGamutCheck_P; // Gamut check, cache
+ return;
+ }
+ if ((InputFormat & ~COLORSPACE_SH(31)) == (OutputFormat & ~COLORSPACE_SH(31)) &&
+ _cmsLutIsIdentity(p->core->Lut)) {
+ /* No point in a cache here! */
+ if (T_PLANAR(InputFormat))
+ p ->xform = PrecalculatedXFORMIdentityPlanar;
+ else
+ p ->xform = PrecalculatedXFORMIdentity;
+ return;
+ }
+ }
if (dwFlags & cmsFLAGS_NOCACHE) {
if (dwFlags & cmsFLAGS_GAMUTCHECK)
p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cache
@@ -1039,11 +1984,11 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number
p ->xform = PrecalculatedXFORMIdentity;
} else
p ->xform = PrecalculatedXFORM; // No cache, no gamut check
- return;
+ return;
}
if (dwFlags & cmsFLAGS_GAMUTCHECK) {
p ->xform = CachedXFORMGamutCheck; // Gamut check, cache
- return;
+ return;
}
if ((InputFormat & ~COLORSPACE_SH(31)) == (OutputFormat & ~COLORSPACE_SH(31)) &&
_cmsLutIsIdentity(p->core->Lut)) {
@@ -1054,8 +1999,140 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number
p ->xform = PrecalculatedXFORMIdentity;
return;
}
+ if (T_EXTRA(InputFormat) == 1 && T_EXTRA(OutputFormat) == 1) {
+ if (dwFlags & cmsFLAGS_PREMULT) {
+ if ((InputFormat & ~(COLORSPACE_SH(31)|CHANNELS_SH(7)|BYTES_SH(3)|EXTRA_SH(1))) == 0 &&
+ (OutputFormat & ~(COLORSPACE_SH(31)|CHANNELS_SH(7)|BYTES_SH(3)|EXTRA_SH(1))) == 0) {
+ switch ((InputFormat & (CHANNELS_SH(7)|BYTES_SH(3)))|
+ ((OutputFormat & (CHANNELS_SH(7)|BYTES_SH(3)))<<6)) {
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to1_P1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to1x2_P2;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to3_P1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to3x2_P2;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to4_P1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to4x2_P2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p ->xform = CachedXFORM3to1_P1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p ->xform = CachedXFORM3x2to1x2_P2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM3to3_P1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM3x2to3x2_P2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM3to4_P1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM3x2to4x2_P2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to1_P1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to1x2_P2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to3_P1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to3x2_P2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to4_P1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to4x2_P2;
+ return;
+ }
+ }
+ } else {
+ if ((InputFormat & ~(COLORSPACE_SH(31)|CHANNELS_SH(7)|BYTES_SH(3)|EXTRA_SH(1))) == 0 &&
+ (OutputFormat & ~(COLORSPACE_SH(31)|CHANNELS_SH(7)|BYTES_SH(3)|EXTRA_SH(1))) == 0) {
+ switch ((InputFormat & (CHANNELS_SH(7)|BYTES_SH(3)))|
+ ((OutputFormat & (CHANNELS_SH(7)|BYTES_SH(3)))<<6)) {
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to1_1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to1x2_2;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to3_1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to3x2_2;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM1to4_1;
+ return;
+ case CHANNELS_SH(1) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM1x2to4x2_2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p ->xform = CachedXFORM3to1_1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p ->xform = CachedXFORM3x2to1x2_2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM3to3_1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM3x2to3x2_2;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM3to4_1;
+ return;
+ case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM3x2to4x2_2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to1_1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to1x2_2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(3) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to3_1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(3) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to3x2_2;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(1) | ((CHANNELS_SH(4) | BYTES_SH(1))<<6):
+ p->xform = CachedXFORM4to4_1;
+ return;
+ case CHANNELS_SH(4) | BYTES_SH(2) | ((CHANNELS_SH(4) | BYTES_SH(2))<<6):
+ p->xform = CachedXFORM4x2to4x2_2;
+ return;
+ }
+ }
+ }
+ }
if (T_EXTRA(InputFormat) != 0) {
- p ->xform = CachedXFORM; // No gamut check, cache
+ if (dwFlags & cmsFLAGS_PREMULT) {
+ if (T_BYTES(InputFormat) == 1)
+ p ->xform = CachedXFORM_P1;// No gamut check, cache
+ else
+ p ->xform = CachedXFORM_P2;// No gamut check, cache
+ } else {
+ p ->xform = CachedXFORM; // No gamut check, cache
+ }
return;
}
if ((InputFormat & ~(COLORSPACE_SH(31)|CHANNELS_SH(7)|BYTES_SH(3))) == 0 &&
@@ -1082,7 +2159,7 @@ _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number
return;
case CHANNELS_SH(3) | BYTES_SH(1) | ((CHANNELS_SH(1) | BYTES_SH(1))<<6):
p ->xform = CachedXFORM3to1;
- return;
+ return;
case CHANNELS_SH(3) | BYTES_SH(2) | ((CHANNELS_SH(1) | BYTES_SH(2))<<6):
p ->xform = CachedXFORM3x2to1x2;
return;
@@ -1416,6 +2493,15 @@ cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID,
return NULL;
}
+ // Check whatever the transform is 16 bits and involves linear RGB in first profile. If so, disable optimizations
+ if (EntryColorSpace == cmsSigRgbData && T_BYTES(InputFormat) == 2 && !(dwFlags & cmsFLAGS_NOOPTIMIZE))
+ {
+ cmsFloat64Number gamma = cmsDetectRGBProfileGamma(ContextID, hProfiles[0], 0.1);
+
+ if (gamma > 0 && gamma < 1.6)
+ dwFlags |= cmsFLAGS_NOOPTIMIZE;
+ }
+
// Create a pipeline with all transformations
Lut = _cmsLinkProfiles(ContextID, nProfiles, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
if (Lut == NULL) {
@@ -1431,6 +2517,21 @@ cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID,
return NULL;
}
+ // Check premultiplication requirements
+ if (dwFlags & cmsFLAGS_PREMULT) {
+ if (T_BYTES(InputFormat) != T_BYTES(OutputFormat)) {
+ cmsPipelineFree(ContextID, Lut);
+ cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Premultiplication requires input and output to be in the same format.");
+ return NULL;
+ }
+
+ if (T_EXTRA(InputFormat) < 1 || T_EXTRA(OutputFormat) < 1 || T_EXTRA(InputFormat) != T_EXTRA(OutputFormat) || (dwFlags & cmsFLAGS_COPY_ALPHA) == 0) {
+ cmsPipelineFree(ContextID, Lut);
+ cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Premultiplication must preserve the extra channels");
+ return NULL;
+ }
+ }
+
// All seems ok
xform = AllocEmptyTransform(ContextID, Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags);
diff --git a/lcms2mt/src/extra_xform.h b/lcms2mt/src/extra_xform.h
index 51dd0e05..3f8a75f7 100644
--- a/lcms2mt/src/extra_xform.h
+++ b/lcms2mt/src/extra_xform.h
@@ -14,20 +14,48 @@
//
// 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 the representation/calculations are to be done using floating point
+// define XFORM_FLOAT. In the absence of this it is assumed that the
+// calculations will be done in 16 bit with appropriate unpacking/repacking.
+//
+// If you know the number of input/output channels, define NUMINCHANNELS and
+// NUMOUTCHANNELS.
+//
+// If you know the number of bytes used for the packed version of input and/or
+// output, define INPACKEDSAMPLESIZE and OUTPACKEDSAMPLESIZE.
+//
+// If you do not know the number of channels and/or the sample size, but you
+// do know a maximum bound on the number of bytes used to represent the
+// unpacked samples, then operation with CACHE can be accelerated by defining
+// CMPBYTES to the number of bytes that should be compared to the cached result.
+// Usually that is calculated from NUMINCHANNELS and INPACKEDSAMPLESIZE, so
+// specifying it directly is only useful if either (or both) of those is not
+// known in advance.
+//
+// For Premultiplied Alpha modes, you must define PREMULT. We only support
+// premultiplied alpha where the alpha is the last 'extra' channel, and
+// where both source and destination are packed in the same way.
//
// 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)
+// UNPACK(T,TO,FROM,SIZE,AL) (Opt) code to unpack input data (T = Transform
+// TO = buffer to unpack into, FROM = data,
+// SIZE = size of data, AL = Alpha)
+// PACK(T,FROM,TO,SIZE,AL) (Opt) code to pack transformed input data
+// (T = Transform, FROM = transformed data,
+// TO = output buffer to pack into,
+// SIZE = size of data, AL = Alpha)
+//
+// Ignore AL unless PREMULT is defined, in which case it will be in the packed
+// format. AL is guaranteed to be non-zero.
+//
+// If UNPACKINCLUDESPREALPHA is defined, then UNPACK should undo the
+// premultiplication by AL (i.e. divide by AL). Otherwise AL should be ignored
+// and this routine will do it for you.
+//
+// If PACKINCLUDESPREALPHA is defined, then PACK should apply AL (i.e. multiply
+// by AL). Otherwise AL should be ignored and this routine will do it for you.
//
// 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
@@ -38,7 +66,7 @@
// 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.
+// data.
//
// 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
@@ -47,7 +75,7 @@
// 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.
+// data.
// 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.
@@ -60,73 +88,126 @@
// COPY_EXTRAS(TRANS,FROM,TO) to do so.
// If none of these are defined, we call cmsHandleExtraChannels.
-#ifdef INBYTES
+#ifndef CMPBYTES
+#ifdef NUMINCHANNELS
+#ifdef XFORM_FLOAT
+#define CMPBYTES (NUMINCHANNELS*4)
+#else
+#define CMPBYTES (NUMINCHANNELS*2)
+#endif
+#endif
+#endif
+
+#ifdef CMPBYTES
// 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
+ #if CMPBYTES == 4
#define COMPARE(A,B) ((A)[0] != (B)[0])
- #elif INBYTES == 8
+ #elif CMPBYTES == 8
#define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]))
- #elif INBYTES == 12
+ #elif CMPBYTES == 12
#define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]))
- #elif INBYTES == 16
+ #elif CMPBYTES == 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
+ #if CMPBYTES == 2
#define COMPARE(A,B) ((A)[0] != (B)[0])
- #elif INBYTES == 4
+ #elif CMPBYTES == 4
#define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]))
- #elif INBYTES == 6
+ #elif CMPBYTES == 6
#define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]))
- #elif INBYTES == 8
+ #elif CMPBYTES == 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)
+ #ifdef XFORM_FLOAT
+ #define CMPBYTES (sizeof(cmsFloat32Number)*cmsMAXCHANNELS)
+ #else
+ #define CMPBYTES (sizeof(cmsUInt16Number)*cmsMAXCHANNELS)
+ #endif
#endif
#ifndef COMPARE
- #define COMPARE(A,B) memcmp((A),(B), INBYTES)
+ #define COMPARE(A,B) memcmp((A),(B), CMPBYTES)
#endif
#if defined(UNPACK)
// Nothing to do, UNPACK is already defined
#elif defined(NO_UNPACK)
- #define UNPACK(CTX,T,TO,FROM,STRIDE) do { } while (0)
+ #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) do { } while (0)
#elif defined(UNPACKFN)
- #define UNPACK(CTX,T,TO,FROM,STRIDE) \
- do { (FROM) = UNPACKFN((CTX),(T),(TO),(FROM),(STRIDE)); } while (0)
+ #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \
+ do { (FROM) = UNPACKFN((CTX),(T),(TO),(FROM),(STRIDE),(AL)); } while (0)
#elif defined(XFORM_FLOAT)
- #define UNPACK(CTX,T,TO,FROM,STRIDE) \
+ #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \
do { (FROM) = (T)->FromInputFloat((CTX),(T),(TO),(FROM),(STRIDE)); } while (0)
#else
- #define UNPACK(CTX,T,TO,FROM,STRIDE) \
+ #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \
do { (FROM) = (T)->FromInput((CTX),(T),(TO),(FROM),(STRIDE)); } while (0)
#endif
#if defined(PACK)
// Nothing to do, PACK is already defined
#elif defined(NO_PACK)
- #define PACK(CTX,T,FROM,TO,STRIDE) \
- do { (FROM) += ((OUTBYTES)/sizeof(XFORM_TYPE)); } while (0)
+ #define PACK(CTX,T,FROM,TO,STRIDE,AL) \
+ do { (FROM) += (totaloutbytes/sizeof(XFORM_TYPE)); } while (0)
#elif defined(PACKFN)
- #define PACK(CTX,T,FROM,TO,STRIDE) \
+ #define PACK(CTX,T,FROM,TO,STRIDE,AL) \
do { (TO) = PACKFN((CTX),(T),(FROM),(TO),(STRIDE)); } while (0)
#elif defined(XFORM_FLOAT)
- #define PACK(CTX,T,FROM,TO,STRIDE) \
+ #define PACK(CTX,T,FROM,TO,STRIDE,AL) \
do { (TO) = (T)->ToOutputFloat((CTX),(T),(FROM),(TO),(STRIDE)); } while (0)
#else
- #define PACK(CTX,T,FROM,TO,STRIDE) \
+ #define PACK(CTX,T,FROM,TO,STRIDE,AL) \
do { (TO) = (T)->ToOutput((CTX),(T),(FROM),(TO),(STRIDE)); } while (0)
#endif
-#if defined(NO_PACK) && !defined(COPY_MATCHED)
+#ifndef ZEROPACK
+/* The 'default' definition of ZEROPACK only works when
+ * inpackedsamplesize == outpackedsamplesize. */
+#define ZEROPACK(CTX,T,TO,FROM) do { \
+ memset((TO),0,numoutchannels*outpackedsamplesize);\
+ if (numextras != 0) memcpy((TO)+numoutchannels*outpackedsamplesize,\
+ (FROM)+numinchannels*inpackedsamplesize,\
+ numextras*outpackedsamplesize);\
+ (TO)+=(1+prealphaindexout)*outpackedsamplesize; } while (0)
+#endif
+
+#ifndef UNPRE
+#ifdef PREALPHA
+#else
+#define UNPRE(CTX,T,S,A) do {} while (0)
+#endif
+#endif
+
+#ifndef REPRE
+#ifdef PREALPHA
+#define REPRE(CTX,T,S,A) do { int i; for (i = 0; i < numoutchannels; i++) \
+ (S)[i] = mul65535((S)[i],A); } while (0)
+#else
+#define REPRE(CTX,T,S,A) do {} while (0)
+#endif
+#endif
+
+#ifndef XFORMVARS
+#define XFORMVARS(p) do { } while (0)
+#endif
+
+#if defined(NUMOUTCHANNELS)
+ #ifdef XFORM_FLOAT
+ #define OUTBYTES (sizeof(cmsFloat32Number)*NUMOUTCHANNELS)
+ #else
+ #define OUTBYTES (sizeof(cmsUInt16Number)*NUMOUTCHANNELS)
+ #endif
+#endif
+
+#if defined(NO_PACK) && !defined(COPY_MATCHED) && defined(OUTBYTES)
#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
@@ -147,11 +228,15 @@
#endif
#ifndef COPY_EXTRAS
- #ifdef EXTRABYTES
- #if EXTRABYTES == 0
+ #ifdef NUMEXTRAS
+ #if NUMEXTRAS == 0
#define COPY_EXTRAS(TRANS,FROM,TO) do { } while (0)
#else
- #define COPY_EXTRAS(TRANS,FROM,TO) memcpy((TO),(FROM),(EXTRABYTES))
+ #define COPY_EXTRAS(TRANS,FROM,TO) \
+ do { memcpy((TO),(FROM),(NUMEXTRAS)*inpackedsamplesize); \
+ (TO) += (NUMEXTRAS)*inpackedsamplesize; \
+ (FROM) += (NUMEXTRAS)*inpackedsamplesize; \
+ } while (0)
#endif
#else
#define BULK_COPY_EXTRAS
@@ -188,6 +273,9 @@ void FUNCTION_NAME(cmsContext ContextID,
#else
XFORM_TYPE wOut[cmsMAXCHANNELS];
#endif
+#if defined(PREALPHA) && !defined(PACKINCLUDESPREALPHA)
+ XFORM_TYPE wScaled[cmsMAXCHANNELS];
+#endif
#ifdef GAMUTCHECK
_cmsPipelineEval16Fn evalGamut = core->GamutCheck->Eval16Fn;
#endif /* GAMUTCHECK */
@@ -200,10 +288,46 @@ void FUNCTION_NAME(cmsContext ContextID,
#endif
cmsUInt32Number bppi = Stride->BytesPerPlaneIn;
cmsUInt32Number bppo = Stride->BytesPerPlaneOut;
+#ifdef NUMINCHANNELS
+ int numinchannels = NUMINCHANNELS;
+#else
+ int numinchannels = T_CHANNELS(p->InputFormat);
+#endif
+#ifdef NUMOUTCHANNELS
+ int numoutchannels = NUMOUTCHANNELS;
+#else
+ int numoutchannels = T_CHANNELS(p->OutputFormat);
+#endif
+#ifdef NUMEXTRAS
+ int numextras = NUMEXTRAS;
+#else
+ int numextras = T_EXTRA(p->InputFormat);
+#endif
+#ifdef INPACKEDSAMPLESIZE
+ int inpackedsamplesize = INPACKEDSAMPLESIZE;
+#else
+ int inpackedsamplesize = T_BYTES(p->InputFormat);
+#endif
+#ifdef OUTPACKEDSAMPLESIZE
+ int outpackedsamplesize = OUTPACKEDSAMPLESIZE;
+#else
+ int outpackedsamplesize = T_BYTES(p->OutputFormat);
+#endif
+ int prealphaindexin = numinchannels + numextras - 1;
+ int prealphaindexout = numoutchannels + numextras - 1;
+ int totalinbytes = (numinchannels + numextras)*inpackedsamplesize;
+ int totaloutbytes = (numoutchannels + numextras)*outpackedsamplesize;
/* Silence some warnings */
(void)bppi;
(void)bppo;
+ (void)prealphaindexin;
+ (void)numextras;
+ (void)prealphaindexout;
+ (void)inpackedsamplesize;
+ (void)outpackedsamplesize;
+ (void)totalinbytes;
+ (void)totaloutbytes;
#ifdef BULK_COPY_EXTRAS
if (core->dwOriginalFlags & cmsFLAGS_COPY_ALPHA)
@@ -240,53 +364,111 @@ void FUNCTION_NAME(cmsContext ContextID,
currIn = (XFORM_TYPE *)accum;
#endif
while (n-- > 0) { // prevIn == CacheIn, wOut = CacheOut
- UNPACK(ContextID,p,currIn,accum,bppi);
+#ifdef PREALPHA
+ #ifdef XFORM_FLOAT
+ cmsFloat32Number alpha = ((cmsFloat32Number *)accum)[prealphaindexin];
+ #else
+ cmsUInt32Number alpha = inpackedsamplesize == 2 ?
+ ((cmsUInt16Number *)accum)[prealphaindexin] :
+ (accum[prealphaindexin]);
+ #endif
+ if (alpha == 0) {
+ ZEROPACK(ContextID,p,output,accum);
+ accum += inpackedsamplesize*(prealphaindexin+1);
+ } else {
+#endif
+ UNPACK(ContextID,p,currIn,accum,bppi,alpha);
+#ifdef PREALPHA
+ #ifndef UNPACKINCLUDESPREALPHA
+ #ifdef XFORM_FLOAT
+ {
+ int i;
+ cmsFloat32Number inva = 1.0f / alpha;
+ for (i = 0; i < numinchannels; i++)
+ currIn[i] *= inva;
+ }
+ #else
+ {
+ int i;
+ cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha;
+ cmsUInt32Number inva = 0xffff0000U / al;
+ for (i = 0; i < numinchannels; i++)
+ currIn[i] = ((currIn[i] * inva)>>16);
+ }
+ #endif
+ #endif
+#endif
#ifdef CACHED
- if (COMPARE(currIn, prevIn))
+ if (COMPARE(currIn, prevIn))
#endif /* CACHED */
- {
+ {
#ifdef GAMUTCHECK
#ifdef XFORM_FLOAT
- cmsFloat32Number OutOfGamut;
+ cmsFloat32Number OutOfGamut;
- // Evaluate gamut marker.
- cmsPipelineEvalFloat(currIn, &OutOfGamut, core->GamutCheck);
+ // Evaluate gamut marker.
+ cmsPipelineEvalFloat(currIn, &OutOfGamut, core->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
+ // 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;
+ cmsUInt16Number wOutOfGamut;
- evalGamut(ContextID, currIn, &wOutOfGamut, core->GamutCheck->Data);
- if (wOutOfGamut >= 1)
- /* RJW: Could be faster? copy once to a local buffer? */
- cmsGetAlarmCodes(ContextID, wOut);
- else
+ evalGamut(ContextID, currIn, &wOutOfGamut, core->GamutCheck->Data);
+ if (wOutOfGamut >= 1)
+ /* RJW: Could be faster? copy once to a local buffer? */
+ cmsGetAlarmCodes(ContextID, wOut);
+ else
#endif /* FLOAT_XFORM */
#endif /* GAMUTCHECK */
- eval(ContextID, currIn, wOut, data);
+ eval(ContextID, currIn, wOut, data);
#ifdef NO_UNPACK
#ifdef CACHED
- prevIn = currIn;
+ prevIn = currIn;
#endif
- currIn = (XFORM_TYPE *)(((char *)currIn) + INBYTES);
+ currIn = (XFORM_TYPE *)(((char *)currIn) + totalinbytes);
#else
#ifdef CACHED
- {XFORM_TYPE *tmp = currIn; currIn = prevIn; prevIn = tmp;} // SWAP
+ {XFORM_TYPE *tmp = currIn; currIn = prevIn; prevIn = tmp;} // SWAP
#endif /* CACHED */
#endif /* NO_UNPACK */
- }
+ }
#ifdef NO_PACK
- else
- COPY_MATCHED(prevOut,wOut);
- prevOut = wOut;
+ else
+ COPY_MATCHED(prevOut,wOut);
+ prevOut = wOut;
+#endif
+#ifdef PREALPHA
+ #ifndef PACKINCLUDESPREALPHA
+ #ifdef XFORM_FLOAT
+ {
+ int i;
+ for (i = 0; i < numoutchannels; i++)
+ wScaled = wOut[i] * alpha;
+ }
+ #else
+ {
+ int i;
+ cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha;
+ for (i = 0; i < numoutchannels; i++)
+ wScaled[i] = mul65535(wOut[i],al);
+ }
+ #endif
+ PACK(ContextID,p,wScaled,output,bppo,alpha);
+ #else
+ PACK(ContextID,p,wOut,output,bppo,alpha);
+ #endif
+#else
+ PACK(ContextID,p,wOut,output,bppo,alpha);
+#endif
+ COPY_EXTRAS(p,accum,output);
+#ifdef PREALPHA
+ }
#endif
- PACK(ContextID,p,wOut,output,bppo);
- COPY_EXTRAS(p,accum,output);
} /* End x loop */
in = (void *)((cmsUInt8Number *)in + Stride->BytesPerLineIn);
out = (void *)((cmsUInt8Number *)out + Stride->BytesPerLineOut);
@@ -296,7 +478,7 @@ void FUNCTION_NAME(cmsContext ContextID,
#if 0
#ifdef CACHED
#ifdef NO_UNPACK
- memcpy(p->Cache.CacheIn,prevIn,INBYTES);
+ memcpy(p->Cache.CacheIn,prevIn, CMPBYTES);
#else
memcpy(p->Cache.CacheIn, prevIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS);
#endif
@@ -316,7 +498,7 @@ void FUNCTION_NAME(cmsContext ContextID,
#undef FUNCTION_NAME
#undef COMPARE
-#undef INBYTES
+#undef CMPBYTES
#undef OUTBYTES
#undef UNPACK
#undef NO_UNPACK
@@ -330,3 +512,13 @@ void FUNCTION_NAME(cmsContext ContextID,
#undef EXTRABYTES
#undef COPY_EXTRAS
#undef BULK_COPY_EXTRAS
+#undef PREALPHA
+#undef ZEROPACK
+#undef XFORMVARS
+#undef UNPRE
+#undef REPRE
+#undef INPACKEDSAMPLESIZE
+#undef OUTPACKEDSAMPLESIZE
+#undef NUMINCHANNELS
+#undef NUMOUTCHANNELS
+#undef NUMEXTRAS
diff --git a/lcms2mt/src/lcms2_internal.h b/lcms2mt/src/lcms2_internal.h
index da205ebf..504393e2 100644
--- a/lcms2mt/src/lcms2_internal.h
+++ b/lcms2mt/src/lcms2_internal.h
@@ -1120,5 +1120,8 @@ void _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32N
cmsUInt32Number _cmsAdjustReferenceCount(cmsUInt32Number *rc, int delta);
+// thread-safe gettime
+cmsBool _cmsGetTime(struct tm* ptr_time);
+
#define _lcms_internal_H
#endif