LRGB.c revision 57f47464
11ab64890Smrg
21ab64890Smrg/*
31ab64890Smrg * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
41ab64890Smrg * 	All Rights Reserved
561b2299dSmrg *
61ab64890Smrg * This file is a component of an X Window System-specific implementation
71ab64890Smrg * of Xcms based on the TekColor Color Management System.  Permission is
81ab64890Smrg * hereby granted to use, copy, modify, sell, and otherwise distribute this
91ab64890Smrg * software and its documentation for any purpose and without fee, provided
101ab64890Smrg * that this copyright, permission, and disclaimer notice is reproduced in
111ab64890Smrg * all copies of this software and in supporting documentation.  TekColor
121ab64890Smrg * is a trademark of Tektronix, Inc.
1361b2299dSmrg *
141ab64890Smrg * Tektronix makes no representation about the suitability of this software
151ab64890Smrg * for any purpose.  It is provided "as is" and with all faults.
1661b2299dSmrg *
171ab64890Smrg * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
181ab64890Smrg * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
191ab64890Smrg * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
201ab64890Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
211ab64890Smrg * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
221ab64890Smrg * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
231ab64890Smrg * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg *
251ab64890Smrg *
261ab64890Smrg *	NAME
271ab64890Smrg *		XcmsLRGB.c
281ab64890Smrg *
291ab64890Smrg *	DESCRIPTION
301ab64890Smrg *		This file contains the conversion routines:
311ab64890Smrg *		    1. CIE XYZ to RGB intensity
321ab64890Smrg *		    2. RGB intensity to device RGB
331ab64890Smrg *		    3. device RGB to RGB intensity
341ab64890Smrg *		    4. RGB intensity to CIE XYZ
351ab64890Smrg *
361ab64890Smrg */
371ab64890Smrg
381ab64890Smrg#ifdef HAVE_CONFIG_H
391ab64890Smrg#include <config.h>
401ab64890Smrg#endif
411ab64890Smrg#include <stdio.h>
421ab64890Smrg#include <X11/Xos.h>
431ab64890Smrg#include <X11/Xatom.h>
441ab64890Smrg#include "Xlibint.h"
451ab64890Smrg#include "Xcmsint.h"
461ab64890Smrg#include "Cv.h"
471ab64890Smrg
481ab64890Smrg/*
491ab64890Smrg *      LOCAL DEFINES
501ab64890Smrg *		#define declarations local to this package.
511ab64890Smrg */
521ab64890Smrg#define EPS	0.001
531ab64890Smrg#ifndef MIN
541ab64890Smrg#define MIN(x,y) ((x) > (y) ? (y) : (x))
551ab64890Smrg#endif /* MIN */
561ab64890Smrg#ifndef MAX
571ab64890Smrg#define MAX(x,y) ((x) > (y) ? (x) : (y))
581ab64890Smrg#endif /* MAX */
591ab64890Smrg#ifndef MIN3
601ab64890Smrg#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x))
611ab64890Smrg#endif /* MIN3 */
621ab64890Smrg#ifndef MAX3
631ab64890Smrg#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z))))
641ab64890Smrg#endif /* MAX3 */
651ab64890Smrg
661ab64890Smrg/*
671ab64890Smrg *      LOCAL TYPEDEFS
681ab64890Smrg *              typedefs local to this package (for use with local vars).
691ab64890Smrg *
701ab64890Smrg */
711ab64890Smrg
721ab64890Smrg/*
731ab64890Smrg *      FORWARD DECLARATIONS
741ab64890Smrg */
751ab64890Smrgstatic void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp);
761ab64890Smrgstatic int LINEAR_RGB_InitSCCData(Display *dpy,
771ab64890Smrg    int screenNumber, XcmsPerScrnInfo *pPerScrnInfo);
781ab64890Smrgstatic int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor);
791ab64890Smrgstatic int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor);
801ab64890Smrgstatic Status
811ab64890Smrg_XcmsGetTableType0(
821ab64890Smrg    IntensityTbl *pTbl,
831ab64890Smrg    int	  format,
841ab64890Smrg    char **pChar,
851ab64890Smrg    unsigned long *pCount);
861ab64890Smrgstatic Status
871ab64890Smrg_XcmsGetTableType1(
881ab64890Smrg    IntensityTbl *pTbl,
891ab64890Smrg    int	  format,
901ab64890Smrg    char **pChar,
911ab64890Smrg    unsigned long *pCount);
921ab64890Smrg
931ab64890Smrg/*
941ab64890Smrg *      LOCALS VARIABLES
951ab64890Smrg *		Variables local to this package.
961ab64890Smrg *		    Usage example:
971ab64890Smrg *		        static int	ExampleLocalVar;
981ab64890Smrg */
991ab64890Smrg
1001ab64890Smrgstatic unsigned short const MASK[17] = {
1011ab64890Smrg    0x0000,	/*  0 bitsPerRGB */
1021ab64890Smrg    0x8000,	/*  1 bitsPerRGB */
1031ab64890Smrg    0xc000,	/*  2 bitsPerRGB */
1041ab64890Smrg    0xe000,	/*  3 bitsPerRGB */
1051ab64890Smrg    0xf000,	/*  4 bitsPerRGB */
1061ab64890Smrg    0xf800,	/*  5 bitsPerRGB */
1071ab64890Smrg    0xfc00,	/*  6 bitsPerRGB */
1081ab64890Smrg    0xfe00,	/*  7 bitsPerRGB */
1091ab64890Smrg    0xff00,	/*  8 bitsPerRGB */
1101ab64890Smrg    0xff80,	/*  9 bitsPerRGB */
1111ab64890Smrg    0xffc0,	/* 10 bitsPerRGB */
1121ab64890Smrg    0xffe0,	/* 11 bitsPerRGB */
1131ab64890Smrg    0xfff0,	/* 12 bitsPerRGB */
1141ab64890Smrg    0xfff8,	/* 13 bitsPerRGB */
1151ab64890Smrg    0xfffc,	/* 14 bitsPerRGB */
1161ab64890Smrg    0xfffe,	/* 15 bitsPerRGB */
1171ab64890Smrg    0xffff	/* 16 bitsPerRGB */
1181ab64890Smrg};
1191ab64890Smrg
1201ab64890Smrg
1211ab64890Smrg    /*
1221ab64890Smrg     * A NULL terminated array of function pointers that when applied
1231ab64890Smrg     * in series will convert an XcmsColor structure from XcmsRGBFormat
1241ab64890Smrg     * to XcmsCIEXYZFormat.
1251ab64890Smrg     */
1261ab64890Smrgstatic XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
1271ab64890Smrg    (XcmsConversionProc)XcmsRGBToRGBi,
1281ab64890Smrg    (XcmsConversionProc)XcmsRGBiToCIEXYZ,
1291ab64890Smrg    NULL
1301ab64890Smrg};
1311ab64890Smrg
1321ab64890Smrg    /*
1331ab64890Smrg     * A NULL terminated array of function pointers that when applied
1341ab64890Smrg     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
1351ab64890Smrg     * to XcmsRGBFormat.
1361ab64890Smrg     */
1371ab64890Smrgstatic XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
1381ab64890Smrg    (XcmsConversionProc)XcmsCIEXYZToRGBi,
1391ab64890Smrg    (XcmsConversionProc)XcmsRGBiToRGB,
1401ab64890Smrg    NULL
1411ab64890Smrg};
1421ab64890Smrg
1431ab64890Smrg    /*
1441ab64890Smrg     * A NULL terminated array of function pointers that when applied
1451ab64890Smrg     * in series will convert an XcmsColor structure from XcmsRGBiFormat
1461ab64890Smrg     * to XcmsCIEXYZFormat.
1471ab64890Smrg     */
1481ab64890Smrgstatic XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
1491ab64890Smrg    (XcmsConversionProc)XcmsRGBiToCIEXYZ,
1501ab64890Smrg    NULL
1511ab64890Smrg};
1521ab64890Smrg
1531ab64890Smrg    /*
1541ab64890Smrg     * A NULL terminated array of function pointers that when applied
1551ab64890Smrg     * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
1561ab64890Smrg     * to XcmsRGBiFormat.
1571ab64890Smrg     */
1581ab64890Smrgstatic XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
1591ab64890Smrg    (XcmsConversionProc)XcmsCIEXYZToRGBi,
1601ab64890Smrg    NULL
1611ab64890Smrg};
1621ab64890Smrg
1631ab64890Smrg    /*
1641ab64890Smrg     * RGBi Color Spaces
1651ab64890Smrg     */
1661ab64890SmrgXcmsColorSpace	XcmsRGBiColorSpace =
1671ab64890Smrg    {
1681ab64890Smrg	_XcmsRGBi_prefix,	/* prefix */
1691ab64890Smrg	XcmsRGBiFormat,		/* id */
1701ab64890Smrg	XcmsLRGB_RGBi_ParseString,	/* parseString */
1711ab64890Smrg	Fl_RGBi_to_CIEXYZ,	/* to_CIEXYZ */
1721ab64890Smrg	Fl_CIEXYZ_to_RGBi,	/* from_CIEXYZ */
1731ab64890Smrg	1
1741ab64890Smrg    };
1751ab64890Smrg
1761ab64890Smrg    /*
1771ab64890Smrg     * RGB Color Spaces
1781ab64890Smrg     */
1791ab64890SmrgXcmsColorSpace	XcmsRGBColorSpace =
1801ab64890Smrg    {
1811ab64890Smrg	_XcmsRGB_prefix,		/* prefix */
1821ab64890Smrg	XcmsRGBFormat,		/* id */
1831ab64890Smrg	XcmsLRGB_RGB_ParseString,	/* parseString */
1841ab64890Smrg	Fl_RGB_to_CIEXYZ,	/* to_CIEXYZ */
1851ab64890Smrg	Fl_CIEXYZ_to_RGB,	/* from_CIEXYZ */
1861ab64890Smrg	1
1871ab64890Smrg    };
1881ab64890Smrg
1891ab64890Smrg    /*
19061b2299dSmrg     * Device-Independent Color Spaces known to the
1911ab64890Smrg     * LINEAR_RGB Screen Color Characteristics Function Set.
1921ab64890Smrg     */
1931ab64890Smrgstatic XcmsColorSpace	*DDColorSpaces[] = {
1941ab64890Smrg    &XcmsRGBColorSpace,
1951ab64890Smrg    &XcmsRGBiColorSpace,
1961ab64890Smrg    NULL
1971ab64890Smrg};
1981ab64890Smrg
1991ab64890Smrg
2001ab64890Smrg/*
2011ab64890Smrg *      GLOBALS
2021ab64890Smrg *              Variables declared in this package that are allowed
2031ab64890Smrg *		to be used globally.
2041ab64890Smrg */
2051ab64890Smrg
2061ab64890Smrg    /*
2071ab64890Smrg     * LINEAR_RGB Screen Color Characteristics Function Set.
2081ab64890Smrg     */
2091ab64890SmrgXcmsFunctionSet	XcmsLinearRGBFunctionSet =
2101ab64890Smrg    {
2111ab64890Smrg	&DDColorSpaces[0],	/* pDDColorSpaces */
2121ab64890Smrg	LINEAR_RGB_InitSCCData,	/* pInitScrnFunc */
2131ab64890Smrg	LINEAR_RGB_FreeSCCData	/* pFreeSCCData */
2141ab64890Smrg    };
2151ab64890Smrg
2161ab64890Smrg/*
2171ab64890Smrg *	DESCRIPTION
2181ab64890Smrg *		Contents of Default SCCData should be replaced if other
2191ab64890Smrg *		data should be used as default.
2201ab64890Smrg *
2211ab64890Smrg *
2221ab64890Smrg */
2231ab64890Smrg
2241ab64890Smrg/*
2251ab64890Smrg * NAME		Tektronix 19" (Sony) CRT
2261ab64890Smrg * PART_NUMBER		119-2451-00
2271ab64890Smrg * MODEL		Tek4300, Tek4800
2281ab64890Smrg */
2291ab64890Smrg
2301ab64890Smrgstatic IntensityRec const Default_RGB_RedTuples[] = {
2311ab64890Smrg    /* {unsigned short value, XcmsFloat intensity} */
2321ab64890Smrg            { 0x0000,    0.000000 },
2331ab64890Smrg            { 0x0909,    0.000000 },
2341ab64890Smrg            { 0x0a0a,    0.000936 },
2351ab64890Smrg            { 0x0f0f,    0.001481 },
2361ab64890Smrg            { 0x1414,    0.002329 },
2371ab64890Smrg            { 0x1919,    0.003529 },
2381ab64890Smrg            { 0x1e1e,    0.005127 },
2391ab64890Smrg            { 0x2323,    0.007169 },
2401ab64890Smrg            { 0x2828,    0.009699 },
2411ab64890Smrg            { 0x2d2d,    0.012759 },
2421ab64890Smrg            { 0x3232,    0.016392 },
2431ab64890Smrg            { 0x3737,    0.020637 },
2441ab64890Smrg            { 0x3c3c,    0.025533 },
2451ab64890Smrg            { 0x4141,    0.031119 },
2461ab64890Smrg            { 0x4646,    0.037431 },
2471ab64890Smrg            { 0x4b4b,    0.044504 },
2481ab64890Smrg            { 0x5050,    0.052373 },
2491ab64890Smrg            { 0x5555,    0.061069 },
2501ab64890Smrg            { 0x5a5a,    0.070624 },
2511ab64890Smrg            { 0x5f5f,    0.081070 },
2521ab64890Smrg            { 0x6464,    0.092433 },
2531ab64890Smrg            { 0x6969,    0.104744 },
2541ab64890Smrg            { 0x6e6e,    0.118026 },
2551ab64890Smrg            { 0x7373,    0.132307 },
2561ab64890Smrg            { 0x7878,    0.147610 },
2571ab64890Smrg            { 0x7d7d,    0.163958 },
2581ab64890Smrg            { 0x8282,    0.181371 },
2591ab64890Smrg            { 0x8787,    0.199871 },
2601ab64890Smrg            { 0x8c8c,    0.219475 },
2611ab64890Smrg            { 0x9191,    0.240202 },
2621ab64890Smrg            { 0x9696,    0.262069 },
2631ab64890Smrg            { 0x9b9b,    0.285089 },
2641ab64890Smrg            { 0xa0a0,    0.309278 },
2651ab64890Smrg            { 0xa5a5,    0.334647 },
2661ab64890Smrg            { 0xaaaa,    0.361208 },
2671ab64890Smrg            { 0xafaf,    0.388971 },
2681ab64890Smrg            { 0xb4b4,    0.417945 },
2691ab64890Smrg            { 0xb9b9,    0.448138 },
2701ab64890Smrg            { 0xbebe,    0.479555 },
2711ab64890Smrg            { 0xc3c3,    0.512202 },
2721ab64890Smrg            { 0xc8c8,    0.546082 },
2731ab64890Smrg            { 0xcdcd,    0.581199 },
2741ab64890Smrg            { 0xd2d2,    0.617552 },
2751ab64890Smrg            { 0xd7d7,    0.655144 },
2761ab64890Smrg            { 0xdcdc,    0.693971 },
2771ab64890Smrg            { 0xe1e1,    0.734031 },
2781ab64890Smrg            { 0xe6e6,    0.775322 },
2791ab64890Smrg            { 0xebeb,    0.817837 },
2801ab64890Smrg            { 0xf0f0,    0.861571 },
2811ab64890Smrg            { 0xf5f5,    0.906515 },
2821ab64890Smrg            { 0xfafa,    0.952662 },
2831ab64890Smrg            { 0xffff,    1.000000 }
2841ab64890Smrg};
2851ab64890Smrg
2861ab64890Smrgstatic IntensityRec const Default_RGB_GreenTuples[] = {
2871ab64890Smrg    /* {unsigned short value, XcmsFloat intensity} */
2881ab64890Smrg            { 0x0000,    0.000000 },
2891ab64890Smrg            { 0x1313,    0.000000 },
2901ab64890Smrg            { 0x1414,    0.000832 },
2911ab64890Smrg            { 0x1919,    0.001998 },
2921ab64890Smrg            { 0x1e1e,    0.003612 },
2931ab64890Smrg            { 0x2323,    0.005736 },
2941ab64890Smrg            { 0x2828,    0.008428 },
2951ab64890Smrg            { 0x2d2d,    0.011745 },
2961ab64890Smrg            { 0x3232,    0.015740 },
2971ab64890Smrg            { 0x3737,    0.020463 },
2981ab64890Smrg            { 0x3c3c,    0.025960 },
2991ab64890Smrg            { 0x4141,    0.032275 },
3001ab64890Smrg            { 0x4646,    0.039449 },
3011ab64890Smrg            { 0x4b4b,    0.047519 },
3021ab64890Smrg            { 0x5050,    0.056520 },
3031ab64890Smrg            { 0x5555,    0.066484 },
3041ab64890Smrg            { 0x5a5a,    0.077439 },
3051ab64890Smrg            { 0x5f5f,    0.089409 },
3061ab64890Smrg            { 0x6464,    0.102418 },
3071ab64890Smrg            { 0x6969,    0.116485 },
3081ab64890Smrg            { 0x6e6e,    0.131625 },
3091ab64890Smrg            { 0x7373,    0.147853 },
3101ab64890Smrg            { 0x7878,    0.165176 },
3111ab64890Smrg            { 0x7d7d,    0.183604 },
3121ab64890Smrg            { 0x8282,    0.203140 },
3131ab64890Smrg            { 0x8787,    0.223783 },
3141ab64890Smrg            { 0x8c8c,    0.245533 },
3151ab64890Smrg            { 0x9191,    0.268384 },
3161ab64890Smrg            { 0x9696,    0.292327 },
3171ab64890Smrg            { 0x9b9b,    0.317351 },
3181ab64890Smrg            { 0xa0a0,    0.343441 },
3191ab64890Smrg            { 0xa5a5,    0.370580 },
3201ab64890Smrg            { 0xaaaa,    0.398747 },
3211ab64890Smrg            { 0xafaf,    0.427919 },
3221ab64890Smrg            { 0xb4b4,    0.458068 },
3231ab64890Smrg            { 0xb9b9,    0.489165 },
3241ab64890Smrg            { 0xbebe,    0.521176 },
3251ab64890Smrg            { 0xc3c3,    0.554067 },
3261ab64890Smrg            { 0xc8c8,    0.587797 },
3271ab64890Smrg            { 0xcdcd,    0.622324 },
3281ab64890Smrg            { 0xd2d2,    0.657604 },
3291ab64890Smrg            { 0xd7d7,    0.693588 },
3301ab64890Smrg            { 0xdcdc,    0.730225 },
3311ab64890Smrg            { 0xe1e1,    0.767459 },
3321ab64890Smrg            { 0xe6e6,    0.805235 },
3331ab64890Smrg            { 0xebeb,    0.843491 },
3341ab64890Smrg            { 0xf0f0,    0.882164 },
3351ab64890Smrg            { 0xf5f5,    0.921187 },
3361ab64890Smrg            { 0xfafa,    0.960490 },
3371ab64890Smrg            { 0xffff,    1.000000 }
3381ab64890Smrg};
3391ab64890Smrg
3401ab64890Smrgstatic IntensityRec const Default_RGB_BlueTuples[] = {
3411ab64890Smrg    /* {unsigned short value, XcmsFloat intensity} */
3421ab64890Smrg            { 0x0000,    0.000000 },
3431ab64890Smrg            { 0x0e0e,    0.000000 },
3441ab64890Smrg            { 0x0f0f,    0.001341 },
3451ab64890Smrg            { 0x1414,    0.002080 },
3461ab64890Smrg            { 0x1919,    0.003188 },
3471ab64890Smrg            { 0x1e1e,    0.004729 },
3481ab64890Smrg            { 0x2323,    0.006766 },
3491ab64890Smrg            { 0x2828,    0.009357 },
3501ab64890Smrg            { 0x2d2d,    0.012559 },
3511ab64890Smrg            { 0x3232,    0.016424 },
3521ab64890Smrg            { 0x3737,    0.021004 },
3531ab64890Smrg            { 0x3c3c,    0.026344 },
3541ab64890Smrg            { 0x4141,    0.032489 },
3551ab64890Smrg            { 0x4646,    0.039481 },
3561ab64890Smrg            { 0x4b4b,    0.047357 },
3571ab64890Smrg            { 0x5050,    0.056154 },
3581ab64890Smrg            { 0x5555,    0.065903 },
3591ab64890Smrg            { 0x5a5a,    0.076634 },
3601ab64890Smrg            { 0x5f5f,    0.088373 },
3611ab64890Smrg            { 0x6464,    0.101145 },
3621ab64890Smrg            { 0x6969,    0.114968 },
3631ab64890Smrg            { 0x6e6e,    0.129862 },
3641ab64890Smrg            { 0x7373,    0.145841 },
3651ab64890Smrg            { 0x7878,    0.162915 },
3661ab64890Smrg            { 0x7d7d,    0.181095 },
3671ab64890Smrg            { 0x8282,    0.200386 },
3681ab64890Smrg            { 0x8787,    0.220791 },
3691ab64890Smrg            { 0x8c8c,    0.242309 },
3701ab64890Smrg            { 0x9191,    0.264937 },
3711ab64890Smrg            { 0x9696,    0.288670 },
3721ab64890Smrg            { 0x9b9b,    0.313499 },
3731ab64890Smrg            { 0xa0a0,    0.339410 },
3741ab64890Smrg            { 0xa5a5,    0.366390 },
3751ab64890Smrg            { 0xaaaa,    0.394421 },
3761ab64890Smrg            { 0xafaf,    0.423481 },
3771ab64890Smrg            { 0xb4b4,    0.453547 },
3781ab64890Smrg            { 0xb9b9,    0.484592 },
3791ab64890Smrg            { 0xbebe,    0.516587 },
3801ab64890Smrg            { 0xc3c3,    0.549498 },
3811ab64890Smrg            { 0xc8c8,    0.583291 },
3821ab64890Smrg            { 0xcdcd,    0.617925 },
3831ab64890Smrg            { 0xd2d2,    0.653361 },
3841ab64890Smrg            { 0xd7d7,    0.689553 },
3851ab64890Smrg            { 0xdcdc,    0.726454 },
3861ab64890Smrg            { 0xe1e1,    0.764013 },
3871ab64890Smrg            { 0xe6e6,    0.802178 },
3881ab64890Smrg            { 0xebeb,    0.840891 },
3891ab64890Smrg            { 0xf0f0,    0.880093 },
3901ab64890Smrg            { 0xf5f5,    0.919723 },
3911ab64890Smrg            { 0xfafa,    0.959715 },
3921ab64890Smrg	    { 0xffff,    1.00000 }
3931ab64890Smrg};
3941ab64890Smrg
3951ab64890Smrgstatic IntensityTbl Default_RGB_RedTbl = {
3961ab64890Smrg    /* IntensityRec *pBase */
3971ab64890Smrg	(IntensityRec *) Default_RGB_RedTuples,
3981ab64890Smrg    /* unsigned int nEntries */
3991ab64890Smrg	52
4001ab64890Smrg};
4011ab64890Smrg
4021ab64890Smrgstatic IntensityTbl Default_RGB_GreenTbl = {
4031ab64890Smrg    /* IntensityRec *pBase */
4041ab64890Smrg	(IntensityRec *)Default_RGB_GreenTuples,
4051ab64890Smrg    /* unsigned int nEntries */
4061ab64890Smrg	50
4071ab64890Smrg};
4081ab64890Smrg
4091ab64890Smrgstatic IntensityTbl Default_RGB_BlueTbl = {
4101ab64890Smrg    /* IntensityRec *pBase */
4111ab64890Smrg	(IntensityRec *)Default_RGB_BlueTuples,
4121ab64890Smrg    /* unsigned int nEntries */
4131ab64890Smrg	51
4141ab64890Smrg};
4151ab64890Smrg
4161ab64890Smrgstatic LINEAR_RGB_SCCData Default_RGB_SCCData = {
4171ab64890Smrg    /* XcmsFloat XYZtoRGBmatrix[3][3] */
4181ab64890Smrg  {
4191ab64890Smrg    { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 },
4201ab64890Smrg    {-1.07152751306193600,  1.96593795204372400,  0.03673691339553462 },
4211ab64890Smrg    { 0.06351179790497788, -0.20020501000496480,  0.81070942031648220 }
4221ab64890Smrg  },
4231ab64890Smrg
4241ab64890Smrg    /* XcmsFloat RGBtoXYZmatrix[3][3] */
4251ab64890Smrg  {
4261ab64890Smrg    { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 },
4271ab64890Smrg    { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 },
4281ab64890Smrg    { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 }
4291ab64890Smrg  },
4301ab64890Smrg
4311ab64890Smrg    /* IntensityTbl *pRedTbl */
4321ab64890Smrg	&Default_RGB_RedTbl,
4331ab64890Smrg
4341ab64890Smrg    /* IntensityTbl *pGreenTbl */
4351ab64890Smrg	&Default_RGB_GreenTbl,
4361ab64890Smrg
4371ab64890Smrg    /* IntensityTbl *pBlueTbl */
4381ab64890Smrg	&Default_RGB_BlueTbl
4391ab64890Smrg};
4401ab64890Smrg
4411ab64890Smrg/************************************************************************
4421ab64890Smrg *									*
4431ab64890Smrg *			PRIVATE ROUTINES				*
4441ab64890Smrg *									*
4451ab64890Smrg ************************************************************************/
4461ab64890Smrg
4471ab64890Smrg/*
4481ab64890Smrg *	NAME
4491ab64890Smrg *		LINEAR_RGB_InitSCCData()
4501ab64890Smrg *
4511ab64890Smrg *	SYNOPSIS
4521ab64890Smrg */
4531ab64890Smrgstatic Status
4541ab64890SmrgLINEAR_RGB_InitSCCData(
4551ab64890Smrg    Display *dpy,
4561ab64890Smrg    int screenNumber,
4571ab64890Smrg    XcmsPerScrnInfo *pPerScrnInfo)
4581ab64890Smrg/*
4591ab64890Smrg *	DESCRIPTION
4601ab64890Smrg *
4611ab64890Smrg *	RETURNS
4621ab64890Smrg *		XcmsFailure if failed.
4631ab64890Smrg *		XcmsSuccess if succeeded.
4641ab64890Smrg *
4651ab64890Smrg */
4661ab64890Smrg{
4671ab64890Smrg    Atom  CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
4681ab64890Smrg    Atom  MatrixAtom  = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
4691ab64890Smrg    int	  format_return, count, cType, nTables;
4701ab64890Smrg    unsigned long nitems, nbytes_return;
4711ab64890Smrg    char *property_return, *pChar;
4721ab64890Smrg    XcmsFloat *pValue;
4731ab64890Smrg#ifdef ALLDEBUG
4741ab64890Smrg    IntensityRec *pIRec;
4751ab64890Smrg#endif /* ALLDEBUG */
4761ab64890Smrg    VisualID visualID;
4771ab64890Smrg
4781ab64890Smrg    LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
4791ab64890Smrg    XcmsIntensityMap *pNewMap;
4801ab64890Smrg
4811ab64890Smrg    /*
4821ab64890Smrg     * Allocate memory for pScreenData
4831ab64890Smrg     */
48461b2299dSmrg    if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *)
4851ab64890Smrg		      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
4861ab64890Smrg	return(XcmsFailure);
4871ab64890Smrg    }
4881ab64890Smrg
48961b2299dSmrg    /*
4901ab64890Smrg     *  1. Get the XYZ->RGB and RGB->XYZ matrices
4911ab64890Smrg     */
4921ab64890Smrg
4931ab64890Smrg    if (MatrixAtom == None ||
49461b2299dSmrg	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom,
4951ab64890Smrg	   &format_return, &nitems, &nbytes_return, &property_return) ||
4961ab64890Smrg	   nitems != 18 || format_return != 32) {
4971ab64890Smrg	/*
4981ab64890Smrg	 * As per the XDCCC, there must be 18 data items and each must be
4991ab64890Smrg	 * in 32 bits !
5001ab64890Smrg	 */
5011ab64890Smrg	goto FreeSCCData;
5021ab64890Smrg
5031ab64890Smrg    } else {
5041ab64890Smrg
5051ab64890Smrg	/*
5061ab64890Smrg	 * RGBtoXYZ and XYZtoRGB matrices
5071ab64890Smrg	 */
5081ab64890Smrg	pValue = (XcmsFloat *) pScreenData;
5091ab64890Smrg	pChar = property_return;
5101ab64890Smrg	for (count = 0; count < 18; count++) {
5111ab64890Smrg	    *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
5121ab64890Smrg		    &nitems) / (XcmsFloat)XDCCC_NUMBER;
5131ab64890Smrg	}
5141ab64890Smrg	Xfree ((char *)property_return);
5151ab64890Smrg	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
5161ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][0] +
5171ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][1] +
5181ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][2];
5191ab64890Smrg	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
5201ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][0] +
5211ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][1] +
5221ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][2];
5231ab64890Smrg	pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
5241ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][0] +
5251ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][1] +
5261ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][2];
5271ab64890Smrg
5281ab64890Smrg	/*
5291ab64890Smrg	 * Compute the Screen White Point
5301ab64890Smrg	 */
5311ab64890Smrg	if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
5321ab64890Smrg		|| (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
5331ab64890Smrg	    goto FreeSCCData;
5341ab64890Smrg	} else {
5351ab64890Smrg	    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
5361ab64890Smrg	}
5371ab64890Smrg	pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
5381ab64890Smrg	pPerScrnInfo->screenWhitePt.pixel = 0;
5391ab64890Smrg
5401ab64890Smrg#ifdef PDEBUG
5411ab64890Smrg	printf ("RGB to XYZ Matrix values:\n");
5421ab64890Smrg	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
5431ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][0],
5441ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][1],
5451ab64890Smrg		pScreenData->RGBtoXYZmatrix[0][2],
5461ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][0],
5471ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][1],
5481ab64890Smrg		pScreenData->RGBtoXYZmatrix[1][2],
5491ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][0],
5501ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][1],
5511ab64890Smrg		pScreenData->RGBtoXYZmatrix[2][2]);
5521ab64890Smrg	printf ("XYZ to RGB Matrix values:\n");
5531ab64890Smrg	printf ("       %f %f %f\n       %f %f %f\n       %f %f %f\n",
5541ab64890Smrg		pScreenData->XYZtoRGBmatrix[0][0],
5551ab64890Smrg		pScreenData->XYZtoRGBmatrix[0][1],
5561ab64890Smrg		pScreenData->XYZtoRGBmatrix[0][2],
5571ab64890Smrg		pScreenData->XYZtoRGBmatrix[1][0],
5581ab64890Smrg		pScreenData->XYZtoRGBmatrix[1][1],
5591ab64890Smrg		pScreenData->XYZtoRGBmatrix[1][2],
5601ab64890Smrg		pScreenData->XYZtoRGBmatrix[2][0],
5611ab64890Smrg		pScreenData->XYZtoRGBmatrix[2][1],
5621ab64890Smrg		pScreenData->XYZtoRGBmatrix[2][2]);
5631ab64890Smrg	printf ("Screen White Pt value: %f %f %f\n",
5641ab64890Smrg		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
5651ab64890Smrg		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
5661ab64890Smrg		pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
5671ab64890Smrg#endif /* PDEBUG */
5681ab64890Smrg    }
5691ab64890Smrg
5701ab64890Smrg    /*
5711ab64890Smrg     *	2. Get the Intensity Profile
5721ab64890Smrg     */
5731ab64890Smrg    if (CorrectAtom == None ||
5741ab64890Smrg	!_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
5751ab64890Smrg	   &format_return, &nitems, &nbytes_return, &property_return)) {
5761ab64890Smrg	goto FreeSCCData;
5771ab64890Smrg    }
5781ab64890Smrg
5791ab64890Smrg    pChar = property_return;
5801ab64890Smrg
5811ab64890Smrg    while (nitems) {
5821ab64890Smrg	switch (format_return) {
5831ab64890Smrg	  case 8:
5841ab64890Smrg	    /*
5851ab64890Smrg	     * Must have at least:
5861ab64890Smrg	     *		VisualID0
5871ab64890Smrg	     *		VisualID1
5881ab64890Smrg	     *		VisualID2
5891ab64890Smrg	     *		VisualID3
5901ab64890Smrg	     *		type
5911ab64890Smrg	     *		count
5921ab64890Smrg	     *		length
5931ab64890Smrg	     *		intensity1
5941ab64890Smrg	     *		intensity2
5951ab64890Smrg	     */
5961ab64890Smrg	    if (nitems < 9) {
59757f47464Smrg		goto Free_property_return;
5981ab64890Smrg	    }
5991ab64890Smrg	    count = 3;
6001ab64890Smrg	    break;
6011ab64890Smrg	  case 16:
6021ab64890Smrg	    /*
6031ab64890Smrg	     * Must have at least:
6041ab64890Smrg	     *		VisualID0
6051ab64890Smrg	     *		VisualID3
6061ab64890Smrg	     *		type
6071ab64890Smrg	     *		count
6081ab64890Smrg	     *		length
6091ab64890Smrg	     *		intensity1
6101ab64890Smrg	     *		intensity2
6111ab64890Smrg	     */
6121ab64890Smrg	    if (nitems < 7) {
61357f47464Smrg		goto Free_property_return;
6141ab64890Smrg	    }
6151ab64890Smrg	    count = 1;
6161ab64890Smrg	    break;
6171ab64890Smrg	  case 32:
6181ab64890Smrg	    /*
6191ab64890Smrg	     * Must have at least:
6201ab64890Smrg	     *		VisualID0
6211ab64890Smrg	     *		type
6221ab64890Smrg	     *		count
6231ab64890Smrg	     *		length
6241ab64890Smrg	     *		intensity1
6251ab64890Smrg	     *		intensity2
6261ab64890Smrg	     */
6271ab64890Smrg	    if (nitems < 6) {
62857f47464Smrg		goto Free_property_return;
6291ab64890Smrg	    }
6301ab64890Smrg	    count = 0;
6311ab64890Smrg	    break;
6321ab64890Smrg	  default:
63357f47464Smrg	    goto Free_property_return;
6341ab64890Smrg	}
6351ab64890Smrg
6361ab64890Smrg	/*
6371ab64890Smrg	 * Get VisualID
6381ab64890Smrg	 */
6391ab64890Smrg	visualID = _XcmsGetElement(format_return, &pChar, &nitems);
6401ab64890Smrg	while (count--) {
6411ab64890Smrg	    visualID = visualID << format_return;
6421ab64890Smrg	    visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
6431ab64890Smrg	}
6441ab64890Smrg
6451ab64890Smrg	if (visualID == 0) {
6461ab64890Smrg	    /*
6471ab64890Smrg	     * This is a shared intensity table
6481ab64890Smrg	     */
6491ab64890Smrg	    pScreenData = pScreenDefaultData;
6501ab64890Smrg	} else {
6511ab64890Smrg	    /*
6521ab64890Smrg	     * This is a per-Visual intensity table
6531ab64890Smrg	     */
65461b2299dSmrg	    if (!(pScreenData = (LINEAR_RGB_SCCData *)
6551ab64890Smrg			      Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
6561ab64890Smrg		return(XcmsFailure);
6571ab64890Smrg	    }
6581ab64890Smrg	    /* copy matrices */
6591ab64890Smrg	    memcpy((char *)pScreenData, (char *)pScreenDefaultData,
6601ab64890Smrg		   18 * sizeof(XcmsFloat));
6611ab64890Smrg
6621ab64890Smrg	    /* Create, initialize, and add map */
66361b2299dSmrg	    if (!(pNewMap = (XcmsIntensityMap *)
6641ab64890Smrg			      Xcalloc (1, sizeof(XcmsIntensityMap)))) {
6651ab64890Smrg		Xfree((char *)pScreenData);
6661ab64890Smrg		return(XcmsFailure);
6671ab64890Smrg	    }
6681ab64890Smrg	    pNewMap->visualID = visualID;
6691ab64890Smrg	    pNewMap->screenData = (XPointer)pScreenData;
6701ab64890Smrg	    pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
6711ab64890Smrg	    pNewMap->pNext =
6721ab64890Smrg		    (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
6731ab64890Smrg	    dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
6741ab64890Smrg	    dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
6751ab64890Smrg	}
6761ab64890Smrg
6771ab64890Smrg	cType = _XcmsGetElement(format_return, &pChar, &nitems);
6781ab64890Smrg	nTables = _XcmsGetElement(format_return, &pChar, &nitems);
6791ab64890Smrg
6801ab64890Smrg	if (cType == 0) {
6811ab64890Smrg
6821ab64890Smrg	    /* Red Intensity Table */
6831ab64890Smrg	    if (!(pScreenData->pRedTbl = (IntensityTbl *)
6841ab64890Smrg		    Xcalloc (1, sizeof(IntensityTbl)))) {
68557f47464Smrg		goto Free_property_return;
6861ab64890Smrg	    }
6871ab64890Smrg	    if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
6881ab64890Smrg		    &nitems) == XcmsFailure) {
6891ab64890Smrg		goto FreeRedTbl;
6901ab64890Smrg	    }
6911ab64890Smrg
6921ab64890Smrg	    if (nTables == 1) {
6931ab64890Smrg		/* Green Intensity Table */
6941ab64890Smrg		pScreenData->pGreenTbl = pScreenData->pRedTbl;
6951ab64890Smrg		/* Blue Intensity Table */
6961ab64890Smrg		pScreenData->pBlueTbl = pScreenData->pRedTbl;
6971ab64890Smrg	    } else {
6981ab64890Smrg		/* Green Intensity Table */
6991ab64890Smrg		if (!(pScreenData->pGreenTbl = (IntensityTbl *)
7001ab64890Smrg			Xcalloc (1, sizeof(IntensityTbl)))) {
7011ab64890Smrg		    goto FreeRedTblElements;
7021ab64890Smrg		}
7031ab64890Smrg		if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
7041ab64890Smrg			&nitems) == XcmsFailure) {
7051ab64890Smrg		    goto FreeGreenTbl;
7061ab64890Smrg		}
7071ab64890Smrg
7081ab64890Smrg		/* Blue Intensity Table */
7091ab64890Smrg		if (!(pScreenData->pBlueTbl = (IntensityTbl *)
7101ab64890Smrg			Xcalloc (1, sizeof(IntensityTbl)))) {
7111ab64890Smrg		    goto FreeGreenTblElements;
7121ab64890Smrg		}
7131ab64890Smrg		if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
7141ab64890Smrg			&nitems) == XcmsFailure) {
7151ab64890Smrg		    goto FreeBlueTbl;
7161ab64890Smrg		}
71761b2299dSmrg	    }
7181ab64890Smrg	} else if (cType == 1) {
7191ab64890Smrg	    /* Red Intensity Table */
7201ab64890Smrg	    if (!(pScreenData->pRedTbl = (IntensityTbl *)
7211ab64890Smrg		    Xcalloc (1, sizeof(IntensityTbl)))) {
72257f47464Smrg		goto Free_property_return;
7231ab64890Smrg	    }
7241ab64890Smrg	    if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
7251ab64890Smrg		    &nitems) == XcmsFailure) {
7261ab64890Smrg		goto FreeRedTbl;
7271ab64890Smrg	    }
7281ab64890Smrg
7291ab64890Smrg	    if (nTables == 1) {
7301ab64890Smrg
7311ab64890Smrg		/* Green Intensity Table */
7321ab64890Smrg		pScreenData->pGreenTbl = pScreenData->pRedTbl;
7331ab64890Smrg		/* Blue Intensity Table */
7341ab64890Smrg		pScreenData->pBlueTbl = pScreenData->pRedTbl;
7351ab64890Smrg
7361ab64890Smrg	    } else {
7371ab64890Smrg
7381ab64890Smrg		/* Green Intensity Table */
7391ab64890Smrg		if (!(pScreenData->pGreenTbl = (IntensityTbl *)
7401ab64890Smrg			Xcalloc (1, sizeof(IntensityTbl)))) {
7411ab64890Smrg		    goto FreeRedTblElements;
7421ab64890Smrg		}
7431ab64890Smrg		if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
7441ab64890Smrg			&nitems) == XcmsFailure) {
7451ab64890Smrg		    goto FreeGreenTbl;
7461ab64890Smrg		}
7471ab64890Smrg
7481ab64890Smrg		/* Blue Intensity Table */
7491ab64890Smrg		if (!(pScreenData->pBlueTbl = (IntensityTbl *)
7501ab64890Smrg			Xcalloc (1, sizeof(IntensityTbl)))) {
751e9fcaa8aSmrg		    goto FreeGreenTblElements;
7521ab64890Smrg		}
7531ab64890Smrg		if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
7541ab64890Smrg			&nitems) == XcmsFailure) {
7551ab64890Smrg		    goto FreeBlueTbl;
7561ab64890Smrg		}
7571ab64890Smrg	    }
7581ab64890Smrg	} else {
75957f47464Smrg	    goto Free_property_return;
7601ab64890Smrg	}
7611ab64890Smrg
7621ab64890Smrg#ifdef ALLDEBUG
7631ab64890Smrg	printf ("Intensity Table  RED    %d\n", pScreenData->pRedTbl->nEntries);
7641ab64890Smrg	pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
7651ab64890Smrg	for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
7661ab64890Smrg	    printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
7671ab64890Smrg	}
7681ab64890Smrg	if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
7691ab64890Smrg	    printf ("Intensity Table  GREEN  %d\n", pScreenData->pGreenTbl->nEntries);
7701ab64890Smrg	    pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
7711ab64890Smrg	    for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
7721ab64890Smrg		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
7731ab64890Smrg	    }
7741ab64890Smrg	}
7751ab64890Smrg	if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
7761ab64890Smrg	    printf ("Intensity Table  BLUE   %d\n", pScreenData->pBlueTbl->nEntries);
7771ab64890Smrg	    pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
7781ab64890Smrg	    for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
7791ab64890Smrg		printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
7801ab64890Smrg	    }
7811ab64890Smrg	}
7821ab64890Smrg#endif /* ALLDEBUG */
7831ab64890Smrg    }
7841ab64890Smrg
7851ab64890Smrg    Xfree ((char *)property_return);
7861ab64890Smrg
7871ab64890Smrg    /* Free the old memory and use the new structure created. */
7881ab64890Smrg    LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData);
7891ab64890Smrg
7901ab64890Smrg    pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
7911ab64890Smrg
7921ab64890Smrg    pPerScrnInfo->screenData = (XPointer) pScreenData;
7931ab64890Smrg
7941ab64890Smrg    pPerScrnInfo->state = XcmsInitSuccess;
7951ab64890Smrg
7961ab64890Smrg    return(XcmsSuccess);
7971ab64890Smrg
7981ab64890SmrgFreeBlueTblElements:
7991ab64890Smrg    Xfree((char *)pScreenData->pBlueTbl->pBase);
8001ab64890Smrg
8011ab64890SmrgFreeBlueTbl:
8021ab64890Smrg    Xfree((char *)pScreenData->pBlueTbl);
8031ab64890Smrg
8041ab64890SmrgFreeGreenTblElements:
8051ab64890Smrg    Xfree((char *)pScreenData->pBlueTbl->pBase);
8061ab64890Smrg
8071ab64890SmrgFreeGreenTbl:
8081ab64890Smrg    Xfree((char *)pScreenData->pGreenTbl);
8091ab64890Smrg
8101ab64890SmrgFreeRedTblElements:
8111ab64890Smrg    Xfree((char *)pScreenData->pRedTbl->pBase);
8121ab64890Smrg
8131ab64890SmrgFreeRedTbl:
8141ab64890Smrg    Xfree((char *)pScreenData->pRedTbl);
8151ab64890Smrg
81657f47464SmrgFree_property_return:
81757f47464Smrg    Xfree ((char *)property_return);
81857f47464Smrg
8191ab64890SmrgFreeSCCData:
8201ab64890Smrg    Xfree((char *)pScreenData);
8211ab64890Smrg    pPerScrnInfo->state = XcmsInitNone;
8221ab64890Smrg    return(XcmsFailure);
8231ab64890Smrg}
8241ab64890Smrg
8251ab64890Smrg
8261ab64890Smrg/*
8271ab64890Smrg *	NAME
8281ab64890Smrg *		LINEAR_RGB_FreeSCCData()
8291ab64890Smrg *
8301ab64890Smrg *	SYNOPSIS
8311ab64890Smrg */
8321ab64890Smrgstatic void
8331ab64890SmrgLINEAR_RGB_FreeSCCData(
8341ab64890Smrg    XPointer pScreenDataTemp)
8351ab64890Smrg/*
8361ab64890Smrg *	DESCRIPTION
8371ab64890Smrg *
8381ab64890Smrg *	RETURNS
8391ab64890Smrg *		0 if failed.
8401ab64890Smrg *		1 if succeeded with no modifications.
8411ab64890Smrg *
8421ab64890Smrg */
8431ab64890Smrg{
8441ab64890Smrg    LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
8451ab64890Smrg
8461ab64890Smrg    if (pScreenData && pScreenData != &Default_RGB_SCCData) {
8471ab64890Smrg	if (pScreenData->pRedTbl) {
8481ab64890Smrg	    if (pScreenData->pGreenTbl) {
84961b2299dSmrg		if (pScreenData->pRedTbl->pBase !=
8501ab64890Smrg		    pScreenData->pGreenTbl->pBase) {
8511ab64890Smrg		    if (pScreenData->pGreenTbl->pBase) {
8521ab64890Smrg			Xfree ((char *)pScreenData->pGreenTbl->pBase);
8531ab64890Smrg		    }
8541ab64890Smrg		}
8551ab64890Smrg		if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
8561ab64890Smrg		    Xfree ((char *)pScreenData->pGreenTbl);
8571ab64890Smrg		}
8581ab64890Smrg	    }
8591ab64890Smrg	    if (pScreenData->pBlueTbl) {
86061b2299dSmrg		if (pScreenData->pRedTbl->pBase !=
8611ab64890Smrg		    pScreenData->pBlueTbl->pBase) {
8621ab64890Smrg		    if (pScreenData->pBlueTbl->pBase) {
8631ab64890Smrg			Xfree ((char *)pScreenData->pBlueTbl->pBase);
8641ab64890Smrg		    }
8651ab64890Smrg		}
8661ab64890Smrg		if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
8671ab64890Smrg		    Xfree ((char *)pScreenData->pBlueTbl);
8681ab64890Smrg		}
8691ab64890Smrg	    }
8701ab64890Smrg	    if (pScreenData->pRedTbl->pBase) {
8711ab64890Smrg		Xfree ((char *)pScreenData->pRedTbl->pBase);
8721ab64890Smrg	    }
8731ab64890Smrg	    Xfree ((char *)pScreenData->pRedTbl);
8741ab64890Smrg	}
8751ab64890Smrg	Xfree ((char *)pScreenData);
8761ab64890Smrg    }
8771ab64890Smrg}
8781ab64890Smrg
8791ab64890Smrg
8801ab64890Smrg
8811ab64890Smrg/************************************************************************
8821ab64890Smrg *									*
8831ab64890Smrg *			API PRIVATE ROUTINES				*
8841ab64890Smrg *									*
8851ab64890Smrg ************************************************************************/
8861ab64890Smrg
8871ab64890Smrg/*
8881ab64890Smrg *	NAME
8891ab64890Smrg *		_XcmsGetTableType0
8901ab64890Smrg *
8911ab64890Smrg *	SYNOPSIS
8921ab64890Smrg */
8931ab64890Smrgstatic Status
8941ab64890Smrg_XcmsGetTableType0(
8951ab64890Smrg    IntensityTbl *pTbl,
8961ab64890Smrg    int	  format,
8971ab64890Smrg    char **pChar,
8981ab64890Smrg    unsigned long *pCount)
8991ab64890Smrg/*
9001ab64890Smrg *	DESCRIPTION
9011ab64890Smrg *
9021ab64890Smrg *	RETURNS
9031ab64890Smrg *		XcmsFailure if failed.
9041ab64890Smrg *		XcmsSuccess if succeeded.
9051ab64890Smrg *
9061ab64890Smrg */
9071ab64890Smrg{
9081ab64890Smrg    unsigned int nElements;
9091ab64890Smrg    IntensityRec *pIRec;
9101ab64890Smrg
9111ab64890Smrg    nElements = pTbl->nEntries =
9121ab64890Smrg	    _XcmsGetElement(format, pChar, pCount) + 1;
9131ab64890Smrg    if (!(pIRec = pTbl->pBase = (IntensityRec *)
9141ab64890Smrg	  Xcalloc (nElements, sizeof(IntensityRec)))) {
9151ab64890Smrg	return(XcmsFailure);
9161ab64890Smrg    }
9171ab64890Smrg
9181ab64890Smrg    switch (format) {
91961b2299dSmrg      case 8:
9201ab64890Smrg	for (; nElements--; pIRec++) {
9211ab64890Smrg	    /* 0xFFFF/0xFF = 0x101 */
9221ab64890Smrg	    pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
9231ab64890Smrg	    pIRec->intensity =
9241ab64890Smrg		    _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
9251ab64890Smrg	}
9261ab64890Smrg	break;
92761b2299dSmrg      case 16:
9281ab64890Smrg	for (; nElements--; pIRec++) {
9291ab64890Smrg	    pIRec->value = _XcmsGetElement (format, pChar, pCount);
9301ab64890Smrg	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
9311ab64890Smrg		    / (XcmsFloat)65535.0;
9321ab64890Smrg	}
9331ab64890Smrg	break;
93461b2299dSmrg      case 32:
9351ab64890Smrg	for (; nElements--; pIRec++) {
9361ab64890Smrg	    pIRec->value = _XcmsGetElement (format, pChar, pCount);
9371ab64890Smrg	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
9381ab64890Smrg		    / (XcmsFloat)4294967295.0;
9391ab64890Smrg	}
9401ab64890Smrg	break;
9411ab64890Smrg      default:
9421ab64890Smrg	return(XcmsFailure);
9431ab64890Smrg    }
9441ab64890Smrg    return(XcmsSuccess);
9451ab64890Smrg}
9461ab64890Smrg
9471ab64890Smrg
9481ab64890Smrg/*
9491ab64890Smrg *	NAME
9501ab64890Smrg *		_XcmsGetTableType1
9511ab64890Smrg *
9521ab64890Smrg *	SYNOPSIS
9531ab64890Smrg */
9541ab64890Smrgstatic Status
9551ab64890Smrg_XcmsGetTableType1(
9561ab64890Smrg    IntensityTbl *pTbl,
9571ab64890Smrg    int	  format,
9581ab64890Smrg    char **pChar,
9591ab64890Smrg    unsigned long *pCount)
9601ab64890Smrg/*
9611ab64890Smrg *	DESCRIPTION
9621ab64890Smrg *
9631ab64890Smrg *	RETURNS
9641ab64890Smrg *		XcmsFailure if failed.
9651ab64890Smrg *		XcmsSuccess if succeeded.
9661ab64890Smrg *
9671ab64890Smrg */
9681ab64890Smrg{
9691ab64890Smrg    int count;
9701ab64890Smrg    unsigned int max_index;
9711ab64890Smrg    IntensityRec *pIRec;
9721ab64890Smrg
9731ab64890Smrg    max_index = _XcmsGetElement(format, pChar, pCount);
9741ab64890Smrg    pTbl->nEntries = max_index + 1;
9751ab64890Smrg    if (!(pIRec = pTbl->pBase = (IntensityRec *)
9761ab64890Smrg	  Xcalloc (max_index+1, sizeof(IntensityRec)))) {
9771ab64890Smrg	return(XcmsFailure);
9781ab64890Smrg    }
9791ab64890Smrg
9801ab64890Smrg    switch (format) {
98161b2299dSmrg      case 8:
9821ab64890Smrg	for (count = 0; count < max_index+1; count++, pIRec++) {
9831ab64890Smrg	    pIRec->value = (count * 65535) / max_index;
9841ab64890Smrg	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
9851ab64890Smrg		    / (XcmsFloat)255.0;
9861ab64890Smrg	}
9871ab64890Smrg	break;
98861b2299dSmrg      case 16:
9891ab64890Smrg	for (count = 0; count < max_index+1; count++, pIRec++) {
9901ab64890Smrg	    pIRec->value = (count * 65535) / max_index;
9911ab64890Smrg	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
9921ab64890Smrg		    / (XcmsFloat)65535.0;
9931ab64890Smrg	}
9941ab64890Smrg	break;
99561b2299dSmrg      case 32:
9961ab64890Smrg	for (count = 0; count < max_index+1; count++, pIRec++) {
9971ab64890Smrg	    pIRec->value = (count * 65535) / max_index;
9981ab64890Smrg	    pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
9991ab64890Smrg		    / (XcmsFloat)4294967295.0;
10001ab64890Smrg	}
10011ab64890Smrg	break;
10021ab64890Smrg      default:
10031ab64890Smrg	return(XcmsFailure);
10041ab64890Smrg    }
10051ab64890Smrg
10061ab64890Smrg    return(XcmsSuccess);
10071ab64890Smrg}
10081ab64890Smrg
10091ab64890Smrg
10101ab64890Smrg/*
10111ab64890Smrg *	NAME
10121ab64890Smrg *		ValueCmp
10131ab64890Smrg *
10141ab64890Smrg *	SYNOPSIS
10151ab64890Smrg */
10161ab64890Smrgstatic int
10171ab64890Smrg_XcmsValueCmp(
10181ab64890Smrg    IntensityRec *p1, IntensityRec *p2)
10191ab64890Smrg/*
10201ab64890Smrg *	DESCRIPTION
10211ab64890Smrg *		Compares the value component of two IntensityRec
10221ab64890Smrg *		structures.
10231ab64890Smrg *
10241ab64890Smrg *	RETURNS
10251ab64890Smrg *		0 if p1->value is equal to p2->value
10261ab64890Smrg *		< 0 if p1->value is less than p2->value
10271ab64890Smrg *		> 0 if p1->value is greater than p2->value
10281ab64890Smrg *
10291ab64890Smrg */
10301ab64890Smrg{
10311ab64890Smrg    return (p1->value - p2->value);
10321ab64890Smrg}
10331ab64890Smrg
10341ab64890Smrg
10351ab64890Smrg/*
10361ab64890Smrg *	NAME
10371ab64890Smrg *		IntensityCmp
10381ab64890Smrg *
10391ab64890Smrg *	SYNOPSIS
10401ab64890Smrg */
10411ab64890Smrgstatic int
10421ab64890Smrg_XcmsIntensityCmp(
10431ab64890Smrg    IntensityRec *p1, IntensityRec *p2)
10441ab64890Smrg/*
10451ab64890Smrg *	DESCRIPTION
10461ab64890Smrg *		Compares the intensity component of two IntensityRec
10471ab64890Smrg *		structures.
10481ab64890Smrg *
10491ab64890Smrg *	RETURNS
10501ab64890Smrg *		0 if equal;
10511ab64890Smrg *		< 0 if first precedes second
10521ab64890Smrg *		> 0 if first succeeds second
10531ab64890Smrg *
10541ab64890Smrg */
10551ab64890Smrg{
10561ab64890Smrg    if (p1->intensity < p2->intensity) {
10571ab64890Smrg	return (-1);
10581ab64890Smrg    }
10591ab64890Smrg    if (p1->intensity > p2->intensity) {
10601ab64890Smrg	return (XcmsSuccess);
10611ab64890Smrg    }
10621ab64890Smrg    return (XcmsFailure);
10631ab64890Smrg}
10641ab64890Smrg
10651ab64890Smrg/*
10661ab64890Smrg *	NAME
10671ab64890Smrg *		ValueInterpolation
10681ab64890Smrg *
10691ab64890Smrg *	SYNOPSIS
10701ab64890Smrg */
10711ab64890Smrg/* ARGSUSED */
10721ab64890Smrgstatic int
10731ab64890Smrg_XcmsValueInterpolation(
10741ab64890Smrg    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
10751ab64890Smrg    int bitsPerRGB)
10761ab64890Smrg/*
10771ab64890Smrg *	DESCRIPTION
10781ab64890Smrg *		Based on a given value, performs a linear interpolation
10791ab64890Smrg *		on the intensities between two IntensityRec structures.
10801ab64890Smrg *		Note that the bitsPerRGB parameter is ignored.
10811ab64890Smrg *
10821ab64890Smrg *	RETURNS
10831ab64890Smrg *		Returns 0 if failed; otherwise non-zero.
10841ab64890Smrg */
10851ab64890Smrg{
10861ab64890Smrg    XcmsFloat ratio;
10871ab64890Smrg
108861b2299dSmrg    ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) /
10891ab64890Smrg	((XcmsFloat)hi->value - (XcmsFloat)lo->value);
10901ab64890Smrg    answer->value = key->value;
10911ab64890Smrg    answer->intensity = (hi->intensity - lo->intensity) * ratio;
10921ab64890Smrg    answer->intensity += lo->intensity;
10931ab64890Smrg    return (XcmsSuccess);
10941ab64890Smrg}
10951ab64890Smrg
10961ab64890Smrg/*
10971ab64890Smrg *	NAME
10981ab64890Smrg *		IntensityInterpolation
10991ab64890Smrg *
11001ab64890Smrg *	SYNOPSIS
11011ab64890Smrg */
11021ab64890Smrgstatic int
11031ab64890Smrg_XcmsIntensityInterpolation(
11041ab64890Smrg    IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
11051ab64890Smrg    int bitsPerRGB)
11061ab64890Smrg/*
11071ab64890Smrg *	DESCRIPTION
11081ab64890Smrg *		Based on a given intensity, performs a linear interpolation
11091ab64890Smrg *		on the values between two IntensityRec structures.
11101ab64890Smrg *		The bitsPerRGB parameter is necessary to perform rounding
11111ab64890Smrg *		to the correct number of significant bits.
11121ab64890Smrg *
11131ab64890Smrg *	RETURNS
11141ab64890Smrg *		Returns 0 if failed; otherwise non-zero.
11151ab64890Smrg */
11161ab64890Smrg{
11171ab64890Smrg    XcmsFloat ratio;
11181ab64890Smrg    long target, up, down;
11191ab64890Smrg    int shift = 16 - bitsPerRGB;
11201ab64890Smrg    int max_color = (1 << bitsPerRGB) - 1;
11211ab64890Smrg
11221ab64890Smrg    ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
11231ab64890Smrg    answer->intensity = key->intensity;
11241ab64890Smrg    target = hi->value - lo->value;
11251ab64890Smrg    target *= ratio;
11261ab64890Smrg    target += lo->value;
11271ab64890Smrg
11281ab64890Smrg    /*
11291ab64890Smrg     * Ok now, lets find the closest in respects to bits per RGB
11301ab64890Smrg     */
11311ab64890Smrg    up = ((target >> shift) * 0xFFFF) / max_color;
11321ab64890Smrg    if (up < target) {
11331ab64890Smrg	down = up;
11341ab64890Smrg	up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
11351ab64890Smrg    } else {
11361ab64890Smrg	down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
11371ab64890Smrg    }
11381ab64890Smrg    answer->value = ((up - target) < (target - down) ? up : down);
11391ab64890Smrg    answer->value &= MASK[bitsPerRGB];
11401ab64890Smrg    return (XcmsSuccess);
11411ab64890Smrg}
11421ab64890Smrg
11431ab64890Smrg
11441ab64890Smrg
11451ab64890Smrgtypedef int (*comparProcp)(
11461ab64890Smrg    char *p1,
11471ab64890Smrg    char *p2);
11481ab64890Smrgtypedef int (*interpolProcp)(
11491ab64890Smrg    char *key,
11501ab64890Smrg    char *lo,
11511ab64890Smrg    char *hi,
11521ab64890Smrg    char *answer,
11531ab64890Smrg    int bitsPerRGB);
11541ab64890Smrg
11551ab64890Smrg/*
11561ab64890Smrg *	NAME
11571ab64890Smrg *		_XcmsTableSearch
11581ab64890Smrg *
11591ab64890Smrg *	SYNOPSIS
11601ab64890Smrg */
11611ab64890Smrgstatic int
11621ab64890Smrg_XcmsTableSearch(
11631ab64890Smrg    char *key,
11641ab64890Smrg    int bitsPerRGB,
11651ab64890Smrg    char *base,
11661ab64890Smrg    unsigned nel,
11671ab64890Smrg    unsigned nKeyPtrSize,
11681ab64890Smrg    int (*compar)(
11691ab64890Smrg        char *p1,
11701ab64890Smrg        char *p2),
11711ab64890Smrg    int (*interpol)(
11721ab64890Smrg        char *key,
11731ab64890Smrg        char *lo,
11741ab64890Smrg        char *hi,
11751ab64890Smrg        char *answer,
11761ab64890Smrg        int bitsPerRGB),
11771ab64890Smrg    char *answer)
11781ab64890Smrg
11791ab64890Smrg/*
11801ab64890Smrg *	DESCRIPTION
11811ab64890Smrg *		A binary search through the specificied table.
11821ab64890Smrg *
11831ab64890Smrg *	RETURNS
11841ab64890Smrg *		Returns 0 if failed; otherwise non-zero.
11851ab64890Smrg *
11861ab64890Smrg */
11871ab64890Smrg{
11881ab64890Smrg    char *hi, *lo, *mid, *last;
11891ab64890Smrg    int result;
11901ab64890Smrg
11911ab64890Smrg    last = hi = base + ((nel - 1) * nKeyPtrSize);
11921ab64890Smrg    mid = lo = base;
11931ab64890Smrg
11941ab64890Smrg    /* use only the significants bits, then scale into 16 bits */
11951ab64890Smrg    ((IntensityRec *)key)->value = ((unsigned long)
11961ab64890Smrg	    (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
11971ab64890Smrg	    / ((1 << bitsPerRGB) - 1);
11981ab64890Smrg
11991ab64890Smrg    /* Special case so that zero intensity always maps to zero value */
12001ab64890Smrg    if ((*compar) (key,lo) <= 0) {
12011ab64890Smrg	memcpy (answer, lo, nKeyPtrSize);
12021ab64890Smrg	((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
12031ab64890Smrg	return XcmsSuccess;
12041ab64890Smrg    }
12051ab64890Smrg    while (mid != last) {
12061ab64890Smrg	last = mid;
12071ab64890Smrg	mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
12081ab64890Smrg	result = (*compar) (key, mid);
12091ab64890Smrg	if (result == 0) {
12101ab64890Smrg
12111ab64890Smrg	    memcpy(answer, mid, nKeyPtrSize);
12121ab64890Smrg	    ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
12131ab64890Smrg	    return (XcmsSuccess);
12141ab64890Smrg	} else if (result < 0) {
12151ab64890Smrg	    hi = mid;
12161ab64890Smrg	} else {
12171ab64890Smrg	    lo = mid;
12181ab64890Smrg	}
12191ab64890Smrg    }
12201ab64890Smrg
12211ab64890Smrg    /*
12221ab64890Smrg     * If we got to here, we didn't find a solution, so we
12231ab64890Smrg     * need to apply interpolation.
12241ab64890Smrg     */
12251ab64890Smrg    return ((*interpol)(key, lo, hi, answer, bitsPerRGB));
12261ab64890Smrg}
12271ab64890Smrg
12281ab64890Smrg
12291ab64890Smrg/*
12301ab64890Smrg *      NAME
12311ab64890Smrg *		_XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
12321ab64890Smrg *
12331ab64890Smrg *	SYNOPSIS
12341ab64890Smrg */
12351ab64890Smrgstatic void _XcmsMatVec(
12361ab64890Smrg    XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut)
12371ab64890Smrg/*
12381ab64890Smrg *      DESCRIPTION
123961b2299dSmrg *		Multiply the passed vector by the passed matrix to return a
12401ab64890Smrg *		vector. Matrix is 3x3, vectors are of length 3.
12411ab64890Smrg *
12421ab64890Smrg *	RETURNS
12431ab64890Smrg *		void
12441ab64890Smrg */
12451ab64890Smrg{
12461ab64890Smrg    int i, j;
12471ab64890Smrg
12481ab64890Smrg    for (i = 0; i < 3; i++) {
12491ab64890Smrg	pOut[i] = 0.0;
12501ab64890Smrg	for (j = 0; j < 3; j++)
12511ab64890Smrg	    pOut[i] += *(pMat+(i*3)+j) * pIn[j];
12521ab64890Smrg    }
12531ab64890Smrg}
12541ab64890Smrg
12551ab64890Smrg
12561ab64890Smrg/************************************************************************
12571ab64890Smrg *									*
12581ab64890Smrg *			 PUBLIC ROUTINES				*
12591ab64890Smrg *									*
12601ab64890Smrg ************************************************************************/
12611ab64890Smrg
12621ab64890Smrg
12631ab64890Smrg/*
12641ab64890Smrg *	NAME
12651ab64890Smrg *		XcmsLRGB_RGB_ParseString
12661ab64890Smrg *
12671ab64890Smrg *	SYNOPSIS
12681ab64890Smrg */
12691ab64890Smrgstatic int
12701ab64890SmrgXcmsLRGB_RGB_ParseString(
12711ab64890Smrg    register char *spec,
12721ab64890Smrg    XcmsColor *pColor)
12731ab64890Smrg/*
12741ab64890Smrg *	DESCRIPTION
12751ab64890Smrg *		This routines takes a string and attempts to convert
12761ab64890Smrg *		it into a XcmsColor structure with XcmsRGBFormat.
12771ab64890Smrg *
12781ab64890Smrg *	RETURNS
12791ab64890Smrg *		0 if failed, non-zero otherwise.
12801ab64890Smrg */
12811ab64890Smrg{
12821ab64890Smrg    register int n, i;
12831ab64890Smrg    unsigned short r, g, b;
12841ab64890Smrg    char c;
12851ab64890Smrg    char *pchar;
12861ab64890Smrg    unsigned short *pShort;
12871ab64890Smrg
12881ab64890Smrg    /*
12891ab64890Smrg     * Check for old # format
12901ab64890Smrg     */
12911ab64890Smrg    if (*spec == '#') {
12921ab64890Smrg	/*
12931ab64890Smrg	 * Attempt to parse the value portion.
12941ab64890Smrg	 */
12951ab64890Smrg	spec++;
12961ab64890Smrg	n = strlen(spec);
12971ab64890Smrg	if (n != 3 && n != 6 && n != 9 && n != 12) {
12981ab64890Smrg	    return(XcmsFailure);
12991ab64890Smrg	}
13001ab64890Smrg
13011ab64890Smrg	n /= 3;
13021ab64890Smrg	g = b = 0;
13031ab64890Smrg	do {
13041ab64890Smrg	    r = g;
13051ab64890Smrg	    g = b;
13061ab64890Smrg	    b = 0;
13071ab64890Smrg	    for (i = n; --i >= 0; ) {
13081ab64890Smrg		c = *spec++;
13091ab64890Smrg		b <<= 4;
13101ab64890Smrg		if (c >= '0' && c <= '9')
13111ab64890Smrg		    b |= c - '0';
13121ab64890Smrg		/* assume string in lowercase
13131ab64890Smrg		else if (c >= 'A' && c <= 'F')
13141ab64890Smrg		    b |= c - ('A' - 10);
13151ab64890Smrg		*/
13161ab64890Smrg		else if (c >= 'a' && c <= 'f')
13171ab64890Smrg		    b |= c - ('a' - 10);
13181ab64890Smrg		else return (XcmsFailure);
13191ab64890Smrg	    }
13201ab64890Smrg	} while (*spec != '\0');
13211ab64890Smrg
13221ab64890Smrg	/*
13231ab64890Smrg	 * Succeeded !
13241ab64890Smrg	 */
13251ab64890Smrg	n <<= 2;
13261ab64890Smrg	n = 16 - n;
13271ab64890Smrg	/* shift instead of scale, to match old broken semantics */
13281ab64890Smrg	pColor->spec.RGB.red = r << n;
13291ab64890Smrg	pColor->spec.RGB.green = g << n;
13301ab64890Smrg	pColor->spec.RGB.blue =  b << n;
13311ab64890Smrg    } else {
13321ab64890Smrg	if ((pchar = strchr(spec, ':')) == NULL) {
13331ab64890Smrg	    return(XcmsFailure);
13341ab64890Smrg	}
13351ab64890Smrg	n = (int)(pchar - spec);
13361ab64890Smrg
13371ab64890Smrg	/*
13381ab64890Smrg	 * Check for proper prefix.
13391ab64890Smrg	 */
13401ab64890Smrg	if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
13411ab64890Smrg	    return(XcmsFailure);
13421ab64890Smrg	}
13431ab64890Smrg
13441ab64890Smrg	/*
13451ab64890Smrg	 * Attempt to parse the value portion.
13461ab64890Smrg	 */
13471ab64890Smrg	spec += (n + 1);
13481ab64890Smrg	pShort = &pColor->spec.RGB.red;
13491ab64890Smrg	for (i = 0; i < 3; i++, pShort++, spec++) {
13501ab64890Smrg	    n = 0;
13511ab64890Smrg	    *pShort = 0;
13521ab64890Smrg	    while (*spec != '/' && *spec != '\0') {
13531ab64890Smrg		if (++n > 4) {
13541ab64890Smrg		    return(XcmsFailure);
13551ab64890Smrg		}
13561ab64890Smrg		c = *spec++;
13571ab64890Smrg		*pShort <<= 4;
13581ab64890Smrg		if (c >= '0' && c <= '9')
13591ab64890Smrg		    *pShort |= c - '0';
13601ab64890Smrg		/* assume string in lowercase
13611ab64890Smrg		else if (c >= 'A' && c <= 'F')
13621ab64890Smrg		    *pShort |= c - ('A' - 10);
13631ab64890Smrg		*/
13641ab64890Smrg		else if (c >= 'a' && c <= 'f')
13651ab64890Smrg		    *pShort |= c - ('a' - 10);
13661ab64890Smrg		else return (XcmsFailure);
13671ab64890Smrg	    }
13681ab64890Smrg	    if (n == 0)
13691ab64890Smrg		return (XcmsFailure);
13701ab64890Smrg	    if (n < 4) {
13711ab64890Smrg		*pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
13721ab64890Smrg	    }
13731ab64890Smrg	}
13741ab64890Smrg    }
13751ab64890Smrg    pColor->format = XcmsRGBFormat;
13761ab64890Smrg    pColor->pixel = 0;
13771ab64890Smrg    return (XcmsSuccess);
13781ab64890Smrg}
13791ab64890Smrg
13801ab64890Smrg
13811ab64890Smrg/*
13821ab64890Smrg *	NAME
13831ab64890Smrg *		XcmsLRGB_RGBi_ParseString
13841ab64890Smrg *
13851ab64890Smrg *	SYNOPSIS
13861ab64890Smrg */
13871ab64890Smrgstatic int
13881ab64890SmrgXcmsLRGB_RGBi_ParseString(
13891ab64890Smrg    register char *spec,
13901ab64890Smrg    XcmsColor *pColor)
13911ab64890Smrg/*
13921ab64890Smrg *	DESCRIPTION
13931ab64890Smrg *		This routines takes a string and attempts to convert
13941ab64890Smrg *		it into a XcmsColor structure with XcmsRGBiFormat.
13951ab64890Smrg *		The assumed RGBi string syntax is:
13961ab64890Smrg *		    RGBi:<r>/<g>/<b>
13971ab64890Smrg *		Where r, g, and b are in string input format for floats
13981ab64890Smrg *		consisting of:
13991ab64890Smrg *		    a. an optional sign
14001ab64890Smrg *		    b. a string of numbers possibly containing a decimal point,
14011ab64890Smrg *		    c. an optional exponent field containing an 'E' or 'e'
14021ab64890Smrg *			followed by a possibly signed integer string.
14031ab64890Smrg *
14041ab64890Smrg *	RETURNS
14051ab64890Smrg *		0 if failed, non-zero otherwise.
14061ab64890Smrg */
14071ab64890Smrg{
14081ab64890Smrg    int n;
14091ab64890Smrg    char *pchar;
14101ab64890Smrg
14111ab64890Smrg    if ((pchar = strchr(spec, ':')) == NULL) {
14121ab64890Smrg	return(XcmsFailure);
14131ab64890Smrg    }
14141ab64890Smrg    n = (int)(pchar - spec);
14151ab64890Smrg
14161ab64890Smrg    /*
14171ab64890Smrg     * Check for proper prefix.
14181ab64890Smrg     */
14191ab64890Smrg    if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
14201ab64890Smrg	return(XcmsFailure);
14211ab64890Smrg    }
14221ab64890Smrg
14231ab64890Smrg    /*
14241ab64890Smrg     * Attempt to parse the value portion.
14251ab64890Smrg     */
14261ab64890Smrg    if (sscanf(spec + n + 1, "%lf/%lf/%lf",
14271ab64890Smrg	    &pColor->spec.RGBi.red,
14281ab64890Smrg	    &pColor->spec.RGBi.green,
14291ab64890Smrg	    &pColor->spec.RGBi.blue) != 3) {
14301ab64890Smrg        char *s; /* Maybe failed due to locale */
14311ab64890Smrg        int f;
14321ab64890Smrg        if ((s = strdup(spec))) {
14331ab64890Smrg            for (f = 0; s[f]; ++f)
14341ab64890Smrg                if (s[f] == '.')
14351ab64890Smrg                    s[f] = ',';
14361ab64890Smrg                else if (s[f] == ',')
14371ab64890Smrg                    s[f] = '.';
14381ab64890Smrg	    if (sscanf(s + n + 1, "%lf/%lf/%lf",
14391ab64890Smrg		       &pColor->spec.RGBi.red,
14401ab64890Smrg		       &pColor->spec.RGBi.green,
14411ab64890Smrg		       &pColor->spec.RGBi.blue) != 3) {
14421ab64890Smrg                free(s);
14431ab64890Smrg                return(XcmsFailure);
14441ab64890Smrg            }
14451ab64890Smrg            free(s);
14461ab64890Smrg        } else
14471ab64890Smrg	    return(XcmsFailure);
14481ab64890Smrg    }
14491ab64890Smrg
14501ab64890Smrg    /*
14511ab64890Smrg     * Succeeded !
14521ab64890Smrg     */
14531ab64890Smrg    pColor->format = XcmsRGBiFormat;
14541ab64890Smrg    pColor->pixel = 0;
14551ab64890Smrg    return (XcmsSuccess);
14561ab64890Smrg}
14571ab64890Smrg
14581ab64890Smrg
14591ab64890Smrg/*
14601ab64890Smrg *	NAME
14611ab64890Smrg *		XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
14621ab64890Smrg *
14631ab64890Smrg *	SYNOPSIS
14641ab64890Smrg */
14651ab64890Smrg/* ARGSUSED */
146661b2299dSmrgStatus
14671ab64890SmrgXcmsCIEXYZToRGBi(
14681ab64890Smrg    XcmsCCC ccc,
14691ab64890Smrg    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
14701ab64890Smrg    unsigned int nColors,	/* Number of colors			*/
14711ab64890Smrg    Bool *pCompressed)		/* pointer to an array of Bool		*/
14721ab64890Smrg/*
14731ab64890Smrg *	DESCRIPTION
14741ab64890Smrg *		Converts color specifications in an array of XcmsColor
14751ab64890Smrg *		structures from RGB format to RGBi format.
14761ab64890Smrg *
14771ab64890Smrg *	RETURNS
14781ab64890Smrg *		XcmsFailure if failed,
14791ab64890Smrg *		XcmsSuccess if succeeded without gamut compression.
14801ab64890Smrg *		XcmsSuccessWithCompression if succeeded with gamut
14811ab64890Smrg *			compression.
14821ab64890Smrg */
14831ab64890Smrg{
14841ab64890Smrg    LINEAR_RGB_SCCData *pScreenData;
14851ab64890Smrg    XcmsFloat tmp[3];
14861ab64890Smrg    int hasCompressed = 0;
14871ab64890Smrg    unsigned int i;
14881ab64890Smrg    XcmsColor *pColor = pXcmsColors_in_out;
14891ab64890Smrg
14901ab64890Smrg    if (ccc == NULL) {
14911ab64890Smrg	return(XcmsFailure);
14921ab64890Smrg    }
14931ab64890Smrg
14941ab64890Smrg    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
14951ab64890Smrg
14961ab64890Smrg    /*
14971ab64890Smrg     * XcmsColors should be White Point Adjusted, if necessary, by now!
14981ab64890Smrg     */
14991ab64890Smrg
15001ab64890Smrg    /*
15011ab64890Smrg     * NEW!!! for extended gamut compression
15021ab64890Smrg     *
15031ab64890Smrg     * 1. Need to zero out pCompressed
15041ab64890Smrg     *
15051ab64890Smrg     * 2. Need to save initial address of pColor
15061ab64890Smrg     *
15071ab64890Smrg     * 3. Need to save initial address of pCompressed
15081ab64890Smrg     */
15091ab64890Smrg
15101ab64890Smrg    for (i = 0; i < nColors; i++) {
15111ab64890Smrg
15121ab64890Smrg	/* Make sure format is XcmsCIEXYZFormat */
15131ab64890Smrg	if (pColor->format != XcmsCIEXYZFormat) {
15141ab64890Smrg	    return(XcmsFailure);
15151ab64890Smrg	}
15161ab64890Smrg
15171ab64890Smrg	/* Multiply [A]-1 * [XYZ] to get RGB intensity */
15181ab64890Smrg	_XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
15191ab64890Smrg		(XcmsFloat *) &pColor->spec, tmp);
15201ab64890Smrg
15211ab64890Smrg	if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
15221ab64890Smrg	    (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
15231ab64890Smrg
15241ab64890Smrg	    /*
15251ab64890Smrg	     * RGBi out of screen's gamut
15261ab64890Smrg	     */
15271ab64890Smrg
15281ab64890Smrg	    if (ccc->gamutCompProc == NULL) {
15291ab64890Smrg		/*
15301ab64890Smrg		 * Aha!! Here's that little trick that will allow
15311ab64890Smrg		 * gamut compression routines to get the out of bound
153261b2299dSmrg		 * RGBi.
15331ab64890Smrg		 */
15341ab64890Smrg		memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
15351ab64890Smrg		pColor->format = XcmsRGBiFormat;
15361ab64890Smrg		return(XcmsFailure);
15371ab64890Smrg	    } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
15381ab64890Smrg		    i, pCompressed) == 0) {
15391ab64890Smrg		return(XcmsFailure);
15401ab64890Smrg	    }
15411ab64890Smrg
15421ab64890Smrg	    /*
15431ab64890Smrg	     * The gamut compression function should return colors in CIEXYZ
15441ab64890Smrg	     *	Also check again to if the new color is within gamut.
15451ab64890Smrg	     */
15461ab64890Smrg	    if (pColor->format != XcmsCIEXYZFormat) {
15471ab64890Smrg		return(XcmsFailure);
15481ab64890Smrg	    }
15491ab64890Smrg	    _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
15501ab64890Smrg		    (XcmsFloat *) &pColor->spec, tmp);
15511ab64890Smrg	    if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
15521ab64890Smrg		(MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
15531ab64890Smrg		return(XcmsFailure);
15541ab64890Smrg	    }
15551ab64890Smrg	    hasCompressed++;
15561ab64890Smrg	}
15571ab64890Smrg	memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
15581ab64890Smrg	/* These if statements are done to ensure the fudge factor is */
15591ab64890Smrg	/* is taken into account. */
15601ab64890Smrg	if (pColor->spec.RGBi.red < 0.0) {
15611ab64890Smrg		pColor->spec.RGBi.red = 0.0;
15621ab64890Smrg	} else if (pColor->spec.RGBi.red > 1.0) {
15631ab64890Smrg		pColor->spec.RGBi.red = 1.0;
15641ab64890Smrg	}
15651ab64890Smrg	if (pColor->spec.RGBi.green < 0.0) {
15661ab64890Smrg		pColor->spec.RGBi.green = 0.0;
15671ab64890Smrg	} else if (pColor->spec.RGBi.green > 1.0) {
15681ab64890Smrg		pColor->spec.RGBi.green = 1.0;
15691ab64890Smrg	}
15701ab64890Smrg	if (pColor->spec.RGBi.blue < 0.0) {
15711ab64890Smrg		pColor->spec.RGBi.blue = 0.0;
15721ab64890Smrg	} else if (pColor->spec.RGBi.blue > 1.0) {
15731ab64890Smrg		pColor->spec.RGBi.blue = 1.0;
15741ab64890Smrg	}
15751ab64890Smrg	(pColor++)->format = XcmsRGBiFormat;
15761ab64890Smrg    }
15771ab64890Smrg    return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
15781ab64890Smrg}
15791ab64890Smrg
15801ab64890Smrg
15811ab64890Smrg/*
15821ab64890Smrg *	NAME
15831ab64890Smrg *		LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
15841ab64890Smrg *
15851ab64890Smrg *	SYNOPSIS
15861ab64890Smrg */
15871ab64890Smrg/* ARGSUSED */
158861b2299dSmrgStatus
15891ab64890SmrgXcmsRGBiToCIEXYZ(
15901ab64890Smrg    XcmsCCC ccc,
15911ab64890Smrg    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
15921ab64890Smrg    unsigned int nColors,	/* Number of colors			*/
15931ab64890Smrg    Bool *pCompressed)		/* pointer to a bit array		*/
15941ab64890Smrg/*
15951ab64890Smrg *	DESCRIPTION
15961ab64890Smrg *		Converts color specifications in an array of XcmsColor
15971ab64890Smrg *		structures from RGBi format to CIEXYZ format.
15981ab64890Smrg *
15991ab64890Smrg *	RETURNS
16001ab64890Smrg *		XcmsFailure if failed,
16011ab64890Smrg *		XcmsSuccess if succeeded.
16021ab64890Smrg */
16031ab64890Smrg{
16041ab64890Smrg    LINEAR_RGB_SCCData *pScreenData;
16051ab64890Smrg    XcmsFloat tmp[3];
16061ab64890Smrg
16071ab64890Smrg    /*
16081ab64890Smrg     * pCompressed ignored in this function.
16091ab64890Smrg     */
16101ab64890Smrg
16111ab64890Smrg    if (ccc == NULL) {
16121ab64890Smrg	return(XcmsFailure);
16131ab64890Smrg    }
16141ab64890Smrg
16151ab64890Smrg    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
16161ab64890Smrg
16171ab64890Smrg    /*
16181ab64890Smrg     * XcmsColors should be White Point Adjusted, if necessary, by now!
16191ab64890Smrg     */
16201ab64890Smrg
16211ab64890Smrg    while (nColors--) {
16221ab64890Smrg
16231ab64890Smrg	/* Multiply [A]-1 * [XYZ] to get RGB intensity */
16241ab64890Smrg	_XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
16251ab64890Smrg		(XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
16261ab64890Smrg
16271ab64890Smrg	memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp));
16281ab64890Smrg	(pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
16291ab64890Smrg    }
16301ab64890Smrg    return(XcmsSuccess);
16311ab64890Smrg}
16321ab64890Smrg
16331ab64890Smrg
16341ab64890Smrg/*
16351ab64890Smrg *	NAME
16361ab64890Smrg *		XcmsRGBiToRGB
16371ab64890Smrg *
16381ab64890Smrg *	SYNOPSIS
16391ab64890Smrg */
16401ab64890Smrg/* ARGSUSED */
164161b2299dSmrgStatus
16421ab64890SmrgXcmsRGBiToRGB(
16431ab64890Smrg    XcmsCCC ccc,
16441ab64890Smrg    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
16451ab64890Smrg    unsigned int nColors,	/* Number of colors			*/
16461ab64890Smrg    Bool *pCompressed)		/* pointer to a bit array		*/
16471ab64890Smrg/*
16481ab64890Smrg *	DESCRIPTION
16491ab64890Smrg *		Converts color specifications in an array of XcmsColor
16501ab64890Smrg *		structures from RGBi format to RGB format.
16511ab64890Smrg *
16521ab64890Smrg *	RETURNS
16531ab64890Smrg *		XcmsFailure if failed,
16541ab64890Smrg *		XcmsSuccess if succeeded without gamut compression.
16551ab64890Smrg *		XcmsSuccessWithCompression if succeeded with gamut
16561ab64890Smrg *			compression.
16571ab64890Smrg */
16581ab64890Smrg{
16591ab64890Smrg    LINEAR_RGB_SCCData *pScreenData;
16601ab64890Smrg    XcmsRGB tmpRGB;
16611ab64890Smrg    IntensityRec keyIRec, answerIRec;
16621ab64890Smrg
16631ab64890Smrg    /*
16641ab64890Smrg     * pCompressed ignored in this function.
16651ab64890Smrg     */
16661ab64890Smrg
16671ab64890Smrg    if (ccc == NULL) {
16681ab64890Smrg	return(XcmsFailure);
16691ab64890Smrg    }
16701ab64890Smrg
16711ab64890Smrg    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
16721ab64890Smrg
16731ab64890Smrg    while (nColors--) {
16741ab64890Smrg
16751ab64890Smrg	/* Make sure format is XcmsRGBiFormat */
16761ab64890Smrg	if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
16771ab64890Smrg	    return(XcmsFailure);
16781ab64890Smrg	}
16791ab64890Smrg
16801ab64890Smrg	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
16811ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
16821ab64890Smrg		(char *)pScreenData->pRedTbl->pBase,
16831ab64890Smrg		(unsigned)pScreenData->pRedTbl->nEntries,
16841ab64890Smrg		(unsigned)sizeof(IntensityRec),
16851ab64890Smrg		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
16861ab64890Smrg	    return(XcmsFailure);
16871ab64890Smrg	}
16881ab64890Smrg	tmpRGB.red = answerIRec.value;
16891ab64890Smrg
16901ab64890Smrg	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
16911ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
16921ab64890Smrg		(char *)pScreenData->pGreenTbl->pBase,
16931ab64890Smrg		(unsigned)pScreenData->pGreenTbl->nEntries,
16941ab64890Smrg		(unsigned)sizeof(IntensityRec),
16951ab64890Smrg		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
16961ab64890Smrg	    return(XcmsFailure);
16971ab64890Smrg	}
16981ab64890Smrg	tmpRGB.green = answerIRec.value;
16991ab64890Smrg
17001ab64890Smrg	keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
17011ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
17021ab64890Smrg		(char *)pScreenData->pBlueTbl->pBase,
17031ab64890Smrg		(unsigned)pScreenData->pBlueTbl->nEntries,
17041ab64890Smrg		(unsigned)sizeof(IntensityRec),
17051ab64890Smrg		(comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
17061ab64890Smrg	    return(XcmsFailure);
17071ab64890Smrg	}
17081ab64890Smrg	tmpRGB.blue = answerIRec.value;
17091ab64890Smrg
17101ab64890Smrg	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
17111ab64890Smrg	(pXcmsColors_in_out++)->format = XcmsRGBFormat;
17121ab64890Smrg    }
17131ab64890Smrg    return(XcmsSuccess);
17141ab64890Smrg}
17151ab64890Smrg
17161ab64890Smrg
17171ab64890Smrg/*
17181ab64890Smrg *	NAME
17191ab64890Smrg *		XcmsRGBToRGBi
17201ab64890Smrg *
17211ab64890Smrg *	SYNOPSIS
17221ab64890Smrg */
17231ab64890Smrg/* ARGSUSED */
172461b2299dSmrgStatus
17251ab64890SmrgXcmsRGBToRGBi(
17261ab64890Smrg    XcmsCCC ccc,
17271ab64890Smrg    XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert 	*/
17281ab64890Smrg    unsigned int nColors,	/* Number of colors			*/
17291ab64890Smrg    Bool *pCompressed)		/* pointer to a bit array		*/
17301ab64890Smrg/*
17311ab64890Smrg *	DESCRIPTION
17321ab64890Smrg *		Converts color specifications in an array of XcmsColor
17331ab64890Smrg *		structures from RGB format to RGBi format.
17341ab64890Smrg *
17351ab64890Smrg *	RETURNS
17361ab64890Smrg *		XcmsFailure if failed,
17371ab64890Smrg *		XcmsSuccess if succeeded.
17381ab64890Smrg */
17391ab64890Smrg{
17401ab64890Smrg    LINEAR_RGB_SCCData *pScreenData;
17411ab64890Smrg    XcmsRGBi tmpRGBi;
17421ab64890Smrg    IntensityRec keyIRec, answerIRec;
17431ab64890Smrg
17441ab64890Smrg    /*
17451ab64890Smrg     * pCompressed ignored in this function.
17461ab64890Smrg     */
17471ab64890Smrg
17481ab64890Smrg    if (ccc == NULL) {
17491ab64890Smrg	return(XcmsFailure);
17501ab64890Smrg    }
17511ab64890Smrg
17521ab64890Smrg    pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
17531ab64890Smrg
17541ab64890Smrg    while (nColors--) {
17551ab64890Smrg
17561ab64890Smrg	/* Make sure format is XcmsRGBFormat */
17571ab64890Smrg	if (pXcmsColors_in_out->format != XcmsRGBFormat) {
17581ab64890Smrg	    return(XcmsFailure);
17591ab64890Smrg	}
17601ab64890Smrg
17611ab64890Smrg	keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
17621ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
17631ab64890Smrg		(char *)pScreenData->pRedTbl->pBase,
17641ab64890Smrg		(unsigned)pScreenData->pRedTbl->nEntries,
17651ab64890Smrg		(unsigned)sizeof(IntensityRec),
17661ab64890Smrg		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
17671ab64890Smrg	    return(XcmsFailure);
17681ab64890Smrg	}
17691ab64890Smrg	tmpRGBi.red = answerIRec.intensity;
17701ab64890Smrg
17711ab64890Smrg	keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
17721ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
17731ab64890Smrg		(char *)pScreenData->pGreenTbl->pBase,
17741ab64890Smrg		(unsigned)pScreenData->pGreenTbl->nEntries,
17751ab64890Smrg		(unsigned)sizeof(IntensityRec),
17761ab64890Smrg		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
17771ab64890Smrg	    return(XcmsFailure);
17781ab64890Smrg	}
17791ab64890Smrg	tmpRGBi.green = answerIRec.intensity;
17801ab64890Smrg
17811ab64890Smrg	keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
17821ab64890Smrg	if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
17831ab64890Smrg		(char *)pScreenData->pBlueTbl->pBase,
17841ab64890Smrg		(unsigned)pScreenData->pBlueTbl->nEntries,
17851ab64890Smrg		(unsigned)sizeof(IntensityRec),
17861ab64890Smrg		(comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
17871ab64890Smrg	    return(XcmsFailure);
17881ab64890Smrg	}
17891ab64890Smrg	tmpRGBi.blue = answerIRec.intensity;
17901ab64890Smrg
17911ab64890Smrg	memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
17921ab64890Smrg	(pXcmsColors_in_out++)->format = XcmsRGBiFormat;
17931ab64890Smrg    }
17941ab64890Smrg    return(XcmsSuccess);
17951ab64890Smrg}
17961ab64890Smrg
17971ab64890Smrg/*
17981ab64890Smrg *	NAME
17991ab64890Smrg *		_XcmsInitScrnDefaultInfo
18001ab64890Smrg *
18011ab64890Smrg *	SYNOPSIS
18021ab64890Smrg */
18031ab64890Smrg/* ARGSUSED */
18041ab64890Smrgint
18051ab64890Smrg_XcmsLRGB_InitScrnDefault(
18061ab64890Smrg    Display *dpy,
18071ab64890Smrg    int screenNumber,
18081ab64890Smrg    XcmsPerScrnInfo *pPerScrnInfo)
18091ab64890Smrg/*
18101ab64890Smrg *	DESCRIPTION
18111ab64890Smrg *		Given a display and screen number, this routine attempts
18121ab64890Smrg *		to initialize the Xcms per Screen Info structure
18131ab64890Smrg *		(XcmsPerScrnInfo) with defaults.
18141ab64890Smrg *
18151ab64890Smrg *	RETURNS
18161ab64890Smrg *		Returns zero if initialization failed; non-zero otherwise.
18171ab64890Smrg */
18181ab64890Smrg{
18191ab64890Smrg    pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
18201ab64890Smrg    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
18211ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
18221ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
18231ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
18241ab64890Smrg    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
18251ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
18261ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
18271ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
18281ab64890Smrg    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
18291ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
18301ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
18311ab64890Smrg		Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
18321ab64890Smrg    if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
18331ab64890Smrg	    || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
18341ab64890Smrg	pPerScrnInfo->screenData = (XPointer)NULL;
18351ab64890Smrg	pPerScrnInfo->state = XcmsInitNone;
18361ab64890Smrg	return(0);
18371ab64890Smrg    }
18381ab64890Smrg    pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
18391ab64890Smrg    pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
18401ab64890Smrg    pPerScrnInfo->screenWhitePt.pixel = 0;
18411ab64890Smrg    pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
18421ab64890Smrg    pPerScrnInfo->state = XcmsInitFailure; /* default initialization */
18431ab64890Smrg    return(1);
18441ab64890Smrg}
1845