Switch to libcms2-2.6
[openjpeg.git] / thirdparty / liblcms2 / src / cmspack.c
index 196afa942a0b9251d0ebcac4af51448688a04ac7..c84fd822905f656e570981226e5dbbc3aa712d58 100644 (file)
@@ -3,22 +3,22 @@
 //  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 
+// 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 
+// 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 
+// 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 
+// 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)
+// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component
+// as special case)
 
 // ---------------------------------------------------------------------------
 
 #define REVERSE_FLAVOR_16(x)    ((cmsUInt16Number)(0xffff-(x)))
 
 // * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
-cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x) 
+cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
 {
-    int a;
-
-    a = (x << 8 | x) >> 8;  // * 257 / 256
+    int a = (x << 8 | x) >> 8;  // * 257 / 256
     if ( a > 0xffff) return 0xffff;
     return (cmsUInt16Number) a;
 }
 
 // * 0xf00 / 0xffff = * 256 / 257
-cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x) 
+cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
 {
     return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
 }
@@ -61,24 +59,25 @@ cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
 typedef struct {
     cmsUInt32Number Type;
     cmsUInt32Number Mask;
-    cmsFormatter16 Frm;
+    cmsFormatter16  Frm;
 
 } cmsFormatters16;
 
 typedef struct {
     cmsUInt32Number    Type;
     cmsUInt32Number    Mask;
-    cmsFormatterFloat Frm;
+    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 ANYSWAPFIRST    SWAPFIRST_SH(1)
 #define ANYFLAVOR       FLAVOR_SH(1)
 
 
@@ -88,12 +87,13 @@ typedef struct {
 #pragma warning(disable : 4100)
 #endif
 
-// Unpacking routines (16 bits) ---------------------------------------------------------------------------------------- 
+// Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
+
 
 // Does almost everything but is slow
 static
-cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info, 
-                                  register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wIn[],
                                   register cmsUInt8Number* accum,
                                   register cmsUInt32Number Stride)
 {
@@ -102,7 +102,7 @@ cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
     int Reverse    = T_FLAVOR(info ->InputFormat);
     int SwapFirst  = T_SWAPFIRST(info -> InputFormat);
     int Extra      = T_EXTRA(info -> InputFormat);
-    int ExtraFirst = DoSwap && !SwapFirst;
+    int ExtraFirst = DoSwap SwapFirst;
     cmsUInt16Number v;
     int i;
 
@@ -113,10 +113,10 @@ cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
     for (i=0; i < nChan; i++) {
         int index = DoSwap ? (nChan - i - 1) : i;
 
-        v = FROM_8_TO_16(*accum); 
+        v = FROM_8_TO_16(*accum);
         v = Reverse ? REVERSE_FLAVOR_16(v) : v;
         wIn[index] = v;
-        accum++;              
+        accum++;
     }
 
     if (!ExtraFirst) {
@@ -131,29 +131,34 @@ cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
     }
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
+
 }
 
 // Extra channels are just ignored because come in the next planes
 static
-cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info, 
-                                  register cmsUInt16Number wIn[], 
+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 nChan     = T_CHANNELS(info -> InputFormat);
+    int DoSwap    = T_DOSWAP(info ->InputFormat);
+    int SwapFirst = T_SWAPFIRST(info ->InputFormat);
+    int Reverse   = T_FLAVOR(info ->InputFormat);
     int i;
     cmsUInt8Number* Init = accum;
 
-    if (DoSwap) {
+    if (DoSwap ^ SwapFirst) {
         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); 
+        cmsUInt16Number v = FROM_8_TO_16(*accum);
 
         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
         accum += Stride;
@@ -164,8 +169,8 @@ cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
 
 // Special cases, provided for performance
 static
-cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wIn[],
                              register cmsUInt8Number* accum,
                              register cmsUInt32Number Stride)
 {
@@ -175,11 +180,14 @@ cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
     wIn[3] = FROM_8_TO_16(*accum); accum++; // K
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wIn[],
                                     register cmsUInt8Number* accum,
                                     register cmsUInt32Number Stride)
 {
@@ -189,11 +197,14 @@ cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
     wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info, 
-                                      register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
+                                      register cmsUInt16Number wIn[],
                                       register cmsUInt8Number* accum,
                                       register cmsUInt32Number Stride)
 {
@@ -203,12 +214,15 @@ cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
     wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // KYMC
 static
-cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
+                                 register cmsUInt16Number wIn[],
                                  register cmsUInt8Number* accum,
                                  register cmsUInt32Number Stride)
 {
@@ -218,11 +232,14 @@ cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
     wIn[0] = FROM_8_TO_16(*accum); accum++;  // C
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info, 
-                                          register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
+                                          register cmsUInt16Number wIn[],
                                           register cmsUInt8Number* accum,
                                           register cmsUInt32Number Stride)
 {
@@ -232,11 +249,14 @@ cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
     wIn[3] = FROM_8_TO_16(*accum); accum++;  // C
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wIn[],
                              register cmsUInt8Number* accum,
                              register cmsUInt32Number Stride)
 {
@@ -245,11 +265,14 @@ cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
     wIn[2] = FROM_8_TO_16(*accum); accum++;     // B
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info, 
-                                      register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
+                                      register cmsUInt16Number wIn[],
                                       register cmsUInt8Number* accum,
                                       register cmsUInt32Number Stride)
 {
@@ -259,6 +282,26 @@ cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
+}
+
+static
+cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(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
+    accum++; // A
+
+    return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
@@ -273,13 +316,16 @@ cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 // BRG
 static
-cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
+                                 register cmsUInt16Number wIn[],
                                  register cmsUInt8Number* accum,
                                  register cmsUInt32Number Stride)
 {
@@ -288,11 +334,14 @@ cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
     wIn[0] = FROM_8_TO_16(*accum); accum++;     // R
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info, 
-                              register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
+                              register cmsUInt16Number wIn[],
                               register cmsUInt8Number* accum,
                               register cmsUInt32Number Stride)
 {
@@ -301,11 +350,14 @@ cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wIn[],
                                register cmsUInt8Number* accum,
                                register cmsUInt32Number Stride)
 {
@@ -315,11 +367,14 @@ cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wIn[],
                                register cmsUInt8Number* accum,
                                register cmsUInt32Number Stride)
 {
@@ -328,18 +383,25 @@ cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
     wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // b
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // for duplex
 static
-cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
-                             register cmsUInt8Number* accum,
-                             register cmsUInt32Number Stride)
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
@@ -347,52 +409,68 @@ cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
 
 // Monochrome duplicates L into RGB for null-transforms
 static
-cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info, 
-                                     register cmsUInt16Number wIn[], 
-                                     register cmsUInt8Number* accum,
-                                     register cmsUInt32Number Stride)
+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       
+    wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
+
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info, 
-                            register cmsUInt16Number wIn[], 
-                            register cmsUInt8Number* accum,
-                            register cmsUInt32Number Stride)
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wIn[],
                                register cmsUInt8Number* accum,
                                register cmsUInt32Number Stride)
 {
@@ -402,7 +480,7 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
     int Reverse     = T_FLAVOR(info ->InputFormat);
     int SwapFirst   = T_SWAPFIRST(info -> InputFormat);
     int Extra       = T_EXTRA(info -> InputFormat);
-    int ExtraFirst  = DoSwap && !SwapFirst;
+    int ExtraFirst  = DoSwap SwapFirst;
     int i;
 
     if (ExtraFirst) {
@@ -412,14 +490,14 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
     for (i=0; i < nChan; i++) {
 
         int index = DoSwap ? (nChan - i - 1) : i;
-        cmsUInt16Number v = *(cmsUInt16Number*) accum; 
+        cmsUInt16Number v = *(cmsUInt16Number*) accum;
 
         if (SwapEndian)
             v = CHANGE_ENDIAN(v);
 
         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 
-        accum += sizeof(cmsUInt16Number);              
+        accum += sizeof(cmsUInt16Number);
     }
 
     if (!ExtraFirst) {
@@ -435,11 +513,13 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
     }
 
     return accum;
+
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info, 
-                                  register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wIn[],
                                   register cmsUInt8Number* accum,
                                   register cmsUInt32Number Stride)
 {
@@ -457,14 +537,14 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
     for (i=0; i < nChan; i++) {
 
         int index = DoSwap ? (nChan - i - 1) : i;
-        cmsUInt16Number v = *(cmsUInt16Number*) accum; 
+        cmsUInt16Number v = *(cmsUInt16Number*) accum;
 
         if (SwapEndian)
             v = CHANGE_ENDIAN(v);
 
         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 
-        accum +=  Stride * sizeof(cmsUInt16Number);           
+        accum +=  Stride * sizeof(cmsUInt16Number);
     }
 
     return (Init + sizeof(cmsUInt16Number));
@@ -472,8 +552,8 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
 
 
 static
-cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wIn[],
                              register cmsUInt8Number* accum,
                              register cmsUInt32Number Stride)
 {
@@ -483,11 +563,14 @@ cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wIn[],
                                     register cmsUInt8Number* accum,
                                     register cmsUInt32Number Stride)
 {
@@ -497,11 +580,14 @@ cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
     wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info, 
-                                      register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
+                                      register cmsUInt16Number wIn[],
                                       register cmsUInt8Number* accum,
                                       register cmsUInt32Number Stride)
 {
@@ -511,12 +597,15 @@ cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // KYMC
 static
-cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
+                                 register cmsUInt16Number wIn[],
                                  register cmsUInt8Number* accum,
                                  register cmsUInt32Number Stride)
 {
@@ -526,11 +615,14 @@ cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info, 
-                                          register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
+                                          register cmsUInt16Number wIn[],
                                           register cmsUInt8Number* accum,
                                           register cmsUInt32Number Stride)
 {
@@ -540,35 +632,46 @@ cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info, 
-                                      register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
+                                      register cmsUInt16Number wIn[],
                                       register cmsUInt8Number* accum,
                                       register cmsUInt32Number Stride)
 {
@@ -578,11 +681,14 @@ cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
     wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info, 
-                                           register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
+                                           register cmsUInt16Number wIn[],
                                            register cmsUInt8Number* accum,
                                            register cmsUInt32Number Stride)
 {
@@ -592,60 +698,78 @@ cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
     wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
 
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info, 
-                            register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info, 
-                                 register cmsUInt16Number wIn[], 
+cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
+                                 register cmsUInt16Number wIn[],
                                  register cmsUInt8Number* accum,
                                  register cmsUInt32Number Stride)
 {
-    wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; 
+    wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
 
     accum += 8;
+
     return accum;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wIn[], 
-                             register cmsUInt8Number* accum,
-                             register cmsUInt32Number Stride)
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 // This is a conversion of Lab double to 16 bits
 static
-cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wIn[],
                                     register cmsUInt8Number* accum,
                                     register cmsUInt32Number  Stride)
