3 * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
6 * This file is a component of an X Window System-specific implementation
7 * of Xcms based on the TekColor Color Management System. Permission is
8 * hereby granted to use, copy, modify, sell, and otherwise distribute this
9 * software and its documentation for any purpose and without fee, provided
10 * that this copyright, permission, and disclaimer notice is reproduced in
11 * all copies of this software and in supporting documentation. TekColor
12 * is a trademark of Tektronix, Inc.
14 * Tektronix makes no representation about the suitability of this software
15 * for any purpose. It is provided "as is" and with all faults.
17 * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
18 * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19 * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21 * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
22 * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
30 * This file contains the conversion routines:
31 * 1. CIE XYZ to RGB intensity
32 * 2. RGB intensity to device RGB
33 * 3. device RGB to RGB intensity
34 * 4. RGB intensity to CIE XYZ
43 #include <X11/Xatom.h>
50 * #define declarations local to this package.
54 #define MIN(x,y) ((x) > (y) ? (y) : (x))
57 #define MAX(x,y) ((x) > (y) ? (x) : (y))
60 #define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x))
63 #define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z))))
68 * typedefs local to this package (for use with local vars).
73 * FORWARD DECLARATIONS
75 static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp);
76 static int LINEAR_RGB_InitSCCData(Display *dpy,
77 int screenNumber, XcmsPerScrnInfo *pPerScrnInfo);
78 static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor);
79 static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor);
85 unsigned long *pCount);
91 unsigned long *pCount);
95 * Variables local to this package.
97 * static int ExampleLocalVar;
100 static unsigned short const MASK[17] = {
101 0x0000, /* 0 bitsPerRGB */
102 0x8000, /* 1 bitsPerRGB */
103 0xc000, /* 2 bitsPerRGB */
104 0xe000, /* 3 bitsPerRGB */
105 0xf000, /* 4 bitsPerRGB */
106 0xf800, /* 5 bitsPerRGB */
107 0xfc00, /* 6 bitsPerRGB */
108 0xfe00, /* 7 bitsPerRGB */
109 0xff00, /* 8 bitsPerRGB */
110 0xff80, /* 9 bitsPerRGB */
111 0xffc0, /* 10 bitsPerRGB */
112 0xffe0, /* 11 bitsPerRGB */
113 0xfff0, /* 12 bitsPerRGB */
114 0xfff8, /* 13 bitsPerRGB */
115 0xfffc, /* 14 bitsPerRGB */
116 0xfffe, /* 15 bitsPerRGB */
117 0xffff /* 16 bitsPerRGB */
122 * A NULL terminated array of function pointers that when applied
123 * in series will convert an XcmsColor structure from XcmsRGBFormat
124 * to XcmsCIEXYZFormat.
126 static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
127 (XcmsConversionProc)XcmsRGBToRGBi,
128 (XcmsConversionProc)XcmsRGBiToCIEXYZ,
133 * A NULL terminated array of function pointers that when applied
134 * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
137 static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
138 (XcmsConversionProc)XcmsCIEXYZToRGBi,
139 (XcmsConversionProc)XcmsRGBiToRGB,
144 * A NULL terminated array of function pointers that when applied
145 * in series will convert an XcmsColor structure from XcmsRGBiFormat
146 * to XcmsCIEXYZFormat.
148 static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
149 (XcmsConversionProc)XcmsRGBiToCIEXYZ,
154 * A NULL terminated array of function pointers that when applied
155 * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
158 static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
159 (XcmsConversionProc)XcmsCIEXYZToRGBi,
166 XcmsColorSpace XcmsRGBiColorSpace =
168 _XcmsRGBi_prefix, /* prefix */
169 XcmsRGBiFormat, /* id */
170 XcmsLRGB_RGBi_ParseString, /* parseString */
171 Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */
172 Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */
179 XcmsColorSpace XcmsRGBColorSpace =
181 _XcmsRGB_prefix, /* prefix */
182 XcmsRGBFormat, /* id */
183 XcmsLRGB_RGB_ParseString, /* parseString */
184 Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */
185 Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */
190 * Device-Independent Color Spaces known to the
191 * LINEAR_RGB Screen Color Characteristics Function Set.
193 static XcmsColorSpace *DDColorSpaces[] = {
202 * Variables declared in this package that are allowed
203 * to be used globally.
207 * LINEAR_RGB Screen Color Characteristics Function Set.
209 XcmsFunctionSet XcmsLinearRGBFunctionSet =
211 &DDColorSpaces[0], /* pDDColorSpaces */
212 LINEAR_RGB_InitSCCData, /* pInitScrnFunc */
213 LINEAR_RGB_FreeSCCData /* pFreeSCCData */
218 * Contents of Default SCCData should be replaced if other
219 * data should be used as default.
225 * NAME Tektronix 19" (Sony) CRT
226 * PART_NUMBER 119-2451-00
227 * MODEL Tek4300, Tek4800
230 static IntensityRec const Default_RGB_RedTuples[] = {
231 /* {unsigned short value, XcmsFloat intensity} */
232 { 0x0000, 0.000000 },
233 { 0x0909, 0.000000 },
234 { 0x0a0a, 0.000936 },
235 { 0x0f0f, 0.001481 },
236 { 0x1414, 0.002329 },
237 { 0x1919, 0.003529 },
238 { 0x1e1e, 0.005127 },
239 { 0x2323, 0.007169 },
240 { 0x2828, 0.009699 },
241 { 0x2d2d, 0.012759 },
242 { 0x3232, 0.016392 },
243 { 0x3737, 0.020637 },
244 { 0x3c3c, 0.025533 },
245 { 0x4141, 0.031119 },
246 { 0x4646, 0.037431 },
247 { 0x4b4b, 0.044504 },
248 { 0x5050, 0.052373 },
249 { 0x5555, 0.061069 },
250 { 0x5a5a, 0.070624 },
251 { 0x5f5f, 0.081070 },
252 { 0x6464, 0.092433 },
253 { 0x6969, 0.104744 },
254 { 0x6e6e, 0.118026 },
255 { 0x7373, 0.132307 },
256 { 0x7878, 0.147610 },
257 { 0x7d7d, 0.163958 },
258 { 0x8282, 0.181371 },
259 { 0x8787, 0.199871 },
260 { 0x8c8c, 0.219475 },
261 { 0x9191, 0.240202 },
262 { 0x9696, 0.262069 },
263 { 0x9b9b, 0.285089 },
264 { 0xa0a0, 0.309278 },
265 { 0xa5a5, 0.334647 },
266 { 0xaaaa, 0.361208 },
267 { 0xafaf, 0.388971 },
268 { 0xb4b4, 0.417945 },
269 { 0xb9b9, 0.448138 },
270 { 0xbebe, 0.479555 },
271 { 0xc3c3, 0.512202 },
272 { 0xc8c8, 0.546082 },
273 { 0xcdcd, 0.581199 },
274 { 0xd2d2, 0.617552 },
275 { 0xd7d7, 0.655144 },
276 { 0xdcdc, 0.693971 },
277 { 0xe1e1, 0.734031 },
278 { 0xe6e6, 0.775322 },
279 { 0xebeb, 0.817837 },
280 { 0xf0f0, 0.861571 },
281 { 0xf5f5, 0.906515 },
282 { 0xfafa, 0.952662 },
286 static IntensityRec const Default_RGB_GreenTuples[] = {
287 /* {unsigned short value, XcmsFloat intensity} */
288 { 0x0000, 0.000000 },
289 { 0x1313, 0.000000 },
290 { 0x1414, 0.000832 },
291 { 0x1919, 0.001998 },
292 { 0x1e1e, 0.003612 },
293 { 0x2323, 0.005736 },
294 { 0x2828, 0.008428 },
295 { 0x2d2d, 0.011745 },
296 { 0x3232, 0.015740 },
297 { 0x3737, 0.020463 },
298 { 0x3c3c, 0.025960 },
299 { 0x4141, 0.032275 },
300 { 0x4646, 0.039449 },
301 { 0x4b4b, 0.047519 },
302 { 0x5050, 0.056520 },
303 { 0x5555, 0.066484 },
304 { 0x5a5a, 0.077439 },
305 { 0x5f5f, 0.089409 },
306 { 0x6464, 0.102418 },
307 { 0x6969, 0.116485 },
308 { 0x6e6e, 0.131625 },
309 { 0x7373, 0.147853 },
310 { 0x7878, 0.165176 },
311 { 0x7d7d, 0.183604 },
312 { 0x8282, 0.203140 },
313 { 0x8787, 0.223783 },
314 { 0x8c8c, 0.245533 },
315 { 0x9191, 0.268384 },
316 { 0x9696, 0.292327 },
317 { 0x9b9b, 0.317351 },
318 { 0xa0a0, 0.343441 },
319 { 0xa5a5, 0.370580 },
320 { 0xaaaa, 0.398747 },
321 { 0xafaf, 0.427919 },
322 { 0xb4b4, 0.458068 },
323 { 0xb9b9, 0.489165 },
324 { 0xbebe, 0.521176 },
325 { 0xc3c3, 0.554067 },
326 { 0xc8c8, 0.587797 },
327 { 0xcdcd, 0.622324 },
328 { 0xd2d2, 0.657604 },
329 { 0xd7d7, 0.693588 },
330 { 0xdcdc, 0.730225 },
331 { 0xe1e1, 0.767459 },
332 { 0xe6e6, 0.805235 },
333 { 0xebeb, 0.843491 },
334 { 0xf0f0, 0.882164 },
335 { 0xf5f5, 0.921187 },
336 { 0xfafa, 0.960490 },
340 static IntensityRec const Default_RGB_BlueTuples[] = {
341 /* {unsigned short value, XcmsFloat intensity} */
342 { 0x0000, 0.000000 },
343 { 0x0e0e, 0.000000 },
344 { 0x0f0f, 0.001341 },
345 { 0x1414, 0.002080 },
346 { 0x1919, 0.003188 },
347 { 0x1e1e, 0.004729 },
348 { 0x2323, 0.006766 },
349 { 0x2828, 0.009357 },
350 { 0x2d2d, 0.012559 },
351 { 0x3232, 0.016424 },
352 { 0x3737, 0.021004 },
353 { 0x3c3c, 0.026344 },
354 { 0x4141, 0.032489 },
355 { 0x4646, 0.039481 },
356 { 0x4b4b, 0.047357 },
357 { 0x5050, 0.056154 },
358 { 0x5555, 0.065903 },
359 { 0x5a5a, 0.076634 },
360 { 0x5f5f, 0.088373 },
361 { 0x6464, 0.101145 },
362 { 0x6969, 0.114968 },
363 { 0x6e6e, 0.129862 },
364 { 0x7373, 0.145841 },
365 { 0x7878, 0.162915 },
366 { 0x7d7d, 0.181095 },
367 { 0x8282, 0.200386 },
368 { 0x8787, 0.220791 },
369 { 0x8c8c, 0.242309 },
370 { 0x9191, 0.264937 },
371 { 0x9696, 0.288670 },
372 { 0x9b9b, 0.313499 },
373 { 0xa0a0, 0.339410 },
374 { 0xa5a5, 0.366390 },
375 { 0xaaaa, 0.394421 },
376 { 0xafaf, 0.423481 },
377 { 0xb4b4, 0.453547 },
378 { 0xb9b9, 0.484592 },
379 { 0xbebe, 0.516587 },
380 { 0xc3c3, 0.549498 },
381 { 0xc8c8, 0.583291 },
382 { 0xcdcd, 0.617925 },
383 { 0xd2d2, 0.653361 },
384 { 0xd7d7, 0.689553 },
385 { 0xdcdc, 0.726454 },
386 { 0xe1e1, 0.764013 },
387 { 0xe6e6, 0.802178 },
388 { 0xebeb, 0.840891 },
389 { 0xf0f0, 0.880093 },
390 { 0xf5f5, 0.919723 },
391 { 0xfafa, 0.959715 },
395 static IntensityTbl Default_RGB_RedTbl = {
396 /* IntensityRec *pBase */
397 (IntensityRec *) Default_RGB_RedTuples,
398 /* unsigned int nEntries */
402 static IntensityTbl Default_RGB_GreenTbl = {
403 /* IntensityRec *pBase */
404 (IntensityRec *)Default_RGB_GreenTuples,
405 /* unsigned int nEntries */
409 static IntensityTbl Default_RGB_BlueTbl = {
410 /* IntensityRec *pBase */
411 (IntensityRec *)Default_RGB_BlueTuples,
412 /* unsigned int nEntries */
416 static LINEAR_RGB_SCCData Default_RGB_SCCData = {
417 /* XcmsFloat XYZtoRGBmatrix[3][3] */
419 { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 },
420 {-1.07152751306193600, 1.96593795204372400, 0.03673691339553462 },
421 { 0.06351179790497788, -0.20020501000496480, 0.81070942031648220 }
424 /* XcmsFloat RGBtoXYZmatrix[3][3] */
426 { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 },
427 { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 },
428 { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 }
431 /* IntensityTbl *pRedTbl */
434 /* IntensityTbl *pGreenTbl */
435 &Default_RGB_GreenTbl,
437 /* IntensityTbl *pBlueTbl */
441 /************************************************************************
445 ************************************************************************/
449 * LINEAR_RGB_InitSCCData()
454 LINEAR_RGB_InitSCCData(
457 XcmsPerScrnInfo *pPerScrnInfo)
462 * XcmsFailure if failed.
463 * XcmsSuccess if succeeded.
467 Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
468 Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
469 int format_return, count, cType, nTables;
470 unsigned long nitems, nbytes_return;
471 char *property_return, *pChar;
475 #endif /* ALLDEBUG */
478 LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
479 XcmsIntensityMap *pNewMap;
482 * Allocate memory for pScreenData
484 if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *)
485 Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
490 * 1. Get the XYZ->RGB and RGB->XYZ matrices
493 if (MatrixAtom == None ||
494 !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom,
495 &format_return, &nitems, &nbytes_return, &property_return) ||
496 nitems != 18 || format_return != 32) {
498 * As per the XDCCC, there must be 18 data items and each must be
506 * RGBtoXYZ and XYZtoRGB matrices
508 pValue = (XcmsFloat *) pScreenData;
509 pChar = property_return;
510 for (count = 0; count < 18; count++) {
511 *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
512 &nitems) / (XcmsFloat)XDCCC_NUMBER;
514 Xfree ((char *)property_return);
515 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
516 pScreenData->RGBtoXYZmatrix[0][0] +
517 pScreenData->RGBtoXYZmatrix[0][1] +
518 pScreenData->RGBtoXYZmatrix[0][2];
519 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
520 pScreenData->RGBtoXYZmatrix[1][0] +
521 pScreenData->RGBtoXYZmatrix[1][1] +
522 pScreenData->RGBtoXYZmatrix[1][2];
523 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
524 pScreenData->RGBtoXYZmatrix[2][0] +
525 pScreenData->RGBtoXYZmatrix[2][1] +
526 pScreenData->RGBtoXYZmatrix[2][2];
529 * Compute the Screen White Point
531 if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
532 || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
535 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
537 pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
538 pPerScrnInfo->screenWhitePt.pixel = 0;
541 printf ("RGB to XYZ Matrix values:\n");
542 printf (" %f %f %f\n %f %f %f\n %f %f %f\n",
543 pScreenData->RGBtoXYZmatrix[0][0],
544 pScreenData->RGBtoXYZmatrix[0][1],
545 pScreenData->RGBtoXYZmatrix[0][2],
546 pScreenData->RGBtoXYZmatrix[1][0],
547 pScreenData->RGBtoXYZmatrix[1][1],
548 pScreenData->RGBtoXYZmatrix[1][2],
549 pScreenData->RGBtoXYZmatrix[2][0],
550 pScreenData->RGBtoXYZmatrix[2][1],
551 pScreenData->RGBtoXYZmatrix[2][2]);
552 printf ("XYZ to RGB Matrix values:\n");
553 printf (" %f %f %f\n %f %f %f\n %f %f %f\n",
554 pScreenData->XYZtoRGBmatrix[0][0],
555 pScreenData->XYZtoRGBmatrix[0][1],
556 pScreenData->XYZtoRGBmatrix[0][2],
557 pScreenData->XYZtoRGBmatrix[1][0],
558 pScreenData->XYZtoRGBmatrix[1][1],
559 pScreenData->XYZtoRGBmatrix[1][2],
560 pScreenData->XYZtoRGBmatrix[2][0],
561 pScreenData->XYZtoRGBmatrix[2][1],
562 pScreenData->XYZtoRGBmatrix[2][2]);
563 printf ("Screen White Pt value: %f %f %f\n",
564 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
565 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
566 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
571 * 2. Get the Intensity Profile
573 if (CorrectAtom == None ||
574 !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
575 &format_return, &nitems, &nbytes_return, &property_return)) {
579 pChar = property_return;
582 switch (format_return) {
585 * Must have at least:
597 goto Free_property_return;
603 * Must have at least:
613 goto Free_property_return;
619 * Must have at least:
628 goto Free_property_return;
633 goto Free_property_return;
639 visualID = _XcmsGetElement(format_return, &pChar, &nitems);
641 visualID = visualID << format_return;
642 visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
647 * This is a shared intensity table
649 pScreenData = pScreenDefaultData;
652 * This is a per-Visual intensity table
654 if (!(pScreenData = (LINEAR_RGB_SCCData *)
655 Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
656 goto Free_property_return;
659 memcpy((char *)pScreenData, (char *)pScreenDefaultData,
660 18 * sizeof(XcmsFloat));
662 /* Create, initialize, and add map */
663 if (!(pNewMap = (XcmsIntensityMap *)
664 Xcalloc (1, sizeof(XcmsIntensityMap)))) {
665 Xfree((char *)pScreenData);
666 goto Free_property_return;
668 pNewMap->visualID = visualID;
669 pNewMap->screenData = (XPointer)pScreenData;
670 pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
672 (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
673 dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
674 dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
677 cType = _XcmsGetElement(format_return, &pChar, &nitems);
678 nTables = _XcmsGetElement(format_return, &pChar, &nitems);
682 /* Red Intensity Table */
683 if (!(pScreenData->pRedTbl = (IntensityTbl *)
684 Xcalloc (1, sizeof(IntensityTbl)))) {
685 goto Free_property_return;
687 if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
688 &nitems) == XcmsFailure) {
693 /* Green Intensity Table */
694 pScreenData->pGreenTbl = pScreenData->pRedTbl;
695 /* Blue Intensity Table */
696 pScreenData->pBlueTbl = pScreenData->pRedTbl;
698 /* Green Intensity Table */
699 if (!(pScreenData->pGreenTbl = (IntensityTbl *)
700 Xcalloc (1, sizeof(IntensityTbl)))) {
701 goto FreeRedTblElements;
703 if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
704 &nitems) == XcmsFailure) {
708 /* Blue Intensity Table */
709 if (!(pScreenData->pBlueTbl = (IntensityTbl *)
710 Xcalloc (1, sizeof(IntensityTbl)))) {
711 goto FreeGreenTblElements;
713 if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
714 &nitems) == XcmsFailure) {
718 } else if (cType == 1) {
719 /* Red Intensity Table */
720 if (!(pScreenData->pRedTbl = (IntensityTbl *)
721 Xcalloc (1, sizeof(IntensityTbl)))) {
722 goto Free_property_return;
724 if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
725 &nitems) == XcmsFailure) {
731 /* Green Intensity Table */
732 pScreenData->pGreenTbl = pScreenData->pRedTbl;
733 /* Blue Intensity Table */
734 pScreenData->pBlueTbl = pScreenData->pRedTbl;
738 /* Green Intensity Table */
739 if (!(pScreenData->pGreenTbl = (IntensityTbl *)
740 Xcalloc (1, sizeof(IntensityTbl)))) {
741 goto FreeRedTblElements;
743 if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
744 &nitems) == XcmsFailure) {
748 /* Blue Intensity Table */
749 if (!(pScreenData->pBlueTbl = (IntensityTbl *)
750 Xcalloc (1, sizeof(IntensityTbl)))) {
751 goto FreeGreenTblElements;
753 if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
754 &nitems) == XcmsFailure) {
759 goto Free_property_return;
763 printf ("Intensity Table RED %d\n", pScreenData->pRedTbl->nEntries);
764 pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
765 for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
766 printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
768 if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
769 printf ("Intensity Table GREEN %d\n", pScreenData->pGreenTbl->nEntries);
770 pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
771 for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
772 printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
775 if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
776 printf ("Intensity Table BLUE %d\n", pScreenData->pBlueTbl->nEntries);
777 pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
778 for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
779 printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
782 #endif /* ALLDEBUG */
785 Xfree ((char *)property_return);
787 /* Free the old memory and use the new structure created. */
788 LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData);
790 pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
792 pPerScrnInfo->screenData = (XPointer) pScreenData;
794 pPerScrnInfo->state = XcmsInitSuccess;
799 Xfree((char *)pScreenData->pBlueTbl->pBase);
802 Xfree((char *)pScreenData->pBlueTbl);
804 FreeGreenTblElements:
805 Xfree((char *)pScreenData->pGreenTbl->pBase);
808 Xfree((char *)pScreenData->pGreenTbl);
811 Xfree((char *)pScreenData->pRedTbl->pBase);
814 Xfree((char *)pScreenData->pRedTbl);
816 Free_property_return:
817 Xfree ((char *)property_return);
820 Xfree((char *)pScreenDefaultData);
821 pPerScrnInfo->state = XcmsInitNone;
828 * LINEAR_RGB_FreeSCCData()
833 LINEAR_RGB_FreeSCCData(
834 XPointer pScreenDataTemp)
840 * 1 if succeeded with no modifications.
844 LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
846 if (pScreenData && pScreenData != &Default_RGB_SCCData) {
847 if (pScreenData->pRedTbl) {
848 if (pScreenData->pGreenTbl) {
849 if (pScreenData->pRedTbl->pBase !=
850 pScreenData->pGreenTbl->pBase) {
851 if (pScreenData->pGreenTbl->pBase) {
852 Xfree ((char *)pScreenData->pGreenTbl->pBase);
855 if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
856 Xfree ((char *)pScreenData->pGreenTbl);
859 if (pScreenData->pBlueTbl) {
860 if (pScreenData->pRedTbl->pBase !=
861 pScreenData->pBlueTbl->pBase) {
862 if (pScreenData->pBlueTbl->pBase) {
863 Xfree ((char *)pScreenData->pBlueTbl->pBase);
866 if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
867 Xfree ((char *)pScreenData->pBlueTbl);
870 if (pScreenData->pRedTbl->pBase) {
871 Xfree ((char *)pScreenData->pRedTbl->pBase);
873 Xfree ((char *)pScreenData->pRedTbl);
875 Xfree ((char *)pScreenData);
881 /************************************************************************
883 * API PRIVATE ROUTINES *
885 ************************************************************************/
898 unsigned long *pCount)
903 * XcmsFailure if failed.
904 * XcmsSuccess if succeeded.
908 unsigned int nElements;
911 nElements = pTbl->nEntries =
912 _XcmsGetElement(format, pChar, pCount) + 1;
913 if (!(pIRec = pTbl->pBase = (IntensityRec *)
914 Xcalloc (nElements, sizeof(IntensityRec)))) {
920 for (; nElements--; pIRec++) {
921 /* 0xFFFF/0xFF = 0x101 */
922 pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
924 _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
928 for (; nElements--; pIRec++) {
929 pIRec->value = _XcmsGetElement (format, pChar, pCount);
930 pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
931 / (XcmsFloat)65535.0;
935 for (; nElements--; pIRec++) {
936 pIRec->value = _XcmsGetElement (format, pChar, pCount);
937 pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
938 / (XcmsFloat)4294967295.0;
959 unsigned long *pCount)
964 * XcmsFailure if failed.
965 * XcmsSuccess if succeeded.
970 unsigned int max_index;
973 max_index = _XcmsGetElement(format, pChar, pCount);
974 pTbl->nEntries = max_index + 1;
975 if (!(pIRec = pTbl->pBase = (IntensityRec *)
976 Xcalloc (max_index+1, sizeof(IntensityRec)))) {
982 for (count = 0; count < max_index+1; count++, pIRec++) {
983 pIRec->value = (count * 65535) / max_index;
984 pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
989 for (count = 0; count < max_index+1; count++, pIRec++) {
990 pIRec->value = (count * 65535) / max_index;
991 pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
992 / (XcmsFloat)65535.0;
996 for (count = 0; count < max_index+1; count++, pIRec++) {
997 pIRec->value = (count * 65535) / max_index;
998 pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
999 / (XcmsFloat)4294967295.0;
1003 return(XcmsFailure);
1006 return(XcmsSuccess);
1018 IntensityRec *p1, IntensityRec *p2)
1021 * Compares the value component of two IntensityRec
1025 * 0 if p1->value is equal to p2->value
1026 * < 0 if p1->value is less than p2->value
1027 * > 0 if p1->value is greater than p2->value
1031 return (p1->value - p2->value);
1043 IntensityRec *p1, IntensityRec *p2)
1046 * Compares the intensity component of two IntensityRec
1051 * < 0 if first precedes second
1052 * > 0 if first succeeds second
1056 if (p1->intensity < p2->intensity) {
1059 if (p1->intensity > p2->intensity) {
1060 return (XcmsSuccess);
1062 return (XcmsFailure);
1067 * ValueInterpolation
1073 _XcmsValueInterpolation(
1074 IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
1078 * Based on a given value, performs a linear interpolation
1079 * on the intensities between two IntensityRec structures.
1080 * Note that the bitsPerRGB parameter is ignored.
1083 * Returns 0 if failed; otherwise non-zero.
1088 ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) /
1089 ((XcmsFloat)hi->value - (XcmsFloat)lo->value);
1090 answer->value = key->value;
1091 answer->intensity = (hi->intensity - lo->intensity) * ratio;
1092 answer->intensity += lo->intensity;
1093 return (XcmsSuccess);
1098 * IntensityInterpolation
1103 _XcmsIntensityInterpolation(
1104 IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
1108 * Based on a given intensity, performs a linear interpolation
1109 * on the values between two IntensityRec structures.
1110 * The bitsPerRGB parameter is necessary to perform rounding
1111 * to the correct number of significant bits.
1114 * Returns 0 if failed; otherwise non-zero.
1118 long target, up, down;
1119 int shift = 16 - bitsPerRGB;
1120 int max_color = (1 << bitsPerRGB) - 1;
1122 ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
1123 answer->intensity = key->intensity;
1124 target = hi->value - lo->value;
1126 target += lo->value;
1129 * Ok now, lets find the closest in respects to bits per RGB
1131 up = ((target >> shift) * 0xFFFF) / max_color;
1134 up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
1136 down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
1138 answer->value = ((up - target) < (target - down) ? up : down);
1139 answer->value &= MASK[bitsPerRGB];
1140 return (XcmsSuccess);
1145 typedef int (*comparProcp)(
1148 typedef int (*interpolProcp)(
1167 unsigned nKeyPtrSize,
1181 * A binary search through the specificied table.
1184 * Returns 0 if failed; otherwise non-zero.
1188 char *hi, *lo, *mid, *last;
1191 last = hi = base + ((nel - 1) * nKeyPtrSize);
1194 /* use only the significants bits, then scale into 16 bits */
1195 ((IntensityRec *)key)->value = ((unsigned long)
1196 (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
1197 / ((1 << bitsPerRGB) - 1);
1199 /* Special case so that zero intensity always maps to zero value */
1200 if ((*compar) (key,lo) <= 0) {
1201 memcpy (answer, lo, nKeyPtrSize);
1202 ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
1205 while (mid != last) {
1207 mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
1208 result = (*compar) (key, mid);
1211 memcpy(answer, mid, nKeyPtrSize);
1212 ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
1213 return (XcmsSuccess);
1214 } else if (result < 0) {
1222 * If we got to here, we didn't find a solution, so we
1223 * need to apply interpolation.
1225 return ((*interpol)(key, lo, hi, answer, bitsPerRGB));
1231 * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
1235 static void _XcmsMatVec(
1236 XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut)
1239 * Multiply the passed vector by the passed matrix to return a
1240 * vector. Matrix is 3x3, vectors are of length 3.
1248 for (i = 0; i < 3; i++) {
1250 for (j = 0; j < 3; j++)
1251 pOut[i] += *(pMat+(i*3)+j) * pIn[j];
1256 /************************************************************************
1260 ************************************************************************/
1265 * XcmsLRGB_RGB_ParseString
1270 XcmsLRGB_RGB_ParseString(
1271 register char *spec,
1275 * This routines takes a string and attempts to convert
1276 * it into a XcmsColor structure with XcmsRGBFormat.
1279 * 0 if failed, non-zero otherwise.
1283 unsigned short r, g, b;
1286 unsigned short *pShort;
1289 * Check for old # format
1293 * Attempt to parse the value portion.
1297 if (n != 3 && n != 6 && n != 9 && n != 12) {
1298 return(XcmsFailure);
1307 for (i = n; --i >= 0; ) {
1310 if (c >= '0' && c <= '9')
1312 /* assume string in lowercase
1313 else if (c >= 'A' && c <= 'F')
1314 b |= c - ('A' - 10);
1316 else if (c >= 'a' && c <= 'f')
1317 b |= c - ('a' - 10);
1318 else return (XcmsFailure);
1320 } while (*spec != '\0');
1327 /* shift instead of scale, to match old broken semantics */
1328 pColor->spec.RGB.red = r << n;
1329 pColor->spec.RGB.green = g << n;
1330 pColor->spec.RGB.blue = b << n;
1332 if ((pchar = strchr(spec, ':')) == NULL) {
1333 return(XcmsFailure);
1335 n = (int)(pchar - spec);
1338 * Check for proper prefix.
1340 if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
1341 return(XcmsFailure);
1345 * Attempt to parse the value portion.
1348 pShort = &pColor->spec.RGB.red;
1349 for (i = 0; i < 3; i++, pShort++, spec++) {
1352 while (*spec != '/' && *spec != '\0') {
1354 return(XcmsFailure);
1358 if (c >= '0' && c <= '9')
1360 /* assume string in lowercase
1361 else if (c >= 'A' && c <= 'F')
1362 *pShort |= c - ('A' - 10);
1364 else if (c >= 'a' && c <= 'f')
1365 *pShort |= c - ('a' - 10);
1366 else return (XcmsFailure);
1369 return (XcmsFailure);
1371 *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
1375 pColor->format = XcmsRGBFormat;
1377 return (XcmsSuccess);
1383 * XcmsLRGB_RGBi_ParseString
1388 XcmsLRGB_RGBi_ParseString(
1389 register char *spec,
1393 * This routines takes a string and attempts to convert
1394 * it into a XcmsColor structure with XcmsRGBiFormat.
1395 * The assumed RGBi string syntax is:
1397 * Where r, g, and b are in string input format for floats
1399 * a. an optional sign
1400 * b. a string of numbers possibly containing a decimal point,
1401 * c. an optional exponent field containing an 'E' or 'e'
1402 * followed by a possibly signed integer string.
1405 * 0 if failed, non-zero otherwise.
1411 if ((pchar = strchr(spec, ':')) == NULL) {
1412 return(XcmsFailure);
1414 n = (int)(pchar - spec);
1417 * Check for proper prefix.
1419 if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
1420 return(XcmsFailure);
1424 * Attempt to parse the value portion.
1426 if (sscanf(spec + n + 1, "%lf/%lf/%lf",
1427 &pColor->spec.RGBi.red,
1428 &pColor->spec.RGBi.green,
1429 &pColor->spec.RGBi.blue) != 3) {
1430 char *s; /* Maybe failed due to locale */
1432 if ((s = strdup(spec))) {
1433 for (f = 0; s[f]; ++f)
1436 else if (s[f] == ',')
1438 if (sscanf(s + n + 1, "%lf/%lf/%lf",
1439 &pColor->spec.RGBi.red,
1440 &pColor->spec.RGBi.green,
1441 &pColor->spec.RGBi.blue) != 3) {
1443 return(XcmsFailure);
1447 return(XcmsFailure);
1453 pColor->format = XcmsRGBiFormat;
1455 return (XcmsSuccess);
1461 * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
1469 XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
1470 unsigned int nColors, /* Number of colors */
1471 Bool *pCompressed) /* pointer to an array of Bool */
1474 * Converts color specifications in an array of XcmsColor
1475 * structures from RGB format to RGBi format.
1478 * XcmsFailure if failed,
1479 * XcmsSuccess if succeeded without gamut compression.
1480 * XcmsSuccessWithCompression if succeeded with gamut
1484 LINEAR_RGB_SCCData *pScreenData;
1486 int hasCompressed = 0;
1488 XcmsColor *pColor = pXcmsColors_in_out;
1491 return(XcmsFailure);
1494 pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
1497 * XcmsColors should be White Point Adjusted, if necessary, by now!
1501 * NEW!!! for extended gamut compression
1503 * 1. Need to zero out pCompressed
1505 * 2. Need to save initial address of pColor
1507 * 3. Need to save initial address of pCompressed
1510 for (i = 0; i < nColors; i++) {
1512 /* Make sure format is XcmsCIEXYZFormat */
1513 if (pColor->format != XcmsCIEXYZFormat) {
1514 return(XcmsFailure);
1517 /* Multiply [A]-1 * [XYZ] to get RGB intensity */
1518 _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
1519 (XcmsFloat *) &pColor->spec, tmp);
1521 if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
1522 (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
1525 * RGBi out of screen's gamut
1528 if (ccc->gamutCompProc == NULL) {
1530 * Aha!! Here's that little trick that will allow
1531 * gamut compression routines to get the out of bound
1534 memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
1535 pColor->format = XcmsRGBiFormat;
1536 return(XcmsFailure);
1537 } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
1538 i, pCompressed) == 0) {
1539 return(XcmsFailure);
1543 * The gamut compression function should return colors in CIEXYZ
1544 * Also check again to if the new color is within gamut.
1546 if (pColor->format != XcmsCIEXYZFormat) {
1547 return(XcmsFailure);
1549 _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
1550 (XcmsFloat *) &pColor->spec, tmp);
1551 if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
1552 (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
1553 return(XcmsFailure);
1557 memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
1558 /* These if statements are done to ensure the fudge factor is */
1559 /* is taken into account. */
1560 if (pColor->spec.RGBi.red < 0.0) {
1561 pColor->spec.RGBi.red = 0.0;
1562 } else if (pColor->spec.RGBi.red > 1.0) {
1563 pColor->spec.RGBi.red = 1.0;
1565 if (pColor->spec.RGBi.green < 0.0) {
1566 pColor->spec.RGBi.green = 0.0;
1567 } else if (pColor->spec.RGBi.green > 1.0) {
1568 pColor->spec.RGBi.green = 1.0;
1570 if (pColor->spec.RGBi.blue < 0.0) {
1571 pColor->spec.RGBi.blue = 0.0;
1572 } else if (pColor->spec.RGBi.blue > 1.0) {
1573 pColor->spec.RGBi.blue = 1.0;
1575 (pColor++)->format = XcmsRGBiFormat;
1577 return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
1583 * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
1591 XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
1592 unsigned int nColors, /* Number of colors */
1593 Bool *pCompressed) /* pointer to a bit array */
1596 * Converts color specifications in an array of XcmsColor
1597 * structures from RGBi format to CIEXYZ format.
1600 * XcmsFailure if failed,
1601 * XcmsSuccess if succeeded.
1604 LINEAR_RGB_SCCData *pScreenData;
1608 * pCompressed ignored in this function.
1612 return(XcmsFailure);
1615 pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
1618 * XcmsColors should be White Point Adjusted, if necessary, by now!
1623 /* Multiply [A]-1 * [XYZ] to get RGB intensity */
1624 _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
1625 (XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
1627 memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp));
1628 (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
1630 return(XcmsSuccess);
1644 XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
1645 unsigned int nColors, /* Number of colors */
1646 Bool *pCompressed) /* pointer to a bit array */
1649 * Converts color specifications in an array of XcmsColor
1650 * structures from RGBi format to RGB format.
1653 * XcmsFailure if failed,
1654 * XcmsSuccess if succeeded without gamut compression.
1655 * XcmsSuccessWithCompression if succeeded with gamut
1659 LINEAR_RGB_SCCData *pScreenData;
1661 IntensityRec keyIRec, answerIRec;
1664 * pCompressed ignored in this function.
1668 return(XcmsFailure);
1671 pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
1675 /* Make sure format is XcmsRGBiFormat */
1676 if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
1677 return(XcmsFailure);
1680 keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
1681 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1682 (char *)pScreenData->pRedTbl->pBase,
1683 (unsigned)pScreenData->pRedTbl->nEntries,
1684 (unsigned)sizeof(IntensityRec),
1685 (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
1686 return(XcmsFailure);
1688 tmpRGB.red = answerIRec.value;
1690 keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
1691 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1692 (char *)pScreenData->pGreenTbl->pBase,
1693 (unsigned)pScreenData->pGreenTbl->nEntries,
1694 (unsigned)sizeof(IntensityRec),
1695 (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
1696 return(XcmsFailure);
1698 tmpRGB.green = answerIRec.value;
1700 keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
1701 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1702 (char *)pScreenData->pBlueTbl->pBase,
1703 (unsigned)pScreenData->pBlueTbl->nEntries,
1704 (unsigned)sizeof(IntensityRec),
1705 (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
1706 return(XcmsFailure);
1708 tmpRGB.blue = answerIRec.value;
1710 memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
1711 (pXcmsColors_in_out++)->format = XcmsRGBFormat;
1713 return(XcmsSuccess);
1727 XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
1728 unsigned int nColors, /* Number of colors */
1729 Bool *pCompressed) /* pointer to a bit array */
1732 * Converts color specifications in an array of XcmsColor
1733 * structures from RGB format to RGBi format.
1736 * XcmsFailure if failed,
1737 * XcmsSuccess if succeeded.
1740 LINEAR_RGB_SCCData *pScreenData;
1742 IntensityRec keyIRec, answerIRec;
1745 * pCompressed ignored in this function.
1749 return(XcmsFailure);
1752 pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
1756 /* Make sure format is XcmsRGBFormat */
1757 if (pXcmsColors_in_out->format != XcmsRGBFormat) {
1758 return(XcmsFailure);
1761 keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
1762 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1763 (char *)pScreenData->pRedTbl->pBase,
1764 (unsigned)pScreenData->pRedTbl->nEntries,
1765 (unsigned)sizeof(IntensityRec),
1766 (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
1767 return(XcmsFailure);
1769 tmpRGBi.red = answerIRec.intensity;
1771 keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
1772 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1773 (char *)pScreenData->pGreenTbl->pBase,
1774 (unsigned)pScreenData->pGreenTbl->nEntries,
1775 (unsigned)sizeof(IntensityRec),
1776 (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
1777 return(XcmsFailure);
1779 tmpRGBi.green = answerIRec.intensity;
1781 keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
1782 if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
1783 (char *)pScreenData->pBlueTbl->pBase,
1784 (unsigned)pScreenData->pBlueTbl->nEntries,
1785 (unsigned)sizeof(IntensityRec),
1786 (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
1787 return(XcmsFailure);
1789 tmpRGBi.blue = answerIRec.intensity;
1791 memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
1792 (pXcmsColors_in_out++)->format = XcmsRGBiFormat;
1794 return(XcmsSuccess);
1799 * _XcmsInitScrnDefaultInfo
1805 _XcmsLRGB_InitScrnDefault(
1808 XcmsPerScrnInfo *pPerScrnInfo)
1811 * Given a display and screen number, this routine attempts
1812 * to initialize the Xcms per Screen Info structure
1813 * (XcmsPerScrnInfo) with defaults.
1816 * Returns zero if initialization failed; non-zero otherwise.
1819 pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
1820 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
1821 Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
1822 Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
1823 Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
1824 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
1825 Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
1826 Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
1827 Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
1828 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
1829 Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
1830 Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
1831 Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
1832 if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
1833 || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
1834 pPerScrnInfo->screenData = (XPointer)NULL;
1835 pPerScrnInfo->state = XcmsInitNone;
1838 pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
1839 pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
1840 pPerScrnInfo->screenWhitePt.pixel = 0;
1841 pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
1842 pPerScrnInfo->state = XcmsInitFailure; /* default initialization */