# HG changeset patch # User Andrew John Hughes # Date 1239123144 -3600 # Node ID 1f049d6728a0d1c02f1a8ca718ad5bba5a09008b # Parent 3a122c249dda9449581e3f295cead8cdcdbf51fc Forwardport Lillian's LCMS security fixes. 2009-04-06 Andrew John Hughes * Makefile.am: Add back missing LCMS patches. 2009-04-03 Lillian Angel * 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 * patches/icedtea-lcms.patch: Updated with most recent security fixes. 2009-03-24 Lillian Angel * patches/icedtea-lcms.patch: Reworked to patch lcms sources with most recent upstream version (1.18). 2009-03-21 Lillian Angel * patches/icedtea-lcms.patch: New patch. * Makefile.am (ICEDTEA_PATCHES): Added new patch to the list. diff -r 3a122c249dda -r 1f049d6728a0 ChangeLog --- 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 + + * Makefile.am: + Add back missing LCMS patches. + +2009-04-03 Lillian Angel + + * 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 + + * patches/icedtea-lcms.patch: Updated with most recent security fixes. + +2009-03-24 Lillian Angel + + * patches/icedtea-lcms.patch: Reworked to patch lcms sources with most + recent upstream version (1.18). + +2009-03-21 Lillian Angel + + * patches/icedtea-lcms.patch: New patch. + * Makefile.am + (ICEDTEA_PATCHES): Added new patch to the list. + 2009-04-06 Andrew John Hughes * Makefile.am: diff -r 3a122c249dda -r 1f049d6728a0 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 diff -r 3a122c249dda -r 1f049d6728a0 patches/icedtea-lcms.patch --- /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 ++#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[ ] ++ /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 ++#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 + +-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. +