-{       
+{
     if (T_PLANAR(info -> InputFormat)) {
 
         cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
@@ -667,13 +791,47 @@ cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
     }
 }
 
+
+// This is a conversion of Lab float to 16 bits
+static
+cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wIn[],
+                                    register cmsUInt8Number* accum,
+                                    register cmsUInt32Number  Stride)
+{
+    cmsCIELab Lab;
+    
+    if (T_PLANAR(info -> InputFormat)) {
+
+        cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+
+     
+        Lab.L = Pt[0];
+        Lab.a = Pt[Stride];
+        Lab.b = Pt[Stride*2];
+
+        cmsFloat2LabEncoded(wIn, &Lab);
+        return accum + sizeof(cmsFloat32Number);
+    }
+    else {
+        Lab.L = ((cmsFloat32Number*) accum)[0];
+        Lab.a = ((cmsFloat32Number*) accum)[1];
+        Lab.b = ((cmsFloat32Number*) accum)[2];
+
+        cmsFloat2LabEncoded(wIn, &Lab);
+        accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+        return accum;
+    }
+}
+
 // This is a conversion of XYZ double to 16 bits
 static
-cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wIn[], 
+cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wIn[],
                                     register cmsUInt8Number* accum,
                                     register cmsUInt32Number Stride)
