view patches/icedtea-lcms.patch @ 1769:1f049d6728a0

Forwardport Lillian's LCMS security fixes. 2009-04-06 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Add back missing LCMS patches. 2009-04-03 Lillian Angel <langel@redhat.com> * patches/icedtea-lcms.patch: Updated. Re-added _cmsModifyTag data patch, which is upstream in OpenJDK6, but is not available in the upstream lcms 1.18 sources. 2009-04-02 Lillian Angel <langel@redhat.com> * patches/icedtea-lcms.patch: Updated with most recent security fixes. 2009-03-24 Lillian Angel <langel@redhat.com> * patches/icedtea-lcms.patch: Reworked to patch lcms sources with most recent upstream version (1.18). 2009-03-21 Lillian Angel <langel@redhat.com> * patches/icedtea-lcms.patch: New patch. * Makefile.am (ICEDTEA_PATCHES): Added new patch to the list.
author Andrew John Hughes <ahughes@redhat.com>
date Tue, 07 Apr 2009 17:52:24 +0100
parents
children
line wrap: on
line source

diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c	2008-11-25 04:06:03.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -51,7 +51,7 @@
 
 
 
-// CIECAM 02 appearance model
+// CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
 
 #include "lcms.h"
 
@@ -196,6 +196,10 @@
             clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1;
         }
     }
+    
+    clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] + 
+        (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
+
     return clr;
 }
 
@@ -249,9 +253,6 @@
         clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp);
     }
 
-    clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
-        (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
-
     clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A),
         (pMod->c * pMod->z));
 
@@ -395,7 +396,7 @@
     LPcmsCIECAM02 lpMod;
 
 
-   if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) {
+   if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) {
         return (LCMSHANDLE) NULL;
     }
 
@@ -449,14 +450,19 @@
     lpMod -> z   = compute_z(lpMod);
     lpMod -> Nbb = computeNbb(lpMod);
     lpMod -> FL  = computeFL(lpMod);
+    
+    if (lpMod -> D == D_CALCULATE ||
+        lpMod -> D == D_CALCULATE_DISCOUNT) {
+
     lpMod -> D   = computeD(lpMod);
+    }
+    
     lpMod -> Ncb = lpMod -> Nbb;
 
     lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
     lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
     lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
     lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
-    lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod);
 
     return (LCMSHANDLE) lpMod;
 
@@ -465,7 +471,7 @@
 void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel)
 {
     LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
-    if (lpMod) free(lpMod);
+    if (lpMod) _cmsFree(lpMod);
 }
 
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c	2008-11-25 04:06:03.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -174,7 +174,7 @@
 LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel)
 {
     LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel;
-    if (lpMod) free(lpMod);
+    if (lpMod) _cmsFree(lpMod);
 }
 
 // Partial discounting for adaptation degree computation
@@ -331,7 +331,7 @@
     LPcmsCIECAM97s lpMod;
     VEC3 tmp;
 
-    if((lpMod = (LPcmsCIECAM97s) malloc(sizeof(cmsCIECAM97s))) == NULL) {
+    if((lpMod = (LPcmsCIECAM97s) _cmsMalloc(sizeof(cmsCIECAM97s))) == NULL) {
         return (LCMSHANDLE) NULL;
     }
 
@@ -449,7 +449,7 @@
 
     // RGB_subw = [MlamRigg][WP/YWp]
 #ifdef USE_CIECAM97s2
-    MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, (LPVEC3) &lpMod -> WP);
+    MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &lpMod -> WP);
 #else
     VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y);
     MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp);
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c	2008-11-25 04:06:03.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -65,22 +65,25 @@
 // Persistence
 LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName);
 LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
 
 // Properties
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
 LCMSAPI double          LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
-LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames);
+LCMSAPI const char*     LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp);
+LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, const char ***PropertyNames);
+LCMSAPI int             LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames);
 
 // Datasets
 
@@ -89,10 +92,10 @@
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col);
 LCMSAPI double          LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int col, int row);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, 
                                                 const char* Val);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, 
                                                 double Val);
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
@@ -100,15 +103,15 @@
 
 LCMSAPI double          LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
                                                 const char* cSample,
                                                 const char *Val);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
                                                 const char* cSample,
                                                 double Val);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
 LCMSAPI int             LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
 
 LCMSAPI void            LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter);
@@ -126,7 +129,7 @@
 // #define STRICT_CGATS  1
 
 #define MAXID       128     // Max lenght of identifier
-#define MAXSTR      255     // Max lenght of string
+#define MAXSTR      1024     // Max lenght of string
 #define MAXTABLES   255     // Max Number of tables in a single stream
 #define MAXINCLUDE   20     // Max number of nested includes
 
@@ -137,6 +140,9 @@
 
 #ifndef NON_WINDOWS
 #include <io.h>
+#define DIR_CHAR    '\\'
+#else
+#define DIR_CHAR    '/'
 #endif
 
 // Symbols
@@ -160,6 +166,7 @@
         SEND_DATA,
         SEND_DATA_FORMAT,
         SKEYWORD,
+        SDATA_FORMAT_ID,
         SINCLUDE
 
     } SYMBOL;
@@ -171,7 +178,8 @@
         WRITE_UNCOOKED,
         WRITE_STRINGIFY,
         WRITE_HEXADECIMAL,
-        WRITE_BINARY
+        WRITE_BINARY,
+        WRITE_PAIR
 
     } WRITEMODE;
 
@@ -181,6 +189,8 @@
 
         struct _KeyVal*  Next;
         char*            Keyword;       // Name of variable
+        struct _KeyVal*  NextSubkey;    // If key is a dictionary, points to the next item
+        char*            Subkey;        // If key is a dictionary, points to the subkey name
         char*            Value;         // Points to value
         WRITEMODE        WriteAs;       // How to write the value
 
@@ -220,7 +230,12 @@
 
     } TABLE, *LPTABLE;
 
+// File stream being parsed
 
+typedef struct _FileContext {
+        char           FileName[MAX_PATH];    // File name if being readed from file
+        FILE*          Stream;                // File stream or NULL if holded in memory
+    } FILECTX, *LPFILECTX;
 
 // This struct hold all information about an openened
 // IT8 handler. Only one dataset is allowed.
@@ -257,9 +272,9 @@
         char*          Source;                // Points to loc. being parsed
         int            lineno;                // line counter for error reporting
 
-        char           FileName[MAX_PATH];    // File name if being readed from file
-        FILE*          Stream[MAXINCLUDE];    // File stream or NULL if holded in memory
+        LPFILECTX      FileStack[MAXINCLUDE]; // Stack of files being parsed
         int            IncludeSP;             // Include Stack Pointer
+
         char*          MemoryBlock;           // The stream if holded in memory
 
         char           DoubleFormatter[MAXID];   // Printf-like 'double' formatter
@@ -298,6 +313,7 @@
         {".INCLUDE",            SINCLUDE},
         {"BEGIN_DATA",          SBEGIN_DATA },
         {"BEGIN_DATA_FORMAT",   SBEGIN_DATA_FORMAT },
+        {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID},
         {"END_DATA",            SEND_DATA},
         {"END_DATA_FORMAT",     SEND_DATA_FORMAT},
         {"KEYWORD",             SKEYWORD}
@@ -308,49 +324,94 @@
 
 // Predefined properties
 
-static const char* PredefinedProperties[] = {
+// A property
+typedef struct {
+        const char *id;
+        WRITEMODE as;
+    } PROPERTY;
 
-        "NUMBER_OF_FIELDS",    // Required - NUMBER OF FIELDS
-        "NUMBER_OF_SETS",      // Required - NUMBER OF SETS
-        "ORIGINATOR",          // Required - Identifies the specific system, organization or individual that created the data file.
-        "FILE_DESCRIPTOR",     // Required - Describes the purpose or contents of the data file.
-        "CREATED",             // Required - Indicates date of creation of the data file.
-        "DESCRIPTOR",          // Required  - Describes the purpose or contents of the data file.
-        "DIFFUSE_GEOMETRY",    // The diffuse geometry used. Allowed values are "sphere" or "opal".
-        "MANUFACTURER",
-        "MANUFACTURE",         // Some broken Fuji targets does store this value
-        "PROD_DATE",           // Identifies year and month of production of the target in the form yyyy:mm.
-        "SERIAL",              // Uniquely identifies individual physical target.
+static PROPERTY PredefinedProperties[] = {
 
-        "MATERIAL",            // Identifies the material on which the target was produced using a code
+        {"NUMBER_OF_FIELDS", WRITE_UNCOOKED},    // Required - NUMBER OF FIELDS
+        {"NUMBER_OF_SETS",   WRITE_UNCOOKED},    // Required - NUMBER OF SETS
+        {"ORIGINATOR",       WRITE_STRINGIFY},   // Required - Identifies the specific system, organization or individual that created the data file.
+        {"FILE_DESCRIPTOR",  WRITE_STRINGIFY},   // Required - Describes the purpose or contents of the data file.
+        {"CREATED",          WRITE_STRINGIFY},   // Required - Indicates date of creation of the data file.
+        {"DESCRIPTOR",       WRITE_STRINGIFY},   // Required  - Describes the purpose or contents of the data file.
+        {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY},   // The diffuse geometry used. Allowed values are "sphere" or "opal".
+        {"MANUFACTURER",     WRITE_STRINGIFY},
+        {"MANUFACTURE",      WRITE_STRINGIFY},   // Some broken Fuji targets does store this value
+        {"PROD_DATE",        WRITE_STRINGIFY},   // Identifies year and month of production of the target in the form yyyy:mm.
+        {"SERIAL",           WRITE_STRINGIFY},   // Uniquely identifies individual physical target.
+
+        {"MATERIAL",         WRITE_STRINGIFY},   // Identifies the material on which the target was produced using a code
                                // uniquely identifying th e material. This is intend ed to be used for IT8.7
                                // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
 
-        "INSTRUMENTATION",     // Used to report the specific instrumentation used (manufacturer and
+        {"INSTRUMENTATION",  WRITE_STRINGIFY},   // Used to report the specific instrumentation used (manufacturer and
                                // model number) to generate the data reported. This data will often
                                // provide more information about the particular data collected than an
                                // extensive list of specific details. This is particularly important for
                                // spectral data or data derived from spectrophotometry.
 
-        "MEASUREMENT_SOURCE",  // Illumination used for spectral measurements. This data helps provide
+        {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
                                // a guide to the potential for issues of paper fluorescence, etc.
 
-        "PRINT_CONDITIONS",    // Used to define the characteristics of the printed sheet being reported.
+        {"PRINT_CONDITIONS", WRITE_STRINGIFY},   // Used to define the characteristics of the printed sheet being reported.
                                // Where standard conditions have been defined (e.g., SWOP at nominal)
                                // named conditions may suffice. Otherwise, detailed information is
                                // needed.
 
-        "SAMPLE_BACKING",      // Identifies the backing material used behind the sample during
-                               // measurement. Allowed values are “black”, “white”, or "na".
+        {"SAMPLE_BACKING",   WRITE_STRINGIFY},   // Identifies the backing material used behind the sample during
+                               // measurement. Allowed values are “black”, “white”, or {"na".
+
+        {"CHISQ_DOF",        WRITE_STRINGIFY},   // Degrees of freedom associated with the Chi squared statistic
+
+//    new in recent specs:
+        {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated 
+                               // along with details of the geometry and the aperture size and shape. For example, 
+                               // for transmission measurements it is important to identify 0/diffuse, diffuse/0, 
+                               // opal or integrating sphere, etc. For reflection it is important to identify 0/45, 
+                               // 45/0, sphere (specular included or excluded), etc.
+
+       {"FILTER",            WRITE_STRINGIFY},   // Identifies the use of physical filter(s) during measurement. Typically used to 
+                               // denote the use of filters such as none, D65, Red, Green or Blue.
+
+       {"POLARIZATION",      WRITE_STRINGIFY},   // Identifies the use of a physical polarization filter during measurement. Allowed 
+                               // values are {"yes”, “white”, “none” or “na”.
+
+       {"WEIGHTING_FUNCTION", WRITE_PAIR},   // Indicates such functions as: the CIE standard observer functions used in the 
+                               // calculation of various data parameters (2 degree and 10 degree), CIE standard 
+                               // illuminant functions used in the calculation of various data parameters (e.g., D50,
+                               // D65, etc.), density status response, etc. If used there shall be at least one 
+                               // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute 
+                               // in the set shall be {"name" and shall identify the particular parameter used.
+                               // The second shall be {"value" and shall provide the value associated with that name. 
+                               // For ASCII data, a string containing the Name and Value attribute pairs shall follow 
+                               // the weighting function keyword. A semi-colon separates attribute pairs from each 
+                               // other and within the attribute the name and value are separated by a comma.
+
+       {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name 
+                               // of the calculation, parameter is the name of the parameter used in the calculation 
+                               // and value is the value of the parameter.
+
+       {"TARGET_TYPE",        WRITE_STRINGIFY},  // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
+
+       {"COLORANT",           WRITE_STRINGIFY},  // Identifies the colorant(s) used in creating the target.
 
-        "CHISQ_DOF"            // Degrees of freedom associated with the Chi squared statistic
+       {"TABLE_DESCRIPTOR",   WRITE_STRINGIFY},  // Describes the purpose or contents of a data table.
+
+       {"TABLE_NAME",         WRITE_STRINGIFY}   // Provides a short name for a data table.
 };
 
-#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(char *))
+#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
 
 
 // Predefined sample types on dataset
 static const char* PredefinedSampleID[] = {
+        "SAMPLE_ID",      // Identifies sample that data represents
+        "STRING",         // Identifies label, or other non-machine readable value. 
+                          // Value must begin and end with a " symbol
 
         "CMYK_C",         // Cyan component of CMYK data expressed as a percentage
         "CMYK_M",         // Magenta component of CMYK data expressed as a percentage
@@ -378,7 +439,7 @@
         "LAB_B",          // b* component of Lab data
         "LAB_C",          // C*ab component of Lab data
         "LAB_H",          // hab component of Lab data
-        "LAB_DE"          //  CIE dE
+        "LAB_DE",         //  CIE dE
         "LAB_DE_94",      //  CIE dE using CIE 94
         "LAB_DE_CMC",     //  dE using CMC
         "LAB_DE_2000",    // CIE dE using CIE DE 2000
@@ -388,7 +449,7 @@
         "STDEV_Y",        // Standard deviation of Y (tristimulus data)
         "STDEV_Z",        // Standard deviation of Z (tristimulus data)
         "STDEV_L",        // Standard deviation of L*
-        "STDEV_A"         // Standard deviation of a*
+        "STDEV_A",        // Standard deviation of a*
         "STDEV_B",        // Standard deviation of b*
         "STDEV_DE",       // Standard deviation of CIE dE
         "CHI_SQD_PAR"};   // The average of the standard deviations of L*, a* and b*. It is
@@ -397,57 +458,119 @@
 
 #define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
 
+//Forward declaration of some internal functions        
+static
+void* AllocChunk(LPIT8 it8, size_t size);
+
 // Checks if c is a separator
 static
-BOOL isseparator(int c)
+LCMSBOOL isseparator(int c)
 {
         return (c == ' ') || (c == '\t') || (c == '\r');
 }
 
 // Checks whatever if c is a valid identifier char
-
 static
-BOOL ismiddle(int c)
+LCMSBOOL ismiddle(int c)
 {
    return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
 }
 
 // Checks whatsever if c is a valid identifier middle char.
 static
-BOOL isidchar(int c)
+LCMSBOOL isidchar(int c)
 {
    return isalnum(c) || ismiddle(c);
 }
 
 // Checks whatsever if c is a valid identifier first char.
 static
-BOOL isfirstidchar(int c)
+LCMSBOOL isfirstidchar(int c)
 {
      return !isdigit(c) && ismiddle(c);
 }
 
+// checks whether the supplied path looks like an absolute path
+// NOTE: this function doesn't checks if the path exists or even if it's legal
+static
+LCMSBOOL isabsolutepath(const char *path)
+{
+    if(path == NULL)
+        return FALSE;
+
+    if(path[0] == DIR_CHAR)
+        return TRUE;
+
+#ifndef NON_WINDOWS
+    if(isalpha(path[0]) && path[1] == ':')
+        return TRUE;
+#endif
+    return FALSE;
+}
+
+// Makes a file path based on a given reference path
+// NOTE: buffer is assumed to point to at least MAX_PATH bytes
+// NOTE: both relPath and basePath are assumed to be no more than MAX_PATH characters long (including the null terminator!)
+// NOTE: this function doesn't check if the path exists or even if it's legal
+static
+LCMSBOOL _cmsMakePath(const char *relPath, const char *basePath, char *buffer)
+{
+    if (!isabsolutepath(relPath)) {
+
+        char *tail;
+        
+        strncpy(buffer, basePath, MAX_PATH-1);
+        tail = strrchr(buffer, DIR_CHAR);
+        if (tail != NULL) {
+
+            size_t len = tail - buffer;
+            strncpy(tail + 1, relPath, MAX_PATH - len -1);
+            //  TODO: if combined path is longer than MAX_PATH, this should return FALSE!
+            return TRUE;
+        }
+    }
+    strncpy(buffer, relPath, MAX_PATH - 1);
+    return TRUE;
+}
+
+
+// Make sure no exploit is being even tried
+
+static
+const char* NoMeta(const char* str)
+{
+    if (strchr(str, '%') != NULL) 
+        return "**** CORRUPTED FORMAT STRING ***";
+
+    return str;
+}
+
 
+// Syntax error
 static
-BOOL SynError(LPIT8 it8, const char *Txt, ...)
+LCMSBOOL SynError(LPIT8 it8, const char *Txt, ...)
 {
         char Buffer[256], ErrMsg[1024];
         va_list args;
 
         va_start(args, Txt);
-        vsprintf(Buffer, Txt, args);
+        vsnprintf(Buffer, 255, Txt, args);
+        Buffer[255] = 0;
         va_end(args);
 
-        sprintf(ErrMsg, "%s: Line %d, %s", it8->FileName, it8->lineno, Buffer);
+        snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer);
+        ErrMsg[1023] = 0;
         it8->sy = SSYNERROR;
-        cmsSignalError(LCMS_ERRC_ABORTED, ErrMsg);
+        cmsSignalError(LCMS_ERRC_ABORTED, "%s", ErrMsg);
         return FALSE;
 }
 
+// Check if current symbol is same as specified. issue an error else.
 static
-BOOL Check(LPIT8 it8, SYMBOL sy, const char* Err)
+LCMSBOOL Check(LPIT8 it8, SYMBOL sy, const char* Err)
 {
         if (it8 -> sy != sy)
-                return SynError(it8, Err);
+                return SynError(it8, NoMeta(Err));
         return TRUE;
 }
 
@@ -457,15 +580,15 @@
 static
 void NextCh(LPIT8 it8)
 {
-    if (it8 -> Stream[it8 ->IncludeSP]) {
+    if (it8 -> FileStack[it8 ->IncludeSP]->Stream) {
 
-        it8 ->ch = fgetc(it8 ->Stream[it8 ->IncludeSP]);
+        it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream);
 
-        if (feof(it8 -> Stream[it8 ->IncludeSP]))  {
+        if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream))  {
 
             if (it8 ->IncludeSP > 0) {
 
-                fclose(it8 ->Stream[it8->IncludeSP--]);
+                fclose(it8 ->FileStack[it8->IncludeSP--]->Stream);
                 it8 -> ch = ' ';                            // Whitespace to be ignored
 
             } else
@@ -799,18 +922,39 @@
 
     if (it8 -> sy == SINCLUDE) {
 
-                FILE* IncludeFile;
+                LPFILECTX FileNest;
+
+                if(it8 -> IncludeSP >= (MAXINCLUDE-1))
+                {
+                    SynError(it8, "Too many recursion levels");
+                    return;
+                }
 
                 InSymbol(it8);
                 if (!Check(it8, SSTRING, "Filename expected")) return;
-                IncludeFile = fopen(it8 -> str, "rt");
-                if (IncludeFile == NULL) {
 
-                        SynError(it8, "File %s not found", it8 ->str);
+                FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
+                if(FileNest == NULL)
+                {
+                    FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX));
+                    //if(FileNest == NULL)
+                        //  TODO: how to manage out-of-memory conditions?
+                }
+
+                if(_cmsMakePath(it8->str, it8->FileStack[it8->IncludeSP]->FileName, FileNest->FileName) == FALSE)
+                {
+                    SynError(it8, "File path too long");
                         return;
                 }
 
-                it8 -> Stream[++it8 -> IncludeSP] = IncludeFile;
+                FileNest->Stream = fopen(FileNest->FileName, "rt");
+                if (FileNest->Stream == NULL) {
+
+                        SynError(it8, "File %s not found", FileNest->FileName);
+                        return;
+                }
+                it8->IncludeSP++;
+
                 it8 ->ch = ' ';
                 InSymbol(it8);
     }
@@ -819,7 +963,7 @@
 
 // Checks end of line separator
 static
-BOOL CheckEOLN(LPIT8 it8)
+LCMSBOOL CheckEOLN(LPIT8 it8)
 {
         if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
         while (it8 -> sy == SEOLN)
@@ -850,20 +994,21 @@
 
 // Returns a string holding current value
 static
-BOOL GetVal(LPIT8 it8, char* Buffer, const char* ErrorTitle)
+LCMSBOOL GetVal(LPIT8 it8, char* Buffer, size_t max, const char* ErrorTitle)
 {
     switch (it8->sy) {
 
-    case SIDENT:  strncpy(Buffer, it8->id, MAXID-1); break;
-    case SINUM:   sprintf(Buffer, "%d", it8 -> inum); break;
-    case SDNUM:   sprintf(Buffer, it8->DoubleFormatter, it8 -> dnum); break;
-    case SSTRING: strncpy(Buffer, it8->str, MAXSTR-1); break;
+    case SIDENT:  strncpy(Buffer, it8->id, max); break;
+    case SINUM:   snprintf(Buffer, max, "%d", it8 -> inum); break;
+    case SDNUM:   snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break;
+    case SSTRING: strncpy(Buffer, it8->str, max); break;
 
 
     default:
-         return SynError(it8, ErrorTitle);
+         return SynError(it8, "%s", ErrorTitle);
     }
 
+    Buffer[max] = 0;
      return TRUE;
 }
 
@@ -872,6 +1017,12 @@
 static
 LPTABLE GetTable(LPIT8 it8)
 {
+   if ((it8 -> nTable >= it8 ->TablesCount) || (it8 -> nTable < 0)) {
+
+           SynError(it8, "Table %d out of sequence", it8 -> nTable);
+           return it8 -> Tab;
+   }            
+
     return it8 ->Tab + it8 ->nTable;
 }
 
@@ -896,15 +1047,15 @@
         for (p = it8->MemorySink; p != NULL; p = n) {
 
             n = p->Next;
-            if (p->Ptr) free(p->Ptr);
-            free(p);
+            if (p->Ptr) _cmsFree(p->Ptr);
+            _cmsFree(p);
         }
     }
 
     if (it8->MemoryBlock)
-        free(it8->MemoryBlock);
+        _cmsFree(it8->MemoryBlock);    
 
-    free(it8);
+     _cmsFree(it8);
 }
 
 
@@ -913,16 +1064,16 @@
 void* AllocBigBlock(LPIT8 it8, size_t size)
 {
    LPOWNEDMEM ptr1;
-   void* ptr = malloc(size);
+   void* ptr = _cmsMalloc(size);
 
         if (ptr) {
 
                 ZeroMemory(ptr, size);
-                ptr1 = (LPOWNEDMEM) malloc(sizeof(OWNEDMEM));
+                ptr1 = (LPOWNEDMEM) _cmsMalloc(sizeof(OWNEDMEM));
 
                 if (ptr1 == NULL) {
 
-                    free(ptr);
+                     _cmsFree(ptr);
                     return NULL;
                 }
 
@@ -986,8 +1137,9 @@
 // Searches through linked list
 
 static
-BOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, LPKEYVALUE* LastPtr)
+LCMSBOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, const char* Subkey, LPKEYVALUE* LastPtr)
 {
+    if (LastPtr) *LastPtr = p;
 
     for (;  p != NULL; p = p->Next) {
 
@@ -996,10 +1148,24 @@
         if (*Key != '#') { // Comments are ignored
 
             if (stricmp(Key, p->Keyword) == 0)
-                    return TRUE;
+                    break;
         }
     }
 
+    if (p == NULL)
+        return FALSE;
+
+    if (Subkey == 0)
+        return TRUE;
+
+    for (; p != NULL; p = p->NextSubkey) {
+
+        if (LastPtr) *LastPtr = p;
+
+        if (stricmp(Subkey, p->Subkey) == 0)
+            return TRUE;
+    }
+
     return FALSE;
 }
 
@@ -1007,66 +1173,77 @@
 
 // Add a property into a linked list
 static
-BOOL AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char* xValue, WRITEMODE WriteAs)
+LPKEYVALUE AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
 {
     LPKEYVALUE p;
-    LPKEYVALUE last;
-
 
     // Check if property is already in list (this is an error)
 
-    if (IsAvailableOnList(*Head, Key, &last)) {
+    if (IsAvailableOnList(*Head, Key, Subkey, &p)) {
 
                         // This may work for editing properties
 
-                         last->Value   = AllocString(it8, xValue);
-                         last->WriteAs = WriteAs;
-                         return TRUE;
-
              // return SynError(it8, "duplicate key <%s>", Key);
     }
+    else {
+        LPKEYVALUE last = p;
 
         // Allocate the container
     p = (LPKEYVALUE) AllocChunk(it8, sizeof(KEYVALUE));
     if (p == NULL)
     {
-        return SynError(it8, "AddToList: out of memory");
+            SynError(it8, "AddToList: out of memory");
+            return NULL;
     }
 
     // Store name and value
     p->Keyword = AllocString(it8, Key);
+        p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey);
 
-    if (xValue != NULL) {
+        // Keep the container in our list
+        if (*Head == NULL)
+            *Head = p;
+        else
+        {
+            if(Subkey != 0 && last != 0) {
+                last->NextSubkey = p;
 
-        p->Value   = AllocString(it8, xValue);
+                // If Subkey is not null, then last is the last property with the same key,
+                // but not necessarily is the last property in the list, so we need to move
+                // to the actual list end
+                while(last->Next != 0) 
+                    last = last->Next;
     }
-    else {
-        p->Value   = NULL;
+            last->Next = p;
     }
 
     p->Next    = NULL;
+        p->NextSubkey = NULL;
+    }
+
     p->WriteAs = WriteAs;
+    if (xValue != NULL) {
 
-    // Keep the container in our list
-    if (*Head == NULL)
-        *Head = p;
-    else
-        last->Next = p;
+        p->Value   = AllocString(it8, xValue);
+    }
+    else {
+        p->Value   = NULL;
+    }
 
-    return TRUE;
+    return p;
 }
 
 static
-BOOL AddAvailableProperty(LPIT8 it8, const char* Key)
+LPKEYVALUE AddAvailableProperty(LPIT8 it8, const char* Key, WRITEMODE as)
 {
-        return AddToList(it8, &it8->ValidKeywords, Key, NULL, WRITE_UNCOOKED);
+        return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as);
 }
 
 
 static
-BOOL AddAvailableSampleID(LPIT8 it8, const char* Key)
+LPKEYVALUE AddAvailableSampleID(LPIT8 it8, const char* Key)
 {
-        return AddToList(it8, &it8->ValidSampleID, Key, NULL, WRITE_UNCOOKED);
+        return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
 }
 
 
@@ -1122,8 +1299,6 @@
     AllocTable(it8);
 
     it8->MemoryBlock = NULL;
-    it8->Stream[0]   = NULL;
-    it8->IncludeSP   = 0;
     it8->MemorySink  = NULL;
 
     it8 ->nTable = 0;
@@ -1141,6 +1316,8 @@
     it8 -> inum = 0;
     it8 -> dnum = 0.0;
 
+    it8->FileStack[0] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX));
+    it8->IncludeSP   = 0;
     it8 -> lineno = 1;
 
     strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
@@ -1149,7 +1326,7 @@
     // Initialize predefined properties & data
 
     for (i=0; i < NUMPREDEFINEDPROPS; i++)
-            AddAvailableProperty(it8, PredefinedProperties[i]);
+            AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as);
 
     for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
             AddAvailableSampleID(it8, PredefinedSampleID[i]);
