~ubuntu-branches/ubuntu/karmic/x11-xserver-utils/karmic

« back to all changes in this revision

Viewing changes to xcmsdb/loadData.c

  • Committer: Bazaar Package Importer
  • Author(s): Brice Goglin, Julien Cristau, Brice Goglin
  • Date: 2007-08-17 09:58:34 UTC
  • Revision ID: james.westby@ubuntu.com-20070817095834-ywge2nyzj1s3rqnd
Tags: 7.3+1
[ Julien Cristau ]
* iceauth 1.0.2.
  + removes blank line in the manpage (closes: #25285).
* xmodmap 1.0.3.
  + manpage updated to state that -pm is the default (closes: #236198)
* xgamma 1.0.2.
  + the manpage now explains how to print the gamma value more clearly
    (closes: #296021).
* xsetroot 1.0.2.
* xrdb 1.0.4.
  + fixes manpage typo (closes: #276286).
* Add upstream URL to debian/copyright, and update it from xgamma's COPYING
  file.

[ Brice Goglin ]
* Add menu entries for xrefresh and xvidtune.
* sessreg 1.0.3.
* xset 1.0.3.
* Add myself to Uploaders, and remove Branden with his permission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: loadData.c,v 1.4 2000/08/17 19:54:13 cpqbld Exp $ */
 
2
 
 
3
/*
 
4
 * (c) Copyright 1990 Tektronix Inc.
 
5
 *      All Rights Reserved
 
6
 *
 
7
 * Permission to use, copy, modify, and distribute this software and its
 
8
 * documentation for any purpose and without fee is hereby granted,
 
9
 * provided that the above copyright notice appear in all copies and that
 
10
 * both that copyright notice and this permission notice appear in
 
11
 * supporting documentation, and that the name of Tektronix not be used
 
12
 * in advertising or publicity pertaining to distribution of the software
 
13
 * without specific, written prior permission.
 
14
 *
 
15
 * Tektronix disclaims all warranties with regard to this software, including
 
16
 * all implied warranties of merchantability and fitness, in no event shall
 
17
 * Tektronix be liable for any special, indirect or consequential damages or
 
18
 * any damages whatsoever resulting from loss of use, data or profits,
 
19
 * whether in an action of contract, negligence or other tortious action,
 
20
 * arising out of or in connection with the use or performance of this
 
21
 * software.
 
22
 *
 
23
 *
 
24
 *      NAME
 
25
 *              LoadSCCData.c
 
26
 *
 
27
 *      DESCRIPTION
 
28
 *              TekCMS API routine that reads screen data from a file
 
29
 *              and then loads the data on the root window of the screen.
 
30
 *              
 
31
 *
 
32
 *
 
33
 */
 
34
/* $XFree86: xc/programs/xcmsdb/loadData.c,v 3.3 2001/07/25 15:05:18 dawes Exp $ */
 
35
 
 
36
/*
 
37
 *      INCLUDES
 
38
 */
 
39
 
 
40
#include <X11/Xos.h>
 
41
#include <sys/stat.h>
 
42
#include <stdio.h>
 
43
 
 
44
#include <X11/Xlib.h>
 
45
#include <X11/Xatom.h>
 
46
#include "SCCDFile.h"
 
47
 
 
48
 
 
49
/*
 
50
 *      EXTERNS
 
51
 *              External declarations required locally to this package
 
52
 *              that are not already declared in any of the included header
 
53
 *              files (external includes or internal includes).
 
54
 */
 
55
 
 
56
#include <stdlib.h>
 
57
 
 
58
/*
 
59
 *      LOCAL TYPEDEFS
 
60
 *              typedefs local to this package (for use with local vars).
 
61
 *
 
62
 */
 
63
 
 
64
typedef struct _DefineEntry {
 
65
    char        *pString;
 
66
    int         define;
 
67
} DefineEntry;
 
68
 
 
69
 
 
70
/*
 
71
 *      LOCAL VARIABLES
 
72
 */
 
73
static int linenum = 0;
 
74
 
 
75
static DefineEntry KeyTbl[] = {
 
76
    { SC_BEGIN_KEYWORD,                 SC_BEGIN },
 
77
    { SC_END_KEYWORD,                   SC_END },
 
78
    { COMMENT_KEYWORD,                  COMMENT },
 
79
    { NAME_KEYWORD,                     NAME },
 
80
    { MODEL_KEYWORD,                    MODEL },
 
81
    { PART_NUMBER_KEYWORD,              PART_NUMBER },
 
82
    { SERIAL_NUMBER_KEYWORD,            SERIAL_NUMBER },
 
83
    { REVISION_KEYWORD,                 REVISION },
 
84
    { SCREEN_CLASS_KEYWORD,             SCREEN_CLASS },
 
85
    { COLORIMETRIC_BEGIN_KEYWORD,       COLORIMETRIC_BEGIN },
 
86
    { COLORIMETRIC_END_KEYWORD,         COLORIMETRIC_END },
 
87
    { XYZTORGBMAT_BEGIN_KEYWORD,        XYZTORGBMAT_BEGIN },
 
88
    { XYZTORGBMAT_END_KEYWORD,          XYZTORGBMAT_END },
 
89
    { WHITEPT_XYZ_BEGIN_KEYWORD,        WHITEPT_XYZ_BEGIN },
 
90
    { WHITEPT_XYZ_END_KEYWORD,          WHITEPT_XYZ_END },
 
91
    { RGBTOXYZMAT_BEGIN_KEYWORD,        RGBTOXYZMAT_BEGIN },
 
92
    { RGBTOXYZMAT_END_KEYWORD,          RGBTOXYZMAT_END },
 
93
    { IPROFILE_BEGIN_KEYWORD,           IPROFILE_BEGIN },
 
94
    { IPROFILE_END_KEYWORD,             IPROFILE_END },
 
95
    { ITBL_BEGIN_KEYWORD,               ITBL_BEGIN },
 
96
    { ITBL_END_KEYWORD,                 ITBL_END },
 
97
    { "",                               -1 }
 
98
};
 
99
 
 
100
static DefineEntry ScrnClassTbl[] = {
 
101
    { VIDEO_RGB_KEYWORD,                VIDEO_RGB },
 
102
#ifdef GRAY
 
103
    { VIDEO_GRAY_KEYWORD,               VIDEO_GRAY },
 
104
#endif /* GRAY */
 
105
    { "",                               -1 }
 
106
};
 
107
 
 
108
#define KEY_VISUALID            1
 
109
#define KEY_DEPTH               2
 
110
#define KEY_CLASS               3
 
111
#define KEY_RED_MASK            4
 
112
#define KEY_GREEN_MASK          5
 
113
#define KEY_BLUE_MASK           6
 
114
#define KEY_COLORMAP_SIZE       7
 
115
#define KEY_BITS_PER_RGB        8
 
116
 
 
117
static DefineEntry VisualOptKeyTbl[] = {
 
118
    { "visualid",               KEY_VISUALID },
 
119
    { "depth",                  KEY_DEPTH },
 
120
    { "class",                  KEY_CLASS },
 
121
    { "red_mask",               KEY_RED_MASK },
 
122
    { "green_mask",             KEY_GREEN_MASK },
 
123
    { "blue_mask",              KEY_BLUE_MASK },
 
124
    { "colormap_size",          KEY_COLORMAP_SIZE },
 
125
    { "bits_per_rgb",           KEY_BITS_PER_RGB },
 
126
    { "",                               -1 }
 
127
};
 
128
static DefineEntry VisualClassTbl[] = {
 
129
    { "StaticGray",             StaticGray },
 
130
    { "GrayScale",              GrayScale },
 
131
    { "StaticColor",            StaticColor },
 
132
    { "PseudoColor",            PseudoColor },
 
133
    { "TrueColor",              TrueColor },
 
134
    { "DirectColor",            DirectColor },
 
135
    { "",                               -1 }
 
136
};
 
137
 
 
138
 
 
139
/************************************************************************
 
140
 *                                                                      *
 
141
 *                       PRIVATE ROUTINES                               *
 
142
 *                                                                      *
 
143
 ************************************************************************/
 
144
 
 
145
/*
 
146
 *      NAME
 
147
 *              StrToDefine - convert a string to a define
 
148
 *
 
149
 *      SYNOPSIS
 
150
 */
 
151
static int
 
152
StrToDefine(DefineEntry pde[],  /* IN: table of X string-define pairs     */
 
153
                                /*     last entry must contain pair "", 0 */
 
154
            char *pstring)      /* IN: string to be looked up in that table */
 
155
/*
 
156
 *      DESCRIPTION
 
157
 *              Converts a string to an integer define.
 
158
 *
 
159
 *              Looks up the string in the table and returns the integer
 
160
 *              associated with the string.
 
161
 *
 
162
 *              Later may need similar function for unsigned long define.
 
163
 *
 
164
 *
 
165
 *
 
166
 *      RETURNS
 
167
 *              The int equivalent of the defined string.
 
168
 *              -1 if the string is not found in table
 
169
 *
 
170
 */
 
171
{
 
172
    while( strcmp(pde->pString,"") != 0 ){
 
173
        if( strcmp(pde->pString,pstring) == 0){
 
174
            return(pde->define);
 
175
        }
 
176
        pde++;
 
177
    }
 
178
    return(-1);
 
179
}
 
180
 
 
181
/*
 
182
 *      NAME
 
183
 *              DefineToStr
 
184
 *
 
185
 *      SYNOPSIS
 
186
 */
 
187
static char *
 
188
DefineToStr(DefineEntry pde[],  /* IN: table of X string-define pairs */
 
189
                                /*     last entry must contain pair "", 0 */
 
190
            int id)             /* IN: id to be looked up in that table */
 
191
/*
 
192
 *      DESCRIPTION
 
193
 *              Converts a string to an integer define.
 
194
 *
 
195
 *              Looks up the string in the table and returns the integer
 
196
 *              associated with the string.
 
197
 *
 
198
 *              Later may need similar function for unsigned long define.
 
199
 *
 
200
 *
 
201
 *
 
202
 *      RETURNS
 
203
 *              The int equivalent of the defined string.
 
204
 *              -1 if the string is not found in table
 
205
 *
 
206
 */
 
207
{
 
208
    while(pde->define != -1) {
 
209
        if (pde->define == id) {
 
210
            return(pde->pString);
 
211
        }
 
212
        pde++;
 
213
    }
 
214
    return(NULL);
 
215
}
 
216
 
 
217
/*
 
218
 *      NAME
 
219
 *              SCKeyOf - convert keyword into key ID
 
220
 *
 
221
 *      SYNOPSIS
 
222
 */
 
223
static int
 
224
SCKeyOf(char *string)
 
225
/*
 
226
 *      DESCRIPTION
 
227
 *              Converts a string to an integer define.
 
228
 *
 
229
 *              Looks up the string in the table and returns the integer
 
230
 *              associated with the string.
 
231
 *
 
232
 *              Later may need similar function for unsigned long define.
 
233
 *
 
234
 *
 
235
 *
 
236
 *      RETURNS
 
237
 *              The int equivalent of the defined string.
 
238
 *              -1 if the string is not found in table
 
239
 *
 
240
 */
 
241
{
 
242
    return(StrToDefine(KeyTbl, string));
 
243
}
 
244
 
 
245
 
 
246
/*
 
247
 *      NAME
 
248
 *              SCScrnClassOf - convert screen class string into class ID
 
249
 *
 
250
 *      SYNOPSIS
 
251
 */
 
252
static int
 
253
SCScrnClassOf(char *string)
 
254
/*
 
255
 *      DESCRIPTION
 
256
 *              Converts a string to an integer define.
 
257
 *
 
258
 *              Looks up the string in the table and returns the integer
 
259
 *              associated with the string.
 
260
 *
 
261
 *              Later may need similar function for unsigned long define.
 
262
 *
 
263
 *
 
264
 *
 
265
 *      RETURNS
 
266
 *              The int equivalent of the defined string.
 
267
 *              -1 if the string is not found in table
 
268
 *
 
269
 */
 
270
{
 
271
    return(StrToDefine(ScrnClassTbl, string));
 
272
}
 
273
 
 
274
 
 
275
/*
 
276
 *      NAME
 
277
 *              SCScrnClassStringOf - convert screen class id into class string
 
278
 *
 
279
 *      SYNOPSIS
 
280
 */
 
281
static char *
 
282
SCScrnClassStringOf(int id)
 
283
/*
 
284
 *      DESCRIPTION
 
285
 *              Converts a id to astring
 
286
 *
 
287
 *      RETURNS
 
288
 *              Pointer to string if found; otherwise NULL.
 
289
 *
 
290
 */
 
291
{
 
292
    return(DefineToStr(ScrnClassTbl, id));
 
293
}
 
294
 
 
295
/* close the stream and return any memory allocated. */
 
296
/*ARGSUSED*/
 
297
static void 
 
298
closeS(FILE *stream, XDCCC_Correction *pCorrection) 
 
299
{
 
300
    XDCCC_Correction* pNext;
 
301
    if (stream) {
 
302
        fclose (stream);
 
303
    }
 
304
    while (pCorrection) {
 
305
        pNext = pCorrection->next;
 
306
        free(pCorrection);
 
307
        pCorrection = pNext;
 
308
    }
 
309
}
 
310
 
 
311
/*
 
312
 *  Get a line of text from the stream.
 
313
 */
 
314
static char *
 
315
nextline(char *buf, int maxch, FILE *stream)
 
316
{
 
317
    linenum++;
 
318
    return (fgets(buf, maxch, stream));
 
319
}
 
320
 
 
321
 
 
322
static int
 
323
ProcessColorimetric(FILE *stream, XDCCC_Matrix *pMatrix, int VisualFlag)
 
324
{
 
325
    char buf[BUFSIZ];
 
326
    char keyword[BUFSIZ];
 
327
    char token[BUFSIZ], *ptoken;
 
328
    int  ntok;
 
329
    unsigned int matrices_processed = 0;
 
330
                /* bit 0 for XYZtoRGB matrix */
 
331
                /* bit 1 for RGBtoXYZ matrix */
 
332
    int  state = 0;
 
333
                 /* 0 -- looking for matrix */
 
334
                 /* 1 -- processing data from matrix */
 
335
                 /* 2 -- both matrices processed */
 
336
                 /* Note: the order of the matrices is not important. */
 
337
    int  count = -1;
 
338
    XcmsFloat *pElement = NULL;
 
339
 
 
340
    while ((nextline(buf, BUFSIZ, stream)) != NULL) {
 
341
        if ((ntok = sscanf(buf, "%s %s", keyword, token)) > 0) {
 
342
            switch (SCKeyOf(keyword)) {
 
343
              case XYZTORGBMAT_BEGIN :
 
344
                if (VisualFlag != VIDEO_RGB) {
 
345
                  fprintf(stderr, 
 
346
                         "Line %d: Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n",
 
347
                          linenum, SCScrnClassStringOf(VisualFlag));
 
348
                  return (0);
 
349
                }
 
350
                if (state != 0) {
 
351
                  fprintf(stderr,
 
352
                          "Line %d: Extraneous keyword %s.\n", 
 
353
                          linenum, keyword);
 
354
                  return (0);
 
355
                }
 
356
                state = 1;
 
357
                count = 0;
 
358
                pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
 
359
                break;
 
360
              case XYZTORGBMAT_END :
 
361
                if (VisualFlag != VIDEO_RGB) {
 
362
                  fprintf(stderr, 
 
363
                          "Line %d: Keyword XYZTORGBMAT_END mismatch for visual %s.\n",
 
364
                          linenum, SCScrnClassStringOf(VisualFlag));
 
365
                  return (0);
 
366
                }
 
367
                if ((state != 1) || (count != 9)) {
 
368
                  fprintf(stderr,
 
369
                          "Line %d: Incomplete XYZtoRGB matrix -- Premature %s\n", 
 
370
                          linenum, keyword);
 
371
                  return (0);
 
372
                }
 
373
                matrices_processed |= 0x1;
 
374
                if (matrices_processed == 3) {
 
375
                    state = 2;
 
376
                } else {
 
377
                    state = 0;
 
378
                }
 
379
                break;
 
380
              case RGBTOXYZMAT_BEGIN :
 
381
                if (VisualFlag != VIDEO_RGB) {
 
382
                  fprintf(stderr,
 
383
                         "Line %d: Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n",
 
384
                          linenum, SCScrnClassStringOf(VisualFlag));
 
385
                  return (0);
 
386
                }
 
387
                if (state != 0) {
 
388
                    fprintf(stderr, "Line %d: Extraneous keyword %s.\n", 
 
389
                            linenum, keyword);
 
390
                    return (0);
 
391
                }
 
392
                state = 1;
 
393
                count = 0;
 
394
                pElement = (XcmsFloat *) pMatrix->RGBtoXYZmatrix;
 
395
                break;
 
396
              case RGBTOXYZMAT_END :
 
397
                if (VisualFlag != VIDEO_RGB) {
 
398
                    fprintf(stderr, 
 
399
                           "Line %d: Keyword RGBTOXYZMAT_END mismatch for visual %s.\n",
 
400
                            linenum, SCScrnClassStringOf(VisualFlag));
 
401
                    return (0);
 
402
                }
 
403
                if ((state != 1) || (count != 9)) {
 
404
                    fprintf(stderr, 
 
405
                           "Line %d: Incomplete RGBtoXYZ matrix -- Premature %s\n", 
 
406
                            linenum, keyword);
 
407
                    return (0);
 
408
                }
 
409
                matrices_processed |= 0x2;
 
410
                if (matrices_processed == 3) {
 
411
                    state = 2;
 
412
                } else {
 
413
                    state = 0;
 
414
                }
 
415
                break;
 
416
#ifdef GRAY
 
417
              case WHITEPT_XYZ_BEGIN :
 
418
                if (VisualFlag != VIDEO_GRAY) {
 
419
                    fprintf(stderr,
 
420
                         "Line %d: Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n",
 
421
                            linenum, SCScrnClassStringOf(VisualFlag));
 
422
                    return (0);
 
423
                }
 
424
                if (state != 0) {
 
425
                  fprintf(stderr,
 
426
                          "Line %d: Extraneous keyword %s.\n", 
 
427
                          linenum, keyword);
 
428
                  return (0);
 
429
                }
 
430
                state = 1;
 
431
                count = 0;
 
432
                pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix;
 
433
                break;
 
434
              case WHITEPT_XYZ_END :
 
435
                if (VisualFlag != VIDEO_GRAY) {
 
436
                    fprintf(stderr,
 
437
                           "Line %d: Keyword WHITEPT_XYZ_END mismatch for visual %s.\n",
 
438
                            linenum, SCScrnClassStringOf(VisualFlag));
 
439
                    return (0);
 
440
                }
 
441
                if ((state != 1) || (count != 3)) {
 
442
                    fprintf(stderr,
 
443
                        "Line %d: Incomplete white point -- Premature %s\n", 
 
444
                            linenum, keyword);
 
445
                    return (0);
 
446
                }
 
447
                state = 2;
 
448
                break;
 
449
#endif /* GRAY */
 
450
              case DATA :
 
451
                for (ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
 
452
                        ptoken = strtok(NULL, DATA_DELIMS)) {
 
453
                    if (sscanf(ptoken, "%lf", pElement) != 1) {
 
454
                        if (VisualFlag == VIDEO_RGB) {
 
455
                            fprintf(stderr,
 
456
                                    "Line %d: Invalid matrix value %s.", 
 
457
                                    linenum, ptoken);
 
458
                        } else {
 
459
                            fprintf(stderr,
 
460
                                    "Line %d: Invalid CIEXYZ value %s.\n",
 
461
                                    linenum, ptoken);
 
462
                        }
 
463
                        return (0);
 
464
                    }
 
465
                    pElement++;
 
466
                    if (VisualFlag == VIDEO_RGB) {
 
467
                        if (++count > 9) {
 
468
                            fprintf(stderr,
 
469
                                   "Line %d: Extra matrix value %s\n", 
 
470
                                    linenum, ptoken);
 
471
                            return (0);
 
472
                        }
 
473
                    } else {
 
474
                        if (++count > 3) {
 
475
                            fprintf(stderr,
 
476
                                    "Line %d: Extra CIEXYZ value %s.\n",
 
477
                                    linenum, ptoken);
 
478
                            return (0);
 
479
                          }
 
480
                    }
 
481
                }
 
482
                break;
 
483
              case COLORIMETRIC_BEGIN :
 
484
                fprintf(stderr, 
 
485
                        "Line %d: Extraneous keyword %s.\n", 
 
486
                        linenum, keyword);
 
487
                return (0);
 
488
/* NOTREACHED */break;  
 
489
              case COLORIMETRIC_END :
 
490
                if (state != 2) {
 
491
                    fprintf(stderr,
 
492
                   "Line %d: Incomplete Colorimetric data -- Premature %s\n",
 
493
                            linenum, keyword);
 
494
                    return (0);
 
495
                }
 
496
                return (1);
 
497
              case COMMENT :
 
498
                /* Currently, do nothing. */
 
499
                break;
 
500
              default :
 
501
                fprintf(stderr,
 
502
                        "Line %d: Unexpected keyword %s\n",
 
503
                        linenum, keyword);
 
504
                return (0);
 
505
/* NOTREACHED */break;          
 
506
            }
 
507
        } else if (ntok < 0) {
 
508
            /* mismatch */
 
509
            fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum);
 
510
            return (0);
 
511
/* NOTREACHED */break;          
 
512
        }
 
513
    }
 
514
    return (0);
 
515
}
 
516
 
 
517
static int
 
518
ProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection)
 
519
{
 
520
    char buf[BUFSIZ];
 
521
    char *keyword;
 
522
    char *tableStr, *sizeStr, *ptoken;
 
523
    int  size;
 
524
    int  state = 0;
 
525
         /************************************************
 
526
          * 0 -- Looking for Intensity Table(s)          *
 
527
          * 1 -- Processing Intensity Table(s)           *
 
528
          ************************************************/
 
529
    int  nTbl = 0;
 
530
    int  count = 0;
 
531
    IntensityRec *pIRec = NULL;
 
532
 
 
533
    while ((nextline(buf, BUFSIZ, stream)) != NULL) {
 
534
        ptoken = keyword = strtok(buf, DATA_DELIMS);
 
535
        if (keyword != (char*)NULL) {
 
536
            switch (SCKeyOf(keyword)) {
 
537
              case ITBL_BEGIN :
 
538
                if (state != 0) {
 
539
                    fprintf(stderr,"Line %d: unexpected keyword %s\n", 
 
540
                           linenum, keyword);
 
541
                    return (0);
 
542
                }
 
543
                tableStr = strtok((char*)NULL, DATA_DELIMS);
 
544
                sizeStr = strtok((char*)NULL, DATA_DELIMS);
 
545
                if ((sizeStr == (char*)NULL) ||
 
546
                        sscanf(sizeStr, "%d", &size) != 1) {
 
547
                    fprintf(stderr,
 
548
                            "Line %d: invalid Intensity Table size, %s.\n",
 
549
                              linenum, sizeStr);
 
550
                    return (0);
 
551
                }
 
552
                if (size < 0) {
 
553
                    fprintf(stderr,
 
554
                            "Line %d: count %d < 0 for Intensity Table.\n",
 
555
                              linenum, size);
 
556
                    return (0);
 
557
                }
 
558
                if (strcmp(tableStr, "GREEN") == 0) {
 
559
                    if (pCorrection->nTables != 3) {
 
560
                        fprintf(stderr,"Line %d: incorrect number of tables\n", 
 
561
                        linenum);
 
562
                        return (0);
 
563
                    }
 
564
                    if (pCorrection->pGreenTbl->pBase != NULL) {
 
565
                        fprintf(stderr,
 
566
                             "Line %d: multiple GREEN Intensity Profiles\n",
 
567
                                   linenum);
 
568
                        return (0);
 
569
                    }
 
570
                    pCorrection->pGreenTbl->nEntries = size;
 
571
                    pCorrection->pGreenTbl->pBase =
 
572
                         (IntensityRec *) calloc (size, sizeof(IntensityRec));
 
573
                    if (!pCorrection->pGreenTbl->pBase) {
 
574
                        fprintf(stderr,
 
575
                     "Line %d: Unable to allocate space for GREEN Intensity Profile\n", linenum);
 
576
                        return (0);
 
577
                    }
 
578
                    pIRec = pCorrection->pGreenTbl->pBase;
 
579
                } else if (strcmp(tableStr, "BLUE") == 0) {
 
580
                    if (pCorrection->nTables != 3) {
 
581
                        fprintf(stderr,
 
582
                                "Line %d: incorrect number of tables\n",
 
583
                                linenum);
 
584
                        return (0);
 
585
                    }
 
586
                    if (pCorrection->pBlueTbl->pBase != NULL) {
 
587
                        fprintf(stderr,
 
588
                              "Line %d: multiple BLUE Intensity Profiles\n",
 
589
                                   linenum);
 
590
                        return (0);
 
591
                    }
 
592
                    pCorrection->pBlueTbl->nEntries = size;
 
593
                    pCorrection->pBlueTbl->pBase =
 
594
                         (IntensityRec *) calloc (size, sizeof(IntensityRec));
 
595
                    if (!pCorrection->pBlueTbl->pBase) {
 
596
                        fprintf(stderr,
 
597
                      "Line %d: Unable to allocate space for BLUE Intensity Profile\n", linenum);
 
598
                        return (0);
 
599
                    }
 
600
                    pIRec = pCorrection->pBlueTbl->pBase;
 
601
                } else {
 
602
                    if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) {
 
603
                        fprintf(stderr,"Line %d: multiple RGB Intensity Tables",
 
604
                              linenum);
 
605
                        return (0);
 
606
                    }
 
607
                    if (pCorrection->pRedTbl->pBase != NULL) {
 
608
                        fprintf(stderr,
 
609
                  "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n",
 
610
                                   linenum);
 
611
                        return (0);
 
612
                    }
 
613
                    pCorrection->pRedTbl->nEntries = size;
 
614
                    pCorrection->pRedTbl->pBase = 
 
615
                         (IntensityRec *) calloc (size, sizeof(IntensityRec));
 
616
                    if (!pCorrection->pRedTbl->pBase) {
 
617
                        fprintf(stderr,
 
618
                             "Line %d: Unable to allocate space for intensity table\n", linenum);
 
619
                        return (0);
 
620
                    }
 
621
                    pIRec = pCorrection->pRedTbl->pBase;
 
622
                }
 
623
                state = 1;
 
624
                count = 0;
 
625
                break;
 
626
              case ITBL_END :
 
627
                if ((state != 1) || (count != size)) {
 
628
                    fprintf(stderr,
 
629
                    "Line %d: incomplete Intensity Table -- Premature %s\n",
 
630
                          linenum, keyword);
 
631
                    return (0);
 
632
                }
 
633
                nTbl++;
 
634
                state = 0;
 
635
                break;
 
636
              case DATA :
 
637
                do {
 
638
                    /********************************************************
 
639
                     * Note: tableType should only be 0 or 1 at this point. 
 
640
                     *       0 indicates value and intensity stored.
 
641
                     *       1 indicates only intensity stored. 
 
642
                     ********************************************************/
 
643
                    if (pCorrection->tableType) {
 
644
                        if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
 
645
                            fprintf(stderr,
 
646
                           "Line %d: invalid Intensity Profile value %s\n", 
 
647
                                  linenum, ptoken);
 
648
                            return (0);
 
649
                        }
 
650
                        /* With tableType 1 only store the intensity. */
 
651
                        pIRec++;
 
652
                    } else {
 
653
                        short tmp;
 
654
                        /* Note ansi C can handle 0x preceeding hex number */
 
655
                        if (sscanf(ptoken, "%hi", &tmp) != 1) {
 
656
                            fprintf(stderr,
 
657
                            "Line %d: invalid Intensity Profile value %s\n",
 
658
                                  linenum, ptoken);
 
659
                            return (0);
 
660
                        } else
 
661
                            pIRec->value = tmp;
 
662
                        if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) {
 
663
                            fprintf(stderr,
 
664
                                  "Line %d: missing Intensity Profile value\n",
 
665
                                  linenum);
 
666
                            return (0);
 
667
                        }
 
668
                        if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) {
 
669
                            fprintf(stderr,
 
670
                        "Line %d: invalid Intensity Profile intensity %s\n",
 
671
                                  linenum, ptoken);
 
672
                            return (0);
 
673
                        }
 
674
                        /* With tableType 0 only store both value & intensity*/
 
675
                        pIRec++;
 
676
                    }
 
677
                    if (++count > size) {
 
678
                        fprintf(stderr,
 
679
                                "Line %d: extra Intensity value %s\n",
 
680
                                linenum, ptoken);
 
681
                        return (0);
 
682
                    }
 
683
                    ptoken = strtok(NULL, DATA_DELIMS);
 
684
                } while(ptoken != NULL);
 
685
                break;
 
686
              case IPROFILE_BEGIN :
 
687
                fprintf(stderr,"Line %d: extraneous keyword %s\n", 
 
688
                          linenum, keyword);
 
689
                return (0);
 
690
/* NOTREACHED */break;
 
691
              case IPROFILE_END :
 
692
                if ((state != 0) || (nTbl != pCorrection->nTables)) {
 
693
                    fprintf(stderr,
 
694
             "Line %d: incomplete Intensity Profile data -- Premature %s\n",
 
695
                           linenum, keyword);
 
696
                    return (0);
 
697
                }
 
698
                return (1);
 
699
              case COMMENT :
 
700
                /* ignore line */
 
701
                break;
 
702
              default :
 
703
                fprintf(stderr,"Line %d: unexpected keyword %s\n",
 
704
                      linenum, keyword);
 
705
                return (0);
 
706
/* NOTREACHED */break;
 
707
            }
 
708
        } /* else its was just a blank line */
 
