aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/xcms/LRGB.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/xcms/LRGB.c')
-rw-r--r--libX11/src/xcms/LRGB.c3689
1 files changed, 1844 insertions, 1845 deletions
diff --git a/libX11/src/xcms/LRGB.c b/libX11/src/xcms/LRGB.c
index 750c4924e..8f1394b7f 100644
--- a/libX11/src/xcms/LRGB.c
+++ b/libX11/src/xcms/LRGB.c
@@ -1,1845 +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)) {
- Xfree ((char *)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);
+}