summaryrefslogtreecommitdiff
path: root/third_party/lcms2-2.6/src/cmscgats.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/lcms2-2.6/src/cmscgats.c')
-rw-r--r--third_party/lcms2-2.6/src/cmscgats.c2776
1 files changed, 0 insertions, 2776 deletions
diff --git a/third_party/lcms2-2.6/src/cmscgats.c b/third_party/lcms2-2.6/src/cmscgats.c
deleted file mode 100644
index cce4cedbad..0000000000
--- a/third_party/lcms2-2.6/src/cmscgats.c
+++ /dev/null
@@ -1,2776 +0,0 @@
-//---------------------------------------------------------------------------------
-//
-// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the Software
-// is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-//---------------------------------------------------------------------------------
-//
-
-#include "lcms2_internal.h"
-
-
-// IT8.7 / CGATS.17-200x handling -----------------------------------------------------------------------------
-
-
-#define MAXID 128 // Max length of identifier
-#define MAXSTR 1024 // Max length of string
-#define MAXTABLES 255 // Max Number of tables in a single stream
-#define MAXINCLUDE 20 // Max number of nested includes
-
-#define DEFAULT_DBL_FORMAT "%.10g" // Double formatting
-
-#ifdef CMS_IS_WINDOWS_
-//sunliang.liu modified 2010426 for wince error
-# ifndef _WIN32_WCE
-# include <io.h>
-# endif
-# define DIR_CHAR '\\'
-#else
-# define DIR_CHAR '/'
-#endif
-
-
-// Symbols
-typedef enum {
-
- SNONE,
- SINUM, // Integer
- SDNUM, // Real
- SIDENT, // Identifier
- SSTRING, // string
- SCOMMENT, // comment
- SEOLN, // End of line
- SEOF, // End of stream
- SSYNERROR, // Syntax error found on stream
-
- // Keywords
-
- SBEGIN_DATA,
- SBEGIN_DATA_FORMAT,
- SEND_DATA,
- SEND_DATA_FORMAT,
- SKEYWORD,
- SDATA_FORMAT_ID,
- SINCLUDE
-
- } SYMBOL;
-
-
-// How to write the value
-typedef enum {
-
- WRITE_UNCOOKED,
- WRITE_STRINGIFY,
- WRITE_HEXADECIMAL,
- WRITE_BINARY,
- WRITE_PAIR
-
- } WRITEMODE;
-
-// Linked list of variable names
-typedef struct _KeyVal {
-
- 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
-
- } KEYVALUE;
-
-
-// Linked list of memory chunks (Memory sink)
-typedef struct _OwnedMem {
-
- struct _OwnedMem* Next;
- void * Ptr; // Point to value
-
- } OWNEDMEM;
-
-// Suballocator
-typedef struct _SubAllocator {
-
- cmsUInt8Number* Block;
- cmsUInt32Number BlockSize;
- cmsUInt32Number Used;
-
- } SUBALLOCATOR;
-
-// Table. Each individual table can hold properties and rows & cols
-typedef struct _Table {
-
- char SheetType[MAXSTR]; // The first row of the IT8 (the type)
-
- int nSamples, nPatches; // Cols, Rows
- int SampleID; // Pos of ID
-
- KEYVALUE* HeaderList; // The properties
-
- char** DataFormat; // The binary stream descriptor
- char** Data; // The binary stream
-
- } TABLE;
-
-// File stream being parsed
-typedef struct _FileContext {
- char FileName[cmsMAX_PATH]; // File name if being readed from file
- FILE* Stream; // File stream or NULL if holded in memory
- } FILECTX;
-
-// This struct hold all information about an open IT8 handler.
-typedef struct {
-
-
- cmsUInt32Number TablesCount; // How many tables in this stream
- cmsUInt32Number nTable; // The actual table
-
- TABLE Tab[MAXTABLES];
-
- // Memory management
- OWNEDMEM* MemorySink; // The storage backend
- SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast
-
- // Parser state machine
- SYMBOL sy; // Current symbol
- int ch; // Current character
-
- cmsInt32Number inum; // integer value
- cmsFloat64Number dnum; // real value
-
- char id[MAXID]; // identifier
- char str[MAXSTR]; // string
-
- // Allowed keywords & datasets. They have visibility on whole stream
- KEYVALUE* ValidKeywords;
- KEYVALUE* ValidSampleID;
-
- char* Source; // Points to loc. being parsed
- cmsInt32Number lineno; // line counter for error reporting
-
- FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed
- cmsInt32Number IncludeSP; // Include Stack Pointer
-
- char* MemoryBlock; // The stream if holded in memory
-
- char DoubleFormatter[MAXID];// Printf-like 'cmsFloat64Number' formatter
-
- cmsContext ContextID; // The threading context
-
- } cmsIT8;
-
-
-// The stream for save operations
-typedef struct {
-
- FILE* stream; // For save-to-file behaviour
-
- cmsUInt8Number* Base;
- cmsUInt8Number* Ptr; // For save-to-mem behaviour
- cmsUInt32Number Used;
- cmsUInt32Number Max;
-
- } SAVESTREAM;
-
-
-// ------------------------------------------------------ cmsIT8 parsing routines
-
-
-// A keyword
-typedef struct {
-
- const char *id;
- SYMBOL sy;
-
- } KEYWORD;
-
-// The keyword->symbol translation table. Sorting is required.
-static const KEYWORD TabKeys[] = {
-
- {"$INCLUDE", SINCLUDE}, // This is an extension!
- {".INCLUDE", SINCLUDE}, // This is an extension!
-
- {"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}
- };
-
-#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
-
-// Predefined properties
-
-// A property
-typedef struct {
- const char *id; // The identifier
- WRITEMODE as; // How is supposed to be written
- } PROPERTY;
-
-static PROPERTY PredefinedProperties[] = {
-
- {"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", 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", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
- // a guide to the potential for issues of paper fluorescence, etc.
-
- {"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", 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
-
- // below properties are 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.
-
- {"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(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
- "CMYK_Y", // Yellow component of CMYK data expressed as a percentage
- "CMYK_K", // Black component of CMYK data expressed as a percentage
- "D_RED", // Red filter density
- "D_GREEN", // Green filter density
- "D_BLUE", // Blue filter density
- "D_VIS", // Visual filter density
- "D_MAJOR_FILTER", // Major filter d ensity
- "RGB_R", // Red component of RGB data
- "RGB_G", // Green component of RGB data
- "RGB_B", // Blue com ponent of RGB data
- "SPECTRAL_NM", // Wavelength of measurement expressed in nanometers
- "SPECTRAL_PCT", // Percentage reflectance/transmittance
- "SPECTRAL_DEC", // Reflectance/transmittance
- "XYZ_X", // X component of tristimulus data
- "XYZ_Y", // Y component of tristimulus data
- "XYZ_Z", // Z component of tristimulus data
- "XYY_X" // x component of chromaticity data
- "XYY_Y", // y component of chromaticity data
- "XYY_CAPY", // Y component of tristimulus data
- "LAB_L", // L* component of Lab data
- "LAB_A", // a* component of Lab data
- "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_94", // CIE dE using CIE 94
- "LAB_DE_CMC", // dE using CMC
- "LAB_DE_2000", // CIE dE using CIE DE 2000
- "MEAN_DE", // Mean Delta E (LAB_DE) of samples compared to batch average
- // (Used for data files for ANSI IT8.7/1 and IT8.7/2 targets)
- "STDEV_X", // Standard deviation of X (tristimulus data)
- "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_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
- // used to derive an estimate of the chi-squared parameter which is
- // recommended as the predictor of the variability of dE
-
-#define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
-
-//Forward declaration of some internal functions
-static void* AllocChunk(cmsIT8* it8, cmsUInt32Number size);
-
-// Checks whatever c is a separator
-static
-cmsBool isseparator(int c)
-{
- return (c == ' ') || (c == '\t') ;
-}
-
-// Checks whatever c is a valid identifier char
-static
-cmsBool ismiddle(int c)
-{
- return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
-}
-
-// Checks whatsever c is a valid identifier middle char.
-static
-cmsBool isidchar(int c)
-{
- return isalnum(c) || ismiddle(c);
-}
-
-// Checks whatsever c is a valid identifier first char.
-static
-cmsBool isfirstidchar(int c)
-{
- return !isdigit(c) && ismiddle(c);
-}
-
-// Guess whether the supplied path looks like an absolute path
-static
-cmsBool isabsolutepath(const char *path)
-{
- char ThreeChars[4];
-
- if(path == NULL)
- return FALSE;
- if (path[0] == 0)
- return FALSE;
-
- strncpy(ThreeChars, path, 3);
- ThreeChars[3] = 0;
-
- if(ThreeChars[0] == DIR_CHAR)
- return TRUE;
-
-#ifdef CMS_IS_WINDOWS_
- if (isalpha((int) ThreeChars[0]) && ThreeChars[1] == ':')
- return TRUE;
-#endif
- return FALSE;
-}
-
-
-// Makes a file path based on a given reference path
-// NOTE: this function doesn't check if the path exists or even if it's legal
-static
-cmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffer, cmsUInt32Number MaxLen)
-{
- char *tail;
- cmsUInt32Number len;
-
- // Already absolute?
- if (isabsolutepath(relPath)) {
-
- strncpy(buffer, relPath, MaxLen);
- buffer[MaxLen-1] = 0;
- return TRUE;
- }
-
- // No, search for last
- strncpy(buffer, basePath, MaxLen);
- buffer[MaxLen-1] = 0;
-
- tail = strrchr(buffer, DIR_CHAR);
- if (tail == NULL) return FALSE; // Is not absolute and has no separators??
-
- len = (cmsUInt32Number) (tail - buffer);
- if (len >= MaxLen) return FALSE;
-
- // No need to assure zero terminator over here
- strncpy(tail + 1, relPath, MaxLen - len);
-
- 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
-cmsBool SynError(cmsIT8* it8, const char *Txt, ...)
-{
- char Buffer[256], ErrMsg[1024];
- va_list args;
-
- va_start(args, Txt);
- vsnprintf(Buffer, 255, Txt, args);
- Buffer[255] = 0;
- va_end(args);
-
- snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer);
- ErrMsg[1023] = 0;
- it8->sy = SSYNERROR;
- cmsSignalError(it8 ->ContextID, cmsERROR_CORRUPTION_DETECTED, "%s", ErrMsg);
- return FALSE;
-}
-
-// Check if current symbol is same as specified. issue an error else.
-static
-cmsBool Check(cmsIT8* it8, SYMBOL sy, const char* Err)
-{
- if (it8 -> sy != sy)
- return SynError(it8, NoMeta(Err));
- return TRUE;
-}
-
-// Read Next character from stream
-static
-void NextCh(cmsIT8* it8)
-{
- if (it8 -> FileStack[it8 ->IncludeSP]->Stream) {
-
- it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream);
-
- if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream)) {
-
- if (it8 ->IncludeSP > 0) {
-
- fclose(it8 ->FileStack[it8->IncludeSP--]->Stream);
- it8 -> ch = ' '; // Whitespace to be ignored
-
- } else
- it8 ->ch = 0; // EOF
- }
- }
- else {
- it8->ch = *it8->Source;
- if (it8->ch) it8->Source++;
- }
-}
-
-
-// Try to see if current identifier is a keyword, if so return the referred symbol
-static
-SYMBOL BinSrchKey(const char *id)
-{
- int l = 1;
- int r = NUMKEYS;
- int x, res;
-
- while (r >= l)
- {
- x = (l+r)/2;
- res = cmsstrcasecmp(id, TabKeys[x-1].id);
- if (res == 0) return TabKeys[x-1].sy;
- if (res < 0) r = x - 1;
- else l = x + 1;
- }
-
- return SNONE;
-}
-
-
-// 10 ^n
-static
-cmsFloat64Number xpow10(int n)
-{
- return pow(10, (cmsFloat64Number) n);
-}
-
-
-// Reads a Real number, tries to follow from integer number
-static
-void ReadReal(cmsIT8* it8, int inum)
-{
- it8->dnum = (cmsFloat64Number) inum;
-
- while (isdigit(it8->ch)) {
-
- it8->dnum = it8->dnum * 10.0 + (it8->ch - '0');
- NextCh(it8);
- }
-
- if (it8->ch == '.') { // Decimal point
-
- cmsFloat64Number frac = 0.0; // fraction
- int prec = 0; // precision
-
- NextCh(it8); // Eats dec. point
-
- while (isdigit(it8->ch)) {
-
- frac = frac * 10.0 + (it8->ch - '0');
- prec++;
- NextCh(it8);
- }
-
- it8->dnum = it8->dnum + (frac / xpow10(prec));
- }
-
- // Exponent, example 34.00E+20
- if (toupper(it8->ch) == 'E') {
-
- cmsInt32Number e;
- cmsInt32Number sgn;
-
- NextCh(it8); sgn = 1;
-
- if (it8->ch == '-') {
-
- sgn = -1; NextCh(it8);
- }
- else
- if (it8->ch == '+') {
-
- sgn = +1;
- NextCh(it8);
- }
-
- e = 0;
- while (isdigit(it8->ch)) {
-
- if ((cmsFloat64Number) e * 10L < (cmsFloat64Number) +2147483647.0)
- e = e * 10 + (it8->ch - '0');
-
- NextCh(it8);
- }
-
- e = sgn*e;
- it8 -> dnum = it8 -> dnum * xpow10(e);
- }
-}
-
-// Parses a float number
-// This can not call directly atof because it uses locale dependant
-// parsing, while CCMX files always use . as decimal separator
-static
-cmsFloat64Number ParseFloatNumber(const char *Buffer)
-{
- cmsFloat64Number dnum = 0.0;
- int sign = 1;
-
- // keep safe
- if (Buffer == NULL) return 0.0;
-
- if (*Buffer == '-' || *Buffer == '+') {
-
- sign = (*Buffer == '-') ? -1 : 1;
- Buffer++;
- }
-
-
- while (*Buffer && isdigit((int) *Buffer)) {
-
- dnum = dnum * 10.0 + (*Buffer - '0');
- if (*Buffer) Buffer++;
- }
-
- if (*Buffer == '.') {
-
- cmsFloat64Number frac = 0.0; // fraction
- int prec = 0; // precission
-
- if (*Buffer) Buffer++;
-
- while (*Buffer && isdigit((int) *Buffer)) {
-
- frac = frac * 10.0 + (*Buffer - '0');
- prec++;
- if (*Buffer) Buffer++;
- }
-
- dnum = dnum + (frac / xpow10(prec));
- }
-
- // Exponent, example 34.00E+20
- if (*Buffer && toupper(*Buffer) == 'E') {
-
- int e;
- int sgn;
-
- if (*Buffer) Buffer++;
- sgn = 1;
-
- if (*Buffer == '-') {
-
- sgn = -1;
- if (*Buffer) Buffer++;
- }
- else
- if (*Buffer == '+') {
-
- sgn = +1;
- if (*Buffer) Buffer++;
- }
-
- e = 0;
- while (*Buffer && isdigit((int) *Buffer)) {
-
- if ((cmsFloat64Number) e * 10L < INT_MAX)
- e = e * 10 + (*Buffer - '0');
-
- if (*Buffer) Buffer++;
- }
-
- e = sgn*e;
- dnum = dnum * xpow10(e);
- }
-
- return sign * dnum;
-}
-
-
-// Reads next symbol
-static
-void InSymbol(cmsIT8* it8)
-{
- register char *idptr;
- register int k;
- SYMBOL key;
- int sng;
-
- do {
-
- while (isseparator(it8->ch))
- NextCh(it8);
-
- if (isfirstidchar(it8->ch)) { // Identifier
-
- k = 0;
- idptr = it8->id;
-
- do {
-
- if (++k < MAXID) *idptr++ = (char) it8->ch;
-
- NextCh(it8);
-
- } while (isidchar(it8->ch));
-
- *idptr = '\0';
-
-
- key = BinSrchKey(it8->id);
- if (key == SNONE) it8->sy = SIDENT;
- else it8->sy = key;
-
- }
- else // Is a number?
- if (isdigit(it8->ch) || it8->ch == '.' || it8->ch == '-' || it8->ch == '+')
- {
- int sign = 1;
-
- if (it8->ch == '-') {
- sign = -1;
- NextCh(it8);
- }
-
- it8->inum = 0;
- it8->sy = SINUM;
-
- if (it8->ch == '0') { // 0xnnnn (Hexa) or 0bnnnn (Binary)
-
- NextCh(it8);
- if (toupper(it8->ch) == 'X') {
-
- int j;
-
- NextCh(it8);
- while (isxdigit(it8->ch))
- {
- it8->ch = toupper(it8->ch);
- if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10;
- else j = it8->ch - '0';
-
- if ((long) it8->inum * 16L > (long) INT_MAX)
- {
- SynError(it8, "Invalid hexadecimal number");
- return;
- }
-
- it8->inum = it8->inum * 16 + j;
- NextCh(it8);
- }
- return;
- }
-
- if (toupper(it8->ch) == 'B') { // Binary
-
- int j;
-
- NextCh(it8);
- while (it8->ch == '0' || it8->ch == '1')
- {
- j = it8->ch - '0';
-
- if ((long) it8->inum * 2L > (long) INT_MAX)
- {
- SynError(it8, "Invalid binary number");
- return;
- }
-
- it8->inum = it8->inum * 2 + j;
- NextCh(it8);
- }
- return;
- }
- }
-
-
- while (isdigit(it8->ch)) {
-
- if ((cmsFloat64Number) it8->inum * 10L > (cmsFloat64Number) +2147483647.0) {
- ReadReal(it8, it8->inum);
- it8->sy = SDNUM;
- it8->dnum *= sign;
- return;
- }
-
- it8->inum = it8->inum * 10 + (it8->ch - '0');
- NextCh(it8);
- }
-
- if (it8->ch == '.') {
-
- ReadReal(it8, it8->inum);
- it8->sy = SDNUM;
- it8->dnum *= sign;
- return;
- }
-
- it8 -> inum *= sign;
-
- // Special case. Numbers followed by letters are taken as identifiers
-
- if (isidchar(it8 ->ch)) {
-
- if (it8 ->sy == SINUM) {
-
- sprintf(it8->id, "%d", it8->inum);
- }
- else {
-
- sprintf(it8->id, it8 ->DoubleFormatter, it8->dnum);
- }
-
- k = (int) strlen(it8 ->id);
- idptr = it8 ->id + k;
- do {
-
- if (++k < MAXID) *idptr++ = (char) it8->ch;
-
- NextCh(it8);
-
- } while (isidchar(it8->ch));
-
- *idptr = '\0';
- it8->sy = SIDENT;
- }
- return;
-
- }
- else
- switch ((int) it8->ch) {
-
- // EOF marker -- ignore it
- case '\x1a':
- NextCh(it8);
- break;
-
- // Eof stream markers
- case 0:
- case -1:
- it8->sy = SEOF;
- break;
-
-
- // Next line
- case '\r':
- NextCh(it8);
- if (it8 ->ch == '\n')
- NextCh(it8);
- it8->sy = SEOLN;
- it8->lineno++;
- break;
-
- case '\n':
- NextCh(it8);
- it8->sy = SEOLN;
- it8->lineno++;
- break;
-
- // Comment
- case '#':
- NextCh(it8);
- while (it8->ch && it8->ch != '\n' && it8->ch != '\r')
- NextCh(it8);
-
- it8->sy = SCOMMENT;
- break;
-
- // String.
- case '\'':
- case '\"':
- idptr = it8->str;
- sng = it8->ch;
- k = 0;
- NextCh(it8);
-
- while (k < MAXSTR && it8->ch != sng) {
-
- if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
- else {
- *idptr++ = (char) it8->ch;
- NextCh(it8);
- k++;
- }
- }
-
- it8->sy = SSTRING;
- *idptr = '\0';
- NextCh(it8);
- break;
-
-
- default:
- SynError(it8, "Unrecognized character: 0x%x", it8 ->ch);
- return;
- }
-
- } while (it8->sy == SCOMMENT);
-
- // Handle the include special token
-
- if (it8 -> sy == SINCLUDE) {
-
- FILECTX* FileNest;
-
- if(it8 -> IncludeSP >= (MAXINCLUDE-1)) {
-
- SynError(it8, "Too many recursion levels");
- return;
- }
-
- InSymbol(it8);
- if (!Check(it8, SSTRING, "Filename expected")) return;
-
- FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
- if(FileNest == NULL) {
-
- FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
- //if(FileNest == NULL)
- // TODO: how to manage out-of-memory conditions?
- }
-
- if (BuildAbsolutePath(it8->str,
- it8->FileStack[it8->IncludeSP]->FileName,
- FileNest->FileName, cmsMAX_PATH-1) == FALSE) {
- SynError(it8, "File path too long");
- return;
- }
-
- 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);
- }
-
-}
-
-// Checks end of line separator
-static
-cmsBool CheckEOLN(cmsIT8* it8)
-{
- if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
- while (it8 -> sy == SEOLN)
- InSymbol(it8);
- return TRUE;
-
-}
-
-// Skip a symbol
-
-static
-void Skip(cmsIT8* it8, SYMBOL sy)
-{
- if (it8->sy == sy && it8->sy != SEOF)
- InSymbol(it8);
-}
-
-
-// Skip multiple EOLN
-static
-void SkipEOLN(cmsIT8* it8)
-{
- while (it8->sy == SEOLN) {
- InSymbol(it8);
- }
-}
-
-
-// Returns a string holding current value
-static
-cmsBool GetVal(cmsIT8* it8, char* Buffer, cmsUInt32Number max, const char* ErrorTitle)
-{
- switch (it8->sy) {
-
- case SEOLN: // Empty value
- Buffer[0]=0;
- break;
- case SIDENT: strncpy(Buffer, it8->id, max);
- Buffer[max-1]=0;
- 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);
- Buffer[max-1] = 0;
- break;
-
-
- default:
- return SynError(it8, "%s", ErrorTitle);
- }
-
- Buffer[max] = 0;
- return TRUE;
-}
-
-// ---------------------------------------------------------- Table
-
-static
-TABLE* GetTable(cmsIT8* it8)
-{
- if ((it8 -> nTable >= it8 ->TablesCount)) {
-
- SynError(it8, "Table %d out of sequence", it8 -> nTable);
- return it8 -> Tab;
- }
-
- return it8 ->Tab + it8 ->nTable;
-}
-
-// ---------------------------------------------------------- Memory management
-
-
-// Frees an allocator and owned memory
-void CMSEXPORT cmsIT8Free(cmsHANDLE hIT8)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- if (it8 == NULL)
- return;
-
- if (it8->MemorySink) {
-
- OWNEDMEM* p;
- OWNEDMEM* n;
-
- for (p = it8->MemorySink; p != NULL; p = n) {
-
- n = p->Next;
- if (p->Ptr) _cmsFree(it8 ->ContextID, p->Ptr);
- _cmsFree(it8 ->ContextID, p);
- }
- }
-
- if (it8->MemoryBlock)
- _cmsFree(it8 ->ContextID, it8->MemoryBlock);
-
- _cmsFree(it8 ->ContextID, it8);
-}
-
-
-// Allocates a chunk of data, keep linked list
-static
-void* AllocBigBlock(cmsIT8* it8, cmsUInt32Number size)
-{
- OWNEDMEM* ptr1;
- void* ptr = _cmsMallocZero(it8->ContextID, size);
-
- if (ptr != NULL) {
-
- ptr1 = (OWNEDMEM*) _cmsMallocZero(it8 ->ContextID, sizeof(OWNEDMEM));
-
- if (ptr1 == NULL) {
-
- _cmsFree(it8 ->ContextID, ptr);
- return NULL;
- }
-
- ptr1-> Ptr = ptr;
- ptr1-> Next = it8 -> MemorySink;
- it8 -> MemorySink = ptr1;
- }
-
- return ptr;
-}
-
-
-// Suballocator.
-static
-void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
-{
- cmsUInt32Number Free = it8 ->Allocator.BlockSize - it8 ->Allocator.Used;
- cmsUInt8Number* ptr;
-
- size = _cmsALIGNMEM(size);
-
- if (size > Free) {
-
- if (it8 -> Allocator.BlockSize == 0)
-
- it8 -> Allocator.BlockSize = 20*1024;
- else
- it8 ->Allocator.BlockSize *= 2;
-
- if (it8 ->Allocator.BlockSize < size)
- it8 ->Allocator.BlockSize = size;
-
- it8 ->Allocator.Used = 0;
- it8 ->Allocator.Block = (cmsUInt8Number*) AllocBigBlock(it8, it8 ->Allocator.BlockSize);
- }
-
- ptr = it8 ->Allocator.Block + it8 ->Allocator.Used;
- it8 ->Allocator.Used += size;
-
- return (void*) ptr;
-
-}
-
-
-// Allocates a string
-static
-char *AllocString(cmsIT8* it8, const char* str)
-{
- cmsUInt32Number Size = (cmsUInt32Number) strlen(str)+1;
- char *ptr;
-
-
- ptr = (char *) AllocChunk(it8, Size);
- if (ptr) strncpy (ptr, str, Size-1);
-
- return ptr;
-}
-
-// Searches through linked list
-
-static
-cmsBool IsAvailableOnList(KEYVALUE* p, const char* Key, const char* Subkey, KEYVALUE** LastPtr)
-{
- if (LastPtr) *LastPtr = p;
-
- for (; p != NULL; p = p->Next) {
-
- if (LastPtr) *LastPtr = p;
-
- if (*Key != '#') { // Comments are ignored
-
- if (cmsstrcasecmp(Key, p->Keyword) == 0)
- break;
- }
- }
-
- if (p == NULL)
- return FALSE;
-
- if (Subkey == 0)
- return TRUE;
-
- for (; p != NULL; p = p->NextSubkey) {
-
- if (p ->Subkey == NULL) continue;
-
- if (LastPtr) *LastPtr = p;
-
- if (cmsstrcasecmp(Subkey, p->Subkey) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-
-// Add a property into a linked list
-static
-KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
-{
- KEYVALUE* p;
- KEYVALUE* last;
-
-
- // Check if property is already in list
-
- if (IsAvailableOnList(*Head, Key, Subkey, &p)) {
-
- // This may work for editing properties
-
- // return SynError(it8, "duplicate key <%s>", Key);
- }
- else {
-
- last = p;
-
- // Allocate the container
- p = (KEYVALUE*) AllocChunk(it8, sizeof(KEYVALUE));
- if (p == NULL)
- {
- 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);
-
- // Keep the container in our list
- if (*Head == NULL) {
- *Head = p;
- }
- else
- {
- if (Subkey != NULL && last != NULL) {
-
- last->NextSubkey = p;
-
- // 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 != NULL)
- last = last->Next;
- }
-
- if (last != NULL) last->Next = p;
- }
-
- p->Next = NULL;
- p->NextSubkey = NULL;
- }
-
- p->WriteAs = WriteAs;
-
- if (xValue != NULL) {
-
- p->Value = AllocString(it8, xValue);
- }
- else {
- p->Value = NULL;
- }
-
- return p;
-}
-
-static
-KEYVALUE* AddAvailableProperty(cmsIT8* it8, const char* Key, WRITEMODE as)
-{
- return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as);
-}
-
-
-static
-KEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key)
-{
- return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
-}
-
-
-static
-void AllocTable(cmsIT8* it8)
-{
- TABLE* t;
-
- t = it8 ->Tab + it8 ->TablesCount;
-
- t->HeaderList = NULL;
- t->DataFormat = NULL;
- t->Data = NULL;
-
- it8 ->TablesCount++;
-}
-
-
-cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE IT8, cmsUInt32Number nTable)
-{
- cmsIT8* it8 = (cmsIT8*) IT8;
-
- if (nTable >= it8 ->TablesCount) {
-
- if (nTable == it8 ->TablesCount) {
-
- AllocTable(it8);
- }
- else {
- SynError(it8, "Table %d is out of sequence", nTable);
- return -1;
- }
- }
-
- it8 ->nTable = nTable;
-
- return (cmsInt32Number) nTable;
-}
-
-
-
-// Init an empty container
-cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
-{
- cmsIT8* it8;
- cmsUInt32Number i;
-
- it8 = (cmsIT8*) _cmsMallocZero(ContextID, sizeof(cmsIT8));
- if (it8 == NULL) return NULL;
-
- AllocTable(it8);
-
- it8->MemoryBlock = NULL;
- it8->MemorySink = NULL;
-
- it8 ->nTable = 0;
-
- it8->ContextID = ContextID;
- it8->Allocator.Used = 0;
- it8->Allocator.Block = NULL;
- it8->Allocator.BlockSize = 0;
-
- it8->ValidKeywords = NULL;
- it8->ValidSampleID = NULL;
-
- it8 -> sy = SNONE;
- it8 -> ch = ' ';
- it8 -> Source = NULL;
- it8 -> inum = 0;
- it8 -> dnum = 0.0;
-
- it8->FileStack[0] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
- it8->IncludeSP = 0;
- it8 -> lineno = 1;
-
- strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
- cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17");
-
- // Initialize predefined properties & data
-
- for (i=0; i < NUMPREDEFINEDPROPS; i++)
- AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as);
-
- for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
- AddAvailableSampleID(it8, PredefinedSampleID[i]);
-
-
- return (cmsHANDLE) it8;
-}
-
-
-const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8)
-{
- return GetTable((cmsIT8*) hIT8)->SheetType;
-}
-
-cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type)
-{
- TABLE* t = GetTable((cmsIT8*) hIT8);
-
- strncpy(t ->SheetType, Type, MAXSTR-1);
- t ->SheetType[MAXSTR-1] = 0;
- return TRUE;
-}
-
-cmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- if (!Val) return FALSE;
- if (!*Val) return FALSE;
-
- return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
-}
-
-// Sets a property
-cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* Key, const char *Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- if (!Val) return FALSE;
- if (!*Val) return FALSE;
-
- return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
-}
-
-cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- char Buffer[1024];
-
- sprintf(Buffer, it8->DoubleFormatter, Val);
-
- return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
-}
-
-cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- char Buffer[1024];
-
- sprintf(Buffer, "%u", Val);
-
- return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
-}
-
-cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL;
-}
-
-cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL;
-}
-
-// Gets a property
-const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* Key)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- KEYVALUE* p;
-
- if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p))
- {
- return p -> Value;
- }
- return NULL;
-}
-
-
-cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp)
-{
- const char *v = cmsIT8GetProperty(hIT8, cProp);
-
- if (v == NULL) return 0.0;
-
- return ParseFloatNumber(v);
-}
-
-const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- KEYVALUE* p;
-
- if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p)) {
- return p -> Value;
- }
- return NULL;
-}
-
-// ----------------------------------------------------------------- Datasets
-
-
-static
-void AllocateDataFormat(cmsIT8* it8)
-{
- TABLE* t = GetTable(it8);
-
- if (t -> DataFormat) return; // Already allocated
-
- t -> nSamples = (int) cmsIT8GetPropertyDbl(it8, "NUMBER_OF_FIELDS");
-
- if (t -> nSamples <= 0) {
-
- SynError(it8, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS");
- t -> nSamples = 10;
- }
-
- t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *));
- if (t->DataFormat == NULL) {
-
- SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array");
- }
-
-}
-
-static
-const char *GetDataFormat(cmsIT8* it8, int n)
-{
- TABLE* t = GetTable(it8);
-
- if (t->DataFormat)
- return t->DataFormat[n];
-
- return NULL;
-}
-
-static
-cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
-{
- TABLE* t = GetTable(it8);
-
- if (!t->DataFormat)
- AllocateDataFormat(it8);
-
- if (n > t -> nSamples) {
- SynError(it8, "More than NUMBER_OF_FIELDS fields.");
- return FALSE;
- }
-
- if (t->DataFormat) {
- t->DataFormat[n] = AllocString(it8, label);
- }
-
- return TRUE;
-}
-
-
-cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
-{
- cmsIT8* it8 = (cmsIT8*) h;
- return SetDataFormat(it8, n, Sample);
-}
-
-static
-void AllocateDataSet(cmsIT8* it8)
-{
- TABLE* t = GetTable(it8);
-
- if (t -> Data) return; // Already allocated
-
- t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
- t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
-
- t-> Data = (char**)AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * ((cmsUInt32Number) t->nPatches + 1) *sizeof (char*));
- if (t->Data == NULL) {
-
- SynError(it8, "AllocateDataSet: Unable to allocate data array");
- }
-
-}
-
-static
-char* GetData(cmsIT8* it8, int nSet, int nField)
-{
- TABLE* t = GetTable(it8);
- int nSamples = t -> nSamples;
- int nPatches = t -> nPatches;
-
- if (nSet >= nPatches || nField >= nSamples)
- return NULL;
-
- if (!t->Data) return NULL;
- return t->Data [nSet * nSamples + nField];
-}
-
-static
-cmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val)
-{
- TABLE* t = GetTable(it8);
-
- if (!t->Data)
- AllocateDataSet(it8);
-
- if (!t->Data) return FALSE;
-
- if (nSet > t -> nPatches || nSet < 0) {
-
- return SynError(it8, "Patch %d out of range, there are %d patches", nSet, t -> nPatches);
- }
-
- if (nField > t ->nSamples || nField < 0) {
- return SynError(it8, "Sample %d out of range, there are %d samples", nField, t ->nSamples);
-
- }
-
- t->Data [nSet * t -> nSamples + nField] = AllocString(it8, Val);
- return TRUE;
-}
-
-
-// --------------------------------------------------------------- File I/O
-
-
-// Writes a string to file
-static
-void WriteStr(SAVESTREAM* f, const char *str)
-{
- cmsUInt32Number len;
-
- if (str == NULL)
- str = " ";
-
- // Length to write
- len = (cmsUInt32Number) strlen(str);
- f ->Used += len;
-
-
- if (f ->stream) { // Should I write it to a file?
-
- if (fwrite(str, 1, len, f->stream) != len) {
- cmsSignalError(0, cmsERROR_WRITE, "Write to file error in CGATS parser");
- return;
- }
-
- }
- else { // Or to a memory block?
-
- if (f ->Base) { // Am I just counting the bytes?
-
- if (f ->Used > f ->Max) {
-
- cmsSignalError(0, cmsERROR_WRITE, "Write to memory overflows in CGATS parser");
- return;
- }
-
- memmove(f ->Ptr, str, len);
- f->Ptr += len;
- }
-
- }
-}
-
-
-// Write formatted
-
-static
-void Writef(SAVESTREAM* f, const char* frm, ...)
-{
- char Buffer[4096];
- va_list args;
-
- va_start(args, frm);
- vsnprintf(Buffer, 4095, frm, args);
- Buffer[4095] = 0;
- WriteStr(f, Buffer);
- va_end(args);
-
-}
-
-// Writes full header
-static
-void WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
-{
- KEYVALUE* p;
- TABLE* t = GetTable(it8);
-
- // Writes the type
- WriteStr(fp, t->SheetType);
- WriteStr(fp, "\n");
-
- for (p = t->HeaderList; (p != NULL); p = p->Next)
- {
- if (*p ->Keyword == '#') {
-
- char* Pt;
-
- WriteStr(fp, "#\n# ");
- for (Pt = p ->Value; *Pt; Pt++) {
-
-
- Writef(fp, "%c", *Pt);
-
- if (*Pt == '\n') {
- WriteStr(fp, "# ");
- }
- }
-
- WriteStr(fp, "\n#\n");
- continue;
- }
-
-
- if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) {
-
-#ifdef CMS_STRICT_CGATS
- WriteStr(fp, "KEYWORD\t\"");
- WriteStr(fp, p->Keyword);
- WriteStr(fp, "\"\n");
-#endif
-
- AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED);
- }
-
- WriteStr(fp, p->Keyword);
- if (p->Value) {
-
- switch (p ->WriteAs) {
-
- case WRITE_UNCOOKED:
- Writef(fp, "\t%s", p ->Value);
- break;
-
- case WRITE_STRINGIFY:
- Writef(fp, "\t\"%s\"", p->Value );
- break;
-
- case WRITE_HEXADECIMAL:
- Writef(fp, "\t0x%X", atoi(p ->Value));
- break;
-
- case WRITE_BINARY:
- 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;
- }
- }
-
- WriteStr (fp, "\n");
- }
-
-}
-
-
-// Writes the data format
-static
-void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
-{
- int i, nSamples;
- TABLE* t = GetTable(it8);
-
- if (!t -> DataFormat) return;
-
- WriteStr(fp, "BEGIN_DATA_FORMAT\n");
- WriteStr(fp, " ");
- nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
-
- for (i = 0; i < nSamples; i++) {
-
- WriteStr(fp, t->DataFormat[i]);
- WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
- }
-
- WriteStr (fp, "END_DATA_FORMAT\n");
-}
-
-
-// Writes data array
-static
-void WriteData(SAVESTREAM* fp, cmsIT8* it8)
-{
- int i, j;
- TABLE* t = GetTable(it8);
-
- if (!t->Data) return;
-
- WriteStr (fp, "BEGIN_DATA\n");
-
- t->nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
-
- for (i = 0; i < t-> nPatches; i++) {
-
- WriteStr(fp, " ");
-
- for (j = 0; j < t->nSamples; j++) {
-
- char *ptr = t->Data[i*t->nSamples+j];
-
- if (ptr == NULL) WriteStr(fp, "\"\"");
- else {
- // If value contains whitespace, enclose within quote
-
- if (strchr(ptr, ' ') != NULL) {
-
- WriteStr(fp, "\"");
- WriteStr(fp, ptr);
- WriteStr(fp, "\"");
- }
- else
- WriteStr(fp, ptr);
- }
-
- WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t"));
- }
- }
- WriteStr (fp, "END_DATA\n");
-}
-
-
-
-// Saves whole file
-cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName)
-{
- SAVESTREAM sd;
- cmsUInt32Number i;
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- memset(&sd, 0, sizeof(sd));
-
- sd.stream = fopen(cFileName, "wt");
- if (!sd.stream) return FALSE;
-
- for (i=0; i < it8 ->TablesCount; i++) {
-
- cmsIT8SetTable(hIT8, i);
- WriteHeader(it8, &sd);
- WriteDataFormat(&sd, it8);
- WriteData(&sd, it8);
- }
-
- if (fclose(sd.stream) != 0) return FALSE;
-
- return TRUE;
-}
-
-
-// Saves to memory
-cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* BytesNeeded)
-{
- SAVESTREAM sd;
- cmsUInt32Number i;
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- memset(&sd, 0, sizeof(sd));
-
- sd.stream = NULL;
- sd.Base = (cmsUInt8Number*) MemPtr;
- sd.Ptr = sd.Base;
-
- sd.Used = 0;
-
- if (sd.Base)
- sd.Max = *BytesNeeded; // Write to memory?
- else
- sd.Max = 0; // Just counting the needed bytes
-
- for (i=0; i < it8 ->TablesCount; i++) {
-
- cmsIT8SetTable(hIT8, i);
- WriteHeader(it8, &sd);
- WriteDataFormat(&sd, it8);
- WriteData(&sd, it8);
- }
-
- sd.Used++; // The \0 at the very end
-
- if (sd.Base)
- *sd.Ptr = 0;
-
- *BytesNeeded = sd.Used;
-
- return TRUE;
-}
-
-
-// -------------------------------------------------------------- Higer level parsing
-
-static
-cmsBool DataFormatSection(cmsIT8* it8)
-{
- int iField = 0;
- TABLE* t = GetTable(it8);
-
- InSymbol(it8); // Eats "BEGIN_DATA_FORMAT"
- CheckEOLN(it8);
-
- while (it8->sy != SEND_DATA_FORMAT &&
- it8->sy != SEOLN &&
- it8->sy != SEOF &&
- it8->sy != SSYNERROR) {
-
- if (it8->sy != SIDENT) {
-
- return SynError(it8, "Sample type expected");
- }
-
- if (!SetDataFormat(it8, iField, it8->id)) return FALSE;
- iField++;
-
- InSymbol(it8);
- SkipEOLN(it8);
- }
-
- SkipEOLN(it8);
- Skip(it8, SEND_DATA_FORMAT);
- SkipEOLN(it8);
-
- if (iField != t ->nSamples) {
- SynError(it8, "Count mismatch. NUMBER_OF_FIELDS was %d, found %d\n", t ->nSamples, iField);
-
-
- }
-
- return TRUE;
-}
-
-
-
-static
-cmsBool DataSection (cmsIT8* it8)
-{
- int iField = 0;
- int iSet = 0;
- char Buffer[256];
- TABLE* 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) {
- iField = 0;
- iSet++;
-
- }
-
- if (it8->sy != SEND_DATA && it8->sy != SEOF) {
-
- if (!GetVal(it8, Buffer, 255, "Sample data expected"))
- return FALSE;
-
- if (!SetData(it8, iSet, iField, Buffer))
- return FALSE;
-
- iField++;
-
- InSymbol(it8);
- SkipEOLN(it8);
- }
- }
-
- SkipEOLN(it8);
- Skip(it8, SEND_DATA);
- SkipEOLN(it8);
-
- // Check for data completion.
-
- if ((iSet+1) != t -> nPatches)
- return SynError(it8, "Count mismatch. NUMBER_OF_SETS was %d, found %d\n", t ->nPatches, iSet+1);
-
- return TRUE;
-}
-
-
-
-
-static
-cmsBool HeaderSection(cmsIT8* it8)
-{
- char VarName[MAXID];
- char Buffer[MAXSTR];
- KEYVALUE* Key;
-
- while (it8->sy != SEOF &&
- it8->sy != SSYNERROR &&
- it8->sy != SBEGIN_DATA_FORMAT &&
- it8->sy != SBEGIN_DATA) {
-
-
- switch (it8 -> sy) {
-
- case SKEYWORD:
- InSymbol(it8);
- 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;
-
-
- case SIDENT:
- strncpy(VarName, it8->id, MAXID-1);
- VarName[MAXID-1] = 0;
-
- if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
-
-#ifdef CMS_STRICT_CGATS
- return SynError(it8, "Undefined keyword '%s'", VarName);
-#else
- Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
- if (Key == NULL) return FALSE;
-#endif
- }
-
- InSymbol(it8);
- if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
-
- 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;
-
-
- case SEOLN: break;
-
- default:
- return SynError(it8, "expected keyword or identifier");
- }
-
- SkipEOLN(it8);
- }
-
- return TRUE;
-
-}
-
-
-static
-void ReadType(cmsIT8* it8, char* SheetTypePtr)
-{
- // First line is a very special case.
-
- while (isseparator(it8->ch))
- NextCh(it8);
-
- while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
-
- *SheetTypePtr++= (char) it8 ->ch;
- NextCh(it8);
- }
-
- *SheetTypePtr = 0;
-}
-
-
-static
-cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
-{
- char* SheetTypePtr = it8 ->Tab[0].SheetType;
-
- if (nosheet == 0) {
- ReadType(it8, SheetTypePtr);
- }
-
- InSymbol(it8);
-
- SkipEOLN(it8);
-
- while (it8-> sy != SEOF &&
- it8-> sy != SSYNERROR) {
-
- switch (it8 -> sy) {
-
- case SBEGIN_DATA_FORMAT:
- if (!DataFormatSection(it8)) return FALSE;
- break;
-
- case SBEGIN_DATA:
-
- if (!DataSection(it8)) return FALSE;
-
- if (it8 -> sy != SEOF) {
-
- AllocTable(it8);
- it8 ->nTable = it8 ->TablesCount - 1;
-
- // Read sheet type if present. We only support identifier and string.
- // <ident> <eoln> is a type string
- // anything else, is not a type string
- if (nosheet == 0) {
-
- if (it8 ->sy == SIDENT) {
-
- // May be a type sheet or may be a prop value statement. We cannot use insymbol in
- // this special case...
- while (isseparator(it8->ch))
- NextCh(it8);
-
- // If a newline is found, then this is a type string
- if (it8 ->ch == '\n' || it8->ch == '\r') {
-
- cmsIT8SetSheetType(it8, it8 ->id);
- InSymbol(it8);
- }
- else
- {
- // It is not. Just continue
- cmsIT8SetSheetType(it8, "");
- }
- }
- else
- // Validate quoted strings
- if (it8 ->sy == SSTRING) {
- cmsIT8SetSheetType(it8, it8 ->str);
- InSymbol(it8);
- }
- }
-
- }
- break;
-
- case SEOLN:
- SkipEOLN(it8);
- break;
-
- default:
- if (!HeaderSection(it8)) return FALSE;
- }
-
- }
-
- return (it8 -> sy != SSYNERROR);
-}
-
-
-
-// Init usefull pointers
-
-static
-void CookPointers(cmsIT8* it8)
-{
- int idField, i;
- char* Fld;
- cmsUInt32Number j;
- cmsUInt32Number nOldTable = it8 ->nTable;
-
- for (j=0; j < it8 ->TablesCount; j++) {
-
- TABLE* t = it8 ->Tab + j;
-
- t -> SampleID = 0;
- it8 ->nTable = j;
-
- for (idField = 0; idField < t -> nSamples; idField++)
- {
- if (t ->DataFormat == NULL){
- SynError(it8, "Undefined DATA_FORMAT");
- return;
- }
-
- Fld = t->DataFormat[idField];
- if (!Fld) continue;
-
-
- if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
-
- t -> SampleID = idField;
-
- for (i=0; i < t -> nPatches; i++) {
-
- char *Data = GetData(it8, i, idField);
- if (Data) {
- char Buffer[256];
-
- strncpy(Buffer, Data, 255);
- Buffer[255] = 0;
-
- if (strlen(Buffer) <= strlen(Data))
- strcpy(Data, Buffer);
- else
- SetData(it8, i, idField, Buffer);
-
- }
- }
-
- }
-
- // "LABEL" is an extension. It keeps references to forward tables
-
- if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$' ) {
-
- // Search for table references...
- for (i=0; i < t -> nPatches; i++) {
-
- char *Label = GetData(it8, i, idField);
-
- if (Label) {
-
- cmsUInt32Number k;
-
- // This is the label, search for a table containing
- // this property
-
- for (k=0; k < it8 ->TablesCount; k++) {
-
- TABLE* Table = it8 ->Tab + k;
- KEYVALUE* p;
-
- if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
-
- // Available, keep type and table
- char Buffer[256];
-
- char *Type = p ->Value;
- int nTable = (int) k;
-
- snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type );
-
- SetData(it8, i, idField, Buffer);
- }
- }
-
-
- }
-
- }
-
-
- }
-
- }
- }
-
- it8 ->nTable = nOldTable;
-}
-
-// Try to infere if the file is a CGATS/IT8 file at all. Read first line
-// that should be something like some printable characters plus a \n
-// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
-static
-int IsMyBlock(cmsUInt8Number* Buffer, int n)
-{
- int words = 1, space = 0, quot = 0;
- int i;
-
- if (n < 10) return 0; // Too small
-
- if (n > 132)
- n = 132;
-
- for (i = 1; i < n; i++) {
-
- switch(Buffer[i])
- {
- case '\n':
- case '\r':
- return ((quot == 1) || (words > 2)) ? 0 : words;
- 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;
- words += space;
- space = 0;
- break;
- }
- }
-
- return 0;
-}
-
-
-static
-cmsBool IsMyFile(const char* FileName)
-{
- FILE *fp;
- cmsUInt32Number Size;
- cmsUInt8Number Ptr[133];
-
- fp = fopen(FileName, "rt");
- if (!fp) {
- cmsSignalError(0, cmsERROR_FILE, "File '%s' not found", FileName);
- return FALSE;
- }
-
- Size = (cmsUInt32Number) fread(Ptr, 1, 132, fp);
-
- if (fclose(fp) != 0)
- return FALSE;
-
- Ptr[Size] = '\0';
-
- return IsMyBlock(Ptr, Size);
-}
-
-// ---------------------------------------------------------- Exported routines
-
-
-cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len)
-{
- cmsHANDLE hIT8;
- cmsIT8* it8;
- int type;
-
- _cmsAssert(Ptr != NULL);
- _cmsAssert(len != 0);
-
- type = IsMyBlock((cmsUInt8Number*)Ptr, len);
- if (type == 0) return NULL;
-
- hIT8 = cmsIT8Alloc(ContextID);
- if (!hIT8) return NULL;
-
- it8 = (cmsIT8*) hIT8;
- it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
-
- strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
- it8 ->MemoryBlock[len] = 0;
-
- strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1);
- it8-> Source = it8 -> MemoryBlock;
-
- if (!ParseIT8(it8, type-1)) {
-
- cmsIT8Free(hIT8);
- return FALSE;
- }
-
- CookPointers(it8);
- it8 ->nTable = 0;
-
- _cmsFree(ContextID, it8->MemoryBlock);
- it8 -> MemoryBlock = NULL;
-
- return hIT8;
-
-
-}
-
-
-cmsHANDLE CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName)
-{
-
- cmsHANDLE hIT8;
- cmsIT8* it8;
- int type;
-
- _cmsAssert(cFileName != NULL);
-
- type = IsMyFile(cFileName);
- if (type == 0) return NULL;
-
- hIT8 = cmsIT8Alloc(ContextID);
- it8 = (cmsIT8*) hIT8;
- if (!hIT8) return NULL;
-
-
- it8 ->FileStack[0]->Stream = fopen(cFileName, "rt");
-
- if (!it8 ->FileStack[0]->Stream) {
- cmsIT8Free(hIT8);
- return NULL;
- }
-
-
- strncpy(it8->FileStack[0]->FileName, cFileName, cmsMAX_PATH-1);
- it8->FileStack[0]->FileName[cmsMAX_PATH-1] = 0;
-
- if (!ParseIT8(it8, type-1)) {
-
- fclose(it8 ->FileStack[0]->Stream);
- cmsIT8Free(hIT8);
- return NULL;
- }
-
- CookPointers(it8);
- it8 ->nTable = 0;
-
- if (fclose(it8 ->FileStack[0]->Stream)!= 0) {
- cmsIT8Free(hIT8);
- return NULL;
- }
-
- return hIT8;
-
-}
-
-int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- TABLE* t;
-
- _cmsAssert(hIT8 != NULL);
-
- t = GetTable(it8);
-
- if (SampleNames)
- *SampleNames = t -> DataFormat;
- return t -> nSamples;
-}
-
-
-cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- KEYVALUE* p;
- cmsUInt32Number n;
- char **Props;
- TABLE* t;
-
- _cmsAssert(hIT8 != NULL);
-
- t = GetTable(it8);
-
- // Pass#1 - count properties
-
- n = 0;
- for (p = t -> HeaderList; p != NULL; p = p->Next) {
- n++;
- }
-
-
- Props = (char **) AllocChunk(it8, sizeof(char *) * n);
-
- // Pass#2 - Fill pointers
- n = 0;
- for (p = t -> HeaderList; p != NULL; p = p->Next) {
- Props[n++] = p -> Keyword;
- }
-
- *PropertyNames = Props;
- return n;
-}
-
-cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- KEYVALUE *p, *tmp;
- cmsUInt32Number n;
- const char **Props;
- TABLE* t;
-
- _cmsAssert(hIT8 != NULL);
-
-
- 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(cmsIT8* it8, const char* cPatch)
-{
- int i;
- const char *data;
- TABLE* t = GetTable(it8);
-
- for (i=0; i < t-> nPatches; i++) {
-
- data = GetData(it8, i, t->SampleID);
-
- if (data != NULL) {
-
- if (cmsstrcasecmp(data, cPatch) == 0)
- return i;
- }
- }
-
- // SynError(it8, "Couldn't find patch '%s'\n", cPatch);
- return -1;
-}
-
-
-static
-int LocateEmptyPatch(cmsIT8* it8)
-{
- int i;
- const char *data;
- TABLE* t = GetTable(it8);
-
- for (i=0; i < t-> nPatches; i++) {
-
- data = GetData(it8, i, t->SampleID);
-
- if (data == NULL)
- return i;
-
- }
-
- return -1;
-}
-
-static
-int LocateSample(cmsIT8* it8, const char* cSample)
-{
- int i;
- const char *fld;
- TABLE* t = GetTable(it8);
-
- for (i=0; i < t->nSamples; i++) {
-
- fld = GetDataFormat(it8, i);
- if (cmsstrcasecmp(fld, cSample) == 0)
- return i;
- }
-
- return -1;
-
-}
-
-
-int CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- _cmsAssert(hIT8 != NULL);
-
- return LocateSample(it8, cSample);
-}
-
-
-
-const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- _cmsAssert(hIT8 != NULL);
-
- return GetData(it8, row, col);
-}
-
-
-cmsFloat64Number CMSEXPORT cmsIT8GetDataRowColDbl(cmsHANDLE hIT8, int row, int col)
-{
- const char* Buffer;
-
- Buffer = cmsIT8GetDataRowCol(hIT8, row, col);
-
- if (Buffer == NULL) return 0.0;
-
- return ParseFloatNumber(Buffer);
-}
-
-
-cmsBool CMSEXPORT cmsIT8SetDataRowCol(cmsHANDLE hIT8, int row, int col, const char* Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- _cmsAssert(hIT8 != NULL);
-
- return SetData(it8, row, col, Val);
-}
-
-
-cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFloat64Number Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- char Buff[256];
-
- _cmsAssert(hIT8 != NULL);
-
- sprintf(Buff, it8->DoubleFormatter, Val);
-
- return SetData(it8, row, col, Buff);
-}
-
-
-
-const char* CMSEXPORT cmsIT8GetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- int iField, iSet;
-
- _cmsAssert(hIT8 != NULL);
-
- iField = LocateSample(it8, cSample);
- if (iField < 0) {
- return NULL;
- }
-
- iSet = LocatePatch(it8, cPatch);
- if (iSet < 0) {
- return NULL;
- }
-
- return GetData(it8, iSet, iField);
-}
-
-
-cmsFloat64Number CMSEXPORT cmsIT8GetDataDbl(cmsHANDLE it8, const char* cPatch, const char* cSample)
-{
- const char* Buffer;
-
- Buffer = cmsIT8GetData(it8, cPatch, cSample);
-
- return ParseFloatNumber(Buffer);
-}
-
-
-
-cmsBool CMSEXPORT cmsIT8SetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample, const char *Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- int iField, iSet;
- TABLE* t;
-
- _cmsAssert(hIT8 != NULL);
-
- t = GetTable(it8);
-
- iField = LocateSample(it8, cSample);
-
- if (iField < 0)
- return FALSE;
-
- if (t-> nPatches == 0) {
-
- AllocateDataFormat(it8);
- AllocateDataSet(it8);
- CookPointers(it8);
- }
-
- if (cmsstrcasecmp(cSample, "SAMPLE_ID") == 0) {
-
- iSet = LocateEmptyPatch(it8);
- if (iSet < 0) {
- return SynError(it8, "Couldn't add more patches '%s'\n", cPatch);
- }
-
- iField = t -> SampleID;
- }
- else {
- iSet = LocatePatch(it8, cPatch);
- if (iSet < 0) {
- return FALSE;
- }
- }
-
- return SetData(it8, iSet, iField, Val);
-}
-
-
-cmsBool CMSEXPORT cmsIT8SetDataDbl(cmsHANDLE hIT8, const char* cPatch,
- const char* cSample,
- cmsFloat64Number Val)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- char Buff[256];
-
- _cmsAssert(hIT8 != NULL);
-
- snprintf(Buff, 255, it8->DoubleFormatter, Val);
- return cmsIT8SetData(hIT8, cPatch, cSample, Buff);
-}
-
-// Buffer should get MAXSTR at least
-
-const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- TABLE* t;
- char* Data;
-
- _cmsAssert(hIT8 != NULL);
-
- t = GetTable(it8);
- Data = GetData(it8, nPatch, t->SampleID);
-
- if (!Data) return NULL;
- if (!buffer) return Data;
-
- strncpy(buffer, Data, MAXSTR-1);
- buffer[MAXSTR-1] = 0;
- return buffer;
-}
-
-int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch)
-{
- _cmsAssert(hIT8 != NULL);
-
- return LocatePatch((cmsIT8*)hIT8, cPatch);
-}
-
-cmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- _cmsAssert(hIT8 != NULL);
-
- return it8 ->TablesCount;
-}
-
-// This handles the "LABEL" extension.
-// Label, nTable, Type
-
-int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType)
-{
- const char* cLabelFld;
- char Type[256], Label[256];
- int nTable;
-
- _cmsAssert(hIT8 != NULL);
-
- if (cField != NULL && *cField == 0)
- cField = "LABEL";
-
- if (cField == NULL)
- cField = "LABEL";
-
- cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
- if (!cLabelFld) return -1;
-
- if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3)
- return -1;
-
- if (ExpectedType != NULL && *ExpectedType == 0)
- ExpectedType = NULL;
-
- if (ExpectedType) {
-
- if (cmsstrcasecmp(Type, ExpectedType) != 0) return -1;
- }
-
- return cmsIT8SetTable(hIT8, nTable);
-}
-
-
-cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
- int pos;
-
- _cmsAssert(hIT8 != NULL);
-
- pos = LocateSample(it8, cSample);
- if(pos == -1)
- return FALSE;
-
- it8->Tab[it8->nTable].SampleID = pos;
- return TRUE;
-}
-
-
-void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter)
-{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- _cmsAssert(hIT8 != NULL);
-
- if (Formatter == NULL)
- strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
- else
- strncpy(it8->DoubleFormatter, Formatter, sizeof(it8->DoubleFormatter));
-
- it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
-}