709
    }
 
710
    return (0);
 
711
}
 
712
 
 
713
static void
 
714
PutTableType0Card8(IntensityTbl *pTbl, unsigned char **pCard8)
 
715
{
 
716
    unsigned int count;
 
717
    IntensityRec *pIRec;
 
718
 
 
719
    pIRec = pTbl->pBase;
 
720
    count = pTbl->nEntries;
 
721
    **pCard8 = count - 1;
 
722
    *pCard8 += 1;
 
723
    for (; count; count--, pIRec++) {
 
724
        **pCard8 = pIRec->value >> 8;
 
725
        *pCard8 += 1;
 
726
        **pCard8 = pIRec->intensity * 255.0;
 
727
        *pCard8 += 1;
 
728
    }
 
729
}
 
730
 
 
731
static void
 
732
PutTableType1Card8(IntensityTbl *pTbl, unsigned char **pCard8)
 
733
{
 
734
    unsigned int count;
 
735
    IntensityRec *pIRec;
 
736
 
 
737
    pIRec = pTbl->pBase;
 
738
    count = pTbl->nEntries;
 
739
    **pCard8 = count - 1;
 
740
    *pCard8 += 1;
 
741
    for (; count; count--, pIRec++) {
 
742
        **pCard8 = pIRec->intensity * 255.0;
 
743
        *pCard8 += 1;
 
744
    }
 
745
}
 