-{   
+{
     if (T_PLANAR(info -> InputFormat)) {
 
         cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
@@ -696,23 +854,59 @@ cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
     }
 }
 
+// This is a conversion of XYZ float to 16 bits
+static
+cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
+                                   register cmsUInt16Number wIn[],
+                                   register cmsUInt8Number* accum,
+                                   register cmsUInt32Number Stride)
+{
+    if (T_PLANAR(info -> InputFormat)) {
+
+        cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+        cmsCIEXYZ XYZ;
+
+        XYZ.X = Pt[0];
+        XYZ.Y = Pt[Stride];
+        XYZ.Z = Pt[Stride*2];
+        cmsFloat2XYZEncoded(wIn, &XYZ);
+
+        return accum + sizeof(cmsFloat32Number);
+
+    }
+
+    else {
+        cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+        cmsCIEXYZ XYZ;
+
+        XYZ.X = Pt[0];
+        XYZ.Y = Pt[1];
+        XYZ.Z = Pt[2];
+        cmsFloat2XYZEncoded(wIn, &XYZ);
+
+        accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
+
+        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_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_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;
@@ -721,70 +915,122 @@ cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
 
 // 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)
+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;
+
+    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;
+    int Planar     = T_PLANAR(info -> InputFormat);
     cmsFloat64Number v;
-    cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+    cmsUInt16Number  vi;
+    int i, start = 0;
+   cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+
+    if (ExtraFirst)
+            start = Extra;
 
     for (i=0; i < nChan; i++) {
 
-        if (Planar)
+        int index = DoSwap ? (nChan - i - 1) : i;
 
-            v = Inks[i * Stride];
+        if (Planar)
+            v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
         else
-            v = Inks[i];
+            v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
+
+        vi = _cmsQuickSaturateWord(v * maximum);
+
+        if (Reverse)
+            vi = REVERSE_FLAVOR_16(vi);
 
-        wIn[i] = _cmsQuickSaturateWord(v * maximum);
+        wIn[index] = vi;
+    }
+
+
+    if (Extra == 0 && SwapFirst) {
+        cmsUInt16Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+        wIn[nChan-1] = tmp;
     }
 
     if (T_PLANAR(info -> InputFormat))
         return accum + sizeof(cmsFloat64Number);
     else
-        return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+        return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
 }
 
+
+
 static
-cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info, 
-                                register cmsUInt16Number wIn[], 
+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;
+
+    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;
+    int Planar     = T_PLANAR(info -> InputFormat);
     cmsFloat32Number v;
-    cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+    cmsUInt16Number  vi;
+    int i, start = 0;
+   cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+
+    if (ExtraFirst)
+            start = Extra;
 
     for (i=0; i < nChan; i++) {
 
-        if (Planar)
+        int index = DoSwap ? (nChan - i - 1) : i;
 
-            v = Inks[i * Stride];
+        if (Planar)
+            v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
         else
-            v = Inks[i];
+            v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
+
+        vi = _cmsQuickSaturateWord(v * maximum);
+
+        if (Reverse)
+            vi = REVERSE_FLAVOR_16(vi);
+
+        wIn[index] = vi;
+    }
+
 
-        wIn[i] = _cmsQuickSaturateWord(v * maximum);
+    if (Extra == 0 && SwapFirst) {
+        cmsUInt16Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+        wIn[nChan-1] = tmp;
     }
 
     if (T_PLANAR(info -> InputFormat))
         return accum + sizeof(cmsFloat32Number);
     else
-        return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+        return accum + (nChan + Extra) * 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[], 
+cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wIn[],
                                   register cmsUInt8Number* accum,
                                   register cmsUInt32Number Stride)
 {
@@ -792,81 +1038,131 @@ cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
 
     wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
 
-    return accum + sizeof(cmsFloat64Number);    
+    return accum + sizeof(cmsFloat64Number);
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 //-------------------------------------------------------------------------------------------------------------------
 
-// True float transformation. 
-
-// For anything going from cmsFloat32Number 
+// For anything going from cmsFloat32Number
 static
-cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info, 
-                                    cmsFloat32Number wIn[], 
+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;
 
+    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;
+    int Planar     = T_PLANAR(info -> InputFormat);
+    cmsFloat32Number v;
+    int i, start = 0;
+    cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
+
+
+    if (ExtraFirst)
+            start = Extra;
+
+    for (i=0; i < nChan; i++) {
 
-    for (i=0; i <  nChan; i++) {
+        int index = DoSwap ? (nChan - i - 1) : i;
 
         if (Planar)
-            wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+            v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
         else
-            wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);                            
+            v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
+
+        v /= maximum;
+
+        wIn[index] = Reverse ? 1 - v : v;
+    }
+
+
+    if (Extra == 0 && SwapFirst) {
+        cmsFloat32Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+        wIn[nChan-1] = tmp;
     }
 
     if (T_PLANAR(info -> InputFormat))
         return accum + sizeof(cmsFloat32Number);
     else
-        return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+        return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
 }
 
 // For anything going from double
+
 static
-cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info, 
-                                     cmsFloat32Number wIn[], 
-                                     cmsUInt8Number* accum,
-                                     cmsUInt32Number Stride)
+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;
+
+    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;
+    int Planar     = T_PLANAR(info -> InputFormat);
+    cmsFloat64Number v;
+    int i, start = 0;
     cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
 
-    for (i=0; i <  nChan; i++) {
+
+    if (ExtraFirst)
+            start = Extra;
+
+    for (i=0; i < nChan; i++) {
+
+        int index = DoSwap ? (nChan - i - 1) : i;
 
         if (Planar)
-            wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+            v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start)  * Stride];
         else
-            wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);                            
+            v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
+
+        v /= maximum;
+
+        wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
+    }
+
+
+    if (Extra == 0 && SwapFirst) {
+        cmsFloat32Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+        wIn[nChan-1] = tmp;
     }
 
     if (T_PLANAR(info -> InputFormat))
         return accum + sizeof(cmsFloat64Number);
     else
-        return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+        return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
 }
 
 
+
 // From Lab double to cmsFloat32Number
 static
-cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,  
-                                       cmsFloat32Number wIn[], 
+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[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);
 
@@ -874,7 +1170,7 @@ cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
     }
     else {
 
-        wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0);             // from 0..100 to 0..1 
+        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);
 
@@ -885,16 +1181,16 @@ cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
 
 // From Lab double to cmsFloat32Number
 static
-cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info, 
-                                      cmsFloat32Number wIn[], 
+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[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);
 
@@ -902,7 +1198,7 @@ cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
     }
     else {
 
-        wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0);             // from 0..100 to 0..1 
+        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);
 
@@ -912,27 +1208,28 @@ cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
 }
 
 
+
 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
 static
-cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,  
-                                       cmsFloat32Number wIn[], 
+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[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[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));
@@ -941,25 +1238,25 @@ cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
 }
 
 static
-cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,  
-                                      cmsFloat32Number wIn[], 
+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[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[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));
@@ -967,14 +1264,16 @@ cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
     }
 }
 
+
+
 // Packing routines -----------------------------------------------------------------------------------------------------------
 
 
 // Generic chunky for byte
 
 static
-cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wOut[],
                              register cmsUInt8Number* output,
                              register cmsUInt32Number Stride)
 {
@@ -983,7 +1282,7 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
     int Reverse    = T_FLAVOR(info ->OutputFormat);
     int Extra      = T_EXTRA(info -> OutputFormat);
     int SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
-    int ExtraFirst = DoSwap && !SwapFirst;
+    int ExtraFirst = DoSwap SwapFirst;
     cmsUInt8Number* swap1;
     cmsUInt8Number v = 0;
     int i;
@@ -1018,13 +1317,15 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
 
 
     return output;
+
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 
 static
-cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wOut[],
                              register cmsUInt8Number* output,
                              register cmsUInt32Number Stride)
 {
@@ -1034,7 +1335,7 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
     int Reverse    = T_FLAVOR(info ->OutputFormat);
     int Extra      = T_EXTRA(info -> OutputFormat);
     int SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
-    int ExtraFirst = DoSwap && !SwapFirst;
+    int ExtraFirst = DoSwap SwapFirst;
     cmsUInt16Number* swap1;
     cmsUInt16Number v = 0;
     int i;
@@ -1074,21 +1375,30 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
 
 
     return output;
+
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info, 
-                                register cmsUInt16Number wOut[], 
+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 nChan     = T_CHANNELS(info -> OutputFormat);
+    int DoSwap    = T_DOSWAP(info ->OutputFormat);
+    int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
+    int Reverse   = T_FLAVOR(info ->OutputFormat);
     int i;
     cmsUInt8Number* Init = output;
 
+
+    if (DoSwap ^ SwapFirst) {
+        output += T_EXTRA(info -> OutputFormat) * Stride;
+    }
+
+
     for (i=0; i < nChan; i++) {
 
         int index = DoSwap ? (nChan - i - 1) : i;
@@ -1099,12 +1409,14 @@ cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
     }
 
     return (Init + 1);
+
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info, 
-                                register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
+                                register cmsUInt16Number wOut[],
                                 register cmsUInt8Number* output,
                                 register cmsUInt32Number Stride)
 {
@@ -1129,7 +1441,7 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
         if (SwapEndian)
             v = CHANGE_ENDIAN(v);
 
-        if (Reverse) 
+        if (Reverse)
             v =  REVERSE_FLAVOR_16(v);
 
         *(cmsUInt16Number*) output = v;
@@ -1142,8 +1454,8 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
 // CMYKcm (unrolled for speed)
 
 static
-cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1155,13 +1467,16 @@ cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[5]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // KCMYcm
 
 static
-cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1173,12 +1488,15 @@ cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[0]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // CMYKcm
 static
-cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1196,12 +1514,15 @@ cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // KCMYcm
 static
-cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1219,12 +1540,15 @@ cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1234,11 +1558,14 @@ cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[3]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info, 
-                                  register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wOut[],
                                   register cmsUInt8Number* output,
                                   register cmsUInt32Number Stride)
 {
@@ -1248,12 +1575,15 @@ cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
                                     register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
@@ -1263,12 +1593,15 @@ cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[2]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // ABGR
 static
-cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1278,11 +1611,14 @@ cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[0]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info, 
-                                        register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
+                                        register cmsUInt16Number wOut[],
                                         register cmsUInt8Number* output,
                                         register cmsUInt32Number Stride)
 {
@@ -1292,11 +1628,14 @@ cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[3]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1310,11 +1649,14 @@ cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info, 
-                                  register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wOut[],
                                   register cmsUInt8Number* output,
                                   register cmsUInt32Number Stride)
 {
@@ -1328,12 +1670,15 @@ cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // ABGR
 static
-cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1347,12 +1692,15 @@ cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 // CMYK
 static
-cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
                                     register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
@@ -1366,12 +1714,15 @@ cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info, 
-                            register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
+                            register cmsUInt16Number wOut[],
                             register cmsUInt8Number* output,
                             register cmsUInt32Number Stride)
 {
@@ -1380,11 +1731,14 @@ cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wOut[],
                              register cmsUInt8Number* output,
                              register cmsUInt32Number Stride)
 {
@@ -1394,11 +1748,14 @@ cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info, 
-                             register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
+                             register cmsUInt16Number wOut[],
                              register cmsUInt8Number* output,
                              register cmsUInt32Number Stride)
 {
@@ -1410,11 +1767,14 @@ cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
     output += 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1423,11 +1783,14 @@ cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[2]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
                                     register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
@@ -1436,11 +1799,14 @@ cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
     *output++ = (wOut[2] & 0xFF);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1449,11 +1815,14 @@ cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
     *output++ = FROM_16_TO_8(wOut[0]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info, 
-                                        register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
+                                        register cmsUInt16Number wOut[],
                                         register cmsUInt8Number* output,
                                         register cmsUInt32Number Stride)
 {
@@ -1462,12 +1831,15 @@ cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
     *output++ = (wOut[0] & 0xFF);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info, 
-                           register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
+                           register cmsUInt16Number wOut[],
                            register cmsUInt8Number* output,
                            register cmsUInt32Number Stride)
 {
@@ -1479,11 +1851,14 @@ cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1495,11 +1870,14 @@ cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info, 
-                                    register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
                                     register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
@@ -1511,11 +1889,14 @@ cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* Info, 
-                                   register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
+                                   register cmsUInt16Number wOut[],
                                    register cmsUInt8Number* output,
                                    register cmsUInt32Number Stride)
 {
@@ -1525,11 +1906,14 @@ cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* Info,
     output++;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* Info, 
-                                            register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
+                                            register cmsUInt16Number wOut[],
                                             register cmsUInt8Number* output,
                                             register cmsUInt32Number Stride)
 {
@@ -1539,12 +1923,15 @@ cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* Info,
     output++;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* Info, 
-                                            register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
+                                            register cmsUInt16Number wOut[],
                                             register cmsUInt8Number* output,
                                             register cmsUInt32Number Stride)
 {
@@ -1554,11 +1941,14 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
     *output++ = FROM_16_TO_8(wOut[2]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* Info, 
-                                                     register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
+                                                     register cmsUInt16Number wOut[],
                                                      register cmsUInt8Number* output,
                                                      register cmsUInt32Number Stride)
 {
@@ -1568,11 +1958,14 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* Inf
     *output++ = (wOut[2] & 0xFF);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* Info, 
-                                       register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
+                                       register cmsUInt16Number wOut[],
                                        register cmsUInt8Number* output,
                                        register cmsUInt32Number Stride)
 {
@@ -1582,11 +1975,14 @@ cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* Info,
     *output++ = FROM_16_TO_8(wOut[0]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* Info, 
-                                                register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
+                                                register cmsUInt16Number wOut[],
                                                 register cmsUInt8Number* output,
                                                 register cmsUInt32Number Stride)
 {
@@ -1596,40 +1992,49 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* Info,
     *output++ = (wOut[0] & 0xFF);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info, 
-                                                register cmsUInt16Number wOut[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* Info, 
-                                                         register cmsUInt16Number wOut[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* Info, 
-                                   register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
+                                   register cmsUInt16Number wOut[],
                                    register cmsUInt8Number* output,
                                    register cmsUInt32Number Stride)
 {
@@ -1642,11 +2047,14 @@ cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* Info, 
-                                       register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
+                                       register cmsUInt16Number wOut[],
                                        register cmsUInt8Number* output,
                                        register cmsUInt32Number Stride)
 {
@@ -1659,15 +2067,18 @@ cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* Info, 
-                                            register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
+                                            register cmsUInt16Number wOut[],
                                             register cmsUInt8Number* output,
                                             register cmsUInt32Number Stride)
-{   
+{
     output+= 2;
     *(cmsUInt16Number*) output = wOut[0];
     output+= 2;
@@ -1677,15 +2088,18 @@ cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info, 
-                                                register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
+                                                register cmsUInt16Number wOut[],
                                                 register cmsUInt8Number* output,
                                                 register cmsUInt32Number Stride)
-{      
+{
     *(cmsUInt16Number*) output = wOut[2];
     output+= 2;
     *(cmsUInt16Number*) output = wOut[1];
@@ -1695,47 +2109,62 @@ cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 
 static
-cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* Info, 
-                          register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
+                          register cmsUInt16Number wOut[],
                           register cmsUInt8Number* output,
                           register cmsUInt32Number Stride)
 {
     *output++ = FROM_16_TO_8(wOut[0]);
+
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* Info, 
-                                  register cmsUInt16Number wOut[], 
+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;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* Info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
     *output++ = FROM_16_TO_8(wOut[0]);
     output++;
+
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* Info, 
-                                        register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
+                                        register cmsUInt16Number wOut[],
                                         register cmsUInt8Number* output,
                                         register cmsUInt32Number Stride)
 {
@@ -1743,11 +2172,14 @@ cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* Info,
     *output++ = FROM_16_TO_8(wOut[0]);
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* Info, 
-                          register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
+                          register cmsUInt16Number wOut[],
                           register cmsUInt8Number* output,
                           register cmsUInt32Number Stride)
 {
@@ -1755,12 +2187,15 @@ cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* Info, 
-                                  register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
+                                  register cmsUInt16Number wOut[],
                                   register cmsUInt8Number* output,
                                   register cmsUInt32Number Stride)
 {
@@ -1768,11 +2203,14 @@ cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* Info, 
-                                   register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
+                                   register cmsUInt16Number wOut[],
                                    register cmsUInt8Number* output,
                                    register cmsUInt32Number Stride)
 {
@@ -1780,12 +2218,15 @@ cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* Info,
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 static
-cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* Info, 
-                               register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
+                               register cmsUInt16Number wOut[],
                                register cmsUInt8Number* output,
                                register cmsUInt32Number Stride)
 {
@@ -1793,31 +2234,37 @@ cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* Info,
     output+= 4;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 static
-cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* Info, 
-                                        register cmsUInt16Number wOut[], 
+cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
+                                        register cmsUInt16Number wOut[],
                                         register cmsUInt8Number* output,
                                         register cmsUInt32Number Stride)
 {
-    output += 2; 
+    output += 2;
     *(cmsUInt16Number*) output = wOut[0];
     output+= 2;
 
     return output;
+
+    cmsUNUSED_PARAMETER(info);
+    cmsUNUSED_PARAMETER(Stride);
 }
 
 
 // Unencoded Float values -- don't try optimize speed
 static
-cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* Info, 
-                                    register cmsUInt16Number wOut[], 
-                                    register cmsUInt8Number* output, 
+cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
+                                    register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
 
-    if (T_PLANAR(Info -> OutputFormat)) {
+    if (T_PLANAR(info -> OutputFormat)) {
 
         cmsCIELab  Lab;
         cmsFloat64Number* Out = (cmsFloat64Number*) output;
@@ -1832,14 +2279,43 @@ cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* Info,
     else {
 
         cmsLabEncoded2Float((cmsCIELab*) output, wOut);
-        return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));            
+        return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
     }
+}
 
+
+static
+cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
+                                    register cmsUInt16Number wOut[],
+                                    register cmsUInt8Number* output,
+                                    register cmsUInt32Number Stride)
+{
+    cmsCIELab  Lab;
+    cmsLabEncoded2Float(&Lab, wOut);
+
+    if (T_PLANAR(info -> OutputFormat)) {
+       
+        cmsFloat32Number* Out = (cmsFloat32Number*) output;
+    
+        Out[0]        = (cmsFloat32Number)Lab.L;
+        Out[Stride]   = (cmsFloat32Number)Lab.a;
+        Out[Stride*2] = (cmsFloat32Number)Lab.b;
+
+        return output + sizeof(cmsFloat32Number);
+    }
+    else {
+
+       ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
+       ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
+       ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
+
+        return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
+    }
 }
 
 static
-cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info, 
-                                    register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
+                                    register cmsUInt16Number wOut[],
                                     register cmsUInt8Number* output,
                                     register cmsUInt32Number Stride)
 {
@@ -1849,7 +2325,7 @@ cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
         cmsFloat64Number* Out = (cmsFloat64Number*) output;
         cmsXYZEncoded2Float(&XYZ, wOut);
 
-        Out[0]                  = XYZ.X;
+        Out[0]        = XYZ.X;
         Out[Stride]   = XYZ.Y;
         Out[Stride*2] = XYZ.Z;
 
@@ -1865,142 +2341,168 @@ cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
 }
 
 static
-cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* Info, 
-                                 register cmsUInt16Number wOut[], 
-                                 register cmsUInt8Number* output,
-                                 register cmsUInt32Number Stride)
+cmsUInt8Number* PackXYZFloatFrom16(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++) {
+        cmsCIEXYZ XYZ;
+        cmsFloat32Number* Out = (cmsFloat32Number*) output;
+        cmsXYZEncoded2Float(&XYZ, wOut);
 
-            Inks[i*Stride] = wOut[i] / maximum;
-        }
+        Out[0]        = (cmsFloat32Number) XYZ.X;
+        Out[Stride]   = (cmsFloat32Number) XYZ.Y;
+        Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
 
-        return output + sizeof(cmsFloat64Number);
-    } 
-    else {
+        return output + sizeof(cmsFloat32Number);
 
-        for (i=0; i <  nChan; i++) {
+    }
+    else {
 
-            Inks[i] = wOut[i] /  maximum;
-        }
+        cmsCIEXYZ XYZ;
+        cmsFloat32Number* Out = (cmsFloat32Number*) output;
+        cmsXYZEncoded2Float(&XYZ, wOut);
 
+        Out[0] = (cmsFloat32Number) XYZ.X;
+        Out[1] = (cmsFloat32Number) XYZ.Y;
+        Out[2] = (cmsFloat32Number) XYZ.Z;
 
-        return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat64Number);
+        return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
     }
-
 }
 
 static
-cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* Info, 
-                                register cmsUInt16Number wOut[], 
+cmsUInt8Number* PackDoubleFrom16(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;
+    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 Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
+    cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
+    cmsFloat64Number v = 0;
+    cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
+    int i, start = 0;
 
-    if (T_PLANAR(Info -> OutputFormat)) {
+    if (ExtraFirst)
+        start = Extra;
 
-        for (i=0; i <  nChan; i++) {
+    for (i=0; i < nChan; i++) {
 
-            Inks[i*Stride] = (cmsFloat32Number) (wOut[i] / maximum);
-        }
+        int index = DoSwap ? (nChan - i - 1) : i;
 
-        return output + sizeof(cmsFloat32Number);
-    } 
-    else {
+        v = (cmsFloat64Number) wOut[index] / maximum;
 
-        for (i=0; i <  nChan; i++) {
+        if (Reverse)
+            v = maximum - v;
 
-            Inks[i] = (cmsFloat32Number) (wOut[i] /  maximum);
-        }
+        if (Planar)
+            ((cmsFloat64Number*) output)[(i + start)  * Stride]= v;
+        else
+            ((cmsFloat64Number*) output)[i + start] = v;
+    }
 
+    if (!ExtraFirst) {
+        output += Extra * sizeof(cmsFloat64Number);
+    }
+
+    if (Extra == 0 && SwapFirst) {
 
-        return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat32Number);
+         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
+        *swap1 = v;
     }
 
-}
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsFloat64Number);
+    else
+        return output + nChan * sizeof(cmsFloat64Number);
 
+}
 
-// --------------------------------------------------------------------------------------------------------
 
 static
