changeset 15157:a70625245529

8162488: JDK should be updated to use LittleCMS 2.8 Reviewed-by: serb, psadhukhan
author prr
date Tue, 26 Jul 2016 11:50:19 -0700
parents d4f7412a51d2
children 25e32d8c26c8
files src/java.desktop/share/native/liblcms/cmsalpha.c src/java.desktop/share/native/liblcms/cmscam02.c src/java.desktop/share/native/liblcms/cmscgats.c src/java.desktop/share/native/liblcms/cmscnvrt.c src/java.desktop/share/native/liblcms/cmserr.c src/java.desktop/share/native/liblcms/cmsgamma.c src/java.desktop/share/native/liblcms/cmsgmt.c src/java.desktop/share/native/liblcms/cmshalf.c src/java.desktop/share/native/liblcms/cmsintrp.c src/java.desktop/share/native/liblcms/cmsio0.c src/java.desktop/share/native/liblcms/cmsio1.c src/java.desktop/share/native/liblcms/cmslut.c src/java.desktop/share/native/liblcms/cmsmd5.c src/java.desktop/share/native/liblcms/cmsmtrx.c src/java.desktop/share/native/liblcms/cmsnamed.c src/java.desktop/share/native/liblcms/cmsopt.c src/java.desktop/share/native/liblcms/cmspack.c src/java.desktop/share/native/liblcms/cmspcs.c src/java.desktop/share/native/liblcms/cmsplugin.c src/java.desktop/share/native/liblcms/cmsps2.c src/java.desktop/share/native/liblcms/cmssamp.c src/java.desktop/share/native/liblcms/cmssm.c src/java.desktop/share/native/liblcms/cmstypes.c src/java.desktop/share/native/liblcms/cmsvirt.c src/java.desktop/share/native/liblcms/cmswtpnt.c src/java.desktop/share/native/liblcms/cmsxform.c src/java.desktop/share/native/liblcms/lcms2.h src/java.desktop/share/native/liblcms/lcms2_internal.h src/java.desktop/share/native/liblcms/lcms2_plugin.h
diffstat 29 files changed, 1249 insertions(+), 359 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/liblcms/cmsalpha.c	Tue Jul 26 11:50:19 2016 -0700
@@ -0,0 +1,547 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This file is available under and governed by the GNU General Public
+// License version 2 only, as published by the Free Software Foundation.
+// However, the following notice accompanied the original version of this
+// file:
+//
+//---------------------------------------------------------------------------------
+//
+//  Little Color Management System
+//  Copyright (c) 1998-2016 Marti Maria Saguer
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//---------------------------------------------------------------------------------
+//
+
+#include "lcms2_internal.h"
+
+
+// Alpha copy ------------------------------------------------------------------------------------------------------------------
+
+// Floor to byte, taking care of saturation
+cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
+{
+       d += 0.5;
+       if (d <= 0) return 0;
+       if (d >= 255.0) return 255;
+
+       return (cmsUInt8Number) _cmsQuickFloorWord(d);
+}
+
+
+// Return the size in bytes of a given formatter
+static
+int trueBytesSize(cmsUInt32Number Format)
+{
+       int fmt_bytes = T_BYTES(Format);
+
+       // For double, the T_BYTES field returns zero
+       if (fmt_bytes == 0)
+              return sizeof(double);
+
+       // Otherwise, it is already correct for all formats
+       return fmt_bytes;
+}
+
+
+// Several format converters
+
+typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src);
+
+
+// From 8
+
+static
+void copy8(void* dst, const void* src)
+{
+       memmove(dst, src, 1);
+}
+
+static
+void from8to16(void* dst, const void* src)
+{
+       cmsUInt8Number n = *(cmsUInt8Number*)src;
+       *(cmsUInt16Number*) dst = FROM_8_TO_16(n);
+}
+
+static
+void from8toFLT(void* dst, const void* src)
+{
+       *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
+}
+
+static
+void from8toDBL(void* dst, const void* src)
+{
+       *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
+}
+
+static
+void from8toHLF(void* dst, const void* src)
+{
+       cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
+       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+// From 16
+
+static
+void from16to8(void* dst, const void* src)
+{
+       cmsUInt16Number n = *(cmsUInt16Number*)src;
+       *(cmsUInt8Number*) dst = FROM_16_TO_8(n);
+}
+
+static
+void copy16(void* dst, const void* src)
+{
+       memmove(dst, src, 2);
+}
+
+void from16toFLT(void* dst, const void* src)
+{
+       *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+}
+
+void from16toDBL(void* dst, const void* src)
+{
+       *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+}
+
+static
+void from16toHLF(void* dst, const void* src)
+{
+       cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
+       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+// From Float
+
+static
+void fromFLTto8(void* dst, const void* src)
+{
+       cmsFloat32Number n = *(cmsFloat32Number*)src;
+       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
+}
+
+static
+void fromFLTto16(void* dst, const void* src)
+{
+       cmsFloat32Number n = *(cmsFloat32Number*)src;
+       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void copy32(void* dst, const void* src)
+{
+       memmove(dst, src, sizeof(cmsFloat32Number));
+}
+
+static
+void fromFLTtoDBL(void* dst, const void* src)
+{
+       cmsFloat32Number n = *(cmsFloat32Number*)src;
+       *(cmsFloat64Number*)dst = (cmsFloat64Number)n;
+}
+
+static
+void fromFLTtoHLF(void* dst, const void* src)
+{
+       cmsFloat32Number n = *(cmsFloat32Number*)src;
+       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+
+// From HALF
+
+static
+void fromHLFto8(void* dst, const void* src)
+{
+       cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
+       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
+}
+
+static
+void fromHLFto16(void* dst, const void* src)
+{
+       cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
+       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void fromHLFtoFLT(void* dst, const void* src)
+{
+       *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
+}
+
+static
+void fromHLFtoDBL(void* dst, const void* src)
+{
+       *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
+}
+
+// From double
+static
+void fromDBLto8(void* dst, const void* src)
+{
+       cmsFloat64Number n = *(cmsFloat64Number*)src;
+       *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
+}
+
+static
+void fromDBLto16(void* dst, const void* src)
+{
+       cmsFloat64Number n = *(cmsFloat64Number*)src;
+       *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void fromDBLtoFLT(void* dst, const void* src)
+{
+       cmsFloat64Number n = *(cmsFloat64Number*)src;
+       *(cmsFloat32Number*)dst = (cmsFloat32Number) n;
+}
+
+static
+void fromDBLtoHLF(void* dst, const void* src)
+{
+       cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
+       *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+static
+void copy64(void* dst, const void* src)
+{
+       memmove(dst, src, sizeof(cmsFloat64Number));
+}
+
+
+// Returns the position (x or y) of the formatter in the table of functions
+static
+int FormatterPos(cmsUInt32Number frm)
+{
+       int  b = T_BYTES(frm);
+
+       if (b == 0 && T_FLOAT(frm))
+              return 4; // DBL
+       if (b == 2 && T_FLOAT(frm))
+              return 2; // HLF
+       if (b == 4 && T_FLOAT(frm))
+              return 3; // FLT
+       if (b == 2 && !T_FLOAT(frm))
+              return 1; // 16
+       if (b == 1 && !T_FLOAT(frm))
+              return 0; // 8
+
+       return -1; // not recognized
+
+}
+
+// Obtains a alpha-to-alpha funmction formatter
+static
+cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out)
+{
+static cmsFormatterAlphaFn FormattersAlpha[5][5] = {
+
+       /* from 8 */  { copy8,      from8to16,   from8toHLF,   from8toFLT,   from8toDBL   },
+       /* from 16*/  { from16to8,  copy16,      from16toHLF,  from16toFLT,  from16toDBL  },
+       /* from HLF*/ { fromHLFto8, fromHLFto16, copy16,       fromHLFtoFLT, fromHLFtoDBL },
+       /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTtoHLF, copy32,       fromFLTtoDBL },
+       /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLtoHLF, fromDBLtoFLT, copy64 }};
+
+        int in_n  = FormatterPos(in);
+        int out_n = FormatterPos(out);
+
+        if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) {
+
+               cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
+               return NULL;
+        }
+
+        return FormattersAlpha[in_n][out_n];
+}
+
+
+
+// This function computes the distance from each component to the next one in bytes.
+static
+void ComputeIncrementsForChunky(cmsUInt32Number Format,
+                                cmsUInt32Number ComponentStartingOrder[],
+                                cmsUInt32Number ComponentPointerIncrements[])
+{
+       cmsUInt32Number channels[cmsMAXCHANNELS];
+       int extra = T_EXTRA(Format);
+       int nchannels = T_CHANNELS(Format);
+       int total_chans = nchannels + extra;
+       int i;
+       int channelSize = trueBytesSize(Format);
+       int pixelSize = channelSize * total_chans;
+
+           // Sanity check
+           if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
+                   return;
+
+        memset(channels, 0, sizeof(channels));
+
+       // Separation is independent of starting point and only depends on channel size
+       for (i = 0; i < extra; i++)
+              ComponentPointerIncrements[i] = pixelSize;
+
+       // Handle do swap
+       for (i = 0; i < total_chans; i++)
+       {
+              if (T_DOSWAP(Format)) {
+                     channels[i] = total_chans - i - 1;
+              }
+              else {
+                     channels[i] = i;
+              }
+       }
+
+       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
+       if (T_SWAPFIRST(Format) && total_chans > 1) {
+
+              cmsUInt32Number tmp = channels[0];
+              for (i = 0; i < total_chans-1; i++)
+                     channels[i] = channels[i + 1];
+
+              channels[total_chans - 1] = tmp;
+       }
+
+       // Handle size
+       if (channelSize > 1)
+              for (i = 0; i < total_chans; i++) {
+                     channels[i] *= channelSize;
+              }
+
+       for (i = 0; i < extra; i++)
+              ComponentStartingOrder[i] = channels[i + nchannels];
+}
+
+
+
+//  On planar configurations, the distance is the stride added to any non-negative
+static
+void ComputeIncrementsForPlanar(cmsUInt32Number Format,
+                                cmsUInt32Number BytesPerPlane,
+                                cmsUInt32Number ComponentStartingOrder[],
+                                cmsUInt32Number ComponentPointerIncrements[])
+{
+       cmsUInt32Number channels[cmsMAXCHANNELS];
+       int extra = T_EXTRA(Format);
+       int nchannels = T_CHANNELS(Format);
+       int total_chans = nchannels + extra;
+       int i;
+       int channelSize = trueBytesSize(Format);
+
+       // Sanity check
+       if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
+           return;
+
+       memset(channels, 0, sizeof(channels));
+
+       // Separation is independent of starting point and only depends on channel size
+       for (i = 0; i < extra; i++)
+              ComponentPointerIncrements[i] = channelSize;
+
+       // Handle do swap
+       for (i = 0; i < total_chans; i++)
+       {
+              if (T_DOSWAP(Format)) {
+                     channels[i] = total_chans - i - 1;
+              }
+              else {
+                     channels[i] = i;
+              }
+       }
+
+       // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
+       if (T_SWAPFIRST(Format) && total_chans > 0) {
+
+              cmsUInt32Number tmp = channels[0];
+              for (i = 0; i < total_chans - 1; i++)
+                     channels[i] = channels[i + 1];
+
+              channels[total_chans - 1] = tmp;
+       }
+
+       // Handle size
+       for (i = 0; i < total_chans; i++) {
+              channels[i] *= BytesPerPlane;
+       }
+
+       for (i = 0; i < extra; i++)
+              ComponentStartingOrder[i] = channels[i + nchannels];
+}
+
+
+
+// Dispatcher por chunky and planar RGB
+static
+void  ComputeComponentIncrements(cmsUInt32Number Format,
+                                 cmsUInt32Number BytesPerPlane,
+                                 cmsUInt32Number ComponentStartingOrder[],
+                                 cmsUInt32Number ComponentPointerIncrements[])
+{
+       if (T_PLANAR(Format)) {
+
+              ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
+       }
+       else {
+              ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
+       }
+
+}
+
+
+
+// Handles extra channels copying alpha if requested by the flags
+void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
+                                               void* out,
+                                               cmsUInt32Number PixelsPerLine,
+                                               cmsUInt32Number LineCount,
+                                               const cmsStride* Stride)
+{
+    cmsUInt32Number i, j, k;
+    cmsUInt32Number nExtra;
+    cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
+    cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
+    cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
+    cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
+
+    cmsFormatterAlphaFn copyValueFn;
+
+    // Make sure we need some copy
+    if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
+        return;
+
+    // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
+    if (p->InputFormat == p->OutputFormat && in == out)
+        return;
+
+    // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
+    nExtra = T_EXTRA(p->InputFormat);
+    if (nExtra != T_EXTRA(p->OutputFormat))
+        return;
+
+    // Anything to do?
+    if (nExtra == 0)
+        return;
+
+    // Compute the increments
+    ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
+    ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
+
+    // Check for conversions 8, 16, half, float, dbl
+    copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
+
+    if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
+
+        cmsUInt8Number* SourcePtr;
+        cmsUInt8Number* DestPtr;
+
+        cmsUInt32Number SourceStrideIncrement = 0;
+        cmsUInt32Number DestStrideIncrement = 0;
+
+        // The loop itself
+        for (i = 0; i < LineCount; i++) {
+
+            // Prepare pointers for the loop
+            SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
+            DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
+
+            for (j = 0; j < PixelsPerLine; j++) {
+
+                copyValueFn(DestPtr, SourcePtr);
+
+                SourcePtr += SourceIncrements[0];
+                DestPtr += DestIncrements[0];
+            }
+
+            SourceStrideIncrement += Stride->BytesPerLineIn;
+            DestStrideIncrement += Stride->BytesPerLineOut;
+        }
+
+    }
+    else { // General case with more than one extra channel
+
+        cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
+        cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
+
+        cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
+        cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
+
+        memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
+        memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
+
+        // The loop itself
+        for (i = 0; i < LineCount; i++) {
+
+            // Prepare pointers for the loop
+            for (j = 0; j < nExtra; j++) {
+
+                SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
+                DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
+            }
+
+            for (j = 0; j < PixelsPerLine; j++) {
+
+                for (k = 0; k < nExtra; k++) {
+
+                    copyValueFn(DestPtr[k], SourcePtr[k]);
+
+                    SourcePtr[k] += SourceIncrements[k];
+                    DestPtr[k] += DestIncrements[k];
+                }
+            }
+
+            for (j = 0; j < nExtra; j++) {
+
+                SourceStrideIncrements[j] += Stride->BytesPerLineIn;
+                DestStrideIncrements[j] += Stride->BytesPerLineOut;
+            }
+        }
+    }
+}
+
+
--- a/src/java.desktop/share/native/liblcms/cmscam02.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmscam02.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
--- a/src/java.desktop/share/native/liblcms/cmscgats.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -625,7 +625,7 @@
 }
 
 // Parses a float number
