changeset 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 3a122c249dda
children 899b8be5aaad
files ChangeLog Makefile.am patches/icedtea-lcms.patch
diffstat 3 files changed, 6516 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Apr 07 01:02:17 2009 +0100
+++ b/ChangeLog	Tue Apr 07 17:52:24 2009 +0100
@@ -1,3 +1,29 @@
+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.
+
 2009-04-06  Andrew John Hughes  <ahughes@redhat.com>
 
 	* Makefile.am:
--- a/Makefile.am	Tue Apr 07 01:02:17 2009 +0100
+++ b/Makefile.am	Tue Apr 07 17:52:24 2009 +0100
@@ -1849,6 +1849,9 @@
 	patches/security/icedtea-6804996.patch \
 	patches/security/icedtea-6804997.patch \
 	patches/security/icedtea-6804998.patch \
+	patches/icedtea-LCMS-setTagData.patch \
+	patches/icedtea-lcms-leak.patch \
+	patches/icedtea-lcms.patch \
 	$(DISTRIBUTION_PATCHES)
 
 if WITH_RHINO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-lcms.patch	Tue Apr 07 17:52:24 2009 +0100
@@ -0,0 +1,6487 @@
+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.
+