xref: /aosp_15_r20/external/pdfium/third_party/lcms/src/cmscgats.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
2*3ac0a46fSAndroid Build Coastguard Worker //
3*3ac0a46fSAndroid Build Coastguard Worker //  Little Color Management System
4*3ac0a46fSAndroid Build Coastguard Worker //  Copyright (c) 1998-2023 Marti Maria Saguer
5*3ac0a46fSAndroid Build Coastguard Worker //
6*3ac0a46fSAndroid Build Coastguard Worker // Permission is hereby granted, free of charge, to any person obtaining
7*3ac0a46fSAndroid Build Coastguard Worker // a copy of this software and associated documentation files (the "Software"),
8*3ac0a46fSAndroid Build Coastguard Worker // to deal in the Software without restriction, including without limitation
9*3ac0a46fSAndroid Build Coastguard Worker // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*3ac0a46fSAndroid Build Coastguard Worker // and/or sell copies of the Software, and to permit persons to whom the Software
11*3ac0a46fSAndroid Build Coastguard Worker // is furnished to do so, subject to the following conditions:
12*3ac0a46fSAndroid Build Coastguard Worker //
13*3ac0a46fSAndroid Build Coastguard Worker // The above copyright notice and this permission notice shall be included in
14*3ac0a46fSAndroid Build Coastguard Worker // all copies or substantial portions of the Software.
15*3ac0a46fSAndroid Build Coastguard Worker //
16*3ac0a46fSAndroid Build Coastguard Worker // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*3ac0a46fSAndroid Build Coastguard Worker // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18*3ac0a46fSAndroid Build Coastguard Worker // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*3ac0a46fSAndroid Build Coastguard Worker // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20*3ac0a46fSAndroid Build Coastguard Worker // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21*3ac0a46fSAndroid Build Coastguard Worker // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22*3ac0a46fSAndroid Build Coastguard Worker // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker //
24*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
25*3ac0a46fSAndroid Build Coastguard Worker //
26*3ac0a46fSAndroid Build Coastguard Worker 
27*3ac0a46fSAndroid Build Coastguard Worker #include "lcms2_internal.h"
28*3ac0a46fSAndroid Build Coastguard Worker 
29*3ac0a46fSAndroid Build Coastguard Worker 
30*3ac0a46fSAndroid Build Coastguard Worker // IT8.7 / CGATS.17-200x handling -----------------------------------------------------------------------------
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker 
33*3ac0a46fSAndroid Build Coastguard Worker #define MAXID        128     // Max length of identifier
34*3ac0a46fSAndroid Build Coastguard Worker #define MAXSTR      1024     // Max length of string
35*3ac0a46fSAndroid Build Coastguard Worker #define MAXTABLES    255     // Max Number of tables in a single stream
36*3ac0a46fSAndroid Build Coastguard Worker #define MAXINCLUDE    20     // Max number of nested includes
37*3ac0a46fSAndroid Build Coastguard Worker 
38*3ac0a46fSAndroid Build Coastguard Worker #define DEFAULT_DBL_FORMAT  "%.10g" // Double formatting
39*3ac0a46fSAndroid Build Coastguard Worker 
40*3ac0a46fSAndroid Build Coastguard Worker #ifdef CMS_IS_WINDOWS_
41*3ac0a46fSAndroid Build Coastguard Worker //sunliang.liu modified 2010426 for wince error
42*3ac0a46fSAndroid Build Coastguard Worker # ifndef _WIN32_WCE
43*3ac0a46fSAndroid Build Coastguard Worker #   include <io.h>
44*3ac0a46fSAndroid Build Coastguard Worker # endif
45*3ac0a46fSAndroid Build Coastguard Worker #    define DIR_CHAR    '\\'
46*3ac0a46fSAndroid Build Coastguard Worker #else
47*3ac0a46fSAndroid Build Coastguard Worker #    define DIR_CHAR    '/'
48*3ac0a46fSAndroid Build Coastguard Worker #endif
49*3ac0a46fSAndroid Build Coastguard Worker 
50*3ac0a46fSAndroid Build Coastguard Worker 
51*3ac0a46fSAndroid Build Coastguard Worker // Symbols
52*3ac0a46fSAndroid Build Coastguard Worker typedef enum {
53*3ac0a46fSAndroid Build Coastguard Worker 
54*3ac0a46fSAndroid Build Coastguard Worker         SUNDEFINED,
55*3ac0a46fSAndroid Build Coastguard Worker         SINUM,      // Integer
56*3ac0a46fSAndroid Build Coastguard Worker         SDNUM,      // Real
57*3ac0a46fSAndroid Build Coastguard Worker         SIDENT,     // Identifier
58*3ac0a46fSAndroid Build Coastguard Worker         SSTRING,    // string
59*3ac0a46fSAndroid Build Coastguard Worker         SCOMMENT,   // comment
60*3ac0a46fSAndroid Build Coastguard Worker         SEOLN,      // End of line
61*3ac0a46fSAndroid Build Coastguard Worker         SEOF,       // End of stream
62*3ac0a46fSAndroid Build Coastguard Worker         SSYNERROR,  // Syntax error found on stream
63*3ac0a46fSAndroid Build Coastguard Worker 
64*3ac0a46fSAndroid Build Coastguard Worker         // Keywords
65*3ac0a46fSAndroid Build Coastguard Worker 
66*3ac0a46fSAndroid Build Coastguard Worker         SBEGIN_DATA,
67*3ac0a46fSAndroid Build Coastguard Worker         SBEGIN_DATA_FORMAT,
68*3ac0a46fSAndroid Build Coastguard Worker         SEND_DATA,
69*3ac0a46fSAndroid Build Coastguard Worker         SEND_DATA_FORMAT,
70*3ac0a46fSAndroid Build Coastguard Worker         SKEYWORD,
71*3ac0a46fSAndroid Build Coastguard Worker         SDATA_FORMAT_ID,
72*3ac0a46fSAndroid Build Coastguard Worker         SINCLUDE
73*3ac0a46fSAndroid Build Coastguard Worker 
74*3ac0a46fSAndroid Build Coastguard Worker     } SYMBOL;
75*3ac0a46fSAndroid Build Coastguard Worker 
76*3ac0a46fSAndroid Build Coastguard Worker 
77*3ac0a46fSAndroid Build Coastguard Worker // How to write the value
78*3ac0a46fSAndroid Build Coastguard Worker typedef enum {
79*3ac0a46fSAndroid Build Coastguard Worker 
80*3ac0a46fSAndroid Build Coastguard Worker         WRITE_UNCOOKED,
81*3ac0a46fSAndroid Build Coastguard Worker         WRITE_STRINGIFY,
82*3ac0a46fSAndroid Build Coastguard Worker         WRITE_HEXADECIMAL,
83*3ac0a46fSAndroid Build Coastguard Worker         WRITE_BINARY,
84*3ac0a46fSAndroid Build Coastguard Worker         WRITE_PAIR
85*3ac0a46fSAndroid Build Coastguard Worker 
86*3ac0a46fSAndroid Build Coastguard Worker     } WRITEMODE;
87*3ac0a46fSAndroid Build Coastguard Worker 
88*3ac0a46fSAndroid Build Coastguard Worker // Linked list of variable names
89*3ac0a46fSAndroid Build Coastguard Worker typedef struct _KeyVal {
90*3ac0a46fSAndroid Build Coastguard Worker 
91*3ac0a46fSAndroid Build Coastguard Worker         struct _KeyVal*  Next;
92*3ac0a46fSAndroid Build Coastguard Worker         char*            Keyword;       // Name of variable
93*3ac0a46fSAndroid Build Coastguard Worker         struct _KeyVal*  NextSubkey;    // If key is a dictionary, points to the next item
94*3ac0a46fSAndroid Build Coastguard Worker         char*            Subkey;        // If key is a dictionary, points to the subkey name
95*3ac0a46fSAndroid Build Coastguard Worker         char*            Value;         // Points to value
96*3ac0a46fSAndroid Build Coastguard Worker         WRITEMODE        WriteAs;       // How to write the value
97*3ac0a46fSAndroid Build Coastguard Worker 
98*3ac0a46fSAndroid Build Coastguard Worker    } KEYVALUE;
99*3ac0a46fSAndroid Build Coastguard Worker 
100*3ac0a46fSAndroid Build Coastguard Worker 
101*3ac0a46fSAndroid Build Coastguard Worker // Linked list of memory chunks (Memory sink)
102*3ac0a46fSAndroid Build Coastguard Worker typedef struct _OwnedMem {
103*3ac0a46fSAndroid Build Coastguard Worker 
104*3ac0a46fSAndroid Build Coastguard Worker         struct _OwnedMem* Next;
105*3ac0a46fSAndroid Build Coastguard Worker         void *            Ptr;          // Point to value
106*3ac0a46fSAndroid Build Coastguard Worker 
107*3ac0a46fSAndroid Build Coastguard Worker    } OWNEDMEM;
108*3ac0a46fSAndroid Build Coastguard Worker 
109*3ac0a46fSAndroid Build Coastguard Worker // Suballocator
110*3ac0a46fSAndroid Build Coastguard Worker typedef struct _SubAllocator {
111*3ac0a46fSAndroid Build Coastguard Worker 
112*3ac0a46fSAndroid Build Coastguard Worker          cmsUInt8Number* Block;
113*3ac0a46fSAndroid Build Coastguard Worker          cmsUInt32Number BlockSize;
114*3ac0a46fSAndroid Build Coastguard Worker          cmsUInt32Number Used;
115*3ac0a46fSAndroid Build Coastguard Worker 
116*3ac0a46fSAndroid Build Coastguard Worker     } SUBALLOCATOR;
117*3ac0a46fSAndroid Build Coastguard Worker 
118*3ac0a46fSAndroid Build Coastguard Worker // Table. Each individual table can hold properties and rows & cols
119*3ac0a46fSAndroid Build Coastguard Worker typedef struct _Table {
120*3ac0a46fSAndroid Build Coastguard Worker 
121*3ac0a46fSAndroid Build Coastguard Worker         char SheetType[MAXSTR];               // The first row of the IT8 (the type)
122*3ac0a46fSAndroid Build Coastguard Worker 
123*3ac0a46fSAndroid Build Coastguard Worker         int            nSamples, nPatches;    // Cols, Rows
124*3ac0a46fSAndroid Build Coastguard Worker         int            SampleID;              // Pos of ID
125*3ac0a46fSAndroid Build Coastguard Worker 
126*3ac0a46fSAndroid Build Coastguard Worker         KEYVALUE*      HeaderList;            // The properties
127*3ac0a46fSAndroid Build Coastguard Worker 
128*3ac0a46fSAndroid Build Coastguard Worker         char**         DataFormat;            // The binary stream descriptor
129*3ac0a46fSAndroid Build Coastguard Worker         char**         Data;                  // The binary stream
130*3ac0a46fSAndroid Build Coastguard Worker 
131*3ac0a46fSAndroid Build Coastguard Worker     } TABLE;
132*3ac0a46fSAndroid Build Coastguard Worker 
133*3ac0a46fSAndroid Build Coastguard Worker // File stream being parsed
134*3ac0a46fSAndroid Build Coastguard Worker typedef struct _FileContext {
135*3ac0a46fSAndroid Build Coastguard Worker         char           FileName[cmsMAX_PATH];    // File name if being read from file
136*3ac0a46fSAndroid Build Coastguard Worker         FILE*          Stream;                   // File stream or NULL if holded in memory
137*3ac0a46fSAndroid Build Coastguard Worker     } FILECTX;
138*3ac0a46fSAndroid Build Coastguard Worker 
139*3ac0a46fSAndroid Build Coastguard Worker //Very simple string
140*3ac0a46fSAndroid Build Coastguard Worker typedef struct {
141*3ac0a46fSAndroid Build Coastguard Worker 
142*3ac0a46fSAndroid Build Coastguard Worker         struct struct_it8* it8;
143*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number max;
144*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number len;
145*3ac0a46fSAndroid Build Coastguard Worker         char* begin;
146*3ac0a46fSAndroid Build Coastguard Worker     } string;
147*3ac0a46fSAndroid Build Coastguard Worker 
148*3ac0a46fSAndroid Build Coastguard Worker 
149*3ac0a46fSAndroid Build Coastguard Worker // This struct hold all information about an open IT8 handler.
150*3ac0a46fSAndroid Build Coastguard Worker typedef struct struct_it8 {
151*3ac0a46fSAndroid Build Coastguard Worker 
152*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt32Number  TablesCount;                     // How many tables in this stream
153*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt32Number  nTable;                          // The actual table
154*3ac0a46fSAndroid Build Coastguard Worker 
155*3ac0a46fSAndroid Build Coastguard Worker         TABLE Tab[MAXTABLES];
156*3ac0a46fSAndroid Build Coastguard Worker 
157*3ac0a46fSAndroid Build Coastguard Worker         // Memory management
158*3ac0a46fSAndroid Build Coastguard Worker         OWNEDMEM*      MemorySink;            // The storage backend
159*3ac0a46fSAndroid Build Coastguard Worker         SUBALLOCATOR   Allocator;             // String suballocator -- just to keep it fast
160*3ac0a46fSAndroid Build Coastguard Worker 
161*3ac0a46fSAndroid Build Coastguard Worker         // Parser state machine
162*3ac0a46fSAndroid Build Coastguard Worker         SYMBOL             sy;                // Current symbol
163*3ac0a46fSAndroid Build Coastguard Worker         int                ch;                // Current character
164*3ac0a46fSAndroid Build Coastguard Worker 
165*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number     inum;              // integer value
166*3ac0a46fSAndroid Build Coastguard Worker         cmsFloat64Number   dnum;              // real value
167*3ac0a46fSAndroid Build Coastguard Worker 
168*3ac0a46fSAndroid Build Coastguard Worker         string*        id;            // identifier
169*3ac0a46fSAndroid Build Coastguard Worker         string*        str;           // string
170*3ac0a46fSAndroid Build Coastguard Worker 
171*3ac0a46fSAndroid Build Coastguard Worker         // Allowed keywords & datasets. They have visibility on whole stream
172*3ac0a46fSAndroid Build Coastguard Worker         KEYVALUE*      ValidKeywords;
173*3ac0a46fSAndroid Build Coastguard Worker         KEYVALUE*      ValidSampleID;
174*3ac0a46fSAndroid Build Coastguard Worker 
175*3ac0a46fSAndroid Build Coastguard Worker         char*          Source;                // Points to loc. being parsed
176*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number lineno;                // line counter for error reporting
177*3ac0a46fSAndroid Build Coastguard Worker 
178*3ac0a46fSAndroid Build Coastguard Worker         FILECTX*       FileStack[MAXINCLUDE]; // Stack of files being parsed
179*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number IncludeSP;             // Include Stack Pointer
180*3ac0a46fSAndroid Build Coastguard Worker 
181*3ac0a46fSAndroid Build Coastguard Worker         char*          MemoryBlock;           // The stream if holded in memory
182*3ac0a46fSAndroid Build Coastguard Worker 
183*3ac0a46fSAndroid Build Coastguard Worker         char           DoubleFormatter[MAXID];// Printf-like 'cmsFloat64Number' formatter
184*3ac0a46fSAndroid Build Coastguard Worker 
185*3ac0a46fSAndroid Build Coastguard Worker         cmsContext    ContextID;              // The threading context
186*3ac0a46fSAndroid Build Coastguard Worker 
187*3ac0a46fSAndroid Build Coastguard Worker    } cmsIT8;
188*3ac0a46fSAndroid Build Coastguard Worker 
189*3ac0a46fSAndroid Build Coastguard Worker 
190*3ac0a46fSAndroid Build Coastguard Worker // The stream for save operations
191*3ac0a46fSAndroid Build Coastguard Worker typedef struct {
192*3ac0a46fSAndroid Build Coastguard Worker 
193*3ac0a46fSAndroid Build Coastguard Worker         FILE* stream;   // For save-to-file behaviour
194*3ac0a46fSAndroid Build Coastguard Worker 
195*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt8Number* Base;
196*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt8Number* Ptr;        // For save-to-mem behaviour
197*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt32Number Used;
198*3ac0a46fSAndroid Build Coastguard Worker         cmsUInt32Number Max;
199*3ac0a46fSAndroid Build Coastguard Worker 
200*3ac0a46fSAndroid Build Coastguard Worker     } SAVESTREAM;
201*3ac0a46fSAndroid Build Coastguard Worker 
202*3ac0a46fSAndroid Build Coastguard Worker 
203*3ac0a46fSAndroid Build Coastguard Worker // ------------------------------------------------------ cmsIT8 parsing routines
204*3ac0a46fSAndroid Build Coastguard Worker 
205*3ac0a46fSAndroid Build Coastguard Worker 
206*3ac0a46fSAndroid Build Coastguard Worker // A keyword
207*3ac0a46fSAndroid Build Coastguard Worker typedef struct {
208*3ac0a46fSAndroid Build Coastguard Worker 
209*3ac0a46fSAndroid Build Coastguard Worker         const char *id;
210*3ac0a46fSAndroid Build Coastguard Worker         SYMBOL sy;
211*3ac0a46fSAndroid Build Coastguard Worker 
212*3ac0a46fSAndroid Build Coastguard Worker    } KEYWORD;
213*3ac0a46fSAndroid Build Coastguard Worker 
214*3ac0a46fSAndroid Build Coastguard Worker // The keyword->symbol translation table. Sorting is required.
215*3ac0a46fSAndroid Build Coastguard Worker static const KEYWORD TabKeys[] = {
216*3ac0a46fSAndroid Build Coastguard Worker 
217*3ac0a46fSAndroid Build Coastguard Worker         {"$INCLUDE",               SINCLUDE},   // This is an extension!
218*3ac0a46fSAndroid Build Coastguard Worker         {".INCLUDE",               SINCLUDE},   // This is an extension!
219*3ac0a46fSAndroid Build Coastguard Worker 
220*3ac0a46fSAndroid Build Coastguard Worker         {"BEGIN_DATA",             SBEGIN_DATA },
221*3ac0a46fSAndroid Build Coastguard Worker         {"BEGIN_DATA_FORMAT",      SBEGIN_DATA_FORMAT },
222*3ac0a46fSAndroid Build Coastguard Worker         {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID},
223*3ac0a46fSAndroid Build Coastguard Worker         {"END_DATA",               SEND_DATA},
224*3ac0a46fSAndroid Build Coastguard Worker         {"END_DATA_FORMAT",        SEND_DATA_FORMAT},
225*3ac0a46fSAndroid Build Coastguard Worker         {"KEYWORD",                SKEYWORD}
226*3ac0a46fSAndroid Build Coastguard Worker         };
227*3ac0a46fSAndroid Build Coastguard Worker 
228*3ac0a46fSAndroid Build Coastguard Worker #define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
229*3ac0a46fSAndroid Build Coastguard Worker 
230*3ac0a46fSAndroid Build Coastguard Worker // Predefined properties
231*3ac0a46fSAndroid Build Coastguard Worker 
232*3ac0a46fSAndroid Build Coastguard Worker // A property
233*3ac0a46fSAndroid Build Coastguard Worker typedef struct {
234*3ac0a46fSAndroid Build Coastguard Worker         const char *id;    // The identifier
235*3ac0a46fSAndroid Build Coastguard Worker         WRITEMODE as;      // How is supposed to be written
236*3ac0a46fSAndroid Build Coastguard Worker     } PROPERTY;
237*3ac0a46fSAndroid Build Coastguard Worker 
238*3ac0a46fSAndroid Build Coastguard Worker static PROPERTY PredefinedProperties[] = {
239*3ac0a46fSAndroid Build Coastguard Worker 
240*3ac0a46fSAndroid Build Coastguard Worker         {"NUMBER_OF_FIELDS", WRITE_UNCOOKED},    // Required - NUMBER OF FIELDS
241*3ac0a46fSAndroid Build Coastguard Worker         {"NUMBER_OF_SETS",   WRITE_UNCOOKED},    // Required - NUMBER OF SETS
242*3ac0a46fSAndroid Build Coastguard Worker         {"ORIGINATOR",       WRITE_STRINGIFY},   // Required - Identifies the specific system, organization or individual that created the data file.
243*3ac0a46fSAndroid Build Coastguard Worker         {"FILE_DESCRIPTOR",  WRITE_STRINGIFY},   // Required - Describes the purpose or contents of the data file.
244*3ac0a46fSAndroid Build Coastguard Worker         {"CREATED",          WRITE_STRINGIFY},   // Required - Indicates date of creation of the data file.
245*3ac0a46fSAndroid Build Coastguard Worker         {"DESCRIPTOR",       WRITE_STRINGIFY},   // Required  - Describes the purpose or contents of the data file.
246*3ac0a46fSAndroid Build Coastguard Worker         {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY},   // The diffuse geometry used. Allowed values are "sphere" or "opal".
247*3ac0a46fSAndroid Build Coastguard Worker         {"MANUFACTURER",     WRITE_STRINGIFY},
248*3ac0a46fSAndroid Build Coastguard Worker         {"MANUFACTURE",      WRITE_STRINGIFY},   // Some broken Fuji targets does store this value
249*3ac0a46fSAndroid Build Coastguard Worker         {"PROD_DATE",        WRITE_STRINGIFY},   // Identifies year and month of production of the target in the form yyyy:mm.
250*3ac0a46fSAndroid Build Coastguard Worker         {"SERIAL",           WRITE_STRINGIFY},   // Uniquely identifies individual physical target.
251*3ac0a46fSAndroid Build Coastguard Worker 
252*3ac0a46fSAndroid Build Coastguard Worker         {"MATERIAL",         WRITE_STRINGIFY},    // Identifies the material on which the target was produced using a code
253*3ac0a46fSAndroid Build Coastguard Worker                                                   // uniquely identifying th e material. This is intend ed to be used for IT8.7
254*3ac0a46fSAndroid Build Coastguard Worker                                                   // physical targets only (i.e . IT8.7/1 and IT8.7/2).
255*3ac0a46fSAndroid Build Coastguard Worker 
256*3ac0a46fSAndroid Build Coastguard Worker         {"INSTRUMENTATION",  WRITE_STRINGIFY},    // Used to report the specific instrumentation used (manufacturer and
257*3ac0a46fSAndroid Build Coastguard Worker                                                   // model number) to generate the data reported. This data will often
258*3ac0a46fSAndroid Build Coastguard Worker                                                   // provide more information about the particular data collected than an
259*3ac0a46fSAndroid Build Coastguard Worker                                                   // extensive list of specific details. This is particularly important for
260*3ac0a46fSAndroid Build Coastguard Worker                                                   // spectral data or data derived from spectrophotometry.
261*3ac0a46fSAndroid Build Coastguard Worker 
262*3ac0a46fSAndroid Build Coastguard Worker         {"MEASUREMENT_SOURCE", WRITE_STRINGIFY},  // Illumination used for spectral measurements. This data helps provide
263*3ac0a46fSAndroid Build Coastguard Worker                                                   // a guide to the potential for issues of paper fluorescence, etc.
264*3ac0a46fSAndroid Build Coastguard Worker 
265*3ac0a46fSAndroid Build Coastguard Worker         {"PRINT_CONDITIONS", WRITE_STRINGIFY},     // Used to define the characteristics of the printed sheet being reported.
266*3ac0a46fSAndroid Build Coastguard Worker                                                    // Where standard conditions have been defined (e.g., SWOP at nominal)
267*3ac0a46fSAndroid Build Coastguard Worker                                                    // named conditions may suffice. Otherwise, detailed information is
268*3ac0a46fSAndroid Build Coastguard Worker                                                    // needed.
269*3ac0a46fSAndroid Build Coastguard Worker 
270*3ac0a46fSAndroid Build Coastguard Worker         {"SAMPLE_BACKING",   WRITE_STRINGIFY},     // Identifies the backing material used behind the sample during
271*3ac0a46fSAndroid Build Coastguard Worker                                                    // measurement. Allowed values are "black", "white", or {"na".
272*3ac0a46fSAndroid Build Coastguard Worker 
273*3ac0a46fSAndroid Build Coastguard Worker         {"CHISQ_DOF",        WRITE_STRINGIFY},     // Degrees of freedom associated with the Chi squared statistic
274*3ac0a46fSAndroid Build Coastguard Worker                                                    // below properties are new in recent specs:
275*3ac0a46fSAndroid Build Coastguard Worker 
276*3ac0a46fSAndroid Build Coastguard Worker         {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
277*3ac0a46fSAndroid Build Coastguard Worker                                                    // along with details of the geometry and the aperture size and shape. For example,
278*3ac0a46fSAndroid Build Coastguard Worker                                                    // for transmission measurements it is important to identify 0/diffuse, diffuse/0,
279*3ac0a46fSAndroid Build Coastguard Worker                                                    // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
280*3ac0a46fSAndroid Build Coastguard Worker                                                    // 45/0, sphere (specular included or excluded), etc.
281*3ac0a46fSAndroid Build Coastguard Worker 
282*3ac0a46fSAndroid Build Coastguard Worker        {"FILTER",            WRITE_STRINGIFY},     // Identifies the use of physical filter(s) during measurement. Typically used to
283*3ac0a46fSAndroid Build Coastguard Worker                                                    // denote the use of filters such as none, D65, Red, Green or Blue.
284*3ac0a46fSAndroid Build Coastguard Worker 
285*3ac0a46fSAndroid Build Coastguard Worker        {"POLARIZATION",      WRITE_STRINGIFY},     // Identifies the use of a physical polarization filter during measurement. Allowed
286*3ac0a46fSAndroid Build Coastguard Worker                                                    // values are {"yes", "white", "none" or "na".
287*3ac0a46fSAndroid Build Coastguard Worker 
288*3ac0a46fSAndroid Build Coastguard Worker        {"WEIGHTING_FUNCTION", WRITE_PAIR},         // Indicates such functions as: the CIE standard observer functions used in the
289*3ac0a46fSAndroid Build Coastguard Worker                                                    // calculation of various data parameters (2 degree and 10 degree), CIE standard
290*3ac0a46fSAndroid Build Coastguard Worker                                                    // illuminant functions used in the calculation of various data parameters (e.g., D50,
291*3ac0a46fSAndroid Build Coastguard Worker                                                    // D65, etc.), density status response, etc. If used there shall be at least one
292*3ac0a46fSAndroid Build Coastguard Worker                                                    // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
293*3ac0a46fSAndroid Build Coastguard Worker                                                    // in the set shall be {"name" and shall identify the particular parameter used.
294*3ac0a46fSAndroid Build Coastguard Worker                                                    // The second shall be {"value" and shall provide the value associated with that name.
295*3ac0a46fSAndroid Build Coastguard Worker                                                    // For ASCII data, a string containing the Name and Value attribute pairs shall follow
296*3ac0a46fSAndroid Build Coastguard Worker                                                    // the weighting function keyword. A semi-colon separates attribute pairs from each
297*3ac0a46fSAndroid Build Coastguard Worker                                                    // other and within the attribute the name and value are separated by a comma.
298*3ac0a46fSAndroid Build Coastguard Worker 
299*3ac0a46fSAndroid Build Coastguard Worker        {"COMPUTATIONAL_PARAMETER", WRITE_PAIR},    // Parameter that is used in computing a value from measured data. Name is the name
300*3ac0a46fSAndroid Build Coastguard Worker                                                    // of the calculation, parameter is the name of the parameter used in the calculation
301*3ac0a46fSAndroid Build Coastguard Worker                                                    // and value is the value of the parameter.
302*3ac0a46fSAndroid Build Coastguard Worker 
303*3ac0a46fSAndroid Build Coastguard Worker        {"TARGET_TYPE",        WRITE_STRINGIFY},    // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
304*3ac0a46fSAndroid Build Coastguard Worker 
305*3ac0a46fSAndroid Build Coastguard Worker        {"COLORANT",           WRITE_STRINGIFY},    // Identifies the colorant(s) used in creating the target.
306*3ac0a46fSAndroid Build Coastguard Worker 
307*3ac0a46fSAndroid Build Coastguard Worker        {"TABLE_DESCRIPTOR",   WRITE_STRINGIFY},    // Describes the purpose or contents of a data table.
308*3ac0a46fSAndroid Build Coastguard Worker 
309*3ac0a46fSAndroid Build Coastguard Worker        {"TABLE_NAME",         WRITE_STRINGIFY}     // Provides a short name for a data table.
310*3ac0a46fSAndroid Build Coastguard Worker };
311*3ac0a46fSAndroid Build Coastguard Worker 
312*3ac0a46fSAndroid Build Coastguard Worker #define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
313*3ac0a46fSAndroid Build Coastguard Worker 
314*3ac0a46fSAndroid Build Coastguard Worker 
315*3ac0a46fSAndroid Build Coastguard Worker // Predefined sample types on dataset
316*3ac0a46fSAndroid Build Coastguard Worker static const char* PredefinedSampleID[] = {
317*3ac0a46fSAndroid Build Coastguard Worker         "SAMPLE_ID",      // Identifies sample that data represents
318*3ac0a46fSAndroid Build Coastguard Worker         "STRING",         // Identifies label, or other non-machine readable value.
319*3ac0a46fSAndroid Build Coastguard Worker                           // Value must begin and end with a " symbol
320*3ac0a46fSAndroid Build Coastguard Worker 
321*3ac0a46fSAndroid Build Coastguard Worker         "CMYK_C",         // Cyan component of CMYK data expressed as a percentage
322*3ac0a46fSAndroid Build Coastguard Worker         "CMYK_M",         // Magenta component of CMYK data expressed as a percentage
323*3ac0a46fSAndroid Build Coastguard Worker         "CMYK_Y",         // Yellow component of CMYK data expressed as a percentage
324*3ac0a46fSAndroid Build Coastguard Worker         "CMYK_K",         // Black component of CMYK data expressed as a percentage
325*3ac0a46fSAndroid Build Coastguard Worker         "D_RED",          // Red filter density
326*3ac0a46fSAndroid Build Coastguard Worker         "D_GREEN",        // Green filter density
327*3ac0a46fSAndroid Build Coastguard Worker         "D_BLUE",         // Blue filter density
328*3ac0a46fSAndroid Build Coastguard Worker         "D_VIS",          // Visual filter density
329*3ac0a46fSAndroid Build Coastguard Worker         "D_MAJOR_FILTER", // Major filter d ensity
330*3ac0a46fSAndroid Build Coastguard Worker         "RGB_R",          // Red component of RGB data
331*3ac0a46fSAndroid Build Coastguard Worker         "RGB_G",          // Green component of RGB data
332*3ac0a46fSAndroid Build Coastguard Worker         "RGB_B",          // Blue com ponent of RGB data
333*3ac0a46fSAndroid Build Coastguard Worker         "SPECTRAL_NM",    // Wavelength of measurement expressed in nanometers
334*3ac0a46fSAndroid Build Coastguard Worker         "SPECTRAL_PCT",   // Percentage reflectance/transmittance
335*3ac0a46fSAndroid Build Coastguard Worker         "SPECTRAL_DEC",   // Reflectance/transmittance
336*3ac0a46fSAndroid Build Coastguard Worker         "XYZ_X",          // X component of tristimulus data
337*3ac0a46fSAndroid Build Coastguard Worker         "XYZ_Y",          // Y component of tristimulus data
338*3ac0a46fSAndroid Build Coastguard Worker         "XYZ_Z",          // Z component of tristimulus data
339*3ac0a46fSAndroid Build Coastguard Worker         "XYY_X",          // x component of chromaticity data
340*3ac0a46fSAndroid Build Coastguard Worker         "XYY_Y",          // y component of chromaticity data
341*3ac0a46fSAndroid Build Coastguard Worker         "XYY_CAPY",       // Y component of tristimulus data
342*3ac0a46fSAndroid Build Coastguard Worker         "LAB_L",          // L* component of Lab data
343*3ac0a46fSAndroid Build Coastguard Worker         "LAB_A",          // a* component of Lab data
344*3ac0a46fSAndroid Build Coastguard Worker         "LAB_B",          // b* component of Lab data
345*3ac0a46fSAndroid Build Coastguard Worker         "LAB_C",          // C*ab component of Lab data
346*3ac0a46fSAndroid Build Coastguard Worker         "LAB_H",          // hab component of Lab data
347*3ac0a46fSAndroid Build Coastguard Worker         "LAB_DE",         // CIE dE
348*3ac0a46fSAndroid Build Coastguard Worker         "LAB_DE_94",      // CIE dE using CIE 94
349*3ac0a46fSAndroid Build Coastguard Worker         "LAB_DE_CMC",     // dE using CMC
350*3ac0a46fSAndroid Build Coastguard Worker         "LAB_DE_2000",    // CIE dE using CIE DE 2000
351*3ac0a46fSAndroid Build Coastguard Worker         "MEAN_DE",        // Mean Delta E (LAB_DE) of samples compared to batch average
352*3ac0a46fSAndroid Build Coastguard Worker                           // (Used for data files for ANSI IT8.7/1 and IT8.7/2 targets)
353*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_X",        // Standard deviation of X (tristimulus data)
354*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_Y",        // Standard deviation of Y (tristimulus data)
355*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_Z",        // Standard deviation of Z (tristimulus data)
356*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_L",        // Standard deviation of L*
357*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_A",        // Standard deviation of a*
358*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_B",        // Standard deviation of b*
359*3ac0a46fSAndroid Build Coastguard Worker         "STDEV_DE",       // Standard deviation of CIE dE
360*3ac0a46fSAndroid Build Coastguard Worker         "CHI_SQD_PAR"};   // The average of the standard deviations of L*, a* and b*. It is
361*3ac0a46fSAndroid Build Coastguard Worker                           // used to derive an estimate of the chi-squared parameter which is
362*3ac0a46fSAndroid Build Coastguard Worker                           // recommended as the predictor of the variability of dE
363*3ac0a46fSAndroid Build Coastguard Worker 
364*3ac0a46fSAndroid Build Coastguard Worker #define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
365*3ac0a46fSAndroid Build Coastguard Worker 
366*3ac0a46fSAndroid Build Coastguard Worker //Forward declaration of some internal functions
367*3ac0a46fSAndroid Build Coastguard Worker static void* AllocChunk(cmsIT8* it8, cmsUInt32Number size);
368*3ac0a46fSAndroid Build Coastguard Worker 
369*3ac0a46fSAndroid Build Coastguard Worker static
StringAlloc(cmsIT8 * it8,int max)370*3ac0a46fSAndroid Build Coastguard Worker string* StringAlloc(cmsIT8* it8, int max)
371*3ac0a46fSAndroid Build Coastguard Worker {
372*3ac0a46fSAndroid Build Coastguard Worker     string* s = (string*) AllocChunk(it8, sizeof(string));
373*3ac0a46fSAndroid Build Coastguard Worker     if (s == NULL) return NULL;
374*3ac0a46fSAndroid Build Coastguard Worker 
375*3ac0a46fSAndroid Build Coastguard Worker     s->it8 = it8;
376*3ac0a46fSAndroid Build Coastguard Worker     s->max = max;
377*3ac0a46fSAndroid Build Coastguard Worker     s->len = 0;
378*3ac0a46fSAndroid Build Coastguard Worker     s->begin = (char*) AllocChunk(it8, s->max);
379*3ac0a46fSAndroid Build Coastguard Worker 
380*3ac0a46fSAndroid Build Coastguard Worker     return s;
381*3ac0a46fSAndroid Build Coastguard Worker }
382*3ac0a46fSAndroid Build Coastguard Worker 
383*3ac0a46fSAndroid Build Coastguard Worker static
StringClear(string * s)384*3ac0a46fSAndroid Build Coastguard Worker void StringClear(string* s)
385*3ac0a46fSAndroid Build Coastguard Worker {
386*3ac0a46fSAndroid Build Coastguard Worker     s->len = 0;
387*3ac0a46fSAndroid Build Coastguard Worker }
388*3ac0a46fSAndroid Build Coastguard Worker 
389*3ac0a46fSAndroid Build Coastguard Worker static
StringAppend(string * s,char c)390*3ac0a46fSAndroid Build Coastguard Worker void StringAppend(string* s, char c)
391*3ac0a46fSAndroid Build Coastguard Worker {
392*3ac0a46fSAndroid Build Coastguard Worker     if (s->len + 1 >= s->max)
393*3ac0a46fSAndroid Build Coastguard Worker     {
394*3ac0a46fSAndroid Build Coastguard Worker         char* new_ptr;
395*3ac0a46fSAndroid Build Coastguard Worker 
396*3ac0a46fSAndroid Build Coastguard Worker         s->max *= 10;
397*3ac0a46fSAndroid Build Coastguard Worker         new_ptr = (char*) AllocChunk(s->it8, s->max);
398*3ac0a46fSAndroid Build Coastguard Worker         if (new_ptr != NULL && s->begin != NULL)
399*3ac0a46fSAndroid Build Coastguard Worker             memcpy(new_ptr, s->begin, s->len);
400*3ac0a46fSAndroid Build Coastguard Worker 
401*3ac0a46fSAndroid Build Coastguard Worker         s->begin = new_ptr;
402*3ac0a46fSAndroid Build Coastguard Worker     }
403*3ac0a46fSAndroid Build Coastguard Worker 
404*3ac0a46fSAndroid Build Coastguard Worker     if (s->begin != NULL)
405*3ac0a46fSAndroid Build Coastguard Worker     {
406*3ac0a46fSAndroid Build Coastguard Worker         s->begin[s->len++] = c;
407*3ac0a46fSAndroid Build Coastguard Worker         s->begin[s->len] = 0;
408*3ac0a46fSAndroid Build Coastguard Worker     }
409*3ac0a46fSAndroid Build Coastguard Worker }
410*3ac0a46fSAndroid Build Coastguard Worker 
411*3ac0a46fSAndroid Build Coastguard Worker static
StringPtr(string * s)412*3ac0a46fSAndroid Build Coastguard Worker char* StringPtr(string* s)
413*3ac0a46fSAndroid Build Coastguard Worker {
414*3ac0a46fSAndroid Build Coastguard Worker     return s->begin;
415*3ac0a46fSAndroid Build Coastguard Worker }
416*3ac0a46fSAndroid Build Coastguard Worker 
417*3ac0a46fSAndroid Build Coastguard Worker static
StringCat(string * s,const char * c)418*3ac0a46fSAndroid Build Coastguard Worker void StringCat(string* s, const char* c)
419*3ac0a46fSAndroid Build Coastguard Worker {
420*3ac0a46fSAndroid Build Coastguard Worker     while (*c)
421*3ac0a46fSAndroid Build Coastguard Worker     {
422*3ac0a46fSAndroid Build Coastguard Worker         StringAppend(s, *c);
423*3ac0a46fSAndroid Build Coastguard Worker         c++;
424*3ac0a46fSAndroid Build Coastguard Worker     }
425*3ac0a46fSAndroid Build Coastguard Worker }
426*3ac0a46fSAndroid Build Coastguard Worker 
427*3ac0a46fSAndroid Build Coastguard Worker 
428*3ac0a46fSAndroid Build Coastguard Worker // Checks whatever c is a separator
429*3ac0a46fSAndroid Build Coastguard Worker static
isseparator(int c)430*3ac0a46fSAndroid Build Coastguard Worker cmsBool isseparator(int c)
431*3ac0a46fSAndroid Build Coastguard Worker {
432*3ac0a46fSAndroid Build Coastguard Worker     return (c == ' ') || (c == '\t') ;
433*3ac0a46fSAndroid Build Coastguard Worker }
434*3ac0a46fSAndroid Build Coastguard Worker 
435*3ac0a46fSAndroid Build Coastguard Worker // Checks whatever c is a valid identifier char
436*3ac0a46fSAndroid Build Coastguard Worker static
ismiddle(int c)437*3ac0a46fSAndroid Build Coastguard Worker cmsBool ismiddle(int c)
438*3ac0a46fSAndroid Build Coastguard Worker {
439*3ac0a46fSAndroid Build Coastguard Worker    return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
440*3ac0a46fSAndroid Build Coastguard Worker }
441*3ac0a46fSAndroid Build Coastguard Worker 
442*3ac0a46fSAndroid Build Coastguard Worker // Checks whatsever c is a valid identifier middle char.
443*3ac0a46fSAndroid Build Coastguard Worker static
isidchar(int c)444*3ac0a46fSAndroid Build Coastguard Worker cmsBool isidchar(int c)
445*3ac0a46fSAndroid Build Coastguard Worker {
446*3ac0a46fSAndroid Build Coastguard Worker    return isalnum(c) || ismiddle(c);
447*3ac0a46fSAndroid Build Coastguard Worker }
448*3ac0a46fSAndroid Build Coastguard Worker 
449*3ac0a46fSAndroid Build Coastguard Worker // Checks whatsever c is a valid identifier first char.
450*3ac0a46fSAndroid Build Coastguard Worker static
isfirstidchar(int c)451*3ac0a46fSAndroid Build Coastguard Worker cmsBool isfirstidchar(int c)
452*3ac0a46fSAndroid Build Coastguard Worker {
453*3ac0a46fSAndroid Build Coastguard Worker      return !isdigit(c) && ismiddle(c);
454*3ac0a46fSAndroid Build Coastguard Worker }
455*3ac0a46fSAndroid Build Coastguard Worker 
456*3ac0a46fSAndroid Build Coastguard Worker // Guess whether the supplied path looks like an absolute path
457*3ac0a46fSAndroid Build Coastguard Worker static
isabsolutepath(const char * path)458*3ac0a46fSAndroid Build Coastguard Worker cmsBool isabsolutepath(const char *path)
459*3ac0a46fSAndroid Build Coastguard Worker {
460*3ac0a46fSAndroid Build Coastguard Worker     char ThreeChars[4];
461*3ac0a46fSAndroid Build Coastguard Worker 
462*3ac0a46fSAndroid Build Coastguard Worker     if(path == NULL)
463*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
464*3ac0a46fSAndroid Build Coastguard Worker     if (path[0] == 0)
465*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
466*3ac0a46fSAndroid Build Coastguard Worker 
467*3ac0a46fSAndroid Build Coastguard Worker     strncpy(ThreeChars, path, 3);
468*3ac0a46fSAndroid Build Coastguard Worker     ThreeChars[3] = 0;
469*3ac0a46fSAndroid Build Coastguard Worker 
470*3ac0a46fSAndroid Build Coastguard Worker     if(ThreeChars[0] == DIR_CHAR)
471*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
472*3ac0a46fSAndroid Build Coastguard Worker 
473*3ac0a46fSAndroid Build Coastguard Worker #ifdef  CMS_IS_WINDOWS_
474*3ac0a46fSAndroid Build Coastguard Worker     if (isalpha((int) ThreeChars[0]) && ThreeChars[1] == ':')
475*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
476*3ac0a46fSAndroid Build Coastguard Worker #endif
477*3ac0a46fSAndroid Build Coastguard Worker     return FALSE;
478*3ac0a46fSAndroid Build Coastguard Worker }
479*3ac0a46fSAndroid Build Coastguard Worker 
480*3ac0a46fSAndroid Build Coastguard Worker 
481*3ac0a46fSAndroid Build Coastguard Worker // Makes a file path based on a given reference path
482*3ac0a46fSAndroid Build Coastguard Worker // NOTE: this function doesn't check if the path exists or even if it's legal
483*3ac0a46fSAndroid Build Coastguard Worker static
BuildAbsolutePath(const char * relPath,const char * basePath,char * buffer,cmsUInt32Number MaxLen)484*3ac0a46fSAndroid Build Coastguard Worker cmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffer, cmsUInt32Number MaxLen)
485*3ac0a46fSAndroid Build Coastguard Worker {
486*3ac0a46fSAndroid Build Coastguard Worker     char *tail;
487*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number len;
488*3ac0a46fSAndroid Build Coastguard Worker 
489*3ac0a46fSAndroid Build Coastguard Worker     // Already absolute?
490*3ac0a46fSAndroid Build Coastguard Worker     if (isabsolutepath(relPath)) {
491*3ac0a46fSAndroid Build Coastguard Worker 
492*3ac0a46fSAndroid Build Coastguard Worker         strncpy(buffer, relPath, MaxLen);
493*3ac0a46fSAndroid Build Coastguard Worker         buffer[MaxLen-1] = 0;
494*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
495*3ac0a46fSAndroid Build Coastguard Worker     }
496*3ac0a46fSAndroid Build Coastguard Worker 
497*3ac0a46fSAndroid Build Coastguard Worker     // No, search for last
498*3ac0a46fSAndroid Build Coastguard Worker     strncpy(buffer, basePath, MaxLen);
499*3ac0a46fSAndroid Build Coastguard Worker     buffer[MaxLen-1] = 0;
500*3ac0a46fSAndroid Build Coastguard Worker 
501*3ac0a46fSAndroid Build Coastguard Worker     tail = strrchr(buffer, DIR_CHAR);
502*3ac0a46fSAndroid Build Coastguard Worker     if (tail == NULL) return FALSE;    // Is not absolute and has no separators??
503*3ac0a46fSAndroid Build Coastguard Worker 
504*3ac0a46fSAndroid Build Coastguard Worker     len = (cmsUInt32Number) (tail - buffer);
505*3ac0a46fSAndroid Build Coastguard Worker     if (len >= MaxLen) return FALSE;
506*3ac0a46fSAndroid Build Coastguard Worker 
507*3ac0a46fSAndroid Build Coastguard Worker     // No need to assure zero terminator over here
508*3ac0a46fSAndroid Build Coastguard Worker     strncpy(tail + 1, relPath, MaxLen - len);
509*3ac0a46fSAndroid Build Coastguard Worker 
510*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
511*3ac0a46fSAndroid Build Coastguard Worker }
512*3ac0a46fSAndroid Build Coastguard Worker 
513*3ac0a46fSAndroid Build Coastguard Worker 
514*3ac0a46fSAndroid Build Coastguard Worker // Make sure no exploit is being even tried
515*3ac0a46fSAndroid Build Coastguard Worker static
NoMeta(const char * str)516*3ac0a46fSAndroid Build Coastguard Worker const char* NoMeta(const char* str)
517*3ac0a46fSAndroid Build Coastguard Worker {
518*3ac0a46fSAndroid Build Coastguard Worker     if (strchr(str, '%') != NULL)
519*3ac0a46fSAndroid Build Coastguard Worker         return "**** CORRUPTED FORMAT STRING ***";
520*3ac0a46fSAndroid Build Coastguard Worker 
521*3ac0a46fSAndroid Build Coastguard Worker     return str;
522*3ac0a46fSAndroid Build Coastguard Worker }
523*3ac0a46fSAndroid Build Coastguard Worker 
524*3ac0a46fSAndroid Build Coastguard Worker // Syntax error
525*3ac0a46fSAndroid Build Coastguard Worker static
SynError(cmsIT8 * it8,const char * Txt,...)526*3ac0a46fSAndroid Build Coastguard Worker cmsBool SynError(cmsIT8* it8, const char *Txt, ...)
527*3ac0a46fSAndroid Build Coastguard Worker {
528*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[256], ErrMsg[1024];
529*3ac0a46fSAndroid Build Coastguard Worker     va_list args;
530*3ac0a46fSAndroid Build Coastguard Worker 
531*3ac0a46fSAndroid Build Coastguard Worker     va_start(args, Txt);
532*3ac0a46fSAndroid Build Coastguard Worker     vsnprintf(Buffer, 255, Txt, args);
533*3ac0a46fSAndroid Build Coastguard Worker     Buffer[255] = 0;
534*3ac0a46fSAndroid Build Coastguard Worker     va_end(args);
535*3ac0a46fSAndroid Build Coastguard Worker 
536*3ac0a46fSAndroid Build Coastguard Worker     snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer);
537*3ac0a46fSAndroid Build Coastguard Worker     ErrMsg[1023] = 0;
538*3ac0a46fSAndroid Build Coastguard Worker     it8->sy = SSYNERROR;
539*3ac0a46fSAndroid Build Coastguard Worker     cmsSignalError(it8 ->ContextID, cmsERROR_CORRUPTION_DETECTED, "%s", ErrMsg);
540*3ac0a46fSAndroid Build Coastguard Worker     return FALSE;
541*3ac0a46fSAndroid Build Coastguard Worker }
542*3ac0a46fSAndroid Build Coastguard Worker 
543*3ac0a46fSAndroid Build Coastguard Worker // Check if current symbol is same as specified. issue an error else.
544*3ac0a46fSAndroid Build Coastguard Worker static
Check(cmsIT8 * it8,SYMBOL sy,const char * Err)545*3ac0a46fSAndroid Build Coastguard Worker cmsBool Check(cmsIT8* it8, SYMBOL sy, const char* Err)
546*3ac0a46fSAndroid Build Coastguard Worker {
547*3ac0a46fSAndroid Build Coastguard Worker         if (it8 -> sy != sy)
548*3ac0a46fSAndroid Build Coastguard Worker                 return SynError(it8, NoMeta(Err));
549*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
550*3ac0a46fSAndroid Build Coastguard Worker }
551*3ac0a46fSAndroid Build Coastguard Worker 
552*3ac0a46fSAndroid Build Coastguard Worker // Read Next character from stream
553*3ac0a46fSAndroid Build Coastguard Worker static
NextCh(cmsIT8 * it8)554*3ac0a46fSAndroid Build Coastguard Worker void NextCh(cmsIT8* it8)
555*3ac0a46fSAndroid Build Coastguard Worker {
556*3ac0a46fSAndroid Build Coastguard Worker     if (it8 -> FileStack[it8 ->IncludeSP]->Stream) {
557*3ac0a46fSAndroid Build Coastguard Worker 
558*3ac0a46fSAndroid Build Coastguard Worker         it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream);
559*3ac0a46fSAndroid Build Coastguard Worker 
560*3ac0a46fSAndroid Build Coastguard Worker         if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream))  {
561*3ac0a46fSAndroid Build Coastguard Worker 
562*3ac0a46fSAndroid Build Coastguard Worker             if (it8 ->IncludeSP > 0) {
563*3ac0a46fSAndroid Build Coastguard Worker 
564*3ac0a46fSAndroid Build Coastguard Worker                 fclose(it8 ->FileStack[it8->IncludeSP--]->Stream);
565*3ac0a46fSAndroid Build Coastguard Worker                 it8 -> ch = ' ';                            // Whitespace to be ignored
566*3ac0a46fSAndroid Build Coastguard Worker 
567*3ac0a46fSAndroid Build Coastguard Worker             } else
568*3ac0a46fSAndroid Build Coastguard Worker                 it8 ->ch = 0;   // EOF
569*3ac0a46fSAndroid Build Coastguard Worker         }
570*3ac0a46fSAndroid Build Coastguard Worker     }
571*3ac0a46fSAndroid Build Coastguard Worker     else {
572*3ac0a46fSAndroid Build Coastguard Worker         it8->ch = *it8->Source;
573*3ac0a46fSAndroid Build Coastguard Worker         if (it8->ch) it8->Source++;
574*3ac0a46fSAndroid Build Coastguard Worker     }
575*3ac0a46fSAndroid Build Coastguard Worker }
576*3ac0a46fSAndroid Build Coastguard Worker 
577*3ac0a46fSAndroid Build Coastguard Worker 
578*3ac0a46fSAndroid Build Coastguard Worker // Try to see if current identifier is a keyword, if so return the referred symbol
579*3ac0a46fSAndroid Build Coastguard Worker static
BinSrchKey(const char * id)580*3ac0a46fSAndroid Build Coastguard Worker SYMBOL BinSrchKey(const char *id)
581*3ac0a46fSAndroid Build Coastguard Worker {
582*3ac0a46fSAndroid Build Coastguard Worker     int l = 1;
583*3ac0a46fSAndroid Build Coastguard Worker     int r = NUMKEYS;
584*3ac0a46fSAndroid Build Coastguard Worker     int x, res;
585*3ac0a46fSAndroid Build Coastguard Worker 
586*3ac0a46fSAndroid Build Coastguard Worker     while (r >= l)
587*3ac0a46fSAndroid Build Coastguard Worker     {
588*3ac0a46fSAndroid Build Coastguard Worker         x = (l+r)/2;
589*3ac0a46fSAndroid Build Coastguard Worker         res = cmsstrcasecmp(id, TabKeys[x-1].id);
590*3ac0a46fSAndroid Build Coastguard Worker         if (res == 0) return TabKeys[x-1].sy;
591*3ac0a46fSAndroid Build Coastguard Worker         if (res < 0) r = x - 1;
592*3ac0a46fSAndroid Build Coastguard Worker         else l = x + 1;
593*3ac0a46fSAndroid Build Coastguard Worker     }
594*3ac0a46fSAndroid Build Coastguard Worker 
595*3ac0a46fSAndroid Build Coastguard Worker     return SUNDEFINED;
596*3ac0a46fSAndroid Build Coastguard Worker }
597*3ac0a46fSAndroid Build Coastguard Worker 
598*3ac0a46fSAndroid Build Coastguard Worker 
599*3ac0a46fSAndroid Build Coastguard Worker // 10 ^n
600*3ac0a46fSAndroid Build Coastguard Worker static
xpow10(int n)601*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number xpow10(int n)
602*3ac0a46fSAndroid Build Coastguard Worker {
603*3ac0a46fSAndroid Build Coastguard Worker     return pow(10, (cmsFloat64Number) n);
604*3ac0a46fSAndroid Build Coastguard Worker }
605*3ac0a46fSAndroid Build Coastguard Worker 
606*3ac0a46fSAndroid Build Coastguard Worker 
607*3ac0a46fSAndroid Build Coastguard Worker //  Reads a Real number, tries to follow from integer number
608*3ac0a46fSAndroid Build Coastguard Worker static
ReadReal(cmsIT8 * it8,cmsInt32Number inum)609*3ac0a46fSAndroid Build Coastguard Worker void ReadReal(cmsIT8* it8, cmsInt32Number inum)
610*3ac0a46fSAndroid Build Coastguard Worker {
611*3ac0a46fSAndroid Build Coastguard Worker     it8->dnum = (cmsFloat64Number)inum;
612*3ac0a46fSAndroid Build Coastguard Worker 
613*3ac0a46fSAndroid Build Coastguard Worker     while (isdigit(it8->ch)) {
614*3ac0a46fSAndroid Build Coastguard Worker 
615*3ac0a46fSAndroid Build Coastguard Worker         it8->dnum = (cmsFloat64Number)it8->dnum * 10.0 + (cmsFloat64Number)(it8->ch - '0');
616*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);
617*3ac0a46fSAndroid Build Coastguard Worker     }
618*3ac0a46fSAndroid Build Coastguard Worker 
619*3ac0a46fSAndroid Build Coastguard Worker     if (it8->ch == '.') {        // Decimal point
620*3ac0a46fSAndroid Build Coastguard Worker 
621*3ac0a46fSAndroid Build Coastguard Worker         cmsFloat64Number frac = 0.0;      // fraction
622*3ac0a46fSAndroid Build Coastguard Worker         int prec = 0;                     // precision
623*3ac0a46fSAndroid Build Coastguard Worker 
624*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);               // Eats dec. point
625*3ac0a46fSAndroid Build Coastguard Worker 
626*3ac0a46fSAndroid Build Coastguard Worker         while (isdigit(it8->ch)) {
627*3ac0a46fSAndroid Build Coastguard Worker 
628*3ac0a46fSAndroid Build Coastguard Worker             frac = frac * 10.0 + (cmsFloat64Number)(it8->ch - '0');
629*3ac0a46fSAndroid Build Coastguard Worker             prec++;
630*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
631*3ac0a46fSAndroid Build Coastguard Worker         }
632*3ac0a46fSAndroid Build Coastguard Worker 
633*3ac0a46fSAndroid Build Coastguard Worker         it8->dnum = it8->dnum + (frac / xpow10(prec));
634*3ac0a46fSAndroid Build Coastguard Worker     }
635*3ac0a46fSAndroid Build Coastguard Worker 
636*3ac0a46fSAndroid Build Coastguard Worker     // Exponent, example 34.00E+20
637*3ac0a46fSAndroid Build Coastguard Worker     if (toupper(it8->ch) == 'E') {
638*3ac0a46fSAndroid Build Coastguard Worker 
639*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number e;
640*3ac0a46fSAndroid Build Coastguard Worker         cmsInt32Number sgn;
641*3ac0a46fSAndroid Build Coastguard Worker 
642*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8); sgn = 1;
643*3ac0a46fSAndroid Build Coastguard Worker 
644*3ac0a46fSAndroid Build Coastguard Worker         if (it8->ch == '-') {
645*3ac0a46fSAndroid Build Coastguard Worker 
646*3ac0a46fSAndroid Build Coastguard Worker             sgn = -1; NextCh(it8);
647*3ac0a46fSAndroid Build Coastguard Worker         }
648*3ac0a46fSAndroid Build Coastguard Worker         else
649*3ac0a46fSAndroid Build Coastguard Worker             if (it8->ch == '+') {
650*3ac0a46fSAndroid Build Coastguard Worker 
651*3ac0a46fSAndroid Build Coastguard Worker                 sgn = +1;
652*3ac0a46fSAndroid Build Coastguard Worker                 NextCh(it8);
653*3ac0a46fSAndroid Build Coastguard Worker             }
654*3ac0a46fSAndroid Build Coastguard Worker 
655*3ac0a46fSAndroid Build Coastguard Worker         e = 0;
656*3ac0a46fSAndroid Build Coastguard Worker         while (isdigit(it8->ch)) {
657*3ac0a46fSAndroid Build Coastguard Worker 
658*3ac0a46fSAndroid Build Coastguard Worker             cmsInt32Number digit = (it8->ch - '0');
659*3ac0a46fSAndroid Build Coastguard Worker 
660*3ac0a46fSAndroid Build Coastguard Worker             if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0)
661*3ac0a46fSAndroid Build Coastguard Worker                 e = e * 10 + digit;
662*3ac0a46fSAndroid Build Coastguard Worker 
663*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
664*3ac0a46fSAndroid Build Coastguard Worker         }
665*3ac0a46fSAndroid Build Coastguard Worker 
666*3ac0a46fSAndroid Build Coastguard Worker         e = sgn*e;
667*3ac0a46fSAndroid Build Coastguard Worker         it8->dnum = it8->dnum * xpow10(e);
668*3ac0a46fSAndroid Build Coastguard Worker     }
669*3ac0a46fSAndroid Build Coastguard Worker }
670*3ac0a46fSAndroid Build Coastguard Worker 
671*3ac0a46fSAndroid Build Coastguard Worker // Parses a float number
672*3ac0a46fSAndroid Build Coastguard Worker // This can not call directly atof because it uses locale dependent
673*3ac0a46fSAndroid Build Coastguard Worker // parsing, while CCMX files always use . as decimal separator
674*3ac0a46fSAndroid Build Coastguard Worker static
ParseFloatNumber(const char * Buffer)675*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number ParseFloatNumber(const char *Buffer)
676*3ac0a46fSAndroid Build Coastguard Worker {
677*3ac0a46fSAndroid Build Coastguard Worker     cmsFloat64Number dnum = 0.0;
678*3ac0a46fSAndroid Build Coastguard Worker     int sign = 1;
679*3ac0a46fSAndroid Build Coastguard Worker 
680*3ac0a46fSAndroid Build Coastguard Worker     // keep safe
681*3ac0a46fSAndroid Build Coastguard Worker     if (Buffer == NULL) return 0.0;
682*3ac0a46fSAndroid Build Coastguard Worker 
683*3ac0a46fSAndroid Build Coastguard Worker     if (*Buffer == '-' || *Buffer == '+') {
684*3ac0a46fSAndroid Build Coastguard Worker 
685*3ac0a46fSAndroid Build Coastguard Worker         sign = (*Buffer == '-') ? -1 : 1;
686*3ac0a46fSAndroid Build Coastguard Worker         Buffer++;
687*3ac0a46fSAndroid Build Coastguard Worker     }
688*3ac0a46fSAndroid Build Coastguard Worker 
689*3ac0a46fSAndroid Build Coastguard Worker 
690*3ac0a46fSAndroid Build Coastguard Worker     while (*Buffer && isdigit((int)*Buffer)) {
691*3ac0a46fSAndroid Build Coastguard Worker 
692*3ac0a46fSAndroid Build Coastguard Worker         dnum = dnum * 10.0 + (*Buffer - '0');
693*3ac0a46fSAndroid Build Coastguard Worker         if (*Buffer) Buffer++;
694*3ac0a46fSAndroid Build Coastguard Worker     }
695*3ac0a46fSAndroid Build Coastguard Worker 
696*3ac0a46fSAndroid Build Coastguard Worker     if (*Buffer == '.') {
697*3ac0a46fSAndroid Build Coastguard Worker 
698*3ac0a46fSAndroid Build Coastguard Worker         cmsFloat64Number frac = 0.0;      // fraction
699*3ac0a46fSAndroid Build Coastguard Worker         int prec = 0;                     // precision
700*3ac0a46fSAndroid Build Coastguard Worker 
701*3ac0a46fSAndroid Build Coastguard Worker         if (*Buffer) Buffer++;
702*3ac0a46fSAndroid Build Coastguard Worker 
703*3ac0a46fSAndroid Build Coastguard Worker         while (*Buffer && isdigit((int)*Buffer)) {
704*3ac0a46fSAndroid Build Coastguard Worker 
705*3ac0a46fSAndroid Build Coastguard Worker             frac = frac * 10.0 + (*Buffer - '0');
706*3ac0a46fSAndroid Build Coastguard Worker             prec++;
707*3ac0a46fSAndroid Build Coastguard Worker             if (*Buffer) Buffer++;
708*3ac0a46fSAndroid Build Coastguard Worker         }
709*3ac0a46fSAndroid Build Coastguard Worker 
710*3ac0a46fSAndroid Build Coastguard Worker         dnum = dnum + (frac / xpow10(prec));
711*3ac0a46fSAndroid Build Coastguard Worker     }
712*3ac0a46fSAndroid Build Coastguard Worker 
713*3ac0a46fSAndroid Build Coastguard Worker     // Exponent, example 34.00E+20
714*3ac0a46fSAndroid Build Coastguard Worker     if (*Buffer && toupper(*Buffer) == 'E') {
715*3ac0a46fSAndroid Build Coastguard Worker 
716*3ac0a46fSAndroid Build Coastguard Worker         int e;
717*3ac0a46fSAndroid Build Coastguard Worker         int sgn;
718*3ac0a46fSAndroid Build Coastguard Worker 
719*3ac0a46fSAndroid Build Coastguard Worker         if (*Buffer) Buffer++;
720*3ac0a46fSAndroid Build Coastguard Worker         sgn = 1;
721*3ac0a46fSAndroid Build Coastguard Worker 
722*3ac0a46fSAndroid Build Coastguard Worker         if (*Buffer == '-') {
723*3ac0a46fSAndroid Build Coastguard Worker 
724*3ac0a46fSAndroid Build Coastguard Worker             sgn = -1;
725*3ac0a46fSAndroid Build Coastguard Worker             if (*Buffer) Buffer++;
726*3ac0a46fSAndroid Build Coastguard Worker         }
727*3ac0a46fSAndroid Build Coastguard Worker         else
728*3ac0a46fSAndroid Build Coastguard Worker             if (*Buffer == '+') {
729*3ac0a46fSAndroid Build Coastguard Worker 
730*3ac0a46fSAndroid Build Coastguard Worker                 sgn = +1;
731*3ac0a46fSAndroid Build Coastguard Worker                 if (*Buffer) Buffer++;
732*3ac0a46fSAndroid Build Coastguard Worker             }
733*3ac0a46fSAndroid Build Coastguard Worker 
734*3ac0a46fSAndroid Build Coastguard Worker         e = 0;
735*3ac0a46fSAndroid Build Coastguard Worker         while (*Buffer && isdigit((int)*Buffer)) {
736*3ac0a46fSAndroid Build Coastguard Worker 
737*3ac0a46fSAndroid Build Coastguard Worker             cmsInt32Number digit = (*Buffer - '0');
738*3ac0a46fSAndroid Build Coastguard Worker 
739*3ac0a46fSAndroid Build Coastguard Worker             if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0)
740*3ac0a46fSAndroid Build Coastguard Worker                 e = e * 10 + digit;
741*3ac0a46fSAndroid Build Coastguard Worker 
742*3ac0a46fSAndroid Build Coastguard Worker             if (*Buffer) Buffer++;
743*3ac0a46fSAndroid Build Coastguard Worker         }
744*3ac0a46fSAndroid Build Coastguard Worker 
745*3ac0a46fSAndroid Build Coastguard Worker         e = sgn*e;
746*3ac0a46fSAndroid Build Coastguard Worker         dnum = dnum * xpow10(e);
747*3ac0a46fSAndroid Build Coastguard Worker     }
748*3ac0a46fSAndroid Build Coastguard Worker 
749*3ac0a46fSAndroid Build Coastguard Worker     return sign * dnum;
750*3ac0a46fSAndroid Build Coastguard Worker }
751*3ac0a46fSAndroid Build Coastguard Worker 
752*3ac0a46fSAndroid Build Coastguard Worker 
753*3ac0a46fSAndroid Build Coastguard Worker // Reads a string, special case to avoid infinite resursion on .include
754*3ac0a46fSAndroid Build Coastguard Worker static
InStringSymbol(cmsIT8 * it8)755*3ac0a46fSAndroid Build Coastguard Worker void InStringSymbol(cmsIT8* it8)
756*3ac0a46fSAndroid Build Coastguard Worker {
757*3ac0a46fSAndroid Build Coastguard Worker     while (isseparator(it8->ch))
758*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);
759*3ac0a46fSAndroid Build Coastguard Worker 
760*3ac0a46fSAndroid Build Coastguard Worker     if (it8->ch == '\'' || it8->ch == '\"')
761*3ac0a46fSAndroid Build Coastguard Worker     {
762*3ac0a46fSAndroid Build Coastguard Worker         int sng;
763*3ac0a46fSAndroid Build Coastguard Worker 
764*3ac0a46fSAndroid Build Coastguard Worker         sng = it8->ch;
765*3ac0a46fSAndroid Build Coastguard Worker         StringClear(it8->str);
766*3ac0a46fSAndroid Build Coastguard Worker 
767*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);
768*3ac0a46fSAndroid Build Coastguard Worker 
769*3ac0a46fSAndroid Build Coastguard Worker         while (it8->ch != sng) {
770*3ac0a46fSAndroid Build Coastguard Worker 
771*3ac0a46fSAndroid Build Coastguard Worker             if (it8->ch == '\n' || it8->ch == '\r' || it8->ch == 0) break;
772*3ac0a46fSAndroid Build Coastguard Worker             else {
773*3ac0a46fSAndroid Build Coastguard Worker                 StringAppend(it8->str, (char)it8->ch);
774*3ac0a46fSAndroid Build Coastguard Worker                 NextCh(it8);
775*3ac0a46fSAndroid Build Coastguard Worker             }
776*3ac0a46fSAndroid Build Coastguard Worker         }
777*3ac0a46fSAndroid Build Coastguard Worker 
778*3ac0a46fSAndroid Build Coastguard Worker         it8->sy = SSTRING;
779*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);
780*3ac0a46fSAndroid Build Coastguard Worker     }
781*3ac0a46fSAndroid Build Coastguard Worker     else
782*3ac0a46fSAndroid Build Coastguard Worker         SynError(it8, "String expected");
783*3ac0a46fSAndroid Build Coastguard Worker 
784*3ac0a46fSAndroid Build Coastguard Worker }
785*3ac0a46fSAndroid Build Coastguard Worker 
786*3ac0a46fSAndroid Build Coastguard Worker // Reads next symbol
787*3ac0a46fSAndroid Build Coastguard Worker static
InSymbol(cmsIT8 * it8)788*3ac0a46fSAndroid Build Coastguard Worker void InSymbol(cmsIT8* it8)
789*3ac0a46fSAndroid Build Coastguard Worker {
790*3ac0a46fSAndroid Build Coastguard Worker     SYMBOL key;
791*3ac0a46fSAndroid Build Coastguard Worker 
792*3ac0a46fSAndroid Build Coastguard Worker     do {
793*3ac0a46fSAndroid Build Coastguard Worker 
794*3ac0a46fSAndroid Build Coastguard Worker         while (isseparator(it8->ch))
795*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
796*3ac0a46fSAndroid Build Coastguard Worker 
797*3ac0a46fSAndroid Build Coastguard Worker         if (isfirstidchar(it8->ch)) {          // Identifier
798*3ac0a46fSAndroid Build Coastguard Worker 
799*3ac0a46fSAndroid Build Coastguard Worker             StringClear(it8->id);
800*3ac0a46fSAndroid Build Coastguard Worker 
801*3ac0a46fSAndroid Build Coastguard Worker             do {
802*3ac0a46fSAndroid Build Coastguard Worker 
803*3ac0a46fSAndroid Build Coastguard Worker                 StringAppend(it8->id, (char) it8->ch);
804*3ac0a46fSAndroid Build Coastguard Worker 
805*3ac0a46fSAndroid Build Coastguard Worker                 NextCh(it8);
806*3ac0a46fSAndroid Build Coastguard Worker 
807*3ac0a46fSAndroid Build Coastguard Worker             } while (isidchar(it8->ch));
808*3ac0a46fSAndroid Build Coastguard Worker 
809*3ac0a46fSAndroid Build Coastguard Worker 
810*3ac0a46fSAndroid Build Coastguard Worker             key = BinSrchKey(StringPtr(it8->id));
811*3ac0a46fSAndroid Build Coastguard Worker             if (key == SUNDEFINED) it8->sy = SIDENT;
812*3ac0a46fSAndroid Build Coastguard Worker             else it8->sy = key;
813*3ac0a46fSAndroid Build Coastguard Worker 
814*3ac0a46fSAndroid Build Coastguard Worker         }
815*3ac0a46fSAndroid Build Coastguard Worker         else                         // Is a number?
816*3ac0a46fSAndroid Build Coastguard Worker             if (isdigit(it8->ch) || it8->ch == '.' || it8->ch == '-' || it8->ch == '+')
817*3ac0a46fSAndroid Build Coastguard Worker             {
818*3ac0a46fSAndroid Build Coastguard Worker                 int sign = 1;
819*3ac0a46fSAndroid Build Coastguard Worker 
820*3ac0a46fSAndroid Build Coastguard Worker                 if (it8->ch == '-') {
821*3ac0a46fSAndroid Build Coastguard Worker                     sign = -1;
822*3ac0a46fSAndroid Build Coastguard Worker                     NextCh(it8);
823*3ac0a46fSAndroid Build Coastguard Worker                 }
824*3ac0a46fSAndroid Build Coastguard Worker 
825*3ac0a46fSAndroid Build Coastguard Worker                 it8->inum = 0;
826*3ac0a46fSAndroid Build Coastguard Worker                 it8->sy   = SINUM;
827*3ac0a46fSAndroid Build Coastguard Worker 
828*3ac0a46fSAndroid Build Coastguard Worker                 if (it8->ch == '0') {          // 0xnnnn (Hexa) or 0bnnnn (Binary)
829*3ac0a46fSAndroid Build Coastguard Worker 
830*3ac0a46fSAndroid Build Coastguard Worker                     NextCh(it8);
831*3ac0a46fSAndroid Build Coastguard Worker                     if (toupper(it8->ch) == 'X') {
832*3ac0a46fSAndroid Build Coastguard Worker 
833*3ac0a46fSAndroid Build Coastguard Worker                         int j;
834*3ac0a46fSAndroid Build Coastguard Worker 
835*3ac0a46fSAndroid Build Coastguard Worker                         NextCh(it8);
836*3ac0a46fSAndroid Build Coastguard Worker                         while (isxdigit(it8->ch))
837*3ac0a46fSAndroid Build Coastguard Worker                         {
838*3ac0a46fSAndroid Build Coastguard Worker                             it8->ch = toupper(it8->ch);
839*3ac0a46fSAndroid Build Coastguard Worker                             if (it8->ch >= 'A' && it8->ch <= 'F')  j = it8->ch -'A'+10;
840*3ac0a46fSAndroid Build Coastguard Worker                             else j = it8->ch - '0';
841*3ac0a46fSAndroid Build Coastguard Worker 
842*3ac0a46fSAndroid Build Coastguard Worker                             if ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0)
843*3ac0a46fSAndroid Build Coastguard Worker                             {
844*3ac0a46fSAndroid Build Coastguard Worker                                 SynError(it8, "Invalid hexadecimal number");
845*3ac0a46fSAndroid Build Coastguard Worker                                 it8->sy = SEOF;
846*3ac0a46fSAndroid Build Coastguard Worker                                 return;
847*3ac0a46fSAndroid Build Coastguard Worker                             }
848*3ac0a46fSAndroid Build Coastguard Worker 
849*3ac0a46fSAndroid Build Coastguard Worker                             it8->inum = it8->inum * 16 + j;
850*3ac0a46fSAndroid Build Coastguard Worker                             NextCh(it8);
851*3ac0a46fSAndroid Build Coastguard Worker                         }
852*3ac0a46fSAndroid Build Coastguard Worker                         return;
853*3ac0a46fSAndroid Build Coastguard Worker                     }
854*3ac0a46fSAndroid Build Coastguard Worker 
855*3ac0a46fSAndroid Build Coastguard Worker                     if (toupper(it8->ch) == 'B') {  // Binary
856*3ac0a46fSAndroid Build Coastguard Worker 
857*3ac0a46fSAndroid Build Coastguard Worker                         int j;
858*3ac0a46fSAndroid Build Coastguard Worker 
859*3ac0a46fSAndroid Build Coastguard Worker                         NextCh(it8);
860*3ac0a46fSAndroid Build Coastguard Worker                         while (it8->ch == '0' || it8->ch == '1')
861*3ac0a46fSAndroid Build Coastguard Worker                         {
862*3ac0a46fSAndroid Build Coastguard Worker                             j = it8->ch - '0';
863*3ac0a46fSAndroid Build Coastguard Worker 
864*3ac0a46fSAndroid Build Coastguard Worker                             if ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0)
865*3ac0a46fSAndroid Build Coastguard Worker                             {
866*3ac0a46fSAndroid Build Coastguard Worker                                 SynError(it8, "Invalid binary number");
867*3ac0a46fSAndroid Build Coastguard Worker                                 it8->sy = SEOF;
868*3ac0a46fSAndroid Build Coastguard Worker                                 return;
869*3ac0a46fSAndroid Build Coastguard Worker                             }
870*3ac0a46fSAndroid Build Coastguard Worker 
871*3ac0a46fSAndroid Build Coastguard Worker                             it8->inum = it8->inum * 2 + j;
872*3ac0a46fSAndroid Build Coastguard Worker                             NextCh(it8);
873*3ac0a46fSAndroid Build Coastguard Worker                         }
874*3ac0a46fSAndroid Build Coastguard Worker                         return;
875*3ac0a46fSAndroid Build Coastguard Worker                     }
876*3ac0a46fSAndroid Build Coastguard Worker                 }
877*3ac0a46fSAndroid Build Coastguard Worker 
878*3ac0a46fSAndroid Build Coastguard Worker 
879*3ac0a46fSAndroid Build Coastguard Worker                 while (isdigit(it8->ch)) {
880*3ac0a46fSAndroid Build Coastguard Worker 
881*3ac0a46fSAndroid Build Coastguard Worker                     cmsInt32Number digit = (it8->ch - '0');
882*3ac0a46fSAndroid Build Coastguard Worker 
883*3ac0a46fSAndroid Build Coastguard Worker                     if ((cmsFloat64Number) it8->inum * 10.0 + (cmsFloat64Number) digit > (cmsFloat64Number) +2147483647.0) {
884*3ac0a46fSAndroid Build Coastguard Worker                         ReadReal(it8, it8->inum);
885*3ac0a46fSAndroid Build Coastguard Worker                         it8->sy = SDNUM;
886*3ac0a46fSAndroid Build Coastguard Worker                         it8->dnum *= sign;
887*3ac0a46fSAndroid Build Coastguard Worker                         return;
888*3ac0a46fSAndroid Build Coastguard Worker                     }
889*3ac0a46fSAndroid Build Coastguard Worker 
890*3ac0a46fSAndroid Build Coastguard Worker                     it8->inum = it8->inum * 10 + digit;
891*3ac0a46fSAndroid Build Coastguard Worker                     NextCh(it8);
892*3ac0a46fSAndroid Build Coastguard Worker                 }
893*3ac0a46fSAndroid Build Coastguard Worker 
894*3ac0a46fSAndroid Build Coastguard Worker                 if (it8->ch == '.') {
895*3ac0a46fSAndroid Build Coastguard Worker 
896*3ac0a46fSAndroid Build Coastguard Worker                     ReadReal(it8, it8->inum);
897*3ac0a46fSAndroid Build Coastguard Worker                     it8->sy = SDNUM;
898*3ac0a46fSAndroid Build Coastguard Worker                     it8->dnum *= sign;
899*3ac0a46fSAndroid Build Coastguard Worker                     return;
900*3ac0a46fSAndroid Build Coastguard Worker                 }
901*3ac0a46fSAndroid Build Coastguard Worker 
902*3ac0a46fSAndroid Build Coastguard Worker                 it8 -> inum *= sign;
903*3ac0a46fSAndroid Build Coastguard Worker 
904*3ac0a46fSAndroid Build Coastguard Worker                 // Special case. Numbers followed by letters are taken as identifiers
905*3ac0a46fSAndroid Build Coastguard Worker 
906*3ac0a46fSAndroid Build Coastguard Worker                 if (isidchar(it8 ->ch)) {
907*3ac0a46fSAndroid Build Coastguard Worker 
908*3ac0a46fSAndroid Build Coastguard Worker                     char buffer[127];
909*3ac0a46fSAndroid Build Coastguard Worker 
910*3ac0a46fSAndroid Build Coastguard Worker                     if (it8 ->sy == SINUM) {
911*3ac0a46fSAndroid Build Coastguard Worker 
912*3ac0a46fSAndroid Build Coastguard Worker                         snprintf(buffer, sizeof(buffer), "%d", it8->inum);
913*3ac0a46fSAndroid Build Coastguard Worker                     }
914*3ac0a46fSAndroid Build Coastguard Worker                     else {
915*3ac0a46fSAndroid Build Coastguard Worker 
916*3ac0a46fSAndroid Build Coastguard Worker                         snprintf(buffer, sizeof(buffer), it8 ->DoubleFormatter, it8->dnum);
917*3ac0a46fSAndroid Build Coastguard Worker                     }
918*3ac0a46fSAndroid Build Coastguard Worker 
919*3ac0a46fSAndroid Build Coastguard Worker                     StringCat(it8->id, buffer);
920*3ac0a46fSAndroid Build Coastguard Worker 
921*3ac0a46fSAndroid Build Coastguard Worker                     do {
922*3ac0a46fSAndroid Build Coastguard Worker 
923*3ac0a46fSAndroid Build Coastguard Worker                         StringAppend(it8->id, (char) it8->ch);
924*3ac0a46fSAndroid Build Coastguard Worker 
925*3ac0a46fSAndroid Build Coastguard Worker                         NextCh(it8);
926*3ac0a46fSAndroid Build Coastguard Worker 
927*3ac0a46fSAndroid Build Coastguard Worker                     } while (isidchar(it8->ch));
928*3ac0a46fSAndroid Build Coastguard Worker 
929*3ac0a46fSAndroid Build Coastguard Worker                     it8->sy = SIDENT;
930*3ac0a46fSAndroid Build Coastguard Worker                 }
931*3ac0a46fSAndroid Build Coastguard Worker                 return;
932*3ac0a46fSAndroid Build Coastguard Worker 
933*3ac0a46fSAndroid Build Coastguard Worker             }
934*3ac0a46fSAndroid Build Coastguard Worker             else
935*3ac0a46fSAndroid Build Coastguard Worker                 switch ((int) it8->ch) {
936*3ac0a46fSAndroid Build Coastguard Worker 
937*3ac0a46fSAndroid Build Coastguard Worker         // Eof stream markers
938*3ac0a46fSAndroid Build Coastguard Worker         case '\x1a':
939*3ac0a46fSAndroid Build Coastguard Worker         case 0:
940*3ac0a46fSAndroid Build Coastguard Worker         case -1:
941*3ac0a46fSAndroid Build Coastguard Worker             it8->sy = SEOF;
942*3ac0a46fSAndroid Build Coastguard Worker             break;
943*3ac0a46fSAndroid Build Coastguard Worker 
944*3ac0a46fSAndroid Build Coastguard Worker 
945*3ac0a46fSAndroid Build Coastguard Worker         // Next line
946*3ac0a46fSAndroid Build Coastguard Worker         case '\r':
947*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
948*3ac0a46fSAndroid Build Coastguard Worker             if (it8 ->ch == '\n')
949*3ac0a46fSAndroid Build Coastguard Worker                 NextCh(it8);
950*3ac0a46fSAndroid Build Coastguard Worker             it8->sy = SEOLN;
951*3ac0a46fSAndroid Build Coastguard Worker             it8->lineno++;
952*3ac0a46fSAndroid Build Coastguard Worker             break;
953*3ac0a46fSAndroid Build Coastguard Worker 
954*3ac0a46fSAndroid Build Coastguard Worker         case '\n':
955*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
956*3ac0a46fSAndroid Build Coastguard Worker             it8->sy = SEOLN;
957*3ac0a46fSAndroid Build Coastguard Worker             it8->lineno++;
958*3ac0a46fSAndroid Build Coastguard Worker             break;
959*3ac0a46fSAndroid Build Coastguard Worker 
960*3ac0a46fSAndroid Build Coastguard Worker         // Comment
961*3ac0a46fSAndroid Build Coastguard Worker         case '#':
962*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
963*3ac0a46fSAndroid Build Coastguard Worker             while (it8->ch && it8->ch != '\n' && it8->ch != '\r')
964*3ac0a46fSAndroid Build Coastguard Worker                 NextCh(it8);
965*3ac0a46fSAndroid Build Coastguard Worker 
966*3ac0a46fSAndroid Build Coastguard Worker             it8->sy = SCOMMENT;
967*3ac0a46fSAndroid Build Coastguard Worker             break;
968*3ac0a46fSAndroid Build Coastguard Worker 
969*3ac0a46fSAndroid Build Coastguard Worker         // String.
970*3ac0a46fSAndroid Build Coastguard Worker         case '\'':
971*3ac0a46fSAndroid Build Coastguard Worker         case '\"':
972*3ac0a46fSAndroid Build Coastguard Worker             InStringSymbol(it8);
973*3ac0a46fSAndroid Build Coastguard Worker             break;
974*3ac0a46fSAndroid Build Coastguard Worker 
975*3ac0a46fSAndroid Build Coastguard Worker 
976*3ac0a46fSAndroid Build Coastguard Worker         default:
977*3ac0a46fSAndroid Build Coastguard Worker             SynError(it8, "Unrecognized character: 0x%x", it8 ->ch);
978*3ac0a46fSAndroid Build Coastguard Worker             it8->sy = SEOF;
979*3ac0a46fSAndroid Build Coastguard Worker             return;
980*3ac0a46fSAndroid Build Coastguard Worker             }
981*3ac0a46fSAndroid Build Coastguard Worker 
982*3ac0a46fSAndroid Build Coastguard Worker     } while (it8->sy == SCOMMENT);
983*3ac0a46fSAndroid Build Coastguard Worker 
984*3ac0a46fSAndroid Build Coastguard Worker     // Handle the include special token
985*3ac0a46fSAndroid Build Coastguard Worker 
986*3ac0a46fSAndroid Build Coastguard Worker     if (it8 -> sy == SINCLUDE) {
987*3ac0a46fSAndroid Build Coastguard Worker 
988*3ac0a46fSAndroid Build Coastguard Worker                 FILECTX* FileNest;
989*3ac0a46fSAndroid Build Coastguard Worker 
990*3ac0a46fSAndroid Build Coastguard Worker                 if(it8 -> IncludeSP >= (MAXINCLUDE-1)) {
991*3ac0a46fSAndroid Build Coastguard Worker 
992*3ac0a46fSAndroid Build Coastguard Worker                     SynError(it8, "Too many recursion levels");
993*3ac0a46fSAndroid Build Coastguard Worker                     it8->sy = SEOF;
994*3ac0a46fSAndroid Build Coastguard Worker                     return;
995*3ac0a46fSAndroid Build Coastguard Worker                 }
996*3ac0a46fSAndroid Build Coastguard Worker 
997*3ac0a46fSAndroid Build Coastguard Worker                 InStringSymbol(it8);
998*3ac0a46fSAndroid Build Coastguard Worker                 if (!Check(it8, SSTRING, "Filename expected"))
999*3ac0a46fSAndroid Build Coastguard Worker                 {
1000*3ac0a46fSAndroid Build Coastguard Worker                     it8->sy = SEOF;
1001*3ac0a46fSAndroid Build Coastguard Worker                     return;
1002*3ac0a46fSAndroid Build Coastguard Worker                 }
1003*3ac0a46fSAndroid Build Coastguard Worker 
1004*3ac0a46fSAndroid Build Coastguard Worker                 FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
1005*3ac0a46fSAndroid Build Coastguard Worker                 if(FileNest == NULL) {
1006*3ac0a46fSAndroid Build Coastguard Worker 
1007*3ac0a46fSAndroid Build Coastguard Worker                     FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
1008*3ac0a46fSAndroid Build Coastguard Worker                     if (FileNest == NULL) {
1009*3ac0a46fSAndroid Build Coastguard Worker                         SynError(it8, "Out of memory");
1010*3ac0a46fSAndroid Build Coastguard Worker                         it8->sy = SEOF;
1011*3ac0a46fSAndroid Build Coastguard Worker                         return;
1012*3ac0a46fSAndroid Build Coastguard Worker                     }
1013*3ac0a46fSAndroid Build Coastguard Worker                 }
1014*3ac0a46fSAndroid Build Coastguard Worker 
1015*3ac0a46fSAndroid Build Coastguard Worker                 if (BuildAbsolutePath(StringPtr(it8->str),
1016*3ac0a46fSAndroid Build Coastguard Worker                                       it8->FileStack[it8->IncludeSP]->FileName,
1017*3ac0a46fSAndroid Build Coastguard Worker                                       FileNest->FileName, cmsMAX_PATH-1) == FALSE) {
1018*3ac0a46fSAndroid Build Coastguard Worker                     SynError(it8, "File path too long");
1019*3ac0a46fSAndroid Build Coastguard Worker                     it8->sy = SEOF;
1020*3ac0a46fSAndroid Build Coastguard Worker                     return;
1021*3ac0a46fSAndroid Build Coastguard Worker                 }
1022*3ac0a46fSAndroid Build Coastguard Worker 
1023*3ac0a46fSAndroid Build Coastguard Worker                 FileNest->Stream = fopen(FileNest->FileName, "rt");
1024*3ac0a46fSAndroid Build Coastguard Worker                 if (FileNest->Stream == NULL) {
1025*3ac0a46fSAndroid Build Coastguard Worker 
1026*3ac0a46fSAndroid Build Coastguard Worker                         SynError(it8, "File %s not found", FileNest->FileName);
1027*3ac0a46fSAndroid Build Coastguard Worker                         it8->sy = SEOF;
1028*3ac0a46fSAndroid Build Coastguard Worker                         return;
1029*3ac0a46fSAndroid Build Coastguard Worker                 }
1030*3ac0a46fSAndroid Build Coastguard Worker                 it8->IncludeSP++;
1031*3ac0a46fSAndroid Build Coastguard Worker 
1032*3ac0a46fSAndroid Build Coastguard Worker                 it8 ->ch = ' ';
1033*3ac0a46fSAndroid Build Coastguard Worker                 InSymbol(it8);
1034*3ac0a46fSAndroid Build Coastguard Worker     }
1035*3ac0a46fSAndroid Build Coastguard Worker 
1036*3ac0a46fSAndroid Build Coastguard Worker }
1037*3ac0a46fSAndroid Build Coastguard Worker 
1038*3ac0a46fSAndroid Build Coastguard Worker // Checks end of line separator
1039*3ac0a46fSAndroid Build Coastguard Worker static
CheckEOLN(cmsIT8 * it8)1040*3ac0a46fSAndroid Build Coastguard Worker cmsBool CheckEOLN(cmsIT8* it8)
1041*3ac0a46fSAndroid Build Coastguard Worker {
1042*3ac0a46fSAndroid Build Coastguard Worker         if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
1043*3ac0a46fSAndroid Build Coastguard Worker         while (it8 -> sy == SEOLN)
1044*3ac0a46fSAndroid Build Coastguard Worker                         InSymbol(it8);
1045*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
1046*3ac0a46fSAndroid Build Coastguard Worker 
1047*3ac0a46fSAndroid Build Coastguard Worker }
1048*3ac0a46fSAndroid Build Coastguard Worker 
1049*3ac0a46fSAndroid Build Coastguard Worker // Skip a symbol
1050*3ac0a46fSAndroid Build Coastguard Worker 
1051*3ac0a46fSAndroid Build Coastguard Worker static
Skip(cmsIT8 * it8,SYMBOL sy)1052*3ac0a46fSAndroid Build Coastguard Worker void Skip(cmsIT8* it8, SYMBOL sy)
1053*3ac0a46fSAndroid Build Coastguard Worker {
1054*3ac0a46fSAndroid Build Coastguard Worker         if (it8->sy == sy && it8->sy != SEOF)
1055*3ac0a46fSAndroid Build Coastguard Worker                         InSymbol(it8);
1056*3ac0a46fSAndroid Build Coastguard Worker }
1057*3ac0a46fSAndroid Build Coastguard Worker 
1058*3ac0a46fSAndroid Build Coastguard Worker 
1059*3ac0a46fSAndroid Build Coastguard Worker // Skip multiple EOLN
1060*3ac0a46fSAndroid Build Coastguard Worker static
SkipEOLN(cmsIT8 * it8)1061*3ac0a46fSAndroid Build Coastguard Worker void SkipEOLN(cmsIT8* it8)
1062*3ac0a46fSAndroid Build Coastguard Worker {
1063*3ac0a46fSAndroid Build Coastguard Worker     while (it8->sy == SEOLN) {
1064*3ac0a46fSAndroid Build Coastguard Worker              InSymbol(it8);
1065*3ac0a46fSAndroid Build Coastguard Worker     }
1066*3ac0a46fSAndroid Build Coastguard Worker }
1067*3ac0a46fSAndroid Build Coastguard Worker 
1068*3ac0a46fSAndroid Build Coastguard Worker 
1069*3ac0a46fSAndroid Build Coastguard Worker // Returns a string holding current value
1070*3ac0a46fSAndroid Build Coastguard Worker static
GetVal(cmsIT8 * it8,char * Buffer,cmsUInt32Number max,const char * ErrorTitle)1071*3ac0a46fSAndroid Build Coastguard Worker cmsBool GetVal(cmsIT8* it8, char* Buffer, cmsUInt32Number max, const char* ErrorTitle)
1072*3ac0a46fSAndroid Build Coastguard Worker {
1073*3ac0a46fSAndroid Build Coastguard Worker     switch (it8->sy) {
1074*3ac0a46fSAndroid Build Coastguard Worker 
1075*3ac0a46fSAndroid Build Coastguard Worker     case SEOLN:   // Empty value
1076*3ac0a46fSAndroid Build Coastguard Worker                   Buffer[0]=0;
1077*3ac0a46fSAndroid Build Coastguard Worker                   break;
1078*3ac0a46fSAndroid Build Coastguard Worker     case SIDENT:  strncpy(Buffer, StringPtr(it8->id), max);
1079*3ac0a46fSAndroid Build Coastguard Worker                   Buffer[max-1]=0;
1080*3ac0a46fSAndroid Build Coastguard Worker                   break;
1081*3ac0a46fSAndroid Build Coastguard Worker     case SINUM:   snprintf(Buffer, max, "%d", it8 -> inum); break;
1082*3ac0a46fSAndroid Build Coastguard Worker     case SDNUM:   snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break;
1083*3ac0a46fSAndroid Build Coastguard Worker     case SSTRING: strncpy(Buffer, StringPtr(it8->str), max);
1084*3ac0a46fSAndroid Build Coastguard Worker                   Buffer[max-1] = 0;
1085*3ac0a46fSAndroid Build Coastguard Worker                   break;
1086*3ac0a46fSAndroid Build Coastguard Worker 
1087*3ac0a46fSAndroid Build Coastguard Worker 
1088*3ac0a46fSAndroid Build Coastguard Worker     default:
1089*3ac0a46fSAndroid Build Coastguard Worker          return SynError(it8, "%s", ErrorTitle);
1090*3ac0a46fSAndroid Build Coastguard Worker     }
1091*3ac0a46fSAndroid Build Coastguard Worker 
1092*3ac0a46fSAndroid Build Coastguard Worker     Buffer[max] = 0;
1093*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1094*3ac0a46fSAndroid Build Coastguard Worker }
1095*3ac0a46fSAndroid Build Coastguard Worker 
1096*3ac0a46fSAndroid Build Coastguard Worker // ---------------------------------------------------------- Table
1097*3ac0a46fSAndroid Build Coastguard Worker 
1098*3ac0a46fSAndroid Build Coastguard Worker static
GetTable(cmsIT8 * it8)1099*3ac0a46fSAndroid Build Coastguard Worker TABLE* GetTable(cmsIT8* it8)
1100*3ac0a46fSAndroid Build Coastguard Worker {
1101*3ac0a46fSAndroid Build Coastguard Worker    if ((it8 -> nTable >= it8 ->TablesCount)) {
1102*3ac0a46fSAndroid Build Coastguard Worker 
1103*3ac0a46fSAndroid Build Coastguard Worker            SynError(it8, "Table %d out of sequence", it8 -> nTable);
1104*3ac0a46fSAndroid Build Coastguard Worker            return it8 -> Tab;
1105*3ac0a46fSAndroid Build Coastguard Worker    }
1106*3ac0a46fSAndroid Build Coastguard Worker 
1107*3ac0a46fSAndroid Build Coastguard Worker    return it8 ->Tab + it8 ->nTable;
1108*3ac0a46fSAndroid Build Coastguard Worker }
1109*3ac0a46fSAndroid Build Coastguard Worker 
1110*3ac0a46fSAndroid Build Coastguard Worker // ---------------------------------------------------------- Memory management
1111*3ac0a46fSAndroid Build Coastguard Worker 
1112*3ac0a46fSAndroid Build Coastguard Worker 
1113*3ac0a46fSAndroid Build Coastguard Worker // Frees an allocator and owned memory
cmsIT8Free(cmsHANDLE hIT8)1114*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsIT8Free(cmsHANDLE hIT8)
1115*3ac0a46fSAndroid Build Coastguard Worker {
1116*3ac0a46fSAndroid Build Coastguard Worker    cmsIT8* it8 = (cmsIT8*) hIT8;
1117*3ac0a46fSAndroid Build Coastguard Worker 
1118*3ac0a46fSAndroid Build Coastguard Worker     if (it8 == NULL)
1119*3ac0a46fSAndroid Build Coastguard Worker         return;
1120*3ac0a46fSAndroid Build Coastguard Worker 
1121*3ac0a46fSAndroid Build Coastguard Worker     if (it8->MemorySink) {
1122*3ac0a46fSAndroid Build Coastguard Worker 
1123*3ac0a46fSAndroid Build Coastguard Worker         OWNEDMEM* p;
1124*3ac0a46fSAndroid Build Coastguard Worker         OWNEDMEM* n;
1125*3ac0a46fSAndroid Build Coastguard Worker 
1126*3ac0a46fSAndroid Build Coastguard Worker         for (p = it8->MemorySink; p != NULL; p = n) {
1127*3ac0a46fSAndroid Build Coastguard Worker 
1128*3ac0a46fSAndroid Build Coastguard Worker             n = p->Next;
1129*3ac0a46fSAndroid Build Coastguard Worker             if (p->Ptr) _cmsFree(it8 ->ContextID, p->Ptr);
1130*3ac0a46fSAndroid Build Coastguard Worker             _cmsFree(it8 ->ContextID, p);
1131*3ac0a46fSAndroid Build Coastguard Worker         }
1132*3ac0a46fSAndroid Build Coastguard Worker     }
1133*3ac0a46fSAndroid Build Coastguard Worker 
1134*3ac0a46fSAndroid Build Coastguard Worker     if (it8->MemoryBlock)
1135*3ac0a46fSAndroid Build Coastguard Worker         _cmsFree(it8 ->ContextID, it8->MemoryBlock);
1136*3ac0a46fSAndroid Build Coastguard Worker 
1137*3ac0a46fSAndroid Build Coastguard Worker     _cmsFree(it8 ->ContextID, it8);
1138*3ac0a46fSAndroid Build Coastguard Worker }
1139*3ac0a46fSAndroid Build Coastguard Worker 
1140*3ac0a46fSAndroid Build Coastguard Worker 
1141*3ac0a46fSAndroid Build Coastguard Worker // Allocates a chunk of data, keep linked list
1142*3ac0a46fSAndroid Build Coastguard Worker static
AllocBigBlock(cmsIT8 * it8,cmsUInt32Number size)1143*3ac0a46fSAndroid Build Coastguard Worker void* AllocBigBlock(cmsIT8* it8, cmsUInt32Number size)
1144*3ac0a46fSAndroid Build Coastguard Worker {
1145*3ac0a46fSAndroid Build Coastguard Worker     OWNEDMEM* ptr1;
1146*3ac0a46fSAndroid Build Coastguard Worker     void* ptr = _cmsMallocZero(it8->ContextID, size);
1147*3ac0a46fSAndroid Build Coastguard Worker 
1148*3ac0a46fSAndroid Build Coastguard Worker     if (ptr != NULL) {
1149*3ac0a46fSAndroid Build Coastguard Worker 
1150*3ac0a46fSAndroid Build Coastguard Worker         ptr1 = (OWNEDMEM*) _cmsMallocZero(it8 ->ContextID, sizeof(OWNEDMEM));
1151*3ac0a46fSAndroid Build Coastguard Worker 
1152*3ac0a46fSAndroid Build Coastguard Worker         if (ptr1 == NULL) {
1153*3ac0a46fSAndroid Build Coastguard Worker 
1154*3ac0a46fSAndroid Build Coastguard Worker             _cmsFree(it8 ->ContextID, ptr);
1155*3ac0a46fSAndroid Build Coastguard Worker             return NULL;
1156*3ac0a46fSAndroid Build Coastguard Worker         }
1157*3ac0a46fSAndroid Build Coastguard Worker 
1158*3ac0a46fSAndroid Build Coastguard Worker         ptr1-> Ptr        = ptr;
1159*3ac0a46fSAndroid Build Coastguard Worker         ptr1-> Next       = it8 -> MemorySink;
1160*3ac0a46fSAndroid Build Coastguard Worker         it8 -> MemorySink = ptr1;
1161*3ac0a46fSAndroid Build Coastguard Worker     }
1162*3ac0a46fSAndroid Build Coastguard Worker 
1163*3ac0a46fSAndroid Build Coastguard Worker     return ptr;
1164*3ac0a46fSAndroid Build Coastguard Worker }
1165*3ac0a46fSAndroid Build Coastguard Worker 
1166*3ac0a46fSAndroid Build Coastguard Worker 
1167*3ac0a46fSAndroid Build Coastguard Worker // Suballocator.
1168*3ac0a46fSAndroid Build Coastguard Worker static
AllocChunk(cmsIT8 * it8,cmsUInt32Number size)1169*3ac0a46fSAndroid Build Coastguard Worker void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
1170*3ac0a46fSAndroid Build Coastguard Worker {
1171*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number Free = it8 ->Allocator.BlockSize - it8 ->Allocator.Used;
1172*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt8Number* ptr;
1173*3ac0a46fSAndroid Build Coastguard Worker 
1174*3ac0a46fSAndroid Build Coastguard Worker     size = _cmsALIGNMEM(size);
1175*3ac0a46fSAndroid Build Coastguard Worker 
1176*3ac0a46fSAndroid Build Coastguard Worker     if (size > Free) {
1177*3ac0a46fSAndroid Build Coastguard Worker 
1178*3ac0a46fSAndroid Build Coastguard Worker         if (it8 -> Allocator.BlockSize == 0)
1179*3ac0a46fSAndroid Build Coastguard Worker 
1180*3ac0a46fSAndroid Build Coastguard Worker                 it8 -> Allocator.BlockSize = 20*1024;
1181*3ac0a46fSAndroid Build Coastguard Worker         else
1182*3ac0a46fSAndroid Build Coastguard Worker                 it8 ->Allocator.BlockSize *= 2;
1183*3ac0a46fSAndroid Build Coastguard Worker 
1184*3ac0a46fSAndroid Build Coastguard Worker         if (it8 ->Allocator.BlockSize < size)
1185*3ac0a46fSAndroid Build Coastguard Worker                 it8 ->Allocator.BlockSize = size;
1186*3ac0a46fSAndroid Build Coastguard Worker 
1187*3ac0a46fSAndroid Build Coastguard Worker         it8 ->Allocator.Used = 0;
1188*3ac0a46fSAndroid Build Coastguard Worker         it8 ->Allocator.Block = (cmsUInt8Number*) AllocBigBlock(it8, it8 ->Allocator.BlockSize);
1189*3ac0a46fSAndroid Build Coastguard Worker     }
1190*3ac0a46fSAndroid Build Coastguard Worker 
1191*3ac0a46fSAndroid Build Coastguard Worker     if (it8->Allocator.Block == NULL)
1192*3ac0a46fSAndroid Build Coastguard Worker         return NULL;
1193*3ac0a46fSAndroid Build Coastguard Worker 
1194*3ac0a46fSAndroid Build Coastguard Worker     ptr = it8 ->Allocator.Block + it8 ->Allocator.Used;
1195*3ac0a46fSAndroid Build Coastguard Worker     it8 ->Allocator.Used += size;
1196*3ac0a46fSAndroid Build Coastguard Worker 
1197*3ac0a46fSAndroid Build Coastguard Worker     return (void*) ptr;
1198*3ac0a46fSAndroid Build Coastguard Worker 
1199*3ac0a46fSAndroid Build Coastguard Worker }
1200*3ac0a46fSAndroid Build Coastguard Worker 
1201*3ac0a46fSAndroid Build Coastguard Worker 
1202*3ac0a46fSAndroid Build Coastguard Worker // Allocates a string
1203*3ac0a46fSAndroid Build Coastguard Worker static
AllocString(cmsIT8 * it8,const char * str)1204*3ac0a46fSAndroid Build Coastguard Worker char *AllocString(cmsIT8* it8, const char* str)
1205*3ac0a46fSAndroid Build Coastguard Worker {
1206*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number Size = (cmsUInt32Number) strlen(str)+1;
1207*3ac0a46fSAndroid Build Coastguard Worker     char *ptr;
1208*3ac0a46fSAndroid Build Coastguard Worker 
1209*3ac0a46fSAndroid Build Coastguard Worker 
1210*3ac0a46fSAndroid Build Coastguard Worker     ptr = (char *) AllocChunk(it8, Size);
1211*3ac0a46fSAndroid Build Coastguard Worker     if (ptr) memcpy(ptr, str, Size-1);
1212*3ac0a46fSAndroid Build Coastguard Worker 
1213*3ac0a46fSAndroid Build Coastguard Worker     return ptr;
1214*3ac0a46fSAndroid Build Coastguard Worker }
1215*3ac0a46fSAndroid Build Coastguard Worker 
1216*3ac0a46fSAndroid Build Coastguard Worker // Searches through linked list
1217*3ac0a46fSAndroid Build Coastguard Worker 
1218*3ac0a46fSAndroid Build Coastguard Worker static
IsAvailableOnList(KEYVALUE * p,const char * Key,const char * Subkey,KEYVALUE ** LastPtr)1219*3ac0a46fSAndroid Build Coastguard Worker cmsBool IsAvailableOnList(KEYVALUE* p, const char* Key, const char* Subkey, KEYVALUE** LastPtr)
1220*3ac0a46fSAndroid Build Coastguard Worker {
1221*3ac0a46fSAndroid Build Coastguard Worker     if (LastPtr) *LastPtr = p;
1222*3ac0a46fSAndroid Build Coastguard Worker 
1223*3ac0a46fSAndroid Build Coastguard Worker     for (;  p != NULL; p = p->Next) {
1224*3ac0a46fSAndroid Build Coastguard Worker 
1225*3ac0a46fSAndroid Build Coastguard Worker         if (LastPtr) *LastPtr = p;
1226*3ac0a46fSAndroid Build Coastguard Worker 
1227*3ac0a46fSAndroid Build Coastguard Worker         if (*Key != '#') { // Comments are ignored
1228*3ac0a46fSAndroid Build Coastguard Worker 
1229*3ac0a46fSAndroid Build Coastguard Worker             if (cmsstrcasecmp(Key, p->Keyword) == 0)
1230*3ac0a46fSAndroid Build Coastguard Worker                 break;
1231*3ac0a46fSAndroid Build Coastguard Worker         }
1232*3ac0a46fSAndroid Build Coastguard Worker     }
1233*3ac0a46fSAndroid Build Coastguard Worker 
1234*3ac0a46fSAndroid Build Coastguard Worker     if (p == NULL)
1235*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
1236*3ac0a46fSAndroid Build Coastguard Worker 
1237*3ac0a46fSAndroid Build Coastguard Worker     if (Subkey == 0)
1238*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
1239*3ac0a46fSAndroid Build Coastguard Worker 
1240*3ac0a46fSAndroid Build Coastguard Worker     for (; p != NULL; p = p->NextSubkey) {
1241*3ac0a46fSAndroid Build Coastguard Worker 
1242*3ac0a46fSAndroid Build Coastguard Worker         if (p ->Subkey == NULL) continue;
1243*3ac0a46fSAndroid Build Coastguard Worker 
1244*3ac0a46fSAndroid Build Coastguard Worker         if (LastPtr) *LastPtr = p;
1245*3ac0a46fSAndroid Build Coastguard Worker 
1246*3ac0a46fSAndroid Build Coastguard Worker         if (cmsstrcasecmp(Subkey, p->Subkey) == 0)
1247*3ac0a46fSAndroid Build Coastguard Worker             return TRUE;
1248*3ac0a46fSAndroid Build Coastguard Worker     }
1249*3ac0a46fSAndroid Build Coastguard Worker 
1250*3ac0a46fSAndroid Build Coastguard Worker     return FALSE;
1251*3ac0a46fSAndroid Build Coastguard Worker }
1252*3ac0a46fSAndroid Build Coastguard Worker 
1253*3ac0a46fSAndroid Build Coastguard Worker 
1254*3ac0a46fSAndroid Build Coastguard Worker 
1255*3ac0a46fSAndroid Build Coastguard Worker // Add a property into a linked list
1256*3ac0a46fSAndroid Build Coastguard Worker static
AddToList(cmsIT8 * it8,KEYVALUE ** Head,const char * Key,const char * Subkey,const char * xValue,WRITEMODE WriteAs)1257*3ac0a46fSAndroid Build Coastguard Worker KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
1258*3ac0a46fSAndroid Build Coastguard Worker {
1259*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* p;
1260*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* last;
1261*3ac0a46fSAndroid Build Coastguard Worker 
1262*3ac0a46fSAndroid Build Coastguard Worker 
1263*3ac0a46fSAndroid Build Coastguard Worker     // Check if property is already in list
1264*3ac0a46fSAndroid Build Coastguard Worker 
1265*3ac0a46fSAndroid Build Coastguard Worker     if (IsAvailableOnList(*Head, Key, Subkey, &p)) {
1266*3ac0a46fSAndroid Build Coastguard Worker 
1267*3ac0a46fSAndroid Build Coastguard Worker         // This may work for editing properties
1268*3ac0a46fSAndroid Build Coastguard Worker 
1269*3ac0a46fSAndroid Build Coastguard Worker         //     return SynError(it8, "duplicate key <%s>", Key);
1270*3ac0a46fSAndroid Build Coastguard Worker     }
1271*3ac0a46fSAndroid Build Coastguard Worker     else {
1272*3ac0a46fSAndroid Build Coastguard Worker 
1273*3ac0a46fSAndroid Build Coastguard Worker         last = p;
1274*3ac0a46fSAndroid Build Coastguard Worker 
1275*3ac0a46fSAndroid Build Coastguard Worker         // Allocate the container
1276*3ac0a46fSAndroid Build Coastguard Worker         p = (KEYVALUE*) AllocChunk(it8, sizeof(KEYVALUE));
1277*3ac0a46fSAndroid Build Coastguard Worker         if (p == NULL)
1278*3ac0a46fSAndroid Build Coastguard Worker         {
1279*3ac0a46fSAndroid Build Coastguard Worker             SynError(it8, "AddToList: out of memory");
1280*3ac0a46fSAndroid Build Coastguard Worker             return NULL;
1281*3ac0a46fSAndroid Build Coastguard Worker         }
1282*3ac0a46fSAndroid Build Coastguard Worker 
1283*3ac0a46fSAndroid Build Coastguard Worker         // Store name and value
1284*3ac0a46fSAndroid Build Coastguard Worker         p->Keyword = AllocString(it8, Key);
1285*3ac0a46fSAndroid Build Coastguard Worker         p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey);
1286*3ac0a46fSAndroid Build Coastguard Worker 
1287*3ac0a46fSAndroid Build Coastguard Worker         // Keep the container in our list
1288*3ac0a46fSAndroid Build Coastguard Worker         if (*Head == NULL) {
1289*3ac0a46fSAndroid Build Coastguard Worker             *Head = p;
1290*3ac0a46fSAndroid Build Coastguard Worker         }
1291*3ac0a46fSAndroid Build Coastguard Worker         else
1292*3ac0a46fSAndroid Build Coastguard Worker         {
1293*3ac0a46fSAndroid Build Coastguard Worker             if (Subkey != NULL && last != NULL) {
1294*3ac0a46fSAndroid Build Coastguard Worker 
1295*3ac0a46fSAndroid Build Coastguard Worker                 last->NextSubkey = p;
1296*3ac0a46fSAndroid Build Coastguard Worker 
1297*3ac0a46fSAndroid Build Coastguard Worker                 // If Subkey is not null, then last is the last property with the same key,
1298*3ac0a46fSAndroid Build Coastguard Worker                 // but not necessarily is the last property in the list, so we need to move
1299*3ac0a46fSAndroid Build Coastguard Worker                 // to the actual list end
1300*3ac0a46fSAndroid Build Coastguard Worker                 while (last->Next != NULL)
1301*3ac0a46fSAndroid Build Coastguard Worker                          last = last->Next;
1302*3ac0a46fSAndroid Build Coastguard Worker             }
1303*3ac0a46fSAndroid Build Coastguard Worker 
1304*3ac0a46fSAndroid Build Coastguard Worker             if (last != NULL) last->Next = p;
1305*3ac0a46fSAndroid Build Coastguard Worker         }
1306*3ac0a46fSAndroid Build Coastguard Worker 
1307*3ac0a46fSAndroid Build Coastguard Worker         p->Next    = NULL;
1308*3ac0a46fSAndroid Build Coastguard Worker         p->NextSubkey = NULL;
1309*3ac0a46fSAndroid Build Coastguard Worker     }
1310*3ac0a46fSAndroid Build Coastguard Worker 
1311*3ac0a46fSAndroid Build Coastguard Worker     p->WriteAs = WriteAs;
1312*3ac0a46fSAndroid Build Coastguard Worker 
1313*3ac0a46fSAndroid Build Coastguard Worker     if (xValue != NULL) {
1314*3ac0a46fSAndroid Build Coastguard Worker 
1315*3ac0a46fSAndroid Build Coastguard Worker         p->Value   = AllocString(it8, xValue);
1316*3ac0a46fSAndroid Build Coastguard Worker     }
1317*3ac0a46fSAndroid Build Coastguard Worker     else {
1318*3ac0a46fSAndroid Build Coastguard Worker         p->Value   = NULL;
1319*3ac0a46fSAndroid Build Coastguard Worker     }
1320*3ac0a46fSAndroid Build Coastguard Worker 
1321*3ac0a46fSAndroid Build Coastguard Worker     return p;
1322*3ac0a46fSAndroid Build Coastguard Worker }
1323*3ac0a46fSAndroid Build Coastguard Worker 
1324*3ac0a46fSAndroid Build Coastguard Worker static
AddAvailableProperty(cmsIT8 * it8,const char * Key,WRITEMODE as)1325*3ac0a46fSAndroid Build Coastguard Worker KEYVALUE* AddAvailableProperty(cmsIT8* it8, const char* Key, WRITEMODE as)
1326*3ac0a46fSAndroid Build Coastguard Worker {
1327*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as);
1328*3ac0a46fSAndroid Build Coastguard Worker }
1329*3ac0a46fSAndroid Build Coastguard Worker 
1330*3ac0a46fSAndroid Build Coastguard Worker 
1331*3ac0a46fSAndroid Build Coastguard Worker static
AddAvailableSampleID(cmsIT8 * it8,const char * Key)1332*3ac0a46fSAndroid Build Coastguard Worker KEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key)
1333*3ac0a46fSAndroid Build Coastguard Worker {
1334*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
1335*3ac0a46fSAndroid Build Coastguard Worker }
1336*3ac0a46fSAndroid Build Coastguard Worker 
1337*3ac0a46fSAndroid Build Coastguard Worker 
1338*3ac0a46fSAndroid Build Coastguard Worker static
AllocTable(cmsIT8 * it8)1339*3ac0a46fSAndroid Build Coastguard Worker void AllocTable(cmsIT8* it8)
1340*3ac0a46fSAndroid Build Coastguard Worker {
1341*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
1342*3ac0a46fSAndroid Build Coastguard Worker 
1343*3ac0a46fSAndroid Build Coastguard Worker     t = it8 ->Tab + it8 ->TablesCount;
1344*3ac0a46fSAndroid Build Coastguard Worker 
1345*3ac0a46fSAndroid Build Coastguard Worker     t->HeaderList = NULL;
1346*3ac0a46fSAndroid Build Coastguard Worker     t->DataFormat = NULL;
1347*3ac0a46fSAndroid Build Coastguard Worker     t->Data       = NULL;
1348*3ac0a46fSAndroid Build Coastguard Worker 
1349*3ac0a46fSAndroid Build Coastguard Worker     it8 ->TablesCount++;
1350*3ac0a46fSAndroid Build Coastguard Worker }
1351*3ac0a46fSAndroid Build Coastguard Worker 
1352*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetTable(cmsHANDLE IT8,cmsUInt32Number nTable)1353*3ac0a46fSAndroid Build Coastguard Worker cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE  IT8, cmsUInt32Number nTable)
1354*3ac0a46fSAndroid Build Coastguard Worker {
1355*3ac0a46fSAndroid Build Coastguard Worker      cmsIT8* it8 = (cmsIT8*) IT8;
1356*3ac0a46fSAndroid Build Coastguard Worker 
1357*3ac0a46fSAndroid Build Coastguard Worker      if (nTable >= it8 ->TablesCount) {
1358*3ac0a46fSAndroid Build Coastguard Worker 
1359*3ac0a46fSAndroid Build Coastguard Worker          if (nTable == it8 ->TablesCount) {
1360*3ac0a46fSAndroid Build Coastguard Worker 
1361*3ac0a46fSAndroid Build Coastguard Worker              AllocTable(it8);
1362*3ac0a46fSAndroid Build Coastguard Worker          }
1363*3ac0a46fSAndroid Build Coastguard Worker          else {
1364*3ac0a46fSAndroid Build Coastguard Worker              SynError(it8, "Table %d is out of sequence", nTable);
1365*3ac0a46fSAndroid Build Coastguard Worker              return -1;
1366*3ac0a46fSAndroid Build Coastguard Worker          }
1367*3ac0a46fSAndroid Build Coastguard Worker      }
1368*3ac0a46fSAndroid Build Coastguard Worker 
1369*3ac0a46fSAndroid Build Coastguard Worker      it8 ->nTable = nTable;
1370*3ac0a46fSAndroid Build Coastguard Worker 
1371*3ac0a46fSAndroid Build Coastguard Worker      return (cmsInt32Number) nTable;
1372*3ac0a46fSAndroid Build Coastguard Worker }
1373*3ac0a46fSAndroid Build Coastguard Worker 
1374*3ac0a46fSAndroid Build Coastguard Worker 
1375*3ac0a46fSAndroid Build Coastguard Worker 
1376*3ac0a46fSAndroid Build Coastguard Worker // Init an empty container
cmsIT8Alloc(cmsContext ContextID)1377*3ac0a46fSAndroid Build Coastguard Worker cmsHANDLE  CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
1378*3ac0a46fSAndroid Build Coastguard Worker {
1379*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8;
1380*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number i;
1381*3ac0a46fSAndroid Build Coastguard Worker 
1382*3ac0a46fSAndroid Build Coastguard Worker     it8 = (cmsIT8*) _cmsMallocZero(ContextID, sizeof(cmsIT8));
1383*3ac0a46fSAndroid Build Coastguard Worker     if (it8 == NULL) return NULL;
1384*3ac0a46fSAndroid Build Coastguard Worker 
1385*3ac0a46fSAndroid Build Coastguard Worker     AllocTable(it8);
1386*3ac0a46fSAndroid Build Coastguard Worker 
1387*3ac0a46fSAndroid Build Coastguard Worker     it8->MemoryBlock = NULL;
1388*3ac0a46fSAndroid Build Coastguard Worker     it8->MemorySink  = NULL;
1389*3ac0a46fSAndroid Build Coastguard Worker 
1390*3ac0a46fSAndroid Build Coastguard Worker     it8 ->nTable = 0;
1391*3ac0a46fSAndroid Build Coastguard Worker 
1392*3ac0a46fSAndroid Build Coastguard Worker     it8->ContextID = ContextID;
1393*3ac0a46fSAndroid Build Coastguard Worker     it8->Allocator.Used = 0;
1394*3ac0a46fSAndroid Build Coastguard Worker     it8->Allocator.Block = NULL;
1395*3ac0a46fSAndroid Build Coastguard Worker     it8->Allocator.BlockSize = 0;
1396*3ac0a46fSAndroid Build Coastguard Worker 
1397*3ac0a46fSAndroid Build Coastguard Worker     it8->ValidKeywords = NULL;
1398*3ac0a46fSAndroid Build Coastguard Worker     it8->ValidSampleID = NULL;
1399*3ac0a46fSAndroid Build Coastguard Worker 
1400*3ac0a46fSAndroid Build Coastguard Worker     it8 -> sy = SUNDEFINED;
1401*3ac0a46fSAndroid Build Coastguard Worker     it8 -> ch = ' ';
1402*3ac0a46fSAndroid Build Coastguard Worker     it8 -> Source = NULL;
1403*3ac0a46fSAndroid Build Coastguard Worker     it8 -> inum = 0;
1404*3ac0a46fSAndroid Build Coastguard Worker     it8 -> dnum = 0.0;
1405*3ac0a46fSAndroid Build Coastguard Worker 
1406*3ac0a46fSAndroid Build Coastguard Worker     it8->FileStack[0] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
1407*3ac0a46fSAndroid Build Coastguard Worker     it8->IncludeSP   = 0;
1408*3ac0a46fSAndroid Build Coastguard Worker     it8 -> lineno = 1;
1409*3ac0a46fSAndroid Build Coastguard Worker 
1410*3ac0a46fSAndroid Build Coastguard Worker     it8->id = StringAlloc(it8, MAXSTR);
1411*3ac0a46fSAndroid Build Coastguard Worker     it8->str = StringAlloc(it8, MAXSTR);
1412*3ac0a46fSAndroid Build Coastguard Worker 
1413*3ac0a46fSAndroid Build Coastguard Worker     strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
1414*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17");
1415*3ac0a46fSAndroid Build Coastguard Worker 
1416*3ac0a46fSAndroid Build Coastguard Worker     // Initialize predefined properties & data
1417*3ac0a46fSAndroid Build Coastguard Worker 
1418*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < NUMPREDEFINEDPROPS; i++)
1419*3ac0a46fSAndroid Build Coastguard Worker             AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as);
1420*3ac0a46fSAndroid Build Coastguard Worker 
1421*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
1422*3ac0a46fSAndroid Build Coastguard Worker             AddAvailableSampleID(it8, PredefinedSampleID[i]);
1423*3ac0a46fSAndroid Build Coastguard Worker 
1424*3ac0a46fSAndroid Build Coastguard Worker 
1425*3ac0a46fSAndroid Build Coastguard Worker    return (cmsHANDLE) it8;
1426*3ac0a46fSAndroid Build Coastguard Worker }
1427*3ac0a46fSAndroid Build Coastguard Worker 
1428*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetSheetType(cmsHANDLE hIT8)1429*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8)
1430*3ac0a46fSAndroid Build Coastguard Worker {
1431*3ac0a46fSAndroid Build Coastguard Worker         return GetTable((cmsIT8*) hIT8)->SheetType;
1432*3ac0a46fSAndroid Build Coastguard Worker }
1433*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetSheetType(cmsHANDLE hIT8,const char * Type)1434*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type)
1435*3ac0a46fSAndroid Build Coastguard Worker {
1436*3ac0a46fSAndroid Build Coastguard Worker         TABLE* t = GetTable((cmsIT8*) hIT8);
1437*3ac0a46fSAndroid Build Coastguard Worker 
1438*3ac0a46fSAndroid Build Coastguard Worker         strncpy(t ->SheetType, Type, MAXSTR-1);
1439*3ac0a46fSAndroid Build Coastguard Worker         t ->SheetType[MAXSTR-1] = 0;
1440*3ac0a46fSAndroid Build Coastguard Worker         return TRUE;
1441*3ac0a46fSAndroid Build Coastguard Worker }
1442*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetComment(cmsHANDLE hIT8,const char * Val)1443*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* Val)
1444*3ac0a46fSAndroid Build Coastguard Worker {
1445*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1446*3ac0a46fSAndroid Build Coastguard Worker 
1447*3ac0a46fSAndroid Build Coastguard Worker     if (!Val) return FALSE;
1448*3ac0a46fSAndroid Build Coastguard Worker     if (!*Val) return FALSE;
1449*3ac0a46fSAndroid Build Coastguard Worker 
1450*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
1451*3ac0a46fSAndroid Build Coastguard Worker }
1452*3ac0a46fSAndroid Build Coastguard Worker 
1453*3ac0a46fSAndroid Build Coastguard Worker // Sets a property
cmsIT8SetPropertyStr(cmsHANDLE hIT8,const char * Key,const char * Val)1454*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* Key, const char *Val)
1455*3ac0a46fSAndroid Build Coastguard Worker {
1456*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1457*3ac0a46fSAndroid Build Coastguard Worker 
1458*3ac0a46fSAndroid Build Coastguard Worker     if (!Val) return FALSE;
1459*3ac0a46fSAndroid Build Coastguard Worker     if (!*Val) return FALSE;
1460*3ac0a46fSAndroid Build Coastguard Worker 
1461*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
1462*3ac0a46fSAndroid Build Coastguard Worker }
1463*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetPropertyDbl(cmsHANDLE hIT8,const char * cProp,cmsFloat64Number Val)1464*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val)
1465*3ac0a46fSAndroid Build Coastguard Worker {
1466*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1467*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[1024];
1468*3ac0a46fSAndroid Build Coastguard Worker 
1469*3ac0a46fSAndroid Build Coastguard Worker     snprintf(Buffer, 1023, it8->DoubleFormatter, Val);
1470*3ac0a46fSAndroid Build Coastguard Worker 
1471*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
1472*3ac0a46fSAndroid Build Coastguard Worker }
1473*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetPropertyHex(cmsHANDLE hIT8,const char * cProp,cmsUInt32Number Val)1474*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val)
1475*3ac0a46fSAndroid Build Coastguard Worker {
1476*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1477*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[1024];
1478*3ac0a46fSAndroid Build Coastguard Worker 
1479*3ac0a46fSAndroid Build Coastguard Worker     snprintf(Buffer, 1023, "%u", Val);
1480*3ac0a46fSAndroid Build Coastguard Worker 
1481*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
1482*3ac0a46fSAndroid Build Coastguard Worker }
1483*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetPropertyUncooked(cmsHANDLE hIT8,const char * Key,const char * Buffer)1484*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer)
1485*3ac0a46fSAndroid Build Coastguard Worker {
1486*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1487*3ac0a46fSAndroid Build Coastguard Worker 
1488*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL;
1489*3ac0a46fSAndroid Build Coastguard Worker }
1490*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetPropertyMulti(cmsHANDLE hIT8,const char * Key,const char * SubKey,const char * Buffer)1491*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer)
1492*3ac0a46fSAndroid Build Coastguard Worker {
1493*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1494*3ac0a46fSAndroid Build Coastguard Worker 
1495*3ac0a46fSAndroid Build Coastguard Worker     return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL;
1496*3ac0a46fSAndroid Build Coastguard Worker }
1497*3ac0a46fSAndroid Build Coastguard Worker 
1498*3ac0a46fSAndroid Build Coastguard Worker // Gets a property
cmsIT8GetProperty(cmsHANDLE hIT8,const char * Key)1499*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* Key)
1500*3ac0a46fSAndroid Build Coastguard Worker {
1501*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1502*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* p;
1503*3ac0a46fSAndroid Build Coastguard Worker 
1504*3ac0a46fSAndroid Build Coastguard Worker     if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p))
1505*3ac0a46fSAndroid Build Coastguard Worker     {
1506*3ac0a46fSAndroid Build Coastguard Worker         return p -> Value;
1507*3ac0a46fSAndroid Build Coastguard Worker     }
1508*3ac0a46fSAndroid Build Coastguard Worker     return NULL;
1509*3ac0a46fSAndroid Build Coastguard Worker }
1510*3ac0a46fSAndroid Build Coastguard Worker 
1511*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetPropertyDbl(cmsHANDLE hIT8,const char * cProp)1512*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp)
1513*3ac0a46fSAndroid Build Coastguard Worker {
1514*3ac0a46fSAndroid Build Coastguard Worker     const char *v = cmsIT8GetProperty(hIT8, cProp);
1515*3ac0a46fSAndroid Build Coastguard Worker 
1516*3ac0a46fSAndroid Build Coastguard Worker     if (v == NULL) return 0.0;
1517*3ac0a46fSAndroid Build Coastguard Worker 
1518*3ac0a46fSAndroid Build Coastguard Worker     return ParseFloatNumber(v);
1519*3ac0a46fSAndroid Build Coastguard Worker }
1520*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetPropertyMulti(cmsHANDLE hIT8,const char * Key,const char * SubKey)1521*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey)
1522*3ac0a46fSAndroid Build Coastguard Worker {
1523*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1524*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* p;
1525*3ac0a46fSAndroid Build Coastguard Worker 
1526*3ac0a46fSAndroid Build Coastguard Worker     if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p)) {
1527*3ac0a46fSAndroid Build Coastguard Worker         return p -> Value;
1528*3ac0a46fSAndroid Build Coastguard Worker     }
1529*3ac0a46fSAndroid Build Coastguard Worker     return NULL;
1530*3ac0a46fSAndroid Build Coastguard Worker }
1531*3ac0a46fSAndroid Build Coastguard Worker 
1532*3ac0a46fSAndroid Build Coastguard Worker // ----------------------------------------------------------------- Datasets
1533*3ac0a46fSAndroid Build Coastguard Worker 
1534*3ac0a46fSAndroid Build Coastguard Worker // A safe atoi that returns 0 when NULL input is given
1535*3ac0a46fSAndroid Build Coastguard Worker static
satoi(const char * b)1536*3ac0a46fSAndroid Build Coastguard Worker cmsInt32Number satoi(const char* b)
1537*3ac0a46fSAndroid Build Coastguard Worker {
1538*3ac0a46fSAndroid Build Coastguard Worker     int n;
1539*3ac0a46fSAndroid Build Coastguard Worker 
1540*3ac0a46fSAndroid Build Coastguard Worker     if (b == NULL) return 0;
1541*3ac0a46fSAndroid Build Coastguard Worker 
1542*3ac0a46fSAndroid Build Coastguard Worker     n = atoi(b);
1543*3ac0a46fSAndroid Build Coastguard Worker     if (n > 0x7fffffffL) return 0x7fffffffL;
1544*3ac0a46fSAndroid Build Coastguard Worker     if (n < -0x7ffffffeL) return -0x7ffffffeL;
1545*3ac0a46fSAndroid Build Coastguard Worker 
1546*3ac0a46fSAndroid Build Coastguard Worker     return (cmsInt32Number)n;
1547*3ac0a46fSAndroid Build Coastguard Worker }
1548*3ac0a46fSAndroid Build Coastguard Worker 
1549*3ac0a46fSAndroid Build Coastguard Worker 
1550*3ac0a46fSAndroid Build Coastguard Worker static
AllocateDataFormat(cmsIT8 * it8)1551*3ac0a46fSAndroid Build Coastguard Worker cmsBool AllocateDataFormat(cmsIT8* it8)
1552*3ac0a46fSAndroid Build Coastguard Worker {
1553*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1554*3ac0a46fSAndroid Build Coastguard Worker 
1555*3ac0a46fSAndroid Build Coastguard Worker     if (t -> DataFormat) return TRUE;    // Already allocated
1556*3ac0a46fSAndroid Build Coastguard Worker 
1557*3ac0a46fSAndroid Build Coastguard Worker     t -> nSamples  = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
1558*3ac0a46fSAndroid Build Coastguard Worker 
1559*3ac0a46fSAndroid Build Coastguard Worker     if (t -> nSamples <= 0) {
1560*3ac0a46fSAndroid Build Coastguard Worker 
1561*3ac0a46fSAndroid Build Coastguard Worker         SynError(it8, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS");
1562*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
1563*3ac0a46fSAndroid Build Coastguard Worker         }
1564*3ac0a46fSAndroid Build Coastguard Worker 
1565*3ac0a46fSAndroid Build Coastguard Worker     t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *));
1566*3ac0a46fSAndroid Build Coastguard Worker     if (t->DataFormat == NULL) {
1567*3ac0a46fSAndroid Build Coastguard Worker 
1568*3ac0a46fSAndroid Build Coastguard Worker         SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array");
1569*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
1570*3ac0a46fSAndroid Build Coastguard Worker     }
1571*3ac0a46fSAndroid Build Coastguard Worker 
1572*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1573*3ac0a46fSAndroid Build Coastguard Worker }
1574*3ac0a46fSAndroid Build Coastguard Worker 
1575*3ac0a46fSAndroid Build Coastguard Worker static
GetDataFormat(cmsIT8 * it8,int n)1576*3ac0a46fSAndroid Build Coastguard Worker const char *GetDataFormat(cmsIT8* it8, int n)
1577*3ac0a46fSAndroid Build Coastguard Worker {
1578*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1579*3ac0a46fSAndroid Build Coastguard Worker 
1580*3ac0a46fSAndroid Build Coastguard Worker     if (t->DataFormat)
1581*3ac0a46fSAndroid Build Coastguard Worker         return t->DataFormat[n];
1582*3ac0a46fSAndroid Build Coastguard Worker 
1583*3ac0a46fSAndroid Build Coastguard Worker     return NULL;
1584*3ac0a46fSAndroid Build Coastguard Worker }
1585*3ac0a46fSAndroid Build Coastguard Worker 
1586*3ac0a46fSAndroid Build Coastguard Worker static
SetDataFormat(cmsIT8 * it8,int n,const char * label)1587*3ac0a46fSAndroid Build Coastguard Worker cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
1588*3ac0a46fSAndroid Build Coastguard Worker {
1589*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1590*3ac0a46fSAndroid Build Coastguard Worker 
1591*3ac0a46fSAndroid Build Coastguard Worker     if (!t->DataFormat) {
1592*3ac0a46fSAndroid Build Coastguard Worker 
1593*3ac0a46fSAndroid Build Coastguard Worker         if (!AllocateDataFormat(it8))
1594*3ac0a46fSAndroid Build Coastguard Worker             return FALSE;
1595*3ac0a46fSAndroid Build Coastguard Worker     }
1596*3ac0a46fSAndroid Build Coastguard Worker 
1597*3ac0a46fSAndroid Build Coastguard Worker     if (n > t -> nSamples) {
1598*3ac0a46fSAndroid Build Coastguard Worker         SynError(it8, "More than NUMBER_OF_FIELDS fields.");
1599*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
1600*3ac0a46fSAndroid Build Coastguard Worker     }
1601*3ac0a46fSAndroid Build Coastguard Worker 
1602*3ac0a46fSAndroid Build Coastguard Worker     if (t->DataFormat) {
1603*3ac0a46fSAndroid Build Coastguard Worker         t->DataFormat[n] = AllocString(it8, label);
1604*3ac0a46fSAndroid Build Coastguard Worker         if (t->DataFormat[n] == NULL) return FALSE;
1605*3ac0a46fSAndroid Build Coastguard Worker     }
1606*3ac0a46fSAndroid Build Coastguard Worker 
1607*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1608*3ac0a46fSAndroid Build Coastguard Worker }
1609*3ac0a46fSAndroid Build Coastguard Worker 
1610*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetDataFormat(cmsHANDLE h,int n,const char * Sample)1611*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE  h, int n, const char *Sample)
1612*3ac0a46fSAndroid Build Coastguard Worker {
1613*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*)h;
1614*3ac0a46fSAndroid Build Coastguard Worker     return SetDataFormat(it8, n, Sample);
1615*3ac0a46fSAndroid Build Coastguard Worker }
1616*3ac0a46fSAndroid Build Coastguard Worker 
1617*3ac0a46fSAndroid Build Coastguard Worker // Convert to binary
1618*3ac0a46fSAndroid Build Coastguard Worker static
satob(const char * v)1619*3ac0a46fSAndroid Build Coastguard Worker const char* satob(const char* v)
1620*3ac0a46fSAndroid Build Coastguard Worker {
1621*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number x;
1622*3ac0a46fSAndroid Build Coastguard Worker     static char buf[33];
1623*3ac0a46fSAndroid Build Coastguard Worker     char *s = buf + 33;
1624*3ac0a46fSAndroid Build Coastguard Worker 
1625*3ac0a46fSAndroid Build Coastguard Worker     if (v == NULL) return "0";
1626*3ac0a46fSAndroid Build Coastguard Worker 
1627*3ac0a46fSAndroid Build Coastguard Worker     x = atoi(v);
1628*3ac0a46fSAndroid Build Coastguard Worker     *--s = 0;
1629*3ac0a46fSAndroid Build Coastguard Worker     if (!x) *--s = '0';
1630*3ac0a46fSAndroid Build Coastguard Worker     for (; x; x /= 2) *--s = '0' + x%2;
1631*3ac0a46fSAndroid Build Coastguard Worker 
1632*3ac0a46fSAndroid Build Coastguard Worker     return s;
1633*3ac0a46fSAndroid Build Coastguard Worker }
1634*3ac0a46fSAndroid Build Coastguard Worker 
1635*3ac0a46fSAndroid Build Coastguard Worker 
1636*3ac0a46fSAndroid Build Coastguard Worker static
AllocateDataSet(cmsIT8 * it8)1637*3ac0a46fSAndroid Build Coastguard Worker cmsBool AllocateDataSet(cmsIT8* it8)
1638*3ac0a46fSAndroid Build Coastguard Worker {
1639*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1640*3ac0a46fSAndroid Build Coastguard Worker 
1641*3ac0a46fSAndroid Build Coastguard Worker     if (t -> Data) return TRUE;    // Already allocated
1642*3ac0a46fSAndroid Build Coastguard Worker 
1643*3ac0a46fSAndroid Build Coastguard Worker     t-> nSamples   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
1644*3ac0a46fSAndroid Build Coastguard Worker     t-> nPatches   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
1645*3ac0a46fSAndroid Build Coastguard Worker 
1646*3ac0a46fSAndroid Build Coastguard Worker     if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
1647*3ac0a46fSAndroid Build Coastguard Worker     {
1648*3ac0a46fSAndroid Build Coastguard Worker         SynError(it8, "AllocateDataSet: too much data");
1649*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
1650*3ac0a46fSAndroid Build Coastguard Worker     }
1651*3ac0a46fSAndroid Build Coastguard Worker     else {
1652*3ac0a46fSAndroid Build Coastguard Worker         // Some dumb analizers warns of possible overflow here, just take a look couple of lines above.
1653*3ac0a46fSAndroid Build Coastguard Worker         t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
1654*3ac0a46fSAndroid Build Coastguard Worker         if (t->Data == NULL) {
1655*3ac0a46fSAndroid Build Coastguard Worker 
1656*3ac0a46fSAndroid Build Coastguard Worker             SynError(it8, "AllocateDataSet: Unable to allocate data array");
1657*3ac0a46fSAndroid Build Coastguard Worker             return FALSE;
1658*3ac0a46fSAndroid Build Coastguard Worker         }
1659*3ac0a46fSAndroid Build Coastguard Worker     }
1660*3ac0a46fSAndroid Build Coastguard Worker 
1661*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1662*3ac0a46fSAndroid Build Coastguard Worker }
1663*3ac0a46fSAndroid Build Coastguard Worker 
1664*3ac0a46fSAndroid Build Coastguard Worker static
GetData(cmsIT8 * it8,int nSet,int nField)1665*3ac0a46fSAndroid Build Coastguard Worker char* GetData(cmsIT8* it8, int nSet, int nField)
1666*3ac0a46fSAndroid Build Coastguard Worker {
1667*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1668*3ac0a46fSAndroid Build Coastguard Worker     int nSamples    = t -> nSamples;
1669*3ac0a46fSAndroid Build Coastguard Worker     int nPatches    = t -> nPatches;
1670*3ac0a46fSAndroid Build Coastguard Worker 
1671*3ac0a46fSAndroid Build Coastguard Worker     if (nSet >= nPatches || nField >= nSamples)
1672*3ac0a46fSAndroid Build Coastguard Worker         return NULL;
1673*3ac0a46fSAndroid Build Coastguard Worker 
1674*3ac0a46fSAndroid Build Coastguard Worker     if (!t->Data) return NULL;
1675*3ac0a46fSAndroid Build Coastguard Worker     return t->Data [nSet * nSamples + nField];
1676*3ac0a46fSAndroid Build Coastguard Worker }
1677*3ac0a46fSAndroid Build Coastguard Worker 
1678*3ac0a46fSAndroid Build Coastguard Worker static
SetData(cmsIT8 * it8,int nSet,int nField,const char * Val)1679*3ac0a46fSAndroid Build Coastguard Worker cmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val)
1680*3ac0a46fSAndroid Build Coastguard Worker {
1681*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1682*3ac0a46fSAndroid Build Coastguard Worker 
1683*3ac0a46fSAndroid Build Coastguard Worker     if (!t->Data) {
1684*3ac0a46fSAndroid Build Coastguard Worker         if (!AllocateDataSet(it8)) return FALSE;
1685*3ac0a46fSAndroid Build Coastguard Worker     }
1686*3ac0a46fSAndroid Build Coastguard Worker 
1687*3ac0a46fSAndroid Build Coastguard Worker     if (!t->Data) return FALSE;
1688*3ac0a46fSAndroid Build Coastguard Worker 
1689*3ac0a46fSAndroid Build Coastguard Worker     if (nSet > t -> nPatches || nSet < 0) {
1690*3ac0a46fSAndroid Build Coastguard Worker 
1691*3ac0a46fSAndroid Build Coastguard Worker             return SynError(it8, "Patch %d out of range, there are %d patches", nSet, t -> nPatches);
1692*3ac0a46fSAndroid Build Coastguard Worker     }
1693*3ac0a46fSAndroid Build Coastguard Worker 
1694*3ac0a46fSAndroid Build Coastguard Worker     if (nField > t ->nSamples || nField < 0) {
1695*3ac0a46fSAndroid Build Coastguard Worker             return SynError(it8, "Sample %d out of range, there are %d samples", nField, t ->nSamples);
1696*3ac0a46fSAndroid Build Coastguard Worker 
1697*3ac0a46fSAndroid Build Coastguard Worker     }
1698*3ac0a46fSAndroid Build Coastguard Worker 
1699*3ac0a46fSAndroid Build Coastguard Worker     t->Data [nSet * t -> nSamples + nField] = AllocString(it8, Val);
1700*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1701*3ac0a46fSAndroid Build Coastguard Worker }
1702*3ac0a46fSAndroid Build Coastguard Worker 
1703*3ac0a46fSAndroid Build Coastguard Worker 
1704*3ac0a46fSAndroid Build Coastguard Worker // --------------------------------------------------------------- File I/O
1705*3ac0a46fSAndroid Build Coastguard Worker 
1706*3ac0a46fSAndroid Build Coastguard Worker 
1707*3ac0a46fSAndroid Build Coastguard Worker // Writes a string to file
1708*3ac0a46fSAndroid Build Coastguard Worker static
WriteStr(SAVESTREAM * f,const char * str)1709*3ac0a46fSAndroid Build Coastguard Worker void WriteStr(SAVESTREAM* f, const char *str)
1710*3ac0a46fSAndroid Build Coastguard Worker {
1711*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number len;
1712*3ac0a46fSAndroid Build Coastguard Worker 
1713*3ac0a46fSAndroid Build Coastguard Worker     if (str == NULL)
1714*3ac0a46fSAndroid Build Coastguard Worker         str = " ";
1715*3ac0a46fSAndroid Build Coastguard Worker 
1716*3ac0a46fSAndroid Build Coastguard Worker     // Length to write
1717*3ac0a46fSAndroid Build Coastguard Worker     len = (cmsUInt32Number) strlen(str);
1718*3ac0a46fSAndroid Build Coastguard Worker     f ->Used += len;
1719*3ac0a46fSAndroid Build Coastguard Worker 
1720*3ac0a46fSAndroid Build Coastguard Worker 
1721*3ac0a46fSAndroid Build Coastguard Worker     if (f ->stream) {   // Should I write it to a file?
1722*3ac0a46fSAndroid Build Coastguard Worker 
1723*3ac0a46fSAndroid Build Coastguard Worker         if (fwrite(str, 1, len, f->stream) != len) {
1724*3ac0a46fSAndroid Build Coastguard Worker             cmsSignalError(0, cmsERROR_WRITE, "Write to file error in CGATS parser");
1725*3ac0a46fSAndroid Build Coastguard Worker             return;
1726*3ac0a46fSAndroid Build Coastguard Worker         }
1727*3ac0a46fSAndroid Build Coastguard Worker 
1728*3ac0a46fSAndroid Build Coastguard Worker     }
1729*3ac0a46fSAndroid Build Coastguard Worker     else {  // Or to a memory block?
1730*3ac0a46fSAndroid Build Coastguard Worker 
1731*3ac0a46fSAndroid Build Coastguard Worker         if (f ->Base) {   // Am I just counting the bytes?
1732*3ac0a46fSAndroid Build Coastguard Worker 
1733*3ac0a46fSAndroid Build Coastguard Worker             if (f ->Used > f ->Max) {
1734*3ac0a46fSAndroid Build Coastguard Worker 
1735*3ac0a46fSAndroid Build Coastguard Worker                  cmsSignalError(0, cmsERROR_WRITE, "Write to memory overflows in CGATS parser");
1736*3ac0a46fSAndroid Build Coastguard Worker                  return;
1737*3ac0a46fSAndroid Build Coastguard Worker             }
1738*3ac0a46fSAndroid Build Coastguard Worker 
1739*3ac0a46fSAndroid Build Coastguard Worker             memmove(f ->Ptr, str, len);
1740*3ac0a46fSAndroid Build Coastguard Worker             f->Ptr += len;
1741*3ac0a46fSAndroid Build Coastguard Worker         }
1742*3ac0a46fSAndroid Build Coastguard Worker 
1743*3ac0a46fSAndroid Build Coastguard Worker     }
1744*3ac0a46fSAndroid Build Coastguard Worker }
1745*3ac0a46fSAndroid Build Coastguard Worker 
1746*3ac0a46fSAndroid Build Coastguard Worker 
1747*3ac0a46fSAndroid Build Coastguard Worker // Write formatted
1748*3ac0a46fSAndroid Build Coastguard Worker 
1749*3ac0a46fSAndroid Build Coastguard Worker static
Writef(SAVESTREAM * f,const char * frm,...)1750*3ac0a46fSAndroid Build Coastguard Worker void Writef(SAVESTREAM* f, const char* frm, ...)
1751*3ac0a46fSAndroid Build Coastguard Worker {
1752*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[4096];
1753*3ac0a46fSAndroid Build Coastguard Worker     va_list args;
1754*3ac0a46fSAndroid Build Coastguard Worker 
1755*3ac0a46fSAndroid Build Coastguard Worker     va_start(args, frm);
1756*3ac0a46fSAndroid Build Coastguard Worker     vsnprintf(Buffer, 4095, frm, args);
1757*3ac0a46fSAndroid Build Coastguard Worker     Buffer[4095] = 0;
1758*3ac0a46fSAndroid Build Coastguard Worker     WriteStr(f, Buffer);
1759*3ac0a46fSAndroid Build Coastguard Worker     va_end(args);
1760*3ac0a46fSAndroid Build Coastguard Worker 
1761*3ac0a46fSAndroid Build Coastguard Worker }
1762*3ac0a46fSAndroid Build Coastguard Worker 
1763*3ac0a46fSAndroid Build Coastguard Worker // Writes full header
1764*3ac0a46fSAndroid Build Coastguard Worker static
WriteHeader(cmsIT8 * it8,SAVESTREAM * fp)1765*3ac0a46fSAndroid Build Coastguard Worker void WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
1766*3ac0a46fSAndroid Build Coastguard Worker {
1767*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* p;
1768*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1769*3ac0a46fSAndroid Build Coastguard Worker 
1770*3ac0a46fSAndroid Build Coastguard Worker     // Writes the type
1771*3ac0a46fSAndroid Build Coastguard Worker     WriteStr(fp, t->SheetType);
1772*3ac0a46fSAndroid Build Coastguard Worker     WriteStr(fp, "\n");
1773*3ac0a46fSAndroid Build Coastguard Worker 
1774*3ac0a46fSAndroid Build Coastguard Worker     for (p = t->HeaderList; (p != NULL); p = p->Next)
1775*3ac0a46fSAndroid Build Coastguard Worker     {
1776*3ac0a46fSAndroid Build Coastguard Worker         if (*p ->Keyword == '#') {
1777*3ac0a46fSAndroid Build Coastguard Worker 
1778*3ac0a46fSAndroid Build Coastguard Worker             char* Pt;
1779*3ac0a46fSAndroid Build Coastguard Worker 
1780*3ac0a46fSAndroid Build Coastguard Worker             WriteStr(fp, "#\n# ");
1781*3ac0a46fSAndroid Build Coastguard Worker             for (Pt = p ->Value; *Pt; Pt++) {
1782*3ac0a46fSAndroid Build Coastguard Worker 
1783*3ac0a46fSAndroid Build Coastguard Worker 
1784*3ac0a46fSAndroid Build Coastguard Worker                 Writef(fp, "%c", *Pt);
1785*3ac0a46fSAndroid Build Coastguard Worker 
1786*3ac0a46fSAndroid Build Coastguard Worker                 if (*Pt == '\n') {
1787*3ac0a46fSAndroid Build Coastguard Worker                     WriteStr(fp, "# ");
1788*3ac0a46fSAndroid Build Coastguard Worker                 }
1789*3ac0a46fSAndroid Build Coastguard Worker             }
1790*3ac0a46fSAndroid Build Coastguard Worker 
1791*3ac0a46fSAndroid Build Coastguard Worker             WriteStr(fp, "\n#\n");
1792*3ac0a46fSAndroid Build Coastguard Worker             continue;
1793*3ac0a46fSAndroid Build Coastguard Worker         }
1794*3ac0a46fSAndroid Build Coastguard Worker 
1795*3ac0a46fSAndroid Build Coastguard Worker 
1796*3ac0a46fSAndroid Build Coastguard Worker         if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) {
1797*3ac0a46fSAndroid Build Coastguard Worker 
1798*3ac0a46fSAndroid Build Coastguard Worker #ifdef CMS_STRICT_CGATS
1799*3ac0a46fSAndroid Build Coastguard Worker             WriteStr(fp, "KEYWORD\t\"");
1800*3ac0a46fSAndroid Build Coastguard Worker             WriteStr(fp, p->Keyword);
1801*3ac0a46fSAndroid Build Coastguard Worker             WriteStr(fp, "\"\n");
1802*3ac0a46fSAndroid Build Coastguard Worker #endif
1803*3ac0a46fSAndroid Build Coastguard Worker 
1804*3ac0a46fSAndroid Build Coastguard Worker             AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED);
1805*3ac0a46fSAndroid Build Coastguard Worker         }
1806*3ac0a46fSAndroid Build Coastguard Worker 
1807*3ac0a46fSAndroid Build Coastguard Worker         WriteStr(fp, p->Keyword);
1808*3ac0a46fSAndroid Build Coastguard Worker         if (p->Value) {
1809*3ac0a46fSAndroid Build Coastguard Worker 
1810*3ac0a46fSAndroid Build Coastguard Worker             switch (p ->WriteAs) {
1811*3ac0a46fSAndroid Build Coastguard Worker 
1812*3ac0a46fSAndroid Build Coastguard Worker             case WRITE_UNCOOKED:
1813*3ac0a46fSAndroid Build Coastguard Worker                     Writef(fp, "\t%s", p ->Value);
1814*3ac0a46fSAndroid Build Coastguard Worker                     break;
1815*3ac0a46fSAndroid Build Coastguard Worker 
1816*3ac0a46fSAndroid Build Coastguard Worker             case WRITE_STRINGIFY:
1817*3ac0a46fSAndroid Build Coastguard Worker                     Writef(fp, "\t\"%s\"", p->Value );
1818*3ac0a46fSAndroid Build Coastguard Worker                     break;
1819*3ac0a46fSAndroid Build Coastguard Worker 
1820*3ac0a46fSAndroid Build Coastguard Worker             case WRITE_HEXADECIMAL:
1821*3ac0a46fSAndroid Build Coastguard Worker                     Writef(fp, "\t0x%X", satoi(p ->Value));
1822*3ac0a46fSAndroid Build Coastguard Worker                     break;
1823*3ac0a46fSAndroid Build Coastguard Worker 
1824*3ac0a46fSAndroid Build Coastguard Worker             case WRITE_BINARY:
1825*3ac0a46fSAndroid Build Coastguard Worker                     Writef(fp, "\t0b%s", satob(p ->Value));
1826*3ac0a46fSAndroid Build Coastguard Worker                     break;
1827*3ac0a46fSAndroid Build Coastguard Worker 
1828*3ac0a46fSAndroid Build Coastguard Worker             case WRITE_PAIR:
1829*3ac0a46fSAndroid Build Coastguard Worker                     Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value);
1830*3ac0a46fSAndroid Build Coastguard Worker                     break;
1831*3ac0a46fSAndroid Build Coastguard Worker 
1832*3ac0a46fSAndroid Build Coastguard Worker             default: SynError(it8, "Unknown write mode %d", p ->WriteAs);
1833*3ac0a46fSAndroid Build Coastguard Worker                      return;
1834*3ac0a46fSAndroid Build Coastguard Worker             }
1835*3ac0a46fSAndroid Build Coastguard Worker         }
1836*3ac0a46fSAndroid Build Coastguard Worker 
1837*3ac0a46fSAndroid Build Coastguard Worker         WriteStr (fp, "\n");
1838*3ac0a46fSAndroid Build Coastguard Worker     }
1839*3ac0a46fSAndroid Build Coastguard Worker 
1840*3ac0a46fSAndroid Build Coastguard Worker }
1841*3ac0a46fSAndroid Build Coastguard Worker 
1842*3ac0a46fSAndroid Build Coastguard Worker 
1843*3ac0a46fSAndroid Build Coastguard Worker // Writes the data format
1844*3ac0a46fSAndroid Build Coastguard Worker static
WriteDataFormat(SAVESTREAM * fp,cmsIT8 * it8)1845*3ac0a46fSAndroid Build Coastguard Worker void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
1846*3ac0a46fSAndroid Build Coastguard Worker {
1847*3ac0a46fSAndroid Build Coastguard Worker     int i, nSamples;
1848*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1849*3ac0a46fSAndroid Build Coastguard Worker 
1850*3ac0a46fSAndroid Build Coastguard Worker     if (!t -> DataFormat) return;
1851*3ac0a46fSAndroid Build Coastguard Worker 
1852*3ac0a46fSAndroid Build Coastguard Worker        WriteStr(fp, "BEGIN_DATA_FORMAT\n");
1853*3ac0a46fSAndroid Build Coastguard Worker        WriteStr(fp, " ");
1854*3ac0a46fSAndroid Build Coastguard Worker        nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
1855*3ac0a46fSAndroid Build Coastguard Worker 
1856*3ac0a46fSAndroid Build Coastguard Worker        for (i = 0; i < nSamples; i++) {
1857*3ac0a46fSAndroid Build Coastguard Worker 
1858*3ac0a46fSAndroid Build Coastguard Worker               WriteStr(fp, t->DataFormat[i]);
1859*3ac0a46fSAndroid Build Coastguard Worker               WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
1860*3ac0a46fSAndroid Build Coastguard Worker           }
1861*3ac0a46fSAndroid Build Coastguard Worker 
1862*3ac0a46fSAndroid Build Coastguard Worker        WriteStr (fp, "END_DATA_FORMAT\n");
1863*3ac0a46fSAndroid Build Coastguard Worker }
1864*3ac0a46fSAndroid Build Coastguard Worker 
1865*3ac0a46fSAndroid Build Coastguard Worker 
1866*3ac0a46fSAndroid Build Coastguard Worker // Writes data array
1867*3ac0a46fSAndroid Build Coastguard Worker static
WriteData(SAVESTREAM * fp,cmsIT8 * it8)1868*3ac0a46fSAndroid Build Coastguard Worker void WriteData(SAVESTREAM* fp, cmsIT8* it8)
1869*3ac0a46fSAndroid Build Coastguard Worker {
1870*3ac0a46fSAndroid Build Coastguard Worker        int  i, j;
1871*3ac0a46fSAndroid Build Coastguard Worker        TABLE* t = GetTable(it8);
1872*3ac0a46fSAndroid Build Coastguard Worker 
1873*3ac0a46fSAndroid Build Coastguard Worker        if (!t->Data) return;
1874*3ac0a46fSAndroid Build Coastguard Worker 
1875*3ac0a46fSAndroid Build Coastguard Worker        WriteStr (fp, "BEGIN_DATA\n");
1876*3ac0a46fSAndroid Build Coastguard Worker 
1877*3ac0a46fSAndroid Build Coastguard Worker        t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
1878*3ac0a46fSAndroid Build Coastguard Worker 
1879*3ac0a46fSAndroid Build Coastguard Worker        for (i = 0; i < t-> nPatches; i++) {
1880*3ac0a46fSAndroid Build Coastguard Worker 
1881*3ac0a46fSAndroid Build Coastguard Worker               WriteStr(fp, " ");
1882*3ac0a46fSAndroid Build Coastguard Worker 
1883*3ac0a46fSAndroid Build Coastguard Worker               for (j = 0; j < t->nSamples; j++) {
1884*3ac0a46fSAndroid Build Coastguard Worker 
1885*3ac0a46fSAndroid Build Coastguard Worker                      char *ptr = t->Data[i*t->nSamples+j];
1886*3ac0a46fSAndroid Build Coastguard Worker 
1887*3ac0a46fSAndroid Build Coastguard Worker                      if (ptr == NULL) WriteStr(fp, "\"\"");
1888*3ac0a46fSAndroid Build Coastguard Worker                      else {
1889*3ac0a46fSAndroid Build Coastguard Worker                          // If value contains whitespace, enclose within quote
1890*3ac0a46fSAndroid Build Coastguard Worker 
1891*3ac0a46fSAndroid Build Coastguard Worker                          if (strchr(ptr, ' ') != NULL) {
1892*3ac0a46fSAndroid Build Coastguard Worker 
1893*3ac0a46fSAndroid Build Coastguard Worker                              WriteStr(fp, "\"");
1894*3ac0a46fSAndroid Build Coastguard Worker                              WriteStr(fp, ptr);
1895*3ac0a46fSAndroid Build Coastguard Worker                              WriteStr(fp, "\"");
1896*3ac0a46fSAndroid Build Coastguard Worker                          }
1897*3ac0a46fSAndroid Build Coastguard Worker                          else
1898*3ac0a46fSAndroid Build Coastguard Worker                             WriteStr(fp, ptr);
1899*3ac0a46fSAndroid Build Coastguard Worker                      }
1900*3ac0a46fSAndroid Build Coastguard Worker 
1901*3ac0a46fSAndroid Build Coastguard Worker                      WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t"));
1902*3ac0a46fSAndroid Build Coastguard Worker               }
1903*3ac0a46fSAndroid Build Coastguard Worker        }
1904*3ac0a46fSAndroid Build Coastguard Worker        WriteStr (fp, "END_DATA\n");
1905*3ac0a46fSAndroid Build Coastguard Worker }
1906*3ac0a46fSAndroid Build Coastguard Worker 
1907*3ac0a46fSAndroid Build Coastguard Worker 
1908*3ac0a46fSAndroid Build Coastguard Worker 
1909*3ac0a46fSAndroid Build Coastguard Worker // Saves whole file
cmsIT8SaveToFile(cmsHANDLE hIT8,const char * cFileName)1910*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName)
1911*3ac0a46fSAndroid Build Coastguard Worker {
1912*3ac0a46fSAndroid Build Coastguard Worker     SAVESTREAM sd;
1913*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number i;
1914*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1915*3ac0a46fSAndroid Build Coastguard Worker 
1916*3ac0a46fSAndroid Build Coastguard Worker     memset(&sd, 0, sizeof(sd));
1917*3ac0a46fSAndroid Build Coastguard Worker 
1918*3ac0a46fSAndroid Build Coastguard Worker     sd.stream = fopen(cFileName, "wt");
1919*3ac0a46fSAndroid Build Coastguard Worker     if (!sd.stream) return FALSE;
1920*3ac0a46fSAndroid Build Coastguard Worker 
1921*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < it8 ->TablesCount; i++) {
1922*3ac0a46fSAndroid Build Coastguard Worker 
1923*3ac0a46fSAndroid Build Coastguard Worker             cmsIT8SetTable(hIT8, i);
1924*3ac0a46fSAndroid Build Coastguard Worker             WriteHeader(it8, &sd);
1925*3ac0a46fSAndroid Build Coastguard Worker             WriteDataFormat(&sd, it8);
1926*3ac0a46fSAndroid Build Coastguard Worker             WriteData(&sd, it8);
1927*3ac0a46fSAndroid Build Coastguard Worker     }
1928*3ac0a46fSAndroid Build Coastguard Worker 
1929*3ac0a46fSAndroid Build Coastguard Worker     if (fclose(sd.stream) != 0) return FALSE;
1930*3ac0a46fSAndroid Build Coastguard Worker 
1931*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1932*3ac0a46fSAndroid Build Coastguard Worker }
1933*3ac0a46fSAndroid Build Coastguard Worker 
1934*3ac0a46fSAndroid Build Coastguard Worker 
1935*3ac0a46fSAndroid Build Coastguard Worker // Saves to memory
cmsIT8SaveToMem(cmsHANDLE hIT8,void * MemPtr,cmsUInt32Number * BytesNeeded)1936*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* BytesNeeded)
1937*3ac0a46fSAndroid Build Coastguard Worker {
1938*3ac0a46fSAndroid Build Coastguard Worker     SAVESTREAM sd;
1939*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number i;
1940*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
1941*3ac0a46fSAndroid Build Coastguard Worker 
1942*3ac0a46fSAndroid Build Coastguard Worker     memset(&sd, 0, sizeof(sd));
1943*3ac0a46fSAndroid Build Coastguard Worker 
1944*3ac0a46fSAndroid Build Coastguard Worker     sd.stream = NULL;
1945*3ac0a46fSAndroid Build Coastguard Worker     sd.Base   = (cmsUInt8Number*) MemPtr;
1946*3ac0a46fSAndroid Build Coastguard Worker     sd.Ptr    = sd.Base;
1947*3ac0a46fSAndroid Build Coastguard Worker 
1948*3ac0a46fSAndroid Build Coastguard Worker     sd.Used = 0;
1949*3ac0a46fSAndroid Build Coastguard Worker 
1950*3ac0a46fSAndroid Build Coastguard Worker     if (sd.Base && (*BytesNeeded > 0)) {
1951*3ac0a46fSAndroid Build Coastguard Worker 
1952*3ac0a46fSAndroid Build Coastguard Worker         sd.Max = (*BytesNeeded) - 1;     // Write to memory?
1953*3ac0a46fSAndroid Build Coastguard Worker     }
1954*3ac0a46fSAndroid Build Coastguard Worker     else
1955*3ac0a46fSAndroid Build Coastguard Worker         sd.Max  = 0;                // Just counting the needed bytes
1956*3ac0a46fSAndroid Build Coastguard Worker 
1957*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < it8 ->TablesCount; i++) {
1958*3ac0a46fSAndroid Build Coastguard Worker 
1959*3ac0a46fSAndroid Build Coastguard Worker         cmsIT8SetTable(hIT8, i);
1960*3ac0a46fSAndroid Build Coastguard Worker         WriteHeader(it8, &sd);
1961*3ac0a46fSAndroid Build Coastguard Worker         WriteDataFormat(&sd, it8);
1962*3ac0a46fSAndroid Build Coastguard Worker         WriteData(&sd, it8);
1963*3ac0a46fSAndroid Build Coastguard Worker     }
1964*3ac0a46fSAndroid Build Coastguard Worker 
1965*3ac0a46fSAndroid Build Coastguard Worker     sd.Used++;  // The \0 at the very end
1966*3ac0a46fSAndroid Build Coastguard Worker 
1967*3ac0a46fSAndroid Build Coastguard Worker     if (sd.Base)
1968*3ac0a46fSAndroid Build Coastguard Worker         *sd.Ptr = 0;
1969*3ac0a46fSAndroid Build Coastguard Worker 
1970*3ac0a46fSAndroid Build Coastguard Worker     *BytesNeeded = sd.Used;
1971*3ac0a46fSAndroid Build Coastguard Worker 
1972*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
1973*3ac0a46fSAndroid Build Coastguard Worker }
1974*3ac0a46fSAndroid Build Coastguard Worker 
1975*3ac0a46fSAndroid Build Coastguard Worker 
1976*3ac0a46fSAndroid Build Coastguard Worker // -------------------------------------------------------------- Higher level parsing
1977*3ac0a46fSAndroid Build Coastguard Worker 
1978*3ac0a46fSAndroid Build Coastguard Worker static
DataFormatSection(cmsIT8 * it8)1979*3ac0a46fSAndroid Build Coastguard Worker cmsBool DataFormatSection(cmsIT8* it8)
1980*3ac0a46fSAndroid Build Coastguard Worker {
1981*3ac0a46fSAndroid Build Coastguard Worker     int iField = 0;
1982*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
1983*3ac0a46fSAndroid Build Coastguard Worker 
1984*3ac0a46fSAndroid Build Coastguard Worker     InSymbol(it8);   // Eats "BEGIN_DATA_FORMAT"
1985*3ac0a46fSAndroid Build Coastguard Worker     CheckEOLN(it8);
1986*3ac0a46fSAndroid Build Coastguard Worker 
1987*3ac0a46fSAndroid Build Coastguard Worker     while (it8->sy != SEND_DATA_FORMAT &&
1988*3ac0a46fSAndroid Build Coastguard Worker         it8->sy != SEOLN &&
1989*3ac0a46fSAndroid Build Coastguard Worker         it8->sy != SEOF &&
1990*3ac0a46fSAndroid Build Coastguard Worker         it8->sy != SSYNERROR)  {
1991*3ac0a46fSAndroid Build Coastguard Worker 
1992*3ac0a46fSAndroid Build Coastguard Worker             if (it8->sy != SIDENT) {
1993*3ac0a46fSAndroid Build Coastguard Worker 
1994*3ac0a46fSAndroid Build Coastguard Worker                 return SynError(it8, "Sample type expected");
1995*3ac0a46fSAndroid Build Coastguard Worker             }
1996*3ac0a46fSAndroid Build Coastguard Worker 
1997*3ac0a46fSAndroid Build Coastguard Worker             if (!SetDataFormat(it8, iField, StringPtr(it8->id))) return FALSE;
1998*3ac0a46fSAndroid Build Coastguard Worker             iField++;
1999*3ac0a46fSAndroid Build Coastguard Worker 
2000*3ac0a46fSAndroid Build Coastguard Worker             InSymbol(it8);
2001*3ac0a46fSAndroid Build Coastguard Worker             SkipEOLN(it8);
2002*3ac0a46fSAndroid Build Coastguard Worker        }
2003*3ac0a46fSAndroid Build Coastguard Worker 
2004*3ac0a46fSAndroid Build Coastguard Worker        SkipEOLN(it8);
2005*3ac0a46fSAndroid Build Coastguard Worker        Skip(it8, SEND_DATA_FORMAT);
2006*3ac0a46fSAndroid Build Coastguard Worker        SkipEOLN(it8);
2007*3ac0a46fSAndroid Build Coastguard Worker 
2008*3ac0a46fSAndroid Build Coastguard Worker        if (iField != t ->nSamples) {
2009*3ac0a46fSAndroid Build Coastguard Worker            SynError(it8, "Count mismatch. NUMBER_OF_FIELDS was %d, found %d\n", t ->nSamples, iField);
2010*3ac0a46fSAndroid Build Coastguard Worker 
2011*3ac0a46fSAndroid Build Coastguard Worker 
2012*3ac0a46fSAndroid Build Coastguard Worker        }
2013*3ac0a46fSAndroid Build Coastguard Worker 
2014*3ac0a46fSAndroid Build Coastguard Worker        return TRUE;
2015*3ac0a46fSAndroid Build Coastguard Worker }
2016*3ac0a46fSAndroid Build Coastguard Worker 
2017*3ac0a46fSAndroid Build Coastguard Worker 
2018*3ac0a46fSAndroid Build Coastguard Worker 
2019*3ac0a46fSAndroid Build Coastguard Worker static
DataSection(cmsIT8 * it8)2020*3ac0a46fSAndroid Build Coastguard Worker cmsBool DataSection (cmsIT8* it8)
2021*3ac0a46fSAndroid Build Coastguard Worker {
2022*3ac0a46fSAndroid Build Coastguard Worker     int  iField = 0;
2023*3ac0a46fSAndroid Build Coastguard Worker     int  iSet   = 0;
2024*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[256];
2025*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
2026*3ac0a46fSAndroid Build Coastguard Worker 
2027*3ac0a46fSAndroid Build Coastguard Worker     InSymbol(it8);   // Eats "BEGIN_DATA"
2028*3ac0a46fSAndroid Build Coastguard Worker     CheckEOLN(it8);
2029*3ac0a46fSAndroid Build Coastguard Worker 
2030*3ac0a46fSAndroid Build Coastguard Worker     if (!t->Data) {
2031*3ac0a46fSAndroid Build Coastguard Worker         if (!AllocateDataSet(it8)) return FALSE;
2032*3ac0a46fSAndroid Build Coastguard Worker     }
2033*3ac0a46fSAndroid Build Coastguard Worker 
2034*3ac0a46fSAndroid Build Coastguard Worker     while (it8->sy != SEND_DATA && it8->sy != SEOF)
2035*3ac0a46fSAndroid Build Coastguard Worker     {
2036*3ac0a46fSAndroid Build Coastguard Worker         if (iField >= t -> nSamples) {
2037*3ac0a46fSAndroid Build Coastguard Worker             iField = 0;
2038*3ac0a46fSAndroid Build Coastguard Worker             iSet++;
2039*3ac0a46fSAndroid Build Coastguard Worker 
2040*3ac0a46fSAndroid Build Coastguard Worker         }
2041*3ac0a46fSAndroid Build Coastguard Worker 
2042*3ac0a46fSAndroid Build Coastguard Worker         if (it8->sy != SEND_DATA && it8->sy != SEOF) {
2043*3ac0a46fSAndroid Build Coastguard Worker 
2044*3ac0a46fSAndroid Build Coastguard Worker             switch (it8->sy)
2045*3ac0a46fSAndroid Build Coastguard Worker             {
2046*3ac0a46fSAndroid Build Coastguard Worker 
2047*3ac0a46fSAndroid Build Coastguard Worker             // To keep very long data
2048*3ac0a46fSAndroid Build Coastguard Worker             case SIDENT:
2049*3ac0a46fSAndroid Build Coastguard Worker                 if (!SetData(it8, iSet, iField, StringPtr(it8->id)))
2050*3ac0a46fSAndroid Build Coastguard Worker                     return FALSE;
2051*3ac0a46fSAndroid Build Coastguard Worker                 break;
2052*3ac0a46fSAndroid Build Coastguard Worker 
2053*3ac0a46fSAndroid Build Coastguard Worker             case SSTRING:
2054*3ac0a46fSAndroid Build Coastguard Worker                 if (!SetData(it8, iSet, iField, StringPtr(it8->str)))
2055*3ac0a46fSAndroid Build Coastguard Worker                     return FALSE;
2056*3ac0a46fSAndroid Build Coastguard Worker                 break;
2057*3ac0a46fSAndroid Build Coastguard Worker 
2058*3ac0a46fSAndroid Build Coastguard Worker             default:
2059*3ac0a46fSAndroid Build Coastguard Worker 
2060*3ac0a46fSAndroid Build Coastguard Worker             if (!GetVal(it8, Buffer, 255, "Sample data expected"))
2061*3ac0a46fSAndroid Build Coastguard Worker                 return FALSE;
2062*3ac0a46fSAndroid Build Coastguard Worker 
2063*3ac0a46fSAndroid Build Coastguard Worker             if (!SetData(it8, iSet, iField, Buffer))
2064*3ac0a46fSAndroid Build Coastguard Worker                 return FALSE;
2065*3ac0a46fSAndroid Build Coastguard Worker             }
2066*3ac0a46fSAndroid Build Coastguard Worker 
2067*3ac0a46fSAndroid Build Coastguard Worker             iField++;
2068*3ac0a46fSAndroid Build Coastguard Worker 
2069*3ac0a46fSAndroid Build Coastguard Worker             InSymbol(it8);
2070*3ac0a46fSAndroid Build Coastguard Worker             SkipEOLN(it8);
2071*3ac0a46fSAndroid Build Coastguard Worker         }
2072*3ac0a46fSAndroid Build Coastguard Worker     }
2073*3ac0a46fSAndroid Build Coastguard Worker 
2074*3ac0a46fSAndroid Build Coastguard Worker     SkipEOLN(it8);
2075*3ac0a46fSAndroid Build Coastguard Worker     Skip(it8, SEND_DATA);
2076*3ac0a46fSAndroid Build Coastguard Worker     SkipEOLN(it8);
2077*3ac0a46fSAndroid Build Coastguard Worker 
2078*3ac0a46fSAndroid Build Coastguard Worker     // Check for data completion.
2079*3ac0a46fSAndroid Build Coastguard Worker 
2080*3ac0a46fSAndroid Build Coastguard Worker     if ((iSet+1) != t -> nPatches)
2081*3ac0a46fSAndroid Build Coastguard Worker         return SynError(it8, "Count mismatch. NUMBER_OF_SETS was %d, found %d\n", t ->nPatches, iSet+1);
2082*3ac0a46fSAndroid Build Coastguard Worker 
2083*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
2084*3ac0a46fSAndroid Build Coastguard Worker }
2085*3ac0a46fSAndroid Build Coastguard Worker 
2086*3ac0a46fSAndroid Build Coastguard Worker 
2087*3ac0a46fSAndroid Build Coastguard Worker 
2088*3ac0a46fSAndroid Build Coastguard Worker 
2089*3ac0a46fSAndroid Build Coastguard Worker static
HeaderSection(cmsIT8 * it8)2090*3ac0a46fSAndroid Build Coastguard Worker cmsBool HeaderSection(cmsIT8* it8)
2091*3ac0a46fSAndroid Build Coastguard Worker {
2092*3ac0a46fSAndroid Build Coastguard Worker     char VarName[MAXID];
2093*3ac0a46fSAndroid Build Coastguard Worker     char Buffer[MAXSTR];
2094*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* Key;
2095*3ac0a46fSAndroid Build Coastguard Worker 
2096*3ac0a46fSAndroid Build Coastguard Worker         while (it8->sy != SEOF &&
2097*3ac0a46fSAndroid Build Coastguard Worker                it8->sy != SSYNERROR &&
2098*3ac0a46fSAndroid Build Coastguard Worker                it8->sy != SBEGIN_DATA_FORMAT &&
2099*3ac0a46fSAndroid Build Coastguard Worker                it8->sy != SBEGIN_DATA) {
2100*3ac0a46fSAndroid Build Coastguard Worker 
2101*3ac0a46fSAndroid Build Coastguard Worker 
2102*3ac0a46fSAndroid Build Coastguard Worker         switch (it8 -> sy) {
2103*3ac0a46fSAndroid Build Coastguard Worker 
2104*3ac0a46fSAndroid Build Coastguard Worker         case SKEYWORD:
2105*3ac0a46fSAndroid Build Coastguard Worker                 InSymbol(it8);
2106*3ac0a46fSAndroid Build Coastguard Worker                 if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
2107*3ac0a46fSAndroid Build Coastguard Worker                 if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE;
2108*3ac0a46fSAndroid Build Coastguard Worker                 InSymbol(it8);
2109*3ac0a46fSAndroid Build Coastguard Worker                 break;
2110*3ac0a46fSAndroid Build Coastguard Worker 
2111*3ac0a46fSAndroid Build Coastguard Worker 
2112*3ac0a46fSAndroid Build Coastguard Worker         case SDATA_FORMAT_ID:
2113*3ac0a46fSAndroid Build Coastguard Worker                 InSymbol(it8);
2114*3ac0a46fSAndroid Build Coastguard Worker                 if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
2115*3ac0a46fSAndroid Build Coastguard Worker                 if (!AddAvailableSampleID(it8, Buffer)) return FALSE;
2116*3ac0a46fSAndroid Build Coastguard Worker                 InSymbol(it8);
2117*3ac0a46fSAndroid Build Coastguard Worker                 break;
2118*3ac0a46fSAndroid Build Coastguard Worker 
2119*3ac0a46fSAndroid Build Coastguard Worker 
2120*3ac0a46fSAndroid Build Coastguard Worker         case SIDENT:
2121*3ac0a46fSAndroid Build Coastguard Worker             strncpy(VarName, StringPtr(it8->id), MAXID - 1);
2122*3ac0a46fSAndroid Build Coastguard Worker             VarName[MAXID - 1] = 0;
2123*3ac0a46fSAndroid Build Coastguard Worker 
2124*3ac0a46fSAndroid Build Coastguard Worker             if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) {
2125*3ac0a46fSAndroid Build Coastguard Worker 
2126*3ac0a46fSAndroid Build Coastguard Worker #ifdef CMS_STRICT_CGATS
2127*3ac0a46fSAndroid Build Coastguard Worker                 return SynError(it8, "Undefined keyword '%s'", VarName);
2128*3ac0a46fSAndroid Build Coastguard Worker #else
2129*3ac0a46fSAndroid Build Coastguard Worker                 Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
2130*3ac0a46fSAndroid Build Coastguard Worker                 if (Key == NULL) return FALSE;
2131*3ac0a46fSAndroid Build Coastguard Worker #endif
2132*3ac0a46fSAndroid Build Coastguard Worker             }
2133*3ac0a46fSAndroid Build Coastguard Worker 
2134*3ac0a46fSAndroid Build Coastguard Worker             InSymbol(it8);
2135*3ac0a46fSAndroid Build Coastguard Worker             if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE;
2136*3ac0a46fSAndroid Build Coastguard Worker 
2137*3ac0a46fSAndroid Build Coastguard Worker             if (Key->WriteAs != WRITE_PAIR) {
2138*3ac0a46fSAndroid Build Coastguard Worker                 AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
2139*3ac0a46fSAndroid Build Coastguard Worker                     (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
2140*3ac0a46fSAndroid Build Coastguard Worker             }
2141*3ac0a46fSAndroid Build Coastguard Worker             else {
2142*3ac0a46fSAndroid Build Coastguard Worker                 const char *Subkey;
2143*3ac0a46fSAndroid Build Coastguard Worker                 char *Nextkey;
2144*3ac0a46fSAndroid Build Coastguard Worker                 if (it8->sy != SSTRING)
2145*3ac0a46fSAndroid Build Coastguard Worker                     return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
2146*3ac0a46fSAndroid Build Coastguard Worker 
2147*3ac0a46fSAndroid Build Coastguard Worker                 // chop the string as a list of "subkey, value" pairs, using ';' as a separator
2148*3ac0a46fSAndroid Build Coastguard Worker                 for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
2149*3ac0a46fSAndroid Build Coastguard Worker                 {
2150*3ac0a46fSAndroid Build Coastguard Worker                     char *Value, *temp;
2151*3ac0a46fSAndroid Build Coastguard Worker 
2152*3ac0a46fSAndroid Build Coastguard Worker                     //  identify token pair boundary
2153*3ac0a46fSAndroid Build Coastguard Worker                     Nextkey = (char*)strchr(Subkey, ';');
2154*3ac0a46fSAndroid Build Coastguard Worker                     if (Nextkey)
2155*3ac0a46fSAndroid Build Coastguard Worker                         *Nextkey++ = '\0';
2156*3ac0a46fSAndroid Build Coastguard Worker 
2157*3ac0a46fSAndroid Build Coastguard Worker                     // for each pair, split the subkey and the value
2158*3ac0a46fSAndroid Build Coastguard Worker                     Value = (char*)strrchr(Subkey, ',');
2159*3ac0a46fSAndroid Build Coastguard Worker                     if (Value == NULL)
2160*3ac0a46fSAndroid Build Coastguard Worker                         return SynError(it8, "Invalid value for property '%s'.", VarName);
2161*3ac0a46fSAndroid Build Coastguard Worker 
2162*3ac0a46fSAndroid Build Coastguard Worker                     // gobble the spaces before the coma, and the coma itself
2163*3ac0a46fSAndroid Build Coastguard Worker                     temp = Value++;
2164*3ac0a46fSAndroid Build Coastguard Worker                     do *temp-- = '\0'; while (temp >= Subkey && *temp == ' ');
2165*3ac0a46fSAndroid Build Coastguard Worker 
2166*3ac0a46fSAndroid Build Coastguard Worker                     // gobble any space at the right
2167*3ac0a46fSAndroid Build Coastguard Worker                     temp = Value + strlen(Value) - 1;
2168*3ac0a46fSAndroid Build Coastguard Worker                     while (*temp == ' ') *temp-- = '\0';
2169*3ac0a46fSAndroid Build Coastguard Worker 
2170*3ac0a46fSAndroid Build Coastguard Worker                     // trim the strings from the left
2171*3ac0a46fSAndroid Build Coastguard Worker                     Subkey += strspn(Subkey, " ");
2172*3ac0a46fSAndroid Build Coastguard Worker                     Value += strspn(Value, " ");
2173*3ac0a46fSAndroid Build Coastguard Worker 
2174*3ac0a46fSAndroid Build Coastguard Worker                     if (Subkey[0] == 0 || Value[0] == 0)
2175*3ac0a46fSAndroid Build Coastguard Worker                         return SynError(it8, "Invalid value for property '%s'.", VarName);
2176*3ac0a46fSAndroid Build Coastguard Worker                     AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
2177*3ac0a46fSAndroid Build Coastguard Worker                 }
2178*3ac0a46fSAndroid Build Coastguard Worker             }
2179*3ac0a46fSAndroid Build Coastguard Worker 
2180*3ac0a46fSAndroid Build Coastguard Worker             InSymbol(it8);
2181*3ac0a46fSAndroid Build Coastguard Worker             break;
2182*3ac0a46fSAndroid Build Coastguard Worker 
2183*3ac0a46fSAndroid Build Coastguard Worker 
2184*3ac0a46fSAndroid Build Coastguard Worker         case SEOLN: break;
2185*3ac0a46fSAndroid Build Coastguard Worker 
2186*3ac0a46fSAndroid Build Coastguard Worker         default:
2187*3ac0a46fSAndroid Build Coastguard Worker                 return SynError(it8, "expected keyword or identifier");
2188*3ac0a46fSAndroid Build Coastguard Worker         }
2189*3ac0a46fSAndroid Build Coastguard Worker 
2190*3ac0a46fSAndroid Build Coastguard Worker     SkipEOLN(it8);
2191*3ac0a46fSAndroid Build Coastguard Worker     }
2192*3ac0a46fSAndroid Build Coastguard Worker 
2193*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
2194*3ac0a46fSAndroid Build Coastguard Worker 
2195*3ac0a46fSAndroid Build Coastguard Worker }
2196*3ac0a46fSAndroid Build Coastguard Worker 
2197*3ac0a46fSAndroid Build Coastguard Worker 
2198*3ac0a46fSAndroid Build Coastguard Worker static
ReadType(cmsIT8 * it8,char * SheetTypePtr)2199*3ac0a46fSAndroid Build Coastguard Worker void ReadType(cmsIT8* it8, char* SheetTypePtr)
2200*3ac0a46fSAndroid Build Coastguard Worker {
2201*3ac0a46fSAndroid Build Coastguard Worker     cmsInt32Number cnt = 0;
2202*3ac0a46fSAndroid Build Coastguard Worker 
2203*3ac0a46fSAndroid Build Coastguard Worker     // First line is a very special case.
2204*3ac0a46fSAndroid Build Coastguard Worker 
2205*3ac0a46fSAndroid Build Coastguard Worker     while (isseparator(it8->ch))
2206*3ac0a46fSAndroid Build Coastguard Worker             NextCh(it8);
2207*3ac0a46fSAndroid Build Coastguard Worker 
2208*3ac0a46fSAndroid Build Coastguard Worker     while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {
2209*3ac0a46fSAndroid Build Coastguard Worker 
2210*3ac0a46fSAndroid Build Coastguard Worker         if (cnt++ < MAXSTR)
2211*3ac0a46fSAndroid Build Coastguard Worker             *SheetTypePtr++= (char) it8 ->ch;
2212*3ac0a46fSAndroid Build Coastguard Worker         NextCh(it8);
2213*3ac0a46fSAndroid Build Coastguard Worker     }
2214*3ac0a46fSAndroid Build Coastguard Worker 
2215*3ac0a46fSAndroid Build Coastguard Worker     *SheetTypePtr = 0;
2216*3ac0a46fSAndroid Build Coastguard Worker }
2217*3ac0a46fSAndroid Build Coastguard Worker 
2218*3ac0a46fSAndroid Build Coastguard Worker 
2219*3ac0a46fSAndroid Build Coastguard Worker static
ParseIT8(cmsIT8 * it8,cmsBool nosheet)2220*3ac0a46fSAndroid Build Coastguard Worker cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
2221*3ac0a46fSAndroid Build Coastguard Worker {
2222*3ac0a46fSAndroid Build Coastguard Worker     char* SheetTypePtr = it8 ->Tab[0].SheetType;
2223*3ac0a46fSAndroid Build Coastguard Worker 
2224*3ac0a46fSAndroid Build Coastguard Worker     if (nosheet == 0) {
2225*3ac0a46fSAndroid Build Coastguard Worker         ReadType(it8, SheetTypePtr);
2226*3ac0a46fSAndroid Build Coastguard Worker     }
2227*3ac0a46fSAndroid Build Coastguard Worker 
2228*3ac0a46fSAndroid Build Coastguard Worker     InSymbol(it8);
2229*3ac0a46fSAndroid Build Coastguard Worker 
2230*3ac0a46fSAndroid Build Coastguard Worker     SkipEOLN(it8);
2231*3ac0a46fSAndroid Build Coastguard Worker 
2232*3ac0a46fSAndroid Build Coastguard Worker     while (it8-> sy != SEOF &&
2233*3ac0a46fSAndroid Build Coastguard Worker            it8-> sy != SSYNERROR) {
2234*3ac0a46fSAndroid Build Coastguard Worker 
2235*3ac0a46fSAndroid Build Coastguard Worker             switch (it8 -> sy) {
2236*3ac0a46fSAndroid Build Coastguard Worker 
2237*3ac0a46fSAndroid Build Coastguard Worker             case SBEGIN_DATA_FORMAT:
2238*3ac0a46fSAndroid Build Coastguard Worker                     if (!DataFormatSection(it8)) return FALSE;
2239*3ac0a46fSAndroid Build Coastguard Worker                     break;
2240*3ac0a46fSAndroid Build Coastguard Worker 
2241*3ac0a46fSAndroid Build Coastguard Worker             case SBEGIN_DATA:
2242*3ac0a46fSAndroid Build Coastguard Worker 
2243*3ac0a46fSAndroid Build Coastguard Worker                     if (!DataSection(it8)) return FALSE;
2244*3ac0a46fSAndroid Build Coastguard Worker 
2245*3ac0a46fSAndroid Build Coastguard Worker                     if (it8 -> sy != SEOF) {
2246*3ac0a46fSAndroid Build Coastguard Worker 
2247*3ac0a46fSAndroid Build Coastguard Worker                             AllocTable(it8);
2248*3ac0a46fSAndroid Build Coastguard Worker                             it8 ->nTable = it8 ->TablesCount - 1;
2249*3ac0a46fSAndroid Build Coastguard Worker 
2250*3ac0a46fSAndroid Build Coastguard Worker                             // Read sheet type if present. We only support identifier and string.
2251*3ac0a46fSAndroid Build Coastguard Worker                             // <ident> <eoln> is a type string
2252*3ac0a46fSAndroid Build Coastguard Worker                             // anything else, is not a type string
2253*3ac0a46fSAndroid Build Coastguard Worker                             if (nosheet == 0) {
2254*3ac0a46fSAndroid Build Coastguard Worker 
2255*3ac0a46fSAndroid Build Coastguard Worker                                 if (it8 ->sy == SIDENT) {
2256*3ac0a46fSAndroid Build Coastguard Worker 
2257*3ac0a46fSAndroid Build Coastguard Worker                                     // May be a type sheet or may be a prop value statement. We cannot use insymbol in
2258*3ac0a46fSAndroid Build Coastguard Worker                                     // this special case...
2259*3ac0a46fSAndroid Build Coastguard Worker                                      while (isseparator(it8->ch))
2260*3ac0a46fSAndroid Build Coastguard Worker                                          NextCh(it8);
2261*3ac0a46fSAndroid Build Coastguard Worker 
2262*3ac0a46fSAndroid Build Coastguard Worker                                      // If a newline is found, then this is a type string
2263*3ac0a46fSAndroid Build Coastguard Worker                                     if (it8 ->ch == '\n' || it8->ch == '\r') {
2264*3ac0a46fSAndroid Build Coastguard Worker 
2265*3ac0a46fSAndroid Build Coastguard Worker                                          cmsIT8SetSheetType(it8, StringPtr(it8 ->id));
2266*3ac0a46fSAndroid Build Coastguard Worker                                          InSymbol(it8);
2267*3ac0a46fSAndroid Build Coastguard Worker                                     }
2268*3ac0a46fSAndroid Build Coastguard Worker                                     else
2269*3ac0a46fSAndroid Build Coastguard Worker                                     {
2270*3ac0a46fSAndroid Build Coastguard Worker                                         // It is not. Just continue
2271*3ac0a46fSAndroid Build Coastguard Worker                                         cmsIT8SetSheetType(it8, "");
2272*3ac0a46fSAndroid Build Coastguard Worker                                     }
2273*3ac0a46fSAndroid Build Coastguard Worker                                 }
2274*3ac0a46fSAndroid Build Coastguard Worker                                 else
2275*3ac0a46fSAndroid Build Coastguard Worker                                     // Validate quoted strings
2276*3ac0a46fSAndroid Build Coastguard Worker                                     if (it8 ->sy == SSTRING) {
2277*3ac0a46fSAndroid Build Coastguard Worker                                         cmsIT8SetSheetType(it8, StringPtr(it8 ->str));
2278*3ac0a46fSAndroid Build Coastguard Worker                                         InSymbol(it8);
2279*3ac0a46fSAndroid Build Coastguard Worker                                     }
2280*3ac0a46fSAndroid Build Coastguard Worker                            }
2281*3ac0a46fSAndroid Build Coastguard Worker 
2282*3ac0a46fSAndroid Build Coastguard Worker                     }
2283*3ac0a46fSAndroid Build Coastguard Worker                     break;
2284*3ac0a46fSAndroid Build Coastguard Worker 
2285*3ac0a46fSAndroid Build Coastguard Worker             case SEOLN:
2286*3ac0a46fSAndroid Build Coastguard Worker                     SkipEOLN(it8);
2287*3ac0a46fSAndroid Build Coastguard Worker                     break;
2288*3ac0a46fSAndroid Build Coastguard Worker 
2289*3ac0a46fSAndroid Build Coastguard Worker             default:
2290*3ac0a46fSAndroid Build Coastguard Worker                     if (!HeaderSection(it8)) return FALSE;
2291*3ac0a46fSAndroid Build Coastguard Worker            }
2292*3ac0a46fSAndroid Build Coastguard Worker 
2293*3ac0a46fSAndroid Build Coastguard Worker     }
2294*3ac0a46fSAndroid Build Coastguard Worker 
2295*3ac0a46fSAndroid Build Coastguard Worker     return (it8 -> sy != SSYNERROR);
2296*3ac0a46fSAndroid Build Coastguard Worker }
2297*3ac0a46fSAndroid Build Coastguard Worker 
2298*3ac0a46fSAndroid Build Coastguard Worker 
2299*3ac0a46fSAndroid Build Coastguard Worker 
2300*3ac0a46fSAndroid Build Coastguard Worker // Init useful pointers
2301*3ac0a46fSAndroid Build Coastguard Worker 
2302*3ac0a46fSAndroid Build Coastguard Worker static
CookPointers(cmsIT8 * it8)2303*3ac0a46fSAndroid Build Coastguard Worker void CookPointers(cmsIT8* it8)
2304*3ac0a46fSAndroid Build Coastguard Worker {
2305*3ac0a46fSAndroid Build Coastguard Worker     int idField, i;
2306*3ac0a46fSAndroid Build Coastguard Worker     char* Fld;
2307*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number j;
2308*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number nOldTable = it8 ->nTable;
2309*3ac0a46fSAndroid Build Coastguard Worker 
2310*3ac0a46fSAndroid Build Coastguard Worker     for (j=0; j < it8 ->TablesCount; j++) {
2311*3ac0a46fSAndroid Build Coastguard Worker 
2312*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = it8 ->Tab + j;
2313*3ac0a46fSAndroid Build Coastguard Worker 
2314*3ac0a46fSAndroid Build Coastguard Worker     t -> SampleID = 0;
2315*3ac0a46fSAndroid Build Coastguard Worker     it8 ->nTable = j;
2316*3ac0a46fSAndroid Build Coastguard Worker 
2317*3ac0a46fSAndroid Build Coastguard Worker     for (idField = 0; idField < t -> nSamples; idField++)
2318*3ac0a46fSAndroid Build Coastguard Worker     {
2319*3ac0a46fSAndroid Build Coastguard Worker         if (t ->DataFormat == NULL){
2320*3ac0a46fSAndroid Build Coastguard Worker             SynError(it8, "Undefined DATA_FORMAT");
2321*3ac0a46fSAndroid Build Coastguard Worker             return;
2322*3ac0a46fSAndroid Build Coastguard Worker         }
2323*3ac0a46fSAndroid Build Coastguard Worker 
2324*3ac0a46fSAndroid Build Coastguard Worker         Fld = t->DataFormat[idField];
2325*3ac0a46fSAndroid Build Coastguard Worker         if (!Fld) continue;
2326*3ac0a46fSAndroid Build Coastguard Worker 
2327*3ac0a46fSAndroid Build Coastguard Worker 
2328*3ac0a46fSAndroid Build Coastguard Worker         if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
2329*3ac0a46fSAndroid Build Coastguard Worker 
2330*3ac0a46fSAndroid Build Coastguard Worker             t -> SampleID = idField;
2331*3ac0a46fSAndroid Build Coastguard Worker         }
2332*3ac0a46fSAndroid Build Coastguard Worker 
2333*3ac0a46fSAndroid Build Coastguard Worker         // "LABEL" is an extension. It keeps references to forward tables
2334*3ac0a46fSAndroid Build Coastguard Worker 
2335*3ac0a46fSAndroid Build Coastguard Worker         if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
2336*3ac0a46fSAndroid Build Coastguard Worker 
2337*3ac0a46fSAndroid Build Coastguard Worker             // Search for table references...
2338*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < t->nPatches; i++) {
2339*3ac0a46fSAndroid Build Coastguard Worker 
2340*3ac0a46fSAndroid Build Coastguard Worker                 char* Label = GetData(it8, i, idField);
2341*3ac0a46fSAndroid Build Coastguard Worker 
2342*3ac0a46fSAndroid Build Coastguard Worker                 if (Label) {
2343*3ac0a46fSAndroid Build Coastguard Worker 
2344*3ac0a46fSAndroid Build Coastguard Worker                     cmsUInt32Number k;
2345*3ac0a46fSAndroid Build Coastguard Worker 
2346*3ac0a46fSAndroid Build Coastguard Worker                     // This is the label, search for a table containing
2347*3ac0a46fSAndroid Build Coastguard Worker                     // this property
2348*3ac0a46fSAndroid Build Coastguard Worker 
2349*3ac0a46fSAndroid Build Coastguard Worker                     for (k = 0; k < it8->TablesCount; k++) {
2350*3ac0a46fSAndroid Build Coastguard Worker 
2351*3ac0a46fSAndroid Build Coastguard Worker                         TABLE* Table = it8->Tab + k;
2352*3ac0a46fSAndroid Build Coastguard Worker                         KEYVALUE* p;
2353*3ac0a46fSAndroid Build Coastguard Worker 
2354*3ac0a46fSAndroid Build Coastguard Worker                         if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
2355*3ac0a46fSAndroid Build Coastguard Worker 
2356*3ac0a46fSAndroid Build Coastguard Worker                             // Available, keep type and table
2357*3ac0a46fSAndroid Build Coastguard Worker                             char Buffer[256];
2358*3ac0a46fSAndroid Build Coastguard Worker 
2359*3ac0a46fSAndroid Build Coastguard Worker                             char* Type = p->Value;
2360*3ac0a46fSAndroid Build Coastguard Worker                             int  nTable = (int)k;
2361*3ac0a46fSAndroid Build Coastguard Worker 
2362*3ac0a46fSAndroid Build Coastguard Worker                             snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
2363*3ac0a46fSAndroid Build Coastguard Worker 
2364*3ac0a46fSAndroid Build Coastguard Worker                             SetData(it8, i, idField, Buffer);
2365*3ac0a46fSAndroid Build Coastguard Worker 						}
2366*3ac0a46fSAndroid Build Coastguard Worker 					}
2367*3ac0a46fSAndroid Build Coastguard Worker 
2368*3ac0a46fSAndroid Build Coastguard Worker 
2369*3ac0a46fSAndroid Build Coastguard Worker 				}
2370*3ac0a46fSAndroid Build Coastguard Worker 
2371*3ac0a46fSAndroid Build Coastguard Worker 			}
2372*3ac0a46fSAndroid Build Coastguard Worker 
2373*3ac0a46fSAndroid Build Coastguard Worker 
2374*3ac0a46fSAndroid Build Coastguard Worker 		}
2375*3ac0a46fSAndroid Build Coastguard Worker 
2376*3ac0a46fSAndroid Build Coastguard Worker 	}
2377*3ac0a46fSAndroid Build Coastguard Worker 	}
2378*3ac0a46fSAndroid Build Coastguard Worker 
2379*3ac0a46fSAndroid Build Coastguard Worker     it8 ->nTable = nOldTable;
2380*3ac0a46fSAndroid Build Coastguard Worker }
2381*3ac0a46fSAndroid Build Coastguard Worker 
2382*3ac0a46fSAndroid Build Coastguard Worker // Try to infere if the file is a CGATS/IT8 file at all. Read first line
2383*3ac0a46fSAndroid Build Coastguard Worker // that should be something like some printable characters plus a \n
2384*3ac0a46fSAndroid Build Coastguard Worker // returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
2385*3ac0a46fSAndroid Build Coastguard Worker static
IsMyBlock(const cmsUInt8Number * Buffer,cmsUInt32Number n)2386*3ac0a46fSAndroid Build Coastguard Worker int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n)
2387*3ac0a46fSAndroid Build Coastguard Worker {
2388*3ac0a46fSAndroid Build Coastguard Worker     int words = 1, space = 0, quot = 0;
2389*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number i;
2390*3ac0a46fSAndroid Build Coastguard Worker 
2391*3ac0a46fSAndroid Build Coastguard Worker     if (n < 10) return 0;   // Too small
2392*3ac0a46fSAndroid Build Coastguard Worker 
2393*3ac0a46fSAndroid Build Coastguard Worker     if (n > 132)
2394*3ac0a46fSAndroid Build Coastguard Worker         n = 132;
2395*3ac0a46fSAndroid Build Coastguard Worker 
2396*3ac0a46fSAndroid Build Coastguard Worker     for (i = 1; i < n; i++) {
2397*3ac0a46fSAndroid Build Coastguard Worker 
2398*3ac0a46fSAndroid Build Coastguard Worker         switch(Buffer[i])
2399*3ac0a46fSAndroid Build Coastguard Worker         {
2400*3ac0a46fSAndroid Build Coastguard Worker         case '\n':
2401*3ac0a46fSAndroid Build Coastguard Worker         case '\r':
2402*3ac0a46fSAndroid Build Coastguard Worker             return ((quot == 1) || (words > 2)) ? 0 : words;
2403*3ac0a46fSAndroid Build Coastguard Worker         case '\t':
2404*3ac0a46fSAndroid Build Coastguard Worker         case ' ':
2405*3ac0a46fSAndroid Build Coastguard Worker             if(!quot && !space)
2406*3ac0a46fSAndroid Build Coastguard Worker                 space = 1;
2407*3ac0a46fSAndroid Build Coastguard Worker             break;
2408*3ac0a46fSAndroid Build Coastguard Worker         case '\"':
2409*3ac0a46fSAndroid Build Coastguard Worker             quot = !quot;
2410*3ac0a46fSAndroid Build Coastguard Worker             break;
2411*3ac0a46fSAndroid Build Coastguard Worker         default:
2412*3ac0a46fSAndroid Build Coastguard Worker             if (Buffer[i] < 32) return 0;
2413*3ac0a46fSAndroid Build Coastguard Worker             if (Buffer[i] > 127) return 0;
2414*3ac0a46fSAndroid Build Coastguard Worker             words += space;
2415*3ac0a46fSAndroid Build Coastguard Worker             space = 0;
2416*3ac0a46fSAndroid Build Coastguard Worker             break;
2417*3ac0a46fSAndroid Build Coastguard Worker         }
2418*3ac0a46fSAndroid Build Coastguard Worker     }
2419*3ac0a46fSAndroid Build Coastguard Worker 
2420*3ac0a46fSAndroid Build Coastguard Worker     return 0;
2421*3ac0a46fSAndroid Build Coastguard Worker }
2422*3ac0a46fSAndroid Build Coastguard Worker 
2423*3ac0a46fSAndroid Build Coastguard Worker 
2424*3ac0a46fSAndroid Build Coastguard Worker static
IsMyFile(const char * FileName)2425*3ac0a46fSAndroid Build Coastguard Worker cmsBool IsMyFile(const char* FileName)
2426*3ac0a46fSAndroid Build Coastguard Worker {
2427*3ac0a46fSAndroid Build Coastguard Worker    FILE *fp;
2428*3ac0a46fSAndroid Build Coastguard Worker    cmsUInt32Number Size;
2429*3ac0a46fSAndroid Build Coastguard Worker    cmsUInt8Number Ptr[133];
2430*3ac0a46fSAndroid Build Coastguard Worker 
2431*3ac0a46fSAndroid Build Coastguard Worker    fp = fopen(FileName, "rt");
2432*3ac0a46fSAndroid Build Coastguard Worker    if (!fp) {
2433*3ac0a46fSAndroid Build Coastguard Worker        cmsSignalError(0, cmsERROR_FILE, "File '%s' not found", FileName);
2434*3ac0a46fSAndroid Build Coastguard Worker        return FALSE;
2435*3ac0a46fSAndroid Build Coastguard Worker    }
2436*3ac0a46fSAndroid Build Coastguard Worker 
2437*3ac0a46fSAndroid Build Coastguard Worker    Size = (cmsUInt32Number) fread(Ptr, 1, 132, fp);
2438*3ac0a46fSAndroid Build Coastguard Worker 
2439*3ac0a46fSAndroid Build Coastguard Worker    if (fclose(fp) != 0)
2440*3ac0a46fSAndroid Build Coastguard Worker        return FALSE;
2441*3ac0a46fSAndroid Build Coastguard Worker 
2442*3ac0a46fSAndroid Build Coastguard Worker    Ptr[Size] = '\0';
2443*3ac0a46fSAndroid Build Coastguard Worker 
2444*3ac0a46fSAndroid Build Coastguard Worker    return IsMyBlock(Ptr, Size);
2445*3ac0a46fSAndroid Build Coastguard Worker }
2446*3ac0a46fSAndroid Build Coastguard Worker 
2447*3ac0a46fSAndroid Build Coastguard Worker // ---------------------------------------------------------- Exported routines
2448*3ac0a46fSAndroid Build Coastguard Worker 
2449*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8LoadFromMem(cmsContext ContextID,const void * Ptr,cmsUInt32Number len)2450*3ac0a46fSAndroid Build Coastguard Worker cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
2451*3ac0a46fSAndroid Build Coastguard Worker {
2452*3ac0a46fSAndroid Build Coastguard Worker     cmsHANDLE hIT8;
2453*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8*  it8;
2454*3ac0a46fSAndroid Build Coastguard Worker     int type;
2455*3ac0a46fSAndroid Build Coastguard Worker 
2456*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(Ptr != NULL);
2457*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(len != 0);
2458*3ac0a46fSAndroid Build Coastguard Worker 
2459*3ac0a46fSAndroid Build Coastguard Worker     type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
2460*3ac0a46fSAndroid Build Coastguard Worker     if (type == 0) return NULL;
2461*3ac0a46fSAndroid Build Coastguard Worker 
2462*3ac0a46fSAndroid Build Coastguard Worker     hIT8 = cmsIT8Alloc(ContextID);
2463*3ac0a46fSAndroid Build Coastguard Worker     if (!hIT8) return NULL;
2464*3ac0a46fSAndroid Build Coastguard Worker 
2465*3ac0a46fSAndroid Build Coastguard Worker     it8 = (cmsIT8*) hIT8;
2466*3ac0a46fSAndroid Build Coastguard Worker     it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
2467*3ac0a46fSAndroid Build Coastguard Worker     if (it8->MemoryBlock == NULL)
2468*3ac0a46fSAndroid Build Coastguard Worker     {
2469*3ac0a46fSAndroid Build Coastguard Worker         cmsIT8Free(hIT8);
2470*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
2471*3ac0a46fSAndroid Build Coastguard Worker     }
2472*3ac0a46fSAndroid Build Coastguard Worker 
2473*3ac0a46fSAndroid Build Coastguard Worker     strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
2474*3ac0a46fSAndroid Build Coastguard Worker     it8 ->MemoryBlock[len] = 0;
2475*3ac0a46fSAndroid Build Coastguard Worker 
2476*3ac0a46fSAndroid Build Coastguard Worker     strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1);
2477*3ac0a46fSAndroid Build Coastguard Worker     it8-> Source = it8 -> MemoryBlock;
2478*3ac0a46fSAndroid Build Coastguard Worker 
2479*3ac0a46fSAndroid Build Coastguard Worker     if (!ParseIT8(it8, type-1)) {
2480*3ac0a46fSAndroid Build Coastguard Worker 
2481*3ac0a46fSAndroid Build Coastguard Worker         cmsIT8Free(hIT8);
2482*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
2483*3ac0a46fSAndroid Build Coastguard Worker     }
2484*3ac0a46fSAndroid Build Coastguard Worker 
2485*3ac0a46fSAndroid Build Coastguard Worker     CookPointers(it8);
2486*3ac0a46fSAndroid Build Coastguard Worker     it8 ->nTable = 0;
2487*3ac0a46fSAndroid Build Coastguard Worker 
2488*3ac0a46fSAndroid Build Coastguard Worker     _cmsFree(ContextID, it8->MemoryBlock);
2489*3ac0a46fSAndroid Build Coastguard Worker     it8 -> MemoryBlock = NULL;
2490*3ac0a46fSAndroid Build Coastguard Worker 
2491*3ac0a46fSAndroid Build Coastguard Worker     return hIT8;
2492*3ac0a46fSAndroid Build Coastguard Worker 
2493*3ac0a46fSAndroid Build Coastguard Worker 
2494*3ac0a46fSAndroid Build Coastguard Worker }
2495*3ac0a46fSAndroid Build Coastguard Worker 
2496*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8LoadFromFile(cmsContext ContextID,const char * cFileName)2497*3ac0a46fSAndroid Build Coastguard Worker cmsHANDLE  CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName)
2498*3ac0a46fSAndroid Build Coastguard Worker {
2499*3ac0a46fSAndroid Build Coastguard Worker 
2500*3ac0a46fSAndroid Build Coastguard Worker      cmsHANDLE hIT8;
2501*3ac0a46fSAndroid Build Coastguard Worker      cmsIT8*  it8;
2502*3ac0a46fSAndroid Build Coastguard Worker      int type;
2503*3ac0a46fSAndroid Build Coastguard Worker 
2504*3ac0a46fSAndroid Build Coastguard Worker      _cmsAssert(cFileName != NULL);
2505*3ac0a46fSAndroid Build Coastguard Worker 
2506*3ac0a46fSAndroid Build Coastguard Worker      type = IsMyFile(cFileName);
2507*3ac0a46fSAndroid Build Coastguard Worker      if (type == 0) return NULL;
2508*3ac0a46fSAndroid Build Coastguard Worker 
2509*3ac0a46fSAndroid Build Coastguard Worker      hIT8 = cmsIT8Alloc(ContextID);
2510*3ac0a46fSAndroid Build Coastguard Worker      it8 = (cmsIT8*) hIT8;
2511*3ac0a46fSAndroid Build Coastguard Worker      if (!hIT8) return NULL;
2512*3ac0a46fSAndroid Build Coastguard Worker 
2513*3ac0a46fSAndroid Build Coastguard Worker 
2514*3ac0a46fSAndroid Build Coastguard Worker      it8 ->FileStack[0]->Stream = fopen(cFileName, "rt");
2515*3ac0a46fSAndroid Build Coastguard Worker 
2516*3ac0a46fSAndroid Build Coastguard Worker      if (!it8 ->FileStack[0]->Stream) {
2517*3ac0a46fSAndroid Build Coastguard Worker          cmsIT8Free(hIT8);
2518*3ac0a46fSAndroid Build Coastguard Worker          return NULL;
2519*3ac0a46fSAndroid Build Coastguard Worker      }
2520*3ac0a46fSAndroid Build Coastguard Worker 
2521*3ac0a46fSAndroid Build Coastguard Worker 
2522*3ac0a46fSAndroid Build Coastguard Worker     strncpy(it8->FileStack[0]->FileName, cFileName, cmsMAX_PATH-1);
2523*3ac0a46fSAndroid Build Coastguard Worker     it8->FileStack[0]->FileName[cmsMAX_PATH-1] = 0;
2524*3ac0a46fSAndroid Build Coastguard Worker 
2525*3ac0a46fSAndroid Build Coastguard Worker     if (!ParseIT8(it8, type-1)) {
2526*3ac0a46fSAndroid Build Coastguard Worker 
2527*3ac0a46fSAndroid Build Coastguard Worker             fclose(it8 ->FileStack[0]->Stream);
2528*3ac0a46fSAndroid Build Coastguard Worker             cmsIT8Free(hIT8);
2529*3ac0a46fSAndroid Build Coastguard Worker             return NULL;
2530*3ac0a46fSAndroid Build Coastguard Worker     }
2531*3ac0a46fSAndroid Build Coastguard Worker 
2532*3ac0a46fSAndroid Build Coastguard Worker     CookPointers(it8);
2533*3ac0a46fSAndroid Build Coastguard Worker     it8 ->nTable = 0;
2534*3ac0a46fSAndroid Build Coastguard Worker 
2535*3ac0a46fSAndroid Build Coastguard Worker     if (fclose(it8 ->FileStack[0]->Stream)!= 0) {
2536*3ac0a46fSAndroid Build Coastguard Worker             cmsIT8Free(hIT8);
2537*3ac0a46fSAndroid Build Coastguard Worker             return NULL;
2538*3ac0a46fSAndroid Build Coastguard Worker     }
2539*3ac0a46fSAndroid Build Coastguard Worker 
2540*3ac0a46fSAndroid Build Coastguard Worker     return hIT8;
2541*3ac0a46fSAndroid Build Coastguard Worker 
2542*3ac0a46fSAndroid Build Coastguard Worker }
2543*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8EnumDataFormat(cmsHANDLE hIT8,char *** SampleNames)2544*3ac0a46fSAndroid Build Coastguard Worker int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames)
2545*3ac0a46fSAndroid Build Coastguard Worker {
2546*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2547*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
2548*3ac0a46fSAndroid Build Coastguard Worker 
2549*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2550*3ac0a46fSAndroid Build Coastguard Worker 
2551*3ac0a46fSAndroid Build Coastguard Worker     t = GetTable(it8);
2552*3ac0a46fSAndroid Build Coastguard Worker 
2553*3ac0a46fSAndroid Build Coastguard Worker     if (SampleNames)
2554*3ac0a46fSAndroid Build Coastguard Worker         *SampleNames = t -> DataFormat;
2555*3ac0a46fSAndroid Build Coastguard Worker     return t -> nSamples;
2556*3ac0a46fSAndroid Build Coastguard Worker }
2557*3ac0a46fSAndroid Build Coastguard Worker 
2558*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8EnumProperties(cmsHANDLE hIT8,char *** PropertyNames)2559*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames)
2560*3ac0a46fSAndroid Build Coastguard Worker {
2561*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2562*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE* p;
2563*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number n;
2564*3ac0a46fSAndroid Build Coastguard Worker     char **Props;
2565*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
2566*3ac0a46fSAndroid Build Coastguard Worker 
2567*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2568*3ac0a46fSAndroid Build Coastguard Worker 
2569*3ac0a46fSAndroid Build Coastguard Worker     t = GetTable(it8);
2570*3ac0a46fSAndroid Build Coastguard Worker 
2571*3ac0a46fSAndroid Build Coastguard Worker     // Pass#1 - count properties
2572*3ac0a46fSAndroid Build Coastguard Worker 
2573*3ac0a46fSAndroid Build Coastguard Worker     n = 0;
2574*3ac0a46fSAndroid Build Coastguard Worker     for (p = t -> HeaderList;  p != NULL; p = p->Next) {
2575*3ac0a46fSAndroid Build Coastguard Worker         n++;
2576*3ac0a46fSAndroid Build Coastguard Worker     }
2577*3ac0a46fSAndroid Build Coastguard Worker 
2578*3ac0a46fSAndroid Build Coastguard Worker 
2579*3ac0a46fSAndroid Build Coastguard Worker 	Props = (char**)AllocChunk(it8, sizeof(char*) * n);
2580*3ac0a46fSAndroid Build Coastguard Worker 	if (Props != NULL) {
2581*3ac0a46fSAndroid Build Coastguard Worker 
2582*3ac0a46fSAndroid Build Coastguard Worker 		// Pass#2 - Fill pointers
2583*3ac0a46fSAndroid Build Coastguard Worker 		n = 0;
2584*3ac0a46fSAndroid Build Coastguard Worker 		for (p = t->HeaderList; p != NULL; p = p->Next) {
2585*3ac0a46fSAndroid Build Coastguard Worker 			Props[n++] = p->Keyword;
2586*3ac0a46fSAndroid Build Coastguard Worker 		}
2587*3ac0a46fSAndroid Build Coastguard Worker 
2588*3ac0a46fSAndroid Build Coastguard Worker 	}
2589*3ac0a46fSAndroid Build Coastguard Worker 	*PropertyNames = Props;
2590*3ac0a46fSAndroid Build Coastguard Worker 
2591*3ac0a46fSAndroid Build Coastguard Worker     return n;
2592*3ac0a46fSAndroid Build Coastguard Worker }
2593*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8EnumPropertyMulti(cmsHANDLE hIT8,const char * cProp,const char *** SubpropertyNames)2594*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames)
2595*3ac0a46fSAndroid Build Coastguard Worker {
2596*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2597*3ac0a46fSAndroid Build Coastguard Worker     KEYVALUE *p, *tmp;
2598*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number n;
2599*3ac0a46fSAndroid Build Coastguard Worker     const char **Props;
2600*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
2601*3ac0a46fSAndroid Build Coastguard Worker 
2602*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2603*3ac0a46fSAndroid Build Coastguard Worker 
2604*3ac0a46fSAndroid Build Coastguard Worker 
2605*3ac0a46fSAndroid Build Coastguard Worker     t = GetTable(it8);
2606*3ac0a46fSAndroid Build Coastguard Worker 
2607*3ac0a46fSAndroid Build Coastguard Worker     if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) {
2608*3ac0a46fSAndroid Build Coastguard Worker         *SubpropertyNames = 0;
2609*3ac0a46fSAndroid Build Coastguard Worker         return 0;
2610*3ac0a46fSAndroid Build Coastguard Worker     }
2611*3ac0a46fSAndroid Build Coastguard Worker 
2612*3ac0a46fSAndroid Build Coastguard Worker     // Pass#1 - count properties
2613*3ac0a46fSAndroid Build Coastguard Worker 
2614*3ac0a46fSAndroid Build Coastguard Worker     n = 0;
2615*3ac0a46fSAndroid Build Coastguard Worker     for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
2616*3ac0a46fSAndroid Build Coastguard Worker         if(tmp->Subkey != NULL)
2617*3ac0a46fSAndroid Build Coastguard Worker             n++;
2618*3ac0a46fSAndroid Build Coastguard Worker     }
2619*3ac0a46fSAndroid Build Coastguard Worker 
2620*3ac0a46fSAndroid Build Coastguard Worker 
2621*3ac0a46fSAndroid Build Coastguard Worker     Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
2622*3ac0a46fSAndroid Build Coastguard Worker     if (Props != NULL) {
2623*3ac0a46fSAndroid Build Coastguard Worker 
2624*3ac0a46fSAndroid Build Coastguard Worker         // Pass#2 - Fill pointers
2625*3ac0a46fSAndroid Build Coastguard Worker         n = 0;
2626*3ac0a46fSAndroid Build Coastguard Worker         for (tmp = p; tmp != NULL; tmp = tmp->NextSubkey) {
2627*3ac0a46fSAndroid Build Coastguard Worker             if (tmp->Subkey != NULL)
2628*3ac0a46fSAndroid Build Coastguard Worker                 Props[n++] = p->Subkey;
2629*3ac0a46fSAndroid Build Coastguard Worker         }
2630*3ac0a46fSAndroid Build Coastguard Worker     }
2631*3ac0a46fSAndroid Build Coastguard Worker 
2632*3ac0a46fSAndroid Build Coastguard Worker     *SubpropertyNames = Props;
2633*3ac0a46fSAndroid Build Coastguard Worker     return n;
2634*3ac0a46fSAndroid Build Coastguard Worker }
2635*3ac0a46fSAndroid Build Coastguard Worker 
2636*3ac0a46fSAndroid Build Coastguard Worker static
LocatePatch(cmsIT8 * it8,const char * cPatch)2637*3ac0a46fSAndroid Build Coastguard Worker int LocatePatch(cmsIT8* it8, const char* cPatch)
2638*3ac0a46fSAndroid Build Coastguard Worker {
2639*3ac0a46fSAndroid Build Coastguard Worker     int i;
2640*3ac0a46fSAndroid Build Coastguard Worker     const char *data;
2641*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
2642*3ac0a46fSAndroid Build Coastguard Worker 
2643*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < t-> nPatches; i++) {
2644*3ac0a46fSAndroid Build Coastguard Worker 
2645*3ac0a46fSAndroid Build Coastguard Worker         data = GetData(it8, i, t->SampleID);
2646*3ac0a46fSAndroid Build Coastguard Worker 
2647*3ac0a46fSAndroid Build Coastguard Worker         if (data != NULL) {
2648*3ac0a46fSAndroid Build Coastguard Worker 
2649*3ac0a46fSAndroid Build Coastguard Worker                 if (cmsstrcasecmp(data, cPatch) == 0)
2650*3ac0a46fSAndroid Build Coastguard Worker                         return i;
2651*3ac0a46fSAndroid Build Coastguard Worker                 }
2652*3ac0a46fSAndroid Build Coastguard Worker         }
2653*3ac0a46fSAndroid Build Coastguard Worker 
2654*3ac0a46fSAndroid Build Coastguard Worker         // SynError(it8, "Couldn't find patch '%s'\n", cPatch);
2655*3ac0a46fSAndroid Build Coastguard Worker         return -1;
2656*3ac0a46fSAndroid Build Coastguard Worker }
2657*3ac0a46fSAndroid Build Coastguard Worker 
2658*3ac0a46fSAndroid Build Coastguard Worker 
2659*3ac0a46fSAndroid Build Coastguard Worker static
LocateEmptyPatch(cmsIT8 * it8)2660*3ac0a46fSAndroid Build Coastguard Worker int LocateEmptyPatch(cmsIT8* it8)
2661*3ac0a46fSAndroid Build Coastguard Worker {
2662*3ac0a46fSAndroid Build Coastguard Worker     int i;
2663*3ac0a46fSAndroid Build Coastguard Worker     const char *data;
2664*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
2665*3ac0a46fSAndroid Build Coastguard Worker 
2666*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < t-> nPatches; i++) {
2667*3ac0a46fSAndroid Build Coastguard Worker 
2668*3ac0a46fSAndroid Build Coastguard Worker         data = GetData(it8, i, t->SampleID);
2669*3ac0a46fSAndroid Build Coastguard Worker 
2670*3ac0a46fSAndroid Build Coastguard Worker         if (data == NULL)
2671*3ac0a46fSAndroid Build Coastguard Worker             return i;
2672*3ac0a46fSAndroid Build Coastguard Worker 
2673*3ac0a46fSAndroid Build Coastguard Worker     }
2674*3ac0a46fSAndroid Build Coastguard Worker 
2675*3ac0a46fSAndroid Build Coastguard Worker     return -1;
2676*3ac0a46fSAndroid Build Coastguard Worker }
2677*3ac0a46fSAndroid Build Coastguard Worker 
2678*3ac0a46fSAndroid Build Coastguard Worker static
LocateSample(cmsIT8 * it8,const char * cSample)2679*3ac0a46fSAndroid Build Coastguard Worker int LocateSample(cmsIT8* it8, const char* cSample)
2680*3ac0a46fSAndroid Build Coastguard Worker {
2681*3ac0a46fSAndroid Build Coastguard Worker     int i;
2682*3ac0a46fSAndroid Build Coastguard Worker     const char *fld;
2683*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t = GetTable(it8);
2684*3ac0a46fSAndroid Build Coastguard Worker 
2685*3ac0a46fSAndroid Build Coastguard Worker     for (i=0; i < t->nSamples; i++) {
2686*3ac0a46fSAndroid Build Coastguard Worker 
2687*3ac0a46fSAndroid Build Coastguard Worker         fld = GetDataFormat(it8, i);
2688*3ac0a46fSAndroid Build Coastguard Worker         if (fld != NULL) {
2689*3ac0a46fSAndroid Build Coastguard Worker             if (cmsstrcasecmp(fld, cSample) == 0)
2690*3ac0a46fSAndroid Build Coastguard Worker                 return i;
2691*3ac0a46fSAndroid Build Coastguard Worker         }
2692*3ac0a46fSAndroid Build Coastguard Worker     }
2693*3ac0a46fSAndroid Build Coastguard Worker 
2694*3ac0a46fSAndroid Build Coastguard Worker     return -1;
2695*3ac0a46fSAndroid Build Coastguard Worker 
2696*3ac0a46fSAndroid Build Coastguard Worker }
2697*3ac0a46fSAndroid Build Coastguard Worker 
2698*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8FindDataFormat(cmsHANDLE hIT8,const char * cSample)2699*3ac0a46fSAndroid Build Coastguard Worker int CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample)
2700*3ac0a46fSAndroid Build Coastguard Worker {
2701*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2702*3ac0a46fSAndroid Build Coastguard Worker 
2703*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2704*3ac0a46fSAndroid Build Coastguard Worker 
2705*3ac0a46fSAndroid Build Coastguard Worker     return LocateSample(it8, cSample);
2706*3ac0a46fSAndroid Build Coastguard Worker }
2707*3ac0a46fSAndroid Build Coastguard Worker 
2708*3ac0a46fSAndroid Build Coastguard Worker 
2709*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetDataRowCol(cmsHANDLE hIT8,int row,int col)2710*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col)
2711*3ac0a46fSAndroid Build Coastguard Worker {
2712*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2713*3ac0a46fSAndroid Build Coastguard Worker 
2714*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2715*3ac0a46fSAndroid Build Coastguard Worker 
2716*3ac0a46fSAndroid Build Coastguard Worker     return GetData(it8, row, col);
2717*3ac0a46fSAndroid Build Coastguard Worker }
2718*3ac0a46fSAndroid Build Coastguard Worker 
2719*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetDataRowColDbl(cmsHANDLE hIT8,int row,int col)2720*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsIT8GetDataRowColDbl(cmsHANDLE hIT8, int row, int col)
2721*3ac0a46fSAndroid Build Coastguard Worker {
2722*3ac0a46fSAndroid Build Coastguard Worker     const char* Buffer;
2723*3ac0a46fSAndroid Build Coastguard Worker 
2724*3ac0a46fSAndroid Build Coastguard Worker     Buffer = cmsIT8GetDataRowCol(hIT8, row, col);
2725*3ac0a46fSAndroid Build Coastguard Worker 
2726*3ac0a46fSAndroid Build Coastguard Worker     if (Buffer == NULL) return 0.0;
2727*3ac0a46fSAndroid Build Coastguard Worker 
2728*3ac0a46fSAndroid Build Coastguard Worker     return ParseFloatNumber(Buffer);
2729*3ac0a46fSAndroid Build Coastguard Worker }
2730*3ac0a46fSAndroid Build Coastguard Worker 
2731*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetDataRowCol(cmsHANDLE hIT8,int row,int col,const char * Val)2732*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetDataRowCol(cmsHANDLE hIT8, int row, int col, const char* Val)
2733*3ac0a46fSAndroid Build Coastguard Worker {
2734*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2735*3ac0a46fSAndroid Build Coastguard Worker 
2736*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2737*3ac0a46fSAndroid Build Coastguard Worker 
2738*3ac0a46fSAndroid Build Coastguard Worker     return SetData(it8, row, col, Val);
2739*3ac0a46fSAndroid Build Coastguard Worker }
2740*3ac0a46fSAndroid Build Coastguard Worker 
2741*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetDataRowColDbl(cmsHANDLE hIT8,int row,int col,cmsFloat64Number Val)2742*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFloat64Number Val)
2743*3ac0a46fSAndroid Build Coastguard Worker {
2744*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2745*3ac0a46fSAndroid Build Coastguard Worker     char Buff[256];
2746*3ac0a46fSAndroid Build Coastguard Worker 
2747*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2748*3ac0a46fSAndroid Build Coastguard Worker 
2749*3ac0a46fSAndroid Build Coastguard Worker     snprintf(Buff, 255, it8->DoubleFormatter, Val);
2750*3ac0a46fSAndroid Build Coastguard Worker 
2751*3ac0a46fSAndroid Build Coastguard Worker     return SetData(it8, row, col, Buff);
2752*3ac0a46fSAndroid Build Coastguard Worker }
2753*3ac0a46fSAndroid Build Coastguard Worker 
2754*3ac0a46fSAndroid Build Coastguard Worker 
2755*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetData(cmsHANDLE hIT8,const char * cPatch,const char * cSample)2756*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample)
2757*3ac0a46fSAndroid Build Coastguard Worker {
2758*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2759*3ac0a46fSAndroid Build Coastguard Worker     int iField, iSet;
2760*3ac0a46fSAndroid Build Coastguard Worker 
2761*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2762*3ac0a46fSAndroid Build Coastguard Worker 
2763*3ac0a46fSAndroid Build Coastguard Worker     iField = LocateSample(it8, cSample);
2764*3ac0a46fSAndroid Build Coastguard Worker     if (iField < 0) {
2765*3ac0a46fSAndroid Build Coastguard Worker         return NULL;
2766*3ac0a46fSAndroid Build Coastguard Worker     }
2767*3ac0a46fSAndroid Build Coastguard Worker 
2768*3ac0a46fSAndroid Build Coastguard Worker     iSet = LocatePatch(it8, cPatch);
2769*3ac0a46fSAndroid Build Coastguard Worker     if (iSet < 0) {
2770*3ac0a46fSAndroid Build Coastguard Worker             return NULL;
2771*3ac0a46fSAndroid Build Coastguard Worker     }
2772*3ac0a46fSAndroid Build Coastguard Worker 
2773*3ac0a46fSAndroid Build Coastguard Worker     return GetData(it8, iSet, iField);
2774*3ac0a46fSAndroid Build Coastguard Worker }
2775*3ac0a46fSAndroid Build Coastguard Worker 
2776*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetDataDbl(cmsHANDLE it8,const char * cPatch,const char * cSample)2777*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsIT8GetDataDbl(cmsHANDLE  it8, const char* cPatch, const char* cSample)
2778*3ac0a46fSAndroid Build Coastguard Worker {
2779*3ac0a46fSAndroid Build Coastguard Worker     const char* Buffer;
2780*3ac0a46fSAndroid Build Coastguard Worker 
2781*3ac0a46fSAndroid Build Coastguard Worker     Buffer = cmsIT8GetData(it8, cPatch, cSample);
2782*3ac0a46fSAndroid Build Coastguard Worker 
2783*3ac0a46fSAndroid Build Coastguard Worker     return ParseFloatNumber(Buffer);
2784*3ac0a46fSAndroid Build Coastguard Worker }
2785*3ac0a46fSAndroid Build Coastguard Worker 
2786*3ac0a46fSAndroid Build Coastguard Worker 
2787*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetData(cmsHANDLE hIT8,const char * cPatch,const char * cSample,const char * Val)2788*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample, const char *Val)
2789*3ac0a46fSAndroid Build Coastguard Worker {
2790*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2791*3ac0a46fSAndroid Build Coastguard Worker     int iField, iSet;
2792*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
2793*3ac0a46fSAndroid Build Coastguard Worker 
2794*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2795*3ac0a46fSAndroid Build Coastguard Worker 
2796*3ac0a46fSAndroid Build Coastguard Worker     t = GetTable(it8);
2797*3ac0a46fSAndroid Build Coastguard Worker 
2798*3ac0a46fSAndroid Build Coastguard Worker     iField = LocateSample(it8, cSample);
2799*3ac0a46fSAndroid Build Coastguard Worker 
2800*3ac0a46fSAndroid Build Coastguard Worker     if (iField < 0)
2801*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
2802*3ac0a46fSAndroid Build Coastguard Worker 
2803*3ac0a46fSAndroid Build Coastguard Worker     if (t-> nPatches == 0) {
2804*3ac0a46fSAndroid Build Coastguard Worker 
2805*3ac0a46fSAndroid Build Coastguard Worker         if (!AllocateDataFormat(it8))
2806*3ac0a46fSAndroid Build Coastguard Worker             return FALSE;
2807*3ac0a46fSAndroid Build Coastguard Worker 
2808*3ac0a46fSAndroid Build Coastguard Worker         if (!AllocateDataSet(it8))
2809*3ac0a46fSAndroid Build Coastguard Worker             return FALSE;
2810*3ac0a46fSAndroid Build Coastguard Worker 
2811*3ac0a46fSAndroid Build Coastguard Worker         CookPointers(it8);
2812*3ac0a46fSAndroid Build Coastguard Worker     }
2813*3ac0a46fSAndroid Build Coastguard Worker 
2814*3ac0a46fSAndroid Build Coastguard Worker     if (cmsstrcasecmp(cSample, "SAMPLE_ID") == 0) {
2815*3ac0a46fSAndroid Build Coastguard Worker 
2816*3ac0a46fSAndroid Build Coastguard Worker         iSet   = LocateEmptyPatch(it8);
2817*3ac0a46fSAndroid Build Coastguard Worker         if (iSet < 0) {
2818*3ac0a46fSAndroid Build Coastguard Worker             return SynError(it8, "Couldn't add more patches '%s'\n", cPatch);
2819*3ac0a46fSAndroid Build Coastguard Worker         }
2820*3ac0a46fSAndroid Build Coastguard Worker 
2821*3ac0a46fSAndroid Build Coastguard Worker         iField = t -> SampleID;
2822*3ac0a46fSAndroid Build Coastguard Worker     }
2823*3ac0a46fSAndroid Build Coastguard Worker     else {
2824*3ac0a46fSAndroid Build Coastguard Worker         iSet = LocatePatch(it8, cPatch);
2825*3ac0a46fSAndroid Build Coastguard Worker         if (iSet < 0) {
2826*3ac0a46fSAndroid Build Coastguard Worker             return FALSE;
2827*3ac0a46fSAndroid Build Coastguard Worker         }
2828*3ac0a46fSAndroid Build Coastguard Worker     }
2829*3ac0a46fSAndroid Build Coastguard Worker 
2830*3ac0a46fSAndroid Build Coastguard Worker     return SetData(it8, iSet, iField, Val);
2831*3ac0a46fSAndroid Build Coastguard Worker }
2832*3ac0a46fSAndroid Build Coastguard Worker 
2833*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetDataDbl(cmsHANDLE hIT8,const char * cPatch,const char * cSample,cmsFloat64Number Val)2834*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetDataDbl(cmsHANDLE hIT8, const char* cPatch,
2835*3ac0a46fSAndroid Build Coastguard Worker                                    const char* cSample,
2836*3ac0a46fSAndroid Build Coastguard Worker                                    cmsFloat64Number Val)
2837*3ac0a46fSAndroid Build Coastguard Worker {
2838*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2839*3ac0a46fSAndroid Build Coastguard Worker     char Buff[256];
2840*3ac0a46fSAndroid Build Coastguard Worker 
2841*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2842*3ac0a46fSAndroid Build Coastguard Worker 
2843*3ac0a46fSAndroid Build Coastguard Worker     snprintf(Buff, 255, it8->DoubleFormatter, Val);
2844*3ac0a46fSAndroid Build Coastguard Worker     return cmsIT8SetData(hIT8, cPatch, cSample, Buff);
2845*3ac0a46fSAndroid Build Coastguard Worker }
2846*3ac0a46fSAndroid Build Coastguard Worker 
2847*3ac0a46fSAndroid Build Coastguard Worker // Buffer should get MAXSTR at least
2848*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetPatchName(cmsHANDLE hIT8,int nPatch,char * buffer)2849*3ac0a46fSAndroid Build Coastguard Worker const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer)
2850*3ac0a46fSAndroid Build Coastguard Worker {
2851*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2852*3ac0a46fSAndroid Build Coastguard Worker     TABLE* t;
2853*3ac0a46fSAndroid Build Coastguard Worker     char* Data;
2854*3ac0a46fSAndroid Build Coastguard Worker 
2855*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2856*3ac0a46fSAndroid Build Coastguard Worker 
2857*3ac0a46fSAndroid Build Coastguard Worker     t = GetTable(it8);
2858*3ac0a46fSAndroid Build Coastguard Worker     Data = GetData(it8, nPatch, t->SampleID);
2859*3ac0a46fSAndroid Build Coastguard Worker 
2860*3ac0a46fSAndroid Build Coastguard Worker     if (!Data) return NULL;
2861*3ac0a46fSAndroid Build Coastguard Worker     if (!buffer) return Data;
2862*3ac0a46fSAndroid Build Coastguard Worker 
2863*3ac0a46fSAndroid Build Coastguard Worker     strncpy(buffer, Data, MAXSTR-1);
2864*3ac0a46fSAndroid Build Coastguard Worker     buffer[MAXSTR-1] = 0;
2865*3ac0a46fSAndroid Build Coastguard Worker     return buffer;
2866*3ac0a46fSAndroid Build Coastguard Worker }
2867*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8GetPatchByName(cmsHANDLE hIT8,const char * cPatch)2868*3ac0a46fSAndroid Build Coastguard Worker int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch)
2869*3ac0a46fSAndroid Build Coastguard Worker {
2870*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2871*3ac0a46fSAndroid Build Coastguard Worker 
2872*3ac0a46fSAndroid Build Coastguard Worker     return LocatePatch((cmsIT8*)hIT8, cPatch);
2873*3ac0a46fSAndroid Build Coastguard Worker }
2874*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8TableCount(cmsHANDLE hIT8)2875*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8)
2876*3ac0a46fSAndroid Build Coastguard Worker {
2877*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2878*3ac0a46fSAndroid Build Coastguard Worker 
2879*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2880*3ac0a46fSAndroid Build Coastguard Worker 
2881*3ac0a46fSAndroid Build Coastguard Worker     return it8 ->TablesCount;
2882*3ac0a46fSAndroid Build Coastguard Worker }
2883*3ac0a46fSAndroid Build Coastguard Worker 
2884*3ac0a46fSAndroid Build Coastguard Worker // This handles the "LABEL" extension.
2885*3ac0a46fSAndroid Build Coastguard Worker // Label, nTable, Type
2886*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetTableByLabel(cmsHANDLE hIT8,const char * cSet,const char * cField,const char * ExpectedType)2887*3ac0a46fSAndroid Build Coastguard Worker int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType)
2888*3ac0a46fSAndroid Build Coastguard Worker {
2889*3ac0a46fSAndroid Build Coastguard Worker     const char* cLabelFld;
2890*3ac0a46fSAndroid Build Coastguard Worker     char Type[256], Label[256];
2891*3ac0a46fSAndroid Build Coastguard Worker     cmsUInt32Number nTable;
2892*3ac0a46fSAndroid Build Coastguard Worker 
2893*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2894*3ac0a46fSAndroid Build Coastguard Worker 
2895*3ac0a46fSAndroid Build Coastguard Worker     if (cField != NULL && *cField == 0)
2896*3ac0a46fSAndroid Build Coastguard Worker             cField = "LABEL";
2897*3ac0a46fSAndroid Build Coastguard Worker 
2898*3ac0a46fSAndroid Build Coastguard Worker     if (cField == NULL)
2899*3ac0a46fSAndroid Build Coastguard Worker             cField = "LABEL";
2900*3ac0a46fSAndroid Build Coastguard Worker 
2901*3ac0a46fSAndroid Build Coastguard Worker     cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
2902*3ac0a46fSAndroid Build Coastguard Worker     if (!cLabelFld) return -1;
2903*3ac0a46fSAndroid Build Coastguard Worker 
2904*3ac0a46fSAndroid Build Coastguard Worker     if (sscanf(cLabelFld, "%255s %u %255s", Label, &nTable, Type) != 3)
2905*3ac0a46fSAndroid Build Coastguard Worker             return -1;
2906*3ac0a46fSAndroid Build Coastguard Worker 
2907*3ac0a46fSAndroid Build Coastguard Worker     if (ExpectedType != NULL && *ExpectedType == 0)
2908*3ac0a46fSAndroid Build Coastguard Worker         ExpectedType = NULL;
2909*3ac0a46fSAndroid Build Coastguard Worker 
2910*3ac0a46fSAndroid Build Coastguard Worker     if (ExpectedType) {
2911*3ac0a46fSAndroid Build Coastguard Worker 
2912*3ac0a46fSAndroid Build Coastguard Worker         if (cmsstrcasecmp(Type, ExpectedType) != 0) return -1;
2913*3ac0a46fSAndroid Build Coastguard Worker     }
2914*3ac0a46fSAndroid Build Coastguard Worker 
2915*3ac0a46fSAndroid Build Coastguard Worker     return cmsIT8SetTable(hIT8, nTable);
2916*3ac0a46fSAndroid Build Coastguard Worker }
2917*3ac0a46fSAndroid Build Coastguard Worker 
2918*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8SetIndexColumn(cmsHANDLE hIT8,const char * cSample)2919*3ac0a46fSAndroid Build Coastguard Worker cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample)
2920*3ac0a46fSAndroid Build Coastguard Worker {
2921*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2922*3ac0a46fSAndroid Build Coastguard Worker     int pos;
2923*3ac0a46fSAndroid Build Coastguard Worker 
2924*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2925*3ac0a46fSAndroid Build Coastguard Worker 
2926*3ac0a46fSAndroid Build Coastguard Worker     pos = LocateSample(it8, cSample);
2927*3ac0a46fSAndroid Build Coastguard Worker     if(pos == -1)
2928*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
2929*3ac0a46fSAndroid Build Coastguard Worker 
2930*3ac0a46fSAndroid Build Coastguard Worker     it8->Tab[it8->nTable].SampleID = pos;
2931*3ac0a46fSAndroid Build Coastguard Worker     return TRUE;
2932*3ac0a46fSAndroid Build Coastguard Worker }
2933*3ac0a46fSAndroid Build Coastguard Worker 
2934*3ac0a46fSAndroid Build Coastguard Worker 
cmsIT8DefineDblFormat(cmsHANDLE hIT8,const char * Formatter)2935*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter)
2936*3ac0a46fSAndroid Build Coastguard Worker {
2937*3ac0a46fSAndroid Build Coastguard Worker     cmsIT8* it8 = (cmsIT8*) hIT8;
2938*3ac0a46fSAndroid Build Coastguard Worker 
2939*3ac0a46fSAndroid Build Coastguard Worker     _cmsAssert(hIT8 != NULL);
2940*3ac0a46fSAndroid Build Coastguard Worker 
2941*3ac0a46fSAndroid Build Coastguard Worker     if (Formatter == NULL)
2942*3ac0a46fSAndroid Build Coastguard Worker         strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
2943*3ac0a46fSAndroid Build Coastguard Worker     else
2944*3ac0a46fSAndroid Build Coastguard Worker         strncpy(it8->DoubleFormatter, Formatter, sizeof(it8->DoubleFormatter));
2945*3ac0a46fSAndroid Build Coastguard Worker 
2946*3ac0a46fSAndroid Build Coastguard Worker     it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
2947*3ac0a46fSAndroid Build Coastguard Worker }
2948*3ac0a46fSAndroid Build Coastguard Worker 
2949