-// This can not call directly atof because it uses locale dependant
+// This can not call directly atof because it uses locale dependent
 // parsing, while CCMX files always use . as decimal separator
 static
 cmsFloat64Number ParseFloatNumber(const char *Buffer)
@@ -830,11 +830,11 @@
 
                     if (it8 ->sy == SINUM) {
 
-                        sprintf(it8->id, "%d", it8->inum);
+                        snprintf(it8->id, 127, "%d", it8->inum);
                     }
                     else {
 
-                        sprintf(it8->id, it8 ->DoubleFormatter, it8->dnum);
+                        snprintf(it8->id, 127, it8 ->DoubleFormatter, it8->dnum);
                     }
 
                     k = (int) strlen(it8 ->id);
@@ -1392,7 +1392,7 @@
     cmsIT8* it8 = (cmsIT8*) hIT8;
     char Buffer[1024];
 
-    sprintf(Buffer, it8->DoubleFormatter, Val);
+    snprintf(Buffer, 1023, it8->DoubleFormatter, Val);
 
     return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
 }
@@ -1402,7 +1402,7 @@
     cmsIT8* it8 = (cmsIT8*) hIT8;
     char Buffer[1024];
 
-    sprintf(Buffer, "%u", Val);
+    snprintf(Buffer, 1023, "%u", Val);
 
     return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
 }
@@ -1846,7 +1846,7 @@
 }
 
 
-// -------------------------------------------------------------- Higer level parsing
+// -------------------------------------------------------------- Higher level parsing
 
 static
 cmsBool DataFormatSection(cmsIT8* it8)
@@ -2149,7 +2149,7 @@
 
 
 
-// Init usefull pointers
+// Init useful pointers
 
 static
 void CookPointers(cmsIT8* it8)
@@ -2546,9 +2546,9 @@
 
         fld = GetDataFormat(it8, i);
         if (fld != NULL) {
-        if (cmsstrcasecmp(fld, cSample) == 0)
-            return i;
-    }
+            if (cmsstrcasecmp(fld, cSample) == 0)
+                return i;
+        }
     }
 
     return -1;
@@ -2606,7 +2606,7 @@
 
     _cmsAssert(hIT8 != NULL);
 
-    sprintf(Buff, it8->DoubleFormatter, Val);
+    snprintf(Buff, 255, it8->DoubleFormatter, Val);
 
     return SetData(it8, row, col, Buff);
 }
--- a/src/java.desktop/share/native/liblcms/cmscnvrt.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmscnvrt.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -136,7 +136,7 @@
 };
 
 
-// A pointer to the begining of the list
+// A pointer to the beginning of the list
 _cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
 
 // Duplicates the zone of memory used by the plug-in in the new context
@@ -299,6 +299,7 @@
     cmsMAT3 Scale, m1, m2, m3, m4;
 
     // TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing.
+    // TODO: Add support for ArgyllArts tag
 
     // Adaptation state
     if (AdaptationState == 1.0) {
@@ -917,7 +918,7 @@
         return TRUE;
     }
 
-    // Make sure to pass thru K (which now is fixed)
+    // Make sure to pass through K (which now is fixed)
     Outf[3] = LabK[3];
 
     // Apply TAC if needed
@@ -985,7 +986,7 @@
     memset(&bp, 0, sizeof(bp));
 
     // We need the input LUT of the last profile, assuming this one is responsible of
-    // black generation. This LUT will be seached in inverse order.
+    // black generation. This LUT will be searched in inverse order.
     bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
     if (bp.LabK2cmyk == NULL) goto Cleanup;
 
--- a/src/java.desktop/share/native/liblcms/cmserr.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmserr.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2015 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -227,7 +227,7 @@
     }
 }
 
-// Auxiliar to fill memory management functions from plugin (or context 0 defaults)
+// Auxiliary to fill memory management functions from plugin (or context 0 defaults)
 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
 {
     if (Plugin == NULL) {
@@ -459,14 +459,14 @@
 
 // Error logging ******************************************************************
 
-// There is no error handling at all. When a funtion fails, it returns proper value.
+// There is no error handling at all. When a function fails, it returns proper value.
 // For example, all create functions does return NULL on failure. Other return FALSE
 // It may be interesting, for the developer, to know why the function is failing.
 // for that reason, lcms2 does offer a logging function. This function does recive
 // a ENGLISH string with some clues on what is going wrong. You can show this
 // info to the end user, or just create some sort of log.
 // The logging function should NOT terminate the program, as this obviously can leave
-// resources. It is the programmer's responsability to check each function return code
+// resources. It is the programmer's responsibility to check each function return code
 // to make sure it didn't fail.
 
 // Error messages are limited to MAX_ERROR_MESSAGE_LEN
--- a/src/java.desktop/share/native/liblcms/cmsgamma.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsgamma.c	Tue Jul 26 11:50:19 2016 -0700
@@ -596,7 +596,7 @@
     return Val;
 }
 
-// Evaluate a segmented funtion for a single value. Return -1 if no valid segment found .
+// Evaluate a segmented function for a single value. Return -1 if no valid segment found .
 // If fn type is 0, perform an interpolation on the table
 static
 cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
--- a/src/java.desktop/share/native/liblcms/cmsgmt.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsgmt.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -56,7 +56,7 @@
 #include "lcms2_internal.h"
 
 
-// Auxiliar: append a Lab identity after the given sequence of profiles
+// Auxiliary: append a Lab identity after the given sequence of profiles
 // and return the transform. Lab profile is closed, rest of profiles are kept open.
 cmsHTRANSFORM _cmsChain2Lab(cmsContext            ContextID,
                             cmsUInt32Number        nProfiles,
@@ -201,7 +201,7 @@
     }
 
     // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
-    // since this is used on black-preserving LUTs, we are not loosing  accuracy in any case
+    // since this is used on black-preserving LUTs, we are not losing  accuracy in any case
     KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
 
     // Get rid of components
@@ -307,7 +307,7 @@
 }
 
 // Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
-// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE
+// the dE obtained is then annotated on the LUT. Values truly out of gamut are clipped to dE = 0xFFFE
 // and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
 //
 // **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
