home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xcms_LRGB.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  50KB  |  1,833 lines

  1. /* $XConsortium: LRGB.c,v 1.32 95/06/08 23:20:39 gildea Exp $" */
  2.  
  3. /*
  4.  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
  5.  *     All Rights Reserved
  6.  * 
  7.  * This file is a component of an X Window System-specific implementation
  8.  * of Xcms based on the TekColor Color Management System.  Permission is
  9.  * hereby granted to use, copy, modify, sell, and otherwise distribute this
  10.  * software and its documentation for any purpose and without fee, provided
  11.  * that this copyright, permission, and disclaimer notice is reproduced in
  12.  * all copies of this software and in supporting documentation.  TekColor
  13.  * is a trademark of Tektronix, Inc.
  14.  * 
  15.  * Tektronix makes no representation about the suitability of this software
  16.  * for any purpose.  It is provided "as is" and with all faults.
  17.  * 
  18.  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
  19.  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  20.  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
  21.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  22.  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
  23.  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  24.  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  *
  27.  *    NAME
  28.  *        XcmsLRGB.c
  29.  *
  30.  *    DESCRIPTION
  31.  *        This file contains the conversion routines:
  32.  *            1. CIE XYZ to RGB intensity
  33.  *            2. RGB intensity to device RGB
  34.  *            3. device RGB to RGB intensity
  35.  *            4. RGB intensity to CIE XYZ
  36.  *
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include "Xlib_private.h"
  41. #include <X11/Xos.h>
  42. #include <X11/Xatom.h>
  43. #include "Xcmsint.h"
  44.  
  45. #ifdef __STDC__
  46. #define Const const
  47. #else
  48. #define Const /**/
  49. #endif
  50.  
  51. /*
  52.  *      EXTERNS
  53.  *              External declarations required locally to this package
  54.  *              that are not already declared in any of the included header
  55.  *        files (external includes or internal includes).
  56.  */
  57. extern char _XcmsRGB_prefix[];
  58. extern char _XcmsRGBi_prefix[];
  59. extern unsigned long _XcmsGetElement();
  60. extern void _XcmsFreeIntensityMaps();
  61.  
  62.  
  63. /*
  64.  *      LOCAL DEFINES
  65.  *        #define declarations local to this package.
  66.  */
  67. #define EPS    0.001
  68. #ifndef MIN
  69. #define MIN(x,y) ((x) > (y) ? (y) : (x))
  70. #endif /* MIN */
  71. #ifndef MAX
  72. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  73. #endif /* MAX */
  74. #ifndef MIN3
  75. #define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x))
  76. #endif /* MIN3 */
  77. #ifndef MAX3
  78. #define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z))))
  79. #endif /* MAX3 */
  80.  
  81. /*
  82.  *      LOCAL TYPEDEFS
  83.  *              typedefs local to this package (for use with local vars).
  84.  *
  85.  */
  86.  
  87. /*
  88.  *      FORWARD DECLARATIONS
  89.  */
  90. static void LINEAR_RGB_FreeSCCData();
  91. static int LINEAR_RGB_InitSCCData();
  92. static int XcmsLRGB_RGB_ParseString();
  93. static int XcmsLRGB_RGBi_ParseString();
  94. Status _XcmsGetTableType0();
  95. Status _XcmsGetTableType1();
  96.  
  97. /*
  98.  *      LOCALS VARIABLES
  99.  *        Variables local to this package.
  100.  *            Usage example:
  101.  *                static int    ExampleLocalVar;
  102.  */
  103.  
  104. static unsigned short Const MASK[17] = {
  105.     0x0000,    /*  0 bitsPerRGB */
  106.     0x8000,    /*  1 bitsPerRGB */
  107.     0xc000,    /*  2 bitsPerRGB */
  108.     0xe000,    /*  3 bitsPerRGB */
  109.     0xf000,    /*  4 bitsPerRGB */
  110.     0xf800,    /*  5 bitsPerRGB */
  111.     0xfc00,    /*  6 bitsPerRGB */
  112.     0xfe00,    /*  7 bitsPerRGB */
  113.     0xff00,    /*  8 bitsPerRGB */
  114.     0xff80,    /*  9 bitsPerRGB */
  115.     0xffc0,    /* 10 bitsPerRGB */
  116.     0xffe0,    /* 11 bitsPerRGB */
  117.     0xfff0,    /* 12 bitsPerRGB */
  118.     0xfff8,    /* 13 bitsPerRGB */
  119.     0xfffc,    /* 14 bitsPerRGB */
  120.     0xfffe,    /* 15 bitsPerRGB */
  121.     0xffff    /* 16 bitsPerRGB */
  122. };
  123.  
  124.  
  125.     /*
  126.      * A NULL terminated array of function pointers that when applied
  127.      * in series will convert an XcmsColor structure from XcmsRGBFormat
  128.      * to XcmsCIEXYZFormat.
  129.      */
  130. static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
  131.     XcmsRGBToRGBi,
  132.     XcmsRGBiToCIEXYZ,
  133.     NULL
  134. };
  135.  
  136.     /*
  137.      * A NULL terminated array of function pointers that when applied
  138.      * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
  139.      * to XcmsRGBFormat.
  140.      */
  141. static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
  142.     XcmsCIEXYZToRGBi,
  143.     XcmsRGBiToRGB,
  144.     NULL
  145. };
  146.  
  147.     /*
  148.      * A NULL terminated array of function pointers that when applied
  149.      * in series will convert an XcmsColor structure from XcmsRGBiFormat
  150.      * to XcmsCIEXYZFormat.
  151.      */
  152. static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
  153.     XcmsRGBiToCIEXYZ,
  154.     NULL
  155. };
  156.  
  157.     /*
  158.      * A NULL terminated array of function pointers that when applied
  159.      * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
  160.      * to XcmsRGBiFormat.
  161.      */
  162. static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
  163.     XcmsCIEXYZToRGBi,
  164.     NULL
  165. };
  166.  
  167.     /*
  168.      * RGBi Color Spaces
  169.      */
  170. XcmsColorSpace    XcmsRGBiColorSpace =
  171.     {
  172.     _XcmsRGBi_prefix,    /* prefix */
  173.     XcmsRGBiFormat,        /* id */
  174.     XcmsLRGB_RGBi_ParseString,    /* parseString */
  175.     Fl_RGBi_to_CIEXYZ,    /* to_CIEXYZ */
  176.     Fl_CIEXYZ_to_RGBi,    /* from_CIEXYZ */
  177.     1
  178.     };
  179.  
  180.     /*
  181.      * RGB Color Spaces
  182.      */
  183. XcmsColorSpace    XcmsRGBColorSpace =
  184.     {
  185.     _XcmsRGB_prefix,        /* prefix */
  186.     XcmsRGBFormat,        /* id */
  187.     XcmsLRGB_RGB_ParseString,    /* parseString */
  188.     Fl_RGB_to_CIEXYZ,    /* to_CIEXYZ */
  189.     Fl_CIEXYZ_to_RGB,    /* from_CIEXYZ */
  190.     1
  191.     };
  192.  
  193.     /*
  194.      * Device-Independent Color Spaces known to the 
  195.      * LINEAR_RGB Screen Color Characteristics Function Set.
  196.      */
  197. static XcmsColorSpace    *DDColorSpaces[] = {
  198.     &XcmsRGBColorSpace,
  199.     &XcmsRGBiColorSpace,
  200.     NULL
  201. };
  202.  
  203.  
  204. /*
  205.  *      GLOBALS
  206.  *              Variables declared in this package that are allowed
  207.  *        to be used globally.
  208.  */
  209.  
  210.     /*
  211.      * LINEAR_RGB Screen Color Characteristics Function Set.
  212.      */
  213. XcmsFunctionSet    XcmsLinearRGBFunctionSet =
  214.     {
  215.     &DDColorSpaces[0],    /* pDDColorSpaces */
  216.     LINEAR_RGB_InitSCCData,    /* pInitScrnFunc */
  217.     LINEAR_RGB_FreeSCCData    /* pFreeSCCData */
  218.     };
  219.  
  220. /*
  221.  *    DESCRIPTION
  222.  *        Contents of Default SCCData should be replaced if other
  223.  *        data should be used as default.
  224.  *
  225.  *
  226.  */
  227.  
  228. /*
  229.  * NAME        Tektronix 19" (Sony) CRT
  230.  * PART_NUMBER        119-2451-00
  231.  * MODEL        Tek4300, Tek4800
  232.  */
  233.  
  234. static IntensityRec Const Default_RGB_RedTuples[] = {
  235.     /* {unsigned short value, XcmsFloat intensity} */
  236.             0x0000,    0.000000,
  237.             0x0909,    0.000000,
  238.             0x0a0a,    0.000936,
  239.             0x0f0f,    0.001481,
  240.             0x1414,    0.002329,
  241.             0x1919,    0.003529,
  242.             0x1e1e,    0.005127,
  243.             0x2323,    0.007169,
  244.             0x2828,    0.009699,
  245.             0x2d2d,    0.012759,
  246.             0x3232,    0.016392,
  247.             0x3737,    0.020637,
  248.             0x3c3c,    0.025533,
  249.             0x4141,    0.031119,
  250.             0x4646,    0.037431,
  251.             0x4b4b,    0.044504,
  252.             0x5050,    0.052373,
  253.             0x5555,    0.061069,
  254.             0x5a5a,    0.070624,
  255.             0x5f5f,    0.081070,
  256.             0x6464,    0.092433,
  257.             0x6969,    0.104744,
  258.             0x6e6e,    0.118026,
  259.             0x7373,    0.132307,
  260.             0x7878,    0.147610,
  261.             0x7d7d,    0.163958,
  262.             0x8282,    0.181371,
  263.             0x8787,    0.199871,
  264.             0x8c8c,    0.219475,
  265.             0x9191,    0.240202,
  266.             0x9696,    0.262069,
  267.             0x9b9b,    0.285089,
  268.             0xa0a0,    0.309278,
  269.             0xa5a5,    0.334647,
  270.             0xaaaa,    0.361208,
  271.             0xafaf,    0.388971,
  272.             0xb4b4,    0.417945,
  273.             0xb9b9,    0.448138,
  274.             0xbebe,    0.479555,
  275.             0xc3c3,    0.512202,
  276.             0xc8c8,    0.546082,
  277.             0xcdcd,    0.581199,
  278.             0xd2d2,    0.617552,
  279.             0xd7d7,    0.655144,
  280.             0xdcdc,    0.693971,
  281.             0xe1e1,    0.734031,
  282.             0xe6e6,    0.775322,
  283.             0xebeb,    0.817837,
  284.             0xf0f0,    0.861571,
  285.             0xf5f5,    0.906515,
  286.             0xfafa,    0.952662,
  287.             0xffff,    1.000000
  288. };
  289.  
  290. static IntensityRec Const Default_RGB_GreenTuples[] = {
  291.     /* {unsigned short value, XcmsFloat intensity} */
  292.             0x0000,    0.000000,
  293.             0x1313,    0.000000,
  294.             0x1414,    0.000832,
  295.             0x1919,    0.001998,
  296.             0x1e1e,    0.003612,
  297.             0x2323,    0.005736,
  298.             0x2828,    0.008428,
  299.             0x2d2d,    0.011745,
  300.             0x3232,    0.015740,
  301.             0x3737,    0.020463,
  302.             0x3c3c,    0.025960,
  303.             0x4141,    0.032275,
  304.             0x4646,    0.039449,
  305.             0x4b4b,    0.047519,
  306.             0x5050,    0.056520,
  307.             0x5555,    0.066484,
  308.             0x5a5a,    0.077439,
  309.             0x5f5f,    0.089409,
  310.             0x6464,    0.102418,
  311.             0x6969,    0.116485,
  312.             0x6e6e,    0.131625,
  313.             0x7373,    0.147853,
  314.             0x7878,    0.165176,
  315.             0x7d7d,    0.183604,
  316.             0x8282,    0.203140,
  317.             0x8787,    0.223783,
  318.             0x8c8c,    0.245533,
  319.             0x9191,    0.268384,
  320.             0x9696,    0.292327,
  321.             0x9b9b,    0.317351,
  322.             0xa0a0,    0.343441,
  323.             0xa5a5,    0.370580,
  324.             0xaaaa,    0.398747,
  325.             0xafaf,    0.427919,
  326.             0xb4b4,    0.458068,
  327.             0xb9b9,    0.489165,
  328.             0xbebe,    0.521176,
  329.             0xc3c3,    0.554067,
  330.             0xc8c8,    0.587797,
  331.             0xcdcd,    0.622324,
  332.             0xd2d2,    0.657604,
  333.             0xd7d7,    0.693588,
  334.             0xdcdc,    0.730225,
  335.             0xe1e1,    0.767459,
  336.             0xe6e6,    0.805235,
  337.             0xebeb,    0.843491,
  338.             0xf0f0,    0.882164,
  339.             0xf5f5,    0.921187,
  340.             0xfafa,    0.960490,
  341.             0xffff,    1.000000
  342. };
  343.  
  344. static IntensityRec Const Default_RGB_BlueTuples[] = {
  345.     /* {unsigned short value, XcmsFloat intensity} */
  346.             0x0000,    0.000000,
  347.             0x0e0e,    0.000000,
  348.             0x0f0f,    0.001341,
  349.             0x1414,    0.002080,
  350.             0x1919,    0.003188,
  351.             0x1e1e,    0.004729,
  352.             0x2323,    0.006766,
  353.             0x2828,    0.009357,
  354.             0x2d2d,    0.012559,
  355.             0x3232,    0.016424,
  356.             0x3737,    0.021004,
  357.             0x3c3c,    0.026344,
  358.             0x4141,    0.032489,
  359.             0x4646,    0.039481,
  360.             0x4b4b,    0.047357,
  361.             0x5050,    0.056154,
  362.             0x5555,    0.065903,
  363.             0x5a5a,    0.076634,
  364.             0x5f5f,    0.088373,
  365.             0x6464,    0.101145,
  366.             0x6969,    0.114968,
  367.             0x6e6e,    0.129862,
  368.             0x7373,    0.145841,
  369.             0x7878,    0.162915,
  370.             0x7d7d,    0.181095,
  371.             0x8282,    0.200386,
  372.             0x8787,    0.220791,
  373.             0x8c8c,    0.242309,
  374.             0x9191,    0.264937,
  375.             0x9696,    0.288670,
  376.             0x9b9b,    0.313499,
  377.             0xa0a0,    0.339410,
  378.             0xa5a5,    0.366390,
  379.             0xaaaa,    0.394421,
  380.             0xafaf,    0.423481,
  381.             0xb4b4,    0.453547,
  382.             0xb9b9,    0.484592,
  383.             0xbebe,    0.516587,
  384.             0xc3c3,    0.549498,
  385.             0xc8c8,    0.583291,
  386.             0xcdcd,    0.617925,
  387.             0xd2d2,    0.653361,
  388.             0xd7d7,    0.689553,
  389.             0xdcdc,    0.726454,
  390.             0xe1e1,    0.764013,
  391.             0xe6e6,    0.802178,
  392.             0xebeb,    0.840891,
  393.             0xf0f0,    0.880093,
  394.             0xf5f5,    0.919723,
  395.             0xfafa,    0.959715,
  396.             0xffff,    1.00000
  397. };
  398.  
  399. static IntensityTbl Default_RGB_RedTbl = {
  400.     /* IntensityRec *pBase */
  401.     (IntensityRec *) Default_RGB_RedTuples,
  402.     /* unsigned int nEntries */
  403.     52
  404. };
  405.  
  406. static IntensityTbl Default_RGB_GreenTbl = {
  407.     /* IntensityRec *pBase */
  408.     (IntensityRec *)Default_RGB_GreenTuples,
  409.     /* unsigned int nEntries */
  410.     50
  411. };
  412.  
  413. static IntensityTbl Default_RGB_BlueTbl = {
  414.     /* IntensityRec *pBase */
  415.     (IntensityRec *)Default_RGB_BlueTuples,
  416.     /* unsigned int nEntries */
  417.     51
  418. };
  419.  
  420. static LINEAR_RGB_SCCData Default_RGB_SCCData = {
  421.  
  422.     /* XcmsFloat XYZtoRGBmatrix[3][3] */
  423.        3.48340481253539000, -1.52176374927285200, -0.55923133354049780,
  424.       -1.07152751306193600,  1.96593795204372400,  0.03673691339553462,
  425.        0.06351179790497788, -0.20020501000496480,  0.81070942031648220,
  426.  
  427.     /* XcmsFloat RGBtoXYZmatrix[3][3] */
  428.        0.38106149108714790, 0.32025712365352110, 0.24834578525933100,
  429.        0.20729745115140850, 0.68054638776373240, 0.11215616108485920,
  430.        0.02133944350088028, 0.14297193020246480, 1.24172892629665500,
  431.  
  432.     /* IntensityTbl *pRedTbl */
  433.     &Default_RGB_RedTbl,
  434.  
  435.     /* IntensityTbl *pGreenTbl */
  436.     &Default_RGB_GreenTbl,
  437.  
  438.     /* IntensityTbl *pBlueTbl */
  439.     &Default_RGB_BlueTbl
  440. };
  441.  
  442. /************************************************************************
  443.  *                                    *
  444.  *            PRIVATE ROUTINES                *
  445.  *                                    *
  446.  ************************************************************************/
  447.  
  448. /*
  449.  *    NAME
  450.  *        LINEAR_RGB_InitSCCData()
  451.  *
  452.  *    SYNOPSIS
  453.  */
  454. static Status
  455. LINEAR_RGB_InitSCCData(dpy, screenNumber, pPerScrnInfo)
  456.     Display *dpy;
  457.     int screenNumber;
  458.     XcmsPerScrnInfo *pPerScrnInfo;
  459. /*
  460.  *    DESCRIPTION
  461.  *
  462.  *    RETURNS
  463.  *        XcmsFailure if failed.
  464.  *        XcmsSuccess if succeeded.
  465.  *
  466.  */
  467. {
  468.     DBUG_ENTER("LINEAR_RGB_InitSCCData")
  469.     Atom  CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
  470.     Atom  MatrixAtom  = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
  471.     int      format_return, count, cType, nTables;
  472.     unsigned long nitems, nbytes_return;
  473.     char *property_return, *pChar;
  474.     XcmsFloat *pValue;
  475. #ifdef ALLDEBUG
  476.     IntensityRec *pIRec;
  477. #endif /* ALLDEBUG */
  478.     VisualID visualID;
  479.  
  480.     LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
  481.     XcmsIntensityMap *pNewMap;
  482.  
  483.     /*
  484.      * Allocate memory for pScreenData
  485.      */
  486.     if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) 
  487.               Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
  488.     DBUG_RETURN(XcmsFailure);
  489.     }
  490.  
  491.     /* 
  492.      *  1. Get the XYZ->RGB and RGB->XYZ matrices
  493.      */
  494.  
  495.     if (MatrixAtom == None ||
  496.     !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, 
  497.        &format_return, &nitems, &nbytes_return, &property_return) ||
  498.        nitems != 18 || format_return != 32) {
  499.     /*
  500.      * As per the XDCCC, there must be 18 data items and each must be
  501.      * in 32 bits !
  502.      */
  503.     goto FreeSCCData;
  504.  
  505.     } else {
  506.  
  507.     /*
  508.      * RGBtoXYZ and XYZtoRGB matrices
  509.      */
  510.     pValue = (XcmsFloat *) pScreenData;
  511.     pChar = property_return;
  512.     for (count = 0; count < 18; count++) {
  513.         *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
  514.             &nitems) / (XcmsFloat)XDCCC_NUMBER;
  515.     }
  516.     Xfree ((char *)property_return);
  517.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
  518.         pScreenData->RGBtoXYZmatrix[0][0] +
  519.         pScreenData->RGBtoXYZmatrix[0][1] +
  520.         pScreenData->RGBtoXYZmatrix[0][2];
  521.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
  522.         pScreenData->RGBtoXYZmatrix[1][0] +
  523.         pScreenData->RGBtoXYZmatrix[1][1] +
  524.         pScreenData->RGBtoXYZmatrix[1][2];
  525.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
  526.         pScreenData->RGBtoXYZmatrix[2][0] +
  527.         pScreenData->RGBtoXYZmatrix[2][1] +
  528.         pScreenData->RGBtoXYZmatrix[2][2];
  529.  
  530.     /*
  531.      * Compute the Screen White Point
  532.      */
  533.     if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
  534.         || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
  535.         goto FreeSCCData;
  536.     } else {
  537.         pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
  538.     }
  539.     pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
  540.     pPerScrnInfo->screenWhitePt.pixel = 0;
  541.  
  542. #ifdef PDEBUG
  543.     printf ("RGB to XYZ Matrix values:\n");
  544.     printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
  545.         pScreenData->RGBtoXYZmatrix[0][0],
  546.         pScreenData->RGBtoXYZmatrix[0][1],
  547.         pScreenData->RGBtoXYZmatrix[0][2],
  548.         pScreenData->RGBtoXYZmatrix[1][0],
  549.         pScreenData->RGBtoXYZmatrix[1][1],
  550.         pScreenData->RGBtoXYZmatrix[1][2],
  551.         pScreenData->RGBtoXYZmatrix[2][0],
  552.         pScreenData->RGBtoXYZmatrix[2][1],
  553.         pScreenData->RGBtoXYZmatrix[2][2]);
  554.     printf ("XYZ to RGB Matrix values:\n");
  555.     printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
  556.         pScreenData->XYZtoRGBmatrix[0][0],
  557.         pScreenData->XYZtoRGBmatrix[0][1],
  558.         pScreenData->XYZtoRGBmatrix[0][2],
  559.         pScreenData->XYZtoRGBmatrix[1][0],
  560.         pScreenData->XYZtoRGBmatrix[1][1],
  561.         pScreenData->XYZtoRGBmatrix[1][2],
  562.         pScreenData->XYZtoRGBmatrix[2][0],
  563.         pScreenData->XYZtoRGBmatrix[2][1],
  564.         pScreenData->XYZtoRGBmatrix[2][2]);
  565.     printf ("Screen White Pt value: %f %f %f\n",
  566.         pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
  567.         pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
  568.         pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
  569. #endif /* PDEBUG */
  570.     }
  571.  
  572.     /*
  573.      *    2. Get the Intensity Profile
  574.      */
  575.     if (CorrectAtom == None ||
  576.     !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
  577.        &format_return, &nitems, &nbytes_return, &property_return)) {
  578.     Xfree ((char *)property_return);
  579.     goto FreeSCCData;
  580.     }
  581.  
  582.     pChar = property_return;
  583.  
  584.     while (nitems) {
  585.     switch (format_return) {
  586.       case 8:
  587.         /*
  588.          * Must have at least:
  589.          *        VisualID0
  590.          *        VisualID1
  591.          *        VisualID2
  592.          *        VisualID3
  593.          *        type
  594.          *        count
  595.          *        length
  596.          *        intensity1
  597.          *        intensity2
  598.          */
  599.         if (nitems < 9) {
  600.         Xfree ((char *)property_return);
  601.         goto FreeSCCData;
  602.         }
  603.         count = 3;
  604.         break;
  605.       case 16:
  606.         /*
  607.          * Must have at least:
  608.          *        VisualID0
  609.          *        VisualID3
  610.          *        type
  611.          *        count
  612.          *        length
  613.          *        intensity1
  614.          *        intensity2
  615.          */
  616.         if (nitems < 7) {
  617.         Xfree ((char *)property_return);
  618.         goto FreeSCCData;
  619.         }
  620.         count = 1;
  621.         break;
  622.       case 32:
  623.         /*
  624.          * Must have at least:
  625.          *        VisualID0
  626.          *        type
  627.          *        count
  628.          *        length
  629.          *        intensity1
  630.          *        intensity2
  631.          */
  632.         if (nitems < 6) {
  633.         Xfree ((char *)property_return);
  634.         goto FreeSCCData;
  635.         }
  636.         count = 0;
  637.         break;
  638.       default:
  639.         Xfree ((char *)property_return);
  640.         goto FreeSCCData;
  641.     }
  642.  
  643.     /*
  644.      * Get VisualID
  645.      */
  646.     visualID = _XcmsGetElement(format_return, &pChar, &nitems);
  647.     while (count--) {
  648.         visualID = visualID << format_return;
  649.         visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
  650.     }
  651.  
  652.     if (visualID == 0) {
  653.         /*
  654.          * This is a shared intensity table
  655.          */
  656.         pScreenData = pScreenDefaultData;
  657.     } else {
  658.         /*
  659.          * This is a per-Visual intensity table
  660.          */
  661.         if (!(pScreenData = (LINEAR_RGB_SCCData *) 
  662.                   Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
  663.         DBUG_RETURN(XcmsFailure);
  664.         }
  665.         /* copy matrices */
  666.         memcpy((char *)pScreenData, (char *)pScreenDefaultData,
  667.            18 * sizeof(XcmsFloat));
  668.  
  669.         /* Create, initialize, and add map */
  670.         if (!(pNewMap = (XcmsIntensityMap *) 
  671.                   Xcalloc (1, sizeof(XcmsIntensityMap)))) {
  672.         Xfree((char *)pScreenData);
  673.         DBUG_RETURN(XcmsFailure);
  674.         }
  675.         pNewMap->visualID = visualID;
  676.         pNewMap->screenData = (XPointer)pScreenData;
  677.         pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
  678.         pNewMap->pNext =
  679.             (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
  680.         dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
  681.         dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
  682.     }
  683.  
  684.     cType = _XcmsGetElement(format_return, &pChar, &nitems);
  685.     nTables = _XcmsGetElement(format_return, &pChar, &nitems);
  686.  
  687.     if (cType == 0) {
  688.  
  689.         /* Red Intensity Table */
  690.         if (!(pScreenData->pRedTbl = (IntensityTbl *)
  691.             Xcalloc (1, sizeof(IntensityTbl)))) {
  692.         goto FreeSCCData;
  693.         }
  694.         if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
  695.             &nitems) == XcmsFailure) {
  696.         goto FreeRedTbl;
  697.         }
  698.  
  699.         if (nTables == 1) {
  700.         /* Green Intensity Table */
  701.         pScreenData->pGreenTbl = pScreenData->pRedTbl;
  702.         /* Blue Intensity Table */
  703.         pScreenData->pBlueTbl = pScreenData->pRedTbl;
  704.         } else {
  705.         /* Green Intensity Table */
  706.         if (!(pScreenData->pGreenTbl = (IntensityTbl *)
  707.             Xcalloc (1, sizeof(IntensityTbl)))) {
  708.             goto FreeRedTblElements;
  709.         }
  710.         if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
  711.             &nitems) == XcmsFailure) {
  712.             goto FreeGreenTbl;
  713.         }
  714.  
  715.         /* Blue Intensity Table */
  716.         if (!(pScreenData->pBlueTbl = (IntensityTbl *)
  717.             Xcalloc (1, sizeof(IntensityTbl)))) {
  718.             goto FreeGreenTblElements;
  719.         }
  720.         if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
  721.             &nitems) == XcmsFailure) {
  722.             goto FreeBlueTbl;
  723.         }
  724.         }        
  725.     } else if (cType == 1) {
  726.         /* Red Intensity Table */
  727.         if (!(pScreenData->pRedTbl = (IntensityTbl *)
  728.             Xcalloc (1, sizeof(IntensityTbl)))) {
  729.         goto FreeSCCData;
  730.         }
  731.         if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
  732.             &nitems) == XcmsFailure) {
  733.         goto FreeRedTbl;
  734.         }
  735.  
  736.         if (nTables == 1) {
  737.  
  738.         /* Green Intensity Table */
  739.         pScreenData->pGreenTbl = pScreenData->pRedTbl;
  740.         /* Blue Intensity Table */
  741.         pScreenData->pBlueTbl = pScreenData->pRedTbl;
  742.  
  743.         } else {
  744.  
  745.         /* Green Intensity Table */
  746.         if (!(pScreenData->pGreenTbl = (IntensityTbl *)
  747.             Xcalloc (1, sizeof(IntensityTbl)))) {
  748.             goto FreeRedTblElements;
  749.         }
  750.         if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
  751.             &nitems) == XcmsFailure) {
  752.             goto FreeGreenTbl;
  753.         }
  754.  
  755.         /* Blue Intensity Table */
  756.         if (!(pScreenData->pBlueTbl = (IntensityTbl *)
  757.             Xcalloc (1, sizeof(IntensityTbl)))) {
  758.             goto FreeBlueTblElements;
  759.         }
  760.         if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
  761.             &nitems) == XcmsFailure) {
  762.             goto FreeBlueTbl;
  763.         }
  764.         }
  765.     } else {
  766.         Xfree ((char *)property_return);
  767.         goto FreeSCCData;
  768.     }
  769.  
  770. #ifdef ALLDEBUG
  771.     printf ("Intensity Table  RED    %d\n", pScreenData->pRedTbl->nEntries);
  772.     pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
  773.     for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
  774.         printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
  775.     }
  776.     if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
  777.         printf ("Intensity Table  GREEN  %d\n", pScreenData->pGreenTbl->nEntries);
  778.         pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
  779.         for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
  780.         printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
  781.         }
  782.     }
  783.     if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
  784.         printf ("Intensity Table  BLUE   %d\n", pScreenData->pBlueTbl->nEntries);
  785.         pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
  786.         for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
  787.         printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
  788.         }
  789.     }
  790. #endif /* ALLDEBUG */
  791.     }
  792.  
  793.     Xfree ((char *)property_return);
  794.  
  795.     /* Free the old memory and use the new structure created. */
  796.     LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData);
  797.  
  798.     pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
  799.  
  800.     pPerScrnInfo->screenData = (XPointer) pScreenData;
  801.  
  802.     pPerScrnInfo->state = XcmsInitSuccess;
  803.  
  804.     DBUG_RETURN(XcmsSuccess);
  805.  
  806. FreeBlueTblElements:
  807.     Xfree((char *)pScreenData->pBlueTbl->pBase);
  808.  
  809. FreeBlueTbl:
  810.     Xfree((char *)pScreenData->pBlueTbl);
  811.  
  812. FreeGreenTblElements:
  813.     Xfree((char *)pScreenData->pBlueTbl->pBase);
  814.  
  815. FreeGreenTbl:
  816.     Xfree((char *)pScreenData->pGreenTbl);
  817.  
  818. FreeRedTblElements:
  819.     Xfree((char *)pScreenData->pRedTbl->pBase);
  820.  
  821. FreeRedTbl:
  822.     Xfree((char *)pScreenData->pRedTbl);
  823.  
  824. FreeSCCData:
  825.     Xfree((char *)pScreenData);
  826.     pPerScrnInfo->state = XcmsInitNone;
  827.     DBUG_RETURN(XcmsFailure);
  828. }
  829.  
  830.  
  831. /*
  832.  *    NAME
  833.  *        LINEAR_RGB_FreeSCCData()
  834.  *
  835.  *    SYNOPSIS
  836.  */
  837. static void
  838. LINEAR_RGB_FreeSCCData(pScreenDataTemp)
  839.     XPointer pScreenDataTemp;
  840. /*
  841.  *    DESCRIPTION
  842.  *
  843.  *    RETURNS
  844.  *        0 if failed.
  845.  *        1 if succeeded with no modifications.
  846.  *
  847.  */
  848. {
  849.     DBUG_ENTER("LINEAR_RGB_FreeSCCData")
  850.     LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
  851.  
  852.     if (pScreenData && pScreenData != &Default_RGB_SCCData) {
  853.     if (pScreenData->pRedTbl) {
  854.         if (pScreenData->pGreenTbl) {
  855.         if (pScreenData->pRedTbl->pBase != 
  856.             pScreenData->pGreenTbl->pBase) {
  857.             if (pScreenData->pGreenTbl->pBase) {
  858.             Xfree ((char *)pScreenData->pGreenTbl->pBase);
  859.             }
  860.         }
  861.         if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
  862.             Xfree ((char *)pScreenData->pGreenTbl);
  863.         }
  864.         }
  865.         if (pScreenData->pBlueTbl) {
  866.         if (pScreenData->pRedTbl->pBase != 
  867.             pScreenData->pBlueTbl->pBase) {
  868.             if (pScreenData->pBlueTbl->pBase) {
  869.             Xfree ((char *)pScreenData->pBlueTbl->pBase);
  870.             }
  871.         }
  872.         if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
  873.             Xfree ((char *)pScreenData->pBlueTbl);
  874.         }
  875.         }
  876.         if (pScreenData->pRedTbl->pBase) {
  877.         Xfree ((char *)pScreenData->pRedTbl->pBase);
  878.         }
  879.         Xfree ((char *)pScreenData->pRedTbl);
  880.     }
  881.     Xfree ((char *)pScreenData);
  882.     }
  883.     DBUG_VOID_RETURN;
  884. }
  885.  
  886.  
  887.  
  888. /************************************************************************
  889.  *                                    *
  890.  *            API PRIVATE ROUTINES                *
  891.  *                                    *
  892.  ************************************************************************/
  893.  
  894. /*
  895.  *    NAME
  896.  *        _XcmsGetTableType0
  897.  *
  898.  *    SYNOPSIS
  899.  */
  900. Status
  901. _XcmsGetTableType0(pTbl, format, pChar, pCount)
  902.     IntensityTbl *pTbl;
  903.     int      format;
  904.     char **pChar;
  905.     unsigned long *pCount;
  906. /*
  907.  *    DESCRIPTION
  908.  *
  909.  *    RETURNS
  910.  *        XcmsFailure if failed.
  911.  *        XcmsSuccess if succeeded.
  912.  *
  913.  */
  914. {
  915.     DBUG_ENTER("_XcmsGetTableType0")
  916.     unsigned int nElements;
  917.     IntensityRec *pIRec;
  918.  
  919.     nElements = pTbl->nEntries =
  920.         _XcmsGetElement(format, pChar, pCount) + 1;
  921.     if (!(pIRec = pTbl->pBase = (IntensityRec *)
  922.       Xcalloc (nElements, sizeof(IntensityRec)))) {
  923.     DBUG_RETURN(XcmsFailure);
  924.     }
  925.  
  926.     switch (format) {
  927.       case 8: 
  928.     for (; nElements--; pIRec++) {
  929.         /* 0xFFFF/0xFF = 0x101 */
  930.         pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
  931.         pIRec->intensity =
  932.             _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
  933.     }
  934.     break;
  935.       case 16: 
  936.     for (; nElements--; pIRec++) {
  937.         pIRec->value = _XcmsGetElement (format, pChar, pCount);
  938.         pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
  939.             / (XcmsFloat)65535.0;
  940.     }
  941.     break;
  942.       case 32: 
  943.     for (; nElements--; pIRec++) {
  944.         pIRec->value = _XcmsGetElement (format, pChar, pCount);
  945.         pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
  946.             / (XcmsFloat)4294967295.0;
  947.     }
  948.     break;
  949.       default:
  950.     DBUG_RETURN(XcmsFailure);
  951.     }
  952.     DBUG_RETURN(XcmsSuccess);
  953. }
  954.  
  955.  
  956. /*
  957.  *    NAME
  958.  *        _XcmsGetTableType1
  959.  *
  960.  *    SYNOPSIS
  961.  */
  962. Status
  963. _XcmsGetTableType1(pTbl, format, pChar, pCount)
  964.     IntensityTbl *pTbl;
  965.     int      format;
  966.     char **pChar;
  967.     unsigned long *pCount;
  968. /*
  969.  *    DESCRIPTION
  970.  *
  971.  *    RETURNS
  972.  *        XcmsFailure if failed.
  973.  *        XcmsSuccess if succeeded.
  974.  *
  975.  */
  976. {
  977.     DBUG_ENTER("_XcmsGetTableType1")
  978.     int count;
  979.     unsigned int max_index;
  980.     IntensityRec *pIRec;
  981.  
  982.     max_index = _XcmsGetElement(format, pChar, pCount);
  983.     pTbl->nEntries = max_index + 1;
  984.     if (!(pIRec = pTbl->pBase = (IntensityRec *)
  985.       Xcalloc (max_index+1, sizeof(IntensityRec)))) {
  986.     DBUG_RETURN(XcmsFailure);
  987.     }
  988.  
  989.     switch (format) {
  990.       case 8: 
  991.     for (count = 0; count < max_index+1; count++, pIRec++) {
  992.         pIRec->value = (count * 65535) / max_index;
  993.         pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
  994.             / (XcmsFloat)255.0;
  995.     }
  996.     break;
  997.       case 16: 
  998.     for (count = 0; count < max_index+1; count++, pIRec++) {
  999.         pIRec->value = (count * 65535) / max_index;
  1000.         pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
  1001.             / (XcmsFloat)65535.0;
  1002.     }
  1003.     break;
  1004.       case 32: 
  1005.     for (count = 0; count < max_index+1; count++, pIRec++) {
  1006.         pIRec->value = (count * 65535) / max_index;
  1007.         pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
  1008.             / (XcmsFloat)4294967295.0;
  1009.     }
  1010.     break;
  1011.       default:
  1012.     DBUG_RETURN(XcmsFailure);
  1013.     }
  1014.  
  1015.     DBUG_RETURN(XcmsSuccess);
  1016. }
  1017.  
  1018.  
  1019. /*
  1020.  *    NAME
  1021.  *        ValueCmp
  1022.  *
  1023.  *    SYNOPSIS
  1024.  */
  1025. int
  1026. _XcmsValueCmp (p1, p2)
  1027.     IntensityRec *p1, *p2;
  1028. /*
  1029.  *    DESCRIPTION
  1030.  *        Compares the value component of two IntensityRec
  1031.  *        structures.
  1032.  *
  1033.  *    RETURNS
  1034.  *        0 if p1->value is equal to p2->value
  1035.  *        < 0 if p1->value is less than p2->value
  1036.  *        > 0 if p1->value is greater than p2->value
  1037.  *
  1038.  */
  1039. {
  1040.     DBUG_ENTER("_XcmsValueCmp")
  1041.     int res = p1->value - p2->value;
  1042.     DBUG_RETURN(res);
  1043. }
  1044.  
  1045.  
  1046. /*
  1047.  *    NAME
  1048.  *        IntensityCmp
  1049.  *
  1050.  *    SYNOPSIS
  1051.  */
  1052. int
  1053. _XcmsIntensityCmp (p1, p2)
  1054.     IntensityRec *p1, *p2;
  1055. /*
  1056.  *    DESCRIPTION
  1057.  *        Compares the intensity component of two IntensityRec
  1058.  *        structures.
  1059.  *
  1060.  *    RETURNS
  1061.  *        0 if equal;
  1062.  *        < 0 if first precedes second
  1063.  *        > 0 if first succeeds second
  1064.  *
  1065.  */
  1066. {
  1067.     DBUG_ENTER("_XcmsIntensityCmp")
  1068.     if (p1->intensity < p2->intensity) {
  1069.     DBUG_RETURN(-1);
  1070.     }
  1071.     if (p1->intensity > p2->intensity) {
  1072.     DBUG_RETURN(XcmsSuccess);
  1073.     }
  1074.     DBUG_RETURN(XcmsFailure);
  1075. }
  1076.  
  1077. /*
  1078.  *    NAME
  1079.  *        ValueInterpolation
  1080.  *
  1081.  *    SYNOPSIS
  1082.  */
  1083. /* ARGSUSED */
  1084. int
  1085. _XcmsValueInterpolation (key, lo, hi, answer, bitsPerRGB)
  1086.     IntensityRec *key, *lo, *hi, *answer;
  1087.     int bitsPerRGB;
  1088. /*
  1089.  *    DESCRIPTION
  1090.  *        Based on a given value, performs a linear interpolation
  1091.  *        on the intensities between two IntensityRec structures.
  1092.  *        Note that the bitsPerRGB parameter is ignored.
  1093.  *
  1094.  *    RETURNS
  1095.  *        Returns 0 if failed; otherwise non-zero.
  1096.  */
  1097. {
  1098.     DBUG_ENTER("_XcmsValueInterpolation")
  1099.     XcmsFloat ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / 
  1100.     ((XcmsFloat)hi->value - (XcmsFloat)lo->value);
  1101.     answer->value = key->value;
  1102.     answer->intensity = (hi->intensity - lo->intensity) * ratio;
  1103.     answer->intensity += lo->intensity;
  1104.     DBUG_RETURN(XcmsSuccess);
  1105. }
  1106.  
  1107. /*
  1108.  *    NAME
  1109.  *        IntensityInterpolation
  1110.  *
  1111.  *    SYNOPSIS
  1112.  */
  1113. int
  1114. _XcmsIntensityInterpolation (key, lo, hi, answer, bitsPerRGB)
  1115.     IntensityRec *key, *lo, *hi, *answer;
  1116.     int bitsPerRGB;
  1117. /*
  1118.  *    DESCRIPTION
  1119.  *        Based on a given intensity, performs a linear interpolation
  1120.  *        on the values between two IntensityRec structures.
  1121.  *        The bitsPerRGB parameter is necessary to perform rounding
  1122.  *        to the correct number of significant bits.
  1123.  *
  1124.  *    RETURNS
  1125.  *        Returns 0 if failed; otherwise non-zero.
  1126.  */
  1127. {
  1128.     DBUG_ENTER("_XcmsIntensityInterpolation")
  1129.     long target, up, down;
  1130.     int shift = 16 - bitsPerRGB;
  1131.     int max_color = (1 << bitsPerRGB) - 1;
  1132.     XcmsFloat ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
  1133.     answer->intensity = key->intensity;
  1134.     target = hi->value - lo->value;
  1135.     target *= ratio;
  1136.     target += lo->value;
  1137.  
  1138.     /*
  1139.      * Ok now, lets find the closest in respects to bits per RGB
  1140.      */
  1141.     up = ((target >> shift) * 0xFFFF) / max_color;
  1142.     if (up < target) {
  1143.     down = up;
  1144.     up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
  1145.     } else {
  1146.     down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
  1147.     }
  1148.     answer->value = ((up - target) < (target - down) ? up : down);
  1149.     answer->value &= MASK[bitsPerRGB];
  1150.     DBUG_RETURN(XcmsSuccess);
  1151. }
  1152.  
  1153.  
  1154. /*
  1155.  *    NAME
  1156.  *        _XcmsTableSearch
  1157.  *
  1158.  *    SYNOPSIS
  1159.  */
  1160. int
  1161. _XcmsTableSearch (key, bitsPerRGB, base, nel, nKeyPtrSize, compar, interpol, answer)
  1162.     char *key;
  1163.     int bitsPerRGB;
  1164.     char *base;
  1165.     unsigned nel;
  1166.     unsigned nKeyPtrSize;
  1167.     int (*compar)();
  1168.     int (*interpol)();
  1169.     char *answer;
  1170.  
  1171. /*
  1172.  *    DESCRIPTION
  1173.  *        A binary search through the specificied table.
  1174.  *
  1175.  *    RETURNS
  1176.  *        Returns 0 if failed; otherwise non-zero.
  1177.  *
  1178.  */
  1179. {
  1180.     DBUG_ENTER("_XcmsTableSearch")
  1181.     char *hi, *lo, *mid, *last;
  1182.     int result;
  1183.  
  1184.     last = hi = base + ((nel - 1) * nKeyPtrSize);
  1185.     mid = lo = base;
  1186.  
  1187.     /* use only the significants bits, then scale into 16 bits */
  1188.     ((IntensityRec *)key)->value = ((unsigned long)
  1189.         (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
  1190.         / ((1 << bitsPerRGB) - 1);
  1191.  
  1192.     /* Special case so that zero intensity always maps to zero value */
  1193.     if ((*compar) (key,lo) <= 0) {
  1194.     memcpy (answer, lo, nKeyPtrSize);
  1195.     ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
  1196.     DBUG_RETURN(XcmsSuccess);
  1197.     }
  1198.     while (mid != last) {
  1199.     last = mid;
  1200.     mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
  1201.     result = (*compar) (key, mid);
  1202.     if (result == 0) {
  1203.  
  1204.         memcpy(answer, mid, nKeyPtrSize);
  1205.         ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
  1206.         DBUG_RETURN(XcmsSuccess);
  1207.     } else if (result < 0) {
  1208.         hi = mid;
  1209.     } else {
  1210.         lo = mid;
  1211.     }
  1212.     }
  1213.  
  1214.     /*
  1215.      * If we got to here, we didn't find a solution, so we
  1216.      * need to apply interpolation.
  1217.      */
  1218.     result = (*interpol)(key, lo, hi, answer, bitsPerRGB);
  1219.     DBUG_RETURN(result);
  1220. }
  1221.  
  1222.  
  1223. /*
  1224.  *      NAME
  1225.  *        _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
  1226.  *
  1227.  *    SYNOPSIS
  1228.  */
  1229. void _XcmsMatVec(pMat, pIn, pOut)
  1230.     XcmsFloat *pMat, *pIn, *pOut;
  1231. /*
  1232.  *      DESCRIPTION
  1233.  *        Multiply the passed vector by the passed matrix to return a 
  1234.  *        vector. Matrix is 3x3, vectors are of length 3.
  1235.  *
  1236.  *    RETURNS
  1237.  *        void
  1238.  */
  1239. {
  1240.     DBUG_ENTER("_XcmsMatVec")
  1241.     int i, j;
  1242.  
  1243.     for (i = 0; i < 3; i++) {
  1244.     pOut[i] = 0.0;
  1245.     for (j = 0; j < 3; j++)
  1246.         pOut[i] += *(pMat+(i*3)+j) * pIn[j];
  1247.     }
  1248.     DBUG_VOID_RETURN;
  1249. }
  1250.  
  1251.  
  1252. /************************************************************************
  1253.  *                                    *
  1254.  *             PUBLIC ROUTINES                *
  1255.  *                                    *
  1256.  ************************************************************************/
  1257.  
  1258.  
  1259. /*
  1260.  *    NAME
  1261.  *        XcmsLRGB_RGB_ParseString
  1262.  *
  1263.  *    SYNOPSIS
  1264.  */
  1265. static int
  1266. XcmsLRGB_RGB_ParseString(spec, pColor)
  1267.     register char *spec;
  1268.     XcmsColor *pColor;
  1269. /*
  1270.  *    DESCRIPTION
  1271.  *        This routines takes a string and attempts to convert
  1272.  *        it into a XcmsColor structure with XcmsRGBFormat.
  1273.  *
  1274.  *    RETURNS
  1275.  *        0 if failed, non-zero otherwise.
  1276.  */
  1277. {
  1278.     DBUG_ENTER("XcmsLRGB_RGB_ParseString")
  1279.     register int n, i;
  1280.     unsigned short r, g, b;
  1281.     char c;
  1282.     char *pchar;
  1283.     unsigned short *pShort;
  1284.  
  1285.     /*
  1286.      * Check for old # format
  1287.      */
  1288.     if (*spec == '#') {
  1289.     /*
  1290.      * Attempt to parse the value portion.
  1291.      */
  1292.     spec++;
  1293.     n = strlen(spec);
  1294.     if (n != 3 && n != 6 && n != 9 && n != 12) {
  1295.         DBUG_RETURN(XcmsFailure);
  1296.     }
  1297.  
  1298.     n /= 3;
  1299.     g = b = 0;
  1300.     do {
  1301.         r = g;
  1302.         g = b;
  1303.         b = 0;
  1304.         for (i = n; --i >= 0; ) {
  1305.         c = *spec++;
  1306.         b <<= 4;
  1307.         if (c >= '0' && c <= '9')
  1308.             b |= c - '0';
  1309.         /* assume string in lowercase
  1310.         else if (c >= 'A' && c <= 'F')
  1311.             b |= c - ('A' - 10);
  1312.         */
  1313.         else if (c >= 'a' && c <= 'f')
  1314.             b |= c - ('a' - 10);
  1315.         else 
  1316.             DBUG_RETURN(XcmsFailure);
  1317.         }
  1318.     } while (*spec != '\0');
  1319.  
  1320.     /*
  1321.      * Succeeded !
  1322.      */
  1323.     n <<= 2;
  1324.     n = 16 - n;
  1325.     /* shift instead of scale, to match old broken semantics */
  1326.     pColor->spec.RGB.red = r << n;
  1327.     pColor->spec.RGB.green = g << n;
  1328.     pColor->spec.RGB.blue =  b << n;
  1329.     } else {
  1330.     if ((pchar = strchr(spec, ':')) == NULL) {
  1331.         DBUG_RETURN(XcmsFailure);
  1332.     }
  1333.     n = (int)(pchar - spec);
  1334.  
  1335.     /*
  1336.      * Check for proper prefix.
  1337.      */
  1338.     if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
  1339.         DBUG_RETURN(XcmsFailure);
  1340.     }
  1341.  
  1342.     /*
  1343.      * Attempt to parse the value portion.
  1344.      */
  1345.     spec += (n + 1);
  1346.     pShort = &pColor->spec.RGB.red;
  1347.     for (i = 0; i < 3; i++, pShort++, spec++) {
  1348.         n = 0;
  1349.         *pShort = 0;
  1350.         while (*spec != '/' && *spec != '\0') {
  1351.         if (++n > 4) {
  1352.             DBUG_RETURN(XcmsFailure);
  1353.         }
  1354.         c = *spec++;
  1355.         *pShort <<= 4;
  1356.         if (c >= '0' && c <= '9')
  1357.             *pShort |= c - '0';
  1358.         /* assume string in lowercase
  1359.         else if (c >= 'A' && c <= 'F')
  1360.             *pShort |= c - ('A' - 10);
  1361.         */
  1362.         else if (c >= 'a' && c <= 'f')
  1363.             *pShort |= c - ('a' - 10);
  1364.         else 
  1365.             DBUG_RETURN(XcmsFailure);
  1366.         }
  1367.         if (n == 0)
  1368.         DBUG_RETURN(XcmsFailure);
  1369.         if (n < 4) {
  1370.         *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
  1371.         }
  1372.     }
  1373.     }
  1374.     pColor->format = XcmsRGBFormat;
  1375.     pColor->pixel = 0;
  1376.     DBUG_RETURN(XcmsSuccess);
  1377. }
  1378.  
  1379.  
  1380. /*
  1381.  *    NAME
  1382.  *        XcmsLRGB_RGBi_ParseString
  1383.  *
  1384.  *    SYNOPSIS
  1385.  */
  1386. static int
  1387. XcmsLRGB_RGBi_ParseString(spec, pColor)
  1388.     register char *spec;
  1389.     XcmsColor *pColor;
  1390. /*
  1391.  *    DESCRIPTION
  1392.  *        This routines takes a string and attempts to convert
  1393.  *        it into a XcmsColor structure with XcmsRGBiFormat.
  1394.  *        The assumed RGBi string syntax is:
  1395.  *            RGBi:<r>/<g>/<b>
  1396.  *        Where r, g, and b are in string input format for floats
  1397.  *        consisting of:
  1398.  *            a. an optional sign
  1399.  *            b. a string of numbers possibly containing a decimal point,
  1400.  *            c. an optional exponent field containing an 'E' or 'e'
  1401.  *            followed by a possibly signed integer string.
  1402.  *
  1403.  *    RETURNS
  1404.  *        0 if failed, non-zero otherwise.
  1405.  */
  1406. {
  1407.     DBUG_ENTER("XcmsLRGB_RGBi_ParseString")
  1408.     int n;
  1409.     char *pchar;
  1410.  
  1411.     if ((pchar = strchr(spec, ':')) == NULL) {
  1412.     DBUG_RETURN(XcmsFailure);
  1413.     }
  1414.     n = (int)(pchar - spec);
  1415.  
  1416.     /*
  1417.      * Check for proper prefix.
  1418.      */
  1419.     if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
  1420.     DBUG_RETURN(XcmsFailure);
  1421.     }
  1422.  
  1423.     /*
  1424.      * Attempt to parse the value portion.
  1425.      */
  1426.     if (sscanf(spec + n + 1, "%lf/%lf/%lf",
  1427.         &pColor->spec.RGBi.red,
  1428.         &pColor->spec.RGBi.green,
  1429.         &pColor->spec.RGBi.blue) != 3) {
  1430.     DBUG_RETURN(XcmsFailure);
  1431.     }
  1432.  
  1433.     /*
  1434.      * Succeeded !
  1435.      */
  1436.     pColor->format = XcmsRGBiFormat;
  1437.     pColor->pixel = 0;
  1438.     DBUG_RETURN(XcmsSuccess);
  1439. }
  1440.  
  1441.  
  1442. /*
  1443.  *    NAME
  1444.  *        XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
  1445.  *
  1446.  *    SYNOPSIS
  1447.  */
  1448. /* ARGSUSED */
  1449. Status 
  1450. XcmsCIEXYZToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
  1451.     XcmsCCC ccc;
  1452.     XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert     */
  1453.     unsigned int nColors;    /* Number of colors            */
  1454.     Bool *pCompressed;        /* pointer to an array of Bool        */
  1455. /*
  1456.  *    DESCRIPTION
  1457.  *        Converts color specifications in an array of XcmsColor
  1458.  *        structures from RGB format to RGBi format.
  1459.  *
  1460.  *    RETURNS
  1461.  *        XcmsFailure if failed,
  1462.  *        XcmsSuccess if succeeded without gamut compression.
  1463.  *        XcmsSuccessWithCompression if succeeded with gamut
  1464.  *            compression.
  1465.  */
  1466. {
  1467.     DBUG_ENTER("XcmsCIEXYZToRGBi")
  1468.     LINEAR_RGB_SCCData *pScreenData;
  1469.     XcmsFloat tmp[3];
  1470.     int hasCompressed = 0;
  1471.     unsigned int i;
  1472.     XcmsColor *pColor = pXcmsColors_in_out;
  1473.  
  1474.     if (ccc == NULL) {
  1475.     DBUG_RETURN(XcmsFailure);
  1476.     }
  1477.  
  1478.     pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
  1479.  
  1480.     /*
  1481.      * XcmsColors should be White Point Adjusted, if necessary, by now!
  1482.      */
  1483.  
  1484.     /*
  1485.      * NEW!!! for extended gamut compression
  1486.      *
  1487.      * 1. Need to zero out pCompressed
  1488.      *
  1489.      * 2. Need to save initial address of pColor
  1490.      *
  1491.      * 3. Need to save initial address of pCompressed
  1492.      */
  1493.  
  1494.     for (i = 0; i < nColors; i++) {
  1495.  
  1496.     /* Make sure format is XcmsCIEXYZFormat */
  1497.     if (pColor->format != XcmsCIEXYZFormat) {
  1498.         DBUG_RETURN(XcmsFailure);
  1499.     }
  1500.  
  1501.     /* Multiply [A]-1 * [XYZ] to get RGB intensity */
  1502.     _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
  1503.         (XcmsFloat *) &pColor->spec, tmp);
  1504.  
  1505.     if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
  1506.         (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
  1507.  
  1508.         /*
  1509.          * RGBi out of screen's gamut
  1510.          */
  1511.  
  1512.         if (ccc->gamutCompProc == NULL) {
  1513.         /*
  1514.          * Aha!! Here's that little trick that will allow
  1515.          * gamut compression routines to get the out of bound
  1516.          * RGBi.  
  1517.          */
  1518.         memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
  1519.         pColor->format = XcmsRGBiFormat;
  1520.         DBUG_RETURN(XcmsFailure);
  1521.         } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
  1522.             i, pCompressed) == 0) {
  1523.         DBUG_RETURN(XcmsFailure);
  1524.         }
  1525.  
  1526.         /*
  1527.          * The gamut compression function should return colors in CIEXYZ
  1528.          *    Also check again to if the new color is within gamut.
  1529.          */
  1530.         if (pColor->format != XcmsCIEXYZFormat) {
  1531.         DBUG_RETURN(XcmsFailure);
  1532.         }
  1533.         _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
  1534.             (XcmsFloat *) &pColor->spec, tmp);
  1535.         if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
  1536.         (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
  1537.         DBUG_RETURN(XcmsFailure);
  1538.         }
  1539.         hasCompressed++;
  1540.     }
  1541.     memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
  1542.     /* These if statements are done to ensure the fudge factor is */
  1543.     /* is taken into account. */
  1544.     if (pColor->spec.RGBi.red < 0.0) {
  1545.         pColor->spec.RGBi.red = 0.0;
  1546.     } else if (pColor->spec.RGBi.red > 1.0) {
  1547.         pColor->spec.RGBi.red = 1.0;
  1548.     }
  1549.     if (pColor->spec.RGBi.green < 0.0) {
  1550.         pColor->spec.RGBi.green = 0.0;
  1551.     } else if (pColor->spec.RGBi.green > 1.0) {
  1552.         pColor->spec.RGBi.green = 1.0;
  1553.     }
  1554.     if (pColor->spec.RGBi.blue < 0.0) {
  1555.         pColor->spec.RGBi.blue = 0.0;
  1556.     } else if (pColor->spec.RGBi.blue > 1.0) {
  1557.         pColor->spec.RGBi.blue = 1.0;
  1558.     }
  1559.     (pColor++)->format = XcmsRGBiFormat;
  1560.     }
  1561.     DBUG_RETURN(hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
  1562. }
  1563.  
  1564.  
  1565. /*
  1566.  *    NAME
  1567.  *        LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
  1568.  *
  1569.  *    SYNOPSIS
  1570.  */
  1571. /* ARGSUSED */
  1572. Status 
  1573. XcmsRGBiToCIEXYZ(ccc, pXcmsColors_in_out, nColors, pCompressed)
  1574.     XcmsCCC ccc;
  1575.     XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert     */
  1576.     unsigned int nColors;    /* Number of colors            */
  1577.     Bool *pCompressed;        /* pointer to a bit array        */
  1578. /*
  1579.  *    DESCRIPTION
  1580.  *        Converts color specifications in an array of XcmsColor
  1581.  *        structures from RGBi format to CIEXYZ format.
  1582.  *
  1583.  *    RETURNS
  1584.  *        XcmsFailure if failed,
  1585.  *        XcmsSuccess if succeeded.
  1586.  */
  1587. {
  1588.     DBUG_ENTER("XcmsRGBiToCIEXYZ")
  1589.     LINEAR_RGB_SCCData *pScreenData;
  1590.     XcmsFloat tmp[3];
  1591.  
  1592.     /*
  1593.      * pCompressed ignored in this function.
  1594.      */
  1595.  
  1596.     if (ccc == NULL) {
  1597.     DBUG_RETURN(XcmsFailure);
  1598.     }
  1599.  
  1600.     pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
  1601.  
  1602.     /*
  1603.      * XcmsColors should be White Point Adjusted, if necessary, by now!
  1604.      */
  1605.  
  1606.     while (nColors--) {
  1607.  
  1608.     /* Multiply [A]-1 * [XYZ] to get RGB intensity */
  1609.     _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
  1610.         (XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
  1611.  
  1612.     memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp));
  1613.     (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
  1614.     }
  1615.     DBUG_RETURN(XcmsSuccess);
  1616. }
  1617.  
  1618.  
  1619. /*
  1620.  *    NAME
  1621.  *        XcmsRGBiToRGB
  1622.  *
  1623.  *    SYNOPSIS
  1624.  */
  1625. /* ARGSUSED */
  1626. Status 
  1627. XcmsRGBiToRGB(ccc, pXcmsColors_in_out, nColors, pCompressed)
  1628.     XcmsCCC ccc;
  1629.     XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert     */
  1630.     unsigned int nColors;    /* Number of colors            */
  1631.     Bool *pCompressed;        /* pointer to a bit array        */
  1632. /*
  1633.  *    DESCRIPTION
  1634.  *        Converts color specifications in an array of XcmsColor
  1635.  *        structures from RGBi format to RGB format.
  1636.  *
  1637.  *    RETURNS
  1638.  *        XcmsFailure if failed,
  1639.  *        XcmsSuccess if succeeded without gamut compression.
  1640.  *        XcmsSuccessWithCompression if succeeded with gamut
  1641.  *            compression.
  1642.  */
  1643. {
  1644.     DBUG_ENTER("XcmsRGBiToRGB")
  1645.     LINEAR_RGB_SCCData *pScreenData;
  1646.     XcmsRGB tmpRGB;
  1647.     IntensityRec keyIRec, answerIRec;
  1648.  
  1649.     /*
  1650.      * pCompressed ignored in this function.
  1651.      */
  1652.  
  1653.     if (ccc == NULL) {
  1654.     DBUG_RETURN(XcmsFailure);
  1655.     }
  1656.  
  1657.     pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
  1658.  
  1659.     while (nColors--) {
  1660.  
  1661.     /* Make sure format is XcmsRGBiFormat */
  1662.     if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
  1663.         DBUG_RETURN(XcmsFailure);
  1664.     }
  1665.  
  1666.     keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
  1667.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1668.         (char *)pScreenData->pRedTbl->pBase,
  1669.         (unsigned)pScreenData->pRedTbl->nEntries,
  1670.         (unsigned)sizeof(IntensityRec),
  1671.         _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
  1672.         DBUG_RETURN(XcmsFailure);
  1673.     }
  1674.     tmpRGB.red = answerIRec.value;
  1675.  
  1676.     keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
  1677.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1678.         (char *)pScreenData->pGreenTbl->pBase,
  1679.         (unsigned)pScreenData->pGreenTbl->nEntries,
  1680.         (unsigned)sizeof(IntensityRec),
  1681.         _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
  1682.         DBUG_RETURN(XcmsFailure);
  1683.     }
  1684.     tmpRGB.green = answerIRec.value;
  1685.  
  1686.     keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
  1687.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1688.         (char *)pScreenData->pBlueTbl->pBase,
  1689.         (unsigned)pScreenData->pBlueTbl->nEntries,
  1690.         (unsigned)sizeof(IntensityRec),
  1691.         _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
  1692.         DBUG_RETURN(XcmsFailure);
  1693.     }
  1694.     tmpRGB.blue = answerIRec.value;
  1695.  
  1696.     memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
  1697.     (pXcmsColors_in_out++)->format = XcmsRGBFormat;
  1698.     }
  1699.     DBUG_RETURN(XcmsSuccess);
  1700. }
  1701.  
  1702.  
  1703. /*
  1704.  *    NAME
  1705.  *        XcmsRGBToRGBi
  1706.  *
  1707.  *    SYNOPSIS
  1708.  */
  1709. /* ARGSUSED */
  1710. Status 
  1711. XcmsRGBToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
  1712.     XcmsCCC ccc;
  1713.     XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert     */
  1714.     unsigned int nColors;    /* Number of colors            */
  1715.     Bool *pCompressed;        /* pointer to a bit array        */
  1716. /*
  1717.  *    DESCRIPTION
  1718.  *        Converts color specifications in an array of XcmsColor
  1719.  *        structures from RGB format to RGBi format.
  1720.  *
  1721.  *    RETURNS
  1722.  *        XcmsFailure if failed,
  1723.  *        XcmsSuccess if succeeded.
  1724.  */
  1725. {
  1726.     DBUG_ENTER("XcmsRGBToRGBi")
  1727.     LINEAR_RGB_SCCData *pScreenData;
  1728.     XcmsRGBi tmpRGBi;
  1729.     IntensityRec keyIRec, answerIRec;
  1730.  
  1731.     /*
  1732.      * pCompressed ignored in this function.
  1733.      */
  1734.  
  1735.     if (ccc == NULL) {
  1736.     DBUG_RETURN(XcmsFailure);
  1737.     }
  1738.  
  1739.     pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
  1740.  
  1741.     while (nColors--) {
  1742.  
  1743.     /* Make sure format is XcmsRGBFormat */
  1744.     if (pXcmsColors_in_out->format != XcmsRGBFormat) {
  1745.         DBUG_RETURN(XcmsFailure);
  1746.     }
  1747.  
  1748.     keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
  1749.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1750.         (char *)pScreenData->pRedTbl->pBase,
  1751.         (unsigned)pScreenData->pRedTbl->nEntries,
  1752.         (unsigned)sizeof(IntensityRec),
  1753.         _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
  1754.         DBUG_RETURN(XcmsFailure);
  1755.     }
  1756.     tmpRGBi.red = answerIRec.intensity;
  1757.  
  1758.     keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
  1759.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1760.         (char *)pScreenData->pGreenTbl->pBase,
  1761.         (unsigned)pScreenData->pGreenTbl->nEntries,
  1762.         (unsigned)sizeof(IntensityRec),
  1763.         _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
  1764.         DBUG_RETURN(XcmsFailure);
  1765.     }
  1766.     tmpRGBi.green = answerIRec.intensity;
  1767.  
  1768.     keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
  1769.     if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
  1770.         (char *)pScreenData->pBlueTbl->pBase,
  1771.         (unsigned)pScreenData->pBlueTbl->nEntries,
  1772.         (unsigned)sizeof(IntensityRec),
  1773.         _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
  1774.         DBUG_RETURN(XcmsFailure);
  1775.     }
  1776.     tmpRGBi.blue = answerIRec.intensity;
  1777.  
  1778.     memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
  1779.     (pXcmsColors_in_out++)->format = XcmsRGBiFormat;
  1780.     }
  1781.     DBUG_RETURN(XcmsSuccess);
  1782. }
  1783.  
  1784. /*
  1785.  *    NAME
  1786.  *        _XcmsInitScrnDefaultInfo
  1787.  *
  1788.  *    SYNOPSIS
  1789.  */
  1790. /* ARGSUSED */
  1791. int
  1792. _XcmsLRGB_InitScrnDefault(dpy, screenNumber, pPerScrnInfo)
  1793.     Display *dpy;
  1794.     int screenNumber;
  1795.     XcmsPerScrnInfo *pPerScrnInfo;
  1796. /*
  1797.  *    DESCRIPTION
  1798.  *        Given a display and screen number, this routine attempts
  1799.  *        to initialize the Xcms per Screen Info structure
  1800.  *        (XcmsPerScrnInfo) with defaults.
  1801.  *
  1802.  *    RETURNS
  1803.  *        Returns zero if initialization failed; non-zero otherwise.
  1804.  */
  1805. {
  1806.     DBUG_ENTER("_XcmsLRGB_InitScrnDefault")
  1807.     pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
  1808.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
  1809.         Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
  1810.         Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
  1811.         Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
  1812.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
  1813.         Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
  1814.         Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
  1815.         Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
  1816.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
  1817.         Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
  1818.         Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
  1819.         Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
  1820.     if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
  1821.         || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
  1822.     pPerScrnInfo->screenData = (XPointer)NULL;
  1823.     pPerScrnInfo->state = XcmsInitNone;
  1824.     DBUG_RETURN(0);
  1825.     }
  1826.     pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
  1827.     pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
  1828.     pPerScrnInfo->screenWhitePt.pixel = 0;
  1829.     pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
  1830.     pPerScrnInfo->state = XcmsInitFailure; /* default initialization */
  1831.     DBUG_RETURN(1);
  1832. }
  1833.