@@ -1167,7 +1344,7 @@
 
 }
 
-BOOL  LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type)
+LCMSBOOL  LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type)
 {
         LPIT8 it8 = (LPIT8) hIT8;
 
@@ -1175,57 +1352,63 @@
         return TRUE;
 }
 
-BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
 
     if (!Val) return FALSE;
     if (!*Val) return FALSE;
 
-    return AddToList(it8, &GetTable(it8)->HeaderList, "# ", Val, WRITE_UNCOOKED);
+    return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
 }
 
 
 
 // Sets a property
-BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
 
     if (!Val) return FALSE;
     if (!*Val) return FALSE;
 
-    return AddToList(it8, &GetTable(it8)->HeaderList, Key, Val, WRITE_STRINGIFY);
+    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
 }
 
 
-BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
     char Buffer[1024];
 
     sprintf(Buffer, it8->DoubleFormatter, Val);
 
-    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_UNCOOKED);
+    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;    
 }
 
-BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
     char Buffer[1024];
 
     sprintf(Buffer, "%d", Val);
 
-    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_HEXADECIMAL);
+    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;    
 }
 
-BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer)
+LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer)
 {
     LPIT8 it8 = (LPIT8) hIT8;
 
-    return AddToList(it8, &GetTable(it8)->HeaderList, Key, Buffer, WRITE_UNCOOKED);
+    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL;
 }
 
+LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer)
+{
+    LPIT8 it8 = (LPIT8) hIT8;
+
+    return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL;
+}
 
 // Gets a property
 const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* Key)
@@ -1233,7 +1416,7 @@
     LPIT8 it8 = (LPIT8) hIT8;
     LPKEYVALUE p;
 
-    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, &p))
+    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p))
     {
         return p -> Value;
     }
@@ -1249,6 +1432,18 @@
     else return 0.0;
 }
 
+const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char *SubKey)
+{
+    LPIT8 it8 = (LPIT8) hIT8;
+    LPKEYVALUE p;
+
+    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p))
+    {
+        return p -> Value;
+    }
+    return NULL;
+}
+
 // ----------------------------------------------------------------- Datasets
 
 
@@ -1287,10 +1482,17 @@
 }
 
 static
-BOOL SetDataFormat(LPIT8 it8, int n, const char *label)
+LCMSBOOL SetDataFormat(LPIT8 it8, int n, const char *label)
 {
     LPTABLE t = GetTable(it8);
 
+#ifdef  STRICT_CGATS
+    if (!IsAvailableOnList(it8-> ValidSampleID, label, NULL, NULL)) {
+        SynError(it8, "Invalid data format '%s'.", label);
+        return FALSE;
+    }
+#endif
+
     if (!t->DataFormat)
         AllocateDataFormat(it8);
 
@@ -1308,7 +1510,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample)
+LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample)
 {
         LPIT8 it8 = (LPIT8) h;
         return SetDataFormat(it8, n, Sample);
@@ -1348,7 +1550,7 @@
 }
 
 static
-BOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val)
+LCMSBOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val)
 {
     LPTABLE t = GetTable(it8);
 
@@ -1418,7 +1620,8 @@
 }
 
 
-//
+// Write formatted
+
 static
 void Writef(LPSAVESTREAM f, const char* frm, ...)
 {
@@ -1426,7 +1629,8 @@
     va_list args;
 
     va_start(args, frm);
-    vsprintf(Buffer, frm, args);
+    vsnprintf(Buffer, 4095, frm, args);
+    Buffer[4095] = 0;
     WriteStr(f, Buffer);
     va_end(args);
 
@@ -1462,7 +1666,7 @@
         }
 
 
-        if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL)) {
+        if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) {
 
 #ifdef STRICT_CGATS
             WriteStr(fp, "KEYWORD\t\"");
@@ -1470,7 +1674,7 @@
             WriteStr(fp, "\"\n");
 #endif
 
-            AddAvailableProperty(it8, p->Keyword);
+            AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED);
 
         }
 
@@ -1495,6 +1699,10 @@
                     Writef(fp, "\t0x%B", atoi(p ->Value));
                     break;
 
+            case WRITE_PAIR:
+                    Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value);
+                    break;
+
             default: SynError(it8, "Unknown write mode %d", p ->WriteAs);
                      return;
             }
@@ -1573,7 +1781,7 @@
 
 
 // Saves whole file
-BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName)
+LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName)
 {
     SAVESTREAM sd;
     int i;
@@ -1601,7 +1809,7 @@
 
 
 // Saves to memory
-BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded)
+LCMSBOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded)
 {
     SAVESTREAM sd;
     int i;
@@ -1644,7 +1852,7 @@
 // -------------------------------------------------------------- Higer level parsing
 
 static
-BOOL DataFormatSection(LPIT8 it8)
+LCMSBOOL DataFormatSection(LPIT8 it8)
 {
     int iField = 0;
     LPTABLE t = GetTable(it8);
@@ -1685,16 +1893,19 @@
 
 
 static
-BOOL DataSection (LPIT8 it8)
+LCMSBOOL DataSection (LPIT8 it8)
 {
     int  iField = 0;
     int  iSet   = 0;
-    char Buffer[256];
+    char Buffer[MAXSTR];
     LPTABLE t = GetTable(it8);
 
     InSymbol(it8);   // Eats "BEGIN_DATA"
     CheckEOLN(it8);
 
+    if (!t->Data)
+        AllocateDataSet(it8);
+
     while (it8->sy != SEND_DATA && it8->sy != SEOF)
     {
         if (iField >= t -> nSamples) {
@@ -1705,7 +1916,7 @@
 
         if (it8->sy != SEND_DATA && it8->sy != SEOF) {
 
-            if (!GetVal(it8, Buffer, "Sample data expected"))
+            if (!GetVal(it8, Buffer, 255, "Sample data expected"))
                 return FALSE;
 
             if (!SetData(it8, iSet, iField, Buffer))
@@ -1734,10 +1945,11 @@
 
 
 static
-BOOL HeaderSection(LPIT8 it8)
+LCMSBOOL HeaderSection(LPIT8 it8)
 {
     char VarName[MAXID];
     char Buffer[MAXSTR];
+    LPKEYVALUE Key;
 
         while (it8->sy != SEOF &&
                it8->sy != SSYNERROR &&
@@ -1749,8 +1961,16 @@
 
         case SKEYWORD:
                 InSymbol(it8);
-                if (!GetVal(it8, Buffer, "Keyword expected")) return FALSE;
-                if (!AddAvailableProperty(it8, Buffer)) return FALSE;
+                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;                
+                if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE;
+                InSymbol(it8);
+                break;
+
+
+        case SDATA_FORMAT_ID:
+                InSymbol(it8);
+                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;                
+                if (!AddAvailableSampleID(it8, Buffer)) return FALSE;
                 InSymbol(it8);
                 break;
 
@@ -1758,21 +1978,61 @@
         case SIDENT:
                 strncpy(VarName, it8->id, MAXID-1);
 
-                if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL)) {
+                if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
 
 #ifdef STRICT_CGATS
                  return SynError(it8, "Undefined keyword '%s'", VarName);
 #else
-                if (!AddAvailableProperty(it8, VarName)) return FALSE;
+                    Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
+                    if (Key == NULL) return FALSE;
 #endif
                 }
 
                 InSymbol(it8);
-                if (!GetVal(it8, Buffer, "Property data expected")) return FALSE;
-
+                if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
 
-                AddToList(it8, &GetTable(it8)->HeaderList, VarName, Buffer,
+                if(Key->WriteAs != WRITE_PAIR) {
+                    AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, 
                                                                 (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
+                }
+                else {
+                    const char *Subkey;
+                    char *Nextkey;
+                    if (it8->sy != SSTRING)
+                        return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
+
+                    // chop the string as a list of "subkey, value" pairs, using ';' as a separator
+                    for(Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
+                    {
+                        char *Value, *temp;
+
+                        //  identify token pair boundary
+                        Nextkey = (char*) strchr(Subkey, ';');
+                        if(Nextkey)
+                            *Nextkey++ = '\0';
+
+                        // for each pair, split the subkey and the value
+                        Value = (char*) strrchr(Subkey, ',');
+                        if(Value == NULL)
+                            return SynError(it8, "Invalid value for property '%s'.", VarName);
+
+                        // gobble the spaces before the coma, and the coma itself
+                        temp = Value++;
+                        do *temp-- = '\0'; while(temp >= Subkey && *temp == ' ');
+
+                        // gobble any space at the right
+                        temp = Value + strlen(Value) - 1;
+                        while(*temp == ' ') *temp-- = '\0'; 
+
+                        // trim the strings from the left
+                        Subkey += strspn(Subkey, " ");
+                        Value += strspn(Value, " ");
+
+                        if(Subkey[0] == 0 || Value[0] == 0)
+                            return SynError(it8, "Invalid value for property '%s'.", VarName);
+                        AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
+                    }
+                }
 
                 InSymbol(it8);
                 break;
@@ -1793,22 +2053,23 @@
 
 
 static
-BOOL ParseIT8(LPIT8 it8)
+LCMSBOOL ParseIT8(LPIT8 it8, LCMSBOOL nosheet)
 {
-    char* SheetTypePtr;
+    char* SheetTypePtr = it8 ->SheetType;
+
+    if (nosheet == 0) {
 
     // First line is a very special case.
 
     while (isseparator(it8->ch))
             NextCh(it8);
 
-    SheetTypePtr = it8 ->SheetType;
-
     while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
 
         *SheetTypePtr++= (char) it8 ->ch;
         NextCh(it8);
     }
+    }
 
     *SheetTypePtr = 0;
     InSymbol(it8);
@@ -1869,6 +2130,12 @@
 
     for (idField = 0; idField < t -> nSamples; idField++)
     {
+        if (t ->DataFormat == NULL) {
+             SynError(it8, "Undefined DATA_FORMAT");
+             return;
+
+        }
+
         Fld = t->DataFormat[idField];
         if (!Fld) continue;
 
@@ -1916,7 +2183,7 @@
                                     LPTABLE Table = it8 ->Tab + k;
                                     LPKEYVALUE p;
 
-                                    if (IsAvailableOnList(Table->HeaderList, Label, &p)) {
+                                    if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
 
                                         // Available, keep type and table
                                         char Buffer[256];
@@ -1924,7 +2191,7 @@
                                         char *Type  = p ->Value;
                                         int  nTable = k;
 
-                                        sprintf(Buffer, "%s %d %s", Label, nTable, Type );
+                                        snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type );
 
                                         SetData(it8, i, idField, Buffer);
                                     }
@@ -1948,8 +2215,9 @@
 // that should be something like some printable characters plus a \n
 
 static
-BOOL IsMyBlock(LPBYTE Buffer, size_t n)
+int IsMyBlock(LPBYTE Buffer, size_t n)
 {
+    int cols = 1, space = 0, quot = 0;
     size_t i;
 
     if (n < 10) return FALSE;   // Too small
@@ -1959,9 +2227,26 @@
 
     for (i = 1; i < n; i++) {
 
-        if (Buffer[i] == '\n' || Buffer[i] == '\r' || Buffer[i] == '\t') return TRUE;
-        if (Buffer[i] < 32) return FALSE;
-
+        switch(Buffer[i])
+        {
+        case '\n':
+        case '\r':
+            return quot == 1 || cols > 2 ? 0 : cols;
+        case '\t':
+        case ' ':
+            if(!quot && !space)
+                space = 1;
+            break;
+        case '\"':
+            quot = !quot;
+            break;
+        default:
+            if (Buffer[i] < 32) return 0;
+            if (Buffer[i] > 127) return 0;
+            cols += space;
+            space = 0;
+            break;
+        }
     }
 
     return FALSE;
@@ -1970,7 +2255,7 @@
 
 
 static
-BOOL IsMyFile(const char* FileName)
+int IsMyFile(const char* FileName)
 {
    FILE *fp;
    size_t Size;
@@ -1998,21 +2283,22 @@
     LCMSHANDLE hIT8;
     LPIT8  it8;
 
-    if (!IsMyBlock((LPBYTE) Ptr, len)) return NULL;
+    int type = IsMyBlock((LPBYTE) Ptr, len);
+    if (type == 0) return NULL;
 
     hIT8 = cmsIT8Alloc();
     if (!hIT8) return NULL;
 
     it8 = (LPIT8) hIT8;
-    it8 ->MemoryBlock = (char*) malloc(len + 1);
+    it8 ->MemoryBlock = (char*) _cmsMalloc(len + 1);
 
     strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
     it8 ->MemoryBlock[len] = 0;
 
-    strncpy(it8->FileName, "", MAX_PATH-1);
+    strncpy(it8->FileStack[0]->FileName, "", MAX_PATH-1);
     it8-> Source = it8 -> MemoryBlock;
 
-    if (!ParseIT8(it8)) {
+    if (!ParseIT8(it8, type-1)) { 
 
         cmsIT8Free(hIT8);
         return FALSE;
@@ -2021,7 +2307,7 @@
     CookPointers(it8);
     it8 ->nTable = 0;
 
-    free(it8->MemoryBlock);
+     _cmsFree(it8->MemoryBlock);
     it8 -> MemoryBlock = NULL;
 
     return hIT8;
@@ -2036,26 +2322,27 @@
      LCMSHANDLE hIT8;
      LPIT8  it8;
 
-     if (!IsMyFile(cFileName)) return NULL;
+     int type = IsMyFile(cFileName);
+     if (type == 0) return NULL;
 
      hIT8 = cmsIT8Alloc();
      it8 = (LPIT8) hIT8;
      if (!hIT8) return NULL;
 
 
-     it8 ->Stream[0] = fopen(cFileName, "rt");
+     it8 ->FileStack[0]->Stream = fopen(cFileName, "rt");
 
-     if (!it8 ->Stream[0]) {
+     if (!it8 ->FileStack[0]->Stream) {         
          cmsIT8Free(hIT8);
          return NULL;
      }
 
 
-    strncpy(it8->FileName, cFileName, MAX_PATH-1);
+    strncpy(it8->FileStack[0]->FileName, cFileName, MAX_PATH-1);    
 
-    if (!ParseIT8(it8)) {
+    if (!ParseIT8(it8, type-1)) { 
 
-            fclose(it8 ->Stream[0]);
+            fclose(it8 ->FileStack[0]->Stream);
             cmsIT8Free(hIT8);
             return NULL;
     }
@@ -2063,7 +2350,7 @@
     CookPointers(it8);
     it8 ->nTable = 0;
 
-    fclose(it8 ->Stream[0]);
+    fclose(it8 ->FileStack[0]->Stream);    
     return hIT8;
 
 }
@@ -2078,12 +2365,12 @@
 }
 
 
-int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, char ***PropertyNames)
+int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames)
 {
     LPIT8 it8 = (LPIT8) hIT8;
     LPKEYVALUE p;
     int n;
-    char **Props;
+    const char **Props;
     LPTABLE t = GetTable(it8);
 
     // Pass#1 - count properties
@@ -2094,7 +2381,7 @@
     }
 
 
-    Props = (char **) AllocChunk(it8, sizeof(char *) * n);
+    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
 
     // Pass#2 - Fill pointers
     n = 0;
@@ -2106,6 +2393,41 @@
     return n;
 }
 
+int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char ***SubpropertyNames)
+{
+    LPIT8 it8 = (LPIT8) hIT8;
+    LPKEYVALUE p, tmp;
+    int n;
+    const char **Props;
+    LPTABLE t = GetTable(it8);
+
+    if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) {
+        *SubpropertyNames = 0;
+        return 0;
+    }
+
+    // Pass#1 - count properties
+
+    n = 0;
+    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
+        if(tmp->Subkey != NULL)
+            n++;
+    }
+
+
+    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
+
+    // Pass#2 - Fill pointers
+    n = 0;
+    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
+        if(tmp->Subkey != NULL)
+            Props[n++] = p ->Subkey;
+    }
+
+    *SubpropertyNames = Props;
+    return n;
+}
+
 static
 int LocatePatch(LPIT8 it8, const char* cPatch)
 {
@@ -2201,7 +2523,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
 
@@ -2209,7 +2531,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val)
+LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
     char Buff[256];
@@ -2260,7 +2582,7 @@
 
 
 
-BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch,
+LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch,
                         const char* cSample,
                         const char *Val)
 {
@@ -2305,18 +2627,19 @@
 }
 
 
-BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
+LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
                         const char* cSample,
                         double Val)
 {
     LPIT8 it8 = (LPIT8) hIT8;
     char Buff[256];
 
-        sprintf(Buff, it8->DoubleFormatter, Val);
+        snprintf(Buff, 255, it8->DoubleFormatter, Val);
         return cmsIT8SetData(hIT8, cPatch, cSample, Buff);
 
 }
 
+// Buffer should get MAXSTR at least
 
 const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer)
 {
@@ -2327,10 +2650,15 @@
         if (!Data) return NULL;
         if (!buffer) return Data;
 
-        strcpy(buffer, Data);
+        strncpy(buffer, Data, MAXSTR-1);        
         return buffer;
 }
 
+int LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cPatch)
+{
+    return LocatePatch((LPIT8)hIT8, cPatch);
+}
+
 int LCMSEXPORT cmsIT8TableCount(LCMSHANDLE hIT8)
 {
         LPIT8 it8 = (LPIT8) hIT8;
@@ -2356,7 +2684,7 @@
     cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
     if (!cLabelFld) return -1;
 
-    if (sscanf(cLabelFld, "%s %d %s", Label, &nTable, Type) != 3)
+    if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3)
             return -1;
 
     if (ExpectedType != NULL && *ExpectedType == 0)
@@ -2371,6 +2699,19 @@
 }
 
 
+LCMSBOOL LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample)
+{
+    LPIT8 it8 = (LPIT8) hIT8;
+
+    int pos = LocateSample(it8, cSample);
+    if(pos == -1)
+        return FALSE;
+
+    it8->Tab[it8->nTable].SampleID = pos;
+    return TRUE;
+}
+
+
 void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE hIT8, const char* Formatter)
 {
     LPIT8 it8 = (LPIT8) hIT8;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -256,7 +256,7 @@
 // Return TRUE if both m and of are empy -- "m" being identity and "of" being 0
 
 static
-BOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
+LCMSBOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
 {
     WVEC3 wv0;
 
@@ -661,3 +661,6 @@
 
        return rc;
 }
+
+
+      
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -96,7 +96,7 @@
 
             char Buffer[1024];
 
-            vsprintf(Buffer, ErrorText, args);
+            vsnprintf(Buffer, 1023, ErrorText, args);
             va_end(args);
 
             if (UserErrorHandler(ErrorCode, Buffer)) {
@@ -118,8 +118,8 @@
               char Buffer1[1024];
               char Buffer2[256];
 
-              sprintf(Buffer1, "Error #%x; ", ErrorCode);
-              vsprintf(Buffer2, ErrorText, args);
+              snprintf(Buffer1,  767, "Error #%x; ", ErrorCode);
+              vsnprintf(Buffer2, 255, ErrorText, args);
               strcat(Buffer1, Buffer2);
               MessageBox(NULL, Buffer1, "Little cms",
                                           MB_OK|MB_ICONSTOP|MB_TASKMODAL);
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -63,9 +63,9 @@
 LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]);
 LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
 LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints);