--- a/src/java.desktop/share/native/liblcms/cmshalf.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmshalf.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
--- a/src/java.desktop/share/native/liblcms/cmsintrp.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsintrp.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -185,7 +185,7 @@
     int i;
     cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
 
-    // Fill the auxiliar array
+    // Fill the auxiliary array
     for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
         Samples[i] = nSamples;
 
--- a/src/java.desktop/share/native/liblcms/cmsio0.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -353,7 +353,7 @@
     return nReaded;
 }
 
-// Postion file pointer in the file
+// Position file pointer in the file
 static
 cmsBool  FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
 {
@@ -397,6 +397,7 @@
 {
     cmsIOHANDLER* iohandler = NULL;
     FILE* fm = NULL;
+    cmsInt32Number fileLen;
 
     _cmsAssert(FileName != NULL);
     _cmsAssert(AccessMode != NULL);
@@ -413,7 +414,16 @@
              cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
             return NULL;
         }
-        iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm);
+        fileLen = cmsfilelength(fm);
+        if (fileLen < 0)
+        {
+            fclose(fm);
+            _cmsFree(ContextID, iohandler);
+            cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
+            return NULL;
+        }
+
+        iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
         break;
 
     case 'w':
@@ -453,6 +463,14 @@
 cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
 {
     cmsIOHANDLER* iohandler = NULL;
+    cmsInt32Number fileSize;
+
+    fileSize = cmsfilelength(Stream);
+    if (fileSize < 0)
+    {
+        cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
+        return NULL;
+    }
 
     iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
     if (iohandler == NULL) return NULL;
@@ -460,7 +478,7 @@
     iohandler -> ContextID = ContextID;
     iohandler -> stream = (void*) Stream;
     iohandler -> UsedSpace = 0;
-    iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream);
+    iohandler -> ReportedSize = (cmsUInt32Number) fileSize;
     iohandler -> PhysicalFile[0] = 0;
 
     iohandler ->Read    = FileRead;
@@ -652,7 +670,7 @@
 }
 
 
-// Check existance
+// Check existence
 cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
 {
        _cmsICCPROFILE*  Icc = (_cmsICCPROFILE*) (void*) hProfile;
@@ -708,7 +726,7 @@
         return FALSE;
     }
 
-    // Adjust endianess of the used parameters
+    // Adjust endianness of the used parameters
     Icc -> DeviceClass     = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
     Icc -> ColorSpace      = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.colorSpace);
     Icc -> PCS             = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.pcs);
@@ -826,7 +844,7 @@
 
     memset(&Header.reserved, 0, sizeof(Header.reserved));
 
-    // Set profile ID. Endianess is always big endian
+    // Set profile ID. Endianness is always big endian
     memmove(&Header.profileID, &Icc ->ProfileID, 16);
 
     // Dump the header
@@ -836,7 +854,7 @@
 
     // Get true count
     for (i=0;  i < Icc -> TagCount; i++) {
-        if (Icc ->TagNames[i] != 0)
+        if (Icc ->TagNames[i] != (cmsTagSignature) 0)
             Count++;
     }
 
@@ -845,7 +863,7 @@
 
     for (i=0; i < Icc -> TagCount; i++) {
 
-        if (Icc ->TagNames[i] == 0) continue;   // It is just a placeholder
+        if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue;   // It is just a placeholder
 
         Tag.sig    = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]);
         Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]);
@@ -1195,7 +1213,7 @@
 
     for (i=0; i < Icc -> TagCount; i++) {
 
-        if (Icc ->TagNames[i] == 0) continue;
+        if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue;
 
         // Linked tags are not written
         if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue;
@@ -1329,11 +1347,15 @@
 
     _cmsAssert(hProfile != NULL);
 
+    if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return 0;
     memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
 
     ContextID = cmsGetProfileContextID(hProfile);
     PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID);
-    if (PrevIO == NULL) return 0;
+    if (PrevIO == NULL) {
+        _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+        return 0;
+    }
 
     // Pass #1 does compute offsets
 
@@ -1353,7 +1375,10 @@
     }
 
     memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
-    if (!cmsCloseIOhandler(PrevIO)) return 0;
+    if (!cmsCloseIOhandler(PrevIO))
+        UsedSpace = 0; // As a error marker
+
+    _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
 
     return UsedSpace;
 
@@ -1361,6 +1386,8 @@
 Error:
     cmsCloseIOhandler(PrevIO);
     memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
+    _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+
     return 0;
 }
 
@@ -1564,7 +1591,7 @@
     LocalTypeHandler.ICCVersion = Icc ->Version;
     Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
 
-    // The tag type is supported, but something wrong happend and we cannot read the tag.
+    // The tag type is supported, but something wrong happened and we cannot read the tag.
     // let know the user about this (although it is just a warning)
     if (Icc -> TagPtrs[n] == NULL) {
 
@@ -1883,7 +1910,7 @@
     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
 
     if (Icc->TagPtrs[i] == NULL) {
-           Icc->TagNames[i] = 0;
+           Icc->TagNames[i] = (cmsTagSignature) 0;
            return FALSE;
     }
     return TRUE;
--- a/src/java.desktop/share/native/liblcms/cmsio1.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsio1.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -157,7 +157,7 @@
 }
 
 
-// Auxiliar, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
+// Auxiliary, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
 static
 cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
 {
@@ -343,7 +343,7 @@
     cmsTagSignature tagFloat;
     cmsContext ContextID = cmsGetProfileContextID(hProfile);
 
-    // On named color, take the appropiate tag
+    // On named color, take the appropriate tag
     if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
 
         cmsPipeline* Lut;
@@ -365,9 +365,9 @@
         return Lut;
     }
 
-    // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
+    // This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no
     // matter other LUT are present and have precedence. Intent = -1 means just this.
-    if (Intent != -1) {
+    if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
 
         tag16 = Device2PCS16[Intent];
         tagFloat = Device2PCSFloat[Intent];
@@ -423,7 +423,7 @@
     // Check if this is a grayscale profile.
     if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
 
-        // if so, build appropiate conversion tables.
+        // if so, build appropriate conversion tables.
         // The tables are the PCS iluminant, scaled across GrayTRC
         return BuildGrayInputMatrixPipeline(hProfile);
     }
@@ -578,7 +578,7 @@
     if (Lut == NULL) return NULL;
 
     // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
-    // and since the formatter has already accomodated to 0..1.0, we should undo this change
+    // and since the formatter has already accommodated to 0..1.0, we should undo this change
     if ( PCS == cmsSigLabData)
     {
         if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
@@ -619,7 +619,7 @@
     cmsContext ContextID  = cmsGetProfileContextID(hProfile);
 
 
-    if (Intent != -1) {
+    if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
 
         tag16 = PCS2Device16[Intent];
         tagFloat = PCS2DeviceFloat[Intent];
@@ -680,7 +680,7 @@
     // Check if this is a grayscale profile.
     if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
 
-        // if so, build appropiate conversion tables.
+        // if so, build appropriate conversion tables.
         // The tables are the PCS iluminant, scaled across GrayTRC
         return BuildGrayOutputPipeline(hProfile);
     }
@@ -738,15 +738,21 @@
 {
     cmsPipeline* Lut;
     cmsTagTypeSignature OriginalType;
-    cmsTagSignature tag16    = Device2PCS16[Intent];
-    cmsTagSignature tagFloat = Device2PCSFloat[Intent];
+    cmsTagSignature tag16;
+    cmsTagSignature tagFloat;
     cmsContext ContextID = cmsGetProfileContextID(hProfile);
 
 
-    // On named color, take the appropiate tag
+    if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC)
+        return NULL;
+
+    tag16 = Device2PCS16[Intent];
+    tagFloat = Device2PCSFloat[Intent];
+
+    // On named color, take the appropriate tag
     if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
 
-        cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
+        cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*)cmsReadTag(hProfile, cmsSigNamedColor2Tag);
 
         if (nc == NULL) return NULL;
 
@@ -762,12 +768,13 @@
                 goto Error;
 
         return Lut;
-Error:
+    Error:
         cmsPipelineFree(Lut);
         cmsFreeNamedColorList(nc);
         return NULL;
     }
 
+
     if (cmsIsTag(hProfile, tagFloat)) {  // Float tag takes precedence
 
         // Floating point LUT are always V
@@ -777,19 +784,19 @@
     tagFloat = Device2PCSFloat[0];
     if (cmsIsTag(hProfile, tagFloat)) {
 
-        return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+        return cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat));
     }
 
     if (!cmsIsTag(hProfile, tag16)) {  // Is there any LUT-Based table?
 
-        tag16    = Device2PCS16[0];
+        tag16 = Device2PCS16[0];
         if (!cmsIsTag(hProfile, tag16)) return NULL;
     }
 
     // Check profile version and LUT type. Do the necessary adjustments if needed
 
     // Read the tag
-    Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
+    Lut = (cmsPipeline*)cmsReadTag(hProfile, tag16);
     if (Lut == NULL) return NULL;
 
     // The profile owns the Lut, so we need to copy it
@@ -802,7 +809,7 @@
         ChangeInterpolationToTrilinear(Lut);
 
     // After reading it, we have info about the original type
-    OriginalType =  _cmsGetTagTrueType(hProfile, tag16);
+    OriginalType = _cmsGetTagTrueType(hProfile, tag16);
 
     // We need to adjust data for Lab16 on output
     if (OriginalType != cmsSigLut16Type) return Lut;
@@ -810,12 +817,12 @@
     // Here it is possible to get Lab on both sides
 
     if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
-        if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+        if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
             goto Error2;
     }
 
     if (cmsGetPCS(hProfile) == cmsSigLabData) {
-        if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+        if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
             goto Error2;
     }
 
@@ -950,7 +957,7 @@
 }
 
 
-// Auxiliar, read and duplicate a MLU if found.
+// Auxiliary, read and duplicate a MLU if found.
 static
 cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
 {
--- a/src/java.desktop/share/native/liblcms/cmslut.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmslut.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -534,7 +534,7 @@
                 goto Error;
         } else {
             NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number));
-            if (NewElem ->Tab.TFloat == NULL)
+            if (NewElem ->Tab.T == NULL)
                 goto Error;
         }
     }
@@ -1482,7 +1482,8 @@
                  First = FALSE;
              }
              else {
-                Anterior ->Next = NewMPE;
+                if (Anterior != NULL)
+                    Anterior ->Next = NewMPE;
              }
 
             Anterior = NewMPE;
@@ -1836,3 +1837,5 @@
 
     return TRUE;
 }
