summaryrefslogtreecommitdiffstats
path: root/debian/lcms/lcms-1.19.dfsg2/src/cmspack.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/lcms/lcms-1.19.dfsg2/src/cmspack.c')
-rwxr-xr-xdebian/lcms/lcms-1.19.dfsg2/src/cmspack.c2146
1 files changed, 2146 insertions, 0 deletions
diff --git a/debian/lcms/lcms-1.19.dfsg2/src/cmspack.c b/debian/lcms/lcms-1.19.dfsg2/src/cmspack.c
new file mode 100755
index 00000000..230ea34c
--- /dev/null
+++ b/debian/lcms/lcms-1.19.dfsg2/src/cmspack.c
@@ -0,0 +1,2146 @@
+// Little cms
+// Copyright (C) 1998-2007 Marti Maria
+//
+// 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 "lcms.h"
+
+// This module handles all formats supported by lcms
+
+
+// ---------------------------------------------------------------------------
+
+
+// This macro return words stored as big endian
+
+#define CHANGE_ENDIAN(w) (WORD) ((WORD) ((w)<<8)|((w)>>8))
+
+// These macros handles reversing (negative)
+
+#define REVERSE_FLAVOR_8(x) ((BYTE) (0xff-(x)))
+#define REVERSE_FLAVOR_16(x) ((WORD)(0xffff-(x)))
+
+// Supress waning about info never being used
+
+#ifdef __BORLANDC__
+#pragma warn -par
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4100)
+#endif
+
+// -------------------------------------------------------- Unpacking routines.
+
+
+static
+LPBYTE UnrollAnyBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ register int i;
+
+ for (i=0; i < nChan; i++) {
+
+ wIn[i] = RGB_8_TO_16(*accum); accum++;
+ }
+
+ return accum + T_EXTRA(info -> InputFormat);
+}
+
+
+
+static
+LPBYTE Unroll4Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // C
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // M
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // K
+
+ return accum;
+}
+
+static
+LPBYTE Unroll4BytesReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
+ wIn[1] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
+ wIn[2] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
+ wIn[3] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
+
+ return accum;
+}
+
+
+static
+LPBYTE Unroll4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // K
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // C
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // M
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
+
+
+ return accum;
+}
+
+
+
+// KYMC
+static
+LPBYTE Unroll4BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // K
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // M
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // C
+
+ return accum;
+}
+
+
+static
+LPBYTE Unroll4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // K
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // Y
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // M
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // C
+
+ return accum;
+}
+
+
+static
+LPBYTE UnrollAnyWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ register int i;
+
+ for (i=0; i < nChan; i++) {
+
+ wIn[i] = *(LPWORD) accum; accum += 2;
+ }
+
+ return accum + T_EXTRA(info -> InputFormat) * sizeof(WORD);
+}
+
+
+static
+LPBYTE Unroll4Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = *(LPWORD) accum; accum+= 2; // C
+ wIn[1] = *(LPWORD) accum; accum+= 2; // M
+ wIn[2] = *(LPWORD) accum; accum+= 2; // Y
+ wIn[3] = *(LPWORD) accum; accum+= 2; // K
+
+ return accum;
+}
+
+static
+LPBYTE Unroll4WordsReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // C
+ wIn[1] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // M
+ wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // Y
+ wIn[3] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // K
+
+ return accum;
+}
+
+
+static
+LPBYTE Unroll4WordsSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = *(LPWORD) accum; accum+= 2; // K
+ wIn[0] = *(LPWORD) accum; accum+= 2; // C
+ wIn[1] = *(LPWORD) accum; accum+= 2; // M
+ wIn[2] = *(LPWORD) accum; accum+= 2; // Y
+
+ return accum;
+}
+
+
+// KYMC
+static
+LPBYTE Unroll4WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = *(LPWORD) accum; accum+= 2; // K
+ wIn[2] = *(LPWORD) accum; accum+= 2; // Y
+ wIn[1] = *(LPWORD) accum; accum+= 2; // M
+ wIn[0] = *(LPWORD) accum; accum+= 2; // C
+
+ return accum;
+}
+
+static
+LPBYTE Unroll4WordsSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[2] = *(LPWORD) accum; accum+= 2; // K
+ wIn[1] = *(LPWORD) accum; accum+= 2; // Y
+ wIn[0] = *(LPWORD) accum; accum+= 2; // M
+ wIn[3] = *(LPWORD) accum; accum+= 2; // C
+
+ return accum;
+}
+
+
+static
+LPBYTE Unroll4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
+ wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
+ wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
+ wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
+
+ return accum;
+}
+
+static
+LPBYTE Unroll4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //C
+ wIn[1] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //M
+ wIn[2] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //Y
+ wIn[3] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //K
+
+ return accum;
+}
+
+
+// KYMC
+static
+LPBYTE Unroll4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
+ wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
+ wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
+ wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
+
+ return accum;
+}
+
+static
+LPBYTE Unroll3Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // R
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // G
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // B
+
+ return accum;
+}
+
+
+// Lab8 encoding using v2 PCS
+
+static
+LPBYTE Unroll3BytesLab(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+
+ wIn[0] = (WORD) ((*accum) << 8); accum++;
+ wIn[1] = (WORD) ((*accum) << 8); accum++;
+ wIn[2] = (WORD) ((*accum) << 8); accum++;
+
+ return accum;
+}
+
+
+// BRG
+
+static
+LPBYTE Unroll3BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+
+ wIn[2] = RGB_8_TO_16(*accum); accum++; // B
+ wIn[1] = RGB_8_TO_16(*accum); accum++; // G
+ wIn[0] = RGB_8_TO_16(*accum); accum++; // R
+
+ return accum;
+}
+
+static
+LPBYTE Unroll3Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = *(LPWORD) accum; accum+= 2; // C R
+ wIn[1] = *(LPWORD) accum; accum+= 2; // M G
+ wIn[2] = *(LPWORD) accum; accum+= 2; // Y B
+ return accum;
+}
+
+
+static
+LPBYTE Unroll3WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[2] = *(LPWORD) accum; accum+= 2; // C R
+ wIn[1] = *(LPWORD) accum; accum+= 2; // M G
+ wIn[0] = *(LPWORD) accum; accum+= 2; // Y B
+ return accum;
+}
+
+
+static
+LPBYTE Unroll3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ return accum;
+}
+
+
+static
+LPBYTE Unroll3WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ return accum;
+}
+
+
+
+// Monochrome duplicates L into RGB for null-transforms
+
+static
+LPBYTE Unroll1Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
+ return accum;
+}
+
+
+static
+LPBYTE Unroll1ByteSkip2(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
+ accum += 2;
+ return accum;
+}
+
+static
+LPBYTE Unroll1ByteReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(RGB_8_TO_16(*accum)); accum++; // L
+ return accum;
+}
+
+
+static
+LPBYTE Unroll1Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
+ return accum;
+}
+
+static
+LPBYTE Unroll1WordReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2;
+ return accum;
+}
+
+
+static
+LPBYTE Unroll1WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ return accum;
+}
+
+static
+LPBYTE Unroll1WordSkip3(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum;
+
+ accum += 8;
+ return accum;
+}
+
+
+// Monochrome + alpha. Alpha is lost
+
+static
+LPBYTE Unroll2Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // alpha
+ return accum;
+}
+
+static
+LPBYTE Unroll2ByteSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = RGB_8_TO_16(*accum); accum++; // alpha
+ wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
+ return accum;
+}
+
+
+static
+LPBYTE Unroll2Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
+ wIn[3] = *(LPWORD) accum; accum += 2; // alpha
+
+ return accum;
+}
+
+
+static
+LPBYTE Unroll2WordSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[3] = *(LPWORD) accum; accum += 2; // alpha
+ wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
+
+ return accum;
+}
+
+static
+LPBYTE Unroll2WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+ wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
+
+ return accum;
+}
+
+
+
+
+static
+LPBYTE UnrollPlanarBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ register int i;
+ LPBYTE Init = accum;
+
+ for (i=0; i < nChan; i++) {
+
+ wIn[i] = RGB_8_TO_16(*accum);
+ accum += info -> StrideIn;
+ }
+
+ return (Init + 1);
+}
+
+
+
+static
+LPBYTE UnrollPlanarWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ register int i;
+ LPBYTE Init = accum;
+
+ for (i=0; i < nChan; i++) {
+
+ wIn[i] = *(LPWORD) accum;
+ accum += (info -> StrideIn * sizeof(WORD));
+ }
+
+ return (Init + sizeof(WORD));
+}
+
+
+
+static
+LPBYTE UnrollPlanarWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ int nChan = T_CHANNELS(info -> InputFormat);
+ register int i;
+ LPBYTE Init = accum;
+
+ for (i=0; i < nChan; i++) {
+
+ wIn[i] = CHANGE_ENDIAN(*(LPWORD) accum);
+ accum += (info -> StrideIn * sizeof(WORD));
+ }
+
+ return (Init + sizeof(WORD));
+}
+
+
+// floating point
+static
+LPBYTE UnrollLabDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ double* Pt = (double*) accum;
+
+ cmsCIELab Lab;
+
+ Lab.L = Pt[0];
+ Lab.a = Pt[info->StrideIn];
+ Lab.b = Pt[info->StrideIn*2];
+
+ if (info ->lInputV4Lab)
+ cmsFloat2LabEncoded4(wIn, &Lab);
+ else
+ cmsFloat2LabEncoded(wIn, &Lab);
+
+ return accum + sizeof(double);
+ }
+ else {
+
+ if (info ->lInputV4Lab)
+ cmsFloat2LabEncoded4(wIn, (LPcmsCIELab) accum);
+ else
+ cmsFloat2LabEncoded(wIn, (LPcmsCIELab) accum);
+
+ accum += sizeof(cmsCIELab);
+
+ return accum;
+ }
+}
+
+static
+LPBYTE UnrollXYZDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ if (T_PLANAR(info -> InputFormat)) {
+
+ double* Pt = (double*) accum;
+ cmsCIEXYZ XYZ;
+
+ XYZ.X = Pt[0];
+ XYZ.Y = Pt[info->StrideIn];
+ XYZ.Z = Pt[info->StrideIn*2];
+ cmsFloat2XYZEncoded(wIn, &XYZ);
+
+ return accum + sizeof(double);
+
+ }
+
+ else {
+
+
+ cmsFloat2XYZEncoded(wIn, (LPcmsCIEXYZ) accum);
+ accum += sizeof(cmsCIEXYZ);
+
+ return accum;
+ }
+}
+
+
+
+// Inks does come in percentage
+static
+LPBYTE UnrollInkDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ double* Inks = (double*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ double v;
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+
+ v = Inks[i * info ->StrideIn];
+ else
+ v = Inks[i];
+
+ v = floor(v * 655.35 + 0.5);
+
+ if (v > 65535.0) v = 65535.0;
+ if (v < 0) v = 0;
+
+ wIn[i] = (WORD) v;
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(double);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
+}
+
+
+// Remaining cases are between 0..1.0
+static
+LPBYTE UnrollDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ double* Inks = (double*) accum;
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int Planar = T_PLANAR(info -> InputFormat);
+ int i;
+ double v;
+
+ for (i=0; i < nChan; i++) {
+
+ if (Planar)
+
+ v = Inks[i * info ->StrideIn];
+ else
+ v = Inks[i];
+
+ v = floor(v * 65535.0 + 0.5);
+
+ if (v > 65535.0) v = 65535.0;
+ if (v < 0) v = 0;
+
+ wIn[i] = (WORD) v;
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(double);
+ else
+ return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
+}
+
+
+
+static
+LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+ double* Inks = (double*) accum;
+ double v;
+
+
+ v = floor(Inks[0] * 65535.0 + 0.5);
+
+ if (v > 65535.0) v = 65535.0;
+ if (v < 0) v = 0;
+
+
+ wIn[0] = wIn[1] = wIn[2] = (WORD) v;
+
+ return accum + sizeof(double);
+}
+
+
+// ----------------------------------------------------------- Packing routines
+
+
+// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
+
+static int err[MAXCHANNELS];
+
+static
+LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+ unsigned int n, pe, pf;
+
+ for (i=0; i < nChan; i++) {
+
+ n = wOut[i] + err[i]; // Value
+
+ pe = (n / 257); // Whole part
+ pf = (n % 257); // Fractional part
+
+ err[i] = pf; // Store it for next pixel
+
+ *output++ = (BYTE) pe;
+ }
+
+ return output + T_EXTRA(info ->OutputFormat);
+}
+
+
+
+static
+LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+ unsigned int n, pe, pf;
+
+ for (i=nChan-1; i >= 0; --i) {
+
+ n = wOut[i] + err[i]; // Value
+
+ pe = (n / 257); // Whole part
+ pf = (n % 257); // Fractional part
+
+ err[i] = pf; // Store it for next pixel
+
+ *output++ = (BYTE) pe;
+ }
+
+
+ return output + T_EXTRA(info ->OutputFormat);
+}
+
+
+
+// Generic chunky for byte
+
+static
+LPBYTE PackNBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=0; i < nChan; i++)
+ *output++ = RGB_16_TO_8(wOut[i]);
+
+ return output + T_EXTRA(info ->OutputFormat);
+}
+
+// Chunky reversed order bytes
+
+static
+LPBYTE PackNBytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=nChan-1; i >= 0; --i)
+ *output++ = RGB_16_TO_8(wOut[i]);
+
+ return output + T_EXTRA(info ->OutputFormat);
+
+}
+
+
+static
+LPBYTE PackNWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=0; i < nChan; i++) {
+ *(LPWORD) output = wOut[i];
+ output += sizeof(WORD);
+ }
+
+ return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
+}
+
+static
+LPBYTE PackNWordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=nChan-1; i >= 0; --i) {
+ *(LPWORD) output = wOut[i];
+ output += sizeof(WORD);
+ }
+
+ return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
+}
+
+
+
+static
+LPBYTE PackNWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=0; i < nChan; i++) {
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
+ output += sizeof(WORD);
+ }
+
+ return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
+}
+
+
+static
+LPBYTE PackNWordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+
+ for (i=nChan-1; i >= 0; --i) {
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
+ output += sizeof(WORD);
+ }
+
+ return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
+}
+
+
+static
+LPBYTE PackPlanarBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+ LPBYTE Init = output;
+
+ for (i=0; i < nChan; i++) {
+
+ *(LPBYTE) output = RGB_16_TO_8(wOut[i]);
+ output += info -> StrideOut;
+ }
+
+ return (Init + 1);
+}
+
+
+static
+LPBYTE PackPlanarWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ register int i;
+ LPBYTE Init = output;
+
+ for (i=0; i < nChan; i++) {
+
+ *(LPWORD) output = wOut[i];
+ output += (info -> StrideOut * sizeof(WORD));
+ }
+
+ return (Init + 2);
+}
+
+
+// CMYKcm (unrolled for speed)
+
+static
+LPBYTE Pack6Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[3]);
+ *output++ = RGB_16_TO_8(wOut[4]);
+ *output++ = RGB_16_TO_8(wOut[5]);
+
+ return output;
+}
+
+// KCMYcm
+
+static
+LPBYTE Pack6BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[3]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[4]);
+ *output++ = RGB_16_TO_8(wOut[5]);
+
+ return output;
+}
+
+// CMYKcm
+static
+LPBYTE Pack6Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[3];
+ output+= 2;
+ *(LPWORD) output = wOut[4];
+ output+= 2;
+ *(LPWORD) output = wOut[5];
+ output+= 2;
+
+ return output;
+}
+
+// KCMYcm
+static
+LPBYTE Pack6WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[3];
+ output+= 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[4];
+ output+= 2;
+ *(LPWORD) output = wOut[5];
+ output+= 2;
+
+ return output;
+}
+
+// CMYKcm
+static
+LPBYTE Pack6WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
+ output+= 2;
+
+ return output;
+}
+
+// KCMYcm
+static
+LPBYTE Pack6WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[3]);
+
+ return output;
+}
+
+static
+LPBYTE Pack4BytesReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[0]));
+ *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[1]));
+ *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[2]));
+ *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[3]));
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[3]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+
+// ABGR
+
+static
+LPBYTE Pack4BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[3]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[3]);
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[3];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4WordsReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = REVERSE_FLAVOR_16(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = REVERSE_FLAVOR_16(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = REVERSE_FLAVOR_16(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = REVERSE_FLAVOR_16(wOut[3]);
+ output+= 2;
+
+ return output;
+}
+
+// ABGR
+
+static
+LPBYTE Pack4WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[3];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+// CMYK
+static
+LPBYTE Pack4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[0]));
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[1]));
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[2]));
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[3]));
+ output+= 2;
+
+ return output;
+}
+
+// KYMC
+
+static
+LPBYTE Pack4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+
+ return output;
+}
+
+static
+LPBYTE Pack3Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+static
+LPBYTE Pack3BytesLab(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = (BYTE) (wOut[0] >> 8);
+ *output++ = (BYTE) (wOut[1] >> 8);
+ *output++ = (BYTE) (wOut[2] >> 8);
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+
+ return output;
+}
+
+static
+LPBYTE Pack3WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+static
+LPBYTE Pack3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3WordsSwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3BytesAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+ output++;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3BytesAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output++;
+ *output++ = RGB_16_TO_8(wOut[0]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[2]);
+
+ return output;
+}
+
+static
+LPBYTE Pack3BytesAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output++;
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3BytesAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[2]);
+ *output++ = RGB_16_TO_8(wOut[1]);
+ *output++ = RGB_16_TO_8(wOut[0]);
+ output++;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3WordsAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ output+= 2;
+
+ return output;
+}
+
+static
+LPBYTE Pack3WordsAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output+= 2;
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3WordsAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[2];
+ output+= 2;
+ *(LPWORD) output = wOut[1];
+ output+= 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+ output+= 2;
+
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3WordsAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack3WordsAndSkip1SwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
+ output+= 2;
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+
+
+ return output;
+}
+
+
+
+static
+LPBYTE Pack1Byte(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ return output;
+}
+
+
+static
+LPBYTE Pack1ByteAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *output++ = RGB_16_TO_8(wOut[0]);
+ output++;
+ return output;
+}
+
+
+static
+LPBYTE Pack1ByteAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output++;
+ *output++ = RGB_16_TO_8(wOut[0]);
+
+ return output;
+}
+
+static
+LPBYTE Pack1Word(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+static
+LPBYTE Pack1WordBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack1WordAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = wOut[0];
+ output+= 4;
+
+ return output;
+}
+
+static
+LPBYTE Pack1WordAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ output += 2;
+ *(LPWORD) output = wOut[0];
+ output+= 2;
+
+ return output;
+}
+
+
+static
+LPBYTE Pack1WordAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
+ output+= 4;
+
+ return output;
+}
+
+
+// Unencoded Float values -- don't try optimize speed
+
+static
+LPBYTE PackLabDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ cmsCIELab Lab;
+ double* Out = (double*) output;
+ cmsLabEncoded2Float(&Lab, wOut);
+
+ Out[0] = Lab.L;
+ Out[Info ->StrideOut] = Lab.a;
+ Out[Info ->StrideOut*2] = Lab.b;
+
+ return output + sizeof(double);
+
+ }
+ else {
+
+ if (Info ->lOutputV4Lab)
+ cmsLabEncoded2Float4((LPcmsCIELab) output, wOut);
+ else
+ cmsLabEncoded2Float((LPcmsCIELab) output, wOut);
+
+ return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
+ }
+
+}
+
+static
+LPBYTE PackXYZDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ cmsCIEXYZ XYZ;
+ double* Out = (double*) output;
+ cmsXYZEncoded2Float(&XYZ, wOut);
+
+ Out[0] = XYZ.X;
+ Out[Info ->StrideOut] = XYZ.Y;
+ Out[Info ->StrideOut*2] = XYZ.Z;
+
+ return output + sizeof(double);
+
+ }
+ else {
+
+ cmsXYZEncoded2Float((LPcmsCIEXYZ) output, wOut);
+
+ return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
+ }
+}
+
+
+
+static
+LPBYTE PackInkDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ double* Inks = (double*) output;
+ int nChan = T_CHANNELS(Info -> OutputFormat);
+ int i;
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i*Info ->StrideOut] = wOut[i] / 655.35;
+ }
+
+ return output + sizeof(double);
+ }
+ else {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i] = wOut[i] / 655.35;
+ }
+
+
+ return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
+ }
+
+}
+
+
+static
+LPBYTE PackDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
+{
+ double* Inks = (double*) output;
+ int nChan = T_CHANNELS(Info -> OutputFormat);
+ int i;
+
+
+ if (T_PLANAR(Info -> OutputFormat)) {
+
+ for (i=0; i < nChan; i++) {
+
+ Inks[i*Info ->StrideOut] = wOut[i] / 65535.0;
+ }
+
+ return output + sizeof(double);
+
+ }
+ else {
+ for (i=0; i < nChan; i++) {
+
+ Inks[i] = wOut[i] / 65535.0;
+ }
+
+ return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
+ }
+
+}
+
+
+// choose routine from Input identifier
+
+_cmsFIXFN _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput)
+{
+ _cmsFIXFN FromInput = NULL;
+
+
+ // Check Named Color
+
+ if (xform) {
+
+ if (xform ->InputProfile) {
+
+ if (cmsGetDeviceClass(xform ->InputProfile) == icSigNamedColorClass) {
+
+ if (dwInput != TYPE_NAMED_COLOR_INDEX) {
+ cmsSignalError(LCMS_ERRC_ABORTED, "Named color needs TYPE_NAMED_COLOR_INDEX");
+ return NULL;
+ }
+ }
+
+ }
+ }
+
+ // Unencoded modes
+
+ if (T_BYTES(dwInput) == 0) {
+
+ switch (T_COLORSPACE(dwInput)) {
+
+ case PT_Lab:
+ FromInput = UnrollLabDouble;
+ break;
+ case PT_XYZ:
+ FromInput = UnrollXYZDouble;
+ break;
+
+ // 0.0 .. 1.0 range
+
+ case PT_GRAY:
+ case PT_RGB:
+ case PT_YCbCr:
+ case PT_YUV:
+ case PT_YUVK:
+ case PT_HSV:
+ case PT_HLS:
+ case PT_Yxy:
+ if (T_CHANNELS(dwInput) == 1)
+ FromInput = UnrollDouble1Chan;
+ else
+ FromInput = UnrollDouble;
+ break;
+
+ // Inks (%) 0.0 .. 100.0
+
+ default:
+ FromInput = UnrollInkDouble;
+ break;
+ }
+
+ }
+ else {
+
+ if (T_PLANAR(dwInput)) {
+
+ switch (T_BYTES(dwInput)) {
+
+ case 1:
+ FromInput = UnrollPlanarBytes;
+ break;
+
+ case 2:
+ if (T_ENDIAN16(dwInput))
+ FromInput = UnrollPlanarWordsBigEndian;
+ else
+ FromInput = UnrollPlanarWords;
+ break;
+
+ default:;
+ }
+ }
+ else {
+
+ switch (T_BYTES(dwInput)) {
+
+ case 1: // 1 byte per channel
+
+ switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput)) {
+
+ case 1: if (T_FLAVOR(dwInput))
+ FromInput = Unroll1ByteReversed;
+ else
+ FromInput = Unroll1Byte;
+ break;
+
+ case 2: if (T_SWAPFIRST(dwInput))
+ FromInput = Unroll2ByteSwapFirst;
+ else
+ FromInput = Unroll2Byte;
+ break;
+
+ case 3: if (T_DOSWAP(dwInput))
+ FromInput = Unroll3BytesSwap;
+ else {
+ if (T_EXTRA(dwInput) == 2)
+ FromInput = Unroll1ByteSkip2;
+ else
+ if (T_COLORSPACE(dwInput) == PT_Lab)
+ FromInput = Unroll3BytesLab;
+ else
+ FromInput = Unroll3Bytes;
+ }
+ break;
+ case 4:
+ // TODO: ALab8 must be fixed to match v2 encoding
+
+ if (T_DOSWAP(dwInput)) {
+ if (T_SWAPFIRST(dwInput))
+
+ FromInput = Unroll4BytesSwapSwapFirst;
+ else
+ FromInput = Unroll4BytesSwap;
+ }
+ else {
+ if (T_SWAPFIRST(dwInput))
+ FromInput = Unroll4BytesSwapFirst;
+ else {
+ if (T_FLAVOR(dwInput))
+ FromInput = Unroll4BytesReverse;
+ else
+ FromInput = Unroll4Bytes;
+ }
+ }
+ break;
+
+
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
+ FromInput = UnrollAnyBytes;
+ break;
+
+
+ default:;
+ }
+ break;
+
+
+ case 2: // 1 word per channel
+
+ switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput))
+ {
+ case 1: if (T_ENDIAN16(dwInput))
+ FromInput = Unroll1WordBigEndian;
+ else
+ if (T_FLAVOR(dwInput))
+ FromInput = Unroll1WordReversed;
+ else
+ FromInput = Unroll1Word;
+ break;
+
+ case 2: if (T_ENDIAN16(dwInput))
+ FromInput = Unroll2WordBigEndian;
+ else {
+ if (T_SWAPFIRST(dwInput))
+ FromInput = Unroll2WordSwapFirst;
+ else
+ FromInput = Unroll2Word;
+ }
+ break;
+
+ case 3: if (T_DOSWAP(dwInput)) {
+ if (T_ENDIAN16(dwInput))
+ FromInput = Unroll3WordsSwapBigEndian;
+ else
+ FromInput = Unroll3WordsSwap;
+ }
+ else {
+ if (T_ENDIAN16(dwInput))
+ FromInput = Unroll3WordsBigEndian;
+ else
+ FromInput = Unroll3Words;
+ }
+ break;
+
+ case 4: if (T_DOSWAP(dwInput)) {
+
+ if (T_ENDIAN16(dwInput))
+ FromInput = Unroll4WordsSwapBigEndian;
+ else {
+
+ if (T_SWAPFIRST(dwInput))
+ FromInput = Unroll4WordsSwapSwapFirst;
+ else
+ FromInput = Unroll4WordsSwap;
+
+ }
+
+ }
+ else {
+
+ if (T_EXTRA(dwInput) == 3)
+ FromInput = Unroll1WordSkip3;
+ else
+
+ if (T_ENDIAN16(dwInput)) {
+
+ if (T_FLAVOR(dwInput))
+ FromInput = Unroll4WordsBigEndianReverse;
+ else
+ FromInput = Unroll4WordsBigEndian;
+ }
+ else {
+ if (T_SWAPFIRST(dwInput))
+ FromInput = Unroll4WordsSwapFirst;
+ else {
+ if (T_FLAVOR(dwInput))
+ FromInput = Unroll4WordsReverse;
+ else
+ FromInput = Unroll4Words;
+ }
+ }
+ }
+ break;
+
+
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
+ FromInput = UnrollAnyWords;
+ break;
+
+ }
+ break;
+
+ default:;
+ }
+ }
+ }
+
+
+ if (!FromInput)
+ cmsSignalError(LCMS_ERRC_ABORTED, "Unknown input format");
+
+ return FromInput;
+}
+
+// choose routine from Input identifier
+
+_cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
+{
+ _cmsFIXFN ToOutput = NULL;
+
+
+ if (T_BYTES(dwOutput) == 0) {
+
+ switch (T_COLORSPACE(dwOutput)) {
+
+ case PT_Lab:
+ ToOutput = PackLabDouble;
+ break;
+ case PT_XYZ:
+ ToOutput = PackXYZDouble;
+ break;
+
+ // 0.0 .. 1.0 range
+ case PT_GRAY:
+ case PT_RGB:
+ case PT_YCbCr:
+ case PT_YUV:
+ case PT_YUVK:
+ case PT_HSV:
+ case PT_HLS:
+ case PT_Yxy:
+ ToOutput = PackDouble;
+ break;
+
+ // Inks (%) 0.0 .. 100.0
+
+ default:
+ ToOutput = PackInkDouble;
+ break;
+ }
+
+ }
+ else
+
+ if (T_PLANAR(dwOutput)) {
+
+ switch (T_BYTES(dwOutput)) {
+
+ case 1: ToOutput = PackPlanarBytes;
+ break;
+
+ case 2:if (!T_ENDIAN16(dwOutput))
+ ToOutput = PackPlanarWords;
+ break;
+
+ default:;
+ }
+ }
+ else {
+
+ switch (T_BYTES(dwOutput)) {
+
+ case 1:
+ switch (T_CHANNELS(dwOutput))
+ {
+ case 1:
+ if (T_DITHER(dwOutput))
+ ToOutput = PackNBytesDither;
+ else
+ ToOutput = Pack1Byte;
+ if (T_EXTRA(dwOutput) == 1) {
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack1ByteAndSkip1SwapFirst;
+ else
+ ToOutput = Pack1ByteAndSkip1;
+ }
+ break;
+
+ case 3:
+ switch (T_EXTRA(dwOutput)) {
+
+ case 0: if (T_DOSWAP(dwOutput))
+ ToOutput = Pack3BytesSwap;
+ else
+ if (T_COLORSPACE(dwOutput) == PT_Lab)
+ ToOutput = Pack3BytesLab;
+ else {
+ if (T_DITHER(dwOutput))
+ ToOutput = PackNBytesDither;
+ else
+ ToOutput = Pack3Bytes;
+ }
+ break;
+
+ case 1: // TODO: ALab8 should be handled here
+
+ if (T_DOSWAP(dwOutput)) {
+
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack3BytesAndSkip1SwapSwapFirst;
+ else
+ ToOutput = Pack3BytesAndSkip1Swap;
+ }
+ else {
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack3BytesAndSkip1SwapFirst;
+ else
+ ToOutput = Pack3BytesAndSkip1;
+ }
+ break;
+
+ default:;
+ }
+ break;
+
+ case 4: if (T_EXTRA(dwOutput) == 0) {
+
+
+ if (T_DOSWAP(dwOutput)) {
+
+
+ if (T_SWAPFIRST(dwOutput)) {
+ ToOutput = Pack4BytesSwapSwapFirst;
+ }
+ else {
+
+ if (T_DITHER(dwOutput)) {
+ ToOutput = PackNBytesSwapDither;
+ }
+ else {
+ ToOutput = Pack4BytesSwap;
+ }
+ }
+ }
+ else {
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack4BytesSwapFirst;
+ else {
+
+ if (T_FLAVOR(dwOutput))
+ ToOutput = Pack4BytesReverse;
+ else {
+ if (T_DITHER(dwOutput))
+ ToOutput = PackNBytesDither;
+ else
+ ToOutput = Pack4Bytes;
+ }
+ }
+ }
+ }
+ else {
+ if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
+ ToOutput = PackNBytes;
+ }
+ break;
+
+ // Hexachrome separations.
+ case 6: if (T_EXTRA(dwOutput) == 0) {
+
+ if( T_DOSWAP(dwOutput))
+ ToOutput = Pack6BytesSwap;
+ else
+ ToOutput = Pack6Bytes;
+ }
+ else {
+ if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
+ ToOutput = PackNBytes;
+
+ }
+ break;
+
+ case 2:
+ case 5:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+
+ if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0))
+ {
+ if (T_DOSWAP(dwOutput))
+ ToOutput = PackNBytesSwap;
+ else {
+
+ if (T_DITHER(dwOutput))
+ ToOutput = PackNBytesDither;
+ else
+ ToOutput = PackNBytes;
+ }
+ }
+ break;
+
+ default:;
+ }
+ break;
+
+
+ case 2:
+
+ switch (T_CHANNELS(dwOutput)) {
+
+ case 1:
+ if (T_ENDIAN16(dwOutput))
+
+ ToOutput = Pack1WordBigEndian;
+ else
+ ToOutput = Pack1Word;
+
+ if (T_EXTRA(dwOutput) == 1) {
+
+ if (T_ENDIAN16(dwOutput))
+
+ ToOutput = Pack1WordAndSkip1BigEndian;
+ else {
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack1WordAndSkip1SwapFirst;
+ else
+ ToOutput = Pack1WordAndSkip1;
+ }
+ }
+ break;
+
+ case 3:
+
+ switch (T_EXTRA(dwOutput)) {
+
+ case 0:
+ if (T_DOSWAP(dwOutput)) {
+
+ if (T_ENDIAN16(dwOutput))
+
+ ToOutput = Pack3WordsSwapBigEndian;
+ else
+ ToOutput = Pack3WordsSwap;
+ }
+ else {
+ if (T_ENDIAN16(dwOutput))
+
+ ToOutput = Pack3WordsBigEndian;
+ else
+ ToOutput = Pack3Words;
+ }
+ break;
+
+ case 1: if (T_DOSWAP(dwOutput)) {
+
+ if (T_ENDIAN16(dwOutput))
+
+ ToOutput = Pack3WordsAndSkip1SwapBigEndian;
+ else {
+ if (T_SWAPFIRST(dwOutput))
+ ToOutput = Pack3WordsAndSkip1SwapSwapFirst;
+ else
+ ToOutput = Pack3WordsAndSkip1Swap;
+ }
+ }
+ else {
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = Pack3WordsAndSkip1BigEndian;
+ else
+ ToOutput = Pack3WordsAndSkip1;
+ }
+ default:;
+ }
+ break;
+
+ case 4: if (T_EXTRA(dwOutput) == 0) {
+
+ if (T_DOSWAP(dwOutput)) {
+
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = Pack4WordsSwapBigEndian;
+ else
+ ToOutput = Pack4WordsSwap;
+ }
+ else {
+
+ if (T_ENDIAN16(dwOutput)) {
+
+ if (T_FLAVOR(dwOutput))
+ ToOutput = Pack4WordsBigEndianReverse;
+ else
+ ToOutput = Pack4WordsBigEndian;
+ }
+ else {
+ if (T_FLAVOR(dwOutput))
+ ToOutput = Pack4WordsReverse;
+ else
+ ToOutput = Pack4Words;
+ }
+ }
+ }
+ else {
+ if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
+ ToOutput = PackNWords;
+ }
+ break;
+
+ case 6: if (T_EXTRA(dwOutput) == 0) {
+
+ if (T_DOSWAP(dwOutput)) {
+
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = Pack6WordsSwapBigEndian;
+ else
+ ToOutput = Pack6WordsSwap;
+ }
+ else {
+
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = Pack6WordsBigEndian;
+ else
+ ToOutput = Pack6Words;
+ }
+ }
+ else {
+ if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
+ ToOutput = PackNWords;
+ }
+ break;
+
+
+ case 2:
+ case 5:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15: if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0)) {
+
+ if (T_DOSWAP(dwOutput)) {
+
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = PackNWordsSwapBigEndian;
+ else
+ ToOutput = PackNWordsSwap;
+ }
+ else {
+
+ if (T_ENDIAN16(dwOutput))
+ ToOutput = PackNWordsBigEndian;
+ else
+ ToOutput = PackNWords;
+ }
+ }
+ break;
+
+ default:;
+ }
+ break;
+
+ default:;
+ }
+ }
+
+ if (!ToOutput)
+ cmsSignalError(LCMS_ERRC_ABORTED, "Unknown output format");
+
+ return ToOutput;
+}
+
+// User formatters for (weird) cases not already included
+
+void LCMSEXPORT cmsSetUserFormatters(cmsHTRANSFORM hTransform, DWORD dwInput, cmsFORMATTER Input,
+ DWORD dwOutput, cmsFORMATTER Output)
+{
+ _LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
+
+ if (Input != NULL) {
+ xform ->FromInput = (_cmsFIXFN) Input;
+ xform ->InputFormat = dwInput;
+ }
+
+ if (Output != NULL) {
+ xform ->ToOutput = (_cmsFIXFN) Output;
+ xform ->OutputFormat = dwOutput;
+ }
+
+}
+
+void LCMSEXPORT cmsGetUserFormatters(cmsHTRANSFORM hTransform,
+ LPDWORD InputFormat, cmsFORMATTER* Input,
+ LPDWORD OutputFormat, cmsFORMATTER* Output)
+{
+ _LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
+
+ if (Input) *Input = (cmsFORMATTER) xform ->FromInput;
+ if (InputFormat) *InputFormat = xform -> InputFormat;
+ if (Output) *Output = (cmsFORMATTER) xform ->ToOutput;
+ if (OutputFormat) *OutputFormat = xform -> OutputFormat;
+}
+
+
+// Change format of yet existing transform. No colorspace checking is performed
+
+void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
+ DWORD dwInputFormat,
+ DWORD dwOutputFormat)
+{
+
+ cmsSetUserFormatters(hTransform,
+ dwInputFormat,
+ (cmsFORMATTER) _cmsIdentifyInputFormat((_LPcmsTRANSFORM) hTransform, dwInputFormat),
+ dwOutputFormat,
+ (cmsFORMATTER) _cmsIdentifyOutputFormat((_LPcmsTRANSFORM) hTransform, dwOutputFormat));
+}