diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-09-27 11:19:24 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-10-20 18:22:47 +0200 |
commit | cc6be9c3577168805ec34b2d396e63361012282b (patch) | |
tree | 7dc794b08a1a6a786d540516c623cb1eebfb1863 /lcms2mt/src | |
parent | Import Ghostscript 9.54 (diff) | |
download | ghostscript-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.in | 1 | ||||
-rw-r--r-- | lcms2mt/src/cmscgats.c | 21 | ||||
-rw-r--r-- | lcms2mt/src/cmsgmt.c | 61 | ||||
-rw-r--r-- | lcms2mt/src/cmsio0.c | 8 | ||||
-rw-r--r-- | lcms2mt/src/cmsopt.c | 31 | ||||
-rw-r--r-- | lcms2mt/src/cmsplugin.c | 30 | ||||
-rw-r--r-- | lcms2mt/src/cmstypes.c | 4 | ||||
-rw-r--r-- | lcms2mt/src/cmsxform.c | 1265 | ||||
-rw-r--r-- | lcms2mt/src/extra_xform.h | 326 | ||||
-rw-r--r-- | lcms2mt/src/lcms2_internal.h | 3 |
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 |