+
+
--- a/src/java.desktop/share/native/liblcms/cmsmd5.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsmd5.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
--- a/src/java.desktop/share/native/liblcms/cmsmtrx.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsmtrx.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -67,7 +67,7 @@
     r -> n[VZ] = z;
 }
 
-// Vector substraction
+// Vector subtraction
 void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b)
 {
   r -> n[VX] = a -> n[VX] - b -> n[VX];
@@ -201,3 +201,5 @@
     r->n[VY] = a->v[1].n[VX]*v->n[VX] + a->v[1].n[VY]*v->n[VY] + a->v[1].n[VZ]*v->n[VZ];
     r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ];
 }
+
+
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -121,7 +121,7 @@
 static
 cmsBool GrowMLUtable(cmsMLU* mlu)
 {
-    int AllocatedEntries;
+    cmsUInt32Number AllocatedEntries;
     _cmsMLUentry *NewPtr;
 
     // Sanity check
@@ -147,7 +147,7 @@
 static
 int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
 {
-    int i;
+    cmsUInt32Number i;
 
     // Sanity check
     if (mlu == NULL) return -1;
@@ -207,15 +207,42 @@
     return TRUE;
 }
 
+// Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some
+// compilers don't properly align beginning of strings
 
-// Add an ASCII entry.
+static
+cmsUInt16Number strTo16(const char str[3])
+{
+    cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1];
+
+    return n;  // Always big endian in this case
+}
+
+static
+void strFrom16(char str[3], cmsUInt16Number n)
+{
+    // Assiming this would be aligned
+    union {
+
+       cmsUInt16Number n;
+       char str[2];
+
+    } c;
+
+    c.n = n;  // Always big endian in this case
+
+    str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0;
+
+}
+
+// Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
 cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
 {
-    cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1;
+    cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
     wchar_t* WStr;
     cmsBool  rc;
-    cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
-    cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
 
     if (mlu == NULL) return FALSE;
 
@@ -245,18 +272,17 @@
     return (cmsUInt32Number)(p - s);
 }
 
-
-// Add a wide entry
+// Add a wide entry. Do not add any \0 terminator (ICC1v43_2010-12.pdf page 61)
 cmsBool  CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
 {
-    cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
-    cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
+    cmsUInt16Number Lang  = strTo16(Language);
+    cmsUInt16Number Cntry = strTo16(Country);
     cmsUInt32Number len;
 
     if (mlu == NULL) return FALSE;
     if (WideString == NULL) return FALSE;
 
-    len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t);
+    len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
     return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
 }
 
@@ -327,8 +353,8 @@
                               cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
                               cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
 {
-    int i;
-    int Best = -1;
+    cmsUInt32Number i;
+    cmsInt32Number Best = -1;
     _cmsMLUentry* v;
 
     if (mlu == NULL) return NULL;
@@ -379,8 +405,8 @@
     cmsUInt32Number  StrLen = 0;
     cmsUInt32Number ASCIIlen, i;
 
-    cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
-    cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
 
     // Sanitize
     if (mlu == NULL) return 0;
@@ -423,8 +449,8 @@
     const wchar_t *Wide;
     cmsUInt32Number  StrLen = 0;
 
-    cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
-    cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
 
     // Sanitize
     if (mlu == NULL) return 0;
@@ -456,8 +482,8 @@
 {
     const wchar_t *Wide;
 
-    cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
-    cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
     cmsUInt16Number ObtLang, ObtCode;
 
     // Sanitize
@@ -467,10 +493,9 @@
     if (Wide == NULL) return FALSE;
 
     // Get used language and code
-    *(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
-    *(cmsUInt16Number *)ObtainedCountry  = _cmsAdjustEndianess16(ObtCode);
+    strFrom16(ObtainedLanguage, ObtLang);
+    strFrom16(ObtainedCountry, ObtCode);
 
-    ObtainedLanguage[2] = ObtainedCountry[2] = 0;
     return TRUE;
 }
 
@@ -493,12 +518,12 @@
 
     if (mlu == NULL) return FALSE;
 
-    if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE;
+    if (idx >= mlu->UsedEntries) return FALSE;
 
     entry = &mlu->Entries[idx];
 
-    *(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language);
-    *(cmsUInt16Number *)CountryCode  = _cmsAdjustEndianess16(entry->Country);
+    strFrom16(LanguageCode, entry->Language);
+    strFrom16(CountryCode, entry->Country);
 
     return TRUE;
 }
--- a/src/java.desktop/share/native/liblcms/cmsopt.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c	Tue Jul 26 11:50:19 2016 -0700
@@ -27,11 +27,10 @@
 // However, the following notice accompanied the original version of this
 // file:
 //
-
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -258,11 +257,10 @@
 
                             // We can not get rid of full matrix
                             cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL);
+                            if (Multmat == NULL) return FALSE;  // Should never happen
 
                             // Recover the chain
-                            if (Multmat != NULL) {
-                                Multmat->Next = chain;
-                            }
+                            Multmat->Next = chain;
                             *pt1 = Multmat;
                      }
 
@@ -560,7 +558,7 @@
             return TRUE;
 }
 
