Commit message: Upgrade Visual studio 2017 15.8

- Upgrade to 15.8
- Add check on CGATS memory allocation (thanks to Quang Nguyen for
pointing out this)
CVE: CVE-2018-16435
CWE: CWE-190
Vulnerability description: Little CMS (aka Little Color Management System) 2.9 has an integer overflow in the AllocateDataSet function in cmscgats.c, leading to a heap-based buffer overflow in the SetData function via a crafted file in the second argument to cmsIT8LoadFromFile.

Project: Little-CMS
File: cmscgats.c

KEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key)
{
    return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
}

Project: Little-CMS

KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
{
    KEYVALUE* p;
    KEYVALUE* last;



    if (IsAvailableOnList(*Head, Key, Subkey, &p)) {


    }
    else {

        last = p;

        p = (KEYVALUE*) AllocChunk(it8, sizeof(KEYVALUE));
        if (p == NULL)
        {
            SynError(it8, "AddToList: out of memory");
            return NULL;
        }

        p->Keyword = AllocString(it8, Key);
        p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey);

        if (*Head == NULL) {
            *Head = p;
        }
        else
        {
            if (Subkey != NULL && last != NULL) {

                last->NextSubkey = p;

                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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;

}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

void AllocTable(cmsIT8* it8)
{
    TABLE* t;

    t = it8 ->Tab + it8 ->TablesCount;

    t->HeaderList = NULL;
    t->DataFormat = NULL;
    t->Data       = NULL;

    it8 ->TablesCount++;
}

Project: Little-CMS
File: cmscgats.c

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");
    }

}

Project: Little-CMS
File: cmscgats.c

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 SUNDEFINED;
}

Project: Little-CMS
File: cmscgats.c

cmsBool Check(cmsIT8* it8, SYMBOL sy, const char* Err)
{
        if (it8 -> sy != sy)
                return SynError(it8, NoMeta(Err));
        return TRUE;
}

Project: Little-CMS
File: cmscgats.c

cmsBool CheckEOLN(cmsIT8* it8)
{
        if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
        while (it8 -> sy == SEOLN)
                        InSymbol(it8);
        return TRUE;

}

Project: Little-CMS

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);

                }
            }

        }


        if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$' ) {

                    for (i=0; i < t -> nPatches; i++) {

                            char *Label = GetData(it8, i, idField);

                            if (Label) {

                                cmsUInt32Number k;


                                for (k=0; k < it8 ->TablesCount; k++) {

                                    TABLE* Table = it8 ->Tab + k;
                                    KEYVALUE* p;

                                    if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {

                                        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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS

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);


    if ((iSet+1) != t -> nPatches)
        return SynError(it8, "Count mismatch. NUMBER_OF_SETS was %d, found %d\n", t ->nPatches, iSet+1);

    return TRUE;
}

Project: Little-CMS
File: cmscgats.c

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];
}

Project: Little-CMS
File: cmscgats.c

const char *GetDataFormat(cmsIT8* it8, int n)
{
    TABLE* t = GetTable(it8);

    if (t->DataFormat)
        return t->DataFormat[n];

    return NULL;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS

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);

                for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
                {
                    char *Value, *temp;

                    Nextkey = (char*)strchr(Subkey, ';');
                    if (Nextkey)
                        *Nextkey++ = '\0';

                    Value = (char*)strrchr(Subkey, ',');
                    if (Value == NULL)
                        return SynError(it8, "Invalid value for property '%s'.", VarName);

                    temp = Value++;
                    do *temp-- = '\0'; while (temp >= Subkey && *temp == ' ');

                    temp = Value + strlen(Value) - 1;
                    while (*temp == ' ') *temp-- = '\0';

                    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;

}