746
 
 
747
static void
 
748
PutTableType0Card16(IntensityTbl *pTbl, unsigned short **pCard16)
 
749
{
 
750
    unsigned int count;
 
751
    IntensityRec *pIRec;
 
752
 
 
753
    pIRec = pTbl->pBase;
 
754
    count = pTbl->nEntries;
 
755
    **pCard16 = count - 1;
 
756
    *pCard16 += 1;
 
757
    for (; count; count--, pIRec++) {
 
758
        **pCard16 = pIRec->value;
 
759
        *pCard16 += 1;
 
760
        **pCard16 = pIRec->intensity * 65535.0;
 
761
        *pCard16 += 1;
 
762
    }
 
763
}
 
764
 
 
765
static void
 
766
PutTableType1Card16(IntensityTbl *pTbl, unsigned short **pCard16)
 
767
{
 
768
    unsigned int count;
 
769
    IntensityRec *pIRec;
 
770
 
 
771
    pIRec = pTbl->pBase;
 
772
    count = pTbl->nEntries;
 
773
    **pCard16 = count - 1;
 
774
    *pCard16 += 1;
 
775
    for (; count; count--, pIRec++) {
 
776
        **pCard16 = pIRec->intensity * 65535.0;
 
777
        *pCard16 += 1;
 
778
    }
 
779
}
 