-BOOL         LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
+LCMSBOOL         LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
 
-BOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints);
+LCMSBOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints);
 
 
 // Sampled curves
@@ -74,7 +74,7 @@
 void           cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p);
 void           cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
 void           cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
-BOOL           cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
+LCMSBOOL       cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
 void           cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
 
 LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
@@ -84,7 +84,6 @@
 
 // ----------------------------------------------------------------------------------------
 
-// #define DEBUG 1
 
 #define MAX_KNOTS   4096
 typedef float vec[MAX_KNOTS+1];
@@ -144,14 +143,14 @@
        LPGAMMATABLE p;
        size_t size;
 
-       if (nEntries > 65530) {
-                cmsSignalError(LCMS_ERRC_WARNING, "Couldn't create gammatable of more than 65530 entries; 65530 assumed");
-                nEntries = 65530;
+       if (nEntries > 65530 || nEntries <= 0) {
+                cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries");
+                return NULL;
        }
 
        size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1));
 
-       p = (LPGAMMATABLE) malloc(size);
+       p = (LPGAMMATABLE) _cmsMalloc(size);
        if (!p) return NULL;
 
        ZeroMemory(p, size);
@@ -164,7 +163,7 @@
 
 void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma)
 {
-       if (Gamma) free(Gamma);
+       if (Gamma)  _cmsFree(Gamma);
 }
 
 
@@ -278,6 +277,15 @@
        LPWORD InPtr;
        LPGAMMATABLE p;
 
+       // Try to reverse it analytically whatever possible
+       if (InGamma -> Seed.Type > 0 && InGamma -> Seed.Type <= 5 &&             
+            _cmsCrc32OfGammaTable(InGamma) == InGamma -> Seed.Crc32) {
+
+                return cmsBuildParametricGamma(nResultSamples, -(InGamma -> Seed.Type), InGamma ->Seed.Params);
+       }
+
+
+       // Nope, reverse the table 
        p = cmsAllocGamma(nResultSamples);
        if (!p) return NULL;
 
@@ -528,7 +536,7 @@
 
 // Smooths a curve sampled at regular intervals
 
-BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
+LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
 
 {
     vec w, y, z;
@@ -640,13 +648,13 @@
 {
     LPSAMPLEDCURVE pOut;
 
-    pOut = (LPSAMPLEDCURVE) malloc(sizeof(SAMPLEDCURVE));
+    pOut = (LPSAMPLEDCURVE) _cmsMalloc(sizeof(SAMPLEDCURVE));
     if (pOut == NULL)
             return NULL;
 
-    if((pOut->Values = (double *) malloc(nItems * sizeof(double))) == NULL)
+    if((pOut->Values = (double *) _cmsMalloc(nItems * sizeof(double))) == NULL)
     {
-        free(pOut);
+         _cmsFree(pOut);
         return NULL;
     }
 
@@ -659,8 +667,8 @@
 
 void cmsFreeSampledCurve(LPSAMPLEDCURVE p)
 {
-    free((LPVOID) p -> Values);
-    free((LPVOID) p);
+     _cmsFree((LPVOID) p -> Values);
+     _cmsFree((LPVOID) p);
 }
 
 
@@ -731,7 +739,7 @@
 
 // Smooths a curve sampled at regular intervals
 
-BOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
+LCMSBOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
 {
     vec w, y, z;
     int i, nItems;
@@ -915,14 +923,11 @@
 
 // Smooth endpoints (used in Black/White compensation)
 
-BOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
+LCMSBOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
 {
     vec w, y, z;
     int i, Zeros, Poles;
 
-#ifdef DEBUG
-        ASAVE(Table, nEntries, "nonsmt.txt");
-#endif
 
 
     if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -66,7 +66,7 @@
 */
 
 
-BOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
+LCMSBOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
                             int *nOutputs)
 {
        // Only most common spaces
@@ -390,15 +390,21 @@
     double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
     double h_ps = atan2deg(a_ps, b_ps);
 
-
-
     double meanC_p =(C_p + C_ps) / 2;
 
-    double meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-360)/2;
+    double hps_plus_hp  = h_ps + h_p;
+    double hps_minus_hp = h_ps - h_p;
+
+    double meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 : 
+                            (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 : 
+                                                 (hps_plus_hp - 360)/2;
+
+    double delta_h = (hps_minus_hp) <= -180.000001 ?  (hps_minus_hp + 360) :
+                            (hps_minus_hp) > 180 ? (hps_minus_hp - 360) : 
+                                                    (hps_minus_hp);
+    double delta_L = (Ls - L1);
+    double delta_C = (C_ps - C_p );
 
-    double delta_h = fabs(h_p - h_ps) <= 180 ? fabs(h_p - h_ps) : 360 - fabs(h_p - h_ps);
-    double delta_L = fabs(L1 - Ls);
-    double delta_C = fabs(C_p - C_ps);
 
     double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2);
 
@@ -1065,7 +1071,7 @@
 // Check for monotonicity.
 
 static
-BOOL IsMonotonic(LPGAMMATABLE t)
+LCMSBOOL IsMonotonic(LPGAMMATABLE t)
 {
     int n = t -> nEntries;
     int i, last;
@@ -1088,7 +1094,7 @@
 // Check for endpoints
 
 static
-BOOL HasProperEndpoints(LPGAMMATABLE t)
+LCMSBOOL HasProperEndpoints(LPGAMMATABLE t)
 {
     if (t ->GammaTable[0] != 0) return FALSE;
     if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE;
@@ -1109,7 +1115,7 @@
     unsigned int t, i, v;
     int j;
     WORD In[MAXCHANNELS], Out[MAXCHANNELS];
-    BOOL lIsSuitable;
+    LCMSBOOL lIsSuitable;
     _LPcmsTRANSFORM InputXForm   = (_LPcmsTRANSFORM) h[0];
     _LPcmsTRANSFORM OutputXForm  = (_LPcmsTRANSFORM) h[nTransforms-1];
 
@@ -1126,10 +1132,10 @@
     }
 
 
-    // Do nothing on all but RGB to RGB transforms
+    // Do nothing on all but Gray/RGB to Gray/RGB transforms
 
-    if ((InputXForm ->EntryColorSpace != icSigRgbData) ||
-        (OutputXForm->ExitColorSpace  != icSigRgbData)) return;
+    if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) || 
+        ((OutputXForm->ExitColorSpace  != icSigRgbData) && (OutputXForm->ExitColorSpace  != icSigGrayData))) return;
 
 
     for (t = 0; t < Grid -> InputChan; t++)
@@ -1169,10 +1175,13 @@
         if (!HasProperEndpoints(Trans[t]))
                     lIsSuitable = FALSE;
 
+        /*
         // Exclude if transfer function is not smooth enough
         // to be modelled as a gamma function, or the gamma is reversed
+        
         if (cmsEstimateGamma(Trans[t]) < 1.0)
                     lIsSuitable = FALSE;
+        */
 
     }
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -282,7 +282,7 @@
 // Fills optimization parameters
 
 void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
-                                            BOOL lUseTetrahedral, LPL16PARAMS p)
+                                            LCMSBOOL lUseTetrahedral, LPL16PARAMS p)
 {
        int clutPoints;
 
@@ -579,7 +579,7 @@
 
                 // Identify if value fall downto 0 or FFFF zone
                 if (Value == 0) return 0;
-                if (Value == 0xFFFF) return 0xFFFF;
+               // if (Value == 0xFFFF) return 0xFFFF;
 
                 // else restrict to valid zone
 
@@ -631,7 +631,7 @@
         a = (y1 - y0) / (x1 - x0);
         b = y0 - a * x0;
 
-        if (a == 0) return (WORD) x;
+        if (fabs(a) < 0.01) return (WORD) x;
 
         f = ((Value - b) / a);
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	2009-04-03 13:43:04.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -62,7 +62,7 @@
 typedef struct {
                 LPBYTE Block;           // Points to allocated memory
                 size_t Size;            // Size of allocated memory
-                int Pointer;            // Points to current location
+                size_t Pointer;         // Points to current location
                 int FreeBlockOnClose;   // As title
 
                 } FILEMEM;
@@ -70,14 +70,16 @@
 static
 LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode)
 {
-    FILEMEM* fm = (FILEMEM*) malloc(sizeof(FILEMEM));
+    FILEMEM* fm = (FILEMEM*) _cmsMalloc(sizeof(FILEMEM));
+    if (fm == NULL) return NULL;
+
     ZeroMemory(fm, sizeof(FILEMEM));
 
     if (Mode == 'r') {
 
-        fm ->Block   = (LPBYTE) malloc(Size);
+        fm ->Block   = (LPBYTE) _cmsMalloc(Size);
         if (fm ->Block == NULL) {
-            free(fm);
+             _cmsFree(fm);
             return NULL;
         }
 
@@ -103,13 +105,27 @@
      FILEMEM* ResData = (FILEMEM*) Icc ->stream;
      LPBYTE Ptr;
      size_t len = size * count;
+     size_t extent = ResData -> Pointer + len;
 
+      if (len == 0) {
+          return 0;
+      }
+
+      if (len / size != count) {
+          cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size.");
+          return 0;
+      }
+
+      if (extent < len || extent < ResData -> Pointer) {
+          cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len.");
+          return 0;
+      } 
 
-     if (ResData -> Pointer + len > ResData -> Size){
+      if (ResData -> Pointer + len > ResData -> Size) {
 
          len = (ResData -> Size - ResData -> Pointer);
-         cmsSignalError(LCMS_ERRC_WARNING, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
-
+         cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
+         return 0;
      }
 
     Ptr  = ResData -> Block;
@@ -123,7 +139,7 @@
 // SEEK_CUR is assumed
 
 static
-BOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
+LCMSBOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
 {
     FILEMEM* ResData = (FILEMEM*) Icc ->stream;
 
@@ -147,10 +163,10 @@
 }
 
 
-// Writes data to memory, also keeps used space for further reference
+// Writes data to memory, also keeps used space for further reference. NO CHECK IS PERFORMED
 
 static
-BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
+LCMSBOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
 {
         FILEMEM* ResData = (FILEMEM*) Icc ->stream;
 
@@ -167,7 +183,7 @@
 
 
 static
-BOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
+LCMSBOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
 {
   FILEMEM* ResData = (FILEMEM*) Icc->stream;
   ResData->Size += size;
@@ -179,15 +195,15 @@
 
 
 static
-BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
+LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
 {
     FILEMEM* ResData = (FILEMEM*) Icc ->stream;
 
     if (ResData ->FreeBlockOnClose) {
 
-        if (ResData ->Block) free(ResData ->Block);
+        if (ResData ->Block)  _cmsFree(ResData ->Block);
     }
-    free(ResData);
+     _cmsFree(ResData);
     return 0;
 }
 
@@ -205,7 +221,7 @@
 {
     size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream);
     if (nReaded != count) {
-            cmsSignalError(LCMS_ERRC_WARNING, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
+            cmsSignalError(LCMS_ERRC_ABORTED, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
             return 0;
     }
 
@@ -214,7 +230,7 @@
 
 
 static
-BOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
+LCMSBOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
 {
     if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) {
 
@@ -236,7 +252,7 @@
 
 
 static
-BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
+LCMSBOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
 {
        if (size == 0) return TRUE;
 
@@ -252,14 +268,14 @@
 
 
 static
-BOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
+LCMSBOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
 {
   return TRUE;
 }
 
 
 static
-BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
+LCMSBOOL FileClose(struct _lcms_iccprofile_struct* Icc)
 {
     return fclose((FILE*) Icc ->stream);
 }
@@ -272,7 +288,7 @@
 cmsHPROFILE _cmsCreateProfilePlaceholder(void)
 {
 
-    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE));
+    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) _cmsMalloc(sizeof(LCMSICCPROFILE));
     if (Icc == NULL) return NULL;
 
     // Empty values
@@ -310,7 +326,7 @@
 // Search for a specific tag in tag dictionary
 // Returns position or -1 if tag not found
 
-icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError)
+icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError)
 {
        icInt32Number i;
 
@@ -331,7 +347,7 @@
 
 // Check existance
 
-BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
+LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
 {
        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
        return _cmsSearchTag(Icc, sig, FALSE) >= 0;
@@ -350,7 +366,7 @@
 
     if (i >=0) {
 
-        if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]);
+        if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]);
     }
     else  {
 
@@ -361,11 +377,14 @@
 
             cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG);
             Icc ->TagCount = MAX_TABLE_TAG-1;
+            return NULL;
         }
     }
 
 
-    Ptr = malloc(size);
+    Ptr = _cmsMalloc(size);
+    if (Ptr == NULL) return NULL;
+
     CopyMemory(Ptr, Init, size);
 
     Icc ->TagNames[i] = sig;
@@ -396,6 +415,8 @@
     if (NewIcc == NULL) return NULL;
 
     strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1);
+    NewIcc -> PhysicalFile[MAX_PATH-1] = 0;
+
     NewIcc ->stream = ICCfile;
 
     NewIcc ->Read  = FileRead;
@@ -498,7 +519,7 @@
 
 
 
-BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
 {
      LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
      *Dest = Icc -> MediaWhitePoint;
@@ -506,14 +527,14 @@
 }
 
 
-BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
 {
       LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
       *Dest = Icc -> MediaBlackPoint;
       return TRUE;
 }
 
-BOOL  LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
+LCMSBOOL  LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
 {
        LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
        *Dest = Icc -> Illuminant;
@@ -571,7 +592,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
 {
     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
     CopyMemory(Dest, &Icc ->Created, sizeof(struct tm));
@@ -660,7 +681,7 @@
 
 // This is tricky, since LUT structs does have pointers
 
-BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
+LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
 {
        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
        LPLUT Orig, Stored;
@@ -688,7 +709,7 @@
 }
 
 
-BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
+LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
 {
        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
@@ -697,7 +718,7 @@
 }
 
 
-BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
+LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
 {
        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
@@ -705,7 +726,7 @@
        return TRUE;
 }
 
-BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
+LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
@@ -714,7 +735,7 @@
 }
 
 
-BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
+LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
@@ -723,7 +744,7 @@
 }
 
 
-BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
+LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
@@ -733,28 +754,40 @@
 }
 
 
-BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
+LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
     _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
-    return FALSE;
+    return TRUE;
 }
 
 
-BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
+LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
     _cmsInitTag(Icc, sig, sizeof(struct tm), DateTime);
-    return FALSE;
+    return TRUE;
 }
 
 
-BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
+LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 
     _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
-    return FALSE;
+    return TRUE;
+}
+
+
+LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat)
+{
+    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
+   
+    _cmsInitTag(Icc, sig, 3*sizeof(cmsCIEXYZ), mat);
+    return TRUE;
+
 }
+
+
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c	2009-04-03 13:43:04.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -288,13 +288,17 @@
 // Read profile header and validate it
 
 static
-LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, BOOL lIsFromMemory)
+LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc,
+                            LCMSBOOL lIsFromMemory,
+                            DWORD dwSize)
 {
      icTag Tag;
      icHeader Header;
      icInt32Number TagCount, i;
+     icUInt32Number extent;
 
-     Icc -> Read(&Header, sizeof(icHeader), 1, Icc);
+       if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1) 
+                      goto ErrorCleanup;
 
        // Convert endian
 
@@ -313,6 +317,9 @@
 
        if (Header.magic != icMagicNumber) goto ErrorCleanup;
 
+       if (dwSize && dwSize != Header.size) {
+            goto ErrorCleanup;
+        }
 
        if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1)
                      goto ErrorCleanup;
@@ -348,7 +355,7 @@
 
        // Read tag directory
 
-       if (TagCount > MAX_TABLE_TAG) {
+       if (TagCount > MAX_TABLE_TAG || TagCount < 0) {
 
            cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount);
            goto ErrorCleanup;
@@ -357,12 +364,18 @@
        Icc -> TagCount = TagCount;
        for (i=0; i < TagCount; i++) {
 
-              Icc ->Read(&Tag, sizeof(icTag), 1, Icc);
+              if (Icc ->Read(&Tag, sizeof(icTag), 1, Icc) != 1) 
+                  goto ErrorCleanup;
 
               AdjustEndianess32((LPBYTE) &Tag.offset);
               AdjustEndianess32((LPBYTE) &Tag.size);
               AdjustEndianess32((LPBYTE) &Tag.sig);            // Signature
 
+              // Perform some sanity check. Offset + size should fall inside file.
+              extent = Tag.offset + Tag.size;
+              if (extent > Header.size || extent < Tag.offset)
+                  goto ErrorCleanup;
+
               Icc -> TagNames[i]   = Tag.sig;
               Icc -> TagOffsets[i] = Tag.offset;
               Icc -> TagSizes[i]   = Tag.size;
@@ -381,7 +394,7 @@
              cmsSignalError(LCMS_ERRC_ABORTED, "Corrupted profile: '%s'", Icc->PhysicalFile);
 
 
-       free(Icc);
+        _cmsFree(Icc);
        return NULL;
 }
 
@@ -497,7 +510,7 @@
 // The infamous LUT 8
 
 static
-void ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig)
+LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig)
 {
     icLut8 LUT8;
     LPBYTE Temp;
@@ -506,7 +519,7 @@
     unsigned int AllLinear;
     LPWORD PtrW;
 
-       Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc);
+       if (Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return FALSE;
 
        NewLUT -> wFlags        = LUT_HASTL1|LUT_HASTL2|LUT_HAS3DGRID;
        NewLUT -> cLutPoints    = LUT8.clutPoints;
@@ -515,6 +528,10 @@
        NewLUT -> InputEntries  = 256;
        NewLUT -> OutputEntries = 256;
 
+       // Do some checking
+       if (!_cmsValidateLUT(NewLUT)) {
+          return FALSE;
+       }
 
        AdjustEndianess32((LPBYTE) &LUT8.e00);
        AdjustEndianess32((LPBYTE) &LUT8.e01);
@@ -550,13 +567,24 @@
 
        // Copy input tables
 
-       Temp = (LPBYTE) malloc(256);
+       Temp = (LPBYTE) _cmsMalloc(256);
+       if (Temp == NULL) return FALSE;
+
        AllLinear = 0;
        for (i=0; i < NewLUT -> InputChan; i++) {
 
-              PtrW = (LPWORD) malloc(sizeof(WORD) * 256);
+              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256);
+              if (PtrW == NULL) {
+                   _cmsFree(Temp);
+                  return FALSE;
+                  }
+
               NewLUT -> L1[i] = PtrW;
-              Icc ->Read(Temp, 1, 256, Icc);
+              if (Icc ->Read(Temp, 1, 256, Icc) != 256) {
+                   _cmsFree(Temp);
+                  return FALSE;
+                  }
+
               for (j=0; j < 256; j++)
                      PtrW[j] = TO16_TAB(Temp[j]);
                      AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries);
@@ -569,7 +597,7 @@
               NewLUT -> wFlags &= ~LUT_HASTL1;
        }
 
-       free(Temp);
+        _cmsFree(Temp);
 
        // Copy 3D CLUT
 
@@ -578,9 +606,20 @@
 
        if (nTabSize > 0) {
 
-            PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize);
-            Temp = (LPBYTE) malloc(nTabSize);
-            Icc ->Read(Temp, 1, nTabSize, Icc);
+            PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
+            if (PtrW == NULL) return FALSE;
+
+            Temp = (LPBYTE) _cmsMalloc(nTabSize);
+            if (Temp == NULL) {
+                 _cmsFree(PtrW);
+                return FALSE;
+                }
+
+            if (Icc ->Read(Temp, 1, nTabSize, Icc) != nTabSize) {
+                 _cmsFree(Temp);
+                _cmsFree(PtrW);
+                return FALSE;
+                }
 
             NewLUT -> T = PtrW;
             NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD));
@@ -589,25 +628,37 @@
 
                      *PtrW++ = TO16_TAB(Temp[i]);
             }