-// Auxiliar, to see if two values are equal or very different
+// Auxiliary, to see if two values are equal or very different
 static
 cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
 {
@@ -568,7 +566,7 @@
 
     for (i=0; i < n; i++) {
 
-        if (abs(White1[i] - White2[i]) > 0xf000) return TRUE;  // Values are so extremly different that the fixup should be avoided
+        if (abs(White1[i] - White2[i]) > 0xf000) return TRUE;  // Values are so extremely different that the fixup should be avoided
         if (White1[i] != White2[i]) return FALSE;
     }
     return TRUE;
@@ -706,7 +704,7 @@
         cmsStage* PreLin = cmsPipelineGetPtrToFirstStage(Src);
 
         // Check if suitable
-        if (PreLin ->Type == cmsSigCurveSetElemType) {
+        if (PreLin && PreLin ->Type == cmsSigCurveSetElemType) {
 
             // Maybe this is a linear tram, so we can avoid the whole stuff
             if (!AllCurvesAreLinear(PreLin)) {
@@ -739,7 +737,7 @@
         cmsStage* PostLin = cmsPipelineGetPtrToLastStage(Src);
 
         // Check if suitable
-        if (cmsStageType(PostLin) == cmsSigCurveSetElemType) {
+        if (PostLin && cmsStageType(PostLin) == cmsSigCurveSetElemType) {
 
             // Maybe this is a linear tram, so we can avoid the whole stuff
             if (!AllCurvesAreLinear(PostLin)) {
@@ -1041,8 +1039,8 @@
     }
 
     if (Zeros == 1 && Poles == 1) return FALSE;  // For linear tables
-    if (Zeros > (nEntries / 4)) return TRUE;  // Degenerated, mostly zeros
-    if (Poles > (nEntries / 4)) return TRUE;  // Degenerated, mostly poles
+    if (Zeros > (nEntries / 20)) return TRUE;  // Degenerated, many zeros
+    if (Poles > (nEntries / 20)) return TRUE;  // Degenerated, many poles
 
     return FALSE;
 }
@@ -1064,17 +1062,19 @@
     cmsColorSpaceSignature ColorSpace, OutputColorSpace;
     cmsStage* OptimizedPrelinMpe;
     cmsStage* mpe;
-    cmsToneCurve**   OptimizedPrelinCurves;
-    _cmsStageCLutData*     OptimizedPrelinCLUT;
+    cmsToneCurve** OptimizedPrelinCurves;
+    _cmsStageCLutData* OptimizedPrelinCLUT;
 
 
     // This is a loosy optimization! does not apply in floating-point cases
     if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
 
-    // Only on RGB
+    // Only on chunky RGB
     if (T_COLORSPACE(*InputFormat)  != PT_RGB) return FALSE;
+    if (T_PLANAR(*InputFormat)) return FALSE;
+
     if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE;
-
+    if (T_PLANAR(*OutputFormat)) return FALSE;
 
     // On 16 bits, user has to specify the feature
     if (!_cmsFormatterIs8bit(*InputFormat)) {
@@ -1098,6 +1098,22 @@
     memset(Trans, 0, sizeof(Trans));
     memset(TransReverse, 0, sizeof(TransReverse));
 
+    // If the last stage of the original lut are curves, and those curves are
+    // degenerated, it is likely the transform is squeezing and clipping
+    // the output from previous CLUT. We cannot optimize this case
+    {
+        cmsStage* last = cmsPipelineGetPtrToLastStage(OriginalLut);
+
+        if (cmsStageType(last) == cmsSigCurveSetElemType) {
+
+            _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*)cmsStageData(last);
+            for (i = 0; i < Data->nCurves; i++) {
+                if (IsDegenerated(Data->TheCurves[i]))
+                    goto Error;
+            }
+        }
+    }
+
     for (t = 0; t < OriginalLut ->InputChannels; t++) {
         Trans[t] = cmsBuildTabulatedToneCurve16(OriginalLut ->ContextID, PRELINEARIZATION_POINTS, NULL);
         if (Trans[t] == NULL) goto Error;
@@ -1431,7 +1447,10 @@
         GammaTables[i] = NULL;
     }
 
-    if (GammaTables != NULL) _cmsFree(Src ->ContextID, GammaTables);
+    if (GammaTables != NULL) {
+        _cmsFree(Src->ContextID, GammaTables);
+        GammaTables = NULL;
+    }
 
     // Maybe the curves are linear at the end
     if (!AllCurvesAreLinear(ObtainedCurves)) {
--- a/src/java.desktop/share/native/liblcms/cmspack.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmspack.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2010 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -110,7 +110,7 @@
 #define ANYFLAVOR       FLAVOR_SH(1)
 
 
-// Supress waning about info never being used
+// Suppress waning about info never being used
 
 #ifdef _MSC_VER
 #pragma warning(disable : 4100)
@@ -3188,6 +3188,8 @@
     cmsUInt32Number i;
     cmsFormatter fr;
 
+    // Optimization is only a hint
+    dwInput &= ~OPTIMIZED_SH(1);
 
     switch (dwFlags)
     {
--- a/src/java.desktop/share/native/liblcms/cmspcs.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmspcs.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2010 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -337,7 +337,7 @@
     wLab[2] = ab2Fix4(Lab.b);
 }
 
-// Auxiliar: convert to Radians
+// Auxiliary: convert to Radians
 static
 cmsFloat64Number RADIANS(cmsFloat64Number deg)
 {
@@ -345,7 +345,7 @@
 }
 
 
-// Auxiliar: atan2 but operating in degrees and returning 0 if a==b==0
+// Auxiliary: atan2 but operating in degrees and returning 0 if a==b==0
 static
 cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
 {
@@ -368,7 +368,7 @@
 }
 
 
-// Auxiliar: Square
+// Auxiliary: Square
 static
 cmsFloat64Number Sqr(cmsFloat64Number v)
 {
--- a/src/java.desktop/share/native/liblcms/cmsplugin.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsplugin.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2010 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -136,7 +136,7 @@
 #endif
 }
 
-// Auxiliar -- read 8, 16 and 32-bit numbers
+// Auxiliary -- read 8, 16 and 32-bit numbers
 cmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
 {
     cmsUInt8Number tmp;
@@ -201,13 +201,13 @@
 
     _cmsAssert(io != NULL);
 
-    if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
+    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
             return FALSE;
 
     if (n != NULL) {
 
         tmp = _cmsAdjustEndianess32(tmp);
-        *n = *(cmsFloat32Number*) &tmp;
+        *n = *(cmsFloat32Number*) (void*) &tmp;
     }
     return TRUE;
 }
@@ -244,22 +244,6 @@
 }
 
 
-// Jun-21-2000: Some profiles (those that comes with W2K) comes
-// with the media white (media black?) x 100. Add a sanity check
-
-static
-void NormalizeXYZ(cmsCIEXYZ* Dest)
-{
-    while (Dest -> X > 2. &&
-           Dest -> Y > 2. &&
-           Dest -> Z > 2.) {
-
-               Dest -> X /= 10.;
-               Dest -> Y /= 10.;
-               Dest -> Z /= 10.;
-       }
-}
-
 cmsBool CMSEXPORT  _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
 {
     cmsEncodedXYZNumber xyz;
@@ -273,8 +257,6 @@
         XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
         XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
         XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
-
-        NormalizeXYZ(XYZ);
     }
     return TRUE;
 }
@@ -336,7 +318,7 @@
 
     _cmsAssert(io != NULL);
 
-    tmp = *(cmsUInt32Number*) &n;
+    tmp = *(cmsUInt32Number*) (void*) &n;
     tmp = _cmsAdjustEndianess32(tmp);
     if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
             return FALSE;
@@ -532,7 +514,10 @@
     va_start(args, frm);
 
     len = vsnprintf((char*) Buffer, 2047, frm, args);
-    if (len < 0) return FALSE;   // Truncated, which is a fatal error for us
+    if (len < 0) {
+        va_end(args);
+        return FALSE;   // Truncated, which is a fatal error for us
+    }
 
     rc = io ->Write(io, len, Buffer);
 
@@ -554,6 +539,7 @@
         if (ContextID == NULL) {
 
             ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
+            if (ctx->MemPool == NULL) return NULL;
         }
         else {
             cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
@@ -989,3 +975,5 @@
 {
     return _cmsContextGetClientChunk(ContextID, UserPtr);
 }
+
+
--- a/src/java.desktop/share/native/liblcms/cmsps2.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -608,7 +608,7 @@
 //
 //  Each row contains Pipeline values for all but first component. So, I
 //  detect row changing by keeping a copy of last value of first
-//  component. -1 is used to mark begining of whole block.
+//  component. -1 is used to mark beginning of whole block.
 
 static
 int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
@@ -1422,14 +1422,15 @@
     if (nColorant > cmsMAXCHANNELS)
         nColorant = cmsMAXCHANNELS;
 
-    for (j=0; j < nColorant; j++) {
+    for (j = 0; j < nColorant; j++) {
 
-                sprintf(Buff, "%.3f", Out[j] / 65535.0);
-                strcat(Colorant, Buff);
-                if (j < nColorant -1)
-                        strcat(Colorant, " ");
+        snprintf(Buff, 31, "%.3f", Out[j] / 65535.0);
+        Buff[31] = 0;
+        strcat(Colorant, Buff);
+        if (j < nColorant - 1)
+            strcat(Colorant, " ");
 
-        }
+    }
 }
 
 
--- a/src/java.desktop/share/native/liblcms/cmssamp.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
--- a/src/java.desktop/share/native/liblcms/cmssm.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmssm.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -247,7 +247,8 @@
 {
     cmsFloat64Number a, b, c, d, e, D;
     cmsFloat64Number sc, sN, sD;
-    cmsFloat64Number tc, tN, tD;
+    //cmsFloat64Number tc; // left for future use
+    cmsFloat64Number tN, tD;
     cmsVEC3 w0;
 
     _cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
@@ -315,7 +316,7 @@
     }
     // finally do the division to get sc and tc
     sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
-    tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD);
+    //tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD); // left for future use.
 
     GetPointOfLine(r, line1, sc);
     return TRUE;
@@ -346,7 +347,7 @@
 }
 
 
-// Auxiliar to retrieve a pointer to the segmentr containing the Lab value
+// Auxiliary to retrieve a pointer to the segmentr containing the Lab value
 static
 cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
 {
@@ -358,7 +359,7 @@
     _cmsAssert(Lab != NULL);
     _cmsAssert(sp != NULL);
 
-    // Center L* by substracting half of its domain, that's 50
+    // Center L* by subtracting half of its domain, that's 50
     _cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
 
     // Convert to spherical coordinates
--- a/src/java.desktop/share/native/liblcms/cmstypes.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -59,7 +59,7 @@
 // This file implements every single tag and tag type as described in the ICC spec. Some types
 // have been deprecated, like ncl and Data. There is no implementation for those types as there
 // are no profiles holding them. The programmer can also extend this list by defining his own types
-// by using the appropiate plug-in. There are three types of plug ins regarding that. First type
+// by using the appropriate plug-in. There are three types of plug ins regarding that. First type
 // allows to define new tags using any existing type. Next plug-in type allows to define new types
 // and the third one is very specific: allows to extend the number of elements in the multiprocessing
 // elements special type.
@@ -142,7 +142,7 @@
 }
 
 
-// Auxiliar to convert UTF-32 to UTF-16 in some cases
+// Auxiliary to convert UTF-32 to UTF-16 in some cases
 static
 cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
 {
@@ -158,7 +158,7 @@
     return TRUE;
 }
 
-// Auxiliar to read an array of wchar_t
+// Auxiliary to read an array of wchar_t
 static
 cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
 {
@@ -189,7 +189,7 @@
                                              cmsUInt32Number n,
                                              cmsUInt32Number SizeOfTag);
 
-// Helper function to deal with position tables as decribed in ICC spec 4.3
+// Helper function to deal with position tables as described in ICC spec 4.3
 // A table of n elements is readed, where first comes n records containing offsets and sizes and
 // then a block containing the data itself. This allows to reuse same data in more than one entry
 static
@@ -980,7 +980,7 @@
     cmsMLU* mlu = (cmsMLU*) Ptr;
     char *Text = NULL;
     wchar_t *Wide = NULL;
-    cmsUInt32Number len, len_aligned, len_filler_alignment;
+    cmsUInt32Number len, len_text, len_tag_requirement, len_aligned;
     cmsBool  rc = FALSE;
     char Filler[68];
 
@@ -990,17 +990,18 @@
     // Get the len of string
     len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
 
-    // From ICC3.4: It has been found that textDescriptionType can contain misaligned data
+    // Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data
     //(see clause 4.1 for the definition of “aligned”). Because the Unicode language
     // code and Unicode count immediately follow the ASCII description, their
     // alignment is not correct if the ASCII count is not a multiple of four. The
     // ScriptCode code is misaligned when the ASCII count is odd. Profile reading and
     // writing software must be written carefully in order to handle these alignment
     // problems.
-
-    // Compute an aligned size
-    len_aligned = _cmsALIGNLONG(len);
-    len_filler_alignment = len_aligned - len;
+    //
+    // The above last sentence suggest to handle alignment issues in the
+    // parser. The provided example (Table 69 on Page 60) makes this clear.
+    // The padding only in the ASCII count is not sufficient for a aligned tag
+    // size, with the same text size in ASCII and Unicode.
 
     // Null strings
     if (len <= 0) {
@@ -1021,6 +1022,12 @@
         cmsMLUgetWide(mlu,  cmsNoLanguage, cmsNoCountry,  Wide, len * sizeof(wchar_t));
     }
 
+    // Tell the real text len including the null terminator and padding
+    len_text = (cmsUInt32Number) strlen(Text) + 1;
+    // Compute an total tag size requirement
+    len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67);
+    len_aligned = _cmsALIGNLONG(len_tag_requirement);
+
   // * cmsUInt32Number       count;          * Description length
   // * cmsInt8Number         desc[count]     * NULL terminated ascii string
   // * cmsUInt32Number       ucLangCode;     * UniCode language code
@@ -1030,20 +1037,14 @@
   // * cmsUInt8Number        scCount;        * ScriptCode count
   // * cmsInt8Number         scDesc[67];     * ScriptCode Description
 
-    if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error;
-    if (!io ->Write(io, len, Text)) goto Error;
-    if (!io ->Write(io, len_filler_alignment, Filler)) goto Error;
+    if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
+    if (!io ->Write(io, len_text, Text)) goto Error;
 
     if (!_cmsWriteUInt32Number(io, 0)) goto Error;  // ucLanguageCode
 
-    // This part is tricky: we need an aligned tag size, and the ScriptCode part
-    // takes 70 bytes, so we need 2 extra bytes to do the alignment
-
-    if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error;
-
+    if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
     // Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t)
-    if (!_cmsWriteWCharArray(io, len, Wide)) goto Error;
-    if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error;
+    if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error;
 
     // ScriptCode Code & count (unused)
     if (!_cmsWriteUInt16Number(io, 0)) goto Error;
@@ -1051,6 +1052,10 @@
 
     if (!io ->Write(io, 67, Filler)) goto Error;
 
+    // possibly add pad at the end of tag
+    if(len_aligned - len_tag_requirement > 0)
+      if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error;
+
     rc = TRUE;
 
 Error:
@@ -1498,7 +1503,7 @@
             LargestPosition = EndOfThisString;
     }
 