-cmsUInt8Number* PackChunkyFloatsFromFloat(_cmsTRANSFORM* info, 
-                                          cmsFloat32Number wOut[], 
-                                          cmsUInt8Number* output,
-                                          cmsUInt32Number Stride)
+cmsUInt8Number* PackFloatFrom16(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;
-    cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
-    cmsFloat32Number* swap1;
+    int Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
+    cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
     cmsFloat64Number v = 0;
-    int i;
+    cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
+    int i, start = 0;
 
-    swap1 = (cmsFloat32Number*) output;
-
-    if (ExtraFirst) {
-        output += Extra * sizeof(cmsFloat32Number);
-    }
+    if (ExtraFirst)
+        start = Extra;
 
     for (i=0; i < nChan; i++) {
 
         int index = DoSwap ? (nChan - i - 1) : i;
 
-        v = wOut[index] * maximum;
+        v = (cmsFloat64Number) wOut[index] / maximum;
 
         if (Reverse)
             v = maximum - v;
 
-        *(cmsFloat32Number*) output = (cmsFloat32Number) v;
-
-        output += sizeof(cmsFloat32Number);
+        if (Planar)
+            ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
+        else
+            ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
     }
 
     if (!ExtraFirst) {
         output += Extra * sizeof(cmsFloat32Number);
     }
 
-    if (Extra == 0 && SwapFirst) {
+  if (Extra == 0 && SwapFirst) {
 
-        memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
+         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
         *swap1 = (cmsFloat32Number) v;
     }
 
-
-    return output;
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsFloat32Number);
+    else
+        return output + nChan * sizeof(cmsFloat32Number);
 }
 
+
+
+// --------------------------------------------------------------------------------------------------------
+
 static
-cmsUInt8Number* PackPlanarFloatsFromFloat(_cmsTRANSFORM* info, 
-                                          cmsFloat32Number wOut[], 
-                                          cmsUInt8Number* output,
-                                          cmsUInt32Number Stride)
+cmsUInt8Number* PackFloatsFromFloat(_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;
+    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 Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
     cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
-    cmsFloat64Number v;
+    cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
+    cmsFloat64Number v = 0;
+    int i, start = 0;
 
-    if (DoSwap) {
-        output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat32Number);
-    }
+    if (ExtraFirst)
+        start = Extra;
 
     for (i=0; i < nChan; i++) {
 
@@ -2008,111 +2510,95 @@ cmsUInt8Number* PackPlanarFloatsFromFloat(_cmsTRANSFORM* info,
 
         v = wOut[index] * maximum;
 
-        if (Reverse) 
-            v =  maximum - v;
+        if (Reverse)
+            v = maximum - v;
 
-        *(cmsFloat32Number*) output = (cmsFloat32Number) v;
-        output += (Stride * sizeof(cmsFloat32Number));
+        if (Planar)
+            ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
+        else
+            ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
     }
 
-    return (Init + sizeof(cmsFloat32Number));
-}
+    if (!ExtraFirst) {
+        output += Extra * sizeof(cmsFloat32Number);
+    }
+
+   if (Extra == 0 && SwapFirst) {
 
+         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
+        *swap1 = (cmsFloat32Number) v;
+    }
+
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsFloat32Number);
+    else
+        return output + nChan * sizeof(cmsFloat32Number);
+}
 
 static
-cmsUInt8Number* PackChunkyDoublesFromFloat(_cmsTRANSFORM* info, 
-                                           cmsFloat32Number wOut[], 
-                                           cmsUInt8Number* output,
-                                           cmsUInt32Number Stride)
+cmsUInt8Number* PackDoublesFromFloat(_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;
+    int Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
     cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
     cmsFloat64Number v = 0;
-    int i;
+    cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
+    int i, start = 0;
 
-    swap1 = (cmsFloat64Number*) output;
-
-    if (ExtraFirst) {
-        output += Extra * sizeof(cmsFloat64Number);
-    }
+    if (ExtraFirst)
+        start = Extra;
 
     for (i=0; i < nChan; i++) {
 
         int index = DoSwap ? (nChan - i - 1) : i;
 
-        v = (cmsFloat64Number) wOut[index] * maximum;
+        v = wOut[index] * maximum;
 
         if (Reverse)
             v = maximum - v;
 
-        *(cmsFloat64Number*) output = v;
-
-        output += sizeof(cmsFloat64Number);
+        if (Planar)
+            ((cmsFloat64Number*) output)[(i + start) * Stride] =  v;
+        else
+            ((cmsFloat64Number*) output)[i + start] =  v;
     }
 
     if (!ExtraFirst) {
         output += Extra * sizeof(cmsFloat64Number);
     }
 
-    if (Extra == 0 && SwapFirst) {
+   if (Extra == 0 && SwapFirst) {
 
-        memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
+         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));
-    }
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsFloat64Number);
+    else
+        return output + nChan * sizeof(cmsFloat64Number);
 
-    return (Init + sizeof(cmsFloat64Number));
 }
 
 
 
 
+
 static
-cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info, 
-                                      cmsFloat32Number wOut[], 
+cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
+                                      cmsFloat32Number wOut[],
                                       cmsUInt8Number* output,
                                       cmsUInt32Number Stride)
-{        
+{
     cmsFloat32Number* Out = (cmsFloat32Number*) output;
 
     if (T_PLANAR(Info -> OutputFormat)) {
@@ -2129,17 +2615,18 @@ cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
         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));            
+        return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
     }
 
 }
 
+
 static
-cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info, 
-                                       cmsFloat32Number wOut[], 
+cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
+                                       cmsFloat32Number wOut[],
                                        cmsUInt8Number* output,
                                        cmsUInt32Number Stride)
-{        
+{
     cmsFloat64Number* Out = (cmsFloat64Number*) output;
 
     if (T_PLANAR(Info -> OutputFormat)) {
@@ -2156,7 +2643,7 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
         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));            
+        return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
     }
 
 }
@@ -2164,11 +2651,11 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
 
 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
 static
-cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info, 
-                                      cmsFloat32Number wOut[], 
+cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
+                                      cmsFloat32Number wOut[],
                                       cmsUInt8Number* output,
                                       cmsUInt32Number Stride)
-{        
+{
     cmsFloat32Number* Out = (cmsFloat32Number*) output;
 
     if (T_PLANAR(Info -> OutputFormat)) {
@@ -2185,19 +2672,18 @@ cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
         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));            
+        return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
     }
 
 }
 
-
 // Same, but convert to double
 static
-cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info, 
-                                       cmsFloat32Number wOut[], 
+cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
+                                       cmsFloat32Number wOut[],
                                        cmsUInt8Number* output,
                                        cmsUInt32Number Stride)
-{        
+{
     cmsFloat64Number* Out = (cmsFloat64Number*) output;
 
     if (T_PLANAR(Info -> OutputFormat)) {
@@ -2214,11 +2700,228 @@ cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
         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));            
+        return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+    }
+
+}
+
+
+// ----------------------------------------------------------------------------------------------------------------
+
+#ifndef CMS_NO_HALF_SUPPORT 
+
+// Decodes an stream of half floats to wIn[] described by input format
+
+static
+cmsUInt8Number* UnrollHalfTo16(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;
+    int Planar     = T_PLANAR(info -> InputFormat);
+    cmsFloat32Number v;
+    int i, start = 0;
+    cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
+
+
+    if (ExtraFirst)
+            start = Extra;
+
+    for (i=0; i < nChan; i++) {
+
+        int index = DoSwap ? (nChan - i - 1) : i;
+
+        if (Planar)
+            v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
+        else
+            v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
+
+        if (Reverse) v = maximum - v;
+
+        wIn[index] = _cmsQuickSaturateWord(v * maximum);
     }
 
+
+    if (Extra == 0 && SwapFirst) {
+        cmsUInt16Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+        wIn[nChan-1] = tmp;
+    }
+
+    if (T_PLANAR(info -> InputFormat))
+        return accum + sizeof(cmsUInt16Number);
+    else
+        return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
 }
 