-            free(Temp);
+            _cmsFree(Temp);
        }
        else {
            NewLUT ->T = NULL;
            NewLUT ->Tsize = 0;
-           NewLUT -> wFlags &= ~LUT_HAS3DGRID;
+           NewLUT ->wFlags &= ~LUT_HAS3DGRID;
        }
 
 
-
        // Copy output tables
 
-       Temp = (LPBYTE) malloc(256);
+       Temp = (LPBYTE) _cmsMalloc(256);
+       if (Temp == NULL) {
+           return FALSE;
+           }
+
        AllLinear = 0;
        for (i=0; i < NewLUT -> OutputChan; i++) {
 
-              PtrW = (LPWORD) malloc(sizeof(WORD) * 256);
+              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256);
+              if (PtrW == NULL) {
+                  _cmsFree(Temp);
+                  return FALSE;
+                  }
+
               NewLUT -> L2[i] = PtrW;
-              Icc ->Read(Temp, 1, 256, Icc);
+              if (Icc ->Read(Temp, 1, 256, Icc) != 256) {
+                  _cmsFree(Temp);
+                  return FALSE;
+                  }
+
               for (j=0; j < 256; j++)
                      PtrW[j] = TO16_TAB(Temp[j]);
                      AllLinear += cmsIsLinear(NewLUT -> L2[i], 256);
@@ -621,7 +672,7 @@
        }
 
 
-       free(Temp);
+       _cmsFree(Temp);
 
        cmsCalcL16Params(NewLUT -> InputEntries,  &NewLUT -> In16params);
        cmsCalcL16Params(NewLUT -> OutputEntries, &NewLUT -> Out16params);
@@ -646,6 +697,15 @@
            // some profiles does claim to do that. Poor lcms will try
            // to detect such condition and fix up "on the fly".
 
+           switch (sig) {
+
+            case icSigBToA0Tag:
+            case icSigBToA1Tag:
+            case icSigBToA2Tag:
+            case icSigGamutTag:
+            case icSigPreview0Tag:
+            case icSigPreview1Tag:
+            case icSigPreview2Tag: 
            {
                LPWORD WhiteLab, ExpectedWhite;
                WORD WhiteFixed[MAXCHANNELS], WhiteUnfixed[MAXCHANNELS];
@@ -685,9 +745,13 @@
                }
 
            }
+           break;
 
+        default:;
+        }           
        }
 
+       return TRUE;
 }
 
 
@@ -696,7 +760,7 @@
 // Case LUT 16
 
 static
-void ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT)
+LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT)
 {
     icLut16 LUT16;
     size_t nTabSize;
@@ -705,7 +769,8 @@
     LPWORD PtrW;
 
 
-       Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc);
+       if (Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc) != 1) 
+            return FALSE;
 
        NewLUT -> wFlags        = LUT_HASTL1 | LUT_HASTL2 | LUT_HAS3DGRID;
        NewLUT -> cLutPoints    = LUT16.clutPoints;
@@ -718,6 +783,9 @@
        NewLUT -> InputEntries  = LUT16.inputEnt;
        NewLUT -> OutputEntries = LUT16.outputEnt;
 
+       if (!_cmsValidateLUT(NewLUT)) {
+         return FALSE;
+       }
 
        // Matrix handling
 
@@ -754,9 +822,14 @@
        AllLinear = 0;
        for (i=0; i < NewLUT -> InputChan; i++) {
 
-              PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries);
+              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries);
+              if (PtrW == NULL) return FALSE;
+
               NewLUT -> L1[i] = PtrW;
-              Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc);
+              if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc) != NewLUT -> InputEntries) {                 
+                  return FALSE;
+                  }
+
               AdjustEndianessArray16(PtrW, NewLUT -> InputEntries);
               AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries);
               }
@@ -775,12 +848,19 @@
                                                 NewLUT->InputChan));
        if (nTabSize > 0) {
 
-           PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize);
+           PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
+           if (PtrW == NULL) {
+               _cmsFree(PtrW);
+               return FALSE;
+           }
 
            NewLUT -> T = PtrW;
            NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD));
 
-           Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc);
+           if (Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc) != nTabSize) {
+               return FALSE;
+           }
+
            AdjustEndianessArray16(NewLUT -> T, nTabSize);
        }
        else {
@@ -794,9 +874,16 @@
        AllLinear = 0;
        for (i=0; i < NewLUT -> OutputChan; i++) {
 
-              PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries);
+              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries);
+              if (PtrW == NULL) {
+                  return FALSE;
+                  }
+
               NewLUT -> L2[i] = PtrW;
-              Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc);
+              if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc) != NewLUT -> OutputEntries) {
+                  return FALSE;
+                  }
+
               AdjustEndianessArray16(PtrW, NewLUT -> OutputEntries);
               AllLinear += cmsIsLinear(NewLUT -> L2[i], NewLUT -> OutputEntries);
               }
@@ -814,6 +901,8 @@
        cmsCalcCLUT16Params(NewLUT -> cLutPoints,  NewLUT -> InputChan,
                                                   NewLUT -> OutputChan,
                                                   &NewLUT -> CLut16params);
+
+       return TRUE;
 }
 
 
@@ -834,13 +923,12 @@
        switch (BaseType) {
 
 
-       case 0x9478ee00L:    // Monaco 2 profiler is BROKEN!
+       case ((icTagTypeSignature) 0x9478ee00):    // Monaco 2 profiler is BROKEN!
        case icSigCurveType:
 
-           Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
+           if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
            AdjustEndianess32((LPBYTE) &Count);
 
-
            switch (Count) {
 
            case 0:   // Linear.
@@ -855,7 +943,7 @@
                     {
                      WORD SingleGammaFixed;
 
-                     Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc);
+                     if (Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL;
                      AdjustEndianess16((LPBYTE) &SingleGammaFixed);
                      return cmsBuildGamma(4096, Convert8Fixed8(SingleGammaFixed));
                      }
@@ -865,10 +953,9 @@
                      NewGamma = cmsAllocGamma(Count);
                      if (!NewGamma) return NULL;
 
-                     Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc);
-
+                     if (Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count) 
+                         return NULL;                    
                      AdjustEndianessArray16(NewGamma -> GammaTable, Count);
-
                      return NewGamma;
                     }
               }
@@ -885,8 +972,8 @@
            icUInt16Number   Type;
            int i;
 
-           Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc);
-           Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc);
+           if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
+           if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
 
            AdjustEndianess16((LPBYTE) &Type);
            if (Type > 5) {
@@ -900,7 +987,7 @@
 
           for (i=0; i < n; i++) {
                 Num = 0;
-                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
+                if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL;
                 Params[i] = Convert15Fixed16(Num);
           }
 
@@ -938,7 +1025,7 @@
        case 0x9478ee00L:    // Monaco 2 profiler is BROKEN!
        case icSigCurveType:
 
-           Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc);
+           if (Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
            AdjustEndianess32((LPBYTE) &Count);
 
 
@@ -955,7 +1042,7 @@
            case 1:  {
                      WORD SingleGammaFixed;
 
-                     Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc);
+                     if (Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL;
                      AdjustEndianess16((LPBYTE) &SingleGammaFixed);
                      return cmsBuildGamma(4096, 1./Convert8Fixed8(SingleGammaFixed));
                      }
@@ -965,7 +1052,8 @@
                      NewGamma = cmsAllocGamma(Count);
                      if (!NewGamma) return NULL;
 
-                     Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc);
+                     if (Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count)
+                         return NULL;
 
                      AdjustEndianessArray16(NewGamma -> GammaTable, Count);
 
@@ -992,8 +1080,8 @@
            int i;
 
 
-           Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc);
-           Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc);
+           if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
+           if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
 
            AdjustEndianess16((LPBYTE) &Type);
            if (Type > 5) {
@@ -1006,7 +1094,7 @@
           n = ParamsByType[Type];
 
           for (i=0; i < n; i++) {
-                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
+                if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL;
                 Params[i] = Convert15Fixed16(Num);
           }
 
@@ -1028,7 +1116,7 @@
 // V4 stuff. Read matrix for LutAtoB and LutBtoA
 
 static
-BOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags)
+LCMSBOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags)
 {
 
     icS15Fixed16Number All[12];
@@ -1038,7 +1126,8 @@
 
     if (Icc -> Seek(Icc, Offset)) return FALSE;
 
-    Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc);
+    if (Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc) != 12) 
+        return FALSE;
 
     for (i=0; i < 12;  i++)
               AdjustEndianess32((LPBYTE) &All[i]);
@@ -1067,17 +1156,26 @@
 //  V4 stuff. Read CLUT part for LutAtoB and LutBtoA
 
 static
-BOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT)
+LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT)
 {
-
+    unsigned int j;
     icCLutStruct CLUT;
 
     if (Icc -> Seek(Icc, Offset)) return FALSE;
-    Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc);
+    if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE;
 
 
-    cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan,
-                                               NewLUT ->OutputChan);
+    for (j=1; j < NewLUT ->InputChan; j++) {
+        if (CLUT.gridPoints[0] != CLUT.gridPoints[j]) {
+            cmsSignalError(LCMS_ERRC_ABORTED, "CLUT with different granulatity is currently unsupported."); 
+            return FALSE;
+        }
+
+                
+    }
+
+    if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, 
+                                               NewLUT ->OutputChan) == NULL) return FALSE;
 
     // Precission can be 1 or 2 bytes
 
@@ -1087,7 +1185,7 @@
         unsigned int i;
 
         for (i=0; i < NewLUT->Tsize / sizeof(WORD); i++) {
-                Icc ->Read(&v, sizeof(BYTE), 1, Icc);
+                if (Icc ->Read(&v, sizeof(BYTE), 1, Icc) != 1) return FALSE;
                 NewLUT->T[i] = TO16_TAB(v);
         }
 
@@ -1095,9 +1193,9 @@
     else
         if (CLUT.prec == 2) {
 
-         Icc ->Read(NewLUT ->T, sizeof(WORD),
-                    NewLUT->Tsize / sizeof(WORD), Icc);
+         size_t n = NewLUT->Tsize / sizeof(WORD);
 
+         if (Icc ->Read(NewLUT ->T, sizeof(WORD), n, Icc) != n) return FALSE;
         AdjustEndianessArray16(NewLUT ->T, NewLUT->Tsize / sizeof(WORD));
     }
     else {
@@ -1110,6 +1208,22 @@
 
 
 static
+void ResampleCurves(LPGAMMATABLE Curves[], int nCurves)
+{
+    int i;
+    LPSAMPLEDCURVE sc;
+
+    for (i=0; i < nCurves; i++) {
+        sc = cmsConvertGammaToSampledCurve(Curves[i], 4096);
+        cmsFreeGamma(Curves[i]);
+        Curves[i] = cmsConvertSampledCurveToGamma(sc, 0xFFFF);
+        cmsFreeSampledCurve(sc);
+    }
+
+}
+
+
+static
 void SkipAlignment(LPLCMSICCPROFILE Icc)
 {
     BYTE Buffer[4];
@@ -1121,7 +1235,7 @@
 
 // Read a set of curves from specific offset
 static
-BOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation)
+LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation)
 {
     LPGAMMATABLE Curves[MAXCHANNELS];
     unsigned int i, nCurves;
@@ -1134,11 +1248,22 @@
     else
         nCurves = NewLUT ->OutputChan;
 
+    ZeroMemory(Curves, sizeof(Curves));
     for (i=0; i < nCurves; i++) {
 
         Curves[i] = ReadCurve(Icc);
+        if (Curves[i] == NULL) goto Error;
         SkipAlignment(Icc);
+    }
 
+    // March-26'08: some V4 profiles may have different sampling
+    // rates, in this case resample all curves to maximum
+
+    for (i=1; i < nCurves; i++) {
+        if (Curves[i]->nEntries != Curves[0]->nEntries) {
+            ResampleCurves(Curves, nCurves);
+        break;
+        }
     }
 
     NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation);
@@ -1148,6 +1273,16 @@
 
     return TRUE;
 
+Error:
+    for (i=0; i < nCurves; i++) {
+
+        if (Curves[i]) 
+            cmsFreeGamma(Curves[i]);
+    }
+
+    return FALSE;
+
+
 }
 
 // V4 stuff. LutAtoB type
@@ -1160,15 +1295,22 @@
 //   L2 = B curves
 
 static
-BOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig)
+LCMSBOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig)
 {
     icLutAtoB LUT16;
 
-       Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc);
+       if (Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc) != 1) return FALSE;
 
        NewLUT -> InputChan     = LUT16.inputChan;
        NewLUT -> OutputChan    = LUT16.outputChan;
 
+       // Validate the NewLUT here to avoid excessive number of channels
+       // (leading to stack-based buffer overflow in ReadSetOfCurves).
+       // Needs revalidation after table size is filled in.
+       if (!_cmsValidateLUT(NewLUT)) {
+           return FALSE;
+       }
+
        AdjustEndianess32((LPBYTE) &LUT16.offsetB);
        AdjustEndianess32((LPBYTE) &LUT16.offsetMat);
        AdjustEndianess32((LPBYTE) &LUT16.offsetM);
@@ -1220,15 +1362,22 @@
 // V4 stuff. LutBtoA type
 
 static
-BOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT,  size_t BaseOffset, icTagSignature sig)
+LCMSBOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT,  size_t BaseOffset, icTagSignature sig)
 {
   icLutBtoA LUT16;
 
-       Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc);
+       if (Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc) != 1) return FALSE;
 
        NewLUT -> InputChan     = LUT16.inputChan;
        NewLUT -> OutputChan    = LUT16.outputChan;
 
+       // Validate the NewLUT here to avoid excessive number of channels
+       // (leading to stack-based buffer overflow in ReadSetOfCurves).
+       // Needs revalidation after table size is filled in.
+       if (!_cmsValidateLUT(NewLUT)) {
+           return FALSE;
+       }
+
        AdjustEndianess32((LPBYTE) &LUT16.offsetB);
        AdjustEndianess32((LPBYTE) &LUT16.offsetMat);
        AdjustEndianess32((LPBYTE) &LUT16.offsetM);
@@ -1294,7 +1443,7 @@
 
 
     // If is in memory, the LUT is already there, so throw a copy
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
         return cmsDupLUT((LPLUT) Icc ->TagPtrs[n]);
     }
@@ -1308,8 +1457,8 @@
 
 
     NewLUT = cmsAllocLUT();
-    if (!NewLUT)
-    {
+    if (!NewLUT) {
+
        cmsSignalError(LCMS_ERRC_ABORTED, "cmsAllocLUT() failed");
        return NULL;
     }
@@ -1317,11 +1466,29 @@
 
     switch (BaseType) {
 
-    case icSigLut8Type:    ReadLUT8(Icc, NewLUT, sig); break;
-    case icSigLut16Type:   ReadLUT16(Icc, NewLUT);     break;
-
-    case icSiglutAtoBType: ReadLUT_A2B(Icc, NewLUT, offset, sig); break;
-    case icSiglutBtoAType: ReadLUT_B2A(Icc, NewLUT, offset, sig); break;
+    case icSigLut8Type:    if (!ReadLUT8(Icc, NewLUT, sig)) {
+                                cmsFreeLUT(NewLUT);
+                                return NULL;
+                           }
+                           break;
+
+    case icSigLut16Type:   if (!ReadLUT16(Icc, NewLUT)) {
+                                cmsFreeLUT(NewLUT);
+                                return NULL;
+                           }
+                           break;
+
+    case icSiglutAtoBType: if (!ReadLUT_A2B(Icc, NewLUT, offset, sig)) {
+                                cmsFreeLUT(NewLUT);
+                                return NULL;
+                           }
+                           break;
+
+    case icSiglutBtoAType: if (!ReadLUT_B2A(Icc, NewLUT, offset, sig)) {
+                                cmsFreeLUT(NewLUT);
+                                return NULL;
+                           }
+                           break;
 
     default:  cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature %lx found.", BaseType);
               cmsFreeLUT(NewLUT);
@@ -1335,16 +1502,23 @@
 
 // Sets the language & country preferences. Used only in ICC 4.0 profiles
 
-void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode)
+void LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4])
 {
-    GlobalLanguageCode = LanguageCode;
-    GlobalCountryCode  = CountryCode;
+
+    int LanguageCodeInt = *(int *) LanguageCode;
+    int CountryCodeInt  = *(int *) CountryCode;
+    
+    AdjustEndianess32((LPBYTE) &LanguageCodeInt);
+    AdjustEndianess32((LPBYTE) &CountryCodeInt);
+
+    GlobalLanguageCode = LanguageCodeInt;
+    GlobalCountryCode  = CountryCodeInt;
 }
 
 
 
 // Some tags (e.g, 'pseq') can have text tags embedded. This function
-// handles such special case.
+// handles such special case. Returns -1 on error, or the number of bytes left on success. 
 
 static
 int ReadEmbeddedTextTag(LPLCMSICCPROFILE Icc, size_t size, char* Name, size_t size_max)
@@ -1365,7 +1539,7 @@
            icUInt16Number  ScriptCodeCode, Dummy;
            icUInt8Number   ScriptCodeCount;
 
-           Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc);
+           if (Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
 
                    if (size < sizeof(icUInt32Number)) return (int) size;
            size -= sizeof(icUInt32Number);
@@ -1379,11 +1553,11 @@
 
            // Skip Unicode code
 
-           Icc ->Read(&UnicodeCode,  sizeof(icUInt32Number), 1, Icc);
+           if (Icc ->Read(&UnicodeCode,  sizeof(icUInt32Number), 1, Icc) != 1) return -1;
                    if (size < sizeof(icUInt32Number)) return (int) size;
            size -= sizeof(icUInt32Number);
 
-           Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc);
+           if (Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
                    if (size < sizeof(icUInt32Number)) return (int) size;
            size -= sizeof(icUInt32Number);
 
@@ -1391,24 +1565,28 @@
 
            if (UnicodeCount > size) return (int) size;
 
-           for (i=0; i < UnicodeCount; i++)
-                Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc);
-
-           size -= UnicodeCount * sizeof(icUInt16Number);
+           for (i=0; i < UnicodeCount; i++) { 
+                size_t nread = Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc);
+                if (nread != 1) return (int) size;
+                size -= sizeof(icUInt16Number);
+           }
 
           // Skip ScriptCode code
 
-           Icc ->Read(&ScriptCodeCode,  sizeof(icUInt16Number), 1, Icc);
+           if (Icc ->Read(&ScriptCodeCode,  sizeof(icUInt16Number), 1, Icc) != 1) return -1;
            size -= sizeof(icUInt16Number);
-           Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc);
+           if (Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc) != 1) return -1;
            size -= sizeof(icUInt8Number);
 
-           if (size < 67) return (int) size;
+           // Should remain 67 bytes as filler
 
-           for (i=0; i < 67; i++)
-                Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc);
+           if (size < 67) return (int) size;
 
-           size -= 67;
+           for (i=0; i < 67; i++) {
+                size_t nread = Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc);
+                if (nread != 1) return (int) size;
+                size --;
+               }           
            }
            break;
 
@@ -1425,7 +1603,7 @@
              size = size_max - 1;
          }
 
-         Icc -> Read(Name, 1, size, Icc);
+         if (Icc -> Read(Name, 1, size, Icc) != size) return -1;
 
          for (i=0; i < Missing; i++)
              Icc -> Read(&Dummy, 1, 1, Icc);
@@ -1445,9 +1623,9 @@
         wchar_t*       wchar  = L"";
 
 
-            Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
+            if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
             AdjustEndianess32((LPBYTE) &Count);
-            Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc);
+            if (Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
             AdjustEndianess32((LPBYTE) &RecLen);
 
             if (RecLen != 12) {
@@ -1458,15 +1636,15 @@
 
             for (i=0; i < Count; i++) {
 
-                Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc);
+                if (Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc) != 1) return -1;
                 AdjustEndianess16((LPBYTE) &Language);
-                Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc);
+                if (Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc) != 1) return -1;
                 AdjustEndianess16((LPBYTE) &Country);
 
-                Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc);
+                if (Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
                 AdjustEndianess32((LPBYTE) &ThisLen);
 
-                Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc);
+                if (Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
                 AdjustEndianess32((LPBYTE) &ThisOffset);
 
                 if (Language == GlobalLanguageCode || Offset == 0) {
@@ -1492,14 +1670,20 @@
             for (i=0; i < Offset; i++) {
 
                     char Discard;
-
+                    // No return checking; could lead to large loop in
+                    // combination with int oflow above computing Offset.
                     Icc ->Read(&Discard, 1, 1, Icc);
             }
 
-            wchar = (wchar_t*) malloc(Len+2);
+
+            // Bound len
+            if (Len < 0) Len = 0;
+            if (Len > 20*1024) Len = 20 * 1024; 
+
+            wchar = (wchar_t*) _cmsMalloc(Len*sizeof(wchar_t)+2);
             if (!wchar) return -1;
 
-            Icc ->Read(wchar, 1, Len, Icc);
+            if (Icc ->Read(wchar, 1, Len, Icc) != Len) return -1;
             AdjustEndianessArray16((LPWORD) wchar, Len / 2);
 
             wchar[Len / 2] = L'\0';
@@ -1509,7 +1693,7 @@
                 Name[0] = 0;    // Error
             }
 
-            free((void*) wchar);
+            _cmsFree((void*) wchar);
             }
             break;
 