-    // Now read the remaining of tag and fill all strings. Substract the directory
+    // Now read the remaining of tag and fill all strings. Subtract the directory
     SizeOfTag   = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
     if (SizeOfTag == 0)
     {
@@ -1532,7 +1537,7 @@
     cmsMLU* mlu =(cmsMLU*) Ptr;
     cmsUInt32Number HeaderSize;
     cmsUInt32Number  Len, Offset;
-    int i;
+    cmsUInt32Number i;
 
     if (Ptr == NULL) {
 
@@ -3133,6 +3138,8 @@
 
         memset(Colorant, 0, sizeof(Colorant));
         if (io -> Read(io, Root, 32, 1) != 1) return NULL;
+        Root[32] = 0;  // To prevent exploits
+
         if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
         if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error;
 
@@ -3155,8 +3162,8 @@
 cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
 {
     cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
-    char                prefix[32];     // Prefix for each color name
-    char                suffix[32];     // Suffix for each color name
+    char                prefix[33];     // Prefix for each color name
+    char                suffix[33];     // Suffix for each color name
     int i, nColors;
 
     nColors = cmsNamedColorCount(NamedColorList);
@@ -3168,7 +3175,7 @@
     strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
     strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
 
-    suffix[31] = prefix[31] = 0;
+    suffix[32] = prefix[32] = 0;
 
     if (!io ->Write(io, 32, prefix)) return FALSE;
     if (!io ->Write(io, 32, suffix)) return FALSE;
@@ -3180,6 +3187,7 @@
        char Root[33];
 
         if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
+        Root[32] = 0;
         if (!io ->Write(io, 32 , Root)) return FALSE;
         if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
         if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE;
@@ -3630,7 +3638,7 @@
 
 
 
-// Auxiliar, read an string specified as count + string
+// Auxiliary, read an string specified as count + string
 static
 cmsBool  ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
 {
@@ -3879,7 +3887,7 @@
 static
 void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
 {
-   return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
+   return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions));
 
    cmsUNUSED_PARAMETER(n);
 }
@@ -4333,13 +4341,13 @@
 static
 cmsBool  Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
 {
-    cmsUInt8Number Dimensions8[16];
+    cmsUInt8Number Dimensions8[16];  // 16 because the spec says 16 and not max number of channels
     cmsUInt32Number i;
     cmsStage* mpe = (cmsStage*) Ptr;
     _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
 
-    // Check for maximum number of channels
-    if (mpe -> InputChannels > 15) return FALSE;
+    // Check for maximum number of channels supported by lcms
+    if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE;
 
     // Only floats are supported in MPE
     if (clut ->HasFloatValues == FALSE) return FALSE;
@@ -5477,8 +5485,9 @@
     { cmsSigScreeningTag,           { 1, 1, { cmsSigScreeningType},          NULL }, &SupportedTags[59]},
     { cmsSigVcgtTag,                { 1, 1, { cmsSigVcgtType},               NULL }, &SupportedTags[60]},
     { cmsSigMetaTag,                { 1, 1, { cmsSigDictType},               NULL }, &SupportedTags[61]},
-    { cmsSigProfileSequenceIdTag,   { 1, 1, { cmsSigProfileSequenceIdType},  NULL },  &SupportedTags[62]},
-    { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL}
+    { cmsSigProfileSequenceIdTag,   { 1, 1, { cmsSigProfileSequenceIdType},  NULL }, &SupportedTags[62]},
+    { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
+    { cmsSigArgyllArtsTag,          { 9, 1, { cmsSigS15Fixed16ArrayType},    NULL}, NULL}
 
 
 };
--- a/src/java.desktop/share/native/liblcms/cmsvirt.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsvirt.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -1167,15 +1167,20 @@
     // If no way, then force CLUT that for sure can be written
     if (AllowedLUT == NULL) {
 
+        cmsStage* FirstStage;
+        cmsStage* LastStage;
+
         dwFlags |= cmsFLAGS_FORCE_CLUT;
         _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
 
         // Put identity curves if needed
-        if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
+        FirstStage = cmsPipelineGetPtrToFirstStage(LUT);
+        if (FirstStage != NULL && FirstStage ->Type != cmsSigCurveSetElemType)
              if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
                  goto Error;
 
-        if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType)
+        LastStage = cmsPipelineGetPtrToLastStage(LUT);
+        if (LastStage != NULL && LastStage ->Type != cmsSigCurveSetElemType)
              if (!cmsPipelineInsertStage(LUT, cmsAT_END,   _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
                  goto Error;
 
--- a/src/java.desktop/share/native/liblcms/cmswtpnt.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmswtpnt.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -376,3 +376,5 @@
 
     return TRUE;
 }
+
+
--- a/src/java.desktop/share/native/liblcms/cmsxform.c	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -208,12 +208,18 @@
 
 {
     _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+    cmsStride stride;
 
-    p -> xform(p, InputBuffer, OutputBuffer, Size, Size);
+    stride.BytesPerLineIn = 0;  // Not used
+    stride.BytesPerLineOut = 0;
+    stride.BytesPerPlaneIn = Size;
+    stride.BytesPerPlaneOut = Size;
+
+    p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
 }
 
 
-// Apply transform.
+// This is a legacy stride for planar
 void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM  Transform,
                               const void* InputBuffer,
                               void* OutputBuffer,
@@ -221,10 +227,40 @@
 
 {
     _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+    cmsStride stride;
 
-    p -> xform(p, InputBuffer, OutputBuffer, Size, Stride);
+    stride.BytesPerLineIn = 0;
+    stride.BytesPerLineOut = 0;
+    stride.BytesPerPlaneIn = Stride;
+    stride.BytesPerPlaneOut = Stride;
+
+    p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
 }
 
+// This is the "fast" function for plugins
+void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM  Transform,
+                              const void* InputBuffer,
+                              void* OutputBuffer,
+                              cmsUInt32Number PixelsPerLine,
+                              cmsUInt32Number LineCount,
+                              cmsUInt32Number BytesPerLineIn,
+                              cmsUInt32Number BytesPerLineOut,
+                              cmsUInt32Number BytesPerPlaneIn,
+                              cmsUInt32Number BytesPerPlaneOut)
+
+{
+    _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+    cmsStride stride;
+
+    stride.BytesPerLineIn = BytesPerLineIn;
+    stride.BytesPerLineOut = BytesPerLineOut;
+    stride.BytesPerPlaneIn = BytesPerPlaneIn;
+    stride.BytesPerPlaneOut = BytesPerPlaneOut;
+
+    p->xform(p, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, &stride);
+}
+
+
 
 // Transform routines ----------------------------------------------------------------------------------------------------------
 
@@ -233,49 +269,64 @@
 static
 void FloatXFORM(_cmsTRANSFORM* p,
                 const void* in,
-                void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+                void* out,
+                cmsUInt32Number PixelsPerLine,
+                cmsUInt32Number LineCount,
+                const cmsStride* Stride)
 {
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
     cmsFloat32Number OutOfGamut;
-    cmsUInt32Number i, j;
+    cmsUInt32Number i, j, c, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-    for (i=0; i < Size; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum = p -> FromInputFloat(p, fIn, accum, Stride);
+    for (i = 0; i < LineCount; i++) {
 
-        // Any gamut chack to do?
-        if (p ->GamutCheck != NULL) {
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
 
-            // Evaluate gamut marker.
-            cmsPipelineEvalFloat( fIn, &OutOfGamut, p ->GamutCheck);
+        for (j = 0; j < PixelsPerLine; j++) {
 
-            // Is current color out of gamut?
-            if (OutOfGamut > 0.0) {
+            accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn);
 
-                // Certainly, out of gamut
-                for (j=0; j < cmsMAXCHANNELS; j++)
-                    fOut[j] = -1.0;
+            // Any gamut chack to do?
+            if (p->GamutCheck != NULL) {
 
+                // Evaluate gamut marker.
+                cmsPipelineEvalFloat(fIn, &OutOfGamut, p->GamutCheck);
+
+                // Is current color out of gamut?
+                if (OutOfGamut > 0.0) {
+
+                    // Certainly, out of gamut
+                    for (c = 0; c < cmsMAXCHANNELS; c++)
+                        fOut[c] = -1.0;
+
+                }
+                else {
+                    // No, proceed normally
+                    cmsPipelineEvalFloat(fIn, fOut, p->Lut);
+                }
             }
             else {
-                // No, proceed normally
-                cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+                // No gamut check at all
+                cmsPipelineEvalFloat(fIn, fOut, p->Lut);
             }
-        }
-        else {
 
-            // No gamut check at all
-            cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+            output = p->ToOutputFloat(p, fOut, output, Stride->BytesPerPlaneOut);
         }
 
-        // Back to asked representation
-        output = p -> ToOutputFloat(p, fOut, output, Stride);
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
     }
+
 }
 
 
@@ -283,22 +334,34 @@
 void NullFloatXFORM(_cmsTRANSFORM* p,
                     const void* in,
                     void* out,
-                    cmsUInt32Number Size,
-                    cmsUInt32Number Stride)
+                    cmsUInt32Number PixelsPerLine,
+                    cmsUInt32Number LineCount,
+                    const cmsStride* Stride)
+
 {
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsFloat32Number fIn[cmsMAXCHANNELS];
-    cmsUInt32Number i, n;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
-    n = Size;
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-    for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum  = p -> FromInputFloat(p, fIn, accum, Stride);
-        output = p -> ToOutputFloat(p, fIn, output, Stride);
+    for (i = 0; i < LineCount; i++) {
+
+           accum = (cmsUInt8Number*) in + strideIn;
+           output = (cmsUInt8Number*) out + strideOut;
+
+           for (j = 0; j < PixelsPerLine; j++) {
+
+                  accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn);
+                  output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut);
+           }
+
+           strideIn += Stride->BytesPerLineIn;
+           strideOut += Stride->BytesPerLineOut;
     }
 }
 
@@ -308,23 +371,36 @@
 static
 void NullXFORM(_cmsTRANSFORM* p,
                const void* in,
-               void* out, cmsUInt32Number Size,
-               cmsUInt32Number Stride)
+               void* out,
+               cmsUInt32Number PixelsPerLine,
+               cmsUInt32Number LineCount,
+               const cmsStride* Stride)
 {
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS];
-    cmsUInt32Number i, n;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
-    n = Size;                    // Buffer len
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-    for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum  = p -> FromInput(p, wIn, accum, Stride);
-        output = p -> ToOutput(p, wIn, output, Stride);
+    for (i = 0; i < LineCount; i++) {
+
+           accum = (cmsUInt8Number*)in + strideIn;
+           output = (cmsUInt8Number*)out + strideOut;
+
+           for (j = 0; j < PixelsPerLine; j++) {
+
+                  accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+                  output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
     }
+
+           strideIn += Stride->BytesPerLineIn;
+           strideOut += Stride->BytesPerLineOut;
+    }
+
 }
 
 
@@ -332,27 +408,41 @@
 static
 void PrecalculatedXFORM(_cmsTRANSFORM* p,
                         const void* in,
-                        void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+                        void* out,
+                        cmsUInt32Number PixelsPerLine,
+                        cmsUInt32Number LineCount,
+                        const cmsStride* Stride)
 {
     register cmsUInt8Number* accum;
     register cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-    cmsUInt32Number i, n;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
-    n = Size;
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-    for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum = p -> FromInput(p, wIn, accum, Stride);
-        p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
-        output = p -> ToOutput(p, wOut, output, Stride);
+    for (i = 0; i < LineCount; i++) {
+
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
+
+        for (j = 0; j < PixelsPerLine; j++) {
+
+            accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+            p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
+            output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+        }
+
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
     }
+
 }
 
 
-// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
+// Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
 static
 void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
                                      const cmsUInt16Number wIn[],
@@ -379,22 +469,35 @@
 static
 void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
                                   const void* in,
-                                  void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+                                  void* out,
+                                  cmsUInt32Number PixelsPerLine,
+                                  cmsUInt32Number LineCount,
+                                  const cmsStride* Stride)
 {
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-    cmsUInt32Number i, n;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
-    n = Size;                    // Buffer len
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-    for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum = p -> FromInput(p, wIn, accum, Stride);
-        TransformOnePixelWithGamutCheck(p, wIn, wOut);
-        output = p -> ToOutput(p, wOut, output, Stride);
+    for (i = 0; i < LineCount; i++) {
+
+           accum = (cmsUInt8Number*)in + strideIn;
+           output = (cmsUInt8Number*)out + strideOut;
+
+           for (j = 0; j < PixelsPerLine; j++) {
+
+                  accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+                  TransformOnePixelWithGamutCheck(p, wIn, wOut);
+                  output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+           }
+
+           strideIn += Stride->BytesPerLineIn;
+           strideOut += Stride->BytesPerLineOut;
     }
 }
 
@@ -403,94 +506,120 @@
 static
 void CachedXFORM(_cmsTRANSFORM* p,
                  const void* in,
-                 void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+                 void* out,
+                 cmsUInt32Number PixelsPerLine,
+                 cmsUInt32Number LineCount,
+                 const cmsStride* Stride)
 {
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-    cmsUInt32Number i, n;
     _cmsCACHE Cache;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-    accum  = (cmsUInt8Number*)  in;
-    output = (cmsUInt8Number*)  out;
-    n = Size;                    // Buffer len
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
     // Empty buffers for quick memcmp
-    memset(wIn,  0, sizeof(wIn));
+    memset(wIn, 0, sizeof(wIn));
     memset(wOut, 0, sizeof(wOut));
 
     // Get copy of zero cache
-    memcpy(&Cache, &p ->Cache, sizeof(Cache));
+    memcpy(&Cache, &p->Cache, sizeof(Cache));
 
-    for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-        accum = p -> FromInput(p, wIn, accum, Stride);
+    for (i = 0; i < LineCount; i++) {
 
-        if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
 
-            memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
-        }
-        else {
+        for (j = 0; j < PixelsPerLine; j++) {
 
-            p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
+            accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
 
-            memcpy(Cache.CacheIn,  wIn,  sizeof(Cache.CacheIn));
-            memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+            if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+
+                memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+            }
+            else {
+                p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
+
+                memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+                memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+            }
+
+            output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
         }
 
-        output = p -> ToOutput(p, wOut, output, Stride);
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
     }
-
 }
 
-
 // All those nice features together
 static
 void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
                            const void* in,
-                           void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+                           void* out,
+                           cmsUInt32Number PixelsPerLine,
+                           cmsUInt32Number LineCount,
+                           const cmsStride* Stride)
 {
-       cmsUInt8Number* accum;
-       cmsUInt8Number* output;
-       cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-       cmsUInt32Number i, n;
-       _cmsCACHE Cache;
+    cmsUInt8Number* accum;
+    cmsUInt8Number* output;
+    cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
+    _cmsCACHE Cache;
+    cmsUInt32Number i, j, strideIn, strideOut;
 
-       accum  = (cmsUInt8Number*)  in;
-       output = (cmsUInt8Number*)  out;
-       n = Size;                    // Buffer len
+    _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
-       // Empty buffers for quick memcmp
-       memset(wIn,  0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
-       memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
+    // Empty buffers for quick memcmp
+    memset(wIn, 0, sizeof(wIn));
+    memset(wOut, 0, sizeof(wOut));
 
-       // Get copy of zero cache
-       memcpy(&Cache, &p ->Cache, sizeof(Cache));
+    // Get copy of zero cache
+    memcpy(&Cache, &p->Cache, sizeof(Cache));
 
-       for (i=0; i < n; i++) {
+    strideIn = 0;
+    strideOut = 0;
 
-            accum = p -> FromInput(p, wIn, accum, Stride);
+    for (i = 0; i < LineCount; i++) {
+
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
+
+        for (j = 0; j < PixelsPerLine; j++) {
+
+            accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
 
             if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
-                    memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+
+                memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
             }
             else {
-                    TransformOnePixelWithGamutCheck(p, wIn, wOut);
-                    memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
-                    memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+                TransformOnePixelWithGamutCheck(p, wIn, wOut);
+
+                memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+                memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
             }
 
-            output = p -> ToOutput(p, wOut, output, Stride);
-       }
+            output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+        }
 
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
+    }
 }
 
-// -------------------------------------------------------------------------------------------------------------
+// Transform plug-ins ----------------------------------------------------------------------------------------------------
 
 // List of used-defined transform factories
 typedef struct _cmsTransformCollection_st {
 
-    _cmsTransformFactory  Factory;
+    _cmsTransform2Factory  Factory;
+    cmsBool                OldXform;   // Factory returns xform function in the old style
+
     struct _cmsTransformCollection_st *Next;
 
 } _cmsTransformCollection;
@@ -533,6 +662,7 @@
   ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
 }
 
+// Allocates memory for transform plugin factory
 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
                                         const struct _cmsContext_struct* src)
 {
@@ -547,6 +677,35 @@
     }
 }
 
+// Adaptor for old versions of plug-in
+static
+void _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo,
+                                      const void* InputBuffer,
+                                      void* OutputBuffer,
+                                      cmsUInt32Number PixelsPerLine,
+                                      cmsUInt32Number LineCount,
+                                      const cmsStride* Stride)
+{
+
+       cmsUInt32Number i, strideIn, strideOut;
+
+       _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride);
+
+       strideIn = 0;
+       strideOut = 0;
+
+       for (i = 0; i < LineCount; i++) {
+
+              void *accum = (cmsUInt8Number*)InputBuffer + strideIn;
+              void *output = (cmsUInt8Number*)OutputBuffer + strideOut;
+
+              CMMcargo->OldXform(CMMcargo, accum, output, PixelsPerLine, Stride->BytesPerPlaneIn);
+
+              strideIn += Stride->BytesPerLineIn;
+              strideOut += Stride->BytesPerLineOut;
+       }
+}
+
 
 
 // Register new ways to transform
@@ -564,14 +723,22 @@
     }
 
     // Factory callback is required
-    if (Plugin ->Factory == NULL) return FALSE;
+    if (Plugin->factories.xform == NULL) return FALSE;
 
 
     fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
     if (fl == NULL) return FALSE;
 
+    // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case
+    if (Plugin->base.ExpectedVersion < 2080) {
+
+           fl->OldXform = TRUE;
+    }
+    else
+           fl->OldXform = FALSE;
+
     // Copy the parameters
-    fl ->Factory = Plugin ->Factory;
+    fl->Factory = Plugin->factories.xform;
 
     // Keep linked list
     fl ->Next = ctx->TransformCollection;
@@ -656,6 +823,12 @@
                             p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
                             p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
 
+                            // Save the day?
+                            if (Plugin->OldXform) {
+                                   p->OldXform = (_cmsTransformFn) p->xform;
+                                   p->xform = _cmsTransform2toTransformAdaptor;
+                            }
+
                             return p;
                      }
               }
@@ -816,6 +989,22 @@
 
 // ----------------------------------------------------------------------------------------------------------------
 
+// Jun-21-2000: Some profiles (those that comes with W2K) comes
+// with the media white (media black?) x 100. Add a sanity check
+
+static
+void NormalizeXYZ(cmsCIEXYZ* Dest)
+{
+    while (Dest -> X > 2. &&
+           Dest -> Y > 2. &&
+           Dest -> Z > 2.) {
+
+               Dest -> X /= 10.;
+               Dest -> Y /= 10.;
+               Dest -> Z /= 10.;
+       }
+}
+
 static
 void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
 {
@@ -828,6 +1017,8 @@
         wtPt ->X = src->X;
         wtPt ->Y = src->Y;
         wtPt ->Z = src->Z;
+
+        NormalizeXYZ(wtPt);
     }
 
 }
