From c397ab0ad492471f8b45c237c43098ff1936156e Mon Sep 17 00:00:00 2001 From: Marti Maria Date: Thu, 15 Dec 2011 14:35:29 +0100 Subject: Fixed CGATS parser to accept types in multitable sheets --- src/cmscgats.c | 94 ++++++++++++++++++++++++++++++++-------------- utils/samples/roundtrip.c | 96 +++++++++++++++++++++++++++++------------------ 2 files changed, 124 insertions(+), 66 deletions(-) diff --git a/src/cmscgats.c b/src/cmscgats.c index c096905..e4ccfbf 100644 --- a/src/cmscgats.c +++ b/src/cmscgats.c @@ -114,6 +114,8 @@ typedef struct _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 @@ -133,8 +135,7 @@ typedef struct _FileContext { // This struct hold all information about an open IT8 handler. typedef struct { - char SheetType[MAXSTR]; // The first row of the IT8 (the type) - + cmsUInt32Number TablesCount; // How many tables in this stream cmsUInt32Number nTable; // The actual table @@ -1214,7 +1215,7 @@ cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID) it8 -> lineno = 1; strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT); - strcpy(it8->SheetType, "CGATS.17"); + cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17"); // Initialize predefined properties & data @@ -1230,19 +1231,16 @@ cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID) const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8) -{ - cmsIT8* it8 = (cmsIT8*) hIT8; - - return it8 ->SheetType; - +{ + return GetTable((cmsIT8*) hIT8)->SheetType; } cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type) { - cmsIT8* it8 = (cmsIT8*) hIT8; + TABLE* t = GetTable((cmsIT8*) hIT8); - strncpy(it8 ->SheetType, Type, MAXSTR-1); - it8 ->SheetType[MAXSTR-1] = 0; + strncpy(t ->SheetType, Type, MAXSTR-1); + t ->SheetType[MAXSTR-1] = 0; return TRUE; } @@ -1524,7 +1522,10 @@ 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 == '#') { @@ -1672,8 +1673,6 @@ cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName) sd.stream = fopen(cFileName, "wt"); if (!sd.stream) return FALSE; - WriteStr(&sd, it8->SheetType); - WriteStr(&sd, "\n"); for (i=0; i < it8 ->TablesCount; i++) { cmsIT8SetTable(hIT8, i); @@ -1708,8 +1707,6 @@ cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* else sd.Max = 0; // Just counting the needed bytes - WriteStr(&sd, it8->SheetType); - WriteStr(&sd, "\n"); for (i=0; i < it8 ->TablesCount; i++) { cmsIT8SetTable(hIT8, i); @@ -1934,12 +1931,8 @@ cmsBool HeaderSection(cmsIT8* it8) static -cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet) -{ - char* SheetTypePtr = it8 ->SheetType; - - if (nosheet == 0) { - +void ReadType(cmsIT8* it8, char* SheetTypePtr) +{ // First line is a very special case. while (isseparator(it8->ch)) @@ -1950,9 +1943,20 @@ cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet) *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); @@ -1969,11 +1973,44 @@ cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet) 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. + // 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') { + + 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; @@ -2094,14 +2131,14 @@ void CookPointers(cmsIT8* it8) // 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 static int IsMyBlock(cmsUInt8Number* Buffer, int n) { int cols = 1, space = 0, quot = 0; int i; - if (n < 10) return FALSE; // Too small + if (n < 10) return 0; // Too small if (n > 132) n = 132; @@ -2112,7 +2149,7 @@ int IsMyBlock(cmsUInt8Number* Buffer, int n) { case '\n': case '\r': - return quot == 1 || cols > 2 ? 0 : cols; + return ((quot == 1) || (cols > 2)) ? 0 : cols; case '\t': case ' ': if(!quot && !space) @@ -2130,8 +2167,7 @@ int IsMyBlock(cmsUInt8Number* Buffer, int n) } } - return FALSE; - + return 0; } diff --git a/utils/samples/roundtrip.c b/utils/samples/roundtrip.c index 024a190..d957b60 100644 --- a/utils/samples/roundtrip.c +++ b/utils/samples/roundtrip.c @@ -1,15 +1,37 @@ +// +// Little cms +// Copyright (C) 1998-2011 Marti Maria +// +// 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 #include "lcms2.h" +#include + static -double VecDist(BYTE bin[3], BYTE bout[3]) +double VecDist(cmsUInt8Number bin[3], cmsUInt8Number bout[3]) { double rdist, gdist, bdist; - rdist = fabs(bout[0] - bin[0]); - gdist = fabs(bout[1] - bin[1]); - bdist = fabs(bout[2] - bin[2]); + rdist = fabs((double) bout[0] - bin[0]); + gdist = fabs((double) bout[1] - bin[1]); + bdist = fabs((double) bout[2] - bin[2]); return (sqrt((rdist*rdist + gdist*gdist + bdist*bdist))); } @@ -18,49 +40,49 @@ double VecDist(BYTE bin[3], BYTE bout[3]) int main(int argc, char* argv[]) { - int r, g, b; - BYTE RGB[3], RGB_OUT[3]; - cmsHTRANSFORM xform; - cmsHPROFILE hProfile; - double err, SumX=0, SumX2=0, Peak = 0, n = 0; + int r, g, b; + cmsUInt8Number RGB[3], RGB_OUT[3]; + cmsHTRANSFORM xform; + cmsHPROFILE hProfile; + double err, SumX=0, SumX2=0, Peak = 0, n = 0; - if (argc != 2) { - printf("roundtrip \n"); - return 1; - } + if (argc != 2) { + printf("roundtrip \n"); + return 1; + } - hProfile = cmsOpenProfileFromFile(argv[1], "r"); - xform = cmsCreateTransform(hProfile,TYPE_RGB_8, hProfile, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); + hProfile = cmsOpenProfileFromFile(argv[1], "r"); + xform = cmsCreateTransform(hProfile,TYPE_RGB_8, hProfile, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); - for (r=0; r< 256; r++) { - printf("%d \r", r); - for (g=0; g < 256; g++) { - for (b=0; b < 256; b++) { + for (r=0; r< 256; r++) { + printf("%d \r", r); + for (g=0; g < 256; g++) { + for (b=0; b < 256; b++) { - RGB[0] = r; - RGB[1] = g; - RGB[2] = b; + RGB[0] = r; + RGB[1] = g; + RGB[2] = b; - cmsDoTransform(xform, RGB, RGB_OUT, 1); + cmsDoTransform(xform, RGB, RGB_OUT, 1); - err = VecDist(RGB, RGB_OUT); + err = VecDist(RGB, RGB_OUT); - SumX += err; + SumX += err; SumX2 += err * err; - n += 1.0; - if (err > Peak) - Peak = err; + n += 1.0; + if (err > Peak) + Peak = err; - } - } - } + } + } + } - printf("Average %g\n", SumX / n); - printf("Max %g\n", Peak); - printf("Std %g\n", sqrt((n*SumX2 - SumX * SumX) / (n*(n-1)))); - cmsCloseProfile(hProfile); - cmsDeleteTransform(xform); + printf("Average %g\n", SumX / n); + printf("Max %g\n", Peak); + printf("Std %g\n", sqrt((n*SumX2 - SumX * SumX) / (n*(n-1)))); + cmsCloseProfile(hProfile); + cmsDeleteTransform(xform); - return 0; + return 0; } \ No newline at end of file -- cgit v1.2.1