@@ -1535,7 +1719,7 @@
     if (n < 0)
         return -1;
 
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
         CopyMemory(Name, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
         return (int) Icc -> TagSizes[n];
@@ -1561,7 +1745,7 @@
 // Take an XYZ item
 
 static
-int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, BOOL lIsFatal)
+int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, LCMSBOOL lIsFatal)
 {
     LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
     icTagTypeSignature  BaseType;
@@ -1573,7 +1757,7 @@
     if (n < 0)
             return -1;
 
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
          CopyMemory(Value, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
          return (int) Icc -> TagSizes[n];
@@ -1628,7 +1812,7 @@
     if (n < 0)
             return -1; // Not found
 
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
             CopyMemory(v, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
             return (int) Icc -> TagSizes[n];
@@ -1677,7 +1861,7 @@
 
 // Primaries are to be in xyY notation
 
-BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile)
 {
        if (ReadICCXYZ(hProfile, icSigRedColorantTag, &Dest -> Red, TRUE) < 0) return FALSE;
        if (ReadICCXYZ(hProfile, icSigGreenColorantTag, &Dest -> Green, TRUE) < 0) return FALSE;
@@ -1687,7 +1871,7 @@
 }
 
 
-BOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile)
+LCMSBOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile)
 {
        cmsCIEXYZTRIPLE Primaries;
 
@@ -1704,7 +1888,7 @@
 
 // Always return a suitable matrix
 
-BOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile)
+LCMSBOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile)
 {
 
     if (ReadICCXYZArray(hProfile, icSigChromaticAdaptationTag, r) < 0) {
@@ -1741,7 +1925,7 @@
        if (n < 0)
            return NULL;
 
-       if (!Icc -> stream) {
+       if (Icc -> TagPtrs[n]) {
 
             return cmsDupGamma((LPGAMMATABLE) Icc -> TagPtrs[n]);
        }
@@ -1769,7 +1953,7 @@
        if (n < 0)
             return NULL;
 
-       if (!Icc -> stream) {
+       if (Icc -> TagPtrs[n]) {
 
             return cmsReverseGamma(256, (LPGAMMATABLE) Icc -> TagPtrs[n]);
        }
@@ -1785,7 +1969,7 @@
 // Check Named color header
 
 static
-BOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2)
+LCMSBOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2)
 {
     if (v ->Prefix[0] == 0 && v ->Suffix[0] == 0 && v ->ColorantCount == 0) return TRUE;
 
@@ -1809,13 +1993,13 @@
        if (n < 0)
             return 0;
 
-       if (!Icc -> stream) {
+       if (Icc -> TagPtrs[n]) {
 
             // This replaces actual named color list.
             size_t size   = Icc -> TagSizes[n];
 
             if (v ->NamedColorList) cmsFreeNamedColorList(v ->NamedColorList);
-            v -> NamedColorList = (LPcmsNAMEDCOLORLIST) malloc(size);
+            v -> NamedColorList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);           
             CopyMemory(v -> NamedColorList, Icc ->TagPtrs[n], size);
             return v ->NamedColorList->nColors;
        }
@@ -1844,7 +2028,7 @@
                 icNamedColor2 nc2;
                 unsigned int i, j;
 
-                Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc);
+                if (Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return 0;
                 AdjustEndianess32((LPBYTE) &nc2.vendorFlag);
                 AdjustEndianess32((LPBYTE) &nc2.count);
                 AdjustEndianess32((LPBYTE) &nc2.nDeviceCoords);
@@ -1854,6 +2038,11 @@
                      return 0;
                 }
 
+                if (nc2.nDeviceCoords > MAXCHANNELS) {
+                          cmsSignalError(LCMS_ERRC_WARNING, "Too many device coordinates.");
+                          return 0;
+                }
+
                 strncpy(v ->NamedColorList->Prefix, (const char*) nc2.prefix, 32);
                 strncpy(v ->NamedColorList->Suffix, (const char*) nc2.suffix, 32);
                 v ->NamedColorList->Prefix[32] = v->NamedColorList->Suffix[32] = 0;
@@ -1867,6 +2056,8 @@
                     char Root[33];
 
                     ZeroMemory(Colorant, sizeof(WORD) * MAXCHANNELS);
+                    // No return value checking; could cause trouble with
+                    // large count.
                     Icc -> Read(Root, 1, 32, Icc);
                     Icc -> Read(PCS,  3, sizeof(WORD), Icc);
 
@@ -1900,7 +2091,8 @@
 
 LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig)
 {
-    icInt32Number n, Count, i;
+    icInt32Number n;
+    icUInt32Number Count, i; 
     size_t offset;
     icTagTypeSignature  BaseType;
     LPLCMSICCPROFILE   Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@@ -1910,10 +2102,12 @@
     if (n < 0)
             return NULL; // Not found
 
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
             size_t size   = Icc -> TagSizes[n];
-            void* v = malloc(size);
+            void* v = _cmsMalloc(size);
+            
+            if (v == NULL) return NULL;
             CopyMemory(v, Icc -> TagPtrs[n], size);
             return (LPcmsNAMEDCOLORLIST) v;
     }
@@ -1932,9 +2126,14 @@
     }
 
 
-    Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
+    if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
     AdjustEndianess32((LPBYTE) &Count);
 
+    if (Count > MAXCHANNELS) {
+        cmsSignalError(LCMS_ERRC_ABORTED, "Too many colorants '%lx'", Count);
+        return NULL;
+    }
+
     List = cmsAllocNamedColorList(Count);
     for (i=0; i < Count; i++) {
 
@@ -1965,7 +2164,7 @@
 
        if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) {
 
-            cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer);
+            cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX);
        }
 
     return Manufacturer;
@@ -1982,7 +2181,7 @@
 
        if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) {
 
-            cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model);
+            cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX);
        }
 
     return Model;
@@ -1995,10 +2194,9 @@
     static char Copyright[LCMS_DESC_MAX] = "";
 
        Copyright[0] = 0;
-
        if (cmsIsTag(hProfile, icSigCopyrightTag)) {
 
-            cmsReadICCText(hProfile, icSigCopyrightTag, Copyright);
+            cmsReadICCTextEx(hProfile, icSigCopyrightTag, Copyright, LCMS_DESC_MAX);
        }
 
     return Copyright;
@@ -2009,7 +2207,7 @@
 
 const char*  LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile)
 {
-    static char Name[2048];
+    static char Name[LCMS_DESC_MAX*2+4];
     char Manufacturer[LCMS_DESC_MAX], Model[LCMS_DESC_MAX];
 
     Name[0] = '\0';
@@ -2017,19 +2215,19 @@
 
     if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) {
 
-        cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer);
+        cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX);
     }
 
     if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) {
 
-        cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model);
+        cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX);
     }
 
     if (!Manufacturer[0] && !Model[0]) {
 
         if (cmsIsTag(hProfile, icSigProfileDescriptionTag)) {
 
-            cmsReadICCText(hProfile, icSigProfileDescriptionTag, Name);
+            cmsReadICCTextEx(hProfile, icSigProfileDescriptionTag, Name, LCMS_DESC_MAX);
             return Name;
         }
         else return "{no name}";
@@ -2129,7 +2327,7 @@
 
 // Extract the target data as a big string. Does not signal if tag is not present.
 
-BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len)
+LCMSBOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len)
 {
     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
     int n;
@@ -2142,7 +2340,11 @@
 
 
     *len =  Icc -> TagSizes[n];
-    *Data = (char*) malloc(*len + 1);  // Plus zero marker
+
+    // Make sure that is reasonable (600K)
+    if (*len > 600*1024) *len = 600*1024;
+
+    *Data = (char*) _cmsMalloc(*len + 1);  // Plus zero marker
 
     if (!*Data) {
 
@@ -2162,7 +2364,7 @@
 
 
 
-BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
 {
     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
     int n;
@@ -2170,8 +2372,8 @@
     n = _cmsSearchTag(Icc, icSigCalibrationDateTimeTag, FALSE);
     if (n < 0) return FALSE;
 
-    if (!Icc ->stream)
-    {
+    if (Icc ->TagPtrs[n]) {
+
         CopyMemory(Dest, Icc ->TagPtrs[n],  sizeof(struct tm));
     }
     else
@@ -2212,9 +2414,10 @@
     size   = Icc -> TagSizes[n];
     if (size < 12)  return NULL;
 
-    if (!Icc -> stream) {
+    if (Icc -> TagPtrs[n]) {
 
-            OutSeq = (LPcmsSEQ) malloc(size);
+            OutSeq = (LPcmsSEQ) _cmsMalloc(size);  
+            if (OutSeq == NULL) return NULL;
             CopyMemory(OutSeq, Icc ->TagPtrs[n], size);
             return OutSeq;
     }
@@ -2231,8 +2434,13 @@
     Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
     AdjustEndianess32((LPBYTE) &Count);
 
+    if (Count > 1000) {
+         return NULL;
+    }
+ 
     size = sizeof(int) + Count * sizeof(cmsPSEQDESC);
-    OutSeq = (LPcmsSEQ) malloc(size);
+    OutSeq = (LPcmsSEQ) _cmsMalloc(size);
+    if (OutSeq == NULL) return NULL;
 
     OutSeq ->n = Count;
 
@@ -2268,181 +2476,11 @@
 void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq)
 {
     if (pseq)
-        free(pseq);
-}
-
-
-
-// Extended gamut -- an HP extension
-
-
-LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index)
-{
-    LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
-    size_t size, offset;
-    icUInt32Number off_samp, off_desc, off_vc;
-    int n;
-    icTagTypeSignature     BaseType;
-    icColorSpaceSignature  CoordSig;
-    icUInt16Number         Method, Usage;
-    icUInt32Number         GamutCount, SamplesCount;
-    LPcmsGAMUTEX gex;
-    size_t                 Offsets[256];
-    size_t                 i, Actual, Loc;
-    icS15Fixed16Number     Num;
-    icUInt16Number         Surround;
-
-
-    n = _cmsSearchTag(Icc, icSigHPGamutDescTag, FALSE);
-    if (n < 0) return NULL;
-
-    if (!Icc ->stream) return NULL;     // In memory is not supported
-
-    // Read the header
-
-    offset = Icc -> TagOffsets[n];
-
-    if (Icc -> Seek(Icc, offset))
-            return NULL;
-
-    // Here is the beginning of tag
-    Actual   = Icc ->Tell(Icc);
-
-
-    BaseType = ReadBase(Icc);
-
-    if (BaseType != icSigHPGamutDescType) {
-            cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature '%lx' found.", BaseType);
-            return NULL;
-    }
-
-
-    // Read the gamut descriptors count
-    Icc ->Read(&GamutCount, sizeof(icUInt32Number), 1, Icc);
-    AdjustEndianess32((LPBYTE) &GamutCount);
-
-
-    if (GamutCount >= 256) {
-            cmsSignalError(LCMS_ERRC_ABORTED, "Too many gamut structures '%d'.", GamutCount);
-            return NULL;
-    }
-
-    // Read the directory
-
-    for (i=0; i < GamutCount; i++) {
-
-        Icc ->Read(&Offsets[i], sizeof(icUInt32Number), 1, Icc);
-        AdjustEndianess32((LPBYTE) &Offsets[i]);
-    }
-
-
-    // Is there such element?
-    if (index >= (int) GamutCount) return NULL;
-    Loc = Actual + Offsets[index];
-
-
-    // Go to specified index
-    if (Icc -> Seek(Icc, Loc))
-            return NULL;
-
-
-    // Read all members
-    Icc ->Read(&CoordSig, sizeof(icColorSpaceSignature), 1, Icc);
-    AdjustEndianess32((LPBYTE) &CoordSig);
-
-    Icc ->Read(&Method, sizeof(icUInt16Number), 1, Icc);
-    AdjustEndianess16((LPBYTE) &Method);
-
-    Icc ->Read(&Usage, sizeof(icUInt16Number), 1, Icc);
-    AdjustEndianess16((LPBYTE) &Usage);
-
-    Icc ->Read(&SamplesCount, sizeof(icUInt32Number), 1, Icc);
-    AdjustEndianess32((LPBYTE) &SamplesCount);
-
-    Icc ->Read(&off_samp, sizeof(icUInt32Number), 1, Icc);
-    AdjustEndianess32((LPBYTE) &off_samp);
-
-    Icc ->Read(&off_desc, sizeof(icUInt32Number), 1, Icc);
-    AdjustEndianess32((LPBYTE) &off_desc);
-
-    Icc ->Read(&off_vc, sizeof(icUInt32Number), 1, Icc);
-    AdjustEndianess32((LPBYTE) &off_vc);
-
-
-    size = sizeof(cmsGAMUTEX) + (SamplesCount - 1) * sizeof(double);
-
-    gex = (LPcmsGAMUTEX) malloc(size);
-        if (gex == NULL) return NULL;
-
-
-    gex ->CoordSig = CoordSig;
-    gex ->Method   = Method;
-    gex ->Usage    = Usage;
-        gex ->Count    = SamplesCount;
-
-
-    // Read data
-    if (Icc -> Seek(Icc, Loc + off_samp))
-            return NULL;
-
-    for (i=0; i < SamplesCount; i++) {
-                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-                gex ->Data[i] = Convert15Fixed16(Num);
-    }
-
-
-    // Read mluc
-    if (Icc -> Seek(Icc, Loc + off_desc)) {
-
-                        free(gex);
-            return NULL;
-        }
-
-    ReadEmbeddedTextTag(Icc, 256, gex ->Description, LCMS_DESC_MAX);
-
-
-    // Read viewing conditions
-    if (Icc -> Seek(Icc, Loc + off_vc)) {
-                        free(gex);
-            return NULL;
-        }
-
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.whitePoint.X = Convert15Fixed16(Num);
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.whitePoint.Y = Convert15Fixed16(Num);
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.whitePoint.Z = Convert15Fixed16(Num);
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.La = Convert15Fixed16(Num);
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.Yb = Convert15Fixed16(Num);
-
-    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
-    gex ->Vc.D_value = Convert15Fixed16(Num);
-
-    Icc -> Read(&Surround, sizeof(icUInt16Number), 1, Icc);
-    AdjustEndianess16((LPBYTE) &Surround);
-    gex ->Vc.surround = Surround;
-
-
-    // All OK
-    return gex;
-
+        _cmsFree(pseq);
 }
 
 
 
-void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex)
-{
-    if (gex)
-        free(gex);
-}
 
 
 // Read a few tags that are hardly required
@@ -2564,6 +2602,7 @@
            NewIcc = (LPLCMSICCPROFILE) (LPSTR) hEmpty;
            NewIcc -> IsWrite = TRUE;
            strncpy(NewIcc ->PhysicalFile, lpFileName, MAX_PATH-1);
+           NewIcc ->PhysicalFile[MAX_PATH-1] = 0;
 
            // Save LUT as 8 bit
 
@@ -2579,7 +2618,7 @@
        NewIcc = _cmsCreateProfileFromFilePlaceholder(lpFileName);
         if (!NewIcc) return NULL;
 
-       if (!ReadHeader(NewIcc, FALSE)) return NULL;
+       if (!ReadHeader(NewIcc, FALSE, 0)) return NULL;
 
        ReadCriticalTags(NewIcc);
 
@@ -2599,7 +2638,7 @@
        NewIcc = _cmsCreateProfileFromMemPlaceholder(MemPtr, dwSize);
        if (!NewIcc) return NULL;
 
-       if (!ReadHeader(NewIcc, TRUE)) return NULL;
+       if (!ReadHeader(NewIcc, TRUE, dwSize)) return NULL;
 
        ReadCriticalTags(NewIcc);
 
@@ -2609,10 +2648,11 @@
 
 
 
-BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
 {
        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
-       BOOL rc = TRUE;
+       LCMSBOOL rc = TRUE;
+       icInt32Number i;         
 
        if (!Icc) return FALSE;
 
@@ -2624,21 +2664,15 @@
            rc = _cmsSaveProfile(hProfile, Icc ->PhysicalFile);
        }
 
-
-       if (Icc -> stream == NULL) {     // Was a memory (i.e. not serialized) profile?
-
-
-              icInt32Number i;          // Yes, free tags
-
               for (i=0; i < Icc -> TagCount; i++) {
 
                   if (Icc -> TagPtrs[i])
                             free(Icc -> TagPtrs[i]);
               }
 
+       if (Icc -> stream != NULL) {     // Was a memory (i.e. not serialized) profile?
+                 Icc -> Close(Icc);     // No, close the stream      
        }
-       else   Icc -> Close(Icc);    // No, close the stream
-
 
        free(Icc);   // Free placeholder memory
 
@@ -2652,11 +2686,11 @@
 
 
 static
-BOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc)
 {
    size_t nTabSize = sizeof(WORD) * nEntries;
-   LPWORD PtrW = (LPWORD) malloc(nTabSize);
-   BOOL rc;
+   LPWORD PtrW = (LPWORD) _cmsMalloc(nTabSize);
+   LCMSBOOL rc;
 
    if (!PtrW) return FALSE;
    CopyMemory(PtrW, Tab, nTabSize);
@@ -2672,7 +2706,7 @@
 // Saves profile header
 
 static
-BOOL SaveHeader(LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveHeader(LPLCMSICCPROFILE Icc)
 {
   icHeader Header;
   time_t now = time(NULL);
@@ -2727,7 +2761,7 @@
 // Setup base marker
 
 static
-BOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc)
+LCMSBOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc)
 {
     icTagBase  Base;
 
@@ -2737,10 +2771,10 @@
 }
 
 
-// Store an XYZ tag
+// Store a XYZ tag
 
 static
-BOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
 {
 
     icXYZNumber XYZ;
@@ -2756,11 +2790,36 @@
 }
 
 
+// Store a XYZ array.
+
+static 
+LCMSBOOL SaveXYZArray(int n, LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
+{
+    int i;
+    icXYZNumber XYZ;
+
+    if (!SetupBase(icSigS15Fixed16ArrayType, Icc)) return FALSE;
+
+    for (i=0; i < n; i++) {
+
+        XYZ.X = TransportValue32(DOUBLE_TO_FIXED(Value -> X));
+        XYZ.Y = TransportValue32(DOUBLE_TO_FIXED(Value -> Y));
+        XYZ.Z = TransportValue32(DOUBLE_TO_FIXED(Value -> Z));
+
+        if (!Icc -> Write(Icc, sizeof(icXYZNumber), &XYZ)) return FALSE;
+
+        Value++;
+    }
+
+    return TRUE;
+}
+
+
 
 // Save a gamma structure as a table
 
 static
-BOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 {
         icInt32Number Count;
 
@@ -2777,7 +2836,7 @@
 // Save a gamma structure as a one-value
 
 static
-BOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 {
         icInt32Number Count;
         Fixed32 GammaFixed32;
@@ -2798,7 +2857,7 @@
 // Save a gamma structure as a parametric gamma
 
 static
-BOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 {
         icUInt16Number Type, Reserved;
         int i, nParams;
@@ -2829,7 +2888,7 @@
 // Save a gamma table
 
 static
-BOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 {
                 // Is the gamma curve type supported by ICC format?
 
@@ -2861,7 +2920,7 @@
 // Save an DESC Tag
 
 static
-BOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc)
 {
 
     icUInt32Number len, Count, TotalSize, AlignedSize;
@@ -2893,6 +2952,11 @@
     if (!Icc ->Write(Icc, len, (LPVOID)Text)) return FALSE;
     AlignedSize -= len;
 
+    if (AlignedSize < 0)
+            AlignedSize = 0;
+    if (AlignedSize > 255) 
+            AlignedSize = 255;
+
     ZeroMemory(Filler, AlignedSize);
     if (!Icc ->Write(Icc, AlignedSize, Filler)) return FALSE;
 
@@ -2902,7 +2966,7 @@
 // Save an ASCII Tag
 
 static
-BOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc)
 {
     size_t len = strlen(Text) + 1;
 
@@ -2915,7 +2979,7 @@
 // Save one of these new chromaticity values
 
 static
-BOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc)
 {
        Fixed32 xf, yf;
 
@@ -2932,7 +2996,7 @@
 // New tag added in Addendum II of old spec.
 
 static
-BOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc)
 {
        WORD nChans, Table;
 
@@ -2952,7 +3016,7 @@
 
 
 static
-BOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc)
 {
     icUInt32Number nSeqs;
     icDescStruct   DescStruct;
@@ -2989,7 +3053,7 @@
 // Saves a timestamp tag
 
 static
-BOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc)
 {
     icDateTimeNumber Dest;
 
@@ -3003,14 +3067,14 @@
 
 // Saves a named color list into a named color profile
 static
-BOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 {
 
     icUInt32Number      vendorFlag;     // Bottom 16 bits for IC use
     icUInt32Number      count;          // Count of named colors
     icUInt32Number      nDeviceCoords;  // Num of device coordinates
-    icInt8Number        prefix[32];     // Prefix for each color name
-    icInt8Number        suffix[32];     // Suffix for each color name
+    char                prefix[32];     // Prefix for each color name 
+    char                suffix[32];     // Suffix for each color name 
     int i;
 
     if (!SetupBase(icSigNamedColor2Type, Icc)) return FALSE;
@@ -3022,6 +3086,8 @@
     strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
     strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
 
+    suffix[31] = prefix[31] = 0;
+
     if (!Icc ->Write(Icc, sizeof(icUInt32Number), &vendorFlag)) return FALSE;
     if (!Icc ->Write(Icc, sizeof(icUInt32Number), &count)) return FALSE;
     if (!Icc ->Write(Icc, sizeof(icUInt32Number), &nDeviceCoords)) return FALSE;
@@ -3032,13 +3098,15 @@
 
           icUInt16Number PCS[3];
           icUInt16Number Colorant[MAXCHANNELS];
-          icInt8Number root[32];
+          char            root[32];
           LPcmsNAMEDCOLOR Color;
           int j;
 
                     Color = NamedColorList ->List + i;
 
-                    strncpy((char*) root, Color ->Name, 32);
+                    strncpy(root, Color ->Name, 32);
+                    Color ->Name[32] = 0;
+
                     if (!Icc ->Write(Icc, 32 , root)) return FALSE;
 
                     for (j=0; j < 3; j++)
@@ -3062,7 +3130,7 @@
 // Saves a colorant table. It is using the named color structure for simplicity sake
 
 static
-BOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 {
      icUInt32Number count;  // Count of named colors
      int i;
@@ -3076,13 +3144,15 @@
      for (i=0; i < NamedColorList ->nColors; i++) {
 
       icUInt16Number PCS[3];
-      icInt8Number root[32];
+      icInt8Number root[33];
       LPcmsNAMEDCOLOR Color;
       int j;
 
             Color = NamedColorList ->List + i;
 
             strncpy((char*) root, Color ->Name, 32);
+            root[32] = 0;
+
             if (!Icc ->Write(Icc, 32 , root)) return FALSE;
 
             for (j=0; j < 3; j++)
@@ -3099,7 +3169,7 @@
 // Does serialization of LUT16 and writes it.
 
 static
-BOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 {
        icLut16 LUT16;
        unsigned int i;
@@ -3189,7 +3259,7 @@
 // Does serialization of LUT8 and writes it
 
 static
-BOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 {
        icLut8 LUT8;
        unsigned int i, j;
@@ -3323,7 +3393,7 @@
 // Saves Tag directory
 
 static
-BOOL SaveTagDirectory(LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveTagDirectory(LPLCMSICCPROFILE Icc)
 {
        icInt32Number i;
        icTag Tag;
@@ -3356,7 +3426,7 @@
 // Dump tag contents
 
 static
-BOOL SaveTags(LPLCMSICCPROFILE Icc)
+LCMSBOOL SaveTags(LPLCMSICCPROFILE Icc, LPLCMSICCPROFILE FileOrig)
 {
 
     LPBYTE Data;
@@ -3384,8 +3454,31 @@
 
        Icc -> TagOffsets[i] = Begin = Icc ->UsedSpace;
        Data = (LPBYTE) Icc -> TagPtrs[i];
-       if (!Data)
+       if (!Data) {
+
+           // Reach here if we are copying a tag from a disk-based ICC profile which has not been modified by user. 
+           // In this case a blind copy of the block data is performed
+
+           if (Icc -> TagOffsets[i]) {
+
+                    size_t TagSize   = FileOrig -> TagSizes[i];
+                    size_t TagOffset = FileOrig -> TagOffsets[i];
+                    void* Mem;
+
+                    if (FileOrig ->Seek(FileOrig, TagOffset)) return FALSE;
+
+                    Mem = _cmsMalloc(TagSize);                  
+
+                    if (FileOrig ->Read(Mem, TagSize, 1, FileOrig) != 1) return FALSE;
+                    if (!Icc ->Write(Icc, TagSize, Mem)) return FALSE;
+
+                    Icc -> TagSizes[i] = (Icc ->UsedSpace - Begin);
+                    free(Mem);
+           }
+
               continue;
+       }
+
 
        switch (Icc -> TagNames[i]) {
 
@@ -3464,6 +3557,10 @@
              break;
 
 
+       case icSigChromaticAdaptationTag:
+              if (!SaveXYZArray(3, (LPcmsCIEXYZ) Data, Icc)) return FALSE;
+              break;
+
        default:
               return FALSE;
        }
@@ -3480,9 +3577,9 @@
 
 // Add tags to profile structure
 
-BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag)
+LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag)
 {
-   BOOL rc;
+   LCMSBOOL rc;
 
    switch (sig) {
 
@@ -3543,6 +3640,11 @@
               rc = _cmsAddColorantTableTag(hProfile, sig, (LPcmsNAMEDCOLORLIST) Tag);
               break;
 
+
+       case icSigChromaticAdaptationTag:
+              rc = _cmsAddChromaticAdaptationTag(hProfile, sig, (const cmsCIEXYZ*) Tag);
+              break;
+
        default:
             cmsSignalError(LCMS_ERRC_ABORTED, "cmsAddTag: Tag '%x' is unsupported", sig);
             return FALSE;
@@ -3568,11 +3670,11 @@
 
 // Low-level save to disk. It closes the profile on exit
 
-BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName)
+LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName)
 {
        LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
        LCMSICCPROFILE Keep;
-       BOOL rc;
+       LCMSBOOL rc;
 
         CopyMemory(&Keep, Icc, sizeof(LCMSICCPROFILE));
        _cmsSetSaveToDisk(Icc, NULL);
@@ -3581,7 +3683,7 @@
 
        if (!SaveHeader(Icc)) return FALSE;
        if (!SaveTagDirectory(Icc)) return FALSE;
-       if (!SaveTags(Icc)) return FALSE;
+       if (!SaveTags(Icc, &Keep)) return FALSE;
 
 
        _cmsSetSaveToDisk(Icc, FileName);
@@ -3591,7 +3693,7 @@
 
        if (!SaveHeader(Icc)) goto CleanUp;
        if (!SaveTagDirectory(Icc)) goto CleanUp;
-       if (!SaveTags(Icc)) goto CleanUp;
+       if (!SaveTags(Icc, &Keep)) goto CleanUp;
 
        rc = (Icc ->Close(Icc) == 0);
        CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
@@ -3608,7 +3710,7 @@
 
 
 // Low-level save from open stream
-BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
+LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, 
                                                            size_t* BytesNeeded)
 {
     LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@@ -3623,7 +3725,7 @@
 
     if (!SaveHeader(Icc)) return FALSE;
     if (!SaveTagDirectory(Icc)) return FALSE;
-    if (!SaveTags(Icc)) return FALSE;
+    if (!SaveTags(Icc, &Keep)) return FALSE;              
 
     if (!MemPtr) {
 
@@ -3646,7 +3748,7 @@
     // Pass #2 does save to file into supplied stream
     if (!SaveHeader(Icc)) goto CleanUp;
     if (!SaveTagDirectory(Icc)) goto CleanUp;
-    if (!SaveTags(Icc)) goto CleanUp;
+    if (!SaveTags(Icc, &Keep)) goto CleanUp;
 
     // update BytesSaved so caller knows how many bytes put into stream
     *BytesNeeded = Icc ->UsedSpace;
@@ -3662,10 +3764,10 @@
     return FALSE;
 }
 
-BOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
+LCMSBOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
 				  void *data, size_t size)
 {
-  BOOL isNew;
+  LCMSBOOL isNew;
   int i, idx, delta, count;
   LPBYTE padChars[3] = {0, 0, 0};
   LPBYTE beforeBuf, afterBuf, ptr;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -118,7 +118,7 @@
 {
        LPLUT NewLUT;
 
-       NewLUT = (LPLUT) malloc(sizeof(LUT));
+       NewLUT = (LPLUT) _cmsMalloc(sizeof(LUT));
        if (NewLUT)
               ZeroMemory(NewLUT, sizeof(LUT));
 
@@ -171,9 +171,10 @@
 static
 LPVOID DupBlockTab(LPVOID Org, size_t size)
 {
-    LPVOID mem = malloc(size);
-
+    LPVOID mem = _cmsMalloc(size);
+    if (mem != NULL)
     CopyMemory(mem, Org, size);
+
     return mem;
 }
 
@@ -211,6 +212,37 @@
 }
 
 
+LCMSBOOL _cmsValidateLUT(LPLUT NewLUT)
+{
+    unsigned int calc = 1;
+    unsigned int oldCalc;
+    unsigned int power = NewLUT -> InputChan;
+
+    if (NewLUT -> cLutPoints > 100) return FALSE;
+    if (NewLUT -> InputChan > MAXCHANNELS)  return FALSE;
+    if (NewLUT -> OutputChan > MAXCHANNELS) return FALSE;
+
+    if (NewLUT -> cLutPoints == 0) return TRUE;
+    
+    for (; power > 0; power--) {
+
+      oldCalc = calc;
+      calc *= NewLUT -> cLutPoints;
+
+      if (calc / NewLUT -> cLutPoints != oldCalc) {
+        return FALSE;
+      }
+    }
+
+    oldCalc = calc;
+    calc *= NewLUT -> OutputChan;
+    if (NewLUT -> OutputChan && calc / NewLUT -> OutputChan != oldCalc) {
+      return FALSE;
+    }
+
+    return TRUE;
+}
+
 LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan)
 {
     DWORD nTabSize;
@@ -220,12 +252,17 @@
        NewLUT -> InputChan     = inputChan;
        NewLUT -> OutputChan    = outputChan;
 
+       if (!_cmsValidateLUT(NewLUT)) {
+         return NULL;
+       }
+
+       nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
+                                               NewLUT->InputChan);
 
-       nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
-                                                NewLUT->InputChan)
-                                                * sizeof(WORD));
+       NewLUT -> T = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
+       nTabSize *= sizeof(WORD);
+       if (NewLUT -> T == NULL) return NULL;
 
-       NewLUT -> T = (LPWORD) malloc(nTabSize);
        ZeroMemory(NewLUT -> T, nTabSize);
        NewLUT ->Tsize = nTabSize;
 
@@ -254,7 +291,9 @@
 
                for (i=0; i < NewLUT -> InputChan; i++) {
 
-                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries);
+                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries);
+                     if (PtrW == NULL) return NULL;
+
                      NewLUT -> L1[i] = PtrW;
                      CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries);
                                          CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@@ -268,7 +307,9 @@
                NewLUT -> OutputEntries = Tables[0] -> nEntries;
                for (i=0; i < NewLUT -> OutputChan; i++) {
 
-                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries);
+                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries);
+                     if (PtrW == NULL) return NULL;
+
                      NewLUT -> L2[i] = PtrW;
                      CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries);
                                          CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@@ -285,7 +326,9 @@
 
                for (i=0; i < NewLUT -> InputChan; i++) {
 
-                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries);
+                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L3Entries);
+                     if (PtrW == NULL) return NULL;
+
                      NewLUT -> L3[i] = PtrW;
                      CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries);
                                          CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@@ -298,7 +341,9 @@
                NewLUT -> L4Entries = Tables[0] -> nEntries;
                for (i=0; i < NewLUT -> OutputChan; i++) {
 
-                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L4Entries);
+                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L4Entries);
+                     if (PtrW == NULL) return NULL;
+
                      NewLUT -> L4[i] = PtrW;
                      CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries);
                                          CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@@ -580,7 +625,7 @@
    LPL16PARAMS p = &Lut ->CLut16params;
 
 
-   p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS));
+   p8 = (LPL8PARAMS) _cmsMalloc(sizeof(L8PARAMS));
    if (p8 == NULL) return NULL;
 
   // values comes * 257, so we can safely take first byte (x << 8 + x)
@@ -593,8 +638,8 @@
            if (Lut ->wFlags & LUT_HASTL1) {
 
               for (j=0; j < 3; j++)
-                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
-                                                        Lut -> L1[i],
+                     StageABC[j] = cmsLinearInterpLUT16(StageABC[j],
+                                                        Lut -> L1[j],
                                                        &Lut -> In16params);
               Lut ->wFlags &= ~LUT_HASTL1;
            }
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -89,7 +89,7 @@
        {
         LPWORD PtrW;
 
-        PtrW = (LPWORD) malloc(sizeof(WORD) * p16 -> nSamples);
+        PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * p16 -> nSamples);
 
         if (PtrW == NULL) return -1;  // Signal error
 
@@ -119,7 +119,7 @@
        LPMATSHAPER NewMatShaper;
        int rc;
 
-       NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER));
+       NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
        if (NewMatShaper)
               ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
 