@@ -1138,7 +1329,6 @@
                                          cmsUInt32Number InputFormat,
                                          cmsUInt32Number OutputFormat)
 {
-
     _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
     cmsFormatter16 FromInput, ToOutput;
 
--- a/src/java.desktop/share/native/liblcms/lcms2.h	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/lcms2.h	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.7
+// Version 2.8
 //
 
 #ifndef _lcms2_H
@@ -104,7 +104,7 @@
 #endif
 
 // Version/release
-#define LCMS_VERSION        2070
+#define LCMS_VERSION        2080
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -202,43 +202,44 @@
 #  define CMS_IS_WINDOWS_ 1
 #endif
 
-// Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
-// you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
+// Try to detect big endian platforms. This list can be endless, so primarily rely on the configure script
+// on Unix-like systems, and allow it to be set on the compiler command line using
+// -DCMS_USE_BIG_ENDIAN or something similar
+#ifdef CMS_USE_BIG_ENDIAN // set at compiler command line takes overall precedence
 
-#if defined(__sgi__) || defined(__sgi) || defined(sparc)
-#   define CMS_USE_BIG_ENDIAN      1
-#endif
+#  if CMS_USE_BIG_ENDIAN == 0
+#    undef CMS_USE_BIG_ENDIAN
+#  endif
 
-#if defined(__s390__) || defined(__s390x__)
-#   define CMS_USE_BIG_ENDIAN   1
-#endif
+#else // CMS_USE_BIG_ENDIAN
 
+#  ifdef WORDS_BIGENDIAN // set by configure (or explicitly on compiler command line)
+#    define CMS_USE_BIG_ENDIAN 1
+#  else // WORDS_BIGENDIAN
+// Fall back to platform/compiler specific tests
+#    if defined(__sgi__) || defined(__sgi) || defined(sparc)
+#      define CMS_USE_BIG_ENDIAN      1
+#    endif
 
-#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
-#  if __powerpc__ || __ppc__ || TARGET_CPU_PPC
-#   define CMS_USE_BIG_ENDIAN   1
-#   if defined (__GNUC__) && defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
-#       if __BYTE_ORDER__  == __ORDER_LITTLE_ENDIAN__
-                // Don't use big endian for PowerPC little endian mode
-#                undef CMS_USE_BIG_ENDIAN
-#       endif
-#     endif
-#   endif
-#endif
+#    if defined(__s390__) || defined(__s390x__)
+#      define CMS_USE_BIG_ENDIAN   1
+#    endif
 
-#ifdef macintosh
-# ifdef __BIG_ENDIAN__
-#   define CMS_USE_BIG_ENDIAN      1
-# endif
-# ifdef __LITTLE_ENDIAN__
-#   undef CMS_USE_BIG_ENDIAN
-# endif
-#endif
+#    ifdef macintosh
+#      ifdef __BIG_ENDIAN__
+#        define CMS_USE_BIG_ENDIAN      1
+#      endif
+#      ifdef __LITTLE_ENDIAN__
+#        undef CMS_USE_BIG_ENDIAN
+#      endif
+#    endif
+#  endif  // WORDS_BIGENDIAN
 
-// WORDS_BIGENDIAN takes precedence
-#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
-#   define CMS_USE_BIG_ENDIAN      1
-#endif
+#  if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
+#    define CMS_USE_BIG_ENDIAN      1
+#  endif
+
+#endif  // CMS_USE_BIG_ENDIAN
 
 
 // Calling convention -- this is hardly platform and compiler dependent
@@ -248,7 +249,7 @@
 #        define CMSEXPORT       __stdcall _export
 #        define CMSAPI
 #     else
-#        define CMSEXPORT      _stdcall
+#        define CMSEXPORT      __stdcall
 #        ifdef CMS_DLL_BUILD
 #            define CMSAPI    __declspec(dllexport)
 #        else
@@ -410,7 +411,8 @@
     cmsSigViewingCondDescTag                = 0x76756564,  // 'vued'
     cmsSigViewingConditionsTag              = 0x76696577,  // 'view'
     cmsSigVcgtTag                           = 0x76636774,  // 'vcgt'
-    cmsSigMetaTag                           = 0x6D657461   // 'meta'
+    cmsSigMetaTag                           = 0x6D657461,  // 'meta'
+    cmsSigArgyllArtsTag                     = 0x61727473   // 'arts'
 
 } cmsTagSignature;
 
@@ -683,7 +685,7 @@
 //            T: Pixeltype
 //            F: Flavor  0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
 //            P: Planar? 0=Chunky, 1=Planar
-//            X: swap 16 bps endianess?
+//            X: swap 16 bps endianness?
 //            S: Do swap? ie, BGR, KYMC
 //            E: Extra samples
 //            C: Channels (Samples per pixel)
@@ -926,7 +928,7 @@
 #define TYPE_ARGB_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1))
 #define TYPE_BGR_FLT          (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
 #define TYPE_BGRA_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
-#define TYPE_ABGR_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
+#define TYPE_ABGR_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
 
 #define TYPE_CMYK_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
 
@@ -1043,7 +1045,7 @@
 // Context handling --------------------------------------------------------------------------------------------------------
 
 // Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
-// though using the global context is not recomended. Proper context handling makes lcms more thread-safe.
+// though using the global context is not recommended. Proper context handling makes lcms more thread-safe.
 
 typedef struct _cmsContext_struct* cmsContext;
 
@@ -1412,7 +1414,7 @@
 typedef struct {
 
     cmsUInt32Number n;
-    cmsContext     ContextID;
+    cmsContext      ContextID;
     cmsPSEQDESC*    seq;
 
 } cmsSEQ;
@@ -1679,6 +1681,8 @@
 // Specific to unbounded mode
 #define cmsFLAGS_NONEGATIVES              0x8000    // Prevent negative numbers in floating point transforms
 
+// Copy alpha channels when transforming
+#define cmsFLAGS_COPY_ALPHA               0x04000000 // Alpha channels are copied on cmsDoTransform()
 
 // Fine-tune control over number of gridpoints
 #define cmsFLAGS_GRIDPOINTS(n)           (((n) & 0xFF) << 16)
@@ -1757,12 +1761,22 @@
                                                  void * OutputBuffer,
                                                  cmsUInt32Number Size);
 
-CMSAPI void             CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
+CMSAPI void             CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,   // Deprecated
                                                  const void * InputBuffer,
                                                  void * OutputBuffer,
                                                  cmsUInt32Number Size,
                                                  cmsUInt32Number Stride);
 
+CMSAPI void             CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM  Transform,
+                                                 const void* InputBuffer,
+                                                 void* OutputBuffer,
+                                                 cmsUInt32Number PixelsPerLine,
+                                                 cmsUInt32Number LineCount,
+                                                 cmsUInt32Number BytesPerLineIn,
+                                                 cmsUInt32Number BytesPerLineOut,
+                                                 cmsUInt32Number BytesPerPlaneIn,
+                                                 cmsUInt32Number BytesPerPlaneOut);
+
 
 CMSAPI void             CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
 CMSAPI void             CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2014 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -86,7 +86,15 @@
 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
 
 // Alignment to memory pointer
-#define _cmsALIGNMEM(x)  (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
+
+// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes
+// even though sizeof(void *) is only four: for greatest flexibility
+// allow the build to specify ptr alignment.
+#ifndef CMS_PTR_ALIGNMENT
+# define CMS_PTR_ALIGNMENT sizeof(void *)
+#endif
+
+#define _cmsALIGNMEM(x)  (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
 
 // Maximum encodeable values in floating point
 #define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0)
@@ -122,7 +130,7 @@
 
 // A fast way to convert from/to 16 <-> 8 bits
 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
-#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
+#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
 
 // Code analysis is broken on asserts
 #ifdef _MSC_VER
@@ -691,8 +699,8 @@
     cmsContext ContextID;
 
     // The directory
-    int AllocatedEntries;
-    int UsedEntries;
+    cmsUInt32Number  AllocatedEntries;
+    cmsUInt32Number  UsedEntries;
     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
 
     // The Pool
@@ -760,7 +768,7 @@
     // Dictionary
     cmsUInt32Number          TagCount;
     cmsTagSignature          TagNames[MAX_TABLE_TAG];
-    cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to wich is linked (0=none)
+    cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to which is linked (0=none)
     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
@@ -988,7 +996,7 @@
     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
 
     // Points to transform code
-    _cmsTransformFn xform;
+    _cmsTransform2Fn xform;
 
     // Formatters, cannot be embedded into LUT because cache
     cmsFormatter16 FromInput;
@@ -1034,9 +1042,20 @@
     void* UserData;
     _cmsFreeUserDataFn FreeUserData;
 
+    // A way to provide backwards compatibility with full xform plugins
+    _cmsTransformFn OldXform;
+
 } _cmsTRANSFORM;
 
-// --------------------------------------------------------------------------------------------------
+// Copies extra channels from input to output if the original flags in the transform structure
+// instructs to do so. This function is called on all standard transform functions.
+void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
+                             void* out,
+                             cmsUInt32Number PixelsPerLine,
+                             cmsUInt32Number LineCount,
+                             const cmsStride* Stride);
+
+// -----------------------------------------------------------------------------------------------------------------------
 
 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
                             cmsUInt32Number        nProfiles,
--- a/src/java.desktop/share/native/liblcms/lcms2_plugin.h	Tue Jul 26 11:30:40 2016 -0700
+++ b/src/java.desktop/share/native/liblcms/lcms2_plugin.h	Tue Jul 26 11:50:19 2016 -0700
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2016 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"),
@@ -157,7 +157,7 @@
                                                                    const void* Buffer);
 };
 
-// Endianess adjust functions
+// Endianness adjust functions
 CMSAPI cmsUInt16Number   CMSEXPORT  _cmsAdjustEndianess16(cmsUInt16Number Word);
 CMSAPI cmsUInt32Number   CMSEXPORT  _cmsAdjustEndianess32(cmsUInt32Number Value);
 CMSAPI void              CMSEXPORT  _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);
@@ -371,8 +371,8 @@
 
 typedef cmsUInt8Number* (* cmsFormatter16)(register struct _cmstransform_struct* CMMcargo,
                                            register cmsUInt16Number Values[],
-                                           register cmsUInt8Number*  Buffer,
-                                           register cmsUInt32Number  Stride);
+                                           register cmsUInt8Number* Buffer,
+                                           register cmsUInt32Number Stride);
 
 typedef cmsUInt8Number* (* cmsFormatterFloat)(struct _cmstransform_struct* CMMcargo,
                                               cmsFloat32Number Values[],
@@ -600,11 +600,28 @@
 
 //----------------------------------------------------------------------------------------------------------
 // Full xform
-typedef void     (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo,
+
+typedef struct {
+       cmsUInt32Number BytesPerLineIn;
+       cmsUInt32Number BytesPerLineOut;
+       cmsUInt32Number BytesPerPlaneIn;
+       cmsUInt32Number BytesPerPlaneOut;
+
+} cmsStride;
+
+typedef void     (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo,   // Legacy function, handles just ONE scanline.
                                      const void* InputBuffer,
                                      void* OutputBuffer,
                                      cmsUInt32Number Size,
-                                     cmsUInt32Number Stride);
+                                     cmsUInt32Number Stride);                 // Stride in bytes to the next plana in planar formats
+
+
+typedef void     (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo,
+                                     const void* InputBuffer,
+                                     void* OutputBuffer,
+                                     cmsUInt32Number PixelsPerLine,
+                                     cmsUInt32Number LineCount,
+                                     const cmsStride* Stride);
 
 typedef cmsBool  (* _cmsTransformFactory)(_cmsTransformFn* xform,
                                          void** UserData,
@@ -614,6 +631,14 @@
                                          cmsUInt32Number* OutputFormat,
                                          cmsUInt32Number* dwFlags);
 
+typedef cmsBool  (* _cmsTransform2Factory)(_cmsTransform2Fn* xform,
+                                         void** UserData,
+                                         _cmsFreeUserDataFn* FreePrivateDataFn,
+                                         cmsPipeline** Lut,
+                                         cmsUInt32Number* InputFormat,
+                                         cmsUInt32Number* OutputFormat,
+                                         cmsUInt32Number* dwFlags);
+
 
 // Retrieve user data as specified by the factory
 CMSAPI void   CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn);
@@ -628,7 +653,10 @@
       cmsPluginBase     base;
 
       // Transform entry point
-      _cmsTransformFactory  Factory;
+      union {
+             _cmsTransformFactory        legacy_xform;
+             _cmsTransform2Factory       xform;
+      } factories;
 
 }  cmsPluginTransform;