home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
evbl0627.zip
/
everblue_20010627.zip
/
x11
/
Xcms_LRGB.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-02
|
50KB
|
1,833 lines
/* $XConsortium: LRGB.c,v 1.32 95/06/08 23:20:39 gildea Exp $" */
/*
* 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
*
*/
#include <stdio.h>
#include "Xlib_private.h"
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include "Xcmsint.h"
#ifdef __STDC__
#define Const const
#else
#define Const /**/
#endif
/*
* EXTERNS
* External declarations required locally to this package
* that are not already declared in any of the included header
* files (external includes or internal includes).
*/
extern char _XcmsRGB_prefix[];
extern char _XcmsRGBi_prefix[];
extern unsigned long _XcmsGetElement();
extern void _XcmsFreeIntensityMaps();
/*
* 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();
static int LINEAR_RGB_InitSCCData();
static int XcmsLRGB_RGB_ParseString();
static int XcmsLRGB_RGBi_ParseString();
Status _XcmsGetTableType0();
Status _XcmsGetTableType1();
/*
* 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[] = {
XcmsRGBToRGBi,
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[] = {
XcmsCIEXYZToRGBi,
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[] = {
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[] = {
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(dpy, screenNumber, pPerScrnInfo)
Display *dpy;
int screenNumber;
XcmsPerScrnInfo *pPerScrnInfo;
/*
* DESCRIPTION
*
* RETURNS
* XcmsFailure if failed.
* XcmsSuccess if succeeded.
*
*/
{
DBUG_ENTER("LINEAR_RGB_InitSCCData")
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)))) {
DBUG_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) {
Xfree ((char *)property_return);
goto FreeSCCData;
}
count = 3;
break;
case 16:
/*
* Must have at least:
* VisualID0
* VisualID3
* type
* count
* length
* intensity1
* intensity2
*/
if (nitems < 7) {
Xfree ((char *)property_return);
goto FreeSCCData;
}
count = 1;
break;
case 32:
/*
* Must have at least:
* VisualID0
* type
* count
* length
* intensity1
* intensity2
*/
if (nitems < 6) {
Xfree ((char *)property_return);
goto FreeSCCData;
}
count = 0;
break;
default:
Xfree ((char *)property_return);
goto FreeSCCData;
}
/*
* 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)))) {
DBUG_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);
DBUG_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 FreeSCCData;
}
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 FreeSCCData;
}
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 FreeBlueTblElements;
}
if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
&nitems) == XcmsFailure) {
goto FreeBlueTbl;
}
}
} else {
Xfree ((char *)property_return);
goto FreeSCCData;
}
#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;
DBUG_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);
FreeSCCData:
Xfree((char *)pScreenData);
pPerScrnInfo->state = XcmsInitNone;
DBUG_RETURN(XcmsFailure);
}
/*
* NAME
* LINEAR_RGB_FreeSCCData()
*
* SYNOPSIS
*/
static void
LINEAR_RGB_FreeSCCData(pScreenDataTemp)
XPointer pScreenDataTemp;
/*
* DESCRIPTION
*
* RETURNS
* 0 if failed.
* 1 if succeeded with no modifications.
*
*/
{
DBUG_ENTER("LINEAR_RGB_FreeSCCData")
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);
}
DBUG_VOID_RETURN;
}
/************************************************************************
* *
* API PRIVATE ROUTINES *
* *
************************************************************************/
/*
* NAME
* _XcmsGetTableType0
*
* SYNOPSIS
*/
Status
_XcmsGetTableType0(pTbl, format, pChar, pCount)
IntensityTbl *pTbl;
int format;
char **pChar;
unsigned long *pCount;
/*
* DESCRIPTION
*
* RETURNS
* XcmsFailure if failed.
* XcmsSuccess if succeeded.
*
*/
{
DBUG_ENTER("_XcmsGetTableType0")
unsigned int nElements;
IntensityRec *pIRec;
nElements = pTbl->nEntries =
_XcmsGetElement(format, pChar, pCount) + 1;
if (!(pIRec = pTbl->pBase = (IntensityRec *)
Xcalloc (nElements, sizeof(IntensityRec)))) {
DBUG_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:
DBUG_RETURN(XcmsFailure);
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* _XcmsGetTableType1
*
* SYNOPSIS
*/
Status
_XcmsGetTableType1(pTbl, format, pChar, pCount)
IntensityTbl *pTbl;
int format;
char **pChar;
unsigned long *pCount;
/*
* DESCRIPTION
*
* RETURNS
* XcmsFailure if failed.
* XcmsSuccess if succeeded.
*
*/
{
DBUG_ENTER("_XcmsGetTableType1")
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)))) {
DBUG_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:
DBUG_RETURN(XcmsFailure);
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* ValueCmp
*
* SYNOPSIS
*/
int
_XcmsValueCmp (p1, p2)
IntensityRec *p1, *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
*
*/
{
DBUG_ENTER("_XcmsValueCmp")
int res = p1->value - p2->value;
DBUG_RETURN(res);
}
/*
* NAME
* IntensityCmp
*
* SYNOPSIS
*/
int
_XcmsIntensityCmp (p1, p2)
IntensityRec *p1, *p2;
/*
* DESCRIPTION
* Compares the intensity component of two IntensityRec
* structures.
*
* RETURNS
* 0 if equal;
* < 0 if first precedes second
* > 0 if first succeeds second
*
*/
{
DBUG_ENTER("_XcmsIntensityCmp")
if (p1->intensity < p2->intensity) {
DBUG_RETURN(-1);
}
if (p1->intensity > p2->intensity) {
DBUG_RETURN(XcmsSuccess);
}
DBUG_RETURN(XcmsFailure);
}
/*
* NAME
* ValueInterpolation
*
* SYNOPSIS
*/
/* ARGSUSED */
int
_XcmsValueInterpolation (key, lo, hi, answer, bitsPerRGB)
IntensityRec *key, *lo, *hi, *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.
*/
{
DBUG_ENTER("_XcmsValueInterpolation")
XcmsFloat 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;
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* IntensityInterpolation
*
* SYNOPSIS
*/
int
_XcmsIntensityInterpolation (key, lo, hi, answer, bitsPerRGB)
IntensityRec *key, *lo, *hi, *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.
*/
{
DBUG_ENTER("_XcmsIntensityInterpolation")
long target, up, down;
int shift = 16 - bitsPerRGB;
int max_color = (1 << bitsPerRGB) - 1;
XcmsFloat 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];
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* _XcmsTableSearch
*
* SYNOPSIS
*/
int
_XcmsTableSearch (key, bitsPerRGB, base, nel, nKeyPtrSize, compar, interpol, answer)
char *key;
int bitsPerRGB;
char *base;
unsigned nel;
unsigned nKeyPtrSize;
int (*compar)();
int (*interpol)();
char *answer;
/*
* DESCRIPTION
* A binary search through the specificied table.
*
* RETURNS
* Returns 0 if failed; otherwise non-zero.
*
*/
{
DBUG_ENTER("_XcmsTableSearch")
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];
DBUG_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];
DBUG_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.
*/
result = (*interpol)(key, lo, hi, answer, bitsPerRGB);
DBUG_RETURN(result);
}
/*
* NAME
* _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
*
* SYNOPSIS
*/
void _XcmsMatVec(pMat, pIn, pOut)
XcmsFloat *pMat, *pIn, *pOut;
/*
* DESCRIPTION
* Multiply the passed vector by the passed matrix to return a
* vector. Matrix is 3x3, vectors are of length 3.
*
* RETURNS
* void
*/
{
DBUG_ENTER("_XcmsMatVec")
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];
}
DBUG_VOID_RETURN;
}
/************************************************************************
* *
* PUBLIC ROUTINES *
* *
************************************************************************/
/*
* NAME
* XcmsLRGB_RGB_ParseString
*
* SYNOPSIS
*/
static int
XcmsLRGB_RGB_ParseString(spec, pColor)
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.
*/
{
DBUG_ENTER("XcmsLRGB_RGB_ParseString")
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) {
DBUG_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
DBUG_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) {
DBUG_RETURN(XcmsFailure);
}
n = (int)(pchar - spec);
/*
* Check for proper prefix.
*/
if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
DBUG_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) {
DBUG_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
DBUG_RETURN(XcmsFailure);
}
if (n == 0)
DBUG_RETURN(XcmsFailure);
if (n < 4) {
*pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
}
}
}
pColor->format = XcmsRGBFormat;
pColor->pixel = 0;
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* XcmsLRGB_RGBi_ParseString
*
* SYNOPSIS
*/
static int
XcmsLRGB_RGBi_ParseString(spec, pColor)
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.
*/
{
DBUG_ENTER("XcmsLRGB_RGBi_ParseString")
int n;
char *pchar;
if ((pchar = strchr(spec, ':')) == NULL) {
DBUG_RETURN(XcmsFailure);
}
n = (int)(pchar - spec);
/*
* Check for proper prefix.
*/
if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
DBUG_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) {
DBUG_RETURN(XcmsFailure);
}
/*
* Succeeded !
*/
pColor->format = XcmsRGBiFormat;
pColor->pixel = 0;
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
*
* SYNOPSIS
*/
/* ARGSUSED */
Status
XcmsCIEXYZToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
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.
*/
{
DBUG_ENTER("XcmsCIEXYZToRGBi")
LINEAR_RGB_SCCData *pScreenData;
XcmsFloat tmp[3];
int hasCompressed = 0;
unsigned int i;
XcmsColor *pColor = pXcmsColors_in_out;
if (ccc == NULL) {
DBUG_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) {
DBUG_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;
DBUG_RETURN(XcmsFailure);
} else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
i, pCompressed) == 0) {
DBUG_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) {
DBUG_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))) {
DBUG_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;
}
DBUG_RETURN(hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
}
/*
* NAME
* LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
*
* SYNOPSIS
*/
/* ARGSUSED */
Status
XcmsRGBiToCIEXYZ(ccc, pXcmsColors_in_out, nColors, pCompressed)
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.
*/
{
DBUG_ENTER("XcmsRGBiToCIEXYZ")
LINEAR_RGB_SCCData *pScreenData;
XcmsFloat tmp[3];
/*
* pCompressed ignored in this function.
*/
if (ccc == NULL) {
DBUG_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;
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* XcmsRGBiToRGB
*
* SYNOPSIS
*/
/* ARGSUSED */
Status
XcmsRGBiToRGB(ccc, pXcmsColors_in_out, nColors, pCompressed)
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.
*/
{
DBUG_ENTER("XcmsRGBiToRGB")
LINEAR_RGB_SCCData *pScreenData;
XcmsRGB tmpRGB;
IntensityRec keyIRec, answerIRec;
/*
* pCompressed ignored in this function.
*/
if (ccc == NULL) {
DBUG_RETURN(XcmsFailure);
}
pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
while (nColors--) {
/* Make sure format is XcmsRGBiFormat */
if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
DBUG_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),
_XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
DBUG_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),
_XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
DBUG_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),
_XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
DBUG_RETURN(XcmsFailure);
}
tmpRGB.blue = answerIRec.value;
memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
(pXcmsColors_in_out++)->format = XcmsRGBFormat;
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* XcmsRGBToRGBi
*
* SYNOPSIS
*/
/* ARGSUSED */
Status
XcmsRGBToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed)
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.
*/
{
DBUG_ENTER("XcmsRGBToRGBi")
LINEAR_RGB_SCCData *pScreenData;
XcmsRGBi tmpRGBi;
IntensityRec keyIRec, answerIRec;
/*
* pCompressed ignored in this function.
*/
if (ccc == NULL) {
DBUG_RETURN(XcmsFailure);
}
pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
while (nColors--) {
/* Make sure format is XcmsRGBFormat */
if (pXcmsColors_in_out->format != XcmsRGBFormat) {
DBUG_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),
_XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
DBUG_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),
_XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
DBUG_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),
_XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
DBUG_RETURN(XcmsFailure);
}
tmpRGBi.blue = answerIRec.intensity;
memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
(pXcmsColors_in_out++)->format = XcmsRGBiFormat;
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* _XcmsInitScrnDefaultInfo
*
* SYNOPSIS
*/
/* ARGSUSED */
int
_XcmsLRGB_InitScrnDefault(dpy, screenNumber, pPerScrnInfo)
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.
*/
{
DBUG_ENTER("_XcmsLRGB_InitScrnDefault")
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;
DBUG_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 */
DBUG_RETURN(1);
}