summaryrefslogtreecommitdiff
path: root/thirdparty/liblcms2/src/cmspack.c
diff options
context:
space:
mode:
authorAntonin Descampe <antonin@gmail.com>2011-03-20 22:45:24 +0000
committerAntonin Descampe <antonin@gmail.com>2011-03-20 22:45:24 +0000
commit19f9147e1076d83dd1111609ca93a01085dbfb4f (patch)
tree8ba9fe2ac562b474f627c3ae8c90eefb7d0435a3 /thirdparty/liblcms2/src/cmspack.c
parent6bda73eeb2134963f64c3d67fdd11c1304cb14f9 (diff)
Removed the libs directory containing win32 compiled versions of libpng, libtiff and liblcms. Added a thirdparty directory to include main source files of libtiff, libpng, libz and liblcms to enable support of these formats in the codec executables. CMake will try to statically build these libraries if they are not found on the system. Note that these third party libraries are not required to build libopenjpeg (which has no dependencies).
Diffstat (limited to 'thirdparty/liblcms2/src/cmspack.c')
-rw-r--r--thirdparty/liblcms2/src/cmspack.c2558
1 files changed, 2558 insertions, 0 deletions
diff --git a/thirdparty/liblcms2/src/cmspack.c b/thirdparty/liblcms2/src/cmspack.c
new file mode 100644
index 00000000..196afa94
--- /dev/null
+++ b/thirdparty/liblcms2/src/cmspack.c
@@ -0,0 +1,2558 @@
+//---------------------------------------------------------------------------------
+//
+// Little Color Management System
+// Copyright (c) 1998-2010 Marti Maria Saguer
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//---------------------------------------------------------------------------------
+//
+
+#include "lcms2_internal.h"
+
+// This module handles all formats supported by lcms. There are two flavors, 16 bits and
+// floating point. Floating point is supported only in a subset, those formats holding
+// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component as special
+// case)
+
+// ---------------------------------------------------------------------------
+
+
+// This macro return words stored as big endian
+#define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
+
+// These macros handles reversing (negative)
+#define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x)))
+#define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x)))
+
+// * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
+cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
+{
+ int a;
+
+ a = (x << 8 | x) >> 8; // * 257 / 256
+ if ( a > 0xffff) return 0xffff;
+ return (cmsUInt16Number) a;
+}
+
+// * 0xf00 / 0xffff = * 256 / 257
+cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
+{
+ return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
+}
+
+
+typedef struct {
+ cmsUInt32Number Type;
+ cmsUInt32Number Mask;
+ cmsFormatter16 Frm;
+
+} cmsFormatters16;
+
+typedef struct {
+ cmsUInt32Number Type;
+ cmsUInt32Number Mask;
+ cmsFormatterFloat Frm;
+
+} cmsFormattersFloat;
+
+#define ANYSPACE COLORSPACE_SH(31)
+#define ANYCHANNELS CHANNELS_SH(15)
+#define ANYEXTRA EXTRA_SH(7)
+#define ANYPLANAR PLANAR_SH(1)
+#define ANYENDIAN ENDIAN16_SH(1)
+#define ANYSWAP DOSWAP_SH(1)
+#define ANYSWAPFIRST SWAPFIRST_SH(1)
+#define ANYFLAVOR FLAVOR_SH(1)
+
+
+// Supress waning about info never being used
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4100)
+#endif
+
+// Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
+
+// Does almost everything but is slow
+static
+cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ cmsUInt16Number v;
+ int i;
+
+ if (ExtraFirst) {
+ accum += Extra;
+ }
+
+ for (i=0; i < nChan; i++) {
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = FROM_8_TO_16(*accum);
+ v = Reverse ? REVERSE_FLAVOR_16(v) : v;
+ wIn[index] = v;
+ accum++;
+ }
+
+ if (!ExtraFirst) {
+ accum += Extra;
+ }
+
+ if (Extra == 0 && SwapFirst) {
+ cmsUInt16Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+ wIn[nChan-1] = tmp;
+ }
+
+ return accum;
+}
+
+// Extra channels are just ignored because come in the next planes
+static
+cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap= T_DOSWAP(info ->InputFormat);
+ int Reverse= T_FLAVOR(info ->InputFormat);
+ int i;
+ cmsUInt8Number* Init = accum;
+
+ if (DoSwap) {
+ accum += T_EXTRA(info -> InputFormat) * Stride;
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+ cmsUInt16Number v = FROM_8_TO_16(*accum);
+
+ wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
+ accum += Stride;
+ }
+
+ return (Init + 1);
+}
+
+// Special cases, provided for performance
+static
+cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // C
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // M
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
+ wIn[3] = FROM_8_TO_16(*accum); accum++; // K
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
+ wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
+ wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
+ wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[3] = FROM_8_TO_16(*accum); accum++; // K
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // C
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // M
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
+
+ return accum;
+}
+
+// KYMC
+static
+cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[3] = FROM_8_TO_16(*accum); accum++; // K
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // M
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // C
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // K
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // Y
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // M
+ wIn[3] = FROM_8_TO_16(*accum); accum++; // C
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // R
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // G
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // B
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ accum++; // A
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // B
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // G
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // R
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ accum++; // A
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // R
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // G
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // B
+
+ return accum;
+}
+
+
+// BRG
+static
+cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[2] = FROM_8_TO_16(*accum); accum++; // B
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // G
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // R
+
+ return accum;
+}
+
+static
+cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
+ wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
+ wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
+
+ return accum;
+}
+
+static
+cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ accum++; // A
+ wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
+ wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
+ wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
+
+ return accum;
+}
+
+static
+cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
+ wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
+ wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
+
+ return accum;
+}
+
+// for duplex
+static
+cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
+ return accum;
+}
+
+
+
+
+// Monochrome duplicates L into RGB for null-transforms
+static
+cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+ return accum;
+}
+
+
+static
+cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+ accum += 1;
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+ accum += 2;
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
+ return accum;
+}
+
+
+static
+cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int SwapEndian = T_ENDIAN16(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ int i;
+
+ if (ExtraFirst) {
+ accum += Extra * sizeof(cmsUInt16Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+ cmsUInt16Number v = *(cmsUInt16Number*) accum;
+
+ if (SwapEndian)
+ v = CHANGE_ENDIAN(v);
+
+ wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
+
+ accum += sizeof(cmsUInt16Number);
+ }
+
+ if (!ExtraFirst) {
+ accum += Extra * sizeof(cmsUInt16Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ cmsUInt16Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+ wIn[nChan-1] = tmp;
+ }
+
+ return accum;
+}
+
+static
+cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap= T_DOSWAP(info ->InputFormat);
+ int Reverse= T_FLAVOR(info ->InputFormat);
+ int SwapEndian = T_ENDIAN16(info -> InputFormat);
+ int i;
+ cmsUInt8Number* Init = accum;
+
+ if (DoSwap) {
+ accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+ cmsUInt16Number v = *(cmsUInt16Number*) accum;
+
+ if (SwapEndian)
+ v = CHANGE_ENDIAN(v);
+
+ wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
+
+ accum += Stride * sizeof(cmsUInt16Number);
+ }
+
+ return (Init + sizeof(cmsUInt16Number));
+}
+
+
+static
+cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
+ wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
+ wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
+ wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
+ wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
+
+ return accum;
+}
+
+// KYMC
+static
+cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
+ wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
+ wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
+ wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ accum += 2; // A
+ wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
+ wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
+ wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ accum += 2; // A
+ wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
+ wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
+ wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
+
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
+
+ accum += 8;
+ return accum;
+}
+
+static
+cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
+ wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
+
+ return accum;
+}
+
+
+// This is a conversion of Lab double to 16 bits
+static
+cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ if (T_PLANAR(info -> InputFormat)) {
+
+ cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
+
+ cmsCIELab Lab;
+
+ Lab.L = Pt[0];
+ Lab.a = Pt[Stride];
+ Lab.b = Pt[Stride*2];
+
+ cmsFloat2LabEncoded(wIn, &Lab);
+ return accum + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
+ accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
+ return accum;
+ }
+}
+
+// This is a conversion of XYZ double to 16 bits
+static
+cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ if (T_PLANAR(info -> InputFormat)) {
+
+ cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
+ cmsCIEXYZ XYZ;
+
+ XYZ.X = Pt[0];
+ XYZ.Y = Pt[Stride];
+ XYZ.Z = Pt[Stride*2];
+ cmsFloat2XYZEncoded(wIn, &XYZ);
+
+ return accum + sizeof(cmsFloat64Number);
+
+ }
+
+ else {
+ cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
+ accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
+
+ return accum;
+ }
+}
+
+// Check if space is marked as ink
+cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
+{
+ switch (T_COLORSPACE(Type)) {
+
+ case PT_CMY:
+ case PT_CMYK:
+ case PT_MCH5:
+ case PT_MCH6:
+ case PT_MCH7:
+ case PT_MCH8:
+ case PT_MCH9:
+ case PT_MCH10:
+ case PT_MCH11:
+ case PT_MCH12:
+ case PT_MCH13:
+ case PT_MCH14:
+ case PT_MCH15: return TRUE;
+
+ default: return FALSE;
+ }
+}
+
+// Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
+static
+cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ cmsFloat64Number v;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+
+ v = Inks[i * Stride];
+ else
+ v = Inks[i];
+
+ wIn[i] = _cmsQuickSaturateWord(v * maximum);
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsFloat64Number);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+}
+
+static
+cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ cmsFloat32Number v;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+
+ v = Inks[i * Stride];
+ else
+ v = Inks[i];
+
+ wIn[i] = _cmsQuickSaturateWord(v * maximum);
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsFloat32Number);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+}
+
+
+// For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
+static
+cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
+
+ wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
+
+ return accum + sizeof(cmsFloat64Number);
+}
+
+//-------------------------------------------------------------------------------------------------------------------
+
+// True float transformation.
+
+// For anything going from cmsFloat32Number
+static
+cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
+
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+ wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+ else
+ wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsFloat32Number);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+}
+
+// For anything going from double
+static
+cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+ wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+ else
+ wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsFloat64Number);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+}
+
+
+// From Lab double to cmsFloat32Number
+static
+cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
+ wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
+
+ return accum + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
+ wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
+
+ accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
+ return accum;
+ }
+}
+
+// From Lab double to cmsFloat32Number
+static
+cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
+ wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
+
+ return accum + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
+ wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
+
+ accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
+ return accum;
+ }
+}
+
+
+// 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
+static
+cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
+ wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
+ wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
+
+ return accum + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
+ wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
+ wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
+
+ accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
+ return accum;
+ }
+}
+
+static
+cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
+ wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
+ wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
+
+ return accum + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
+ wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
+ wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
+
+ accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
+ return accum;
+ }
+}
+
+// Packing routines -----------------------------------------------------------------------------------------------------------
+
+
+// Generic chunky for byte
+
+static
+cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ cmsUInt8Number* swap1;
+ cmsUInt8Number v = 0;
+ int i;
+
+ swap1 = output;
+
+ if (ExtraFirst) {
+ output += Extra;
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = FROM_16_TO_8(wOut[index]);
+
+ if (Reverse)
+ v = REVERSE_FLAVOR_8(v);
+
+ *output++ = v;
+ }
+
+ if (!ExtraFirst) {
+ output += Extra;
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, nChan-1);
+ *swap1 = v;
+ }
+
+
+ return output;
+}
+
+
+
+static
+cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int SwapEndian = T_ENDIAN16(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ cmsUInt16Number* swap1;
+ cmsUInt16Number v = 0;
+ int i;
+
+ swap1 = (cmsUInt16Number*) output;
+
+ if (ExtraFirst) {
+ output += Extra * sizeof(cmsUInt16Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = wOut[index];
+
+ if (SwapEndian)
+ v = CHANGE_ENDIAN(v);
+
+ if (Reverse)
+ v = REVERSE_FLAVOR_16(v);
+
+ *(cmsUInt16Number*) output = v;
+
+ output += sizeof(cmsUInt16Number);
+ }
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsUInt16Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
+ *swap1 = v;
+ }
+
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse= T_FLAVOR(info ->OutputFormat);
+ int i;
+ cmsUInt8Number* Init = output;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+ cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
+
+ *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
+ output += Stride;
+ }
+
+ return (Init + 1);
+}
+
+
+static
+cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse= T_FLAVOR(info ->OutputFormat);
+ int SwapEndian = T_ENDIAN16(info -> OutputFormat);
+ int i;
+ cmsUInt8Number* Init = output;
+ cmsUInt16Number v;
+
+ if (DoSwap) {
+ output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = wOut[index];
+
+ if (SwapEndian)
+ v = CHANGE_ENDIAN(v);
+
+ if (Reverse)
+ v = REVERSE_FLAVOR_16(v);
+
+ *(cmsUInt16Number*) output = v;
+ output += (Stride * sizeof(cmsUInt16Number));
+ }
+
+ return (Init + sizeof(cmsUInt16Number));
+}
+
+// CMYKcm (unrolled for speed)
+
+static
+cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[3]);
+ *output++ = FROM_16_TO_8(wOut[4]);
+ *output++ = FROM_16_TO_8(wOut[5]);
+
+ return output;
+}
+
+// KCMYcm
+
+static
+cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[5]);
+ *output++ = FROM_16_TO_8(wOut[4]);
+ *output++ = FROM_16_TO_8(wOut[3]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+// CMYKcm
+static
+cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[3];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[4];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[5];
+ output+= 2;
+
+ return output;
+}
+
+// KCMYcm
+static
+cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[5];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[4];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[3];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[3]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
+ *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
+ *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
+ *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[3]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+// ABGR
+static
+cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[3]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[3]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[3];
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
+ output+= 2;
+ *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
+ output+= 2;
+ *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
+ output+= 2;
+ *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
+ output+= 2;
+
+ return output;
+}
+
+// ABGR
+static
+cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[3];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+// CMYK
+static
+cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
+
+ return output;
+}
+
+static
+cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
+ *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
+
+ return output;
+}
+
+static
+cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
+ output += 2;
+ *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
+ output += 2;
+ *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
+ output += 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = (wOut[0] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[2] & 0xFF);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = (wOut[2] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[0] & 0xFF);
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+ output++;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = (wOut[0] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[2] & 0xFF);
+ output++;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = FROM_16_TO_8(wOut[0]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = (wOut[0] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[2] & 0xFF);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = (wOut[2] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[0] & 0xFF);
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[2]);
+ *output++ = FROM_16_TO_8(wOut[1]);
+ *output++ = FROM_16_TO_8(wOut[0]);
+ output++;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = (wOut[2] & 0xFF);
+ *output++ = (wOut[1] & 0xFF);
+ *output++ = (wOut[0] & 0xFF);
+ output++;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[2];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[1];
+ output+= 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+ output+= 2;
+
+ return output;
+}
+
+
+
+static
+cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *output++ = FROM_16_TO_8(wOut[0]);
+ output++;
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output++;
+ *output++ = FROM_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
+ output+= 2;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 4;
+
+ return output;
+}
+
+static
+cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ output += 2;
+ *(cmsUInt16Number*) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+
+// Unencoded Float values -- don't try optimize speed
+static
+cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ cmsCIELab Lab;
+ cmsFloat64Number* Out = (cmsFloat64Number*) output;
+ cmsLabEncoded2Float(&Lab, wOut);
+
+ Out[0] = Lab.L;
+ Out[Stride] = Lab.a;
+ Out[Stride*2] = Lab.b;
+
+ return output + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ cmsLabEncoded2Float((cmsCIELab*) output, wOut);
+ return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+ }
+
+}
+
+static
+cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ cmsCIEXYZ XYZ;
+ cmsFloat64Number* Out = (cmsFloat64Number*) output;
+ cmsXYZEncoded2Float(&XYZ, wOut);
+
+ Out[0] = XYZ.X;
+ Out[Stride] = XYZ.Y;
+ Out[Stride*2] = XYZ.Z;
+
+ return output + sizeof(cmsFloat64Number);
+
+ }
+ else {
+
+ cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
+
+ return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+ }
+}
+
+static
+cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Inks = (cmsFloat64Number*) output;
+ int nChan = T_CHANNELS(Info -> OutputFormat);
+ int i;
+ cmsFloat64Number maximum = IsInkSpace(Info ->InputFormat) ? 655.35 : 65535.0;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i*Stride] = wOut[i] / maximum;
+ }
+
+ return output + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i] = wOut[i] / maximum;
+ }
+
+
+ return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat64Number);
+ }
+
+}
+
+static
+cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* Info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Inks = (cmsFloat32Number*) output;
+ int nChan = T_CHANNELS(Info -> OutputFormat);
+ int i;
+ cmsFloat64Number maximum = IsInkSpace(Info ->OutputFormat) ? 655.35 : 65535.0;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i*Stride] = (cmsFloat32Number) (wOut[i] / maximum);
+ }
+
+ return output + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i] = (cmsFloat32Number) (wOut[i] / maximum);
+ }
+
+
+ return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat32Number);
+ }
+
+}
+
+
+// --------------------------------------------------------------------------------------------------------
+
+static
+cmsUInt8Number* PackChunkyFloatsFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat32Number* swap1;
+ cmsFloat64Number v = 0;
+ int i;
+
+ swap1 = (cmsFloat32Number*) output;
+
+ if (ExtraFirst) {
+ output += Extra * sizeof(cmsFloat32Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = wOut[index] * maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ *(cmsFloat32Number*) output = (cmsFloat32Number) v;
+
+ output += sizeof(cmsFloat32Number);
+ }
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsFloat32Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number) v;
+ }
+
+
+ return output;
+}
+
+static
+cmsUInt8Number* PackPlanarFloatsFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse= T_FLAVOR(info ->OutputFormat);
+ int i;
+ cmsUInt8Number* Init = output;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat64Number v;
+
+ if (DoSwap) {
+ output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat32Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = wOut[index] * maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ *(cmsFloat32Number*) output = (cmsFloat32Number) v;
+ output += (Stride * sizeof(cmsFloat32Number));
+ }
+
+ return (Init + sizeof(cmsFloat32Number));
+}
+
+
+static
+cmsUInt8Number* PackChunkyDoublesFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int ExtraFirst = DoSwap && !SwapFirst;
+ cmsFloat64Number* swap1;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat64Number v = 0;
+ int i;
+
+ swap1 = (cmsFloat64Number*) output;
+
+ if (ExtraFirst) {
+ output += Extra * sizeof(cmsFloat64Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = (cmsFloat64Number) wOut[index] * maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ *(cmsFloat64Number*) output = v;
+
+ output += sizeof(cmsFloat64Number);
+ }
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsFloat64Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
+ *swap1 = v;
+ }
+
+
+ return output;
+}
+
+static
+cmsUInt8Number* PackPlanarDoublesFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse= T_FLAVOR(info ->OutputFormat);
+ int i;
+ cmsUInt8Number* Init = output;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat64Number v;
+
+ if (DoSwap) {
+ output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat64Number);
+ }
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = (cmsFloat64Number) wOut[index] * maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ *(cmsFloat64Number*) output = v;
+ output += (Stride * sizeof(cmsFloat64Number));
+ }
+
+ return (Init + sizeof(cmsFloat64Number));
+}
+
+
+
+
+static
+cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Out = (cmsFloat32Number*) output;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
+ Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
+ Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
+
+ return output + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
+ Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
+ Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
+
+ return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
+ }
+
+}
+
+static
+cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Out = (cmsFloat64Number*) output;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
+ Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
+ Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
+
+ return output + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
+ Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
+ Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
+
+ return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+ }
+
+}
+
+
+// From 0..1 range to 0..MAX_ENCODEABLE_XYZ
+static
+cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ cmsFloat32Number* Out = (cmsFloat32Number*) output;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
+ Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
+
+ return output + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
+ Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
+
+ return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
+ }
+
+}
+
+
+// Same, but convert to double
+static
+cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ cmsFloat64Number* Out = (cmsFloat64Number*) output;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
+ Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
+
+ return output + sizeof(cmsFloat64Number);
+ }
+ else {
+
+ Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
+ Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
+
+ return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+ }
+
+}
+
+
+// ----------------------------------------------------------------------------------------------------------------
+
+
+static cmsFormatters16 InputFormatters16[] = {
+
+ // Type Mask Function
+ // ---------------------------- ------------------------------------ ----------------------------
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
+ { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
+ { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
+ { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
+
+
+ { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
+ { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
+ { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
+ { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
+ { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
+
+ { TYPE_LabV2_8, 0, UnrollLabV2_8 },
+ { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
+ { TYPE_LabV2_16, 0, UnrollLabV2_16 },
+
+ { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
+ { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
+ { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
+ { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
+
+ { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
+ { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
+ { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
+ { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
+ { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
+
+ { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
+ { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
+
+
+ { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
+ { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
+ { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
+
+ { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
+ { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
+ { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
+
+ { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
+ { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
+ { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
+ { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
+ { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
+
+
+ { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords },
+ { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
+};
+
+
+
+static cmsFormattersFloat InputFormattersFloat[] = {
+
+ // Type Mask Function
+ // ---------------------------- ------------------------------------ ----------------------------
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
+ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
+
+ { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
+ { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
+};
+
+
+// Bit fields set to one in the mask are not compared
+static
+cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
+{
+ cmsUInt32Number i;
+ cmsFormatter fr;
+
+
+ if (!(dwFlags & CMS_PACK_FLAGS_FLOAT)) {
+
+ for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
+ cmsFormatters16* f = InputFormatters16 + i;
+
+ if ((dwInput & ~f ->Mask) == f ->Type) {
+ fr.Fmt16 = f ->Frm;
+ return fr;
+ }
+ }
+ }
+ else {
+ for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
+ cmsFormattersFloat* f = InputFormattersFloat + i;
+
+ if ((dwInput & ~f ->Mask) == f ->Type) {
+ fr.FmtFloat = f ->Frm;
+ return fr;
+ }
+ }
+ }
+
+ fr.Fmt16 = NULL;
+ return fr;
+}
+
+static cmsFormatters16 OutputFormatters16[] = {
+ // Type Mask Function
+ // ---------------------------- ------------------------------------ ----------------------------
+
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
+ { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
+ { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
+
+ { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
+ { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
+ { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
+
+ { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
+
+ { TYPE_LabV2_8, 0, PackLabV2_8 },
+ { TYPE_ALabV2_8, 0, PackALabV2_8 },
+ { TYPE_LabV2_16, 0, PackLabV2_16 },
+
+ { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
+ ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
+ ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
+ { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
+ ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
+ { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
+
+
+
+ { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
+ { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
+ ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
+ { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
+ { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
+ { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
+ { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
+ { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
+ { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
+ { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
+ { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
+ { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
+
+ { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
+ { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
+
+ { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
+ { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
+ { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
+ { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
+ { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
+ { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
+ { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
+ { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
+
+ { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
+ ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
+
+ { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
+ { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
+ { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
+ { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
+
+ { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
+ { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
+
+ { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
+ { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
+
+};
+
+
+static cmsFormattersFloat OutputFormattersFloat[] = {
+ // Type Mask Function
+ // ---------------------------- --------------------------------------------------- ----------------------------
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
+ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
+ { FLOAT_SH(1)|BYTES_SH(4),
+ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyFloatsFromFloat },
+ { FLOAT_SH(1)|BYTES_SH(4)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarFloatsFromFloat},
+ { FLOAT_SH(1)|BYTES_SH(0),
+ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyDoublesFromFloat },
+ { FLOAT_SH(1)|BYTES_SH(0)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarDoublesFromFloat},
+
+
+};
+
+
+// Bit fields set to one in the mask are not compared
+cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
+{
+ cmsUInt32Number i;
+ cmsFormatter fr;
+
+
+ if (dwFlags & CMS_PACK_FLAGS_FLOAT) {
+
+ for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
+ cmsFormattersFloat* f = OutputFormattersFloat + i;
+
+ if ((dwInput & ~f ->Mask) == f ->Type) {
+ fr.FmtFloat = f ->Frm;
+ return fr;
+ }
+ }
+
+ }
+ else {
+
+ for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
+ cmsFormatters16* f = OutputFormatters16 + i;
+
+ if ((dwInput & ~f ->Mask) == f ->Type) {
+ fr.Fmt16 = f ->Frm;
+ return fr;
+ }
+ }
+ }
+
+ fr.Fmt16 = NULL;
+ return fr;
+}
+
+
+typedef struct _cms_formatters_factory_list {
+
+ cmsFormatterFactory Factory;
+ struct _cms_formatters_factory_list *Next;
+
+} cmsFormattersFactoryList;
+
+static cmsFormattersFactoryList* FactoryList = NULL;
+
+
+// Formatters management
+cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Data)
+{
+ cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
+ cmsFormattersFactoryList* fl ;
+
+ // Reset
+ if (Data == NULL) {
+
+ FactoryList = NULL;
+ return TRUE;
+ }
+
+ fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList));
+ if (fl == NULL) return FALSE;
+
+ fl ->Factory = Plugin ->FormattersFactory;
+
+ fl ->Next = FactoryList;
+ FactoryList = fl;
+
+ return TRUE;
+}
+
+cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
+ cmsFormatterDirection Dir,
+ cmsUInt32Number dwFlags) // Float or 16 bits
+{
+ cmsFormattersFactoryList* f;
+
+ for (f = FactoryList; f != NULL; f = f ->Next) {
+
+ cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
+ if (fn.Fmt16 != NULL) return fn;
+ }
+
+ // Revert to default
+ if (Dir == cmsFormatterInput)
+ return _cmsGetStockInputFormatter(Type, dwFlags);
+ else
+ return _cmsGetStockOutputFormatter(Type, dwFlags);
+}
+
+
+// Return whatever given formatter refers to float values
+cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
+{
+ return T_FLOAT(Type) ? TRUE : FALSE;
+}
+
+// Return whatever given formatter refers to 8 bits
+cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
+{
+ int Bytes = T_BYTES(Type);
+
+ return (Bytes == 1);
+}
+
+// Build a suitable formatter for the colorspace of this profile
+cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
+{
+
+ cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
+ cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
+ cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
+ cmsUInt32Number Float = lIsFloat ? 1 : 0;
+
+ // Create a fake formatter for result
+ return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
+}
+
+// Build a suitable formatter for the colorspace of this profile
+cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
+{
+
+ cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
+ int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
+ cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
+ cmsUInt32Number Float = lIsFloat ? 1 : 0;
+
+ // Create a fake formatter for result
+ return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
+}
+