home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xcmsdb / loadData.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-22  |  39.3 KB  |  1,470 lines

  1. /* $XConsortium: loadData.c,v 1.8 91/07/22 14:58:03 rws 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.  
  35. /*
  36.  *      INCLUDES
  37.  */
  38.  
  39. #include <X11/Xos.h>
  40. #include <sys/stat.h>
  41. #include <stdio.h>
  42.  
  43. #include <X11/Xlib.h>
  44. #include <X11/Xatom.h>
  45. #include "Xcmsint.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. #ifdef X_NOT_STDC_ENV
  57. extern char *strtok();
  58. extern char *strchr();
  59. #endif
  60. #ifndef X_NOT_STDC_ENV
  61. #include <stdlib.h>
  62. #else
  63. char *calloc();
  64. #endif
  65. #if defined(macII) && !defined(__STDC__)  /* stdlib.h fails to define these */
  66. char *calloc();
  67. #endif /* macII */
  68.  
  69. /* extern int LINEAR_RGB_FreeSCCData(); /* /* XXX Xlib internal */
  70.  
  71. /*
  72.  *      LOCAL TYPEDEFS
  73.  *              typedefs local to this package (for use with local vars).
  74.  *
  75.  */
  76.  
  77. typedef struct _DefineEntry {
  78.     char    *pString;
  79.     int        define;
  80. } DefineEntry;
  81.  
  82.  
  83. /*
  84.  *      LOCAL VARIABLES
  85.  */
  86. static int linenum = 0;
  87.  
  88. static DefineEntry KeyTbl[] = {
  89.     SC_BEGIN_KEYWORD,        SC_BEGIN,
  90.     SC_END_KEYWORD,        SC_END,
  91.     COMMENT_KEYWORD,        COMMENT,
  92.     NAME_KEYWORD,        NAME,
  93.     MODEL_KEYWORD,        MODEL,
  94.     PART_NUMBER_KEYWORD,    PART_NUMBER,
  95.     SERIAL_NUMBER_KEYWORD,    SERIAL_NUMBER,
  96.     REVISION_KEYWORD,        REVISION,
  97.     SCREEN_CLASS_KEYWORD,    SCREEN_CLASS,
  98.     COLORIMETRIC_BEGIN_KEYWORD,    COLORIMETRIC_BEGIN,
  99.     COLORIMETRIC_END_KEYWORD,    COLORIMETRIC_END,
  100.     XYZTORGBMAT_BEGIN_KEYWORD,    XYZTORGBMAT_BEGIN,
  101.     XYZTORGBMAT_END_KEYWORD,    XYZTORGBMAT_END,
  102.     WHITEPT_XYZ_BEGIN_KEYWORD,    WHITEPT_XYZ_BEGIN,
  103.     WHITEPT_XYZ_END_KEYWORD,    WHITEPT_XYZ_END,
  104.     RGBTOXYZMAT_BEGIN_KEYWORD,    RGBTOXYZMAT_BEGIN,
  105.     RGBTOXYZMAT_END_KEYWORD,    RGBTOXYZMAT_END,
  106.     IPROFILE_BEGIN_KEYWORD,    IPROFILE_BEGIN,
  107.     IPROFILE_END_KEYWORD,    IPROFILE_END,
  108.     ITBL_BEGIN_KEYWORD,        ITBL_BEGIN,
  109.     ITBL_END_KEYWORD,        ITBL_END,
  110.     "",                -1
  111. };
  112.  
  113. static DefineEntry ScrnClassTbl[] = {
  114.     VIDEO_RGB_KEYWORD,        VIDEO_RGB,
  115. #ifdef GRAY
  116.     VIDEO_GRAY_KEYWORD,        VIDEO_GRAY,
  117. #endif /* GRAY */
  118.     "",                -1
  119. };
  120.  
  121.  
  122. /************************************************************************
  123.  *                                    *
  124.  *             PRIVATE ROUTINES                *
  125.  *                                    *
  126.  ************************************************************************/
  127.  
  128. /*
  129.  *    NAME
  130.  *        StrToDefine - convert a string to a define
  131.  *
  132.  *    SYNOPSIS
  133.  */
  134. static int
  135. StrToDefine(pde,pstring)
  136.     DefineEntry    pde[];    /* IN: table of X string-define pairs        */
  137.             /*     last entry must contain pair "", 0    */
  138.     char *pstring;    /* IN: string to be looked up in that table    */
  139. /*
  140.  *    DESCRIPTION
  141.  *        Converts a string to an integer define.
  142.  *
  143.  *        Looks up the string in the table and returns the integer
  144.  *        associated with the string.
  145.  *
  146.  *        Later may need similar function for unsigned long define.
  147.  *
  148.  *
  149.  *
  150.  *    RETURNS
  151.  *        The int equivalent of the defined string.
  152.  *        -1 if the string is not found in table
  153.  *
  154.  */
  155. {
  156.     while( strcmp(pde->pString,"") != 0 ){
  157.     if( strcmp(pde->pString,pstring) == 0){
  158.         return(pde->define);
  159.     }
  160.     pde++;
  161.     }
  162.     return(-1);
  163. }
  164.  
  165. /*
  166.  *    NAME
  167.  *        DefineToStr
  168.  *
  169.  *    SYNOPSIS
  170.  */
  171. static char *
  172. DefineToStr(pde,id)
  173.     DefineEntry    pde[];    /* IN: table of X string-define pairs        */
  174.             /*     last entry must contain pair "", 0    */
  175.     int        id;    /* IN: id to be looked up in that table    */
  176. /*
  177.  *    DESCRIPTION
  178.  *        Converts a string to an integer define.
  179.  *
  180.  *        Looks up the string in the table and returns the integer
  181.  *        associated with the string.
  182.  *
  183.  *        Later may need similar function for unsigned long define.
  184.  *
  185.  *
  186.  *
  187.  *    RETURNS
  188.  *        The int equivalent of the defined string.
  189.  *        -1 if the string is not found in table
  190.  *
  191.  */
  192. {
  193.     while(pde->define != -1) {
  194.     if (pde->define == id) {
  195.         return(pde->pString);
  196.     }
  197.     pde++;
  198.     }
  199.     return(NULL);
  200. }
  201.  
  202. /*
  203.  *    NAME
  204.  *        SCKeyOf - convert keyword into key ID
  205.  *
  206.  *    SYNOPSIS
  207.  */
  208. static int
  209. SCKeyOf(string)
  210.     char *string;
  211. /*
  212.  *    DESCRIPTION
  213.  *        Converts a string to an integer define.
  214.  *
  215.  *        Looks up the string in the table and returns the integer
  216.  *        associated with the string.
  217.  *
  218.  *        Later may need similar function for unsigned long define.
  219.  *
  220.  *
  221.  *
  222.  *    RETURNS
  223.  *        The int equivalent of the defined string.
  224.  *        -1 if the string is not found in table
  225.  *
  226.  */
  227. {
  228.     return(StrToDefine(KeyTbl, string));
  229. }
  230.  
  231.  
  232. /*
  233.  *    NAME
  234.  *        SCScrnClassOf - convert screen class string into class ID
  235.  *
  236.  *    SYNOPSIS
  237.  */
  238. static int
  239. SCScrnClassOf(string)
  240.     char *string;
  241. /*
  242.  *    DESCRIPTION
  243.  *        Converts a string to an integer define.
  244.  *
  245.  *        Looks up the string in the table and returns the integer
  246.  *        associated with the string.
  247.  *
  248.  *        Later may need similar function for unsigned long define.
  249.  *
  250.  *
  251.  *
  252.  *    RETURNS
  253.  *        The int equivalent of the defined string.
  254.  *        -1 if the string is not found in table
  255.  *
  256.  */
  257. {
  258.     return(StrToDefine(ScrnClassTbl, string));
  259. }
  260.  
  261.  
  262. /*
  263.  *    NAME
  264.  *        SCScrnClassStringOf - convert screen class id into class string
  265.  *
  266.  *    SYNOPSIS
  267.  */
  268. static char *
  269. SCScrnClassStringOf(id)
  270.     int id;
  271. /*
  272.  *    DESCRIPTION
  273.  *        Converts a id to astring
  274.  *
  275.  *    RETURNS
  276.  *        Pointer to string if found; otherwise NULL.
  277.  *
  278.  */
  279. {
  280.     return(DefineToStr(ScrnClassTbl, id));
  281. }
  282.  
  283. /* close the stream and return any memory allocated. */
  284. /*ARGSUSED*/
  285. static void 
  286. closeS(stream, pScreenData) 
  287.     FILE *stream;
  288.     LINEAR_RGB_SCCData *pScreenData;
  289. {
  290.     if (stream) {
  291.         fclose (stream);
  292.     }
  293.     /* (void) LINEAR_RGB_FreeSCCData(pScreenData); */ /* Xlib internal */
  294. }
  295.  
  296. /*
  297.  *  Get a line of text from the stream.
  298.  */
  299. static char *
  300. nextline(buf, maxch, stream)
  301.     char *buf;
  302.     int    maxch;
  303.     FILE *stream;
  304. {
  305.     linenum++;
  306.     return (fgets(buf, maxch, stream));
  307. }
  308.  
  309.  
  310. static int
  311. ProcessColorimetric(stream, pScreenData, filename, VisualFlag)
  312.     FILE *stream;
  313.     LINEAR_RGB_SCCData *pScreenData;
  314.     char *filename;
  315.     int VisualFlag;
  316. {
  317.     char buf[BUFSIZ];
  318.     char keyword[BUFSIZ];
  319.     char token[BUFSIZ], *ptoken;
  320.     int  ntok;
  321.     int     state = 0;
  322.          /* 0 -- looking for XYZTORGBMAT */
  323.          /* 1 -- processing data for XYZTORGBMAT */
  324.          /* 2 -- completed processing XYZTORGBMAT and */
  325.          /*      looking for RGBTOXYZMat */
  326.          /* 3 -- processing data fro RGBTOXYZMat */
  327.          /* 4 -- completed processing RGBTOXYZMat */
  328.          /* Note: the order of the matrices is important. */
  329.          /*       The XYZTORGBMAT must preceed the RGBTOXYZMat. */
  330.     int     count;
  331.     XcmsFloat *pElement;
  332.     float fNum;
  333.  
  334.     while ((nextline(buf, BUFSIZ, stream)) != NULL) {
  335.     if ((ntok = sscanf(buf, "%s %s", keyword, token)) > 0) {
  336.         switch (SCKeyOf(keyword)) {
  337.           case XYZTORGBMAT_BEGIN :
  338.         if (VisualFlag != VIDEO_RGB) {
  339.           fprintf(stderr, 
  340.              "Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n",
  341.               SCScrnClassStringOf(VisualFlag));
  342.           return (0);
  343.         }
  344.         if (state != 0) {
  345.           fprintf(stderr,
  346.               "Extraneous keyword %s in file %s.\n", 
  347.               keyword, filename);
  348.           return (0);
  349.         }
  350.         state = 1;
  351.         count = 0;
  352.         pElement = (XcmsFloat *) pScreenData->XYZtoRGBmatrix;
  353.         break;
  354.           case XYZTORGBMAT_END :
  355.         if (VisualFlag != VIDEO_RGB) {
  356.           fprintf(stderr, 
  357.               "Keyword XYZTORGBMAT_END mismatch for visual %s.\n",
  358.               SCScrnClassStringOf(VisualFlag));
  359.           return (0);
  360.         }
  361.         if ((state != 1) || (count != 9)) {
  362.           fprintf(stderr,
  363.               "Incomplete A matrix in file %s -- Premature %s\n", 
  364.               keyword, filename);
  365.           return (0);
  366.         }
  367.         state = 2;
  368.         break;
  369.           case RGBTOXYZMAT_BEGIN :
  370.         if (VisualFlag != VIDEO_RGB) {
  371.           fprintf(stderr,
  372.              "Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n",
  373.               SCScrnClassStringOf(VisualFlag));
  374.           return (0);
  375.         }
  376.         if (state != 0 && state != 2) {
  377.             fprintf(stderr, "Extraneous keyword %s in file %s.\n", 
  378.                 keyword, filename);
  379.             return (0);
  380.         }
  381.         state = 3;
  382.         count = 0;
  383.         pElement = (XcmsFloat *) pScreenData->RGBtoXYZmatrix;
  384.         break;
  385.           case RGBTOXYZMAT_END :
  386.         if (VisualFlag != VIDEO_RGB) {
  387.             fprintf(stderr, 
  388.                "Keyword RGBTOXYZMAT_END mismatch for visual %s.\n",
  389.                 SCScrnClassStringOf(VisualFlag));
  390.             return (0);
  391.         }
  392.         if ((state != 3) || (count != 9)) {
  393.             fprintf(stderr, 
  394.                "Incomplete A matrix in file %s -- Premature %s\n", 
  395.                 keyword, filename);
  396.             return (0);
  397.         }
  398.         state = 4;
  399.         break;
  400. #ifdef GRAY
  401.           case WHITEPT_XYZ_BEGIN :
  402.         if (VisualFlag != VIDEO_GRAY) {
  403.             fprintf(stderr,
  404.              "Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n",
  405.                 SCScrnClassStringOf(VisualFlag));
  406.             return (0);
  407.         }
  408.         if (state != 0) {
  409.           fprintf(stderr,
  410.               "Extraneous keyword %s in file %s.\n", 
  411.               keyword, filename);
  412.           return (0);
  413.         }
  414.         state = 1;
  415.         count = 0;
  416.         pElement = (XcmsFloat *) pScreenData->XYZtoRGBmatrix;
  417.         break;
  418.           case WHITEPT_XYZ_END :
  419.         if (VisualFlag != VIDEO_GRAY) {
  420.             fprintf(stderr,
  421.                "Keyword WHITEPT_XYZ_END mismatch for visual %s.\n",
  422.                 SCScrnClassStringOf(VisualFlag));
  423.             return (0);
  424.         }
  425.         if ((state != 1) || (count != 3)) {
  426.             fprintf(stderr,
  427.             "Incomplete white point in file %s -- Premature %s\n", 
  428.                 keyword, filename);
  429.             return (0);
  430.         }
  431.         state = 4;
  432.         break;
  433. #endif /* GRAY */
  434.           case DATA :
  435.         for (ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
  436.             ptoken = strtok(NULL, DATA_DELIMS)) {
  437.             /*******************************************************
  438.              *  This magic about fNum converted to XcmsFloat is 
  439.              *  because our stupid sscanf does not understand that 
  440.              *  %f also applies to doubles.
  441.              *******************************************************/
  442.             if (sscanf(ptoken, "%f", &fNum) != 1) {
  443.             if (VisualFlag == VIDEO_RGB) {
  444.                 fprintf(stderr,
  445.                     "Invalid A Matrix value %s in file %s.", 
  446.                     ptoken, filename);
  447.             } else {
  448.                 fprintf(stderr,
  449.                     "Invalid CIEXYZ value %s in file %s.\n",
  450.                     ptoken, filename);
  451.             }
  452.             return (0);
  453.             }
  454.             *pElement++ = (XcmsFloat) fNum;
  455.             if (VisualFlag == VIDEO_RGB) {
  456.             if (++count > 9) {
  457.                 fprintf(stderr,
  458.                    "Extra A Matrix value %s in filename %s\n", 
  459.                     ptoken, filename);
  460.                 return (0);
  461.             }
  462.             } else {
  463.             if (++count > 3) {
  464.                 fprintf(stderr,
  465.                     "Extra CIEXYZ value %s in file %s.\n",
  466.                     ptoken, filename);
  467.                 return (0);
  468.               }
  469.             }
  470.         }
  471.         break;
  472.           case COLORIMETRIC_BEGIN :
  473.         fprintf(stderr, 
  474.             "Extraneous keyword %s in file %s.\n", 
  475.             keyword, filename);
  476.         return (0);
  477. /* NOTREACHED */break;    
  478.           case COLORIMETRIC_END :
  479.         if (state != 4) {
  480.             fprintf(stderr,
  481.            "Incomplete Colorimetric data in file %s -- Premature %s\n",
  482.                 filename, keyword);
  483.             return (0);
  484.         }
  485.         return (1);
  486.           case COMMENT :
  487.         /* Currently, do nothing. */
  488.         break;
  489.           default :
  490.         fprintf(stderr,
  491.             "Unexpected keyword %s in file %s\n",
  492.             keyword, filename);
  493.         return (0);
  494. /* NOTREACHED */break;        
  495.         }
  496.     } else if (ntok < 0) {
  497.         /* mismatch */
  498.         fprintf(stderr, "Unrecognized keyword\n");
  499.         return (0);
  500. /* NOTREACHED */break;        
  501.     }
  502.     }
  503.     return (0);
  504. }
  505.  
  506. static int
  507. ProcessIProfile(stream, pScreenData, tableType, nTables, filename)
  508.     FILE *stream;
  509.     LINEAR_RGB_SCCData *pScreenData;
  510.     int  tableType, nTables;
  511.     char *filename;
  512. {
  513.     char buf[BUFSIZ];
  514.     char keyword[BUFSIZ];
  515.     char tableStr[BUFSIZ], *ptoken;
  516.     int  ntok;
  517.     int  size;
  518.     int     state = 0;
  519.      /************************************************
  520.       * 0 -- Looking for Intensity Table(s)          *
  521.       * 1 -- Processing Intensity Table(s)           *
  522.           ************************************************/
  523.     int     nTbl = 0;
  524.     int     count = 0;
  525.     IntensityRec *pIRec = NULL;
  526.     float fNum;
  527.     int dNum;
  528.  
  529.     while ((nextline(buf, BUFSIZ, stream)) != NULL) {
  530.     if ((ntok = sscanf(buf, "%s %s %d", keyword, tableStr, &size)) > 0) {
  531.         switch (SCKeyOf(keyword)) {
  532.           case ITBL_BEGIN :
  533.         if (state != 0) {
  534.             fprintf(stderr,"File %s has an unexpected keyword %s\n", 
  535.                filename, keyword);
  536.             return (0);
  537.         }
  538.         if (size < 0) {
  539.             fprintf(stderr,
  540.                 "File %s has count %d < 0 for Intensity Table.\n",
  541.                   filename, size);
  542.             return (0);
  543.         }
  544.         if (strcmp(tableStr, "GREEN") == 0) {
  545.             if (nTables != 3) {
  546.             fprintf(stderr,"File %s incorrect number of tables\n", 
  547.             filename);
  548.             return (0);
  549.             }
  550.             if (pScreenData->pGreenTbl->pBase != NULL) {
  551.             fprintf(stderr,
  552.                  "File %s has multiple GREEN Intensity Profiles\n",
  553.                        filename);
  554.             return (0);
  555.             }
  556.             pScreenData->pGreenTbl->nEntries = size;
  557.             pScreenData->pGreenTbl->pBase =
  558.              (IntensityRec *) calloc (size, sizeof(IntensityRec));
  559.             if (!pScreenData->pGreenTbl->pBase) {
  560.             fprintf(stderr,
  561.              "Unable to allocate space for GREEN Intensity Profile\n");
  562.             return (0);
  563.             }
  564.             pIRec = pScreenData->pGreenTbl->pBase;
  565.         } else if (strcmp(tableStr, "BLUE") == 0) {
  566.             if (nTables != 3) {
  567.             fprintf(stderr,
  568.                 "File %s incorrect number of tables\n",
  569.                 filename);
  570.             return (0);
  571.             }
  572.             if (pScreenData->pBlueTbl->pBase != NULL) {
  573.             fprintf(stderr,
  574.                   "File %s has multiple BLUE Intensity Profiles\n",
  575.                        filename);
  576.             return (0);
  577.             }
  578.             pScreenData->pBlueTbl->nEntries = size;
  579.             pScreenData->pBlueTbl->pBase =
  580.              (IntensityRec *) calloc (size, sizeof(IntensityRec));
  581.             if (!pScreenData->pBlueTbl->pBase) {
  582.             fprintf(stderr,
  583.               "Unable to allocate space for BLUE Intensity Profile\n");
  584.             return (0);
  585.             }
  586.             pIRec = pScreenData->pBlueTbl->pBase;
  587.         } else {
  588.             if (!strcmp(tableStr, "RGB") && nTables != 1) {
  589.             fprintf(stderr,"File %s has multiple RGB Intensity Tables",
  590.                   filename);
  591.             return (0);
  592.             }
  593.             if (pScreenData->pRedTbl->pBase != NULL) {
  594.             fprintf(stderr,
  595.           "File %s has multiple RED or GRAY or RGB Intensity Tables\n",
  596.                    filename);
  597.             return (0);
  598.             }
  599.             pScreenData->pRedTbl->nEntries = size;
  600.             pScreenData->pRedTbl->pBase = 
  601.              (IntensityRec *) calloc (size, sizeof(IntensityRec));
  602.             if (!pScreenData->pRedTbl->pBase) {
  603.             fprintf(stderr,
  604.                  "Unable to allocate space for intensity table\n");
  605.             return (0);
  606.             }
  607.             pIRec = pScreenData->pRedTbl->pBase;
  608.         }
  609.         state = 1;
  610.         count = 0;
  611.         break;
  612.           case ITBL_END :
  613.         if ((state != 1) || (count != size)) {
  614.             fprintf(stderr,
  615.             "File %s has incomplete Intensity Table -- Premature %s\n",
  616.               filename, keyword);
  617.             return (0);
  618.         }
  619.         nTbl++;
  620.         state = 0;
  621.         break;
  622.           case DATA :
  623.         for (ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL;
  624.             ptoken = strtok(NULL, DATA_DELIMS)) {
  625.             /********************************************************
  626.              * Note: tableType should only be 0 or 1 at this point. 
  627.              *       0 indicates value and intensity stored.
  628.              *       1 indicates only intensity stored. 
  629.              ********************************************************/
  630.             if (tableType) {
  631.             if (sscanf(ptoken, "%f", &fNum) != 1) {
  632.                 fprintf(stderr,
  633.                "File %s has invalid Intensity Profile value %s\n", 
  634.                   filename, ptoken);
  635.                 return (0);
  636.             }
  637.             /* With tableType 1 only store the intensity. */
  638.             pIRec->intensity = (XcmsFloat) fNum;
  639.             pIRec++;
  640.             } else {
  641. #ifndef ANSI_C        /* Note ansi C can handle 0x preceeding hex number */
  642.             if (*ptoken == '0' && *(ptoken+1) == 'x') 
  643.                 ptoken += 2;
  644. #endif /* ANSI_C */
  645.             /****************************************************
  646.                  *  This magic about dNum is required because of 
  647.              *  a stupid compiler that does not know that %x
  648.              *  also applies to shorts.
  649.              ****************************************************/
  650.             if (sscanf(ptoken, "%x", &dNum) != 1) {
  651.                 fprintf(stderr,
  652.                 "File %s has invalid Intensity Profile value %s\n",
  653.                   filename, ptoken);
  654.                 return (0);
  655.             }
  656.             if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) {
  657.                 fprintf(stderr,
  658.                   "File %s is missing Intensity Profile value",
  659.                   filename);
  660.                 return (0);
  661.             }
  662.             /****************************************************
  663.                  *  This magic about fNum is required because of 
  664.              *  a stupid compiler that does not know that %f
  665.              *  also applies to doubles.
  666.              ****************************************************/
  667.             if (sscanf(ptoken, "%f", &fNum) != 1) {
  668.                 fprintf(stderr,
  669.             "File %s has invalid Intensity Profile intensity %s\n",
  670.                   filename, ptoken);
  671.                 return (0);
  672.             }
  673.             /* With tableType 0 only store both value & intensity*/
  674.             pIRec->value = (unsigned short) dNum;
  675.             pIRec->intensity = (XcmsFloat) fNum;
  676.             pIRec++;
  677.             }
  678.             if (++count > size) {
  679.             fprintf(stderr,
  680.                 "File %s has extra Intensity value %s\n",
  681.                 filename, ptoken);
  682.             return (0);
  683.             }
  684.         }
  685.         break;
  686.           case IPROFILE_BEGIN :
  687.         fprintf(stderr,"File %s has extraneous keyword %s\n", 
  688.               filename, keyword);
  689.         return (0);
  690. /* NOTREACHED */break;
  691.           case IPROFILE_END :
  692.         if ((state != 0) || (nTbl != nTables)) {
  693.             fprintf(stderr,
  694.          "File %s has incomplete Intensity Profile data -- Premature %s\n",
  695.                filename, keyword);
  696.             return (0);
  697.         }
  698.         return (1);
  699.           case COMMENT :
  700.         /* ignore line */
  701.         break;
  702.           default :
  703.         fprintf(stderr,"File %s has unexpected keyword %s\n",
  704.               filename, keyword);
  705.         return (0);
  706. /* NOTREACHED */break;
  707.         }
  708.     } else if (ntok < 0) {
  709.         /* mismatch */
  710.         fprintf(stderr,"Unrecognized keyword");
  711.         return (0);
  712. /* NOTREACHED */break;
  713.     }
  714.     }
  715.     return (0);
  716. }
  717.  
  718. static void
  719. PutTableType0Card8(pTbl, pCard8)
  720.     IntensityTbl *pTbl;
  721.     unsigned char **pCard8;
  722. {
  723.     unsigned int count;
  724.     IntensityRec *pIRec;
  725.  
  726.     pIRec = pTbl->pBase;
  727.     count = pTbl->nEntries;
  728.     **pCard8 = count - 1;
  729.     *pCard8 += 1;
  730.     for (; count; count--, pIRec++) {
  731.     **pCard8 = pIRec->value >> 8;
  732.     *pCard8 += 1;
  733.     **pCard8 = pIRec->intensity * 255.0;
  734.     *pCard8 += 1;
  735.     }
  736. }
  737.  
  738. static void
  739. PutTableType1Card8(pTbl, pCard8)
  740.     IntensityTbl *pTbl;
  741.     unsigned char **pCard8;
  742. {
  743.     unsigned int count;
  744.     IntensityRec *pIRec;
  745.  
  746.     pIRec = pTbl->pBase;
  747.     count = pTbl->nEntries;
  748.     **pCard8 = count - 1;
  749.     *pCard8 += 1;
  750.     for (; count; count--, pIRec++) {
  751.     **pCard8 = pIRec->intensity * 255.0;
  752.     *pCard8 += 1;
  753.     }
  754. }
  755.  
  756. static void
  757. PutTableType0Card16(pTbl, pCard16)
  758.     IntensityTbl *pTbl;
  759.     unsigned short **pCard16;
  760. {
  761.     unsigned int count;
  762.     IntensityRec *pIRec;
  763.  
  764.     pIRec = pTbl->pBase;
  765.     count = pTbl->nEntries;
  766.     **pCard16 = count - 1;
  767.     *pCard16 += 1;
  768.     for (; count; count--, pIRec++) {
  769.     **pCard16 = pIRec->value;
  770.     *pCard16 += 1;
  771.     **pCard16 = pIRec->intensity * 65535.0;
  772.     *pCard16 += 1;
  773.     }
  774. }
  775.  
  776. static void
  777. PutTableType1Card16(pTbl, pCard16)
  778.     IntensityTbl *pTbl;
  779.     unsigned short **pCard16;
  780. {
  781.     unsigned int count;
  782.     IntensityRec *pIRec;
  783.  
  784.     pIRec = pTbl->pBase;
  785.     count = pTbl->nEntries;
  786.     **pCard16 = count - 1;
  787.     *pCard16 += 1;
  788.     for (; count; count--, pIRec++) {
  789.     **pCard16 = pIRec->intensity * 65535.0;
  790.     *pCard16 += 1;
  791.     }
  792. }
  793.  
  794. static void
  795. PutTableType0Card32(pTbl, pCard32)
  796.     IntensityTbl *pTbl;
  797.     unsigned long **pCard32;
  798. {
  799.     unsigned int count;
  800.     IntensityRec *pIRec;
  801.  
  802.     pIRec = pTbl->pBase;
  803.     count = pTbl->nEntries;
  804.     **pCard32 = count - 1;
  805.     *pCard32 += 1;
  806.     for (; count; count--, pIRec++) {
  807.     **pCard32 = pIRec->value;
  808.     *pCard32 += 1;
  809.     **pCard32 = pIRec->intensity * 4294967295.0;
  810.     *pCard32 += 1;
  811.     }
  812. }
  813.  
  814. static void
  815. PutTableType1Card32(pTbl, pCard32)
  816.     IntensityTbl *pTbl;
  817.     unsigned long **pCard32;
  818. {
  819.     unsigned int count;
  820.     IntensityRec *pIRec;
  821.  
  822.     pIRec = pTbl->pBase;
  823.     count = pTbl->nEntries;
  824.     **pCard32 = count - 1;
  825.     *pCard32 += 1;
  826.     for (; count; count--, pIRec++) {
  827.     **pCard32 = pIRec->intensity * 4294967295.0;
  828.     *pCard32 += 1;
  829.     }
  830. }
  831.  
  832. static int
  833. LoadDataRGB(pDpy, root, tableType, nTables, pScreenData, targetFormat)
  834.     Display *pDpy;
  835.     Window root;
  836.     int tableType, nTables;
  837.     LINEAR_RGB_SCCData *pScreenData;
  838.     int targetFormat;
  839. {
  840.     unsigned char *ret_prop;
  841.     int  count;
  842.     unsigned char  *pCard8;
  843.     unsigned char  *pCard8Array = (unsigned char *)NULL;
  844.     unsigned short  *pCard16;
  845.     unsigned short  *pCard16Array = (unsigned short *)NULL;
  846.     unsigned long  *pCard32;
  847.     unsigned long  *pCard32Array = (unsigned long *)NULL;
  848.     unsigned long  Card32Array[18];
  849.     int  format;
  850.     unsigned long nitems, ret_after;
  851.     Atom MatricesAtom, CorrectAtom, ret_atom;
  852.     XcmsFloat *pValue;
  853.     int    total;
  854.  
  855.     /*
  856.      * Store the XDCCC_LINEAR_RGB_MATRICES
  857.      */
  858.     pCard32 = Card32Array;
  859.     pValue = (XcmsFloat *)pScreenData->XYZtoRGBmatrix;
  860.     for (count = 0; count < 9; count++) {
  861.     *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
  862.     }
  863.     pValue = (XcmsFloat *)pScreenData->RGBtoXYZmatrix;
  864.     for (count = 0; count < 9; count++) {
  865.     *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
  866.     }
  867.     MatricesAtom = XInternAtom (pDpy, XDCCC_MATRIX_ATOM_NAME, False);
  868.     XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32, 
  869.              PropModeReplace, (unsigned char *)Card32Array, 18);
  870.  
  871.     /*
  872.      * Now store the XDCCC_LINEAR_RGB_CORRECTION
  873.      */
  874.     CorrectAtom = XInternAtom (pDpy, XDCCC_CORRECT_ATOM_NAME, False);
  875.  
  876.     if (tableType != CORR_TYPE_NONE && tableType != 0 && tableType != 1) {
  877.     fprintf(stderr,"Invalid intensity table type %d.\n", tableType);
  878.     return(0);
  879.     }
  880.  
  881.     if (nTables != 1 && nTables != 3) {
  882.     fprintf(stderr,"%d invalid number of tables.\n", nTables);
  883.     return(0);
  884.     }
  885.  
  886.     if (tableType == CORR_TYPE_NONE) {
  887.     XGetWindowProperty (pDpy, root, CorrectAtom, 
  888.                 0, 5, False, XA_INTEGER, 
  889.                 &ret_atom, &format, &nitems, &ret_after,
  890.                 &ret_prop);
  891.     if (format != 0) {
  892.         XDeleteProperty (pDpy, root, CorrectAtom);
  893.         XFree ((char *)ret_prop);
  894.     }
  895.     return (1);
  896.     }
  897.  
  898.     if (nTables == 1) {
  899.     if (pScreenData->pRedTbl->nEntries < 2) {
  900.         fprintf(stderr,"Illegal number of entries in table\n");
  901.         return (0);
  902.     }
  903.     switch (targetFormat) {
  904.       case 8:
  905.         total = 7 + (pScreenData->pRedTbl->nEntries *
  906.             (tableType == 0 ? 2 : 1));
  907.         if ((pCard8 = pCard8Array = (unsigned char *) calloc (total,
  908.             sizeof (unsigned char))) == NULL) {
  909.         fprintf(stderr,"Unable allocate array of ints\n");
  910.         return (0);
  911.         }
  912.         *pCard8++ = 0;        /* VisualID = 0 */
  913.         *pCard8++ = 0;        /* VisualID = 0 */
  914.         *pCard8++ = 0;        /* VisualID = 0 */
  915.         *pCard8++ = 0;        /* VisualID = 0 */
  916.         *pCard8++ = tableType;    /* type */
  917.         *pCard8++ = 1;        /* number of tables = 1 */
  918.         if (tableType == 0) {
  919.         PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
  920.         } else {
  921.         PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
  922.         }
  923.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
  924.             PropModeReplace, (unsigned char *)pCard8Array, total);
  925.         free(pCard8Array);
  926.         break;
  927.       case 16:
  928.         total = 5 + (pScreenData->pRedTbl->nEntries * 
  929.             (tableType == 0 ? 2 : 1));
  930.         if ((pCard16 = pCard16Array = (unsigned short *) calloc (total,
  931.             sizeof (unsigned short))) == NULL) {
  932.         fprintf(stderr,"Unable allocate array of ints\n");
  933.         return (0);
  934.         }
  935.         *pCard16++ = 0;        /* VisualID = 0 */
  936.         *pCard16++ = 0;        /* VisualID = 0 */
  937.         *pCard16++ = tableType;    /* type */
  938.         *pCard16++ = 1;        /* number of tables = 1 */
  939.         if (tableType == 0) {
  940.         PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
  941.         } else {
  942.         PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
  943.         }
  944.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
  945.             PropModeReplace, (unsigned char *)pCard16Array, total);
  946.         free(pCard16Array);
  947.         break;
  948.       case 32:
  949.         total = 4 + (pScreenData->pRedTbl->nEntries * 
  950.             (tableType == 0 ? 2 : 1));
  951.         if ((pCard32 = pCard32Array =
  952.             (unsigned long *) calloc (total,
  953.             sizeof (unsigned long))) == NULL) {
  954.         fprintf(stderr,"Unable allocate array of ints\n");
  955.         return (0);
  956.         }
  957.         *pCard32++ = 0;        /* VisualID = 0 */
  958.         *pCard32++ = tableType;    /* type */
  959.         *pCard32++ = 1;        /* number of tables = 1 */
  960.         if (tableType == 0) {
  961.         PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
  962.         } else {
  963.         PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
  964.         }
  965.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
  966.             PropModeReplace, (unsigned char *)pCard32Array, total);
  967.         free(pCard32Array);
  968.         break;
  969.       default:
  970.         fprintf(stderr,"Invalid property format\n");
  971.         return (0);
  972.     }
  973.       } else { /* nTables == 3 */
  974.     if ((pScreenData->pRedTbl->nEntries < 2) ||
  975.         (pScreenData->pGreenTbl->nEntries < 2) ||
  976.         (pScreenData->pBlueTbl->nEntries < 2)) {
  977.         fprintf(stderr,"Illegal number of entries in table\n");
  978.         return (0);
  979.     }
  980.     switch (targetFormat) {
  981.       case 8:
  982.         total = 9 +    /* visualID, type, count, and 3 lengths */
  983.         (pScreenData->pRedTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  984.         (pScreenData->pGreenTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  985.         (pScreenData->pBlueTbl->nEntries * (tableType == 0 ? 2 : 1));
  986.         if ((pCard8 = pCard8Array =
  987.             (unsigned char *) calloc (total,
  988.             sizeof (unsigned char))) == NULL) {
  989.         fprintf(stderr,"Unable allocate array of ints\n");
  990.         return (0);
  991.         }
  992.         *pCard8++ = 0;        /* VisualID = 0 */
  993.         *pCard8++ = 0;        /* VisualID = 0 */
  994.         *pCard8++ = 0;        /* VisualID = 0 */
  995.         *pCard8++ = 0;        /* VisualID = 0 */
  996.         *pCard8++ = tableType;    /* type */
  997.         *pCard8++ = 3;        /* number of tables = 3 */
  998.         if (tableType == 0) {
  999.         PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
  1000.         PutTableType0Card8(pScreenData->pGreenTbl, &pCard8);
  1001.         PutTableType0Card8(pScreenData->pBlueTbl, &pCard8);
  1002.         } else {
  1003.         PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
  1004.         PutTableType1Card8(pScreenData->pGreenTbl, &pCard8);
  1005.         PutTableType1Card8(pScreenData->pBlueTbl, &pCard8);
  1006.         }
  1007.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
  1008.             PropModeReplace, (unsigned char *)pCard8Array, total);
  1009.         free(pCard8Array);
  1010.         break;
  1011.       case 16:
  1012.         total = 7 +    /* visualID, type, count, and 3 lengths */
  1013.         (pScreenData->pRedTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  1014.         (pScreenData->pGreenTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  1015.         (pScreenData->pBlueTbl->nEntries * (tableType == 0 ? 2 : 1));
  1016.         if ((pCard16 = pCard16Array =
  1017.             (unsigned short *) calloc (total,
  1018.             sizeof (unsigned short))) == NULL) {
  1019.         fprintf(stderr,"Unable allocate array of ints\n");
  1020.         return (0);
  1021.         }
  1022.         *pCard16++ = 0;        /* VisualID = 0 */
  1023.         *pCard16++ = 0;        /* VisualID = 0 */
  1024.         *pCard16++ = tableType;    /* type = 0 */
  1025.         *pCard16++ = 3;        /* number of tables = 3 */
  1026.         if (tableType == 0) {
  1027.         PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
  1028.         PutTableType0Card16(pScreenData->pGreenTbl, &pCard16);
  1029.         PutTableType0Card16(pScreenData->pBlueTbl, &pCard16);
  1030.         } else {
  1031.         PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
  1032.         PutTableType1Card16(pScreenData->pGreenTbl, &pCard16);
  1033.         PutTableType1Card16(pScreenData->pBlueTbl, &pCard16);
  1034.         }
  1035.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
  1036.             PropModeReplace, (unsigned char *)pCard16Array, total);
  1037.         free(pCard16Array);
  1038.         break;
  1039.       case 32:
  1040.         total = 6 +    /* visualID, type, count, and 3 lengths */
  1041.         (pScreenData->pRedTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  1042.         (pScreenData->pGreenTbl->nEntries * (tableType == 0 ? 2 : 1)) +
  1043.         (pScreenData->pBlueTbl->nEntries * (tableType == 0 ? 2 : 1));
  1044.         if ((pCard32 = pCard32Array =
  1045.             (unsigned long *) calloc (total,
  1046.             sizeof (unsigned long))) == NULL) {
  1047.         fprintf(stderr,"Unable allocate array of ints\n");
  1048.         return (0);
  1049.         }
  1050.         *pCard32++ = 0;        /* VisualID = 0 */
  1051.         *pCard32++ = tableType;    /* type */
  1052.         *pCard32++ = 3;        /* number of tables = 3 */
  1053.         if (tableType == 0) {
  1054.         PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
  1055.         PutTableType0Card32(pScreenData->pGreenTbl, &pCard32);
  1056.         PutTableType0Card32(pScreenData->pBlueTbl, &pCard32);
  1057.         } else {
  1058.         PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
  1059.         PutTableType1Card32(pScreenData->pGreenTbl, &pCard32);
  1060.         PutTableType1Card32(pScreenData->pBlueTbl, &pCard32);
  1061.         }
  1062.         XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
  1063.             PropModeReplace, (unsigned char *)pCard32Array, total);
  1064.         free(pCard32Array);
  1065.         break;
  1066.       default:
  1067.         fprintf(stderr,"Invalid property format\n");
  1068.         return (0);
  1069.     }
  1070.     }
  1071.  
  1072.     return (1);
  1073.  
  1074. }
  1075.  
  1076. #ifdef GRAY
  1077.  
  1078. static int
  1079. LoadDataGray(pDpy, root, tableType, pScreenData, targetFormat)
  1080.     Display *pDpy;
  1081.     Window root;
  1082.     LINEAR_RGB_SCCData *pScreenData;
  1083.     int targetFormat;
  1084. {
  1085.     unsigned char *ret_prop;
  1086.     int  count;
  1087.     int  nLevels;
  1088.     unsigned char  *pCard8;
  1089.     unsigned char  *pCard8Array = (unsigned char *)NULL;
  1090.     unsigned short  *pCard16;
  1091.     unsigned short  *pCard16Array = (unsigned short *)NULL;
  1092.     unsigned long  *pCard32;
  1093.     unsigned long  *pCard32Array = (unsigned long *)NULL;
  1094.     unsigned long  Card32Array[18];
  1095.     int  ret_format;
  1096.     unsigned long ret_len, ret_after;
  1097.     Atom MatricesAtom, CorrectAtom, ret_atom;
  1098.     XcmsFloat *pValue;
  1099.     int total;
  1100.  
  1101.     /* Now store the XDCCC_SCREENWHITEPT */
  1102.     pCard32 = Card32Array;
  1103.     pValue = (XcmsFloat *)pScreenData->XYZtoRGBmatrix;
  1104.     for (count = 0; count < 3; count++) {
  1105.     *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER);
  1106.     }
  1107.     MatricesAtom = XInternAtom (pDpy,XDCCC_SCREENWHITEPT_ATOM_NAME,False);
  1108.     XChangeProperty (pDpy, root, MatricesAtom, XA_INTEGER, 32, 
  1109.              PropModeReplace, (unsigned char *)Card32Array, 3);
  1110.  
  1111.     /* Now store the XDCCC_GRAY_CORRECTION */
  1112.     CorrectAtom = XInternAtom (pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False);
  1113.  
  1114.     if (tableType == CORR_TYPE_NONE) {
  1115.     XGetWindowProperty (pDpy, root, CorrectAtom, 
  1116.                 0, 5, False, XA_INTEGER, 
  1117.                 &ret_atom, &ret_format, &ret_len, &ret_after,
  1118.                 &ret_prop);
  1119.     if (ret_format != 0) {
  1120.         XDeleteProperty (pDpy, root, CorrectAtom);
  1121.         XFree ((char *)ret_prop);
  1122.     }
  1123.     return (1);
  1124.     }
  1125.     nLevels = pScreenData->pRedTbl->nEntries;
  1126.     if (nLevels < 2) {
  1127.     fprintf(stderr,"Illegal number of entries in table\n");
  1128.     return (0);
  1129.     }
  1130.     switch (targetFormat) {
  1131.       case 8:
  1132.     total = 6 /* visualID, type, length */
  1133.         + (nLevels * (tableType == 0 ? 2 : 1));
  1134.     if ((pCard8 = pCard8Array = (unsigned char *)
  1135.         calloc (total, sizeof (unsigned char))) == NULL) {
  1136.         fprintf(stderr,"Unable allocate array of Card8\n");
  1137.         return (0);
  1138.     }
  1139.     *pCard8++ = 0;        /* VisualID = 0 */
  1140.     *pCard8++ = 0;        /* VisualID = 0 */
  1141.     *pCard8++ = 0;        /* VisualID = 0 */
  1142.     *pCard8++ = 0;        /* VisualID = 0 */
  1143.     *pCard8++ = tableType;    /* type */
  1144.     if (tableType == 0) {
  1145.         PutTableType0Card8(pScreenData->pRedTbl, &pCard8);
  1146.     } else { /* tableType == 1 */
  1147.         PutTableType1Card8(pScreenData->pRedTbl, &pCard8);
  1148.     }
  1149.     XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 8, 
  1150.              PropModeReplace, (unsigned char *)pCard8Array,
  1151.              total);
  1152.     free (pCard8Array);
  1153.     break;
  1154.       case 16:
  1155.     total = 4 /* visualID, type, length */
  1156.         + (nLevels * (tableType == 0 ? 2 : 1));
  1157.     if ((pCard16 = pCard16Array = (unsigned short *)
  1158.         calloc (total, sizeof (unsigned short))) == NULL) {
  1159.         fprintf(stderr,"Unable allocate array of Card16\n");
  1160.         return (0);
  1161.     }
  1162.     *pCard16++ = 0;        /* VisualID = 0 */
  1163.     *pCard16++ = 0;        /* VisualID = 0 */
  1164.     *pCard16++ = tableType;    /* type */
  1165.     if (tableType == 0) {
  1166.         PutTableType0Card16(pScreenData->pRedTbl, &pCard16);
  1167.     } else { /* tableType == 1 */
  1168.         PutTableType1Card16(pScreenData->pRedTbl, &pCard16);
  1169.     }
  1170.     XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 16, 
  1171.              PropModeReplace, (unsigned char *)pCard16Array,
  1172.              total);
  1173.     free (pCard16Array);
  1174.     break;
  1175.       case 32:
  1176.     total = 3 /* visualID, type, length */
  1177.         + (nLevels * (tableType == 0 ? 2 : 1));
  1178.     if ((pCard32 = pCard32Array = (unsigned long *)
  1179.         calloc (total, sizeof (unsigned long))) == NULL) {
  1180.         fprintf(stderr,"Unable allocate array of Card32\n");
  1181.         return (0);
  1182.     }
  1183.     *pCard32++ = 0;        /* VisualID = 0 */
  1184.     *pCard32++ = tableType;    /* type */
  1185.     if (tableType == 0) {
  1186.         PutTableType0Card32(pScreenData->pRedTbl, &pCard32);
  1187.     } else { /* tableType == 1 */
  1188.         PutTableType1Card32(pScreenData->pRedTbl, &pCard32);
  1189.     }
  1190.     XChangeProperty (pDpy, root, CorrectAtom, XA_INTEGER, 32, 
  1191.              PropModeReplace, (unsigned char *)pCard32Array,
  1192.              total);
  1193.     free (pCard32Array);
  1194.     break;
  1195.       default:
  1196.     fprintf(stderr,"Invalid property format\n");
  1197.     return (0);
  1198.     }
  1199.     return (1);
  1200. }
  1201. #endif /* GRAY */
  1202.  
  1203.  
  1204. /************************************************************************
  1205.  *                                    *
  1206.  *             PUBLIC ROUTINES                *
  1207.  *                                    *
  1208.  ************************************************************************/
  1209.  
  1210. /*
  1211.  *    NAME
  1212.  *        XLoadSCCData - Read and store the screen data
  1213.  *
  1214.  *    SYNOPSIS
  1215.  */
  1216. int
  1217. LoadSCCData(pDpy, screenNumber, filename, targetFormat)
  1218.     Display *pDpy;
  1219.     int screenNumber;
  1220.     char *filename;
  1221.     int targetFormat;
  1222.  
  1223. /*
  1224.  *    DESCRIPTION
  1225.  *        Using the X Device Color Characterization Convention (XDCCC)
  1226.  *        read the screen data and store it on the root window of the
  1227.  *        screen.
  1228.  *
  1229.  *    RETURNS
  1230.  *        Returns 0 if failed; otherwise 1.
  1231.  *
  1232.  */
  1233. {    
  1234.     FILE *stream;
  1235.     char *pStr;
  1236.     char buf[BUFSIZ];
  1237.     char keyword[BUFSIZ];
  1238.     char token1[BUFSIZ], token2[BUFSIZ];
  1239.     int  state = 0, tableType = -1, nTables = 0;
  1240.     int VisualFlag = -2;
  1241.     Window root;
  1242.     LINEAR_RGB_SCCData *pScreenData;
  1243.  
  1244.     if (screenNumber < 0) {
  1245.     fprintf(stderr,"Invalid Screen Number %d\n", screenNumber);
  1246.     return(0);
  1247.     }
  1248.     root = RootWindow(pDpy, screenNumber);
  1249.  
  1250.     if (!root) {
  1251.     /* if no root window is available then return an error */
  1252.     fprintf(stderr,"Could not open root window supplied.\n ");
  1253.     return (0);
  1254.     }
  1255.     /*
  1256.      * Open the file, determine its size, then read it into memory.
  1257.      */
  1258.     if (filename == NULL) {
  1259.     stream = stdin;
  1260.     filename = "stdin";
  1261.     } else if ((stream = fopen(filename, "r")) == NULL) {
  1262.     fprintf(stderr,"Could not open file %s.\n", filename);
  1263.     return (0);
  1264.     }
  1265.  
  1266.     if ((pScreenData = 
  1267.      (LINEAR_RGB_SCCData *)calloc(1, sizeof(LINEAR_RGB_SCCData))) ==NULL) {
  1268.     fprintf(stderr,"Could not allocate buffer for screen data.");
  1269.     closeS (stream, pScreenData);
  1270.     return (0);
  1271.     }
  1272.  
  1273.     /* need to read screen data file and fill up a LINEAR_RGB_SCCData struct */
  1274.  
  1275.     /*
  1276.      * Advance to starting keyword 
  1277.      * Anything before this keyword is just treated as comments.
  1278.      */
  1279.  
  1280.     while((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
  1281.     if ((sscanf(buf, "%s %s", keyword, token1) > 0)
  1282.         && (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) {
  1283.         break;
  1284.     }  /* else ignore the line */
  1285.     }
  1286.  
  1287.     if (pStr == NULL) {
  1288.     fprintf(stderr,"File %s is missing %s\n", filename, SC_BEGIN_KEYWORD);
  1289.     closeS (stream, pScreenData);
  1290.     return (0);
  1291.     }
  1292.  
  1293.     if (strcmp(token1, TXT_FORMAT_VERSION) != 0) {
  1294.     fprintf(stderr,
  1295.     "Screen data format version mismatch in file %s-- expected %s, found %s\n",
  1296.         filename, TXT_FORMAT_VERSION, token1);
  1297.     closeS (stream, pScreenData);
  1298.     return (0);
  1299.     }
  1300.  
  1301.     while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) {
  1302.     token1[0] = '\0'; token2[0] = '\0';
  1303.     if (sscanf(buf, "%s %s %s", keyword, token1, token2) > 0) {
  1304.         switch (SCKeyOf(keyword)) {
  1305.           case COMMENT :
  1306.           case NAME :
  1307.           case PART_NUMBER :
  1308.           case MODEL :
  1309.           case SERIAL_NUMBER :
  1310.           case REVISION :
  1311.         /* Do nothing */
  1312.         break;
  1313.           case SCREEN_CLASS :
  1314.         VisualFlag = SCScrnClassOf(token1);
  1315.         if (VisualFlag == -1) {
  1316.             closeS (stream, pScreenData);
  1317.             return (0);
  1318.         }
  1319.         break;
  1320.           case COLORIMETRIC_BEGIN :
  1321.         if (VisualFlag == -2) {
  1322.             closeS (stream, pScreenData);
  1323.             return (0);
  1324.         }
  1325.         if (!ProcessColorimetric(stream, 
  1326.                      pScreenData, filename, VisualFlag)) {
  1327.             closeS (stream, pScreenData);
  1328.             return (0);
  1329.         }
  1330.         state |= 0x02;
  1331.         break;
  1332.           case IPROFILE_BEGIN :
  1333.         if (VisualFlag == -2) {
  1334.             closeS (stream, pScreenData);
  1335.             return (0);
  1336.         }
  1337.         if (!token1[0]) {
  1338.             state |= 0x04;
  1339.             break;
  1340.         }
  1341.         if (sscanf(token1, "%d", &tableType) != 1 ||
  1342.             (tableType < -1 || tableType > 1)) {
  1343.             fprintf(stderr,
  1344.                 "File %s has invalid type specified %s\n",
  1345.                 filename, buf);
  1346.             closeS (stream, pScreenData);
  1347.             return (0);
  1348.         } 
  1349.         if (tableType == CORR_TYPE_NONE) {
  1350.             /* a CORR_TYPE_NONE (-1) : no conversion is used*/
  1351.             state |= 0x04;
  1352.             break;
  1353.         }
  1354.         if (!token2[0] && (VisualFlag == VIDEO_RGB)) {
  1355.             fprintf(stderr,
  1356.             "File %s has invalid number of tables specified\n",
  1357.                 filename, buf);
  1358.             closeS (stream, pScreenData);
  1359.             return (0);
  1360.         }
  1361.         if (VisualFlag == VIDEO_RGB) {
  1362.             if (sscanf(token2, "%d", &nTables) != 1 ||
  1363.             (nTables != 0 && nTables != 1 && nTables != 3)) {
  1364.             fprintf(stderr,
  1365.                 "File %s has invalid number of tables (must be 0, 1, or 3)\n",
  1366.                 filename, buf);
  1367.             closeS (stream, pScreenData);
  1368.             return (0);
  1369.             }
  1370.         } else {
  1371.             nTables = 0;
  1372.         }
  1373.         switch (nTables) {
  1374.           case 3 :
  1375.             if (!(pScreenData->pRedTbl = (IntensityTbl *)
  1376.             calloc (1, sizeof (IntensityTbl)))) {
  1377.             fprintf(stderr,
  1378.                    "Could not allocate Red Intensity Table\n");
  1379.             closeS (stream, pScreenData);
  1380.             return (0);
  1381.             }
  1382.             if (!(pScreenData->pGreenTbl = (IntensityTbl *)
  1383.             calloc (1, sizeof (IntensityTbl)))) {
  1384.             fprintf(stderr,
  1385.                  "Could not allocate Green Intensity Table\n");
  1386.             closeS (stream, pScreenData);
  1387.             return (0);
  1388.             }
  1389.             if (!(pScreenData->pBlueTbl = (IntensityTbl *)
  1390.             calloc (1, sizeof (IntensityTbl)))) {
  1391.             fprintf(stderr,
  1392.                 "Could not allocate Blue Intensity Table");
  1393.             closeS (stream, pScreenData);
  1394.             return (0);
  1395.             }
  1396.             if (!ProcessIProfile(stream, pScreenData, 
  1397.                      tableType, nTables, filename)) {
  1398.             closeS (stream, pScreenData);
  1399.             return (0);
  1400.             }
  1401.             break;
  1402.           case 1 :
  1403.             if (!(pScreenData->pRedTbl = (IntensityTbl *)
  1404.               calloc (1, sizeof (IntensityTbl)))) {
  1405.             fprintf(stderr,
  1406.                 "Could not allocate Red Intensity Table");
  1407.             closeS (stream, pScreenData);
  1408.             return (0);
  1409.             }
  1410.             pScreenData->pGreenTbl = pScreenData->pRedTbl;
  1411.             pScreenData->pBlueTbl = pScreenData->pRedTbl;
  1412.             if (!ProcessIProfile(stream, pScreenData, 
  1413.                      tableType, nTables, filename)) {
  1414.             closeS (stream, pScreenData);
  1415.             return (0);
  1416.             }
  1417.             break;
  1418.           default :
  1419.             /* do nothing */
  1420.             break;
  1421.         }
  1422.         state |= 0x04;
  1423.         break;
  1424.           case SC_END :
  1425.         if (!(state & 0x02)) {
  1426.             fprintf(stderr,
  1427.                 "File %s is missing Colormetric data.\n", 
  1428.                 filename);
  1429.             closeS (stream, pScreenData);
  1430.             return (0);
  1431.         }
  1432.         if (!(state & 0x04)) {
  1433.             fprintf(stderr,
  1434.                 "File %s is missing Intensity Profile Data.\n",
  1435.                 filename);
  1436.         }
  1437.         if (VisualFlag == VIDEO_RGB) {
  1438.             if (!LoadDataRGB(pDpy, root,
  1439.                      tableType, nTables, pScreenData,
  1440.                      targetFormat)) {
  1441.             closeS (stream, pScreenData);
  1442.             return (0);
  1443.             }
  1444. #ifdef GRAY
  1445.         } else if (VisualFlag == VIDEO_GRAY) {
  1446.             if (!LoadDataGray(pDpy, root,
  1447.                       tableType, pScreenData, targetFormat)) {
  1448.             closeS (stream, pScreenData);
  1449.             return (0);
  1450.             }
  1451. #endif /* GRAY */
  1452.         } else {
  1453.             fprintf(stderr,"File %s Visual missing.", filename);
  1454.         }
  1455.         closeS (stream, pScreenData);
  1456.         return (1);
  1457. /* NOTREACHED */    break;
  1458.           default :
  1459.         fprintf(stderr,"File %s has extraneous keyword %s\n", 
  1460.             filename, keyword);
  1461.         closeS (stream, pScreenData);
  1462.         return (0);
  1463.  
  1464.         }
  1465.     }   /* else it was just a blank line */
  1466.     }
  1467.     closeS (stream, pScreenData);
  1468.     return (1);
  1469. }
  1470.