780
 
 
781
static void
 
782
PutTableType0Card32(IntensityTbl *pTbl, unsigned long **pCard32)
 
783
{
 
784
    unsigned int count;
 
785
    IntensityRec *pIRec;
 
786
 
 
787
    pIRec = pTbl->pBase;
 
788
    count = pTbl->nEntries;
 
789
    **pCard32 = count - 1;
 
790
    *pCard32 += 1;
 
791
    for (; count; count--, pIRec++) {
 
792
        **pCard32 = pIRec->value;
 
793
        *pCard32 += 1;
 
794
        **pCard32 = pIRec->intensity * 4294967295.0;
 
795
        *pCard32 += 1;
 
796
    }
 
797
}
 
798
 
 
799
static void
 
800
PutTableType1Card32(IntensityTbl *pTbl, unsigned long **pCard32)
 
801
{
 
802
    unsigned int count;
 
803
    IntensityRec *pIRec;
 
804
 
 
805
    pIRec = pTbl->pBase;
 
806
    count = pTbl->nEntries;
 
807
    **pCard32 = count - 1;
 
808
    *pCard32 += 1;
 
809
    for (; count; count--, pIRec++) {
 
810
        **pCard32 = pIRec->intensity * 4294967295.0;
 
811
        *pCard32 += 1;
 
812
    }
 
813
}
 
814
 
 
815
 
 
816
static void
 
817
LoadMatrix(Display *pDpy, Window root, XDCCC_Matrix *pMatrix)
 
818
{
 
819
    int  count;
 
820
    unsigned long  *pCard32;
 
821
    unsigned long  Card32Array[18];
 
822
    Atom MatricesAtom;
 
823
    XcmsFloat *pValue;
 
824
 
 
825
    /*
 
826
     * Store the XDCCC_LINEAR_RGB_MATRICES
 
827
     */
 
828
    pCard32 = Card32Array;
 
829
    pValue = (XcmsFloat *)pMatrix->XYZtoRGBmatrix;
 
830
    for (count = 0; count < 9; count++) {
 
831
        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
 
832
    }
 
833
    pValue = (XcmsFloat *)pMatrix->RGBtoXYZmatrix;
 
834
    for (count = 0; count < 9; count++) {
 
835
        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
 
836
    }
 
837
    MatricesAtom = XInternAtom (pDpy, XDCCC_MATRIX_ATOM_NAME, False);
 
838
    XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32, 
 
839
                     PropModeReplace, (unsigned char *)Card32Array, 18);
 
840
}
 
841
 
 
842
 
 
843
static int
 
844
LoadCorrections(Display *pDpy, Window root, XDCCC_Correction *pCorrection, 
 
845
                int targetFormat)
 
846
{
 
847
    unsigned char  *pCard8;
 
848
    unsigned char  *pCard8Array = (unsigned char *)NULL;
 
849
    unsigned short  *pCard16;
 
850
    unsigned short  *pCard16Array = (unsigned short *)NULL;
 
851
    unsigned long  *pCard32;
 
852
    unsigned long  *pCard32Array = (unsigned long *)NULL;
 
853
    Atom CorrectAtom;
 
854
    int total;
 
855
    int i;
 
856
 
 
857
    /*
 
858
     * Store each XDCCC_CORRECTION into XDCCC_LINEAR_RGB_CORRECTION property
 
859
     */
 
860
    CorrectAtom = XInternAtom (pDpy, XDCCC_CORRECT_ATOM_NAME, False);
 
861
 
 
862
    for (i = 0; pCorrection; i++, pCorrection = pCorrection->next) {
 
863
        if ((pCorrection->tableType != 0) && (pCorrection->tableType != 1)) {
 
864
            if (pCorrection->visual_info.visualid) {
 
865
                fprintf(stderr,"RGB Correction for visualid %ld: Invalid intensity table type %d.\n",
 
866
                        pCorrection->visual_info.visualid,
 
867
                        pCorrection->tableType);
 
868
            } else {
 
869
                fprintf(stderr,"Global RGB Correction: Invalid intensity table type %d.\n",
 
870
                        pCorrection->tableType);
 
871
            }
 
872
            return(0);
 
873
        }
 
874
 
 
875
        if (pCorrection->nTables != 1 && pCorrection->nTables != 3) {
 
876
            if (pCorrection->visual_info.visualid) {
 
877
                fprintf(stderr,"RGB Correction for visualid %ld: %d invalid number of tables.\n",
 
878
                        pCorrection->visual_info.visualid,
 
879
                        pCorrection->nTables);
 
880
            } else {
 
881
                fprintf(stderr,"Global RGB Correction: %d invalid number of tables.\n",
 
882
                        pCorrection->nTables);
 
883
            }
 
884
            return(0);
 
885
        }
 
886
 
 
887
        if (pCorrection->nTables == 1) {
 
888
            if (pCorrection->pRedTbl->nEntries < 2) {
 
889
                if (pCorrection->visual_info.visualid) {
 
890
                    fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
 
891
                            pCorrection->visual_info.visualid);
 
892
                } else {
 
893
                    fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
 
894
                }
 
895
                return (0);
 
896
            }
 
897
            switch (targetFormat) {
 
898
              case 8:
 
899
                total = 7 + (pCorrection->pRedTbl->nEntries *
 
900
                        (pCorrection->tableType == 0 ? 2 : 1));
 
901
                if ((pCard8 = pCard8Array = (unsigned char *) calloc (total,
 
902
                        sizeof (unsigned char))) == NULL) {
 
903
                    fprintf(stderr,"Unable allocate array of ints\n");
 
904
                    return (0);
 
905
                }
 
906
                *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
 
907
                *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
 
908
                *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
 
909
                *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
 
910
                *pCard8++ = pCorrection->tableType;     /* type */
 
911
                *pCard8++ = 1;          /* number of tables = 1 */
 
912
                if (pCorrection->tableType == 0) {
 
913
                    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
 
914
                } else {
 
915
                    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
 
916
                }
 
917
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
 
918
                        i ? PropModeAppend : PropModeReplace,
 
919
                        (unsigned char *)pCard8Array, total);
 
920
                free(pCard8Array);
 
921
                break;
 
922
              case 16:
 
923
                total = 5 + (pCorrection->pRedTbl->nEntries * 
 
924
                        (pCorrection->tableType == 0 ? 2 : 1));
 
925
                if ((pCard16 = pCard16Array = (unsigned short *) calloc (total,
 
926
                        sizeof (unsigned short))) == NULL) {
 
927
                    fprintf(stderr,"Unable allocate array of ints\n");
 
928
                    return (0);
 
929
                }
 
930
                *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
 
931
                *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
 
932
                *pCard16++ = pCorrection->tableType;    /* type */
 
933
                *pCard16++ = 1;         /* number of tables = 1 */
 
934
                if (pCorrection->tableType == 0) {
 
935
                    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
 
936
                } else {
 
937
                    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
 
938
                }
 
939
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
 
940
                        i ? PropModeAppend : PropModeReplace,
 
941
                        (unsigned char *)pCard16Array, total);
 
942
                free(pCard16Array);
 
943
                break;
 
944
              case 32:
 
945
                total = 4 + (pCorrection->pRedTbl->nEntries * 
 
946
                        (pCorrection->tableType == 0 ? 2 : 1));
 
947
                if ((pCard32 = pCard32Array =
 
948
                        (unsigned long *) calloc (total,
 
949
                        sizeof (unsigned long))) == NULL) {
 
950
                    fprintf(stderr,"Unable allocate array of ints\n");
 
951
                    return (0);
 
952
                }
 
953
                *pCard32++ = pCorrection->visual_info.visualid;
 
954
                *pCard32++ = pCorrection->tableType;    /* type */
 
955
                *pCard32++ = 1;         /* number of tables = 1 */
 
956
                if (pCorrection->tableType == 0) {
 
957
                    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
 
958
                } else {
 
959
                    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
 
960
                }
 
961
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
 
962
                        i ? PropModeAppend : PropModeReplace,
 
963
                        (unsigned char *)pCard32Array, total);
 
