home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-21 | 45.3 KB | 1,811 lines |
- /* $XConsortium: XcmsLRGB.c,v 1.20 91/08/20 13:51:23 keith 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 <X11/Xos.h>
- #include <X11/Xatom.h>
- #include "Xlibint.h"
- #include "Xcmsint.h"
-
- #if __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) (MIN(x, MIN(y, z)))
- #endif /* MIN3 */
- #ifndef MAX3
- #define MAX3(x,y,z) (MAX(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();
- int XcmsLRGB_RGB_ParseString();
- 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.
- *
- */
- {
- 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 (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 (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 (property_return);
- goto FreeSCCData;
- }
- count = 3;
- break;
- case 16:
- /*
- * Must have at least:
- * VisualID0
- * VisualID3
- * type
- * count
- * length
- * intensity1
- * intensity2
- */
- if (nitems < 7) {
- XFree (property_return);
- goto FreeSCCData;
- }
- count = 1;
- break;
- case 32:
- /*
- * Must have at least:
- * VisualID0
- * type
- * count
- * length
- * intensity1
- * intensity2
- */
- if (nitems < 6) {
- XFree (property_return);
- goto FreeSCCData;
- }
- count = 0;
- break;
- default:
- XFree (property_return);
- goto FreeSCCData;
- break;
- }
-
- /*
- * 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 */
- bcopy((char *)pScreenDefaultData, (char *)pScreenData,
- 18 * sizeof(XcmsFloat));
-
- /* Create, initialize, and add map */
- if (!(pNewMap = (XcmsIntensityMap *)
- Xcalloc (1, sizeof(XcmsIntensityMap)))) {
- Xfree(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 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 (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 (property_return);
-
- /* Free the old memory and use the new structure created. */
- LINEAR_RGB_FreeSCCData((LINEAR_RGB_SCCData *) pPerScrnInfo->screenData);
-
- pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
-
- pPerScrnInfo->screenData = (XPointer) pScreenData;
-
- pPerScrnInfo->state = XcmsInitSuccess;
-
- return(XcmsSuccess);
-
- FreeBlueTblElements:
- free(pScreenData->pBlueTbl->pBase);
-
- FreeBlueTbl:
- free(pScreenData->pBlueTbl);
-
- FreeGreenTblElements:
- free(pScreenData->pBlueTbl->pBase);
-
- FreeGreenTbl:
- free(pScreenData->pGreenTbl);
-
- FreeRedTblElements:
- free(pScreenData->pRedTbl->pBase);
-
- FreeRedTbl:
- free(pScreenData->pRedTbl);
-
- FreeSCCData:
- free(pScreenData);
- pPerScrnInfo->state = XcmsInitNone;
- return(XcmsFailure);
- }
-
-
- /*
- * NAME
- * LINEAR_RGB_FreeSCCData()
- *
- * SYNOPSIS
- */
- static void
- LINEAR_RGB_FreeSCCData(pScreenData)
- LINEAR_RGB_SCCData *pScreenData;
- /*
- * DESCRIPTION
- *
- * RETURNS
- * 0 if failed.
- * 1 if succeeded with no modifications.
- *
- */
- {
- if (pScreenData) {
- if (pScreenData->pRedTbl) {
- if (pScreenData->pGreenTbl) {
- if (pScreenData->pRedTbl->pBase !=
- pScreenData->pGreenTbl->pBase) {
- if (pScreenData->pGreenTbl->pBase) {
- free (pScreenData->pGreenTbl->pBase);
- }
- }
- if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
- free (pScreenData->pGreenTbl);
- }
- }
- if (pScreenData->pBlueTbl) {
- if (pScreenData->pRedTbl->pBase !=
- pScreenData->pBlueTbl->pBase) {
- if (pScreenData->pBlueTbl->pBase) {
- free (pScreenData->pBlueTbl->pBase);
- }
- }
- if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
- free (pScreenData->pBlueTbl);
- }
- }
- if (pScreenData->pRedTbl->pBase) {
- free (pScreenData->pRedTbl->pBase);
- }
- free (pScreenData->pRedTbl);
- }
- free (pScreenData);
- }
- }
-
-
-
- /************************************************************************
- * *
- * 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.
- *
- */
- {
- 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
- */
- Status
- _XcmsGetTableType1(pTbl, format, pChar, pCount)
- 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
- */
- 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
- *
- */
- {
- return (p1->value - p2->value);
- }
-
-
- /*
- * 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
- *
- */
- {
- if (p1->intensity < p2->intensity) {
- return (-1);
- }
- if (p1->intensity > p2->intensity) {
- return (XcmsSuccess);
- }
- 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.
- */
- {
- 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
- */
- 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.
- */
- {
- 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);
- }
-
-
- /*
- * 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.
- *
- */
- {
- 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) {
- bcopy (lo, answer, 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) {
-
- bcopy(mid, answer, 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
- */
- 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
- */
- {
- 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
- */
- 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.
- */
- {
- 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 < 4) {
- *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
- }
- }
- }
- pColor->format = XcmsRGBFormat;
- pColor->pixel = 0;
- return (XcmsSuccess);
- }
-
-
- /*
- * NAME
- * XcmsLRGB_RGBi_ParseString
- *
- * SYNOPSIS
- */
- 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.
- */
- {
- 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) {
- return(XcmsFailure);
- }
-
- /*
- * Succeeded !
- */
- pColor->format = XcmsRGBiFormat;
- pColor->pixel = 0;
- 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.
- */
- {
- 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.
- */
- bcopy((char *)tmp, (char *)&pColor->spec, 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++;
- }
- bcopy((char *)tmp, (char *)&pColor->spec, 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(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.
- */
- {
- 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);
-
- bcopy((char *)tmp, (char *)&pXcmsColors_in_out->spec, sizeof(tmp));
- (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
- }
- 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.
- */
- {
- 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),
- _XcmsIntensityCmp, _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),
- _XcmsIntensityCmp, _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),
- _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) {
- return(XcmsFailure);
- }
- tmpRGB.blue = answerIRec.value;
-
- bcopy((char *)&tmpRGB, (char *)&pXcmsColors_in_out->spec, sizeof(XcmsRGB));
- (pXcmsColors_in_out++)->format = XcmsRGBFormat;
- }
- 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.
- */
- {
- 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),
- _XcmsValueCmp, _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),
- _XcmsValueCmp, _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),
- _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) {
- return(XcmsFailure);
- }
- tmpRGBi.blue = answerIRec.intensity;
-
- bcopy((char *)&tmpRGBi, (char *)&pXcmsColors_in_out->spec, sizeof(XcmsRGBi));
- (pXcmsColors_in_out++)->format = XcmsRGBiFormat;
- }
- 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 TekCMS 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 = XcmsInitDefault;
- return(1);
- }
-