@@ -171,7 +171,7 @@
        LPMATSHAPER NewMatShaper;
        int i, AllLinear;
 
-       NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER));
+       NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
        if (NewMatShaper)
               ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
 
@@ -197,7 +197,7 @@
        {
         LPWORD PtrW;
 
-        PtrW = (LPWORD) malloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
+        PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
 
         if (PtrW == NULL) {
               cmsFreeMatShaper(NewMatShaper);
@@ -235,11 +235,11 @@
 
        for (i=0; i < 3; i++)
        {
-              if (MatShaper -> L[i]) free(MatShaper ->L[i]);
-              if (MatShaper -> L2[i]) free(MatShaper ->L2[i]);
+              if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]);
+              if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]);
        }
 
-       free(MatShaper);
+       _cmsFree(MatShaper);
 }
 
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -74,7 +74,7 @@
 void   cdecl MAT3identity(LPMAT3 a);
 void   cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
 int    cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
-BOOL   cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
+LCMSBOOL  cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
 double cdecl MAT3det(LPMAT3 m);
 void   cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
 void   cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
@@ -345,13 +345,13 @@
 // Check id two vectors are the same, allowing tolerance
 
 static
-BOOL RangeCheck(double l, double h, double v)
+LCMSBOOL RangeCheck(double l, double h, double v)
 {
        return (v >= l && v <= h);
 }
 
 
-BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
+LCMSBOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
 {
        int i;
        double c;
@@ -367,7 +367,7 @@
        return TRUE;
 }
 
-BOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
+LCMSBOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
 {
        int i;
        double c;
@@ -462,7 +462,7 @@
 
 // Check if matrix is Identity. Allow a tolerance as %
 
-BOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
+LCMSBOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
 {
        int i;
        MAT3 Idd;
@@ -545,7 +545,7 @@
 
 // Solve a system in the form Ax = b
 
-BOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b)
+LCMSBOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b)
 {
         MAT3 m, a_1;
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -74,7 +74,7 @@
                 NewElements *= 2;
 
         size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements);
-        TheNewList = (LPcmsNAMEDCOLORLIST) malloc(size);
+        TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
 
 
         if (TheNewList == NULL) {
@@ -86,7 +86,7 @@
               CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR));
               TheNewList -> Allocated = NewElements;
 
-              free(v);
+              _cmsFree(v);
               return TheNewList;
         }
     }
@@ -99,7 +99,7 @@
 {
     size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR);
 
-    LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) malloc(size);
+    LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
 
 
     if (v == NULL) {
@@ -124,10 +124,10 @@
         return;
     }
 
-    free(v);
+    _cmsFree(v);
 }
 
-BOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS])
+LCMSBOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS])
 {
     _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
     LPcmsNAMEDCOLORLIST List;
@@ -164,7 +164,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix)
+LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix)
 {
     _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
 
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c	2009-04-03 13:42:46.000000000 -0400
@@ -28,7 +28,7 @@
 // file:
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -639,9 +639,81 @@
 
 
 
+static
+LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
+{
+    double* Inks = (double*) accum;
+    double v;
+    
+    
+    v = floor(Inks[0] * 65535.0 + 0.5);
+    
+    if (v > 65535.0) v = 65535.0;
+    if (v < 0) v = 0;
+    
+    
+    wIn[0] = wIn[1] = wIn[2] = (WORD) v;
+    
+    return accum + sizeof(double);    
+}
+
+
 // ----------------------------------------------------------- Packing routines
 
 
+// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
+
+static int err[MAXCHANNELS];
+
+static
+LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+       int nChan  = T_CHANNELS(info -> OutputFormat);
+       register int i;
+       unsigned int n, pe, pf;
+
+       for (i=0; i < nChan;  i++) {
+
+              n = wOut[i] + err[i]; // Value
+             
+              pe = (n / 257);       // Whole part
+              pf = (n % 257);       // Fractional part
+
+              err[i] = pf;          // Store it for next pixel
+
+              *output++ = (BYTE) pe;
+       }
+
+       return output + T_EXTRA(info ->OutputFormat);
+}
+
+
+
+static
+LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
+{
+       int nChan  = T_CHANNELS(info -> OutputFormat);
+       register int i;
+       unsigned int n, pe, pf;
+
+       for (i=nChan-1; i >= 0;  --i) {
+
+              n = wOut[i] + err[i];     // Value
+
+              pe = (n / 257);           // Whole part
+              pf = (n % 257);           // Fractional part
+
+              err[i] = pf;              // Store it for next pixel
+
+              *output++ = (BYTE) pe;
+       }
+
+
+       return output + T_EXTRA(info ->OutputFormat);
+}
+
+
+
 // Generic chunky for byte
 
 static
@@ -1486,6 +1558,9 @@
            case PT_HSV:
            case PT_HLS:
            case PT_Yxy:
+                    if (T_CHANNELS(dwInput) == 1)
+                        FromInput = UnrollDouble1Chan;
+                    else
                     FromInput = UnrollDouble;
                     break;
 
@@ -1749,6 +1824,9 @@
                      switch (T_CHANNELS(dwOutput))
                      {
                      case 1:
+                            if (T_DITHER(dwOutput))
+                                    ToOutput = PackNBytesDither;
+                            else                                        
                             ToOutput = Pack1Byte;
                             if (T_EXTRA(dwOutput) == 1) {
                                 if (T_SWAPFIRST(dwOutput))
@@ -1766,8 +1844,12 @@
                                  else
                                      if (T_COLORSPACE(dwOutput) == PT_Lab)
                                         ToOutput = Pack3BytesLab;
+                                     else {
+                                         if (T_DITHER(dwOutput))
+                                                 ToOutput = PackNBytesDither;
                                      else
                                         ToOutput = Pack3Bytes;
+                                     }
                              break;
 
                          case 1:    // TODO: ALab8 should be handled here
@@ -1793,13 +1875,23 @@
 
                      case 4: if (T_EXTRA(dwOutput) == 0) {
 
+ 
                                 if (T_DOSWAP(dwOutput)) {
 
-                                     if (T_SWAPFIRST(dwOutput))
+
+                                     if (T_SWAPFIRST(dwOutput)) {
                                          ToOutput = Pack4BytesSwapSwapFirst;
-                                     else
+                                     }
+                                     else {
+
+                                           if (T_DITHER(dwOutput)) {
+                                                  ToOutput = PackNBytesSwapDither;
+                                           }
+                                           else {
                                          ToOutput = Pack4BytesSwap;
                                  }
+                                     }
+                                 }
                                  else {
                                      if (T_SWAPFIRST(dwOutput))
                                          ToOutput = Pack4BytesSwapFirst;
@@ -1807,11 +1899,15 @@
 
                                          if (T_FLAVOR(dwOutput))
                                              ToOutput = Pack4BytesReverse;
+                                         else {
+                                             if (T_DITHER(dwOutput))
+                                                 ToOutput = PackNBytesDither;
                                          else
                                              ToOutput = Pack4Bytes;
                                      }
                                  }
                              }
+                             }
                             else {
                                     if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
                                              ToOutput = PackNBytes;
@@ -1849,9 +1945,14 @@
                             {
                                    if (T_DOSWAP(dwOutput))
                                           ToOutput = PackNBytesSwap;
+                                   else {
+
+                                       if (T_DITHER(dwOutput))
+                                                 ToOutput = PackNBytesDither;
                                    else
                                           ToOutput = PackNBytes;
                             }
+                            }
                             break;
 
                      default:;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -144,6 +144,8 @@
             /Table [ p p p [<...>]]
             /RangeABC [ 0 1 0 1 0 1]
             /DecodeABC[ <postlinearization> ]
+            /RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ] 
+               % -128/500 1+127/500 0 1  -127/200 1+128/200 
             /MatrixABC [ 1 1 1 1 0 0 0 0 -1]
             /WhitePoint [D50]
             /BlackPoint [BP]
@@ -347,7 +349,8 @@
 static
 LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols)
 {
-    LPMEMSTREAM m = (LPMEMSTREAM) malloc(sizeof(MEMSTREAM));
+    LPMEMSTREAM m = (LPMEMSTREAM) _cmsMalloc(sizeof(MEMSTREAM));
+    if (m == NULL) return NULL;
 
     ZeroMemory(m, sizeof(MEMSTREAM));
 
@@ -422,7 +425,7 @@
 
 }
 