964
                free(pCard32Array);
 
965
                break;
 
966
              default:
 
967
                if (pCorrection->visual_info.visualid) {
 
968
                    fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
 
969
                            pCorrection->visual_info.visualid);
 
970
                } else {
 
971
                    fprintf(stderr,"Global RGB Correction: Invalid property format\n");
 
972
                }
 
973
                return (0);
 
974
            }
 
975
          } else { /* pCorrection->nTables == 3 */
 
976
            if ((pCorrection->pRedTbl->nEntries < 2) ||
 
977
                    (pCorrection->pGreenTbl->nEntries < 2) ||
 
978
                    (pCorrection->pBlueTbl->nEntries < 2)) {
 
979
                if (pCorrection->visual_info.visualid) {
 
980
                    fprintf(stderr,"RGB Correction for visualid %ld: Illegal number of entries in table\n",
 
981
                            pCorrection->visual_info.visualid);
 
982
                } else {
 
983
                    fprintf(stderr,"Global RGB Correction: Illegal number of entries in table\n");
 
984
                }
 
985
                return (0);
 
986
            }
 
987
            switch (targetFormat) {
 
988
              case 8:
 
989
                total = 9 +     /* visualID, type, and 3 lengths */
 
990
                    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
991
                    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
992
                    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
 
993
                if ((pCard8 = pCard8Array =
 
994
                        (unsigned char *) calloc (total,
 
995
                        sizeof (unsigned char))) == NULL) {
 
996
                    fprintf(stderr,"Unable allocate array of ints\n");
 
997
                    return (0);
 
998
                }
 
999
                *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF;
 
1000
                *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF;
 
1001
                *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF;
 
1002
                *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF;
 
1003
                *pCard8++ = pCorrection->tableType;     /* type */
 
1004
                *pCard8++ = 3;          /* number of tables = 3 */
 
1005
                if (pCorrection->tableType == 0) {
 
1006
                    PutTableType0Card8(pCorrection->pRedTbl, &pCard8);
 
1007
                    PutTableType0Card8(pCorrection->pGreenTbl, &pCard8);
 
1008
                    PutTableType0Card8(pCorrection->pBlueTbl, &pCard8);
 
1009
                } else {
 
1010
                    PutTableType1Card8(pCorrection->pRedTbl, &pCard8);
 
1011
                    PutTableType1Card8(pCorrection->pGreenTbl, &pCard8);
 
1012
                    PutTableType1Card8(pCorrection->pBlueTbl, &pCard8);
 
1013
                }
 
1014
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
 
1015
                        i ? PropModeAppend : PropModeReplace,
 
1016
                        (unsigned char *)pCard8Array, total);
 
1017
                free(pCard8Array);
 
1018
                break;
 
1019
              case 16:
 
1020
                total = 7 +     /* visualID, type, and 3 lengths */
 
1021
                    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
1022
                    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
1023
                    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
 
1024
                if ((pCard16 = pCard16Array =
 
1025
                        (unsigned short *) calloc (total,
 
1026
                        sizeof (unsigned short))) == NULL) {
 
1027
                    fprintf(stderr,"Unable allocate array of ints\n");
 
1028
                    return (0);
 
1029
                }
 
1030
                *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF;
 
1031
                *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF;
 
1032
                *pCard16++ = pCorrection->tableType;    /* type = 0 */
 
1033
                *pCard16++ = 3;         /* number of tables = 3 */
 
1034
                if (pCorrection->tableType == 0) {
 
1035
                    PutTableType0Card16(pCorrection->pRedTbl, &pCard16);
 
1036
                    PutTableType0Card16(pCorrection->pGreenTbl, &pCard16);
 
1037
                    PutTableType0Card16(pCorrection->pBlueTbl, &pCard16);
 
1038
                } else {
 
1039
                    PutTableType1Card16(pCorrection->pRedTbl, &pCard16);
 
1040
                    PutTableType1Card16(pCorrection->pGreenTbl, &pCard16);
 
1041
                    PutTableType1Card16(pCorrection->pBlueTbl, &pCard16);
 
1042
                }
 
1043
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
 
1044
                        i ? PropModeAppend : PropModeReplace,
 
1045
                        (unsigned char *)pCard16Array, total);
 
1046
                free(pCard16Array);
 
1047
                break;
 
1048
              case 32:
 
1049
                total = 6 +     /* visualID, type, and 3 lengths */
 
1050
                    (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
1051
                    (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) +
 
1052
                    (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1));
 
1053
                if ((pCard32 = pCard32Array =
 
1054
                        (unsigned long *) calloc (total,
 
1055
                        sizeof (unsigned long))) == NULL) {
 
1056
                    fprintf(stderr,"Unable allocate array of ints\n");
 
1057
                    return (0);
 
1058
                }
 
1059
                *pCard32++ = pCorrection->visual_info.visualid;
 
1060
                *pCard32++ = pCorrection->tableType;    /* type */
 
1061
                *pCard32++ = 3;         /* number of tables = 3 */
 
1062
                if (pCorrection->tableType == 0) {
 
1063
                    PutTableType0Card32(pCorrection->pRedTbl, &pCard32);
 
1064
                    PutTableType0Card32(pCorrection->pGreenTbl, &pCard32);
 
1065
                    PutTableType0Card32(pCorrection->pBlueTbl, &pCard32);
 
1066
                } else {
 
1067
                    PutTableType1Card32(pCorrection->pRedTbl, &pCard32);
 
1068
                    PutTableType1Card32(pCorrection->pGreenTbl, &pCard32);
 
1069
                    PutTableType1Card32(pCorrection->pBlueTbl, &pCard32);
 
1070
                }
 
1071
                XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
 
1072
                        i ? PropModeAppend : PropModeReplace,
 
1073
                        (unsigned char *)pCard32Array, total);
 
1074
                free(pCard32Array);
 
1075
                break;
 
1076
              default:
 
1077
                if (pCorrection->visual_info.visualid) {
 
1078
                    fprintf(stderr,"RGB Correction for visualid %ld: Invalid property format\n",
 
1079
                            pCorrection->visual_info.visualid);
 
1080
                } else {
 
1081
                    fprintf(stderr,"Global RGB Correction: Invalid property format\n");
 
1082
                }
 
1083
                return (0);
 
1084
            }
 
1085
        }
 
1086
    }
 
1087
 
 
1088
    return (1);
 
1089
}
 
1090
 
 
1091
#ifdef GRAY
 
1092
 
 
1093
static int
 
1094
LoadDataGray(Display *pDpy, window root, int tableType, 
 
1095
             LINEAR_RGB_SCCData *pScreenData, int targetFormat)
 
1096
{
 
1097
    unsigned char *ret_prop;
 
1098
    int  count;
 
1099
    int  nLevels;
 
1100
    unsigned char  *pCard8;
 
1101
    unsigned char  *pCard8Array = (unsigned char *)NULL;
 
1102
    unsigned short  *pCard16;
 
1103
    unsigned short  *pCard16Array = (unsigned short *)NULL;
 
1104
    unsigned long  *pCard32;
 
1105
    unsigned long  *pCard32Array = (unsigned long *)NULL;
 
1106
    unsigned long  Card32Array[18];
 
1107
    int  ret_format;
 
1108
    unsigned long ret_len, ret_after;
 
1109
    Atom MatricesAtom, CorrectAtom, ret_atom;
 
1110
    XcmsFloat *pValue;
 
1111
    int total;
 
1112
 
 
1113
    /* Now store the XDCCC_SCREENWHITEPT */
 
1114
    pCard32 = Card32Array;
 
1115
    pValue = (XcmsFloat *)pScreenData->XYZtoRGBmatrix;
 
1116
    for (count = 0; count < 3; count++) {
 
1117
        *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
 
1118
    }
 
1119
    MatricesAtom = XInternAtom (pDpy,XDCCC_SCREENWHITEPT_ATOM_NAME,False);
 
1120
    XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32, 
 
1121
                     PropModeReplace, (unsigned char *)Card32Array, 3);
 