Project: Little-CMS

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 == SUNDEFINED) 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 ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0)
                            {
                                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 ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0)
                            {
                                SynError(it8, "Invalid binary number");
                                return;
                            }

                            it8->inum = it8->inum * 2 + j;
                            NextCh(it8);
                        }
                        return;
                    }
                }


                while (isdigit(it8->ch)) {

                    cmsInt32Number digit = (it8->ch - '0');

                    if ((cmsFloat64Number) it8->inum * 10.0 + (cmsFloat64Number) digit > (cmsFloat64Number) +2147483647.0) {
                        ReadReal(it8, it8->inum);
                        it8->sy = SDNUM;
                        it8->dnum *= sign;
                        return;
                    }

                    it8->inum = it8->inum * 10 + digit;
                    NextCh(it8);
                }

                if (it8->ch == '.') {

                    ReadReal(it8, it8->inum);
                    it8->sy = SDNUM;
                    it8->dnum *= sign;
                    return;
                }

                it8 -> inum *= sign;


                if (isidchar(it8 ->ch)) {

                    if (it8 ->sy == SINUM) {

                        snprintf(it8->id, 127, "%d", it8->inum);
                    }
                    else {

                        snprintf(it8->id, 127, 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) {

        case '\x1a':
            NextCh(it8);
            break;

        case 0:
        case -1:
            it8->sy = SEOF;
            break;


        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;

        case '#':
            NextCh(it8);
            while (it8->ch && it8->ch != '\n' && it8->ch != '\r')
                NextCh(it8);

            it8->sy = SCOMMENT;
            break;

        case '\'':
        case '\"':
            idptr = it8->str;
            sng = it8->ch;
            k = 0;
            NextCh(it8);

            while (k < (MAXSTR-1) && 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);


    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 (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);
    }

}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n)
{
    int words = 1, space = 0, quot = 0;
    cmsUInt32Number 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;
}

Project: Little-CMS
File: cmscgats.c

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);
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS

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;
                }
        }

        return -1;
}

Project: Little-CMS
File: cmscgats.c

const char* NoMeta(const char* str)
{
    if (strchr(str, '%') != NULL)
        return "**** CORRUPTED FORMAT STRING ***";

    return str;
}

Project: Little-CMS

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;

                            if (nosheet == 0) {

                                if (it8 ->sy == SIDENT) {

                                     while (isseparator(it8->ch))
                                         NextCh(it8);

                                    if (it8 ->ch == '\n' || it8->ch == '\r') {

                                         cmsIT8SetSheetType(it8, it8 ->id);
                                         InSymbol(it8);
                                    }
                                    else
                                    {
                                        cmsIT8SetSheetType(it8, "");
                                    }
                                }
                                else
                                    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);
}

Project: Little-CMS

void ReadReal(cmsIT8* it8, cmsInt32Number inum)
{
    it8->dnum = (cmsFloat64Number)inum;

    while (isdigit(it8->ch)) {

        it8->dnum = (cmsFloat64Number)it8->dnum * 10.0 + (cmsFloat64Number)(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 + (cmsFloat64Number)(it8->ch - '0');
            prec++;
            NextCh(it8);
        }

        it8->dnum = it8->dnum + (frac / xpow10(prec));
    }

    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)) {

            cmsInt32Number digit = (it8->ch - '0');

            if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0)
                e = e * 10 + digit;

            NextCh(it8);
        }

        e = sgn*e;
        it8->dnum = it8->dnum * xpow10(e);
    }
}

Project: Little-CMS

void ReadType(cmsIT8* it8, char* SheetTypePtr)
{
    cmsInt32Number cnt = 0;


    while (isseparator(it8->ch))
            NextCh(it8);

    while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {

        if (cnt++ < MAXSTR) 
            *SheetTypePtr++= (char) it8 ->ch;
        NextCh(it8);
    }

    *SheetTypePtr = 0;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

void Skip(cmsIT8* it8, SYMBOL sy)
{
        if (it8->sy == sy && it8->sy != SEOF)
                        InSymbol(it8);
}

Project: Little-CMS
File: cmscgats.c

void SkipEOLN(cmsIT8* it8)
{
    while (it8->sy == SEOLN) {
             InSymbol(it8);
    }
}

Project: Little-CMS

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 (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");
}

Project: Little-CMS
File: cmscgats.c

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");
}