-// Does write a formatted string
+// Does write a formatted string. Guaranteed to be 2048 bytes at most.
 static
 void Writef(LPMEMSTREAM m, const char *frm, ...)
 {
@@ -432,7 +435,7 @@
 
         va_start(args, frm);
 
-        vsprintf((char*) Buffer, frm, args);
+        vsnprintf((char*) Buffer, 2048, frm, args);
 
         for (pt = Buffer; *pt; pt++)  {
 
@@ -562,7 +565,7 @@
     Writef(m, "{255 mul 128 sub 200 div } bind\n");
     Writef(m, "]\n");
     Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
-        Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
+    Writef(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n"); 
     Writef(m, "/DecodeLMN [\n");
     Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n");
     Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
@@ -584,7 +587,11 @@
     if (nEntries <= 0) return;  // Empty table
 
     // Suppress whole if identity
-    if (cmsIsLinear(Table, nEntries)) return;
+    if (cmsIsLinear(Table, nEntries)) {
+            Writef(m, "{} ");
+            return;
+    }
+
 
     // Check if is really an exponential. If so, emit "exp"
      gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
@@ -646,7 +653,7 @@
 // Compare gamma table
 
 static
-BOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
+LCMSBOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
 {
     return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0;
 }
@@ -676,7 +683,7 @@
 // Check whatever a profile has CLUT tables (only on input)
 
 static
-BOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
+LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
 {
     icTagSignature Tag;
 
@@ -718,10 +725,10 @@
 
     if (sc -> FixWhite) {
 
-        if (In[0] == 0xFFFF) {  // Only in L* = 100
+        if (In[0] == 0xFFFF) {  // Only in L* = 100, ab = [-8..8]
 
-            if ((In[1] >= 0x8000 && In[1] <= 0x87FF) ||
-                (In[2] >= 0x8000 && In[2] <= 0x87FF)) {
+            if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
+                (In[2] >= 0x7800 && In[2] <= 0x8800)) {
 
                 WORD* Black;
                 WORD* White;
@@ -830,7 +837,7 @@
     sc.PostMaj= PostMaj;
 
     sc.PreMin = PreMin;
-    sc.PostMin= PostMin;
+    sc.PostMin  = PostMin;
     sc.lIsInput = lIsInput;
     sc.FixWhite = FixWhite;
     sc.ColorSpace = ColorSpace;
@@ -1231,7 +1238,7 @@
 
         if (!WriteNamedColorCSA(mem, hProfile, Intent)) {
 
-                    free((void*) mem);
+                    _cmsFree((void*) mem);
                     return 0;
         }
     }
@@ -1246,7 +1253,7 @@
         ColorSpace != icSigLabData) {
 
             cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
-            free((void*) mem);
+            _cmsFree((void*) mem);
             return 0;
     }
 
@@ -1256,7 +1263,7 @@
         // Yes, so handle as LUT-based
         if (!WriteInputLUT(mem, hProfile, Intent)) {
 
-                    free((void*) mem);
+                    _cmsFree((void*) mem);
                     return 0;
         }
     }
@@ -1266,7 +1273,7 @@
 
         if (!WriteInputMatrixShaper(mem, hProfile)) {
 
-                    free((void*) mem);  // Something went wrong
+                    _cmsFree((void*) mem);  // Something went wrong
                     return 0;
         }
     }
@@ -1277,7 +1284,7 @@
     dwBytesUsed = mem ->dwUsed;
 
     // Get rid of memory stream
-    free((void*) mem);
+    _cmsFree((void*) mem);
 
     // Finally, return used byte count
     return dwBytesUsed;
@@ -1350,27 +1357,40 @@
 
 
 static
-void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
+void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
 {
 
 
-        Writef(m,"%% Bradford Cone Space\n"
-                 "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
+        if (lIsAbsolute) {
 
-        Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
+            // For absolute colorimetric intent, encode back to relative 
+            // and generate a relative LUT
 
+            // Relative encoding is obtained across XYZpcs*(D50/WhitePoint)
 
-        if (lIsAbsolute) {
+            cmsCIEXYZ White;
 
-            // For absolute colorimetric intent, do nothing
+            cmsTakeMediaWhitePoint(&White, hProfile);
 
-            Writef(m, "%% Absolute colorimetric -- no transformation\n"
+            Writef(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
+            Writef(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
+
+            Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
                       "/TransformPQR [\n"
-                      "{exch pop exch pop exch pop exch pop} bind dup dup]\n");
+                      "{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
+                      "{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
+                      "{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n", 
+                      White.X, White.Y, White.Z);
             return;
         }
 
 
+        Writef(m,"%% Bradford Cone Space\n"
+                 "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
+
+        Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
+
+
         // No BPC
 
         if (!DoBPC) {
@@ -1414,6 +1434,7 @@
 static
 void EmitXYZ2Lab(LPMEMSTREAM m)
 {
+    Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n"); 
     Writef(m, "/EncodeLMN [\n");
     Writef(m, "{ 0.964200  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
     Writef(m, "{ 1.000000  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
@@ -1423,17 +1444,10 @@
     Writef(m, "/EncodeABC [\n");
 
 
-
     Writef(m, "{ 116 mul  16 sub 100 div  } bind\n");
-    Writef(m, "{ 500 mul 128 add 255 div  } bind\n");
-    Writef(m, "{ 200 mul 128 add 255 div  } bind\n");
-
+    Writef(m, "{ 500 mul 128 add 256 div  } bind\n");
+    Writef(m, "{ 200 mul 128 add 256 div  } bind\n");
 
-    /*
-    Writef(m, "{ 116 mul  16 sub 256 mul 25700 div  } bind\n");
-    Writef(m, "{ 500 mul 128 add 256 mul 65535 div  } bind\n");
-    Writef(m, "{ 200 mul 128 add 256 mul 65535 div  } bind\n");
-    */
 
     Writef(m, "]\n");
 
@@ -1458,20 +1472,27 @@
     LPLUT DeviceLink;
     cmsHPROFILE Profiles[3];
     cmsCIEXYZ BlackPointAdaptedToD50;
-    BOOL lFreeDeviceLink = FALSE;
-    BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
+    LCMSBOOL lFreeDeviceLink = FALSE;
+    LCMSBOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
+    LCMSBOOL lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
+    int RelativeEncodingIntent;
 
 
-    // Trick our v4 profile as it were v2. This prevents the ajusting done
-    // in perceptual & saturation. We only neew v4 encoding!
 
-    hLab         = cmsCreateLab4Profile(NULL);
-    cmsSetProfileICCversion(hLab, 0);
+    hLab = cmsCreateLabProfile(NULL);
 
     ColorSpace  =  cmsGetColorSpace(hProfile);
     nChannels   = _cmsChannelsOf(ColorSpace);
     OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);
 
+    // For absolute colorimetric, the LUT is encoded as relative 
+    // in order to preserve precission.
+
+    RelativeEncodingIntent = Intent;
+    if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
+        RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;
+
+
     // Is a devicelink profile?
     if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
 
@@ -1479,13 +1500,14 @@
 
         if (ColorSpace == icSigLabData) {
 
-              // adjust input to Lab to out v4
+              // adjust input to Lab to our v4
 
             Profiles[0] = hLab;
             Profiles[1] = hProfile;
 
             xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
-                                                        OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
+                                                        OutputFormat, RelativeEncodingIntent, 
+                                                        dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
 
         }
         else {
@@ -1499,7 +1521,7 @@
 
         // This is a normal profile
         xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile,
-                            OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
+                            OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
     }
 
     if (xform == NULL) {
@@ -1515,7 +1537,7 @@
 
     if (!DeviceLink) {
 
-        DeviceLink = _cmsPrecalculateDeviceLink(xform, 0);
+        DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION);
         lFreeDeviceLink = TRUE;
     }
 
@@ -1527,7 +1549,7 @@
 
     // Emit headers, etc.
     EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
-    EmitPQRStage(m, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
+    EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
     EmitXYZ2Lab(m);
 
     if (DeviceLink ->wFlags & LUT_HASTL1) {
@@ -1544,10 +1566,13 @@
     // zero. This would sacrifice a bit of highlights, but failure to do so would cause
     // scum dot. Ouch.
 
+    if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
+            lFixWhite = FALSE;
+
     Writef(m, "/RenderTable ");
 
     WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
-                (Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace);
+                lFixWhite, ColorSpace);
 
     Writef(m, " %d {} bind ", nChannels);
 
@@ -1582,6 +1607,9 @@
     int j;
 
     Colorant[0] = 0;
+    if (nColorant > MAXCHANNELS)
+        nColorant = MAXCHANNELS;
+
     for (j=0; j < nColorant; j++) {
 
                 sprintf(Buff, "%.3f", Out[j] / 65535.0);
@@ -1677,7 +1705,7 @@
 
         if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
 
-                    free((void*) mem);
+                    _cmsFree((void*) mem);
                     return 0;
         }
     }
@@ -1687,7 +1715,7 @@
 
 
     if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
-        free((void*) mem);
+        _cmsFree((void*) mem);
         return 0;
     }
     }
@@ -1702,7 +1730,7 @@
     dwBytesUsed = mem ->dwUsed;
 
     // Get rid of memory stream
-    free((void*) mem);
+    _cmsFree((void*) mem);
 
     // Finally, return used byte count
     return dwBytesUsed;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -120,7 +120,7 @@
 // This routine does a sweep on whole input space, and calls its callback
 // function on knots. returns TRUE if all ok, FALSE otherwise.
 
-BOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags)
+LCMSBOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags)
 {
    int i, t, nTotalPoints, Colorant, index;
    WORD In[MAXCHANNELS], Out[MAXCHANNELS];
@@ -145,12 +145,16 @@
                                                 &Lut -> In16params);
         }
 
+        for (t=0; t < (int) Lut -> OutputChan; t++)
+                     Out[t] = Lut->T[index + t];
 
-        // if (dwFlags & SAMPLER_INSPECT) {
+        if (dwFlags & SAMPLER_HASTL2) {
 
              for (t=0; t < (int) Lut -> OutputChan; t++)
-                        Out[t] = Lut->T[index + t];
-        // }
+                     Out[t] = cmsLinearInterpLUT16(Out[t],
+                                                   Lut -> L2[t],
+                                                   &Lut -> Out16params);               
+        }   
 
 
         if (!Sampler(In, Out, Cargo))
@@ -255,6 +259,7 @@
        LPLUT Grid;
        int nGridPoints;
        DWORD dwFormatIn, dwFormatOut;
+       DWORD SaveFormatIn, SaveFormatOut;
        int ChannelsIn, ChannelsOut;
        LPLUT SaveGamutLUT;
 
@@ -276,6 +281,11 @@
        dwFormatIn   = (CHANNELS_SH(ChannelsIn)|BYTES_SH(2));
        dwFormatOut  = (CHANNELS_SH(ChannelsOut)|BYTES_SH(2));
 
+       SaveFormatIn  = p ->InputFormat;
+       SaveFormatOut = p ->OutputFormat;
+
+       p -> InputFormat  = dwFormatIn;
+       p -> OutputFormat = dwFormatOut;
        p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn);
        p -> ToOutput  = _cmsIdentifyOutputFormat(p, dwFormatOut);
 
@@ -297,11 +307,13 @@
        if (!cmsSample3DGrid(Grid, XFormSampler, (LPVOID) p, Grid -> wFlags)) {
 
                 cmsFreeLUT(Grid);
-                return NULL;
+                Grid = NULL;
        }
 
-
        p ->Gamut = SaveGamutLUT;
+       p ->InputFormat  = SaveFormatIn; 
+       p ->OutputFormat = SaveFormatOut;
+
        return Grid;
 }
 
@@ -348,7 +360,7 @@
 
 
 
-// That is our K-preserving callback.
+// Preserve all K plane.
 static
 int BlackPreservingSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
 {
@@ -469,6 +481,7 @@
     return OldVal;
 }
 
+#pragma warning(disable: 4550)
 
 // Get a pointer to callback on depending of strategy
 static
@@ -508,7 +521,7 @@
        // Fill in cargo struct
        Cargo.cmyk2cmyk = hCMYK2CMYK;
 
-       // Compute tone curve
+       // Compute tone curve.       
        Cargo.KTone  =  _cmsBuildKToneCurve(hCMYK2CMYK, 256);
        if (Cargo.KTone == NULL) return NULL;
        cmsCalcL16Params(Cargo.KTone ->nEntries, &Cargo.KToneParams);
@@ -654,7 +667,7 @@
 
 
 
-BOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
+LCMSBOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
 {
 
        WORD *WhitePointIn, *WhitePointOut, *BlackPointIn, *BlackPointOut;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -320,7 +320,7 @@
     cmsHPROFILE hICC;
     _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform;
     LPLUT Lut;
-    BOOL MustFreeLUT;
+    LCMSBOOL MustFreeLUT;
     LPcmsNAMEDCOLORLIST InputColorant = NULL;
     LPcmsNAMEDCOLORLIST OutputColorant = NULL;
 
@@ -446,6 +446,7 @@
 
        // Creates a LUT with prelinearization step only
        Lut = cmsAllocLUT();
+       if (Lut == NULL) return NULL;
 
        // Set up channels
        Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace);
@@ -548,6 +549,10 @@
 
        // Creates a LUT with 3D grid only
        Lut = cmsAllocLUT();
+       if (Lut == NULL) {
+           cmsCloseProfile(hICC);
+           return NULL;
+           }
 
 
        cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace),
@@ -584,8 +589,9 @@
 LPLUT Create3x3EmptyLUT(void)
 {
         LPLUT AToB0 = cmsAllocLUT();
-        AToB0 -> InputChan = AToB0 -> OutputChan = 3;
+        if (AToB0 == NULL) return NULL;
 
+        AToB0 -> InputChan = AToB0 -> OutputChan = 3;
         return AToB0;
 }
 
@@ -597,8 +603,8 @@
         cmsHPROFILE hProfile;
         LPLUT Lut;
 
-
         hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
+        if (hProfile == NULL) return NULL;
 
         cmsSetDeviceClass(hProfile, icSigAbstractClass);
         cmsSetColorSpace(hProfile,  icSigLabData);
@@ -611,7 +617,10 @@
 
        // An empty LUTs is all we need
        Lut = Create3x3EmptyLUT();
-       if (Lut == NULL) return NULL;
+       if (Lut == NULL) {
+           cmsCloseProfile(hProfile);
+           return NULL;
+           }
 
        cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
        cmsAddTag(hProfile, icSigBToA0Tag,    (LPVOID) Lut);
@@ -628,8 +637,8 @@
         cmsHPROFILE hProfile;
         LPLUT Lut;
 
-
         hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
+        if (hProfile == NULL) return NULL;
 
         cmsSetProfileICCversion(hProfile, 0x4000000);
 
@@ -644,7 +653,10 @@
 
        // An empty LUTs is all we need
        Lut = Create3x3EmptyLUT();
-       if (Lut == NULL) return NULL;
+       if (Lut == NULL) {
+           cmsCloseProfile(hProfile);
+           return NULL;
+           }
 
        Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2;
        cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
@@ -666,6 +678,7 @@
         LPLUT Lut;
 
         hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL);
+        if (hProfile == NULL) return NULL;
 
         cmsSetDeviceClass(hProfile, icSigAbstractClass);
         cmsSetColorSpace(hProfile, icSigXYZData);
@@ -677,7 +690,10 @@
 
        // An empty LUTs is all we need
        Lut = Create3x3EmptyLUT();
-       if (Lut == NULL) return NULL;
+       if (Lut == NULL) {
+           cmsCloseProfile(hProfile);
+           return NULL;
+           }
 
        cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
        cmsAddTag(hProfile, icSigBToA0Tag,    (LPVOID) Lut);
@@ -723,6 +739,7 @@
     return cmsBuildParametricGamma(1024, 4, Parameters);
 }
 
+// Create the ICC virtual profile for sRGB space 
 cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void)
 {
        cmsCIExyY       D65;
@@ -739,6 +756,7 @@
 
        hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22);
        cmsFreeGamma(Gamma22[0]);
+       if (hsRGB == NULL) return NULL;
 
 
        cmsAddTag(hsRGB, icSigDeviceMfgDescTag,      (LPVOID) "(lcms internal)");
@@ -839,7 +857,10 @@
 
        // Creates a LUT with 3D grid only
        Lut = cmsAllocLUT();
-
+       if (Lut == NULL) {
+           cmsCloseProfile(hICC);
+           return NULL;
+           }
 
        cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3);
 
@@ -890,7 +911,10 @@
 
        // An empty LUTs is all we need
        Lut = cmsAllocLUT();
-       if (Lut == NULL) return NULL;
+       if (Lut == NULL) {
+           cmsCloseProfile(hProfile);
+           return NULL;
+           }
 
        Lut -> InputChan = 3;
        Lut -> OutputChan = 1;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -51,10 +51,6 @@
 
 #include "lcms.h"
 
-// Uncomment this line if you want lcms to use the black point tag in profile,
-// if commented, lcms will compute the black point by its own.
-// It is safer to leve it commented out
-// #define HONOR_BLACK_POINT_TAG
 
 // Conversions
 
@@ -79,10 +75,9 @@
 }
 
 
-
 // Obtains WhitePoint from Temperature
 
-BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
+LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
 {
        double x, y;
        double T, T2, T3;
@@ -147,7 +142,7 @@
 //            - Then, I apply these coeficients to the original matrix
 
 
-BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
+LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
                                             LPcmsCIExyYTRIPLE Primrs)
 {
         VEC3 WhitePoint, Coef;
@@ -246,7 +241,7 @@
 // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll
 // The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed
 
-BOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll)
+LCMSBOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll)
 {
      MAT3 LamRigg   = {{ // Bradford matrix
                       {{  0.8951,  0.2664, -0.1614 }},
@@ -265,7 +260,7 @@
 
 // Same as anterior, but assuming D50 destination. White point is given in xyY
 
-BOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
+LCMSBOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
 {
         cmsCIEXYZ Dn;
         MAT3 Bradford;
@@ -284,7 +279,7 @@
 
 // Same as anterior, but assuming D50 source. White point is given in xyY
 
-BOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
+LCMSBOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
 {
         cmsCIEXYZ Dn;
         MAT3 Bradford;
@@ -304,7 +299,7 @@
 // Adapts a color to a given illuminant. Original color is expected to have
 // a SourceWhitePt white point.
 
-BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
+LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, 
                                      LPcmsCIEXYZ SourceWhitePt,
                                      LPcmsCIEXYZ Illuminant,
                                      LPcmsCIEXYZ Value)
@@ -423,7 +418,7 @@
 
 
 static
-BOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance)
+LCMSBOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance)
 {
        double dist_x, dist_y;
 
@@ -458,6 +453,7 @@
 }
 
 
+// To be removed in future versions
 void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt)
 {
        int i, n;
@@ -576,7 +572,7 @@
 
 
 // Get a black point of output CMYK profile, discounting any ink-limiting embedded
-// in the profile. Fou doing that, use perceptual intent in input direction:
+// in the profile. For doing that, use perceptual intent in input direction:
 // Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
 
 static
@@ -651,6 +647,8 @@
             D50BlackPoint.X = PERCEPTUAL_BLACK_X;
             D50BlackPoint.Y = PERCEPTUAL_BLACK_Y;
             D50BlackPoint.Z = PERCEPTUAL_BLACK_Z;
+
+            // Obtain the absolute XYZ. Adapt perceptual black back from D50 to whatever media white
             cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &D50BlackPoint);
         }
 
@@ -662,16 +660,15 @@
 // This function shouldn't exist at all -- there is such quantity of broken
 // profiles on black point tag, that we must somehow fix chromaticity to
 // avoid huge tint when doing Black point compensation. This function does
-// just that. If BP is specified, then forces it to neutral and uses only L
-// component. If does not exist, computes it by taking 400% of ink or RGB=0 This
-// works well on relative intent and is undefined on perceptual & saturation.
-// However, I will support all intents for tricking & trapping.
-
+// just that. There is a special flag for using black point tag, but turned 
+// off by default because it is bogus on most profiles. The detection algorithm 
+// involves to turn BP to neutral and to use only L component.  
 
 int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags)
 {
 
-    // v4 + perceptual & saturation intents does have its own black point
+    // v4 + perceptual & saturation intents does have its own black point, and it is 
+    // well specified enough to use it.
 
     if ((cmsGetProfileICCversion(hProfile) >= 0x4000000) &&
         (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {
@@ -681,7 +678,7 @@
        if (_cmsIsMatrixShaper(hProfile))
            return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, cmsFLAGS_NOTPRECALC);
 
-       // Get fixed value
+       // CLUT based - Get perceptual black point (fixed value)
        return GetV4PerceptualBlack(BlackPoint, hProfile, dwFlags);
     }
 
@@ -724,8 +721,9 @@
 
 #endif
 
-    // If output profile, discount ink-limiting
+    // That is about v2 profiles. 
 
+    // If output profile, discount ink-limiting and that's all
     if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
             (cmsGetDeviceClass(hProfile) == icSigOutputClass) &&
             (cmsGetColorSpace(hProfile) == icSigCmykData))
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c	2009-04-03 13:42:46.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,6 @@
 
 #include "lcms.h"
 
-// #define DEBUG 1
 
 // Transformations stuff
 // -----------------------------------------------------------------------
@@ -85,7 +84,7 @@
 
 void         LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b);
 void         LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b);
-BOOL         LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
+LCMSBOOL     LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
                                                 int Intent, int UsedDirection);
 
 // -------------------------------------------------------------------------
@@ -635,6 +634,8 @@
        MAT3 Scale;
 
        GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag);        // Y
+       if (GrayTRC == NULL) return NULL;
+
        cmsTakeIluminant(&Illuminant, hProfile);
 
        if (cmsGetPCS(hProfile) == icSigLabData) {
@@ -688,6 +689,9 @@
                 GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag);
                 FromLstarToXYZ(GrayTRC, Shapes1);
 
+		if (GrayTRC == NULL)
+		  return NULL;		
+
                 // Reversing must be done after curve translation
 
                 Shapes[0] = cmsReverseGamma(Shapes1[0]->nEntries, Shapes1[0]);
@@ -703,6 +707,9 @@
 
                 GrayTRC = cmsReadICCGammaReversed(hProfile, icSigGrayTRCTag);   // Y
 
+                if (GrayTRC == NULL)
+                  return NULL;
+
                 Shapes[0] = cmsDupGamma(GrayTRC);
                 Shapes[1] = cmsDupGamma(GrayTRC);
                 Shapes[2] = cmsDupGamma(GrayTRC);
@@ -801,7 +808,7 @@
 // This function builds a transform matrix chaining parameters
 
 static
-BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
+LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
 {
        MAT3 From, To, ToInv, Transfer;
        LPGAMMATABLE In[3], InverseOut[3];
@@ -838,6 +845,11 @@
         InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag);
         InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag);
 
+        if (!InverseOut[0] || !InverseOut[1] || !InverseOut[2]) {
+                     cmsFreeGammaTriple(In); 
+                     return FALSE;
+        }
+
         p -> SmeltMatShaper = cmsAllocMatShaper2(&Transfer, In, InverseOut, MATSHAPER_ALLSMELTED);
 
         cmsFreeGammaTriple(In);
@@ -1029,7 +1041,7 @@
 // Check colorspace
 
 static
-BOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, BOOL lUsePCS)
+LCMSBOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, LCMSBOOL lUsePCS)
 {
        int Space = T_COLORSPACE(dwFormat);
 
@@ -1049,10 +1061,10 @@
 {
     // Allocate needed memory
 
-    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) malloc(sizeof(_cmsTRANSFORM));
+    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) _cmsMalloc(sizeof(_cmsTRANSFORM));
     if (!p) {
 
-          cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: malloc() failed");
+          cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: _cmsMalloc() failed");
           return NULL;
     }
 
@@ -1269,10 +1281,10 @@
         else {
                 // Can we optimize matrix-shaper only transform?
 
-                   if (*FromTagPtr == 0 &&
-                       *ToTagPtr == 0 &&
-                       !p->PreviewProfile  &&
-                       p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC &&
+                   if ((*FromTagPtr == 0) && 
+                       (*ToTagPtr == 0) && 
+                       (!p->PreviewProfile) && 
+                       (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) && 
                        (p -> EntryColorSpace == icSigRgbData) &&
                        (p -> ExitColorSpace == icSigRgbData) &&
                        !(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) {
@@ -1335,7 +1347,7 @@
                      p -> ToDevice = PCStoShaperMatrix;
                      p -> OutMatShaper = cmsBuildOutputMatrixShaper(p->OutputProfile);
 
-                     if (!p -> OutMatShaper) {
+                     if (!p || !p -> OutMatShaper) {
                             cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output");
                             return NULL;
                             }
@@ -1553,7 +1565,8 @@
                     DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags);
                }
 
-               if (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK) {
+               // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given               
+               if ((p ->PreviewProfile != NULL) && (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK)) {
 
                    GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p);
                }
@@ -1668,7 +1681,7 @@
 
            LCMS_FREE_LOCK(&p->rwlock);
 
-       free((void *) p);
+       _cmsFree((void *) p);
 }
 
 
@@ -1704,7 +1717,7 @@
 
 // Returns TRUE if the profile is implemented as matrix-shaper
 
-BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
+LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
 {
     switch (cmsGetColorSpace(hProfile)) {
 
@@ -1728,7 +1741,7 @@
 }
 
 
-BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
+LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
                                                 int Intent, int UsedDirection)
 {
 
@@ -1774,6 +1787,16 @@
 }
 
 
+static
+int IsAllowedInSingleXform(icProfileClassSignature aClass)
+{
+    return (aClass == icSigInputClass) ||
+           (aClass == icSigDisplayClass) ||
+           (aClass == icSigOutputClass) ||
+           (aClass == icSigColorSpaceClass);
+}
+
+
 // A multiprofile transform does chain several profiles into a single
 // devicelink. It couls also be used to merge named color profiles into
 // a single database.
@@ -1805,10 +1828,16 @@
     // There is a simple case with just two profiles, try to catch it in order of getting
     // black preservation to work on this function, at least with two profiles.
 
+    
     if (nProfiles == 2) {
 
-        if ((cmsGetDeviceClass(hProfiles[0]) != icSigLinkClass) &&
-            (cmsGetDeviceClass(hProfiles[1]) != icSigLinkClass))
+        icProfileClassSignature Class1 = cmsGetDeviceClass(hProfiles[0]);
+        icProfileClassSignature Class2 = cmsGetDeviceClass(hProfiles[1]);
+
+        // Only input, output and display are allowed
+
+        if (IsAllowedInSingleXform(Class1) && 
+            IsAllowedInSingleXform(Class2)) 
                    return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags);
     }
 
@@ -1897,6 +1926,7 @@
 
         ColorSpace = ColorSpaceIn;
 
+	Transforms[i] = NULL;
 
         if (ColorSpace == CurrentColorSpace) {
 
@@ -1946,7 +1976,12 @@
                 goto ErrorCleanup;
         }
 
-        CurrentColorSpace = ColorSpaceOut;
+	if (Transforms[i] == NULL) {
+                cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateMultiprofileTransform: Invalid profile");
+                goto ErrorCleanup;
+        }
+
+	CurrentColorSpace = ColorSpaceOut;
 
     }
 