1122
 
 
1123
    /* Now store the XDCCC_GRAY_CORRECTION */
 
1124
    CorrectAtom = XInternAtom (pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False);
 
1125
 
 
1126
    if (tableType == CORR_TYPE_NONE) {
 
1127
        XGetWindowProperty (pDpy, root, CorrectAtom, 
 
1128
                            0, 5, False, XA_INTEGER, 
 
1129
                            &ret_atom, &ret_format, &ret_len, &ret_after,
 
1130
                            &ret_prop);
 
1131
        if (ret_format != 0) {
 
1132
            XDeleteProperty (pDpy, root, CorrectAtom);
 
1133
            XFree ((char *)ret_prop);
 
1134
        }
 
1135
        return (1);
 
1136
    }
 
1137
    nLevels = pScreenData->pRedTbl->nEntries;
 
1138
    if (nLevels < 2) {
 
1139
        fprintf(stderr,"Illegal number of entries in table\n");
 
1140
        return (0);
 
1141
    }
 
1142
    switch (targetFormat) {
 
1143
      case 8:
 
1144
        total = 6 /* visualID, type, length */
 
1145
                + (nLevels * (tableType == 0 ? 2 : 1));
 
1146
        if ((pCard8 = pCard8Array = (unsigned char *)
 
1147
                calloc (total, sizeof (unsigned char))) == NULL) {
 
1148
            fprintf(stderr,"Unable allocate array of Card8\n");
 
1149
            return (0);
 
1150
        }
 
1151
        *pCard8++ = 0;          /* VisualID = 0 */
 
1152
        *pCard8++ = 0;          /* VisualID = 0 */
 
1153
        *pCard8++ = 0;          /* VisualID = 0 */
 
1154
        *pCard8++ = 0;          /* VisualID = 0 */
 
1155
        *pCard8++ = tableType;  /* type */
 
1156
        if (tableType == 0) {
 
1157
            PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
 
1158
        } else { /* tableType == 1 */
 
1159
            PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
 
1160
        }
 
1161
        XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
 
1162
                         PropModeReplace, (unsigned char *)pCard8Array,
 
1163
                         total);
 
1164
        free (pCard8Array);
 
1165
        break;
 
1166
      case 16:
 
1167
        total = 4 /* visualID, type, length */
 
1168
                + (nLevels * (tableType == 0 ? 2 : 1));
 
1169
        if ((pCard16 = pCard16Array = (unsigned short *)
 
1170
                calloc (total, sizeof (unsigned short))) == NULL) {
 
1171
            fprintf(stderr,"Unable allocate array of Card16\n");
 
1172
            return (0);
 
1173
        }
 
1174
        *pCard16++ = 0;         /* VisualID = 0 */
 
1175
        *pCard16++ = 0;         /* VisualID = 0 */
 
1176
        *pCard16++ = tableType; /* type */
 
1177
        if (tableType == 0) {
 
1178
            PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
 
1179
        } else { /* tableType == 1 */
 
1180
            PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
 
1181
        }
 
1182
        XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
 
1183
                         PropModeReplace, (unsigned char *)pCard16Array,
 
1184
                         total);
 
1185
        free (pCard16Array);
 
1186
        break;
 
1187
      case 32:
 
1188
        total = 3 /* visualID, type, length */
 
1189
                + (nLevels * (tableType == 0 ? 2 : 1));
 
1190
        if ((pCard32 = pCard32Array = (unsigned long *)
 
1191
                calloc (total, sizeof (unsigned long))) == NULL) {
 
1192
            fprintf(stderr,"Unable allocate array of Card32\n");
 
1193
            return (0);
 
1194
        }
 
1195
        *pCard32++ = 0;         /* VisualID = 0 */
 
1196
        *pCard32++ = tableType; /* type */
 
1197
        if (tableType == 0) {
 
1198
            PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
 
1199
        } else { /* tableType == 1 */
 
1200
            PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
 
1201
        }
 
1202
        XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
 
1203
                         PropModeReplace, (unsigned char *)pCard32Array,
 
1204
                         total);
 
1205
        free (pCard32Array);
 
1206
        break;
 
1207
      default:
 
1208
        fprintf(stderr,"Invalid property format\n");
 
1209
        return (0);
 
1210
    }
 
1211
    return (1);
 
1212
}
 
1213
#endif /* GRAY */
 
1214
 
 
1215
 
 
1216
static void
 
1217
PrintVisualOptions(XDCCC_Correction *pCorrection)
 
1218
{
 
1219
    if (pCorrection->visual_info_mask & VisualIDMask) {
 
1220
        fprintf(stderr, "\t%s:0x%lx\n",
 
1221
                DefineToStr(VisualOptKeyTbl, KEY_VISUALID),
 
1222
                (unsigned long)pCorrection->visual_info.visualid);
 
1223
    }
 
1224
    if (pCorrection->visual_info_mask & VisualDepthMask) {
 
1225
        fprintf(stderr, "\t%s:%d\n",
 
1226
                DefineToStr(VisualOptKeyTbl, KEY_DEPTH),
 
1227
                pCorrection->visual_info.depth);
 
1228
    }
 
1229
    if (pCorrection->visual_info_mask & VisualClassMask) {
 
1230
        fprintf(stderr, "\t%s:%s\n",
 
1231
                DefineToStr(VisualOptKeyTbl, KEY_CLASS),
 
1232
                DefineToStr(VisualClassTbl, pCorrection->visual_info.class));
 
1233
    }
 
1234
    if (pCorrection->visual_info_mask & VisualRedMaskMask) {
 
1235
        fprintf(stderr, "\t%s:0x%lx\n",
 
1236
                DefineToStr(VisualOptKeyTbl, KEY_RED_MASK),
 
1237
                pCorrection->visual_info.red_mask);
 
1238
    }
 
1239
    if (pCorrection->visual_info_mask & VisualGreenMaskMask) {
 
1240
        fprintf(stderr, "\t%s:0x%lx\n",
 
1241
                DefineToStr(VisualOptKeyTbl, KEY_GREEN_MASK),
 
1242
                pCorrection->visual_info.green_mask);
 
1243
    }
 
1244
    if (pCorrection->visual_info_mask & VisualBlueMaskMask) {
 
1245
        fprintf(stderr, "\t%s:0x%lx\n",
 
1246
                DefineToStr(VisualOptKeyTbl, KEY_BLUE_MASK),
 
1247
                pCorrection->visual_info.blue_mask);
 
1248
    }
 
1249
    if (pCorrection->visual_info_mask & VisualColormapSizeMask) {
 
1250
        fprintf(stderr, "\t%s:0x%x\n",
 
1251
                DefineToStr(VisualOptKeyTbl, KEY_COLORMAP_SIZE),
 
1252
                pCorrection->visual_info.colormap_size);
 
1253
    }
 
1254
    if (pCorrection->visual_info_mask & VisualBitsPerRGBMask) {
 
1255
        fprintf(stderr, "\t%s:%d\n",
 
1256
                DefineToStr(VisualOptKeyTbl, KEY_BITS_PER_RGB),
 
1257
                pCorrection->visual_info.bits_per_rgb);
 
1258
    }
 
1259
}
 
1260
 
 
1261
 
 
1262
static int
 
1263
ParseVisualOptions(Display *pDpy, XDCCC_Correction *pCorrection, char *pbuf)
 
