diff options
Diffstat (limited to 'libX11/src/xcms/LRGB.c')
| -rw-r--r-- | libX11/src/xcms/LRGB.c | 3688 | 
1 files changed, 1844 insertions, 1844 deletions
| diff --git a/libX11/src/xcms/LRGB.c b/libX11/src/xcms/LRGB.c index 2dca82ee8..8f1394b7f 100644 --- a/libX11/src/xcms/LRGB.c +++ b/libX11/src/xcms/LRGB.c @@ -1,1844 +1,1844 @@ - -/* - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * 	All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System.  Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation.  TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose.  It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. - * - * - *	NAME - *		XcmsLRGB.c - * - *	DESCRIPTION - *		This file contains the conversion routines: - *		    1. CIE XYZ to RGB intensity - *		    2. RGB intensity to device RGB - *		    3. device RGB to RGB intensity - *		    4. RGB intensity to CIE XYZ - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xcmsint.h" -#include "Cv.h" - -/* - *      LOCAL DEFINES - *		#define declarations local to this package. - */ -#define EPS	0.001 -#ifndef MIN -#define MIN(x,y) ((x) > (y) ? (y) : (x)) -#endif /* MIN */ -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif /* MAX */ -#ifndef MIN3 -#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) -#endif /* MIN3 */ -#ifndef MAX3 -#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) -#endif /* MAX3 */ - -/* - *      LOCAL TYPEDEFS - *              typedefs local to this package (for use with local vars). - * - */ - -/* - *      FORWARD DECLARATIONS - */ -static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp); -static int LINEAR_RGB_InitSCCData(Display *dpy, -    int screenNumber, XcmsPerScrnInfo *pPerScrnInfo); -static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor); -static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor); -static Status -_XcmsGetTableType0( -    IntensityTbl *pTbl, -    int	  format, -    char **pChar, -    unsigned long *pCount); -static Status -_XcmsGetTableType1( -    IntensityTbl *pTbl, -    int	  format, -    char **pChar, -    unsigned long *pCount); - -/* - *      LOCALS VARIABLES - *		Variables local to this package. - *		    Usage example: - *		        static int	ExampleLocalVar; - */ - -static unsigned short const MASK[17] = { -    0x0000,	/*  0 bitsPerRGB */ -    0x8000,	/*  1 bitsPerRGB */ -    0xc000,	/*  2 bitsPerRGB */ -    0xe000,	/*  3 bitsPerRGB */ -    0xf000,	/*  4 bitsPerRGB */ -    0xf800,	/*  5 bitsPerRGB */ -    0xfc00,	/*  6 bitsPerRGB */ -    0xfe00,	/*  7 bitsPerRGB */ -    0xff00,	/*  8 bitsPerRGB */ -    0xff80,	/*  9 bitsPerRGB */ -    0xffc0,	/* 10 bitsPerRGB */ -    0xffe0,	/* 11 bitsPerRGB */ -    0xfff0,	/* 12 bitsPerRGB */ -    0xfff8,	/* 13 bitsPerRGB */ -    0xfffc,	/* 14 bitsPerRGB */ -    0xfffe,	/* 15 bitsPerRGB */ -    0xffff	/* 16 bitsPerRGB */ -}; - - -    /* -     * A NULL terminated array of function pointers that when applied -     * in series will convert an XcmsColor structure from XcmsRGBFormat -     * to XcmsCIEXYZFormat. -     */ -static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = { -    (XcmsConversionProc)XcmsRGBToRGBi, -    (XcmsConversionProc)XcmsRGBiToCIEXYZ, -    NULL -}; - -    /* -     * A NULL terminated array of function pointers that when applied -     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat -     * to XcmsRGBFormat. -     */ -static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = { -    (XcmsConversionProc)XcmsCIEXYZToRGBi, -    (XcmsConversionProc)XcmsRGBiToRGB, -    NULL -}; - -    /* -     * A NULL terminated array of function pointers that when applied -     * in series will convert an XcmsColor structure from XcmsRGBiFormat -     * to XcmsCIEXYZFormat. -     */ -static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = { -    (XcmsConversionProc)XcmsRGBiToCIEXYZ, -    NULL -}; - -    /* -     * A NULL terminated array of function pointers that when applied -     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat -     * to XcmsRGBiFormat. -     */ -static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = { -    (XcmsConversionProc)XcmsCIEXYZToRGBi, -    NULL -}; - -    /* -     * RGBi Color Spaces -     */ -XcmsColorSpace	XcmsRGBiColorSpace = -    { -	_XcmsRGBi_prefix,	/* prefix */ -	XcmsRGBiFormat,		/* id */ -	XcmsLRGB_RGBi_ParseString,	/* parseString */ -	Fl_RGBi_to_CIEXYZ,	/* to_CIEXYZ */ -	Fl_CIEXYZ_to_RGBi,	/* from_CIEXYZ */ -	1 -    }; - -    /* -     * RGB Color Spaces -     */ -XcmsColorSpace	XcmsRGBColorSpace = -    { -	_XcmsRGB_prefix,		/* prefix */ -	XcmsRGBFormat,		/* id */ -	XcmsLRGB_RGB_ParseString,	/* parseString */ -	Fl_RGB_to_CIEXYZ,	/* to_CIEXYZ */ -	Fl_CIEXYZ_to_RGB,	/* from_CIEXYZ */ -	1 -    }; - -    /* -     * Device-Independent Color Spaces known to the -     * LINEAR_RGB Screen Color Characteristics Function Set. -     */ -static XcmsColorSpace	*DDColorSpaces[] = { -    &XcmsRGBColorSpace, -    &XcmsRGBiColorSpace, -    NULL -}; - - -/* - *      GLOBALS - *              Variables declared in this package that are allowed - *		to be used globally. - */ - -    /* -     * LINEAR_RGB Screen Color Characteristics Function Set. -     */ -XcmsFunctionSet	XcmsLinearRGBFunctionSet = -    { -	&DDColorSpaces[0],	/* pDDColorSpaces */ -	LINEAR_RGB_InitSCCData,	/* pInitScrnFunc */ -	LINEAR_RGB_FreeSCCData	/* pFreeSCCData */ -    }; - -/* - *	DESCRIPTION - *		Contents of Default SCCData should be replaced if other - *		data should be used as default. - * - * - */ - -/* - * NAME		Tektronix 19" (Sony) CRT - * PART_NUMBER		119-2451-00 - * MODEL		Tek4300, Tek4800 - */ - -static IntensityRec const Default_RGB_RedTuples[] = { -    /* {unsigned short value, XcmsFloat intensity} */ -            { 0x0000,    0.000000 }, -            { 0x0909,    0.000000 }, -            { 0x0a0a,    0.000936 }, -            { 0x0f0f,    0.001481 }, -            { 0x1414,    0.002329 }, -            { 0x1919,    0.003529 }, -            { 0x1e1e,    0.005127 }, -            { 0x2323,    0.007169 }, -            { 0x2828,    0.009699 }, -            { 0x2d2d,    0.012759 }, -            { 0x3232,    0.016392 }, -            { 0x3737,    0.020637 }, -            { 0x3c3c,    0.025533 }, -            { 0x4141,    0.031119 }, -            { 0x4646,    0.037431 }, -            { 0x4b4b,    0.044504 }, -            { 0x5050,    0.052373 }, -            { 0x5555,    0.061069 }, -            { 0x5a5a,    0.070624 }, -            { 0x5f5f,    0.081070 }, -            { 0x6464,    0.092433 }, -            { 0x6969,    0.104744 }, -            { 0x6e6e,    0.118026 }, -            { 0x7373,    0.132307 }, -            { 0x7878,    0.147610 }, -            { 0x7d7d,    0.163958 }, -            { 0x8282,    0.181371 }, -            { 0x8787,    0.199871 }, -            { 0x8c8c,    0.219475 }, -            { 0x9191,    0.240202 }, -            { 0x9696,    0.262069 }, -            { 0x9b9b,    0.285089 }, -            { 0xa0a0,    0.309278 }, -            { 0xa5a5,    0.334647 }, -            { 0xaaaa,    0.361208 }, -            { 0xafaf,    0.388971 }, -            { 0xb4b4,    0.417945 }, -            { 0xb9b9,    0.448138 }, -            { 0xbebe,    0.479555 }, -            { 0xc3c3,    0.512202 }, -            { 0xc8c8,    0.546082 }, -            { 0xcdcd,    0.581199 }, -            { 0xd2d2,    0.617552 }, -            { 0xd7d7,    0.655144 }, -            { 0xdcdc,    0.693971 }, -            { 0xe1e1,    0.734031 }, -            { 0xe6e6,    0.775322 }, -            { 0xebeb,    0.817837 }, -            { 0xf0f0,    0.861571 }, -            { 0xf5f5,    0.906515 }, -            { 0xfafa,    0.952662 }, -            { 0xffff,    1.000000 } -}; - -static IntensityRec const Default_RGB_GreenTuples[] = { -    /* {unsigned short value, XcmsFloat intensity} */ -            { 0x0000,    0.000000 }, -            { 0x1313,    0.000000 }, -            { 0x1414,    0.000832 }, -            { 0x1919,    0.001998 }, -            { 0x1e1e,    0.003612 }, -            { 0x2323,    0.005736 }, -            { 0x2828,    0.008428 }, -            { 0x2d2d,    0.011745 }, -            { 0x3232,    0.015740 }, -            { 0x3737,    0.020463 }, -            { 0x3c3c,    0.025960 }, -            { 0x4141,    0.032275 }, -            { 0x4646,    0.039449 }, -            { 0x4b4b,    0.047519 }, -            { 0x5050,    0.056520 }, -            { 0x5555,    0.066484 }, -            { 0x5a5a,    0.077439 }, -            { 0x5f5f,    0.089409 }, -            { 0x6464,    0.102418 }, -            { 0x6969,    0.116485 }, -            { 0x6e6e,    0.131625 }, -            { 0x7373,    0.147853 }, -            { 0x7878,    0.165176 }, -            { 0x7d7d,    0.183604 }, -            { 0x8282,    0.203140 }, -            { 0x8787,    0.223783 }, -            { 0x8c8c,    0.245533 }, -            { 0x9191,    0.268384 }, -            { 0x9696,    0.292327 }, -            { 0x9b9b,    0.317351 }, -            { 0xa0a0,    0.343441 }, -            { 0xa5a5,    0.370580 }, -            { 0xaaaa,    0.398747 }, -            { 0xafaf,    0.427919 }, -            { 0xb4b4,    0.458068 }, -            { 0xb9b9,    0.489165 }, -            { 0xbebe,    0.521176 }, -            { 0xc3c3,    0.554067 }, -            { 0xc8c8,    0.587797 }, -            { 0xcdcd,    0.622324 }, -            { 0xd2d2,    0.657604 }, -            { 0xd7d7,    0.693588 }, -            { 0xdcdc,    0.730225 }, -            { 0xe1e1,    0.767459 }, -            { 0xe6e6,    0.805235 }, -            { 0xebeb,    0.843491 }, -            { 0xf0f0,    0.882164 }, -            { 0xf5f5,    0.921187 }, -            { 0xfafa,    0.960490 }, -            { 0xffff,    1.000000 } -}; - -static IntensityRec const Default_RGB_BlueTuples[] = { -    /* {unsigned short value, XcmsFloat intensity} */ -            { 0x0000,    0.000000 }, -            { 0x0e0e,    0.000000 }, -            { 0x0f0f,    0.001341 }, -            { 0x1414,    0.002080 }, -            { 0x1919,    0.003188 }, -            { 0x1e1e,    0.004729 }, -            { 0x2323,    0.006766 }, -            { 0x2828,    0.009357 }, -            { 0x2d2d,    0.012559 }, -            { 0x3232,    0.016424 }, -            { 0x3737,    0.021004 }, -            { 0x3c3c,    0.026344 }, -            { 0x4141,    0.032489 }, -            { 0x4646,    0.039481 }, -            { 0x4b4b,    0.047357 }, -            { 0x5050,    0.056154 }, -            { 0x5555,    0.065903 }, -            { 0x5a5a,    0.076634 }, -            { 0x5f5f,    0.088373 }, -            { 0x6464,    0.101145 }, -            { 0x6969,    0.114968 }, -            { 0x6e6e,    0.129862 }, -            { 0x7373,    0.145841 }, -            { 0x7878,    0.162915 }, -            { 0x7d7d,    0.181095 }, -            { 0x8282,    0.200386 }, -            { 0x8787,    0.220791 }, -            { 0x8c8c,    0.242309 }, -            { 0x9191,    0.264937 }, -            { 0x9696,    0.288670 }, -            { 0x9b9b,    0.313499 }, -            { 0xa0a0,    0.339410 }, -            { 0xa5a5,    0.366390 }, -            { 0xaaaa,    0.394421 }, -            { 0xafaf,    0.423481 }, -            { 0xb4b4,    0.453547 }, -            { 0xb9b9,    0.484592 }, -            { 0xbebe,    0.516587 }, -            { 0xc3c3,    0.549498 }, -            { 0xc8c8,    0.583291 }, -            { 0xcdcd,    0.617925 }, -            { 0xd2d2,    0.653361 }, -            { 0xd7d7,    0.689553 }, -            { 0xdcdc,    0.726454 }, -            { 0xe1e1,    0.764013 }, -            { 0xe6e6,    0.802178 }, -            { 0xebeb,    0.840891 }, -            { 0xf0f0,    0.880093 }, -            { 0xf5f5,    0.919723 }, -            { 0xfafa,    0.959715 }, -	    { 0xffff,    1.00000 } -}; - -static IntensityTbl Default_RGB_RedTbl = { -    /* IntensityRec *pBase */ -	(IntensityRec *) Default_RGB_RedTuples, -    /* unsigned int nEntries */ -	52 -}; - -static IntensityTbl Default_RGB_GreenTbl = { -    /* IntensityRec *pBase */ -	(IntensityRec *)Default_RGB_GreenTuples, -    /* unsigned int nEntries */ -	50 -}; - -static IntensityTbl Default_RGB_BlueTbl = { -    /* IntensityRec *pBase */ -	(IntensityRec *)Default_RGB_BlueTuples, -    /* unsigned int nEntries */ -	51 -}; - -static LINEAR_RGB_SCCData Default_RGB_SCCData = { -    /* XcmsFloat XYZtoRGBmatrix[3][3] */ -  { -    { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 }, -    {-1.07152751306193600,  1.96593795204372400,  0.03673691339553462 }, -    { 0.06351179790497788, -0.20020501000496480,  0.81070942031648220 } -  }, - -    /* XcmsFloat RGBtoXYZmatrix[3][3] */ -  { -    { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 }, -    { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 }, -    { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 } -  }, - -    /* IntensityTbl *pRedTbl */ -	&Default_RGB_RedTbl, - -    /* IntensityTbl *pGreenTbl */ -	&Default_RGB_GreenTbl, - -    /* IntensityTbl *pBlueTbl */ -	&Default_RGB_BlueTbl -}; - -/************************************************************************ - *									* - *			PRIVATE ROUTINES				* - *									* - ************************************************************************/ - -/* - *	NAME - *		LINEAR_RGB_InitSCCData() - * - *	SYNOPSIS - */ -static Status -LINEAR_RGB_InitSCCData( -    Display *dpy, -    int screenNumber, -    XcmsPerScrnInfo *pPerScrnInfo) -/* - *	DESCRIPTION - * - *	RETURNS - *		XcmsFailure if failed. - *		XcmsSuccess if succeeded. - * - */ -{ -    Atom  CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); -    Atom  MatrixAtom  = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); -    int	  format_return, count, cType, nTables; -    unsigned long nitems, nbytes_return; -    char *property_return, *pChar; -    XcmsFloat *pValue; -#ifdef ALLDEBUG -    IntensityRec *pIRec; -#endif /* ALLDEBUG */ -    VisualID visualID; - -    LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData; -    XcmsIntensityMap *pNewMap; - -    /* -     * Allocate memory for pScreenData -     */ -    if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) -		      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { -	return(XcmsFailure); -    } - -    /* -     *  1. Get the XYZ->RGB and RGB->XYZ matrices -     */ - -    if (MatrixAtom == None || -	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, -	   &format_return, &nitems, &nbytes_return, &property_return) || -	   nitems != 18 || format_return != 32) { -	/* -	 * As per the XDCCC, there must be 18 data items and each must be -	 * in 32 bits ! -	 */ -	goto FreeSCCData; - -    } else { - -	/* -	 * RGBtoXYZ and XYZtoRGB matrices -	 */ -	pValue = (XcmsFloat *) pScreenData; -	pChar = property_return; -	for (count = 0; count < 18; count++) { -	    *pValue++ = (long)_XcmsGetElement(format_return, &pChar, -		    &nitems) / (XcmsFloat)XDCCC_NUMBER; -	} -	Xfree ((char *)property_return); -	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = -		pScreenData->RGBtoXYZmatrix[0][0] + -		pScreenData->RGBtoXYZmatrix[0][1] + -		pScreenData->RGBtoXYZmatrix[0][2]; -	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = -		pScreenData->RGBtoXYZmatrix[1][0] + -		pScreenData->RGBtoXYZmatrix[1][1] + -		pScreenData->RGBtoXYZmatrix[1][2]; -	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = -		pScreenData->RGBtoXYZmatrix[2][0] + -		pScreenData->RGBtoXYZmatrix[2][1] + -		pScreenData->RGBtoXYZmatrix[2][2]; - -	/* -	 * Compute the Screen White Point -	 */ -	if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) -		|| (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { -	    goto FreeSCCData; -	} else { -	    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; -	} -	pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; -	pPerScrnInfo->screenWhitePt.pixel = 0; - -#ifdef PDEBUG -	printf ("RGB to XYZ Matrix values:\n"); -	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n", -		pScreenData->RGBtoXYZmatrix[0][0], -		pScreenData->RGBtoXYZmatrix[0][1], -		pScreenData->RGBtoXYZmatrix[0][2], -		pScreenData->RGBtoXYZmatrix[1][0], -		pScreenData->RGBtoXYZmatrix[1][1], -		pScreenData->RGBtoXYZmatrix[1][2], -		pScreenData->RGBtoXYZmatrix[2][0], -		pScreenData->RGBtoXYZmatrix[2][1], -		pScreenData->RGBtoXYZmatrix[2][2]); -	printf ("XYZ to RGB Matrix values:\n"); -	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n", -		pScreenData->XYZtoRGBmatrix[0][0], -		pScreenData->XYZtoRGBmatrix[0][1], -		pScreenData->XYZtoRGBmatrix[0][2], -		pScreenData->XYZtoRGBmatrix[1][0], -		pScreenData->XYZtoRGBmatrix[1][1], -		pScreenData->XYZtoRGBmatrix[1][2], -		pScreenData->XYZtoRGBmatrix[2][0], -		pScreenData->XYZtoRGBmatrix[2][1], -		pScreenData->XYZtoRGBmatrix[2][2]); -	printf ("Screen White Pt value: %f %f %f\n", -		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X, -		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y, -		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z); -#endif /* PDEBUG */ -    } - -    /* -     *	2. Get the Intensity Profile -     */ -    if (CorrectAtom == None || -	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom, -	   &format_return, &nitems, &nbytes_return, &property_return)) { -	goto FreeSCCData; -    } - -    pChar = property_return; - -    while (nitems) { -	switch (format_return) { -	  case 8: -	    /* -	     * Must have at least: -	     *		VisualID0 -	     *		VisualID1 -	     *		VisualID2 -	     *		VisualID3 -	     *		type -	     *		count -	     *		length -	     *		intensity1 -	     *		intensity2 -	     */ -	    if (nitems < 9) { -		goto Free_property_return; -	    } -	    count = 3; -	    break; -	  case 16: -	    /* -	     * Must have at least: -	     *		VisualID0 -	     *		VisualID3 -	     *		type -	     *		count -	     *		length -	     *		intensity1 -	     *		intensity2 -	     */ -	    if (nitems < 7) { -		goto Free_property_return; -	    } -	    count = 1; -	    break; -	  case 32: -	    /* -	     * Must have at least: -	     *		VisualID0 -	     *		type -	     *		count -	     *		length -	     *		intensity1 -	     *		intensity2 -	     */ -	    if (nitems < 6) { -		goto Free_property_return; -	    } -	    count = 0; -	    break; -	  default: -	    goto Free_property_return; -	} - -	/* -	 * Get VisualID -	 */ -	visualID = _XcmsGetElement(format_return, &pChar, &nitems); -	while (count--) { -	    visualID = visualID << format_return; -	    visualID |= _XcmsGetElement(format_return, &pChar, &nitems); -	} - -	if (visualID == 0) { -	    /* -	     * This is a shared intensity table -	     */ -	    pScreenData = pScreenDefaultData; -	} else { -	    /* -	     * This is a per-Visual intensity table -	     */ -	    if (!(pScreenData = (LINEAR_RGB_SCCData *) -			      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { -		return(XcmsFailure); -	    } -	    /* copy matrices */ -	    memcpy((char *)pScreenData, (char *)pScreenDefaultData, -		   18 * sizeof(XcmsFloat)); - -	    /* Create, initialize, and add map */ -	    if (!(pNewMap = (XcmsIntensityMap *) -			      Xcalloc (1, sizeof(XcmsIntensityMap)))) { -		Xfree((char *)pScreenData); -		return(XcmsFailure); -	    } -	    pNewMap->visualID = visualID; -	    pNewMap->screenData = (XPointer)pScreenData; -	    pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData; -	    pNewMap->pNext = -		    (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; -	    dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap; -	    dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps; -	} - -	cType = _XcmsGetElement(format_return, &pChar, &nitems); -	nTables = _XcmsGetElement(format_return, &pChar, &nitems); - -	if (cType == 0) { - -	    /* Red Intensity Table */ -	    if (!(pScreenData->pRedTbl = (IntensityTbl *) -		    Xcalloc (1, sizeof(IntensityTbl)))) { -		goto Free_property_return; -	    } -	    if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar, -		    &nitems) == XcmsFailure) { -		goto FreeRedTbl; -	    } - -	    if (nTables == 1) { -		/* Green Intensity Table */ -		pScreenData->pGreenTbl = pScreenData->pRedTbl; -		/* Blue Intensity Table */ -		pScreenData->pBlueTbl = pScreenData->pRedTbl; -	    } else { -		/* Green Intensity Table */ -		if (!(pScreenData->pGreenTbl = (IntensityTbl *) -			Xcalloc (1, sizeof(IntensityTbl)))) { -		    goto FreeRedTblElements; -		} -		if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar, -			&nitems) == XcmsFailure) { -		    goto FreeGreenTbl; -		} - -		/* Blue Intensity Table */ -		if (!(pScreenData->pBlueTbl = (IntensityTbl *) -			Xcalloc (1, sizeof(IntensityTbl)))) { -		    goto FreeGreenTblElements; -		} -		if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar, -			&nitems) == XcmsFailure) { -		    goto FreeBlueTbl; -		} -	    } -	} else if (cType == 1) { -	    /* Red Intensity Table */ -	    if (!(pScreenData->pRedTbl = (IntensityTbl *) -		    Xcalloc (1, sizeof(IntensityTbl)))) { -		goto Free_property_return; -	    } -	    if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar, -		    &nitems) == XcmsFailure) { -		goto FreeRedTbl; -	    } - -	    if (nTables == 1) { - -		/* Green Intensity Table */ -		pScreenData->pGreenTbl = pScreenData->pRedTbl; -		/* Blue Intensity Table */ -		pScreenData->pBlueTbl = pScreenData->pRedTbl; - -	    } else { - -		/* Green Intensity Table */ -		if (!(pScreenData->pGreenTbl = (IntensityTbl *) -			Xcalloc (1, sizeof(IntensityTbl)))) { -		    goto FreeRedTblElements; -		} -		if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar, -			&nitems) == XcmsFailure) { -		    goto FreeGreenTbl; -		} - -		/* Blue Intensity Table */ -		if (!(pScreenData->pBlueTbl = (IntensityTbl *) -			Xcalloc (1, sizeof(IntensityTbl)))) { -		    goto FreeGreenTblElements; -		} -		if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar, -			&nitems) == XcmsFailure) { -		    goto FreeBlueTbl; -		} -	    } -	} else { -	    goto Free_property_return; -	} - -#ifdef ALLDEBUG -	printf ("Intensity Table  RED    %d\n", pScreenData->pRedTbl->nEntries); -	pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase; -	for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) { -	    printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); -	} -	if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) { -	    printf ("Intensity Table  GREEN  %d\n", pScreenData->pGreenTbl->nEntries); -	    pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase; -	    for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) { -		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); -	    } -	} -	if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) { -	    printf ("Intensity Table  BLUE   %d\n", pScreenData->pBlueTbl->nEntries); -	    pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase; -	    for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) { -		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); -	    } -	} -#endif /* ALLDEBUG */ -    } - -    Xfree ((char *)property_return); - -    /* Free the old memory and use the new structure created. */ -    LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData); - -    pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet; - -    pPerScrnInfo->screenData = (XPointer) pScreenData; - -    pPerScrnInfo->state = XcmsInitSuccess; - -    return(XcmsSuccess); - -FreeBlueTblElements: -    Xfree((char *)pScreenData->pBlueTbl->pBase); - -FreeBlueTbl: -    Xfree((char *)pScreenData->pBlueTbl); - -FreeGreenTblElements: -    Xfree((char *)pScreenData->pBlueTbl->pBase); - -FreeGreenTbl: -    Xfree((char *)pScreenData->pGreenTbl); - -FreeRedTblElements: -    Xfree((char *)pScreenData->pRedTbl->pBase); - -FreeRedTbl: -    Xfree((char *)pScreenData->pRedTbl); - -Free_property_return: -    Xfree ((char *)property_return); - -FreeSCCData: -    Xfree((char *)pScreenData); -    pPerScrnInfo->state = XcmsInitNone; -    return(XcmsFailure); -} - - -/* - *	NAME - *		LINEAR_RGB_FreeSCCData() - * - *	SYNOPSIS - */ -static void -LINEAR_RGB_FreeSCCData( -    XPointer pScreenDataTemp) -/* - *	DESCRIPTION - * - *	RETURNS - *		0 if failed. - *		1 if succeeded with no modifications. - * - */ -{ -    LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp; - -    if (pScreenData && pScreenData != &Default_RGB_SCCData) { -	if (pScreenData->pRedTbl) { -	    if (pScreenData->pGreenTbl) { -		if (pScreenData->pRedTbl->pBase != -		    pScreenData->pGreenTbl->pBase) { -		    if (pScreenData->pGreenTbl->pBase) { -			Xfree ((char *)pScreenData->pGreenTbl->pBase); -		    } -		} -		if (pScreenData->pGreenTbl != pScreenData->pRedTbl) { -		    Xfree ((char *)pScreenData->pGreenTbl); -		} -	    } -	    if (pScreenData->pBlueTbl) { -		if (pScreenData->pRedTbl->pBase != -		    pScreenData->pBlueTbl->pBase) { -		    if (pScreenData->pBlueTbl->pBase) { -			Xfree ((char *)pScreenData->pBlueTbl->pBase); -		    } -		} -		if (pScreenData->pBlueTbl != pScreenData->pRedTbl) { -		    Xfree ((char *)pScreenData->pBlueTbl); -		} -	    } -	    if (pScreenData->pRedTbl->pBase) { -		Xfree ((char *)pScreenData->pRedTbl->pBase); -	    } -	    Xfree ((char *)pScreenData->pRedTbl); -	} -	Xfree ((char *)pScreenData); -    } -} - - - -/************************************************************************ - *									* - *			API PRIVATE ROUTINES				* - *									* - ************************************************************************/ - -/* - *	NAME - *		_XcmsGetTableType0 - * - *	SYNOPSIS - */ -static Status -_XcmsGetTableType0( -    IntensityTbl *pTbl, -    int	  format, -    char **pChar, -    unsigned long *pCount) -/* - *	DESCRIPTION - * - *	RETURNS - *		XcmsFailure if failed. - *		XcmsSuccess if succeeded. - * - */ -{ -    unsigned int nElements; -    IntensityRec *pIRec; - -    nElements = pTbl->nEntries = -	    _XcmsGetElement(format, pChar, pCount) + 1; -    if (!(pIRec = pTbl->pBase = (IntensityRec *) -	  Xcalloc (nElements, sizeof(IntensityRec)))) { -	return(XcmsFailure); -    } - -    switch (format) { -      case 8: -	for (; nElements--; pIRec++) { -	    /* 0xFFFF/0xFF = 0x101 */ -	    pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; -	    pIRec->intensity = -		    _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; -	} -	break; -      case 16: -	for (; nElements--; pIRec++) { -	    pIRec->value = _XcmsGetElement (format, pChar, pCount); -	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount) -		    / (XcmsFloat)65535.0; -	} -	break; -      case 32: -	for (; nElements--; pIRec++) { -	    pIRec->value = _XcmsGetElement (format, pChar, pCount); -	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount) -		    / (XcmsFloat)4294967295.0; -	} -	break; -      default: -	return(XcmsFailure); -    } -    return(XcmsSuccess); -} - - -/* - *	NAME - *		_XcmsGetTableType1 - * - *	SYNOPSIS - */ -static Status -_XcmsGetTableType1( -    IntensityTbl *pTbl, -    int	  format, -    char **pChar, -    unsigned long *pCount) -/* - *	DESCRIPTION - * - *	RETURNS - *		XcmsFailure if failed. - *		XcmsSuccess if succeeded. - * - */ -{ -    int count; -    unsigned int max_index; -    IntensityRec *pIRec; - -    max_index = _XcmsGetElement(format, pChar, pCount); -    pTbl->nEntries = max_index + 1; -    if (!(pIRec = pTbl->pBase = (IntensityRec *) -	  Xcalloc (max_index+1, sizeof(IntensityRec)))) { -	return(XcmsFailure); -    } - -    switch (format) { -      case 8: -	for (count = 0; count < max_index+1; count++, pIRec++) { -	    pIRec->value = (count * 65535) / max_index; -	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount) -		    / (XcmsFloat)255.0; -	} -	break; -      case 16: -	for (count = 0; count < max_index+1; count++, pIRec++) { -	    pIRec->value = (count * 65535) / max_index; -	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount) -		    / (XcmsFloat)65535.0; -	} -	break; -      case 32: -	for (count = 0; count < max_index+1; count++, pIRec++) { -	    pIRec->value = (count * 65535) / max_index; -	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount) -		    / (XcmsFloat)4294967295.0; -	} -	break; -      default: -	return(XcmsFailure); -    } - -    return(XcmsSuccess); -} - - -/* - *	NAME - *		ValueCmp - * - *	SYNOPSIS - */ -static int -_XcmsValueCmp( -    IntensityRec *p1, IntensityRec *p2) -/* - *	DESCRIPTION - *		Compares the value component of two IntensityRec - *		structures. - * - *	RETURNS - *		0 if p1->value is equal to p2->value - *		< 0 if p1->value is less than p2->value - *		> 0 if p1->value is greater than p2->value - * - */ -{ -    return (p1->value - p2->value); -} - - -/* - *	NAME - *		IntensityCmp - * - *	SYNOPSIS - */ -static int -_XcmsIntensityCmp( -    IntensityRec *p1, IntensityRec *p2) -/* - *	DESCRIPTION - *		Compares the intensity component of two IntensityRec - *		structures. - * - *	RETURNS - *		0 if equal; - *		< 0 if first precedes second - *		> 0 if first succeeds second - * - */ -{ -    if (p1->intensity < p2->intensity) { -	return (-1); -    } -    if (p1->intensity > p2->intensity) { -	return (XcmsSuccess); -    } -    return (XcmsFailure); -} - -/* - *	NAME - *		ValueInterpolation - * - *	SYNOPSIS - */ -/* ARGSUSED */ -static int -_XcmsValueInterpolation( -    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, -    int bitsPerRGB) -/* - *	DESCRIPTION - *		Based on a given value, performs a linear interpolation - *		on the intensities between two IntensityRec structures. - *		Note that the bitsPerRGB parameter is ignored. - * - *	RETURNS - *		Returns 0 if failed; otherwise non-zero. - */ -{ -    XcmsFloat ratio; - -    ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / -	((XcmsFloat)hi->value - (XcmsFloat)lo->value); -    answer->value = key->value; -    answer->intensity = (hi->intensity - lo->intensity) * ratio; -    answer->intensity += lo->intensity; -    return (XcmsSuccess); -} - -/* - *	NAME - *		IntensityInterpolation - * - *	SYNOPSIS - */ -static int -_XcmsIntensityInterpolation( -    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, -    int bitsPerRGB) -/* - *	DESCRIPTION - *		Based on a given intensity, performs a linear interpolation - *		on the values between two IntensityRec structures. - *		The bitsPerRGB parameter is necessary to perform rounding - *		to the correct number of significant bits. - * - *	RETURNS - *		Returns 0 if failed; otherwise non-zero. - */ -{ -    XcmsFloat ratio; -    long target, up, down; -    int shift = 16 - bitsPerRGB; -    int max_color = (1 << bitsPerRGB) - 1; - -    ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); -    answer->intensity = key->intensity; -    target = hi->value - lo->value; -    target *= ratio; -    target += lo->value; - -    /* -     * Ok now, lets find the closest in respects to bits per RGB -     */ -    up = ((target >> shift) * 0xFFFF) / max_color; -    if (up < target) { -	down = up; -	up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; -    } else { -	down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; -    } -    answer->value = ((up - target) < (target - down) ? up : down); -    answer->value &= MASK[bitsPerRGB]; -    return (XcmsSuccess); -} - - - -typedef int (*comparProcp)( -    char *p1, -    char *p2); -typedef int (*interpolProcp)( -    char *key, -    char *lo, -    char *hi, -    char *answer, -    int bitsPerRGB); - -/* - *	NAME - *		_XcmsTableSearch - * - *	SYNOPSIS - */ -static int -_XcmsTableSearch( -    char *key, -    int bitsPerRGB, -    char *base, -    unsigned nel, -    unsigned nKeyPtrSize, -    int (*compar)( -        char *p1, -        char *p2), -    int (*interpol)( -        char *key, -        char *lo, -        char *hi, -        char *answer, -        int bitsPerRGB), -    char *answer) - -/* - *	DESCRIPTION - *		A binary search through the specificied table. - * - *	RETURNS - *		Returns 0 if failed; otherwise non-zero. - * - */ -{ -    char *hi, *lo, *mid, *last; -    int result; - -    last = hi = base + ((nel - 1) * nKeyPtrSize); -    mid = lo = base; - -    /* use only the significants bits, then scale into 16 bits */ -    ((IntensityRec *)key)->value = ((unsigned long) -	    (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) -	    / ((1 << bitsPerRGB) - 1); - -    /* Special case so that zero intensity always maps to zero value */ -    if ((*compar) (key,lo) <= 0) { -	memcpy (answer, lo, nKeyPtrSize); -	((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; -	return XcmsSuccess; -    } -    while (mid != last) { -	last = mid; -	mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; -	result = (*compar) (key, mid); -	if (result == 0) { - -	    memcpy(answer, mid, nKeyPtrSize); -	    ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; -	    return (XcmsSuccess); -	} else if (result < 0) { -	    hi = mid; -	} else { -	    lo = mid; -	} -    } - -    /* -     * If we got to here, we didn't find a solution, so we -     * need to apply interpolation. -     */ -    return ((*interpol)(key, lo, hi, answer, bitsPerRGB)); -} - - -/* - *      NAME - *		_XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector - * - *	SYNOPSIS - */ -static void _XcmsMatVec( -    XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut) -/* - *      DESCRIPTION - *		Multiply the passed vector by the passed matrix to return a - *		vector. Matrix is 3x3, vectors are of length 3. - * - *	RETURNS - *		void - */ -{ -    int i, j; - -    for (i = 0; i < 3; i++) { -	pOut[i] = 0.0; -	for (j = 0; j < 3; j++) -	    pOut[i] += *(pMat+(i*3)+j) * pIn[j]; -    } -} - - -/************************************************************************ - *									* - *			 PUBLIC ROUTINES				* - *									* - ************************************************************************/ - - -/* - *	NAME - *		XcmsLRGB_RGB_ParseString - * - *	SYNOPSIS - */ -static int -XcmsLRGB_RGB_ParseString( -    register char *spec, -    XcmsColor *pColor) -/* - *	DESCRIPTION - *		This routines takes a string and attempts to convert - *		it into a XcmsColor structure with XcmsRGBFormat. - * - *	RETURNS - *		0 if failed, non-zero otherwise. - */ -{ -    register int n, i; -    unsigned short r, g, b; -    char c; -    char *pchar; -    unsigned short *pShort; - -    /* -     * Check for old # format -     */ -    if (*spec == '#') { -	/* -	 * Attempt to parse the value portion. -	 */ -	spec++; -	n = strlen(spec); -	if (n != 3 && n != 6 && n != 9 && n != 12) { -	    return(XcmsFailure); -	} - -	n /= 3; -	g = b = 0; -	do { -	    r = g; -	    g = b; -	    b = 0; -	    for (i = n; --i >= 0; ) { -		c = *spec++; -		b <<= 4; -		if (c >= '0' && c <= '9') -		    b |= c - '0'; -		/* assume string in lowercase -		else if (c >= 'A' && c <= 'F') -		    b |= c - ('A' - 10); -		*/ -		else if (c >= 'a' && c <= 'f') -		    b |= c - ('a' - 10); -		else return (XcmsFailure); -	    } -	} while (*spec != '\0'); - -	/* -	 * Succeeded ! -	 */ -	n <<= 2; -	n = 16 - n; -	/* shift instead of scale, to match old broken semantics */ -	pColor->spec.RGB.red = r << n; -	pColor->spec.RGB.green = g << n; -	pColor->spec.RGB.blue =  b << n; -    } else { -	if ((pchar = strchr(spec, ':')) == NULL) { -	    return(XcmsFailure); -	} -	n = (int)(pchar - spec); - -	/* -	 * Check for proper prefix. -	 */ -	if (strncmp(spec, _XcmsRGB_prefix, n) != 0) { -	    return(XcmsFailure); -	} - -	/* -	 * Attempt to parse the value portion. -	 */ -	spec += (n + 1); -	pShort = &pColor->spec.RGB.red; -	for (i = 0; i < 3; i++, pShort++, spec++) { -	    n = 0; -	    *pShort = 0; -	    while (*spec != '/' && *spec != '\0') { -		if (++n > 4) { -		    return(XcmsFailure); -		} -		c = *spec++; -		*pShort <<= 4; -		if (c >= '0' && c <= '9') -		    *pShort |= c - '0'; -		/* assume string in lowercase -		else if (c >= 'A' && c <= 'F') -		    *pShort |= c - ('A' - 10); -		*/ -		else if (c >= 'a' && c <= 'f') -		    *pShort |= c - ('a' - 10); -		else return (XcmsFailure); -	    } -	    if (n == 0) -		return (XcmsFailure); -	    if (n < 4) { -		*pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); -	    } -	} -    } -    pColor->format = XcmsRGBFormat; -    pColor->pixel = 0; -    return (XcmsSuccess); -} - - -/* - *	NAME - *		XcmsLRGB_RGBi_ParseString - * - *	SYNOPSIS - */ -static int -XcmsLRGB_RGBi_ParseString( -    register char *spec, -    XcmsColor *pColor) -/* - *	DESCRIPTION - *		This routines takes a string and attempts to convert - *		it into a XcmsColor structure with XcmsRGBiFormat. - *		The assumed RGBi string syntax is: - *		    RGBi:<r>/<g>/<b> - *		Where r, g, and b are in string input format for floats - *		consisting of: - *		    a. an optional sign - *		    b. a string of numbers possibly containing a decimal point, - *		    c. an optional exponent field containing an 'E' or 'e' - *			followed by a possibly signed integer string. - * - *	RETURNS - *		0 if failed, non-zero otherwise. - */ -{ -    int n; -    char *pchar; - -    if ((pchar = strchr(spec, ':')) == NULL) { -	return(XcmsFailure); -    } -    n = (int)(pchar - spec); - -    /* -     * Check for proper prefix. -     */ -    if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) { -	return(XcmsFailure); -    } - -    /* -     * Attempt to parse the value portion. -     */ -    if (sscanf(spec + n + 1, "%lf/%lf/%lf", -	    &pColor->spec.RGBi.red, -	    &pColor->spec.RGBi.green, -	    &pColor->spec.RGBi.blue) != 3) { -        char *s; /* Maybe failed due to locale */ -        int f; -        if ((s = strdup(spec))) { -            for (f = 0; s[f]; ++f) -                if (s[f] == '.') -                    s[f] = ','; -                else if (s[f] == ',') -                    s[f] = '.'; -	    if (sscanf(s + n + 1, "%lf/%lf/%lf", -		       &pColor->spec.RGBi.red, -		       &pColor->spec.RGBi.green, -		       &pColor->spec.RGBi.blue) != 3) { -                free(s); -                return(XcmsFailure); -            } -            free(s); -        } else -	    return(XcmsFailure); -    } - -    /* -     * Succeeded ! -     */ -    pColor->format = XcmsRGBiFormat; -    pColor->pixel = 0; -    return (XcmsSuccess); -} - - -/* - *	NAME - *		XcmsCIEXYZToRGBi - convert CIE XYZ to RGB - * - *	SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsCIEXYZToRGBi( -    XcmsCCC ccc, -    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/ -    unsigned int nColors,	/* Number of colors			*/ -    Bool *pCompressed)		/* pointer to an array of Bool		*/ -/* - *	DESCRIPTION - *		Converts color specifications in an array of XcmsColor - *		structures from RGB format to RGBi format. - * - *	RETURNS - *		XcmsFailure if failed, - *		XcmsSuccess if succeeded without gamut compression. - *		XcmsSuccessWithCompression if succeeded with gamut - *			compression. - */ -{ -    LINEAR_RGB_SCCData *pScreenData; -    XcmsFloat tmp[3]; -    int hasCompressed = 0; -    unsigned int i; -    XcmsColor *pColor = pXcmsColors_in_out; - -    if (ccc == NULL) { -	return(XcmsFailure); -    } - -    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - -    /* -     * XcmsColors should be White Point Adjusted, if necessary, by now! -     */ - -    /* -     * NEW!!! for extended gamut compression -     * -     * 1. Need to zero out pCompressed -     * -     * 2. Need to save initial address of pColor -     * -     * 3. Need to save initial address of pCompressed -     */ - -    for (i = 0; i < nColors; i++) { - -	/* Make sure format is XcmsCIEXYZFormat */ -	if (pColor->format != XcmsCIEXYZFormat) { -	    return(XcmsFailure); -	} - -	/* Multiply [A]-1 * [XYZ] to get RGB intensity */ -	_XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, -		(XcmsFloat *) &pColor->spec, tmp); - -	if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || -	    (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { - -	    /* -	     * RGBi out of screen's gamut -	     */ - -	    if (ccc->gamutCompProc == NULL) { -		/* -		 * Aha!! Here's that little trick that will allow -		 * gamut compression routines to get the out of bound -		 * RGBi. -		 */ -		memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); -		pColor->format = XcmsRGBiFormat; -		return(XcmsFailure); -	    } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors, -		    i, pCompressed) == 0) { -		return(XcmsFailure); -	    } - -	    /* -	     * The gamut compression function should return colors in CIEXYZ -	     *	Also check again to if the new color is within gamut. -	     */ -	    if (pColor->format != XcmsCIEXYZFormat) { -		return(XcmsFailure); -	    } -	    _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, -		    (XcmsFloat *) &pColor->spec, tmp); -	    if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || -		(MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { -		return(XcmsFailure); -	    } -	    hasCompressed++; -	} -	memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); -	/* These if statements are done to ensure the fudge factor is */ -	/* is taken into account. */ -	if (pColor->spec.RGBi.red < 0.0) { -		pColor->spec.RGBi.red = 0.0; -	} else if (pColor->spec.RGBi.red > 1.0) { -		pColor->spec.RGBi.red = 1.0; -	} -	if (pColor->spec.RGBi.green < 0.0) { -		pColor->spec.RGBi.green = 0.0; -	} else if (pColor->spec.RGBi.green > 1.0) { -		pColor->spec.RGBi.green = 1.0; -	} -	if (pColor->spec.RGBi.blue < 0.0) { -		pColor->spec.RGBi.blue = 0.0; -	} else if (pColor->spec.RGBi.blue > 1.0) { -		pColor->spec.RGBi.blue = 1.0; -	} -	(pColor++)->format = XcmsRGBiFormat; -    } -    return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); -} - - -/* - *	NAME - *		LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ - * - *	SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToCIEXYZ( -    XcmsCCC ccc, -    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/ -    unsigned int nColors,	/* Number of colors			*/ -    Bool *pCompressed)		/* pointer to a bit array		*/ -/* - *	DESCRIPTION - *		Converts color specifications in an array of XcmsColor - *		structures from RGBi format to CIEXYZ format. - * - *	RETURNS - *		XcmsFailure if failed, - *		XcmsSuccess if succeeded. - */ -{ -    LINEAR_RGB_SCCData *pScreenData; -    XcmsFloat tmp[3]; - -    /* -     * pCompressed ignored in this function. -     */ - -    if (ccc == NULL) { -	return(XcmsFailure); -    } - -    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - -    /* -     * XcmsColors should be White Point Adjusted, if necessary, by now! -     */ - -    while (nColors--) { - -	/* Multiply [A]-1 * [XYZ] to get RGB intensity */ -	_XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix, -		(XcmsFloat *) &pXcmsColors_in_out->spec, tmp); - -	memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp)); -	(pXcmsColors_in_out++)->format = XcmsCIEXYZFormat; -    } -    return(XcmsSuccess); -} - - -/* - *	NAME - *		XcmsRGBiToRGB - * - *	SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToRGB( -    XcmsCCC ccc, -    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/ -    unsigned int nColors,	/* Number of colors			*/ -    Bool *pCompressed)		/* pointer to a bit array		*/ -/* - *	DESCRIPTION - *		Converts color specifications in an array of XcmsColor - *		structures from RGBi format to RGB format. - * - *	RETURNS - *		XcmsFailure if failed, - *		XcmsSuccess if succeeded without gamut compression. - *		XcmsSuccessWithCompression if succeeded with gamut - *			compression. - */ -{ -    LINEAR_RGB_SCCData *pScreenData; -    XcmsRGB tmpRGB; -    IntensityRec keyIRec, answerIRec; - -    /* -     * pCompressed ignored in this function. -     */ - -    if (ccc == NULL) { -	return(XcmsFailure); -    } - -    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - -    while (nColors--) { - -	/* Make sure format is XcmsRGBiFormat */ -	if (pXcmsColors_in_out->format != XcmsRGBiFormat) { -	    return(XcmsFailure); -	} - -	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pRedTbl->pBase, -		(unsigned)pScreenData->pRedTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGB.red = answerIRec.value; - -	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pGreenTbl->pBase, -		(unsigned)pScreenData->pGreenTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGB.green = answerIRec.value; - -	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pBlueTbl->pBase, -		(unsigned)pScreenData->pBlueTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGB.blue = answerIRec.value; - -	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB)); -	(pXcmsColors_in_out++)->format = XcmsRGBFormat; -    } -    return(XcmsSuccess); -} - - -/* - *	NAME - *		XcmsRGBToRGBi - * - *	SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBToRGBi( -    XcmsCCC ccc, -    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/ -    unsigned int nColors,	/* Number of colors			*/ -    Bool *pCompressed)		/* pointer to a bit array		*/ -/* - *	DESCRIPTION - *		Converts color specifications in an array of XcmsColor - *		structures from RGB format to RGBi format. - * - *	RETURNS - *		XcmsFailure if failed, - *		XcmsSuccess if succeeded. - */ -{ -    LINEAR_RGB_SCCData *pScreenData; -    XcmsRGBi tmpRGBi; -    IntensityRec keyIRec, answerIRec; - -    /* -     * pCompressed ignored in this function. -     */ - -    if (ccc == NULL) { -	return(XcmsFailure); -    } - -    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - -    while (nColors--) { - -	/* Make sure format is XcmsRGBFormat */ -	if (pXcmsColors_in_out->format != XcmsRGBFormat) { -	    return(XcmsFailure); -	} - -	keyIRec.value = pXcmsColors_in_out->spec.RGB.red; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pRedTbl->pBase, -		(unsigned)pScreenData->pRedTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGBi.red = answerIRec.intensity; - -	keyIRec.value = pXcmsColors_in_out->spec.RGB.green; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pGreenTbl->pBase, -		(unsigned)pScreenData->pGreenTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGBi.green = answerIRec.intensity; - -	keyIRec.value = pXcmsColors_in_out->spec.RGB.blue; -	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, -		(char *)pScreenData->pBlueTbl->pBase, -		(unsigned)pScreenData->pBlueTbl->nEntries, -		(unsigned)sizeof(IntensityRec), -		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { -	    return(XcmsFailure); -	} -	tmpRGBi.blue = answerIRec.intensity; - -	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi)); -	(pXcmsColors_in_out++)->format = XcmsRGBiFormat; -    } -    return(XcmsSuccess); -} - -/* - *	NAME - *		_XcmsInitScrnDefaultInfo - * - *	SYNOPSIS - */ -/* ARGSUSED */ -int -_XcmsLRGB_InitScrnDefault( -    Display *dpy, -    int screenNumber, -    XcmsPerScrnInfo *pPerScrnInfo) -/* - *	DESCRIPTION - *		Given a display and screen number, this routine attempts - *		to initialize the Xcms per Screen Info structure - *		(XcmsPerScrnInfo) with defaults. - * - *	RETURNS - *		Returns zero if initialization failed; non-zero otherwise. - */ -{ -    pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData; -    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = -		Default_RGB_SCCData.RGBtoXYZmatrix[0][0] + -		Default_RGB_SCCData.RGBtoXYZmatrix[0][1] + -		Default_RGB_SCCData.RGBtoXYZmatrix[0][2]; -    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = -		Default_RGB_SCCData.RGBtoXYZmatrix[1][0] + -		Default_RGB_SCCData.RGBtoXYZmatrix[1][1] + -		Default_RGB_SCCData.RGBtoXYZmatrix[1][2]; -    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = -		Default_RGB_SCCData.RGBtoXYZmatrix[2][0] + -		Default_RGB_SCCData.RGBtoXYZmatrix[2][1] + -		Default_RGB_SCCData.RGBtoXYZmatrix[2][2]; -    if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) -	    || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { -	pPerScrnInfo->screenData = (XPointer)NULL; -	pPerScrnInfo->state = XcmsInitNone; -	return(0); -    } -    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; -    pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; -    pPerScrnInfo->screenWhitePt.pixel = 0; -    pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet; -    pPerScrnInfo->state = XcmsInitFailure; /* default initialization */ -    return(1); -} +
 +/*
 + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
 + * 	All Rights Reserved
 + *
 + * This file is a component of an X Window System-specific implementation
 + * of Xcms based on the TekColor Color Management System.  Permission is
 + * hereby granted to use, copy, modify, sell, and otherwise distribute this
 + * software and its documentation for any purpose and without fee, provided
 + * that this copyright, permission, and disclaimer notice is reproduced in
 + * all copies of this software and in supporting documentation.  TekColor
 + * is a trademark of Tektronix, Inc.
 + *
 + * Tektronix makes no representation about the suitability of this software
 + * for any purpose.  It is provided "as is" and with all faults.
 + *
 + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
 + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 + * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 + * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
 + * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 + * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
 + *
 + *
 + *	NAME
 + *		XcmsLRGB.c
 + *
 + *	DESCRIPTION
 + *		This file contains the conversion routines:
 + *		    1. CIE XYZ to RGB intensity
 + *		    2. RGB intensity to device RGB
 + *		    3. device RGB to RGB intensity
 + *		    4. RGB intensity to CIE XYZ
 + *
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include <config.h>
 +#endif
 +#include <stdio.h>
 +#include <X11/Xos.h>
 +#include <X11/Xatom.h>
 +#include "Xlibint.h"
 +#include "Xcmsint.h"
 +#include "Cv.h"
 +
 +/*
 + *      LOCAL DEFINES
 + *		#define declarations local to this package.
 + */
 +#define EPS	0.001
 +#ifndef MIN
 +#define MIN(x,y) ((x) > (y) ? (y) : (x))
 +#endif /* MIN */
 +#ifndef MAX
 +#define MAX(x,y) ((x) > (y) ? (x) : (y))
 +#endif /* MAX */
 +#ifndef MIN3
 +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x))
 +#endif /* MIN3 */
 +#ifndef MAX3
 +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z))))
 +#endif /* MAX3 */
 +
 +/*
 + *      LOCAL TYPEDEFS
 + *              typedefs local to this package (for use with local vars).
 + *
 + */
 +
 +/*
 + *      FORWARD DECLARATIONS
 + */
 +static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp);
 +static int LINEAR_RGB_InitSCCData(Display *dpy,
 +    int screenNumber, XcmsPerScrnInfo *pPerScrnInfo);
 +static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor);
 +static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor);
 +static Status
 +_XcmsGetTableType0(
 +    IntensityTbl *pTbl,
 +    int	  format,
 +    char **pChar,
 +    unsigned long *pCount);
 +static Status
 +_XcmsGetTableType1(
 +    IntensityTbl *pTbl,
 +    int	  format,
 +    char **pChar,
 +    unsigned long *pCount);
 +
 +/*
 + *      LOCALS VARIABLES
 + *		Variables local to this package.
 + *		    Usage example:
 + *		        static int	ExampleLocalVar;
 + */
 +
 +static unsigned short const MASK[17] = {
 +    0x0000,	/*  0 bitsPerRGB */
 +    0x8000,	/*  1 bitsPerRGB */
 +    0xc000,	/*  2 bitsPerRGB */
 +    0xe000,	/*  3 bitsPerRGB */
 +    0xf000,	/*  4 bitsPerRGB */
 +    0xf800,	/*  5 bitsPerRGB */
 +    0xfc00,	/*  6 bitsPerRGB */
 +    0xfe00,	/*  7 bitsPerRGB */
 +    0xff00,	/*  8 bitsPerRGB */
 +    0xff80,	/*  9 bitsPerRGB */
 +    0xffc0,	/* 10 bitsPerRGB */
 +    0xffe0,	/* 11 bitsPerRGB */
 +    0xfff0,	/* 12 bitsPerRGB */
 +    0xfff8,	/* 13 bitsPerRGB */
 +    0xfffc,	/* 14 bitsPerRGB */
 +    0xfffe,	/* 15 bitsPerRGB */
 +    0xffff	/* 16 bitsPerRGB */
 +};
 +
 +
 +    /*
 +     * A NULL terminated array of function pointers that when applied
 +     * in series will convert an XcmsColor structure from XcmsRGBFormat
 +     * to XcmsCIEXYZFormat.
 +     */
 +static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
 +    (XcmsConversionProc)XcmsRGBToRGBi,
 +    (XcmsConversionProc)XcmsRGBiToCIEXYZ,
 +    NULL
 +};
 +
 +    /*
 +     * A NULL terminated array of function pointers that when applied
 +     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
 +     * to XcmsRGBFormat.
 +     */
 +static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
 +    (XcmsConversionProc)XcmsCIEXYZToRGBi,
 +    (XcmsConversionProc)XcmsRGBiToRGB,
 +    NULL
 +};
 +
 +    /*
 +     * A NULL terminated array of function pointers that when applied
 +     * in series will convert an XcmsColor structure from XcmsRGBiFormat
 +     * to XcmsCIEXYZFormat.
 +     */
 +static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
 +    (XcmsConversionProc)XcmsRGBiToCIEXYZ,
 +    NULL
 +};
 +
 +    /*
 +     * A NULL terminated array of function pointers that when applied
 +     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
 +     * to XcmsRGBiFormat.
 +     */
 +static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
 +    (XcmsConversionProc)XcmsCIEXYZToRGBi,
 +    NULL
 +};
 +
 +    /*
 +     * RGBi Color Spaces
 +     */
 +XcmsColorSpace	XcmsRGBiColorSpace =
 +    {
 +	_XcmsRGBi_prefix,	/* prefix */
 +	XcmsRGBiFormat,		/* id */
 +	XcmsLRGB_RGBi_ParseString,	/* parseString */
 +	Fl_RGBi_to_CIEXYZ,	/* to_CIEXYZ */
 +	Fl_CIEXYZ_to_RGBi,	/* from_CIEXYZ */
 +	1
 +    };
 +
 +    /*
 +     * RGB Color Spaces
 +     */
 +XcmsColorSpace	XcmsRGBColorSpace =
 +    {
 +	_XcmsRGB_prefix,		/* prefix */
 +	XcmsRGBFormat,		/* id */
 +	XcmsLRGB_RGB_ParseString,	/* parseString */
 +	Fl_RGB_to_CIEXYZ,	/* to_CIEXYZ */
 +	Fl_CIEXYZ_to_RGB,	/* from_CIEXYZ */
 +	1
 +    };
 +
 +    /*
 +     * Device-Independent Color Spaces known to the
 +     * LINEAR_RGB Screen Color Characteristics Function Set.
 +     */
 +static XcmsColorSpace	*DDColorSpaces[] = {
 +    &XcmsRGBColorSpace,
 +    &XcmsRGBiColorSpace,
 +    NULL
 +};
 +
 +
 +/*
 + *      GLOBALS
 + *              Variables declared in this package that are allowed
 + *		to be used globally.
 + */
 +
 +    /*
 +     * LINEAR_RGB Screen Color Characteristics Function Set.
 +     */
 +XcmsFunctionSet	XcmsLinearRGBFunctionSet =
 +    {
 +	&DDColorSpaces[0],	/* pDDColorSpaces */
 +	LINEAR_RGB_InitSCCData,	/* pInitScrnFunc */
 +	LINEAR_RGB_FreeSCCData	/* pFreeSCCData */
 +    };
 +
 +/*
 + *	DESCRIPTION
 + *		Contents of Default SCCData should be replaced if other
 + *		data should be used as default.
 + *
 + *
 + */
 +
 +/*
 + * NAME		Tektronix 19" (Sony) CRT
 + * PART_NUMBER		119-2451-00
 + * MODEL		Tek4300, Tek4800
 + */
 +
 +static IntensityRec const Default_RGB_RedTuples[] = {
 +    /* {unsigned short value, XcmsFloat intensity} */
 +            { 0x0000,    0.000000 },
 +            { 0x0909,    0.000000 },
 +            { 0x0a0a,    0.000936 },
 +            { 0x0f0f,    0.001481 },
 +            { 0x1414,    0.002329 },
 +            { 0x1919,    0.003529 },
 +            { 0x1e1e,    0.005127 },
 +            { 0x2323,    0.007169 },
 +            { 0x2828,    0.009699 },
 +            { 0x2d2d,    0.012759 },
 +            { 0x3232,    0.016392 },
 +            { 0x3737,    0.020637 },
 +            { 0x3c3c,    0.025533 },
 +            { 0x4141,    0.031119 },
 +            { 0x4646,    0.037431 },
 +            { 0x4b4b,    0.044504 },
 +            { 0x5050,    0.052373 },
 +            { 0x5555,    0.061069 },
 +            { 0x5a5a,    0.070624 },
 +            { 0x5f5f,    0.081070 },
 +            { 0x6464,    0.092433 },
 +            { 0x6969,    0.104744 },
 +            { 0x6e6e,    0.118026 },
 +            { 0x7373,    0.132307 },
 +            { 0x7878,    0.147610 },
 +            { 0x7d7d,    0.163958 },
 +            { 0x8282,    0.181371 },
 +            { 0x8787,    0.199871 },
 +            { 0x8c8c,    0.219475 },
 +            { 0x9191,    0.240202 },
 +            { 0x9696,    0.262069 },
 +            { 0x9b9b,    0.285089 },
 +            { 0xa0a0,    0.309278 },
 +            { 0xa5a5,    0.334647 },
 +            { 0xaaaa,    0.361208 },
 +            { 0xafaf,    0.388971 },
 +            { 0xb4b4,    0.417945 },
 +            { 0xb9b9,    0.448138 },
 +            { 0xbebe,    0.479555 },
 +            { 0xc3c3,    0.512202 },
 +            { 0xc8c8,    0.546082 },
 +            { 0xcdcd,    0.581199 },
 +            { 0xd2d2,    0.617552 },
 +            { 0xd7d7,    0.655144 },
 +            { 0xdcdc,    0.693971 },
 +            { 0xe1e1,    0.734031 },
 +            { 0xe6e6,    0.775322 },
 +            { 0xebeb,    0.817837 },
 +            { 0xf0f0,    0.861571 },
 +            { 0xf5f5,    0.906515 },
 +            { 0xfafa,    0.952662 },
 +            { 0xffff,    1.000000 }
 +};
 +
 +static IntensityRec const Default_RGB_GreenTuples[] = {
 +    /* {unsigned short value, XcmsFloat intensity} */
 +            { 0x0000,    0.000000 },
 +            { 0x1313,    0.000000 },
 +            { 0x1414,    0.000832 },
 +            { 0x1919,    0.001998 },
 +            { 0x1e1e,    0.003612 },
 +            { 0x2323,    0.005736 },
 +            { 0x2828,    0.008428 },
 +            { 0x2d2d,    0.011745 },
 +            { 0x3232,    0.015740 },
 +            { 0x3737,    0.020463 },
 +            { 0x3c3c,    0.025960 },
 +            { 0x4141,    0.032275 },
 +            { 0x4646,    0.039449 },
 +            { 0x4b4b,    0.047519 },
 +            { 0x5050,    0.056520 },
 +            { 0x5555,    0.066484 },
 +            { 0x5a5a,    0.077439 },
 +            { 0x5f5f,    0.089409 },
 +            { 0x6464,    0.102418 },
 +            { 0x6969,    0.116485 },
 +            { 0x6e6e,    0.131625 },
 +            { 0x7373,    0.147853 },
 +            { 0x7878,    0.165176 },
 +            { 0x7d7d,    0.183604 },
 +            { 0x8282,    0.203140 },
 +            { 0x8787,    0.223783 },
 +            { 0x8c8c,    0.245533 },
 +            { 0x9191,    0.268384 },
 +            { 0x9696,    0.292327 },
 +            { 0x9b9b,    0.317351 },
 +            { 0xa0a0,    0.343441 },
 +            { 0xa5a5,    0.370580 },
 +            { 0xaaaa,    0.398747 },
 +            { 0xafaf,    0.427919 },
 +            { 0xb4b4,    0.458068 },
 +            { 0xb9b9,    0.489165 },
 +            { 0xbebe,    0.521176 },
 +            { 0xc3c3,    0.554067 },
 +            { 0xc8c8,    0.587797 },
 +            { 0xcdcd,    0.622324 },
 +            { 0xd2d2,    0.657604 },
 +            { 0xd7d7,    0.693588 },
 +            { 0xdcdc,    0.730225 },
 +            { 0xe1e1,    0.767459 },
 +            { 0xe6e6,    0.805235 },
 +            { 0xebeb,    0.843491 },
 +            { 0xf0f0,    0.882164 },
 +            { 0xf5f5,    0.921187 },
 +            { 0xfafa,    0.960490 },
 +            { 0xffff,    1.000000 }
 +};
 +
 +static IntensityRec const Default_RGB_BlueTuples[] = {
 +    /* {unsigned short value, XcmsFloat intensity} */
 +            { 0x0000,    0.000000 },
 +            { 0x0e0e,    0.000000 },
 +            { 0x0f0f,    0.001341 },
 +            { 0x1414,    0.002080 },
 +            { 0x1919,    0.003188 },
 +            { 0x1e1e,    0.004729 },
 +            { 0x2323,    0.006766 },
 +            { 0x2828,    0.009357 },
 +            { 0x2d2d,    0.012559 },
 +            { 0x3232,    0.016424 },
 +            { 0x3737,    0.021004 },
 +            { 0x3c3c,    0.026344 },
 +            { 0x4141,    0.032489 },
 +            { 0x4646,    0.039481 },
 +            { 0x4b4b,    0.047357 },
 +            { 0x5050,    0.056154 },
 +            { 0x5555,    0.065903 },
 +            { 0x5a5a,    0.076634 },
 +            { 0x5f5f,    0.088373 },
 +            { 0x6464,    0.101145 },
 +            { 0x6969,    0.114968 },
 +            { 0x6e6e,    0.129862 },
 +            { 0x7373,    0.145841 },
 +            { 0x7878,    0.162915 },
 +            { 0x7d7d,    0.181095 },
 +            { 0x8282,    0.200386 },
 +            { 0x8787,    0.220791 },
 +            { 0x8c8c,    0.242309 },
 +            { 0x9191,    0.264937 },
 +            { 0x9696,    0.288670 },
 +            { 0x9b9b,    0.313499 },
 +            { 0xa0a0,    0.339410 },
 +            { 0xa5a5,    0.366390 },
 +            { 0xaaaa,    0.394421 },
 +            { 0xafaf,    0.423481 },
 +            { 0xb4b4,    0.453547 },
 +            { 0xb9b9,    0.484592 },
 +            { 0xbebe,    0.516587 },
 +            { 0xc3c3,    0.549498 },
 +            { 0xc8c8,    0.583291 },
 +            { 0xcdcd,    0.617925 },
 +            { 0xd2d2,    0.653361 },
 +            { 0xd7d7,    0.689553 },
 +            { 0xdcdc,    0.726454 },
 +            { 0xe1e1,    0.764013 },
 +            { 0xe6e6,    0.802178 },
 +            { 0xebeb,    0.840891 },
 +            { 0xf0f0,    0.880093 },
 +            { 0xf5f5,    0.919723 },
 +            { 0xfafa,    0.959715 },
 +	    { 0xffff,    1.00000 }
 +};
 +
 +static IntensityTbl Default_RGB_RedTbl = {
 +    /* IntensityRec *pBase */
 +	(IntensityRec *) Default_RGB_RedTuples,
 +    /* unsigned int nEntries */
 +	52
 +};
 +
 +static IntensityTbl Default_RGB_GreenTbl = {
 +    /* IntensityRec *pBase */
 +	(IntensityRec *)Default_RGB_GreenTuples,
 +    /* unsigned int nEntries */
 +	50
 +};
 +
 +static IntensityTbl Default_RGB_BlueTbl = {
 +    /* IntensityRec *pBase */
 +	(IntensityRec *)Default_RGB_BlueTuples,
 +    /* unsigned int nEntries */
 +	51
 +};
 +
 +static LINEAR_RGB_SCCData Default_RGB_SCCData = {
 +    /* XcmsFloat XYZtoRGBmatrix[3][3] */
 +  {
 +    { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 },
 +    {-1.07152751306193600,  1.96593795204372400,  0.03673691339553462 },
 +    { 0.06351179790497788, -0.20020501000496480,  0.81070942031648220 }
 +  },
 +
 +    /* XcmsFloat RGBtoXYZmatrix[3][3] */
 +  {
 +    { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 },
 +    { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 },
 +    { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 }
 +  },
 +
 +    /* IntensityTbl *pRedTbl */
 +	&Default_RGB_RedTbl,
 +
 +    /* IntensityTbl *pGreenTbl */
 +	&Default_RGB_GreenTbl,
 +
 +    /* IntensityTbl *pBlueTbl */
 +	&Default_RGB_BlueTbl
 +};
 +
 +/************************************************************************
 + *									*
 + *			PRIVATE ROUTINES				*
 + *									*
 + ************************************************************************/
 +
 +/*
 + *	NAME
 + *		LINEAR_RGB_InitSCCData()
 + *
 + *	SYNOPSIS
 + */
 +static Status
 +LINEAR_RGB_InitSCCData(
 +    Display *dpy,
 +    int screenNumber,
 +    XcmsPerScrnInfo *pPerScrnInfo)
 +/*
 + *	DESCRIPTION
 + *
 + *	RETURNS
 + *		XcmsFailure if failed.
 + *		XcmsSuccess if succeeded.
 + *
 + */
 +{
 +    Atom  CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
 +    Atom  MatrixAtom  = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
 +    int	  format_return, count, cType, nTables;
 +    unsigned long nitems, nbytes_return;
 +    char *property_return, *pChar;
 +    XcmsFloat *pValue;
 +#ifdef ALLDEBUG
 +    IntensityRec *pIRec;
 +#endif /* ALLDEBUG */
 +    VisualID visualID;
 +
 +    LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
 +    XcmsIntensityMap *pNewMap;
 +
 +    /*
 +     * Allocate memory for pScreenData
 +     */
 +    if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *)
 +		      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
 +	return(XcmsFailure);
 +    }
 +
 +    /*
 +     *  1. Get the XYZ->RGB and RGB->XYZ matrices
 +     */
 +
 +    if (MatrixAtom == None ||
 +	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom,
 +	   &format_return, &nitems, &nbytes_return, &property_return) ||
 +	   nitems != 18 || format_return != 32) {
 +	/*
 +	 * As per the XDCCC, there must be 18 data items and each must be
 +	 * in 32 bits !
 +	 */
 +	goto FreeSCCData;
 +
 +    } else {
 +
 +	/*
 +	 * RGBtoXYZ and XYZtoRGB matrices
 +	 */
 +	pValue = (XcmsFloat *) pScreenData;
 +	pChar = property_return;
 +	for (count = 0; count < 18; count++) {
 +	    *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
 +		    &nitems) / (XcmsFloat)XDCCC_NUMBER;
 +	}
 +	Xfree ((char *)property_return);
 +	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
 +		pScreenData->RGBtoXYZmatrix[0][0] +
 +		pScreenData->RGBtoXYZmatrix[0][1] +
 +		pScreenData->RGBtoXYZmatrix[0][2];
 +	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
 +		pScreenData->RGBtoXYZmatrix[1][0] +
 +		pScreenData->RGBtoXYZmatrix[1][1] +
 +		pScreenData->RGBtoXYZmatrix[1][2];
 +	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
 +		pScreenData->RGBtoXYZmatrix[2][0] +
 +		pScreenData->RGBtoXYZmatrix[2][1] +
 +		pScreenData->RGBtoXYZmatrix[2][2];
 +
 +	/*
 +	 * Compute the Screen White Point
 +	 */
 +	if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
 +		|| (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
 +	    goto FreeSCCData;
 +	} else {
 +	    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
 +	}
 +	pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
 +	pPerScrnInfo->screenWhitePt.pixel = 0;
 +
 +#ifdef PDEBUG
 +	printf ("RGB to XYZ Matrix values:\n");
 +	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
 +		pScreenData->RGBtoXYZmatrix[0][0],
 +		pScreenData->RGBtoXYZmatrix[0][1],
 +		pScreenData->RGBtoXYZmatrix[0][2],
 +		pScreenData->RGBtoXYZmatrix[1][0],
 +		pScreenData->RGBtoXYZmatrix[1][1],
 +		pScreenData->RGBtoXYZmatrix[1][2],
 +		pScreenData->RGBtoXYZmatrix[2][0],
 +		pScreenData->RGBtoXYZmatrix[2][1],
 +		pScreenData->RGBtoXYZmatrix[2][2]);
 +	printf ("XYZ to RGB Matrix values:\n");
 +	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
 +		pScreenData->XYZtoRGBmatrix[0][0],
 +		pScreenData->XYZtoRGBmatrix[0][1],
 +		pScreenData->XYZtoRGBmatrix[0][2],
 +		pScreenData->XYZtoRGBmatrix[1][0],
 +		pScreenData->XYZtoRGBmatrix[1][1],
 +		pScreenData->XYZtoRGBmatrix[1][2],
 +		pScreenData->XYZtoRGBmatrix[2][0],
 +		pScreenData->XYZtoRGBmatrix[2][1],
 +		pScreenData->XYZtoRGBmatrix[2][2]);
 +	printf ("Screen White Pt value: %f %f %f\n",
 +		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
 +		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
 +		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
 +#endif /* PDEBUG */
 +    }
 +
 +    /*
 +     *	2. Get the Intensity Profile
 +     */
 +    if (CorrectAtom == None ||
 +	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
 +	   &format_return, &nitems, &nbytes_return, &property_return)) {
 +	goto FreeSCCData;
 +    }
 +
 +    pChar = property_return;
 +
 +    while (nitems) {
 +	switch (format_return) {
 +	  case 8:
 +	    /*
 +	     * Must have at least:
 +	     *		VisualID0
 +	     *		VisualID1
 +	     *		VisualID2
 +	     *		VisualID3
 +	     *		type
 +	     *		count
 +	     *		length
 +	     *		intensity1
 +	     *		intensity2
 +	     */
 +	    if (nitems < 9) {
 +		goto Free_property_return;
 +	    }
 +	    count = 3;
 +	    break;
 +	  case 16:
 +	    /*
 +	     * Must have at least:
 +	     *		VisualID0
 +	     *		VisualID3
 +	     *		type
 +	     *		count
 +	     *		length
 +	     *		intensity1
 +	     *		intensity2
 +	     */
 +	    if (nitems < 7) {
 +		goto Free_property_return;
 +	    }
 +	    count = 1;
 +	    break;
 +	  case 32:
 +	    /*
 +	     * Must have at least:
 +	     *		VisualID0
 +	     *		type
 +	     *		count
 +	     *		length
 +	     *		intensity1
 +	     *		intensity2
 +	     */
 +	    if (nitems < 6) {
 +		goto Free_property_return;
 +	    }
 +	    count = 0;
 +	    break;
 +	  default:
 +	    goto Free_property_return;
 +	}
 +
 +	/*
 +	 * Get VisualID
 +	 */
 +	visualID = _XcmsGetElement(format_return, &pChar, &nitems);
 +	while (count--) {
 +	    visualID = visualID << format_return;
 +	    visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
 +	}
 +
 +	if (visualID == 0) {
 +	    /*
 +	     * This is a shared intensity table
 +	     */
 +	    pScreenData = pScreenDefaultData;
 +	} else {
 +	    /*
 +	     * This is a per-Visual intensity table
 +	     */
 +	    if (!(pScreenData = (LINEAR_RGB_SCCData *)
 +			      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
 +		return(XcmsFailure);
 +	    }
 +	    /* copy matrices */
 +	    memcpy((char *)pScreenData, (char *)pScreenDefaultData,
 +		   18 * sizeof(XcmsFloat));
 +
 +	    /* Create, initialize, and add map */
 +	    if (!(pNewMap = (XcmsIntensityMap *)
 +			      Xcalloc (1, sizeof(XcmsIntensityMap)))) {
 +		Xfree((char *)pScreenData);
 +		return(XcmsFailure);
 +	    }
 +	    pNewMap->visualID = visualID;
 +	    pNewMap->screenData = (XPointer)pScreenData;
 +	    pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
 +	    pNewMap->pNext =
 +		    (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
 +	    dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
 +	    dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
 +	}
 +
 +	cType = _XcmsGetElement(format_return, &pChar, &nitems);
 +	nTables = _XcmsGetElement(format_return, &pChar, &nitems);
 +
 +	if (cType == 0) {
 +
 +	    /* Red Intensity Table */
 +	    if (!(pScreenData->pRedTbl = (IntensityTbl *)
 +		    Xcalloc (1, sizeof(IntensityTbl)))) {
 +		goto Free_property_return;
 +	    }
 +	    if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
 +		    &nitems) == XcmsFailure) {
 +		goto FreeRedTbl;
 +	    }
 +
 +	    if (nTables == 1) {
 +		/* Green Intensity Table */
 +		pScreenData->pGreenTbl = pScreenData->pRedTbl;
 +		/* Blue Intensity Table */
 +		pScreenData->pBlueTbl = pScreenData->pRedTbl;
 +	    } else {
 +		/* Green Intensity Table */
 +		if (!(pScreenData->pGreenTbl = (IntensityTbl *)
 +			Xcalloc (1, sizeof(IntensityTbl)))) {
 +		    goto FreeRedTblElements;
 +		}
 +		if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
 +			&nitems) == XcmsFailure) {
 +		    goto FreeGreenTbl;
 +		}
 +
 +		/* Blue Intensity Table */
 +		if (!(pScreenData->pBlueTbl = (IntensityTbl *)
 +			Xcalloc (1, sizeof(IntensityTbl)))) {
 +		    goto FreeGreenTblElements;
 +		}
 +		if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
 +			&nitems) == XcmsFailure) {
 +		    goto FreeBlueTbl;
 +		}
 +	    }
 +	} else if (cType == 1) {
 +	    /* Red Intensity Table */
 +	    if (!(pScreenData->pRedTbl = (IntensityTbl *)
 +		    Xcalloc (1, sizeof(IntensityTbl)))) {
 +		goto Free_property_return;
 +	    }
 +	    if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
 +		    &nitems) == XcmsFailure) {
 +		goto FreeRedTbl;
 +	    }
 +
 +	    if (nTables == 1) {
 +
 +		/* Green Intensity Table */
 +		pScreenData->pGreenTbl = pScreenData->pRedTbl;
 +		/* Blue Intensity Table */
 +		pScreenData->pBlueTbl = pScreenData->pRedTbl;
 +
 +	    } else {
 +
 +		/* Green Intensity Table */
 +		if (!(pScreenData->pGreenTbl = (IntensityTbl *)
 +			Xcalloc (1, sizeof(IntensityTbl)))) {
 +		    goto FreeRedTblElements;
 +		}
 +		if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
 +			&nitems) == XcmsFailure) {
 +		    goto FreeGreenTbl;
 +		}
 +
 +		/* Blue Intensity Table */
 +		if (!(pScreenData->pBlueTbl = (IntensityTbl *)
 +			Xcalloc (1, sizeof(IntensityTbl)))) {
 +		    goto FreeGreenTblElements;
 +		}
 +		if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
 +			&nitems) == XcmsFailure) {
 +		    goto FreeBlueTbl;
 +		}
 +	    }
 +	} else {
 +	    goto Free_property_return;
 +	}
 +
 +#ifdef ALLDEBUG
 +	printf ("Intensity Table  RED    %d\n", pScreenData->pRedTbl->nEntries);
 +	pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
 +	for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
 +	    printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
 +	}
 +	if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
 +	    printf ("Intensity Table  GREEN  %d\n", pScreenData->pGreenTbl->nEntries);
 +	    pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
 +	    for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
 +		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
 +	    }
 +	}
 +	if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
 +	    printf ("Intensity Table  BLUE   %d\n", pScreenData->pBlueTbl->nEntries);
 +	    pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
 +	    for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
 +		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
 +	    }
 +	}
 +#endif /* ALLDEBUG */
 +    }
 +
 +    Xfree ((char *)property_return);
 +
 +    /* Free the old memory and use the new structure created. */
 +    LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData);
 +
 +    pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
 +
 +    pPerScrnInfo->screenData = (XPointer) pScreenData;
 +
 +    pPerScrnInfo->state = XcmsInitSuccess;
 +
 +    return(XcmsSuccess);
 +
 +FreeBlueTblElements:
 +    Xfree((char *)pScreenData->pBlueTbl->pBase);
 +
 +FreeBlueTbl:
 +    Xfree((char *)pScreenData->pBlueTbl);
 +
 +FreeGreenTblElements:
 +    Xfree((char *)pScreenData->pBlueTbl->pBase);
 +
 +FreeGreenTbl:
 +    Xfree((char *)pScreenData->pGreenTbl);
 +
 +FreeRedTblElements:
 +    Xfree((char *)pScreenData->pRedTbl->pBase);
 +
 +FreeRedTbl:
 +    Xfree((char *)pScreenData->pRedTbl);
 +
 +Free_property_return:
 +    Xfree ((char *)property_return);
 +
 +FreeSCCData:
 +    Xfree((char *)pScreenData);
 +    pPerScrnInfo->state = XcmsInitNone;
 +    return(XcmsFailure);
 +}
 +
 +
 +/*
 + *	NAME
 + *		LINEAR_RGB_FreeSCCData()
 + *
 + *	SYNOPSIS
 + */
 +static void
 +LINEAR_RGB_FreeSCCData(
 +    XPointer pScreenDataTemp)
 +/*
 + *	DESCRIPTION
 + *
 + *	RETURNS
 + *		0 if failed.
 + *		1 if succeeded with no modifications.
 + *
 + */
 +{
 +    LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
 +
 +    if (pScreenData && pScreenData != &Default_RGB_SCCData) {
 +	if (pScreenData->pRedTbl) {
 +	    if (pScreenData->pGreenTbl) {
 +		if (pScreenData->pRedTbl->pBase !=
 +		    pScreenData->pGreenTbl->pBase) {
 +		    if (pScreenData->pGreenTbl->pBase) {
 +			Xfree ((char *)pScreenData->pGreenTbl->pBase);
 +		    }
 +		}
 +		if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
 +		    Xfree ((char *)pScreenData->pGreenTbl);
 +		}
 +	    }
 +	    if (pScreenData->pBlueTbl) {
 +		if (pScreenData->pRedTbl->pBase !=
 +		    pScreenData->pBlueTbl->pBase) {
 +		    if (pScreenData->pBlueTbl->pBase) {
 +			Xfree ((char *)pScreenData->pBlueTbl->pBase);
 +		    }
 +		}
 +		if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
 +		    Xfree ((char *)pScreenData->pBlueTbl);
 +		}
 +	    }
 +	    if (pScreenData->pRedTbl->pBase) {
 +		Xfree ((char *)pScreenData->pRedTbl->pBase);
 +	    }
 +	    Xfree ((char *)pScreenData->pRedTbl);
 +	}
 +	Xfree ((char *)pScreenData);
 +    }
 +}
 +
 +
 +
 +/************************************************************************
 + *									*
 + *			API PRIVATE ROUTINES				*
 + *									*
 + ************************************************************************/
 +
 +/*
 + *	NAME
 + *		_XcmsGetTableType0
 + *
 + *	SYNOPSIS
 + */
 +static Status
 +_XcmsGetTableType0(
 +    IntensityTbl *pTbl,
 +    int	  format,
 +    char **pChar,
 +    unsigned long *pCount)
 +/*
 + *	DESCRIPTION
 + *
 + *	RETURNS
 + *		XcmsFailure if failed.
 + *		XcmsSuccess if succeeded.
 + *
 + */
 +{
 +    unsigned int nElements;
 +    IntensityRec *pIRec;
 +
 +    nElements = pTbl->nEntries =
 +	    _XcmsGetElement(format, pChar, pCount) + 1;
 +    if (!(pIRec = pTbl->pBase = (IntensityRec *)
 +	  Xcalloc (nElements, sizeof(IntensityRec)))) {
 +	return(XcmsFailure);
 +    }
 +
 +    switch (format) {
 +      case 8:
 +	for (; nElements--; pIRec++) {
 +	    /* 0xFFFF/0xFF = 0x101 */
 +	    pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
 +	    pIRec->intensity =
 +		    _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
 +	}
 +	break;
 +      case 16:
 +	for (; nElements--; pIRec++) {
 +	    pIRec->value = _XcmsGetElement (format, pChar, pCount);
 +	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
 +		    / (XcmsFloat)65535.0;
 +	}
 +	break;
 +      case 32:
 +	for (; nElements--; pIRec++) {
 +	    pIRec->value = _XcmsGetElement (format, pChar, pCount);
 +	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
 +		    / (XcmsFloat)4294967295.0;
 +	}
 +	break;
 +      default:
 +	return(XcmsFailure);
 +    }
 +    return(XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		_XcmsGetTableType1
 + *
 + *	SYNOPSIS
 + */
 +static Status
 +_XcmsGetTableType1(
 +    IntensityTbl *pTbl,
 +    int	  format,
 +    char **pChar,
 +    unsigned long *pCount)
 +/*
 + *	DESCRIPTION
 + *
 + *	RETURNS
 + *		XcmsFailure if failed.
 + *		XcmsSuccess if succeeded.
 + *
 + */
 +{
 +    int count;
 +    unsigned int max_index;
 +    IntensityRec *pIRec;
 +
 +    max_index = _XcmsGetElement(format, pChar, pCount);
 +    pTbl->nEntries = max_index + 1;
 +    if (!(pIRec = pTbl->pBase = (IntensityRec *)
 +	  Xcalloc (max_index+1, sizeof(IntensityRec)))) {
 +	return(XcmsFailure);
 +    }
 +
 +    switch (format) {
 +      case 8:
 +	for (count = 0; count < max_index+1; count++, pIRec++) {
 +	    pIRec->value = (count * 65535) / max_index;
 +	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
 +		    / (XcmsFloat)255.0;
 +	}
 +	break;
 +      case 16:
 +	for (count = 0; count < max_index+1; count++, pIRec++) {
 +	    pIRec->value = (count * 65535) / max_index;
 +	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
 +		    / (XcmsFloat)65535.0;
 +	}
 +	break;
 +      case 32:
 +	for (count = 0; count < max_index+1; count++, pIRec++) {
 +	    pIRec->value = (count * 65535) / max_index;
 +	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
 +		    / (XcmsFloat)4294967295.0;
 +	}
 +	break;
 +      default:
 +	return(XcmsFailure);
 +    }
 +
 +    return(XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		ValueCmp
 + *
 + *	SYNOPSIS
 + */
 +static int
 +_XcmsValueCmp(
 +    IntensityRec *p1, IntensityRec *p2)
 +/*
 + *	DESCRIPTION
 + *		Compares the value component of two IntensityRec
 + *		structures.
 + *
 + *	RETURNS
 + *		0 if p1->value is equal to p2->value
 + *		< 0 if p1->value is less than p2->value
 + *		> 0 if p1->value is greater than p2->value
 + *
 + */
 +{
 +    return (p1->value - p2->value);
 +}
 +
 +
 +/*
 + *	NAME
 + *		IntensityCmp
 + *
 + *	SYNOPSIS
 + */
 +static int
 +_XcmsIntensityCmp(
 +    IntensityRec *p1, IntensityRec *p2)
 +/*
 + *	DESCRIPTION
 + *		Compares the intensity component of two IntensityRec
 + *		structures.
 + *
 + *	RETURNS
 + *		0 if equal;
 + *		< 0 if first precedes second
 + *		> 0 if first succeeds second
 + *
 + */
 +{
 +    if (p1->intensity < p2->intensity) {
 +	return (-1);
 +    }
 +    if (p1->intensity > p2->intensity) {
 +	return (XcmsSuccess);
 +    }
 +    return (XcmsFailure);
 +}
 +
 +/*
 + *	NAME
 + *		ValueInterpolation
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +static int
 +_XcmsValueInterpolation(
 +    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
 +    int bitsPerRGB)
 +/*
 + *	DESCRIPTION
 + *		Based on a given value, performs a linear interpolation
 + *		on the intensities between two IntensityRec structures.
 + *		Note that the bitsPerRGB parameter is ignored.
 + *
 + *	RETURNS
 + *		Returns 0 if failed; otherwise non-zero.
 + */
 +{
 +    XcmsFloat ratio;
 +
 +    ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) /
 +	((XcmsFloat)hi->value - (XcmsFloat)lo->value);
 +    answer->value = key->value;
 +    answer->intensity = (hi->intensity - lo->intensity) * ratio;
 +    answer->intensity += lo->intensity;
 +    return (XcmsSuccess);
 +}
 +
 +/*
 + *	NAME
 + *		IntensityInterpolation
 + *
 + *	SYNOPSIS
 + */
 +static int
 +_XcmsIntensityInterpolation(
 +    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
 +    int bitsPerRGB)
 +/*
 + *	DESCRIPTION
 + *		Based on a given intensity, performs a linear interpolation
 + *		on the values between two IntensityRec structures.
 + *		The bitsPerRGB parameter is necessary to perform rounding
 + *		to the correct number of significant bits.
 + *
 + *	RETURNS
 + *		Returns 0 if failed; otherwise non-zero.
 + */
 +{
 +    XcmsFloat ratio;
 +    long target, up, down;
 +    int shift = 16 - bitsPerRGB;
 +    int max_color = (1 << bitsPerRGB) - 1;
 +
 +    ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
 +    answer->intensity = key->intensity;
 +    target = hi->value - lo->value;
 +    target *= ratio;
 +    target += lo->value;
 +
 +    /*
 +     * Ok now, lets find the closest in respects to bits per RGB
 +     */
 +    up = ((target >> shift) * 0xFFFF) / max_color;
 +    if (up < target) {
 +	down = up;
 +	up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
 +    } else {
 +	down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
 +    }
 +    answer->value = ((up - target) < (target - down) ? up : down);
 +    answer->value &= MASK[bitsPerRGB];
 +    return (XcmsSuccess);
 +}
 +
 +
 +
 +typedef int (*comparProcp)(
 +    char *p1,
 +    char *p2);
 +typedef int (*interpolProcp)(
 +    char *key,
 +    char *lo,
 +    char *hi,
 +    char *answer,
 +    int bitsPerRGB);
 +
 +/*
 + *	NAME
 + *		_XcmsTableSearch
 + *
 + *	SYNOPSIS
 + */
 +static int
 +_XcmsTableSearch(
 +    char *key,
 +    int bitsPerRGB,
 +    char *base,
 +    unsigned nel,
 +    unsigned nKeyPtrSize,
 +    int (*compar)(
 +        char *p1,
 +        char *p2),
 +    int (*interpol)(
 +        char *key,
 +        char *lo,
 +        char *hi,
 +        char *answer,
 +        int bitsPerRGB),
 +    char *answer)
 +
 +/*
 + *	DESCRIPTION
 + *		A binary search through the specificied table.
 + *
 + *	RETURNS
 + *		Returns 0 if failed; otherwise non-zero.
 + *
 + */
 +{
 +    char *hi, *lo, *mid, *last;
 +    int result;
 +
 +    last = hi = base + ((nel - 1) * nKeyPtrSize);
 +    mid = lo = base;
 +
 +    /* use only the significants bits, then scale into 16 bits */
 +    ((IntensityRec *)key)->value = ((unsigned long)
 +	    (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
 +	    / ((1 << bitsPerRGB) - 1);
 +
 +    /* Special case so that zero intensity always maps to zero value */
 +    if ((*compar) (key,lo) <= 0) {
 +	memcpy (answer, lo, nKeyPtrSize);
 +	((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
 +	return XcmsSuccess;
 +    }
 +    while (mid != last) {
 +	last = mid;
 +	mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
 +	result = (*compar) (key, mid);
 +	if (result == 0) {
 +
 +	    memcpy(answer, mid, nKeyPtrSize);
 +	    ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
 +	    return (XcmsSuccess);
 +	} else if (result < 0) {
 +	    hi = mid;
 +	} else {
 +	    lo = mid;
 +	}
 +    }
 +
 +    /*
 +     * If we got to here, we didn't find a solution, so we
 +     * need to apply interpolation.
 +     */
 +    return ((*interpol)(key, lo, hi, answer, bitsPerRGB));
 +}
 +
 +
 +/*
 + *      NAME
 + *		_XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
 + *
 + *	SYNOPSIS
 + */
 +static void _XcmsMatVec(
 +    XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut)
 +/*
 + *      DESCRIPTION
 + *		Multiply the passed vector by the passed matrix to return a
 + *		vector. Matrix is 3x3, vectors are of length 3.
 + *
 + *	RETURNS
 + *		void
 + */
 +{
 +    int i, j;
 +
 +    for (i = 0; i < 3; i++) {
 +	pOut[i] = 0.0;
 +	for (j = 0; j < 3; j++)
 +	    pOut[i] += *(pMat+(i*3)+j) * pIn[j];
 +    }
 +}
 +
 +
 +/************************************************************************
 + *									*
 + *			 PUBLIC ROUTINES				*
 + *									*
 + ************************************************************************/
 +
 +
 +/*
 + *	NAME
 + *		XcmsLRGB_RGB_ParseString
 + *
 + *	SYNOPSIS
 + */
 +static int
 +XcmsLRGB_RGB_ParseString(
 +    register char *spec,
 +    XcmsColor *pColor)
 +/*
 + *	DESCRIPTION
 + *		This routines takes a string and attempts to convert
 + *		it into a XcmsColor structure with XcmsRGBFormat.
 + *
 + *	RETURNS
 + *		0 if failed, non-zero otherwise.
 + */
 +{
 +    register int n, i;
 +    unsigned short r, g, b;
 +    char c;
 +    char *pchar;
 +    unsigned short *pShort;
 +
 +    /*
 +     * Check for old # format
 +     */
 +    if (*spec == '#') {
 +	/*
 +	 * Attempt to parse the value portion.
 +	 */
 +	spec++;
 +	n = strlen(spec);
 +	if (n != 3 && n != 6 && n != 9 && n != 12) {
 +	    return(XcmsFailure);
 +	}
 +
 +	n /= 3;
 +	g = b = 0;
 +	do {
 +	    r = g;
 +	    g = b;
 +	    b = 0;
 +	    for (i = n; --i >= 0; ) {
 +		c = *spec++;
 +		b <<= 4;
 +		if (c >= '0' && c <= '9')
 +		    b |= c - '0';
 +		/* assume string in lowercase
 +		else if (c >= 'A' && c <= 'F')
 +		    b |= c - ('A' - 10);
 +		*/
 +		else if (c >= 'a' && c <= 'f')
 +		    b |= c - ('a' - 10);
 +		else return (XcmsFailure);
 +	    }
 +	} while (*spec != '\0');
 +
 +	/*
 +	 * Succeeded !
 +	 */
 +	n <<= 2;
 +	n = 16 - n;
 +	/* shift instead of scale, to match old broken semantics */
 +	pColor->spec.RGB.red = r << n;
 +	pColor->spec.RGB.green = g << n;
 +	pColor->spec.RGB.blue =  b << n;
 +    } else {
 +	if ((pchar = strchr(spec, ':')) == NULL) {
 +	    return(XcmsFailure);
 +	}
 +	n = (int)(pchar - spec);
 +
 +	/*
 +	 * Check for proper prefix.
 +	 */
 +	if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
 +	    return(XcmsFailure);
 +	}
 +
 +	/*
 +	 * Attempt to parse the value portion.
 +	 */
 +	spec += (n + 1);
 +	pShort = &pColor->spec.RGB.red;
 +	for (i = 0; i < 3; i++, pShort++, spec++) {
 +	    n = 0;
 +	    *pShort = 0;
 +	    while (*spec != '/' && *spec != '\0') {
 +		if (++n > 4) {
 +		    return(XcmsFailure);
 +		}
 +		c = *spec++;
 +		*pShort <<= 4;
 +		if (c >= '0' && c <= '9')
 +		    *pShort |= c - '0';
 +		/* assume string in lowercase
 +		else if (c >= 'A' && c <= 'F')
 +		    *pShort |= c - ('A' - 10);
 +		*/
 +		else if (c >= 'a' && c <= 'f')
 +		    *pShort |= c - ('a' - 10);
 +		else return (XcmsFailure);
 +	    }
 +	    if (n == 0)
 +		return (XcmsFailure);
 +	    if (n < 4) {
 +		*pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
 +	    }
 +	}
 +    }
 +    pColor->format = XcmsRGBFormat;
 +    pColor->pixel = 0;
 +    return (XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		XcmsLRGB_RGBi_ParseString
 + *
 + *	SYNOPSIS
 + */
 +static int
 +XcmsLRGB_RGBi_ParseString(
 +    register char *spec,
 +    XcmsColor *pColor)
 +/*
 + *	DESCRIPTION
 + *		This routines takes a string and attempts to convert
 + *		it into a XcmsColor structure with XcmsRGBiFormat.
 + *		The assumed RGBi string syntax is:
 + *		    RGBi:<r>/<g>/<b>
 + *		Where r, g, and b are in string input format for floats
 + *		consisting of:
 + *		    a. an optional sign
 + *		    b. a string of numbers possibly containing a decimal point,
 + *		    c. an optional exponent field containing an 'E' or 'e'
 + *			followed by a possibly signed integer string.
 + *
 + *	RETURNS
 + *		0 if failed, non-zero otherwise.
 + */
 +{
 +    int n;
 +    char *pchar;
 +
 +    if ((pchar = strchr(spec, ':')) == NULL) {
 +	return(XcmsFailure);
 +    }
 +    n = (int)(pchar - spec);
 +
 +    /*
 +     * Check for proper prefix.
 +     */
 +    if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
 +	return(XcmsFailure);
 +    }
 +
 +    /*
 +     * Attempt to parse the value portion.
 +     */
 +    if (sscanf(spec + n + 1, "%lf/%lf/%lf",
 +	    &pColor->spec.RGBi.red,
 +	    &pColor->spec.RGBi.green,
 +	    &pColor->spec.RGBi.blue) != 3) {
 +        char *s; /* Maybe failed due to locale */
 +        int f;
 +        if ((s = strdup(spec))) {
 +            for (f = 0; s[f]; ++f)
 +                if (s[f] == '.')
 +                    s[f] = ',';
 +                else if (s[f] == ',')
 +                    s[f] = '.';
 +	    if (sscanf(s + n + 1, "%lf/%lf/%lf",
 +		       &pColor->spec.RGBi.red,
 +		       &pColor->spec.RGBi.green,
 +		       &pColor->spec.RGBi.blue) != 3) {
 +                free(s);
 +                return(XcmsFailure);
 +            }
 +            free(s);
 +        } else
 +	    return(XcmsFailure);
 +    }
 +
 +    /*
 +     * Succeeded !
 +     */
 +    pColor->format = XcmsRGBiFormat;
 +    pColor->pixel = 0;
 +    return (XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +Status
 +XcmsCIEXYZToRGBi(
 +    XcmsCCC ccc,
 +    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
 +    unsigned int nColors,	/* Number of colors			*/
 +    Bool *pCompressed)		/* pointer to an array of Bool		*/
 +/*
 + *	DESCRIPTION
 + *		Converts color specifications in an array of XcmsColor
 + *		structures from RGB format to RGBi format.
 + *
 + *	RETURNS
 + *		XcmsFailure if failed,
 + *		XcmsSuccess if succeeded without gamut compression.
 + *		XcmsSuccessWithCompression if succeeded with gamut
 + *			compression.
 + */
 +{
 +    LINEAR_RGB_SCCData *pScreenData;
 +    XcmsFloat tmp[3];
 +    int hasCompressed = 0;
 +    unsigned int i;
 +    XcmsColor *pColor = pXcmsColors_in_out;
 +
 +    if (ccc == NULL) {
 +	return(XcmsFailure);
 +    }
 +
 +    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
 +
 +    /*
 +     * XcmsColors should be White Point Adjusted, if necessary, by now!
 +     */
 +
 +    /*
 +     * NEW!!! for extended gamut compression
 +     *
 +     * 1. Need to zero out pCompressed
 +     *
 +     * 2. Need to save initial address of pColor
 +     *
 +     * 3. Need to save initial address of pCompressed
 +     */
 +
 +    for (i = 0; i < nColors; i++) {
 +
 +	/* Make sure format is XcmsCIEXYZFormat */
 +	if (pColor->format != XcmsCIEXYZFormat) {
 +	    return(XcmsFailure);
 +	}
 +
 +	/* Multiply [A]-1 * [XYZ] to get RGB intensity */
 +	_XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
 +		(XcmsFloat *) &pColor->spec, tmp);
 +
 +	if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
 +	    (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
 +
 +	    /*
 +	     * RGBi out of screen's gamut
 +	     */
 +
 +	    if (ccc->gamutCompProc == NULL) {
 +		/*
 +		 * Aha!! Here's that little trick that will allow
 +		 * gamut compression routines to get the out of bound
 +		 * RGBi.
 +		 */
 +		memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
 +		pColor->format = XcmsRGBiFormat;
 +		return(XcmsFailure);
 +	    } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
 +		    i, pCompressed) == 0) {
 +		return(XcmsFailure);
 +	    }
 +
 +	    /*
 +	     * The gamut compression function should return colors in CIEXYZ
 +	     *	Also check again to if the new color is within gamut.
 +	     */
 +	    if (pColor->format != XcmsCIEXYZFormat) {
 +		return(XcmsFailure);
 +	    }
 +	    _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
 +		    (XcmsFloat *) &pColor->spec, tmp);
 +	    if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
 +		(MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
 +		return(XcmsFailure);
 +	    }
 +	    hasCompressed++;
 +	}
 +	memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
 +	/* These if statements are done to ensure the fudge factor is */
 +	/* is taken into account. */
 +	if (pColor->spec.RGBi.red < 0.0) {
 +		pColor->spec.RGBi.red = 0.0;
 +	} else if (pColor->spec.RGBi.red > 1.0) {
 +		pColor->spec.RGBi.red = 1.0;
 +	}
 +	if (pColor->spec.RGBi.green < 0.0) {
 +		pColor->spec.RGBi.green = 0.0;
 +	} else if (pColor->spec.RGBi.green > 1.0) {
 +		pColor->spec.RGBi.green = 1.0;
 +	}
 +	if (pColor->spec.RGBi.blue < 0.0) {
 +		pColor->spec.RGBi.blue = 0.0;
 +	} else if (pColor->spec.RGBi.blue > 1.0) {
 +		pColor->spec.RGBi.blue = 1.0;
 +	}
 +	(pColor++)->format = XcmsRGBiFormat;
 +    }
 +    return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +Status
 +XcmsRGBiToCIEXYZ(
 +    XcmsCCC ccc,
 +    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
 +    unsigned int nColors,	/* Number of colors			*/
 +    Bool *pCompressed)		/* pointer to a bit array		*/
 +/*
 + *	DESCRIPTION
 + *		Converts color specifications in an array of XcmsColor
 + *		structures from RGBi format to CIEXYZ format.
 + *
 + *	RETURNS
 + *		XcmsFailure if failed,
 + *		XcmsSuccess if succeeded.
 + */
 +{
 +    LINEAR_RGB_SCCData *pScreenData;
 +    XcmsFloat tmp[3];
 +
 +    /*
 +     * pCompressed ignored in this function.
 +     */
 +
 +    if (ccc == NULL) {
 +	return(XcmsFailure);
 +    }
 +
 +    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
 +
 +    /*
 +     * XcmsColors should be White Point Adjusted, if necessary, by now!
 +     */
 +
 +    while (nColors--) {
 +
 +	/* Multiply [A]-1 * [XYZ] to get RGB intensity */
 +	_XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
 +		(XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
 +
 +	memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp));
 +	(pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
 +    }
 +    return(XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		XcmsRGBiToRGB
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +Status
 +XcmsRGBiToRGB(
 +    XcmsCCC ccc,
 +    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
 +    unsigned int nColors,	/* Number of colors			*/
 +    Bool *pCompressed)		/* pointer to a bit array		*/
 +/*
 + *	DESCRIPTION
 + *		Converts color specifications in an array of XcmsColor
 + *		structures from RGBi format to RGB format.
 + *
 + *	RETURNS
 + *		XcmsFailure if failed,
 + *		XcmsSuccess if succeeded without gamut compression.
 + *		XcmsSuccessWithCompression if succeeded with gamut
 + *			compression.
 + */
 +{
 +    LINEAR_RGB_SCCData *pScreenData;
 +    XcmsRGB tmpRGB;
 +    IntensityRec keyIRec, answerIRec;
 +
 +    /*
 +     * pCompressed ignored in this function.
 +     */
 +
 +    if (ccc == NULL) {
 +	return(XcmsFailure);
 +    }
 +
 +    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
 +
 +    while (nColors--) {
 +
 +	/* Make sure format is XcmsRGBiFormat */
 +	if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
 +	    return(XcmsFailure);
 +	}
 +
 +	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pRedTbl->pBase,
 +		(unsigned)pScreenData->pRedTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGB.red = answerIRec.value;
 +
 +	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pGreenTbl->pBase,
 +		(unsigned)pScreenData->pGreenTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGB.green = answerIRec.value;
 +
 +	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pBlueTbl->pBase,
 +		(unsigned)pScreenData->pBlueTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGB.blue = answerIRec.value;
 +
 +	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
 +	(pXcmsColors_in_out++)->format = XcmsRGBFormat;
 +    }
 +    return(XcmsSuccess);
 +}
 +
 +
 +/*
 + *	NAME
 + *		XcmsRGBToRGBi
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +Status
 +XcmsRGBToRGBi(
 +    XcmsCCC ccc,
 +    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
 +    unsigned int nColors,	/* Number of colors			*/
 +    Bool *pCompressed)		/* pointer to a bit array		*/
 +/*
 + *	DESCRIPTION
 + *		Converts color specifications in an array of XcmsColor
 + *		structures from RGB format to RGBi format.
 + *
 + *	RETURNS
 + *		XcmsFailure if failed,
 + *		XcmsSuccess if succeeded.
 + */
 +{
 +    LINEAR_RGB_SCCData *pScreenData;
 +    XcmsRGBi tmpRGBi;
 +    IntensityRec keyIRec, answerIRec;
 +
 +    /*
 +     * pCompressed ignored in this function.
 +     */
 +
 +    if (ccc == NULL) {
 +	return(XcmsFailure);
 +    }
 +
 +    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
 +
 +    while (nColors--) {
 +
 +	/* Make sure format is XcmsRGBFormat */
 +	if (pXcmsColors_in_out->format != XcmsRGBFormat) {
 +	    return(XcmsFailure);
 +	}
 +
 +	keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pRedTbl->pBase,
 +		(unsigned)pScreenData->pRedTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGBi.red = answerIRec.intensity;
 +
 +	keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pGreenTbl->pBase,
 +		(unsigned)pScreenData->pGreenTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGBi.green = answerIRec.intensity;
 +
 +	keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
 +	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
 +		(char *)pScreenData->pBlueTbl->pBase,
 +		(unsigned)pScreenData->pBlueTbl->nEntries,
 +		(unsigned)sizeof(IntensityRec),
 +		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
 +	    return(XcmsFailure);
 +	}
 +	tmpRGBi.blue = answerIRec.intensity;
 +
 +	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
 +	(pXcmsColors_in_out++)->format = XcmsRGBiFormat;
 +    }
 +    return(XcmsSuccess);
 +}
 +
 +/*
 + *	NAME
 + *		_XcmsInitScrnDefaultInfo
 + *
 + *	SYNOPSIS
 + */
 +/* ARGSUSED */
 +int
 +_XcmsLRGB_InitScrnDefault(
 +    Display *dpy,
 +    int screenNumber,
 +    XcmsPerScrnInfo *pPerScrnInfo)
 +/*
 + *	DESCRIPTION
 + *		Given a display and screen number, this routine attempts
 + *		to initialize the Xcms per Screen Info structure
 + *		(XcmsPerScrnInfo) with defaults.
 + *
 + *	RETURNS
 + *		Returns zero if initialization failed; non-zero otherwise.
 + */
 +{
 +    pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
 +    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
 +		Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
 +    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
 +		Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
 +    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
 +		Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
 +		Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
 +    if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
 +	    || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
 +	pPerScrnInfo->screenData = (XPointer)NULL;
 +	pPerScrnInfo->state = XcmsInitNone;
 +	return(0);
 +    }
 +    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
 +    pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
 +    pPerScrnInfo->screenWhitePt.pixel = 0;
 +    pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
 +    pPerScrnInfo->state = XcmsInitFailure; /* default initialization */
 +    return(1);
 +}
 | 
