summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lcms2mt/src/cmsxform.c')
-rw-r--r--lcms2mt/src/cmsxform.c1265
1 files changed, 1183 insertions, 82 deletions
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);