13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 // This file is available under and governed by the GNU General Public
26 // License version 2 only, as published by the Free Software Foundation.
27 // However, the following notice accompanied the original version of this
28 // file:
29 //
30 //---------------------------------------------------------------------------------
31 //
32 // Little Color Management System
33 // Copyright (c) 1998-2017 Marti Maria Saguer
34 //
35 // Permission is hereby granted, free of charge, to any person obtaining
36 // a copy of this software and associated documentation files (the "Software"),
37 // to deal in the Software without restriction, including without limitation
38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
39 // and/or sell copies of the Software, and to permit persons to whom the Software
40 // is furnished to do so, subject to the following conditions:
41 //
42 // The above copyright notice and this permission notice shall be included in
43 // all copies or substantial portions of the Software.
44 //
45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 //
53 //---------------------------------------------------------------------------------
141
142 } SUBALLOCATOR;
143
144 // Table. Each individual table can hold properties and rows & cols
145 typedef struct _Table {
146
147 char SheetType[MAXSTR]; // The first row of the IT8 (the type)
148
149 int nSamples, nPatches; // Cols, Rows
150 int SampleID; // Pos of ID
151
152 KEYVALUE* HeaderList; // The properties
153
154 char** DataFormat; // The binary stream descriptor
155 char** Data; // The binary stream
156
157 } TABLE;
158
159 // File stream being parsed
160 typedef struct _FileContext {
161 char FileName[cmsMAX_PATH]; // File name if being readed from file
162 FILE* Stream; // File stream or NULL if holded in memory
163 } FILECTX;
164
165 // This struct hold all information about an open IT8 handler.
166 typedef struct {
167
168
169 cmsUInt32Number TablesCount; // How many tables in this stream
170 cmsUInt32Number nTable; // The actual table
171
172 TABLE Tab[MAXTABLES];
173
174 // Memory management
175 OWNEDMEM* MemorySink; // The storage backend
176 SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast
177
178 // Parser state machine
179 SYMBOL sy; // Current symbol
180 int ch; // Current character
181
268
269 {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code
270 // uniquely identifying th e material. This is intend ed to be used for IT8.7
271 // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
272
273 {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and
274 // model number) to generate the data reported. This data will often
275 // provide more information about the particular data collected than an
276 // extensive list of specific details. This is particularly important for
277 // spectral data or data derived from spectrophotometry.
278
279 {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
280 // a guide to the potential for issues of paper fluorescence, etc.
281
282 {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported.
283 // Where standard conditions have been defined (e.g., SWOP at nominal)
284 // named conditions may suffice. Otherwise, detailed information is
285 // needed.
286
287 {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during
288 // measurement. Allowed values are “black”, “white”, or {"na".
289
290 {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic
291 // below properties are new in recent specs:
292
293 {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
294 // along with details of the geometry and the aperture size and shape. For example,
295 // for transmission measurements it is important to identify 0/diffuse, diffuse/0,
296 // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
297 // 45/0, sphere (specular included or excluded), etc.
298
299 {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to
300 // denote the use of filters such as none, D65, Red, Green or Blue.
301
302 {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed
303 // values are {"yes”, “white”, “none” or “na”.
304
305 {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the
306 // calculation of various data parameters (2 degree and 10 degree), CIE standard
307 // illuminant functions used in the calculation of various data parameters (e.g., D50,
308 // D65, etc.), density status response, etc. If used there shall be at least one
309 // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
310 // in the set shall be {"name" and shall identify the particular parameter used.
311 // The second shall be {"value" and shall provide the value associated with that name.
312 // For ASCII data, a string containing the Name and Value attribute pairs shall follow
313 // the weighting function keyword. A semi-colon separates attribute pairs from each
314 // other and within the attribute the name and value are separated by a comma.
315
316 {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
317 // of the calculation, parameter is the name of the parameter used in the calculation
318 // and value is the value of the parameter.
319
320 {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
321
322 {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target.
323
695 cmsInt32Number digit = (*Buffer - '0');
696
697 if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0)
698 e = e * 10 + digit;
699
700 if (*Buffer) Buffer++;
701 }
702
703 e = sgn*e;
704 dnum = dnum * xpow10(e);
705 }
706
707 return sign * dnum;
708 }
709
710
711 // Reads next symbol
712 static
713 void InSymbol(cmsIT8* it8)
714 {
715 register char *idptr;
716 register int k;
717 SYMBOL key;
718 int sng;
719
720 do {
721
722 while (isseparator(it8->ch))
723 NextCh(it8);
724
725 if (isfirstidchar(it8->ch)) { // Identifier
726
727 k = 0;
728 idptr = it8->id;
729
730 do {
731
732 if (++k < MAXID) *idptr++ = (char) it8->ch;
733
734 NextCh(it8);
735
736 } while (isidchar(it8->ch));
2178
2179 TABLE* t = it8 ->Tab + j;
2180
2181 t -> SampleID = 0;
2182 it8 ->nTable = j;
2183
2184 for (idField = 0; idField < t -> nSamples; idField++)
2185 {
2186 if (t ->DataFormat == NULL){
2187 SynError(it8, "Undefined DATA_FORMAT");
2188 return;
2189 }
2190
2191 Fld = t->DataFormat[idField];
2192 if (!Fld) continue;
2193
2194
2195 if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
2196
2197 t -> SampleID = idField;
2198
2199 for (i=0; i < t -> nPatches; i++) {
2200
2201 char *Data = GetData(it8, i, idField);
2202 if (Data) {
2203 char Buffer[256];
2204
2205 strncpy(Buffer, Data, 255);
2206 Buffer[255] = 0;
2207
2208 if (strlen(Buffer) <= strlen(Data))
2209 strcpy(Data, Buffer);
2210 else
2211 SetData(it8, i, idField, Buffer);
2212
2213 }
2214 }
2215
2216 }
2217
2218 // "LABEL" is an extension. It keeps references to forward tables
2219
2220 if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$' ) {
2221
2222 // Search for table references...
2223 for (i=0; i < t -> nPatches; i++) {
2224
2225 char *Label = GetData(it8, i, idField);
2226
2227 if (Label) {
2228
2229 cmsUInt32Number k;
2230
2231 // This is the label, search for a table containing
2232 // this property
2233
2234 for (k=0; k < it8 ->TablesCount; k++) {
2235
2236 TABLE* Table = it8 ->Tab + k;
2237 KEYVALUE* p;
2238
2239 if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
2240
2241 // Available, keep type and table
2242 char Buffer[256];
2243
2244 char *Type = p ->Value;
2245 int nTable = (int) k;
2246
2247 snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type );
2248
2249 SetData(it8, i, idField, Buffer);
2250 }
2251 }
2252
2253
2254 }
2255
2256 }
2257
2258
2259 }
2260
2261 }
2262 }
2263
2264 it8 ->nTable = nOldTable;
2265 }
2266
2267 // Try to infere if the file is a CGATS/IT8 file at all. Read first line
2332 // ---------------------------------------------------------- Exported routines
2333
2334
2335 cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
2336 {
2337 cmsHANDLE hIT8;
2338 cmsIT8* it8;
2339 int type;
2340
2341 _cmsAssert(Ptr != NULL);
2342 _cmsAssert(len != 0);
2343
2344 type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
2345 if (type == 0) return NULL;
2346
2347 hIT8 = cmsIT8Alloc(ContextID);
2348 if (!hIT8) return NULL;
2349
2350 it8 = (cmsIT8*) hIT8;
2351 it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
2352
2353 strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
2354 it8 ->MemoryBlock[len] = 0;
2355
2356 strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1);
2357 it8-> Source = it8 -> MemoryBlock;
2358
2359 if (!ParseIT8(it8, type-1)) {
2360
2361 cmsIT8Free(hIT8);
2362 return FALSE;
2363 }
2364
2365 CookPointers(it8);
2366 it8 ->nTable = 0;
2367
2368 _cmsFree(ContextID, it8->MemoryBlock);
2369 it8 -> MemoryBlock = NULL;
2370
2371 return hIT8;
|
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 // This file is available under and governed by the GNU General Public
26 // License version 2 only, as published by the Free Software Foundation.
27 // However, the following notice accompanied the original version of this
28 // file:
29 //
30 //---------------------------------------------------------------------------------
31 //
32 // Little Color Management System
33 // Copyright (c) 1998-2020 Marti Maria Saguer
34 //
35 // Permission is hereby granted, free of charge, to any person obtaining
36 // a copy of this software and associated documentation files (the "Software"),
37 // to deal in the Software without restriction, including without limitation
38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
39 // and/or sell copies of the Software, and to permit persons to whom the Software
40 // is furnished to do so, subject to the following conditions:
41 //
42 // The above copyright notice and this permission notice shall be included in
43 // all copies or substantial portions of the Software.
44 //
45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 //
53 //---------------------------------------------------------------------------------
141
142 } SUBALLOCATOR;
143
144 // Table. Each individual table can hold properties and rows & cols
145 typedef struct _Table {
146
147 char SheetType[MAXSTR]; // The first row of the IT8 (the type)
148
149 int nSamples, nPatches; // Cols, Rows
150 int SampleID; // Pos of ID
151
152 KEYVALUE* HeaderList; // The properties
153
154 char** DataFormat; // The binary stream descriptor
155 char** Data; // The binary stream
156
157 } TABLE;
158
159 // File stream being parsed
160 typedef struct _FileContext {
161 char FileName[cmsMAX_PATH]; // File name if being read from file
162 FILE* Stream; // File stream or NULL if holded in memory
163 } FILECTX;
164
165 // This struct hold all information about an open IT8 handler.
166 typedef struct {
167
168
169 cmsUInt32Number TablesCount; // How many tables in this stream
170 cmsUInt32Number nTable; // The actual table
171
172 TABLE Tab[MAXTABLES];
173
174 // Memory management
175 OWNEDMEM* MemorySink; // The storage backend
176 SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast
177
178 // Parser state machine
179 SYMBOL sy; // Current symbol
180 int ch; // Current character
181
268
269 {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code
270 // uniquely identifying th e material. This is intend ed to be used for IT8.7
271 // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
272
273 {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and
274 // model number) to generate the data reported. This data will often
275 // provide more information about the particular data collected than an
276 // extensive list of specific details. This is particularly important for
277 // spectral data or data derived from spectrophotometry.
278
279 {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
280 // a guide to the potential for issues of paper fluorescence, etc.
281
282 {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported.
283 // Where standard conditions have been defined (e.g., SWOP at nominal)
284 // named conditions may suffice. Otherwise, detailed information is
285 // needed.
286
287 {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during
288 // measurement. Allowed values are "black", "white", or {"na".
289
290 {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic
291 // below properties are new in recent specs:
292
293 {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
294 // along with details of the geometry and the aperture size and shape. For example,
295 // for transmission measurements it is important to identify 0/diffuse, diffuse/0,
296 // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
297 // 45/0, sphere (specular included or excluded), etc.
298
299 {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to
300 // denote the use of filters such as none, D65, Red, Green or Blue.
301
302 {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed
303 // values are {"yes", "white", "none" or "na".
304
305 {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the
306 // calculation of various data parameters (2 degree and 10 degree), CIE standard
307 // illuminant functions used in the calculation of various data parameters (e.g., D50,
308 // D65, etc.), density status response, etc. If used there shall be at least one
309 // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
310 // in the set shall be {"name" and shall identify the particular parameter used.
311 // The second shall be {"value" and shall provide the value associated with that name.
312 // For ASCII data, a string containing the Name and Value attribute pairs shall follow
313 // the weighting function keyword. A semi-colon separates attribute pairs from each
314 // other and within the attribute the name and value are separated by a comma.
315
316 {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
317 // of the calculation, parameter is the name of the parameter used in the calculation
318 // and value is the value of the parameter.
319
320 {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
321
322 {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target.
323
695 cmsInt32Number digit = (*Buffer - '0');
696
697 if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0)
698 e = e * 10 + digit;
699
700 if (*Buffer) Buffer++;
701 }
702
703 e = sgn*e;
704 dnum = dnum * xpow10(e);
705 }
706
707 return sign * dnum;
708 }
709
710
711 // Reads next symbol
712 static
713 void InSymbol(cmsIT8* it8)
714 {
715 CMSREGISTER char *idptr;
716 CMSREGISTER int k;
717 SYMBOL key;
718 int sng;
719
720 do {
721
722 while (isseparator(it8->ch))
723 NextCh(it8);
724
725 if (isfirstidchar(it8->ch)) { // Identifier
726
727 k = 0;
728 idptr = it8->id;
729
730 do {
731
732 if (++k < MAXID) *idptr++ = (char) it8->ch;
733
734 NextCh(it8);
735
736 } while (isidchar(it8->ch));
2178
2179 TABLE* t = it8 ->Tab + j;
2180
2181 t -> SampleID = 0;
2182 it8 ->nTable = j;
2183
2184 for (idField = 0; idField < t -> nSamples; idField++)
2185 {
2186 if (t ->DataFormat == NULL){
2187 SynError(it8, "Undefined DATA_FORMAT");
2188 return;
2189 }
2190
2191 Fld = t->DataFormat[idField];
2192 if (!Fld) continue;
2193
2194
2195 if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
2196
2197 t -> SampleID = idField;
2198 }
2199
2200 // "LABEL" is an extension. It keeps references to forward tables
2201
2202 if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
2203
2204 // Search for table references...
2205 for (i = 0; i < t->nPatches; i++) {
2206
2207 char* Label = GetData(it8, i, idField);
2208
2209 if (Label) {
2210
2211 cmsUInt32Number k;
2212
2213 // This is the label, search for a table containing
2214 // this property
2215
2216 for (k = 0; k < it8->TablesCount; k++) {
2217
2218 TABLE* Table = it8->Tab + k;
2219 KEYVALUE* p;
2220
2221 if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
2222
2223 // Available, keep type and table
2224 char Buffer[256];
2225
2226 char* Type = p->Value;
2227 int nTable = (int)k;
2228
2229 snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
2230
2231 SetData(it8, i, idField, Buffer);
2232 }
2233 }
2234
2235
2236 }
2237
2238 }
2239
2240
2241 }
2242
2243 }
2244 }
2245
2246 it8 ->nTable = nOldTable;
2247 }
2248
2249 // Try to infere if the file is a CGATS/IT8 file at all. Read first line
2314 // ---------------------------------------------------------- Exported routines
2315
2316
2317 cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
2318 {
2319 cmsHANDLE hIT8;
2320 cmsIT8* it8;
2321 int type;
2322
2323 _cmsAssert(Ptr != NULL);
2324 _cmsAssert(len != 0);
2325
2326 type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
2327 if (type == 0) return NULL;
2328
2329 hIT8 = cmsIT8Alloc(ContextID);
2330 if (!hIT8) return NULL;
2331
2332 it8 = (cmsIT8*) hIT8;
2333 it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
2334 if (it8->MemoryBlock == NULL)
2335 {
2336 cmsIT8Free(hIT8);
2337 return FALSE;
2338 }
2339
2340 strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
2341 it8 ->MemoryBlock[len] = 0;
2342
2343 strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1);
2344 it8-> Source = it8 -> MemoryBlock;
2345
2346 if (!ParseIT8(it8, type-1)) {
2347
2348 cmsIT8Free(hIT8);
2349 return FALSE;
2350 }
2351
2352 CookPointers(it8);
2353 it8 ->nTable = 0;
2354
2355 _cmsFree(ContextID, it8->MemoryBlock);
2356 it8 -> MemoryBlock = NULL;
2357
2358 return hIT8;
|