+// Decodes an stream of half floats to wIn[] described by input format
+
+static
+cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
+                                    cmsFloat32Number wIn[],
+                                    cmsUInt8Number* accum,
+                                    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;
+    int Planar     = T_PLANAR(info -> InputFormat);
+    cmsFloat32Number v;
+    int i, start = 0;
+    cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
+
+
+    if (ExtraFirst)
+            start = Extra;
+
+    for (i=0; i < nChan; i++) {
+
+        int index = DoSwap ? (nChan - i - 1) : i;
+
+        if (Planar)
+            v =  _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
+        else
+            v =  _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
+
+        v /= maximum;
+
+        wIn[index] = Reverse ? 1 - v : v;
+    }
+
+
+    if (Extra == 0 && SwapFirst) {
+        cmsFloat32Number tmp = wIn[0];
+
+        memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+        wIn[nChan-1] = tmp;
+    }
+
+    if (T_PLANAR(info -> InputFormat))
+        return accum + sizeof(cmsUInt16Number);
+    else
+        return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
+}
+
+
+static
+cmsUInt8Number* PackHalfFrom16(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 Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
+    cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
+    cmsFloat32Number v = 0;
+    cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
+    int i, start = 0;
+
+    if (ExtraFirst)
+        start = Extra;
+
+    for (i=0; i < nChan; i++) {
+
+        int index = DoSwap ? (nChan - i - 1) : i;
+
+        v = (cmsFloat32Number) wOut[index] / maximum;
+
+        if (Reverse)
+            v = maximum - v;
+
+        if (Planar)
+            ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
+        else
+            ((cmsUInt16Number*) output)[i + start] =  _cmsFloat2Half(v);
+    }
+
+    if (!ExtraFirst) {
+        output += Extra * sizeof(cmsUInt16Number);
+    }
+
+  if (Extra == 0 && SwapFirst) {
+
+         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
+        *swap1 = _cmsFloat2Half(v);
+    }
+
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsUInt16Number);
+    else
+        return output + nChan * sizeof(cmsUInt16Number);
+}
+
+
+
+static
+cmsUInt8Number* PackHalfFromFloat(_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 Planar     = T_PLANAR(info -> OutputFormat);
+    int ExtraFirst = DoSwap ^ SwapFirst;
+    cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
+    cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
+    cmsFloat32Number v = 0;
+    int i, start = 0;
+
+    if (ExtraFirst)
+        start = Extra;
+
+    for (i=0; i < nChan; i++) {
+
+        int index = DoSwap ? (nChan - i - 1) : i;
+
+        v = wOut[index] * maximum;
+
+        if (Reverse)
+            v = maximum - v;
+
+        if (Planar)
+            ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
+        else
+            ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
+    }
+
+    if (!ExtraFirst) {
+        output += Extra * sizeof(cmsUInt16Number);
+    }
+
+   if (Extra == 0 && SwapFirst) {
+
+         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
+        *swap1 = (cmsUInt16Number)  _cmsFloat2Half( v );
+    }
+
+    if (T_PLANAR(info -> OutputFormat))
+        return output + sizeof(cmsUInt16Number);
+    else
+        return output + nChan * sizeof(cmsUInt16Number);
+}
+
+#endif
 
 // ----------------------------------------------------------------------------------------------------------------
 
@@ -2229,12 +2932,19 @@ static cmsFormatters16 InputFormatters16[] = {
     //  ----------------------------   ------------------------------------  ----------------------------
     { TYPE_Lab_DBL,                                 ANYPLANAR|ANYEXTRA,   UnrollLabDoubleTo16},
     { TYPE_XYZ_DBL,                                 ANYPLANAR|ANYEXTRA,   UnrollXYZDoubleTo16},
+    { TYPE_Lab_FLT,                                 ANYPLANAR|ANYEXTRA,   UnrollLabFloatTo16},
+    { TYPE_XYZ_FLT,                                 ANYPLANAR|ANYEXTRA,   UnrollXYZFloatTo16},
     { 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},
-
+    { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+                                             ANYSWAP|ANYEXTRA|ANYSPACE,   UnrollDoubleTo16},
+    { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+                                             ANYSWAP|ANYEXTRA|ANYSPACE,   UnrollFloatTo16},
+#ifndef CMS_NO_HALF_SUPPORT 
+    { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+                                            ANYEXTRA|ANYSWAP|ANYSPACE,   UnrollHalfTo16},
+#endif
 
-    { CHANNELS_SH(1)|BYTES_SH(1),                              ANYSPACE,  Unroll1Byte}, 
+    { 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},
@@ -2249,15 +2959,20 @@ static cmsFormatters16 InputFormatters16[] = {
     { 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(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),  
+                                                               ANYSPACE,  Unroll3BytesSkip1SwapSwapFirst},
+
     { 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}, 
+    { 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},     
+    { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
+                                   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},
@@ -2271,13 +2986,13 @@ static cmsFormatters16 InputFormatters16[] = {
     { 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}, 
+    { 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}, 
+    { BYTES_SH(2)|PLANAR_SH(1),  ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE,  UnrollPlanarWords},
+    { BYTES_SH(2),  ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE,  UnrollAnyWords},
 };
 
 
@@ -2288,11 +3003,19 @@ static cmsFormattersFloat InputFormattersFloat[] = {
     //  ----------------------------   ------------------------------------  ----------------------------
     {     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},
+    {     FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+                                                      ANYCHANNELS|ANYSPACE,  UnrollFloatsToFloat},
+
+    {     FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+                                                        ANYCHANNELS|ANYSPACE,  UnrollDoublesToFloat},
+#ifndef CMS_NO_HALF_SUPPORT 
+    {     FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+                                                        ANYCHANNELS|ANYSPACE,  UnrollHalfToFloat},
+#endif
 };
 
 
@@ -2303,9 +3026,9 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
     cmsUInt32Number i;
     cmsFormatter fr;
 
+    switch (dwFlags) {
 
-    if (!(dwFlags & CMS_PACK_FLAGS_FLOAT)) {
-
+    case CMS_PACK_FLAGS_16BITS: {
         for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
             cmsFormatters16* f = InputFormatters16 + i;
 
@@ -2315,7 +3038,9 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
             }
         }
     }
-    else {
+    break;
+
+    case CMS_PACK_FLAGS_FLOAT: {
         for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
             cmsFormattersFloat* f = InputFormattersFloat + i;
 
@@ -2325,6 +3050,11 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
             }
         }
     }
+    break;
+
+    default:;
+
+    }
 
     fr.Fmt16 = NULL;
     return fr;