1264
{
 
1265
    char *key;
 
1266
    char *value;
 
1267
    XVisualInfo *vinfo;
 
1268
    int n_matches;
 
1269
    char delims[8];
 
1270
 
 
1271
    strcpy(delims, DATA_DELIMS);
 
1272
    strcat(delims, ":");
 
1273
    pCorrection->visual_info_mask = VisualNoMask;
 
1274
    key = strtok(pbuf, delims);
 
1275
    do {
 
1276
        long tmp;
 
1277
        value = strtok((char*)NULL, delims);
 
1278
        if ((key == (char*)NULL) || (value == (char*)NULL)) {
 
1279
            return (0);
 
1280
        }
 
1281
        switch (StrToDefine(VisualOptKeyTbl, key)) {
 
1282
          case  KEY_VISUALID:
 
1283
            if (sscanf(value, "%li", &tmp) != 1) {
 
1284
                fprintf(stderr,
 
1285
                        "Line %d: invalid VisualID specified, %s\n",
 
1286
                        linenum, value);
 
1287
                return (0);
 
1288
            } else
 
1289
                pCorrection->visual_info.visualid = tmp;
 
1290
            pCorrection->visual_info_mask |= VisualIDMask;
 
1291
            break;
 
1292
          case  KEY_DEPTH:
 
1293
            if (sscanf(value, "%i", &pCorrection->visual_info.depth) != 1) {
 
1294
                fprintf(stderr,
 
1295
                        "Line %d: invalid depth specified, %s\n",
 
1296
                        linenum, value);
 
1297
                return (0);
 
1298
            } 
 
1299
            pCorrection->visual_info_mask |= VisualDepthMask;
 
1300
            break;
 
1301
          case  KEY_CLASS:
 
1302
            switch (pCorrection->visual_info.class =
 
1303
                    StrToDefine(VisualClassTbl, value)) {
 
1304
              case  StaticColor:
 
1305
                break;
 
1306
              case  PseudoColor:
 
1307
                break;
 
1308
              case  TrueColor:
 
1309
                break;
 
1310
              case  DirectColor:
 
1311
                break;
 
1312
              case  StaticGray:
 
1313
                /* invalid, fall through */
 
1314
              case  GrayScale:
 
1315
                /* invalid, fall through */
 
1316
              default:
 
1317
                fprintf(stderr,
 
1318
                        "Line %d: invalid Visual Class -- %s\n",
 
1319
                        linenum, value);
 
1320
                return (0);
 
1321
            }
 
1322
            pCorrection->visual_info_mask |= VisualClassMask;
 
1323
            break;
 
1324
          case  KEY_RED_MASK:
 
1325
            if (sscanf(value, "%li", &tmp) != 1) {
 
1326
                fprintf(stderr,
 
1327
                        "Line %d: invalid red_mask specified -- %s\n",
 
1328
                        linenum, value);
 
1329
                return (0);
 
1330
            } else
 
1331
                pCorrection->visual_info.red_mask = tmp;
 
1332
            pCorrection->visual_info_mask |= VisualRedMaskMask;
 
1333
            break;
 
1334
          case  KEY_GREEN_MASK:
 
1335
            if (sscanf(value, "%li", &tmp) != 1) {
 
1336
                fprintf(stderr,
 
1337
                        "Line %d: invalid green_mask specified -- %s\n",
 
1338
                        linenum, value);
 
1339
                return (0);
 
1340
            } else
 
1341
                pCorrection->visual_info.green_mask = tmp;
 
1342
            pCorrection->visual_info_mask |= VisualGreenMaskMask;
 
1343
            break;
 
1344
          case  KEY_BLUE_MASK:
 
1345
            if (sscanf(value, "%li", &tmp) != 1) {
 
1346
                fprintf(stderr,
 
1347
                        "Line %d: invalid blue_mask specified -- %s\n",
 
1348
                        linenum, value);
 
1349
                return (0);
 
1350
            } else
 
1351
                pCorrection->visual_info.blue_mask = tmp;
 
1352
            pCorrection->visual_info_mask |= VisualBlueMaskMask;
 
1353
            break;
 
1354
          case  KEY_COLORMAP_SIZE:
 
1355
            if (sscanf(value, "%i", &pCorrection->visual_info.colormap_size) != 1) {
 
1356
                fprintf(stderr,
 
1357
                        "Line %d: invalid colormap_size specified -- %s\n",
 
1358
                        linenum, value);
 
1359
                return (0);
 
1360
            } 
 
1361
            pCorrection->visual_info_mask |= VisualColormapSizeMask;
 
1362
            break;
 
1363
          case  KEY_BITS_PER_RGB:
 
1364
            if (sscanf(value, "%i", &pCorrection->visual_info.bits_per_rgb) != 1) {
 
1365
                fprintf(stderr,
 
1366
                        "Line %d: invalid bits_per_rgb specified -- %s\n",
 
1367
                        linenum, value);
 
1368
                return (0);
 
1369
            } 
 
1370
            pCorrection->visual_info_mask |= VisualBitsPerRGBMask;
 
1371
            break;
 
1372
          default:
 
1373
            fprintf(stderr,
 
1374
                    "Line %d: invalid keyword %s\n", linenum, key);
 
1375
            return (0);
 
1376
        }
 
1377
        key = strtok((char*)NULL, delims);
 
1378
    } while (key != (char *)NULL);
 
1379
 
 
1380
    vinfo = XGetVisualInfo(pDpy,
 
1381
            pCorrection->visual_info_mask,
 
1382
            &pCorrection->visual_info,
 
1383
            &n_matches);
 
1384
 
 
1385
    if (!n_matches) {
 
1386
        fprintf(stderr, "Line %d: Cannot find visual matching ...\n", linenum);
 
1387
        PrintVisualOptions(pCorrection);
 
1388
        fprintf(stderr, "\n");
 
1389
        return(0);
 
1390
    }
 
1391
    if (n_matches > 1) {
 
1392
        fprintf(stderr, "Line %d: Found more than one visual matching ...\n", linenum);
 
1393
        PrintVisualOptions(pCorrection);
 
1394
        fprintf(stderr, "    Using VisualId 0x%lx\n", (unsigned long)vinfo->visualid);
 
1395
    }
 
1396
    memcpy((char*)&pCorrection->visual_info, (char*)vinfo,
 
1397
            sizeof(XVisualInfo));
 
1398
    return (1);
 
1399
 
1400
 
 
1401
 
 
1402
/************************************************************************
 
1403
 *                                                                      *
 
1404
 *                       PUBLIC ROUTINES                                *
 
1405
 *                                                                      *
 
1406
 ************************************************************************/
 
1407
 
 
1408
/*
 
1409
 *      NAME
 
1410
 *              LoadSCCData - Read and store the screen data
 
1411
 *
 
1412
 *      SYNOPSIS
 
1413
 */
 
1414
int
 
1415
LoadSCCData(Display *pDpy, int screenNumber, char *filename, int targetFormat)
 
1416
 
 
1417
/*
 
1418
 *      DESCRIPTION
 
1419
 *              Using the X Device Color Characterization Convention (XDCCC)
 
1420
 *              read the screen data and store it on the root window of the
 
1421
 *              screen.
 
1422
 *
 
1423
 *      RETURNS
 
1424
 *              Returns 0 if failed; otherwise 1.
 
1425
 *
 
1426
 */
 
1427
{    
 
1428
    FILE *stream;
 
1429
    char *pStr;
 
1430
    char buf[BUFSIZ];
 
1431
    char *keyword, *token1, *token2, *token3;
 
1432
    int  state = 0;
 
1433
    int VisualFlag = -2;
 
1434
    Window root;
 
1435
    XDCCC_Matrix matrix;
 
1436
    XDCCC_Correction* CorrectionTail = (XDCCC_Correction*)NULL;
 
1437
    XDCCC_Correction* CorrectionHead = (XDCCC_Correction*)NULL;
 
1438
    XDCCC_Correction* pCurrent;
 
1439
 
 
1440
    if (screenNumber < 0) {
 
1441
        fprintf(stderr,"Invalid Screen Number %d\n", screenNumber);
 
1442
        return(0);
 
1443
    }
 
1444
    root = RootWindow(pDpy, screenNumber);
 
1445
 
 
1446
    if (!root) {
 
1447
        /* if no root window is available then return an error */
 
1448
        fprintf(stderr,"Could not open root window supplied.\n ");
 
1449
        return (0);
 
1450
    }
 
1451
    /*
 
1452
     * Open the file, determine its size, then read it into memory.
 
1453
     */
 
1454
    if (filename == NULL) {
 
1455
        stream = stdin;
 
1456
        filename = "stdin";
 
1457
    } else if ((stream = fopen(filename, "r")) == NULL) {
 
1458
        fprintf(stderr,"Could not open file %s.\n", filename);
 
1459
        return (0);
 
1460
    }
 
1461
 
 
1462
    /*
 
1463
     * Advance to starting keyword 
 
1464
     * Anything before this keyword is just treated as comments.
 
1465
     */
 
1466
 
 
1467
    while((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
 
1468
        keyword = strtok(buf, DATA_DELIMS);
 
1469
        if (keyword != (char *)NULL &&
 
1470
                (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) {
 
1471
            break;
 
1472
        }  /* else ignore the line */
 
1473
    }
 
1474
 
 
1475
    if (pStr == NULL) {
 
1476
        fprintf(stderr,"File %s is missing %s\n", filename, SC_BEGIN_KEYWORD);
 
1477
        closeS (stream, CorrectionHead);
 
1478
        return (0);
 
1479
    }
 
1480
 
 
1481
    token1 = strtok((char*)NULL, DATA_DELIMS);
 
1482
    if ((strcmp(token1, TXT_FORMAT_VERSION) != 0) &&
 
1483
            (strcmp(token1, "0.3") != 0)) {
 
1484
        fprintf(stderr,
 
1485
    "Screen data format version mismatch in file %s-- expected %s, found %s\n",
 
1486
                filename, TXT_FORMAT_VERSION, token1);
 
1487
        closeS (stream, CorrectionHead);
 
1488
        return (0);
 
1489
    }
 
1490
 
 
1491
    while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
 
1492
        token1 = token2 = token3 = (char*)NULL;
 
1493
        keyword = strtok(buf, DATA_DELIMS);
 
1494
        if (keyword != (char*)NULL) {
 
1495
            switch (SCKeyOf(keyword)) {
 
1496
              case COMMENT :
 
1497
              case NAME :
 
1498
              case PART_NUMBER :
 
1499
              case MODEL :
 
1500
              case SERIAL_NUMBER :
 
1501
              case REVISION :
 
1502
                /* Do nothing */
 
1503
                break;
 
1504
              case SCREEN_CLASS :
 
1505
                token1 = strtok((char*)NULL, DATA_DELIMS);
 
1506
                token2 = strtok((char*)NULL, DATA_DELIMS);
 
1507
                if ((token1 == (char*)NULL)
 
1508
                        || ((VisualFlag = SCScrnClassOf(token1)) == -1)) {
 
1509
                    closeS (stream, CorrectionHead);
 
1510
                    return (0);
 
1511
                }
 
1512
                /*include code to handle screen number input*/
 
1513
                if (token2 != (char*)NULL) {
 
1514
                    screenNumber = atoi(token2);
 
1515
 
 
1516
                    if (screenNumber < 0) {
 
1517
                        fprintf(stderr,"Invalid Screen Number %d\n", 
 
1518
                                screenNumber);
 
1519
                    }
 
1520
                    else {
 
1521
                        root = RootWindow(pDpy, screenNumber);
 
1522
                        if (!root) {
 
1523
        /* if no root window is available then return an error */
 
1524
                            fprintf(stderr,
 
1525
                                    "Could not open root window supplied.\n ");
 
1526
                            return (0);
 
1527
                        }
 
1528
                    }
 
1529
                }
 
1530
                break;
 
1531
              case COLORIMETRIC_BEGIN :
 
1532
                if (VisualFlag == -2) {
 
1533
                    closeS (stream, CorrectionHead);
 
1534
                    return (0);
 
1535
                }
 
1536
                if (!ProcessColorimetric(stream, 
 
1537
                                         &matrix, VisualFlag)) {
 
1538
                    closeS (stream, CorrectionHead);
 
1539
                    return (0);
 
1540
                }
 
1541
                state |= 0x02;
 
1542
                break;
 
1543
              case IPROFILE_BEGIN :
 
1544
                if (VisualFlag == -2) {
 
1545
                    closeS (stream, CorrectionHead);
 
1546
                    return (0);
 
1547
                }
 
1548
                token1 = strtok((char*)NULL, DATA_DELIMS);
 
1549
                token2 = strtok((char*)NULL, DATA_DELIMS);
 
1550
                if ((token1 == (char*)NULL) || (token2 == (char*)NULL)) {
 
1551
                    fprintf(stderr,
 
1552
                        "Line %d: Intensity profile missing TableType and/or nTables.",
 
1553
                        linenum);
 
1554
                    closeS (stream, CorrectionHead);
 
1555
                    return (0);
 
1556
                }
 
1557
 
 
1558
                if ((pCurrent = (XDCCC_Correction *)
 
1559
                        calloc(1, sizeof(XDCCC_Correction))) ==NULL) {
 
1560
                    fprintf(stderr,
 
1561
                        "Line %d: Could not allocate memory for intensity profile.",
 
1562
                        linenum);
 
1563
                    closeS (stream, CorrectionHead);
 
1564
                    return (0);
 
1565
                }
 
1566
 
 
1567
                if (sscanf(token1, "%d", &pCurrent->tableType) != 1 ||
 
1568
                    (pCurrent->tableType < 0 || pCurrent->tableType > 1)) {
 
1569
                    fprintf(stderr,
 
1570
                            "Line %d: invalid table type specified -- %s\n",
 
1571
                            linenum, buf);
 
1572
                    closeS (stream, CorrectionHead);
 
1573
                    return (0);
 
1574
                } 
 
1575
 
 
1576
                if ((VisualFlag == VIDEO_RGB) && (token2 == (char *)NULL)) {
 
1577
                    fprintf(stderr,
 
1578
                        "Line %d: invalid number of tables specified -- %s\n",
 
1579
                            linenum, buf);
 
1580
                    closeS (stream, CorrectionHead);
 
1581
                    return (0);
 
1582
                }
 
1583
 
 
1584
                if (VisualFlag == VIDEO_RGB) {
 
1585
                    if (sscanf(token2, "%d", &pCurrent->nTables) != 1 ||
 
1586
                            (pCurrent->nTables != 0 && pCurrent->nTables != 1
 
1587
                            && pCurrent->nTables != 3)) {
 
1588
                        fprintf(stderr,
 
1589
                                "Line %d: invalid number of tables (must be 0, 1, or 3)\n",
 
1590
                                linenum);
 
1591
                        closeS (stream, CorrectionHead);
 
1592
                        return (0);
 
1593
                    }
 
1594
                } else {
 
1595
                    pCurrent->nTables = 0;
 
1596
                }
 
1597
 
 
1598
                token3 = strtok((char*)NULL, "\n");
 
1599
                if (token3 != (char*)NULL) {
 
1600
                    if (!ParseVisualOptions(pDpy, pCurrent, token3)) {
 
1601
                        goto ByPassThisIProfile;
 
1602
                    } 
 
1603
                }
 
1604
 
 
1605
                switch (pCurrent->nTables) {
 
1606
                  case 3 :
 
1607
                    if (!(pCurrent->pRedTbl = (IntensityTbl *)
 
1608
                        calloc (1, sizeof (IntensityTbl)))) {
 
1609
                        fprintf(stderr,
 
1610
                               "Line %d: Could not allocate Red Intensity Table\n",
 
1611
                               linenum);
 
1612
                        closeS (stream, CorrectionHead);
 
1613
                        return (0);
 
1614
                    }
 
1615
                    if (!(pCurrent->pGreenTbl = (IntensityTbl *)
 
1616
                        calloc (1, sizeof (IntensityTbl)))) {
 
1617
                        fprintf(stderr,
 
1618
                             "Line %d: Could not allocate Green Intensity Table\n",
 
1619
                             linenum);
 
1620
                        closeS (stream, CorrectionHead);
 
1621
                        return (0);
 
1622
                    }
 
1623
                    if (!(pCurrent->pBlueTbl = (IntensityTbl *)
 
1624
                        calloc (1, sizeof (IntensityTbl)))) {
 
1625
                        fprintf(stderr,
 
1626
                                "Line %d: Could not allocate Blue Intensity Table",
 
1627
                                linenum);
 
1628
                        closeS (stream, CorrectionHead);
 
1629
                        return (0);
 
1630
                    }
 
1631
                    if (!ProcessIProfile(stream, pCurrent)) {
 
1632
                        goto ByPassThisIProfile;
 
1633
                    }
 
1634
                    break;
 
1635
                  case 1 :
 
1636
                    if (!(pCurrent->pRedTbl = (IntensityTbl *)
 
1637
                          calloc (1, sizeof (IntensityTbl)))) {
 
1638
                        fprintf(stderr,
 
1639
                                "Line %d: Could not allocate Red Intensity Table",
 
1640
                                linenum);
 
1641
                        closeS (stream, CorrectionHead);
 
1642
                        return (0);
 
1643
                    }
 
1644
                    pCurrent->pGreenTbl = pCurrent->pRedTbl;
 
1645
                    pCurrent->pBlueTbl = pCurrent->pRedTbl;
 
1646
                    if (!ProcessIProfile(stream, pCurrent)) {
 
1647
                        goto ByPassThisIProfile;
 
1648
                    }
 
1649
                    break;
 
1650
                  default :
 
1651
                    /* do nothing */
 
1652
                    break;
 
1653
                }
 
1654
 
 
1655
                if (CorrectionHead == NULL) {
 
1656
                    CorrectionHead = CorrectionTail = pCurrent;
 
1657
                } else {
 
1658
                    CorrectionTail->next = pCurrent;
 
1659
                    CorrectionTail = pCurrent;
 
1660
                }
 
1661
                state |= 0x04;
 
1662
                break;
 
1663
ByPassThisIProfile:
 
1664
                /* read till INTENSITY_PROFILE_END */
 
1665
                while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
 
1666
                    keyword = strtok(buf, DATA_DELIMS);
 
1667
                    if (keyword != (char*)NULL) {
 
1668
                        switch (SCKeyOf(keyword)) {
 
1669
                          case ITBL_BEGIN:
 
1670
                          case ITBL_END:
 
1671
                          case COMMENT:
 
1672
                          case DATA:
 
1673
                            break;
 
1674
                          case IPROFILE_END:
 
1675
                            goto IProfileProcessed;
 
1676
                          default:
 
1677
                            closeS (stream, CorrectionHead);
 
1678
                            return (0);
 
1679
                        }
 
1680
                    }
 
1681
                }
 
1682
                free(pCurrent);
 
1683
IProfileProcessed:
 
1684
                state |= 0x04;
 
1685
                break;
 
1686
              case SC_END :
 
1687
                if (!(state & 0x02)) {
 
1688
                    fprintf(stderr,
 
1689
                            "File %s is missing Colorimetric data.\n", 
 
1690
                            filename);
 
1691
                    closeS (stream, CorrectionHead);
 
1692
                    return (0);
 
1693
                }
 
1694
                if (!(state & 0x04)) {
 
1695
                    fprintf(stderr,
 
1696
                            "File %s is missing Intensity Profile Data.\n",
 
1697
                            filename);
 
1698
                }
 
1699
                if (VisualFlag == VIDEO_RGB) {
 
1700
                    LoadMatrix(pDpy, root, &matrix);
 
1701
                    if (!LoadCorrections(pDpy, root, CorrectionHead,
 
1702
                            targetFormat)) {
 
1703
                        closeS (stream, CorrectionHead);
 
1704
                        return (0);
 
1705
                    }
 
1706
#ifdef GRAY
 
1707
                } else if (VisualFlag == VIDEO_GRAY) {
 
1708
                    if (!LoadDataGray(pDpy, root,
 
1709
                                      pCurrent->tableType, pScreenData, targetFormat)) {
 
1710
                        closeS (stream, CorrectionHead);
 
1711
                        return (0);
 
1712
                    }
 
1713
#endif /* GRAY */
 
1714
                } else {
 
1715
                    fprintf(stderr,"File %s Visual missing.", filename);
 
1716
                }
 
1717
                closeS (stream, CorrectionHead);
 
1718
                return (1);
 
1719
/* NOTREACHED */    break;
 
1720
              default :
 
1721
                fprintf(stderr,"Line %d: extraneous keyword %s\n", 
 
1722
                        linenum, keyword);
 
1723
                closeS (stream, CorrectionHead);
 
1724
                return (0);
 
1725
 
 
1726
            }
 
1727
        }   /* else it was just a blank line */
 
1728
    }
 
1729
    closeS (stream, CorrectionHead);
 
1730
    return (1);
 
1731
}