@@ -1984,6 +2019,14 @@
     if (hLab) cmsCloseProfile(hLab);
     if (hXYZ) cmsCloseProfile(hXYZ);
 
+    
+    if (p ->EntryColorSpace == icSigRgbData ||
+        p ->EntryColorSpace == icSigCmyData) {
+                   
+                    p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16;
+    }
+    
+
     if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) &&
         !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP))
                             _cmsFixWhiteMisalignment(p);
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h	2009-04-03 13:42:46.000000000 -0400
@@ -1,5 +1,8 @@
+/* Header file guard bands */
+#ifndef ICC_H
+#define ICC_H
+
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +26,37 @@
  * have any questions.
  */
 
-/* Header file guard bands */
-#ifndef ICC_H
-#define ICC_H
+
+/***************************************************************** 
+ Copyright (c) 1994-1996 SunSoft, Inc.
+
+                    Rights Reserved
+
+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 restrict- 
+ion, 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 NON-
+INFRINGEMENT.  IN NO EVENT SHALL SUNSOFT, INC. OR ITS PARENT 
+COMPANY 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. 
+ 
+Except as contained in this notice, the name of SunSoft, Inc. 
+shall not be used in advertising or otherwise to promote the 
+sale, use or other dealings in this Software without written 
+authorization from SunSoft Inc. 
+******************************************************************/
 
 /*
  * This version of the header file corresponds to the profile
@@ -206,6 +237,11 @@
 
 #if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__)
 
+#if defined (__MINGW) || defined(__MINGW32__)
+#include <stdint.h>
+#endif
+
+
 typedef uint8_t   icUInt8Number;
 typedef uint16_t  icUInt16Number;
 typedef uint32_t  icUInt32Number;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c	2008-11-25 04:06:03.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c	2009-04-03 13:44:42.000000000 -0400
@@ -356,6 +356,12 @@
       fprintf(stderr, "setTagData on icSigHead not permitted");
       return;
     }
+    
+    if (data == NULL)
+    {
+      JNU_ThrowByName(env, "java/lang/NullPointerException", "");
+      return;
+    }
 
     sProf.j = id;
     profile = (cmsHPROFILE) sProf.pf;
diff -ruN openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h
--- openjdkold/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h	2008-11-25 04:06:04.000000000 -0500
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h	2009-04-03 13:43:04.000000000 -0400
@@ -29,7 +29,7 @@
 //
 //
 //  Little cms
-//  Copyright (C) 1998-2006 Marti Maria
+//  Copyright (C) 1998-2007 Marti Maria
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -49,8 +49,8 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-// Version 1.16
-#undef DEBUG
+// Version 1.18
+
 #ifndef __cms_H
 
 // ********** Configuration toggles ****************************************
@@ -62,13 +62,8 @@
 // virtually any machine.
 
 //#define USE_FLOAT        1
-#ifdef _WIN64
-#define USE_C            1
-#undef USE_ASSEMBLER
-#else
-#undef USE_C
+// #define USE_C            1
 #define USE_ASSEMBLER    1
-#endif
 
 // Define this if you are using this package as a DLL (windows only)
 
@@ -77,15 +72,11 @@
 
 // Uncomment if you are trying the engine in a non-windows environment
 // like linux, SGI, VAX, FreeBSD, BeOS, etc.
-#if !defined(_WIN32) || !defined(_WIN64)
 #define NON_WINDOWS  1
-#endif
 
 // Uncomment this one if you are using big endian machines (only meaningful
 // when NON_WINDOWS is used)
-#ifndef _LITTLE_ENDIAN
-#define USE_BIG_ENDIAN   1
-#endif
+// #define USE_BIG_ENDIAN   1
 
 // Uncomment this one if your compiler/machine does support the
 // "long long" type This will speedup fixed point math. (USE_C only)
@@ -104,9 +95,14 @@
 // Uncomment this line on multithreading environments
 // #define USE_PTHREADS    1
 
+// Uncomment this line if you want lcms to use the black point tag in profile, 
+// if commented, lcms will compute the black point by its own. 
+// It is safer to leve it commented out
+// #define HONOR_BLACK_POINT_TAG    1
+
 // ********** End of configuration toggles ******************************
 
-#define LCMS_VERSION        116
+#define LCMS_VERSION        117
 
 // Microsoft VisualC++
 
@@ -115,8 +111,10 @@
 #ifdef _MSC_VER
 #    undef NON_WINDOWS
 #    if (_MSC_VER >= 1400)
+#      ifndef _CRT_SECURE_NO_DEPRECATE
 #        define _CRT_SECURE_NO_DEPRECATE 1
 #    endif
+#    endif
 #endif
 
 // Borland C
@@ -139,6 +137,7 @@
 #   define unlink remove
 #   if WIN32
 #       define USE_CUSTOM_SWAB 1
+#       undef  NON_WINDOWS
 #   else
 #       define NON_WINDOWS   1
 #   endif
@@ -176,11 +175,17 @@
 #   define USE_BIG_ENDIAN      1
 #endif
 
-#ifdef TARGET_CPU_PPC
+#if TARGET_CPU_PPC
 #   define USE_BIG_ENDIAN   1
 #endif
 
-#ifdef macintosh
+#if macintosh
+# ifndef __LITTLE_ENDIAN__
+#   define USE_BIG_ENDIAN      1
+# endif
+#endif
+
+#if __BIG_ENDIAN__
 #   define USE_BIG_ENDIAN      1
 #endif
 
@@ -217,11 +222,8 @@
 typedef unsigned char BYTE, *LPBYTE;
 typedef unsigned short WORD, *LPWORD;
 typedef unsigned long DWORD, *LPDWORD;
-typedef int BOOL;
 typedef char *LPSTR;
 typedef void *LPVOID;
-typedef void* LCMSHANDLE;
-
 
 #define ZeroMemory(p,l)     memset((p),0,(l))
 #define CopyMemory(d,s,l)   memcpy((d),(s),(l))
@@ -263,8 +265,12 @@
 
 #include <windows.h>
 
-typedef HANDLE LCMSHANDLE;
-
+#ifdef _WIN64
+# ifdef USE_ASSEMBLER
+#    undef  USE_ASSEMBLER
+#    define USE_C           1
+# endif
+#endif
 
 #ifdef  USE_INT64
 #  ifndef LCMSULONGLONG
@@ -296,6 +302,10 @@
 #   define LCMS_UNLOCK(x)
 #endif
 
+// Base types
+
+typedef int   LCMSBOOL;
+typedef void* LCMSHANDLE;
 
 #include "icc34.h"          // ICC header file
 
@@ -322,16 +332,10 @@
 #define icSigMCHEData                  ((icColorSpaceSignature) 0x4d434845L)  // MCHE
 #define icSigMCHFData                  ((icColorSpaceSignature) 0x4d434846L)  // MCHF
 
-#define icSigCAM97JABData              ((icColorSpaceSignature) 0x4A616231L)  // 'Jab1' H. Zeng
-#define icSigCAM02JABData              ((icColorSpaceSignature) 0x4A616232L)  // 'Jab2' H. Zeng
-#define icSigCAM02JCHData              ((icColorSpaceSignature) 0x4A636A32L)  // 'Jch2' H. Zeng
-
 #define icSigChromaticityTag            ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09
 #define icSigChromaticAdaptationTag     ((icTagSignature) 0x63686164L) // 'chad'
 #define icSigColorantTableTag           ((icTagSignature) 0x636c7274L) // 'clrt'
 #define icSigColorantTableOutTag        ((icTagSignature) 0x636c6f74L) // 'clot'
-#define icSigHPGamutDescTag             ((icTagSignature) 0x676D7441L) // 'gmtA' H. Zeng
-
 
 #define icSigParametricCurveType        ((icTagTypeSignature) 0x70617261L)  // parametric (ICC 4.0)
 #define icSigMultiLocalizedUnicodeType  ((icTagTypeSignature) 0x6D6C7563L)
@@ -340,7 +344,6 @@
 #define icSiglutAtoBType                ((icTagTypeSignature) 0x6d414220L)  // mAB
 #define icSiglutBtoAType                ((icTagTypeSignature) 0x6d424120L)  // mBA
 #define icSigColorantTableType          ((icTagTypeSignature) 0x636c7274L)  // clrt
-#define icSigHPGamutDescType            ((icTagTypeSignature) 0x676D7441L)  // gmtA H. Zeng
 
 
 typedef struct {
@@ -438,9 +441,6 @@
 #ifndef itoa
 #       define itoa   _itoa
 #endif
-#ifndef filelength
-#       define filelength _filelength
-#endif
 #ifndef fileno
 #       define fileno   _fileno
 #endif
@@ -450,6 +450,14 @@
 #ifndef hypot
 #       define hypot    _hypot
 #endif
+#ifndef snprintf
+#       define snprintf  _snprintf
+#endif
+#ifndef vsnprintf
+#       define vsnprintf  _vsnprintf
+#endif
+
+
 #endif
 
 
@@ -470,8 +478,9 @@
 
 // Format of pixel is defined by one DWORD, using bit fields as follows
 //
-//            TTTTT U Y F P X S EEE CCCC BBB
+//            D TTTTT U Y F P X S EEE CCCC BBB
 //
+//            D: Use dither (8 bits only)
 //            T: Pixeltype
 //            F: Flavor  0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
 //            P: Planar? 0=Chunky, 1=Planar
@@ -483,6 +492,7 @@
 //            Y: Swap first - changes ABGR to BGRA and KCMY to CMYK
 
 
+#define DITHER_SH(s)           ((s) << 22)
 #define COLORSPACE_SH(s)       ((s) << 16)
 #define SWAPFIRST_SH(s)        ((s) << 14)
 #define FLAVOR_SH(s)           ((s) << 13)
@@ -858,7 +868,7 @@
 
 LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
 LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
-LCMSAPI BOOL          LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
 
 // Predefined run-time profiles
 
@@ -915,14 +925,14 @@
 
 LCMSAPI void          LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin);
 
-LCMSAPI BOOL          LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
 
-LCMSAPI BOOL          LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
                                                         LPcmsCIEXYZ SourceWhitePt,
                                                         LPcmsCIEXYZ Illuminant,
                                                         LPcmsCIEXYZ Value);
 
-LCMSAPI BOOL          LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r,
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r,
                                                         LPcmsCIExyY WhitePoint,
                                                         LPcmsCIExyYTRIPLE Primaries);
 
@@ -976,7 +986,7 @@
 LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma);
 LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma,  LPGAMMATABLE OutGamma);
 LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma,  LPGAMMATABLE OutGamma, int nPoints);
-LCMSAPI BOOL          LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
 LCMSAPI double        LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t);
 LCMSAPI double        LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold);
 LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig);
@@ -984,14 +994,14 @@
 
 // Access to Profile data.
 
-LCMSAPI BOOL          LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
-LCMSAPI BOOL          LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
-LCMSAPI BOOL          LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
-LCMSAPI BOOL          LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
 LCMSAPI DWORD         LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile);
 LCMSAPI DWORD         LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile);
 
-LCMSAPI void          LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode);
+LCMSAPI void          LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4]);
 LCMSAPI const char*   LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile);
 LCMSAPI const char*   LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile);
 LCMSAPI const char*   LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile);
@@ -1000,13 +1010,13 @@
 LCMSAPI const char*   LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile);
 LCMSAPI const BYTE*   LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile);
 
-LCMSAPI BOOL          LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
-LCMSAPI BOOL          LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
 
-LCMSAPI BOOL          LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
 LCMSAPI int           LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile);
 
-LCMSAPI BOOL          LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len);
+LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len);
 
 LCMSAPI int           LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size);
 LCMSAPI int           LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text);
@@ -1038,50 +1048,18 @@
 LCMSAPI void          LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq);
 
 
-// Extended gamut tag -- an HP extension
-
-#define LCMSGAMUTMETHOD_SEGMENTMAXIMA   0
-#define LCMSGAMUTMETHOD_CONVEXHULL      1
-#define LCMSGAMUTMETHOD_ALPHASHAPE      2
-
-
-#define LCMSGAMUT_PHYSICAL                              0
-#define LCMSGAMUT_HP1                                   1
-#define LCMSGAMUT_HP2                                   2
-
-typedef struct {
-
-                        icColorSpaceSignature  CoordSig;        // Gamut coordinates signature
-                        icUInt16Number         Method;          // Method used to generate gamut
-                        icUInt16Number         Usage;       // Gamut usage or intent
-
-                        char Description[LCMS_DESC_MAX];        // Textual description
-
-                        cmsViewingConditions   Vc;                      // The viewing conditions
-
-                        icUInt32Number         Count;           // Number of entries
-                        double                             Data[1];         // The current data
-
-        } cmsGAMUTEX, FAR* LPcmsGAMUTEX;
-
-
-LCMSAPI LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index);
-LCMSAPI void         LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex);
-
-
-
-
 // Translate form/to our notation to ICC
 LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation);
 LCMSAPI                   int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace);
 LCMSAPI                   int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace);
-LCMSAPI BOOL                  LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile);
+LCMSAPI LCMSBOOL              LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile);
 
+// How profiles may be used
 #define LCMS_USED_AS_INPUT      0
 #define LCMS_USED_AS_OUTPUT     1
 #define LCMS_USED_AS_PROOF      2
 
-LCMSAPI BOOL         LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection);
+LCMSAPI LCMSBOOL                LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection);
 
 LCMSAPI icColorSpaceSignature   LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile);
 LCMSAPI icColorSpaceSignature   LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile);
@@ -1141,7 +1119,7 @@
 
 // CRD special
 
-#define cmsFLAGS_NODEFAULTRESOURCEDEF     0x00010000
+#define cmsFLAGS_NODEFAULTRESOURCEDEF     0x01000000
 
 // Gridpoints
 
@@ -1221,7 +1199,7 @@
 // Named color support
 
 LCMSAPI int  LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform);
-LCMSAPI BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix);
+LCMSAPI LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix);
 LCMSAPI int  LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name);
 
 // Colorant tables
@@ -1230,7 +1208,7 @@
 
 // Profile creation
 
-LCMSAPI BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data);
+LCMSAPI LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data);
 
 // Converts a transform to a devicelink profile
 LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags);
@@ -1240,12 +1218,14 @@
 
 
 // Save profile
-LCMSAPI BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName);
-LCMSAPI BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
+LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName);
+LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, 
                                                                 size_t* BytesNeeded);
 
+
+
 // Modify data for a tag in a profile
-LCMSAPI BOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, void *data, size_t size);
+LCMSAPI LCMSBOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, void *data, size_t size);
 
 // PostScript ColorRenderingDictionary and ColorSpaceArray
 
@@ -1326,35 +1306,37 @@
 // Persistence
 LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName);
 LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded);
 
 // Properties
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
-
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
 
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
 LCMSAPI double          LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
-LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames);
+LCMSAPI const char*     LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp);
+LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames);
+LCMSAPI int             LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames);
 
 // Datasets
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col);
 LCMSAPI double          LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, 
                                                 const char* Val);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, 
                                                 double Val);
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
@@ -1362,25 +1344,28 @@
 
 LCMSAPI double          LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
                                                 const char* cSample,
                                                 const char *Val);
 
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
                                                 const char* cSample,
                                                 double Val);
 
 LCMSAPI int             LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample);
-LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
 LCMSAPI int             LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
 
 
 LCMSAPI const char*     LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer);
+LCMSAPI int             LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cSample);
 
 // The LABEL extension
 
 LCMSAPI int             LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType);
 
+LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample);
+
 // Formatter for double
 LCMSAPI void            LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter);
 
@@ -1406,15 +1391,16 @@
 
 // Profiling Extensions --- Would be removed from API in future revisions
 
-LCMSAPI BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile,  icTagSignature sig, const char* Text);
-LCMSAPI BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile,   icTagSignature sig, const cmsCIEXYZ* XYZ);
-LCMSAPI BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile,   icTagSignature sig, const void* lut);
-LCMSAPI BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction);
-LCMSAPI BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm);
-LCMSAPI BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq);
-LCMSAPI BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
-LCMSAPI BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime);
-LCMSAPI BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile,  icTagSignature sig, const char* Text);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile,   icTagSignature sig, const cmsCIEXYZ* XYZ);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile,   icTagSignature sig, const void* lut);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
+LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat);
 
 // --------------------------------------------------------------------------------------------------- Inline functions
 
@@ -1456,6 +1442,34 @@
        return (WORD) in;
 }
 
+#ifndef LCMS_USER_ALLOC
+
+// Low-level alloc hook
+
+LCMS_INLINE void* _cmsMalloc(size_t size)
+{
+    if (size > ((size_t) 1024*1024*500)) return NULL;  // Never allow over 500Mb
+    if (size < 0) return NULL;              // Prevent signed size_t exploits
+
+    return (void*) malloc(size);
+}
+
+LCMS_INLINE void* _cmsCalloc(size_t nmemb, size_t size)
+{
+    size_t alloc = nmemb * size;
+    if (alloc < nmemb || alloc < size) {
+        return NULL;
+    }
+    return _cmsMalloc(alloc);
+}
+
+LCMS_INLINE void _cmsFree(void *Ptr)
+{
+    if (Ptr) free(Ptr);    
+}
+
+#endif
+
 // ------------------------------------------------------------------------------------------- end of inline functions
 
 // Signal error from inside lcms code
@@ -1542,8 +1556,8 @@
 void   cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d);
 void   cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b);
 void   cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b);
-BOOL   cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance);
-BOOL   cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance);
+LCMSBOOL  cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance);
+LCMSBOOL  cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance);
 void   cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d);
 void   cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v);
 void   cdecl VEC3saturate(LPVEC3 v);
@@ -1554,13 +1568,13 @@
 void   cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
 void   cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
 int    cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
-BOOL   cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
+LCMSBOOL  cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
 double cdecl MAT3det(LPMAT3 m);
 void   cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
 void   cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
 void   cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v);
 void   cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
-BOOL   cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance);
+LCMSBOOL  cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance);
 void   cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
 
 // Is a table linear?
@@ -1609,7 +1623,7 @@
 void    cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p);
 void    cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p);
 void    cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
-                                            BOOL lUseTetrahedral, LPL16PARAMS p);
+                                            LCMSBOOL lUseTetrahedral, LPL16PARAMS p);
 
 WORD    cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p);
 Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p);
@@ -1693,7 +1707,7 @@
 
                // Gray axes fixup. Only on v2 8-bit Lab LUT
 
-               BOOL FixGrayAxes;
+               LCMSBOOL FixGrayAxes;
 
 
                            // Parameters used for curve creation
@@ -1704,7 +1718,7 @@
                }; // LUT, FAR* LPLUT;
 
 
-BOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries);
+LCMSBOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries);
 
 
 // CRC of gamma tables
@@ -1722,7 +1736,7 @@
 
 void           cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
 void           cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
-BOOL           cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
+LCMSBOOL       cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
 void           cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
 
 LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
@@ -1756,7 +1770,7 @@
 void        cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper);
 void        cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]);
 
-BOOL         cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);
+LCMSBOOL    cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);
 
 LPMATSHAPER  cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile);
 LPMATSHAPER  cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile);
@@ -1764,11 +1778,11 @@
 
 
 // White Point & Primary chromas handling
-BOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll);
-BOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt);
-BOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt);
+LCMSBOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll);
+LCMSBOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt);
+LCMSBOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt);
 
-BOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile);
+LCMSBOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile);
 
 // Inter-PCS conversion routines. They assume D50 as white point.
 void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]);
@@ -1783,7 +1797,7 @@
 LPcmsNAMEDCOLORLIST  cdecl cmsAllocNamedColorList(int n);
 int                  cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig);
 void                 cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List);
-BOOL                 cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]);
+LCMSBOOL             cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]);
 
 
 // I/O
@@ -1827,8 +1841,8 @@
 
                char                    PhysicalFile[MAX_PATH];
 
-               BOOL                    IsWrite;
-               BOOL                    SaveAs8Bits;
+               LCMSBOOL                IsWrite;
+               LCMSBOOL                SaveAs8Bits;
 
                struct tm               Created;
 
@@ -1836,14 +1850,13 @@
 
                size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc);
 
-               BOOL   (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset);
-               BOOL   (* Close)(struct _lcms_iccprofile_struct* Icc);
+               LCMSBOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset);
+               LCMSBOOL (* Close)(struct _lcms_iccprofile_struct* Icc);
                size_t (* Tell)(struct _lcms_iccprofile_struct* Icc);
-               BOOL   (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount);
-
+               LCMSBOOL   (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount);
                // Writting
 
-               BOOL   (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr);
+               LCMSBOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr);
 
                size_t UsedSpace;
 
@@ -1855,7 +1868,7 @@
 cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void);
 
 // Search into tag dictionary
-icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError);
+icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError);
 
 // Search for a particular tag, replace if found or add new one else
 LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init);
@@ -1871,6 +1884,7 @@
 
 // These macros unpack format specifiers into integers
 
+#define T_DITHER(s)           (((s)>>22)&1)
 #define T_COLORSPACE(s)       (((s)>>16)&31)
 #define T_SWAPFIRST(s)        (((s)>>14)&1)
 #define T_FLAVOR(s)           (((s)>>13)&1)
@@ -1967,7 +1981,7 @@
 
                     // Flag for transform involving v4 profiles
 
-                    BOOL lInputV4Lab, lOutputV4Lab;
+                    LCMSBOOL lInputV4Lab, lOutputV4Lab;
 
 
                     // 1-pixel cache
@@ -2014,7 +2028,7 @@
 
 // Clamping & Gamut handling
 
-BOOL cdecl   _cmsEndPointsBySpace(icColorSpaceSignature Space,
+LCMSBOOL cdecl   _cmsEndPointsBySpace(icColorSpaceSignature Space,
                             WORD **White, WORD **Black, int *nOutputs);
 
 WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space);
@@ -2043,7 +2057,7 @@
 LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h);
 
 // Hot fixes bad profiles
-BOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p);
+LCMSBOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p);
 
 // Marks LUT as 8 bit on input
 LPLUT cdecl _cmsBlessLUT8(LPLUT Lut);
@@ -2061,6 +2075,10 @@
 // Build a tone curve for K->K' if possible (only works on CMYK)
 LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints);
 
+// Validates a LUT
+LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT);
+
+
 // These are two VITAL macros, from converting between 8 and 16 bit
 // representation.