Project: Little-CMS

void WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
{
    KEYVALUE* p;
    TABLE* t = GetTable(it8);

    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");
    }

}

Project: Little-CMS
File: cmscgats.c

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);

}

Project: Little-CMS

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 = SUNDEFINED;
    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");


    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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS

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);


    n = 0;
    for (p = t -> HeaderList;  p != NULL; p = p->Next) {
        n++;
    }


    Props = (char **) AllocChunk(it8, sizeof(char *) * n);

    n = 0;
    for (p = t -> HeaderList;  p != NULL; p = p->Next) {
        Props[n++] = p -> Keyword;
    }

    *PropertyNames = Props;
    return n;
}

Project: Little-CMS

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;
    }


    n = 0;
    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
        if(tmp->Subkey != NULL)
            n++;
    }


    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);

    n = 0;
    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
        if(tmp->Subkey != NULL)
            Props[n++] = p ->Subkey;
    }

    *SubpropertyNames = Props;
    return n;
}

Project: Little-CMS
File: cmscgats.c

int CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;

    _cmsAssert(hIT8 != NULL);

    return LocateSample(it8, cSample);
}

Project: Little-CMS
File: cmscgats.c

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);
}

Project: Little-CMS
File: cmscgats.c

const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;

    _cmsAssert(hIT8 != NULL);

    return GetData(it8, row, col);
}

Project: Little-CMS
File: cmscgats.c

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);
}

Project: Little-CMS
File: cmscgats.c

int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch)
{
    _cmsAssert(hIT8 != NULL);

    return LocatePatch((cmsIT8*)hIT8, cPatch);
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp)
{
    const char *v = cmsIT8GetProperty(hIT8, cProp);

    if (v == NULL) return 0.0;

    return ParseFloatNumber(v);
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8)
{
        return GetTable((cmsIT8*) hIT8)->SheetType;
}

Project: Little-CMS
File: cmscgats.c

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;

}

Project: Little-CMS
File: cmscgats.c

cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
{
    cmsHANDLE hIT8;
    cmsIT8*  it8;
    int type;

    _cmsAssert(Ptr != NULL);
    _cmsAssert(len != 0);

    type = IsMyBlock((const 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);
    if (it8->MemoryBlock == NULL)
    {
        cmsIT8Free(hIT8);
        return FALSE;
    }

    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;


}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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);
}

Project: Little-CMS
File: cmscgats.c

cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE  h, int n, const char *Sample)
{
    cmsIT8* it8 = (cmsIT8*)h;
    return SetDataFormat(it8, n, Sample);
}

Project: Little-CMS
File: cmscgats.c

cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFloat64Number Val)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;
    char Buff[256];

    _cmsAssert(hIT8 != NULL);

    snprintf(Buff, 255, it8->DoubleFormatter, Val);

    return SetData(it8, row, col, Buff);
}

Project: Little-CMS
File: cmscgats.c

cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;
    char Buffer[1024];

    snprintf(Buffer, 1023, it8->DoubleFormatter, Val);

    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
}

Project: Little-CMS
File: cmscgats.c

cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;
    char Buffer[1024];

    snprintf(Buffer, 1023, "%u", Val);

    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType)
{
    const char* cLabelFld;
    char Type[256], Label[256];
    cmsUInt32Number 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 %u %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);
}

Project: Little-CMS
File: cmscgats.c

cmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8)
{
    cmsIT8* it8 = (cmsIT8*) hIT8;

    _cmsAssert(hIT8 != NULL);

    return it8 ->TablesCount;
}

Project: Little-CMS
File: cmscgats.c

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;
}

Project: Little-CMS
File: cmscgats.c

cmsBool isidchar(int c)
{
   return isalnum(c) || ismiddle(c);
}

Project: Little-CMS
File: cmscgats.c

cmsBool ismiddle(int c)
{
   return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
}

Project: Little-CMS
File: cmscgats.c

cmsBool isseparator(int c)
{
    return (c == ' ') || (c == '\t') ; 
}