@@ -2336,10 +3066,20 @@ static cmsFormatters16 OutputFormatters16[] = {
 
     { 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},   
+    { TYPE_Lab_FLT,                                      ANYPLANAR|ANYEXTRA,  PackLabFloatFrom16},
+    { TYPE_XYZ_FLT,                                      ANYPLANAR|ANYEXTRA,  PackXYZFloatFrom16},
+    
+    { FLOAT_SH(1)|BYTES_SH(0),      ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+                                    ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE,  PackDoubleFrom16},
+    { FLOAT_SH(1)|BYTES_SH(4),      ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+                                    ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE,  PackFloatFrom16},
+#ifndef CMS_NO_HALF_SUPPORT 
+    { FLOAT_SH(1)|BYTES_SH(2),      ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+                                    ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE,  PackHalfFrom16},
+#endif
+
+    { 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},
 
@@ -2353,9 +3093,9 @@ static cmsFormatters16 OutputFormatters16[] = {
     { 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),  
+    { 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),         
+    { 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},
 
@@ -2364,7 +3104,7 @@ static cmsFormatters16 OutputFormatters16[] = {
     { 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),  
+    { 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},
@@ -2372,12 +3112,12 @@ static cmsFormatters16 OutputFormatters16[] = {
     { 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}, 
+    { 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},   
+    { BYTES_SH(1),                 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
+    { BYTES_SH(1)|PLANAR_SH(1),    ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
 
     { CHANNELS_SH(1)|BYTES_SH(2),                                  ANYSPACE,  Pack1Word},
     { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1),                      ANYSPACE,  Pack1WordSkip1},
@@ -2391,18 +3131,18 @@ static cmsFormatters16 OutputFormatters16[] = {
     { 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),             
+    { 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)|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)|PLANAR_SH(1),     ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
     { BYTES_SH(2),                  ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
 
 };
@@ -2413,48 +3153,63 @@ static cmsFormattersFloat OutputFormattersFloat[] = {
     //  ----------------------------   ---------------------------------------------------  ----------------------------
     {     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},
+
+    {     FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
+                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackFloatsFromFloat },
+    {     FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
+                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackDoublesFromFloat },
+#ifndef CMS_NO_HALF_SUPPORT 
+    {     FLOAT_SH(1)|BYTES_SH(2),                                   
+                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackHalfFromFloat },
+#endif
+
 
 
 };
 
 
 // Bit fields set to one in the mask are not compared
+static
 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
 {
     cmsUInt32Number i;
     cmsFormatter fr;
 
 
-    if (dwFlags & CMS_PACK_FLAGS_FLOAT) {
+    switch (dwFlags)
+    {
 
-        for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
-            cmsFormattersFloat* f = OutputFormattersFloat + i;
+     case CMS_PACK_FLAGS_16BITS: {
+
+        for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
+            cmsFormatters16* f = OutputFormatters16 + i;
 
             if ((dwInput & ~f ->Mask) == f ->Type) {
-                fr.FmtFloat = f ->Frm;
+                fr.Fmt16 = f ->Frm;
                 return fr;
             }
         }
+        }
+        break;
 
-    }
-    else {
+    case CMS_PACK_FLAGS_FLOAT: {
 
-        for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
-            cmsFormatters16* f = OutputFormatters16 + i;
+        for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
+            cmsFormattersFloat* f = OutputFormattersFloat + i;
 
             if ((dwInput & ~f ->Mask) == f ->Type) {
-                fr.Fmt16 = f ->Frm;
+                fr.FmtFloat = f ->Frm;
                 return fr;
             }
         }
+        }
+        break;
+
+    default:;
+
     }
 
     fr.Fmt16 = NULL;
@@ -2469,49 +3224,107 @@ typedef struct _cms_formatters_factory_list {
 
 } cmsFormattersFactoryList;
 
-static cmsFormattersFactoryList* FactoryList = NULL;
+_cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupFormatterFactoryList(struct _cmsContext_struct* ctx, 
+                                               const struct _cmsContext_struct* src)
+{
+   _cmsFormattersPluginChunkType newHead = { NULL };
+   cmsFormattersFactoryList*  entry;
+   cmsFormattersFactoryList*  Anterior = NULL;
+   _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
+
+     _cmsAssert(head != NULL);
+
+   // Walk the list copying all nodes
+   for (entry = head->FactoryList;
+       entry != NULL;
+       entry = entry ->Next) {
+
+           cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
+
+           if (newEntry == NULL) 
+               return;
+
+           // We want to keep the linked list order, so this is a little bit tricky
+           newEntry -> Next = NULL;
+           if (Anterior)
+               Anterior -> Next = newEntry;
+
+           Anterior = newEntry;
+
+           if (newHead.FactoryList == NULL)
+               newHead.FactoryList = newEntry;
+   }
+
+   ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
+}
+
+// The interpolation plug-in memory chunk allocator/dup
+void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, 
+                                    const struct _cmsContext_struct* src)
+{
+      _cmsAssert(ctx != NULL);
+
+     if (src != NULL) {
+        
+         // Duplicate the LIST
+         DupFormatterFactoryList(ctx, src);
+     }
+     else {
+          static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
+          ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
+     }
+}
+
 
 
 // Formatters management
-cmsBool  _cmsRegisterFormattersPlugin(cmsPluginBase* Data)
+cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
+    _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
     cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
     cmsFormattersFactoryList* fl ;
 
-    // Reset
+    // Reset to built-in defaults
     if (Data == NULL) {
 
-          FactoryList = NULL;
+          ctx ->FactoryList = NULL;
           return TRUE;
     }
-    
-    fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList));
+
+    fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
     if (fl == NULL) return FALSE;
 
     fl ->Factory    = Plugin ->FormattersFactory;
 
-    fl ->Next = FactoryList;
-    FactoryList = fl;
+    fl ->Next = ctx -> FactoryList;
+    ctx ->FactoryList = fl;
 
     return TRUE;
 }
 
-cmsFormatter _cmsGetFormatter(cmsUInt32Number Type,         // Specific type, i.e. TYPE_RGB_8
-                             cmsFormatterDirection Dir, 
-                             cmsUInt32Number dwFlags)       // Float or 16 bits
+cmsFormatter _cmsGetFormatter(cmsContext ContextID,
+                             cmsUInt32Number Type,         // Specific type, i.e. TYPE_RGB_8
+                             cmsFormatterDirection Dir,
+                             cmsUInt32Number dwFlags)
 {
+    _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
     cmsFormattersFactoryList* f;
 
-    for (f = FactoryList; f != NULL; f = f ->Next) {
+    for (f =ctx->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) 
+    if (Dir == cmsFormatterInput)
         return _cmsGetStockInputFormatter(Type, dwFlags);
-    else 
+    else
         return _cmsGetStockOutputFormatter(Type, dwFlags);
 }
 
@@ -2533,7 +3346,7 @@ cmsBool  _cmsFormatterIs8bit(cmsUInt32Number Type)
 // 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);
@@ -2546,7 +3359,7 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil
 // 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);