From 6753f87d9a6be8dcab916b479a0a122b1b375298 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 14 Jun 2010 13:29:24 +0000 Subject: libX11 git update 14/6/2010 --- libX11/nls/fi_FI.UTF-8/Compose.pre | 112 +- libX11/src/xcms/LRGB.c | 3694 ++++++++++++++++++------------------ 2 files changed, 1957 insertions(+), 1849 deletions(-) (limited to 'libX11') diff --git a/libX11/nls/fi_FI.UTF-8/Compose.pre b/libX11/nls/fi_FI.UTF-8/Compose.pre index 0f87ea0af..76c56650e 100644 --- a/libX11/nls/fi_FI.UTF-8/Compose.pre +++ b/libX11/nls/fi_FI.UTF-8/Compose.pre @@ -2,8 +2,9 @@ XCOMM XCOMM Official compose sequences for Finland based on SFS 5966 standard XCOMM XCOMM This compose sequence map implements all the functionality of Annex 3 -XCOMM of the standard and additionally defines the sequences provided in -XCOMM en_US.UTF-8/Compose. Annex 3 definitions override en_US.UTF-8 rules. +XCOMM and Annex 4 of the standard and additionally defines the sequences +XCOMM provided in en_US.UTF-8/Compose. SFS 5966 sequences override any +XCOMM conflicting rules from en_US.UTF-8/Compose. XCOMM XCOMM Annex 1 of the standard is implemented in the keymap symbols/fi XCOMM @@ -17,6 +18,8 @@ include "X11_LOCALEDATADIR/en_US.UTF-8/Compose" XCOMM Define all the sequences of the standard overriding any sequence XCOMM from en_US.UTF-8/Compose if such a sequence was provided already +XCOMM Sequences from Annex 3 + XCOMM Sequences with COMBINING ACUTE ACCENT / : "´" # ACUTE ACCENT : "á" # LATIN CAPITAL LETTER A WITH ACUTE @@ -300,6 +303,110 @@ XCOMM Sequences with AUXILIARY STROKE / : "ŧ" # LATIN SMALL LETTER T WITH STROKE : "Ŧ" # LATIN CAPITAL LETTER T WITH STROKE +XCOMM Sequences from Annex 4 + +XCOMM Sequences with COMBINING BREVE / + : "ắ" # LATIN SMALL LETTER A WITH BREVE AND ACUTE + : "ặ" # LATIN SMALL LETTER A WITH BREVE AND DOT BELOW + : "ằ" # LATIN SMALL LETTER A WITH BREVE AND GRAVE + : "ẳ" # LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE + : "ẵ" # LATIN SMALL LETTER A WITH BREVE AND TILDE + : "Ắ" # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE + : "Ặ" # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW + : "Ằ" # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE + : "Ẳ" # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE + : "Ẵ" # LATIN CAPITAL LETTER A WITH BREVE AND TILDE + +XCOMM Sequences with COMBINING CIRCUMFLEX ACCENT / + : "ấ" # LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + : "ậ" # LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW + : "ầ" # LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE + : "ẩ" # LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + : "ẫ" # LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE + : "Ấ" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE + : "Ậ" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW + : "Ầ" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE + : "Ẩ" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + : "Ẫ" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE + : "ế" # LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE + : "ệ" # LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW + : "ề" # LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + : "ể" # LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + : "ễ" # LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE + : "Ệ" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE + : "Ệ" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW + : "Ề" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE + : "Ể" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + : "Ễ" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE + : "ố" # LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE + : "ộ" # LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW + : "ồ" # LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE + : "ổ" # LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + : "ỗ" # LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE + : "Ố" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE + : "Ộ" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW + : "Ồ" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE + : "Ổ" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + : "Ỗ" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE + +XCOMM Sequences with COMBINING DIAERESIS / + : "ǟ" # LATIN SMALL LETTER A WITH DIAERESIS AND MACRON + : "Ǟ" # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON + +XCOMM Sequences with COMBINING DOT ABOVE / + : "ȧ" # LATIN SMALL LETTER A WITH DOT ABOVE + : "ǡ" # LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON + : "Ȧ" # LATIN CAPITAL LETTER A WITH DOT ABOVE + : "Ǡ" # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON + +XCOMM Sequences with COMBINING HOOK ABOVE / + : "ả" # LATIN SMALL LETTER A WITH HOOK ABOVE + : "Ả" # LATIN CAPITAL LETTER A WITH HOOK ABOVE + : "ẻ" # LATIN SMALL LETTER E WITH HOOK ABOVE + : "Ẻ" # LATIN CAPITAL LETTER E WITH HOOK ABOVE + : "ỉ" # LATIN SMALL LETTER I WITH HOOK ABOVE + : "Ỉ" # LATIN CAPITAL LETTER I WITH HOOK ABOVE + : "ỏ" # LATIN SMALL LETTER O WITH HOOK ABOVE + : "Ỏ" # LATIN CAPITAL LETTER O WITH HOOK ABOVE + : "ủ" # LATIN SMALL LETTER U WITH HOOK ABOVE + : "Ủ" # LATIN CAPITAL LETTER U WITH HOOK ABOVE + : "ỷ" # LATIN SMALL LETTER Y WITH HOOK ABOVE + : "Ỷ" # LATIN CAPITAL LETTER Y WITH HOOK ABOVE + +XCOMM Sequences with COMBINING HORN / + : "ơ" # LATIN SMALL LETTER O WITH HORN + : "ớ" # LATIN SMALL LETTER O WITH HORN AND ACUTE + : "ợ" # LATIN SMALL LETTER O WITH HORN AND DOT BELOW + : "ờ" # LATIN SMALL LETTER O WITH HORN AND GRAVE + : "ờ" # LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE + : "ỡ" # LATIN SMALL LETTER O WITH HORN AND TILDE + : "Ơ" # LATIN CAPITAL LETTER O WITH HORN + : "Ớ" # LATIN CAPITAL LETTER O WITH HORN AND ACUTE + : "Ợ" # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW + : "Ờ" # LATIN CAPITAL LETTER O WITH HORN AND GRAVE + : "Ở" # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE + : "Ỡ" # LATIN CAPITAL LETTER O WITH HORN AND TILDE + : "ư" # LATIN SMALL LETTER U WITH HORN + : "ứ" # LATIN SMALL LETTER U WITH HORN AND ACUTE + : "ự" # LATIN SMALL LETTER U WITH HORN AND DOT BELOW + : "ừ" # LATIN SMALL LETTER U WITH HORN AND GRAVE + : "ử" # LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE + : "ữ" # LATIN SMALL LETTER U WITH HORN AND TILDE + : "Ư" # LATIN CAPITAL LETTER U WITH HORN + : "Ứ" # LATIN CAPITAL LETTER U WITH HORN AND ACUTE + : "Ự" # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW + : "Ừ" # LATIN CAPITAL LETTER U WITH HORN AND GRAVE + : "Ử" # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE + : "Ữ" # LATIN CAPITAL LETTER U WITH HORN AND TILDE + +XCOMM Sequences with COMBINING OGONEK / + : "ǭ" # LATIN SMALL LETTER O WITH OGONEK AND MACRON + : "Ǭ" # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON + +XCOMM Sequences with COMBINING RING ABOVE / + : "ǻ" # LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE + : "Ǻ" # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE + XCOMM Additional sequences from Annex 5 for the reportoire of the MES-2 XCOMM (Multilingual European Subset No. 2 in ISO/IEC 10646, Collection 282) : "ƒ" # LATIN SMALL LETTER F WITH HOOK @@ -312,6 +419,7 @@ XCOMM (Multilingual European Subset No. 2 in ISO/IEC 10646, Collection 282) : "ʼn" # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE : "ɼ" # LATIN SMALL LETTER R WITH LONG LEG : "ſ" # LATIN SMALL LETTER LONG S + : "ẛ" # LATIN SMALL LETTER LONG S WITH DOT ABOVE : "ẛ" # LATIN SMALL LETTER LONG S WITH DOT ABOVE : "ș" # LATIN SMALL LETTER S WITH COMMA BELOW : "Ș" # LATIN CAPITAL LETTER S WITH COMMA BELOW diff --git a/libX11/src/xcms/LRGB.c b/libX11/src/xcms/LRGB.c index 4e9f029e4..7e09db00a 100644 --- a/libX11/src/xcms/LRGB.c +++ b/libX11/src/xcms/LRGB.c @@ -1,1847 +1,1847 @@ - -/* - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System. Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation. TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose. It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. - * - * - * NAME - * XcmsLRGB.c - * - * DESCRIPTION - * This file contains the conversion routines: - * 1. CIE XYZ to RGB intensity - * 2. RGB intensity to device RGB - * 3. device RGB to RGB intensity - * 4. RGB intensity to CIE XYZ - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include "Xlibint.h" -#include "Xcmsint.h" -#include "Cv.h" - -/* - * LOCAL DEFINES - * #define declarations local to this package. - */ -#define EPS 0.001 -#ifndef MIN -#define MIN(x,y) ((x) > (y) ? (y) : (x)) -#endif /* MIN */ -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif /* MAX */ -#ifndef MIN3 -#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) -#endif /* MIN3 */ -#ifndef MAX3 -#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) -#endif /* MAX3 */ - -/* - * LOCAL TYPEDEFS - * typedefs local to this package (for use with local vars). - * - */ - -/* - * FORWARD DECLARATIONS - */ -static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp); -static int LINEAR_RGB_InitSCCData(Display *dpy, - int screenNumber, XcmsPerScrnInfo *pPerScrnInfo); -static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor); -static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor); -static Status -_XcmsGetTableType0( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount); -static Status -_XcmsGetTableType1( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount); - -/* - * LOCALS VARIABLES - * Variables local to this package. - * Usage example: - * static int ExampleLocalVar; - */ - -static unsigned short const MASK[17] = { - 0x0000, /* 0 bitsPerRGB */ - 0x8000, /* 1 bitsPerRGB */ - 0xc000, /* 2 bitsPerRGB */ - 0xe000, /* 3 bitsPerRGB */ - 0xf000, /* 4 bitsPerRGB */ - 0xf800, /* 5 bitsPerRGB */ - 0xfc00, /* 6 bitsPerRGB */ - 0xfe00, /* 7 bitsPerRGB */ - 0xff00, /* 8 bitsPerRGB */ - 0xff80, /* 9 bitsPerRGB */ - 0xffc0, /* 10 bitsPerRGB */ - 0xffe0, /* 11 bitsPerRGB */ - 0xfff0, /* 12 bitsPerRGB */ - 0xfff8, /* 13 bitsPerRGB */ - 0xfffc, /* 14 bitsPerRGB */ - 0xfffe, /* 15 bitsPerRGB */ - 0xffff /* 16 bitsPerRGB */ -}; - - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsRGBFormat - * to XcmsCIEXYZFormat. - */ -static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = { - (XcmsConversionProc)XcmsRGBToRGBi, - (XcmsConversionProc)XcmsRGBiToCIEXYZ, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsCIEXYZFormat - * to XcmsRGBFormat. - */ -static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = { - (XcmsConversionProc)XcmsCIEXYZToRGBi, - (XcmsConversionProc)XcmsRGBiToRGB, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsRGBiFormat - * to XcmsCIEXYZFormat. - */ -static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = { - (XcmsConversionProc)XcmsRGBiToCIEXYZ, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsCIEXYZFormat - * to XcmsRGBiFormat. - */ -static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = { - (XcmsConversionProc)XcmsCIEXYZToRGBi, - NULL -}; - - /* - * RGBi Color Spaces - */ -XcmsColorSpace XcmsRGBiColorSpace = - { - _XcmsRGBi_prefix, /* prefix */ - XcmsRGBiFormat, /* id */ - XcmsLRGB_RGBi_ParseString, /* parseString */ - Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */ - Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */ - 1 - }; - - /* - * RGB Color Spaces - */ -XcmsColorSpace XcmsRGBColorSpace = - { - _XcmsRGB_prefix, /* prefix */ - XcmsRGBFormat, /* id */ - XcmsLRGB_RGB_ParseString, /* parseString */ - Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */ - Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */ - 1 - }; - - /* - * Device-Independent Color Spaces known to the - * LINEAR_RGB Screen Color Characteristics Function Set. - */ -static XcmsColorSpace *DDColorSpaces[] = { - &XcmsRGBColorSpace, - &XcmsRGBiColorSpace, - NULL -}; - - -/* - * GLOBALS - * Variables declared in this package that are allowed - * to be used globally. - */ - - /* - * LINEAR_RGB Screen Color Characteristics Function Set. - */ -XcmsFunctionSet XcmsLinearRGBFunctionSet = - { - &DDColorSpaces[0], /* pDDColorSpaces */ - LINEAR_RGB_InitSCCData, /* pInitScrnFunc */ - LINEAR_RGB_FreeSCCData /* pFreeSCCData */ - }; - -/* - * DESCRIPTION - * Contents of Default SCCData should be replaced if other - * data should be used as default. - * - * - */ - -/* - * NAME Tektronix 19" (Sony) CRT - * PART_NUMBER 119-2451-00 - * MODEL Tek4300, Tek4800 - */ - -static IntensityRec const Default_RGB_RedTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x0909, 0.000000 }, - { 0x0a0a, 0.000936 }, - { 0x0f0f, 0.001481 }, - { 0x1414, 0.002329 }, - { 0x1919, 0.003529 }, - { 0x1e1e, 0.005127 }, - { 0x2323, 0.007169 }, - { 0x2828, 0.009699 }, - { 0x2d2d, 0.012759 }, - { 0x3232, 0.016392 }, - { 0x3737, 0.020637 }, - { 0x3c3c, 0.025533 }, - { 0x4141, 0.031119 }, - { 0x4646, 0.037431 }, - { 0x4b4b, 0.044504 }, - { 0x5050, 0.052373 }, - { 0x5555, 0.061069 }, - { 0x5a5a, 0.070624 }, - { 0x5f5f, 0.081070 }, - { 0x6464, 0.092433 }, - { 0x6969, 0.104744 }, - { 0x6e6e, 0.118026 }, - { 0x7373, 0.132307 }, - { 0x7878, 0.147610 }, - { 0x7d7d, 0.163958 }, - { 0x8282, 0.181371 }, - { 0x8787, 0.199871 }, - { 0x8c8c, 0.219475 }, - { 0x9191, 0.240202 }, - { 0x9696, 0.262069 }, - { 0x9b9b, 0.285089 }, - { 0xa0a0, 0.309278 }, - { 0xa5a5, 0.334647 }, - { 0xaaaa, 0.361208 }, - { 0xafaf, 0.388971 }, - { 0xb4b4, 0.417945 }, - { 0xb9b9, 0.448138 }, - { 0xbebe, 0.479555 }, - { 0xc3c3, 0.512202 }, - { 0xc8c8, 0.546082 }, - { 0xcdcd, 0.581199 }, - { 0xd2d2, 0.617552 }, - { 0xd7d7, 0.655144 }, - { 0xdcdc, 0.693971 }, - { 0xe1e1, 0.734031 }, - { 0xe6e6, 0.775322 }, - { 0xebeb, 0.817837 }, - { 0xf0f0, 0.861571 }, - { 0xf5f5, 0.906515 }, - { 0xfafa, 0.952662 }, - { 0xffff, 1.000000 } -}; - -static IntensityRec const Default_RGB_GreenTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x1313, 0.000000 }, - { 0x1414, 0.000832 }, - { 0x1919, 0.001998 }, - { 0x1e1e, 0.003612 }, - { 0x2323, 0.005736 }, - { 0x2828, 0.008428 }, - { 0x2d2d, 0.011745 }, - { 0x3232, 0.015740 }, - { 0x3737, 0.020463 }, - { 0x3c3c, 0.025960 }, - { 0x4141, 0.032275 }, - { 0x4646, 0.039449 }, - { 0x4b4b, 0.047519 }, - { 0x5050, 0.056520 }, - { 0x5555, 0.066484 }, - { 0x5a5a, 0.077439 }, - { 0x5f5f, 0.089409 }, - { 0x6464, 0.102418 }, - { 0x6969, 0.116485 }, - { 0x6e6e, 0.131625 }, - { 0x7373, 0.147853 }, - { 0x7878, 0.165176 }, - { 0x7d7d, 0.183604 }, - { 0x8282, 0.203140 }, - { 0x8787, 0.223783 }, - { 0x8c8c, 0.245533 }, - { 0x9191, 0.268384 }, - { 0x9696, 0.292327 }, - { 0x9b9b, 0.317351 }, - { 0xa0a0, 0.343441 }, - { 0xa5a5, 0.370580 }, - { 0xaaaa, 0.398747 }, - { 0xafaf, 0.427919 }, - { 0xb4b4, 0.458068 }, - { 0xb9b9, 0.489165 }, - { 0xbebe, 0.521176 }, - { 0xc3c3, 0.554067 }, - { 0xc8c8, 0.587797 }, - { 0xcdcd, 0.622324 }, - { 0xd2d2, 0.657604 }, - { 0xd7d7, 0.693588 }, - { 0xdcdc, 0.730225 }, - { 0xe1e1, 0.767459 }, - { 0xe6e6, 0.805235 }, - { 0xebeb, 0.843491 }, - { 0xf0f0, 0.882164 }, - { 0xf5f5, 0.921187 }, - { 0xfafa, 0.960490 }, - { 0xffff, 1.000000 } -}; - -static IntensityRec const Default_RGB_BlueTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x0e0e, 0.000000 }, - { 0x0f0f, 0.001341 }, - { 0x1414, 0.002080 }, - { 0x1919, 0.003188 }, - { 0x1e1e, 0.004729 }, - { 0x2323, 0.006766 }, - { 0x2828, 0.009357 }, - { 0x2d2d, 0.012559 }, - { 0x3232, 0.016424 }, - { 0x3737, 0.021004 }, - { 0x3c3c, 0.026344 }, - { 0x4141, 0.032489 }, - { 0x4646, 0.039481 }, - { 0x4b4b, 0.047357 }, - { 0x5050, 0.056154 }, - { 0x5555, 0.065903 }, - { 0x5a5a, 0.076634 }, - { 0x5f5f, 0.088373 }, - { 0x6464, 0.101145 }, - { 0x6969, 0.114968 }, - { 0x6e6e, 0.129862 }, - { 0x7373, 0.145841 }, - { 0x7878, 0.162915 }, - { 0x7d7d, 0.181095 }, - { 0x8282, 0.200386 }, - { 0x8787, 0.220791 }, - { 0x8c8c, 0.242309 }, - { 0x9191, 0.264937 }, - { 0x9696, 0.288670 }, - { 0x9b9b, 0.313499 }, - { 0xa0a0, 0.339410 }, - { 0xa5a5, 0.366390 }, - { 0xaaaa, 0.394421 }, - { 0xafaf, 0.423481 }, - { 0xb4b4, 0.453547 }, - { 0xb9b9, 0.484592 }, - { 0xbebe, 0.516587 }, - { 0xc3c3, 0.549498 }, - { 0xc8c8, 0.583291 }, - { 0xcdcd, 0.617925 }, - { 0xd2d2, 0.653361 }, - { 0xd7d7, 0.689553 }, - { 0xdcdc, 0.726454 }, - { 0xe1e1, 0.764013 }, - { 0xe6e6, 0.802178 }, - { 0xebeb, 0.840891 }, - { 0xf0f0, 0.880093 }, - { 0xf5f5, 0.919723 }, - { 0xfafa, 0.959715 }, - { 0xffff, 1.00000 } -}; - -static IntensityTbl Default_RGB_RedTbl = { - /* IntensityRec *pBase */ - (IntensityRec *) Default_RGB_RedTuples, - /* unsigned int nEntries */ - 52 -}; - -static IntensityTbl Default_RGB_GreenTbl = { - /* IntensityRec *pBase */ - (IntensityRec *)Default_RGB_GreenTuples, - /* unsigned int nEntries */ - 50 -}; - -static IntensityTbl Default_RGB_BlueTbl = { - /* IntensityRec *pBase */ - (IntensityRec *)Default_RGB_BlueTuples, - /* unsigned int nEntries */ - 51 -}; - -static LINEAR_RGB_SCCData Default_RGB_SCCData = { - /* XcmsFloat XYZtoRGBmatrix[3][3] */ - { - { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 }, - {-1.07152751306193600, 1.96593795204372400, 0.03673691339553462 }, - { 0.06351179790497788, -0.20020501000496480, 0.81070942031648220 } - }, - - /* XcmsFloat RGBtoXYZmatrix[3][3] */ - { - { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 }, - { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 }, - { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 } - }, - - /* IntensityTbl *pRedTbl */ - &Default_RGB_RedTbl, - - /* IntensityTbl *pGreenTbl */ - &Default_RGB_GreenTbl, - - /* IntensityTbl *pBlueTbl */ - &Default_RGB_BlueTbl -}; - -/************************************************************************ - * * - * PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * LINEAR_RGB_InitSCCData() - * - * SYNOPSIS - */ -static Status -LINEAR_RGB_InitSCCData( - Display *dpy, - int screenNumber, - XcmsPerScrnInfo *pPerScrnInfo) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); - Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); - int format_return, count, cType, nTables; - unsigned long nitems, nbytes_return; - char *property_return, *pChar; - XcmsFloat *pValue; -#ifdef ALLDEBUG - IntensityRec *pIRec; -#endif /* ALLDEBUG */ - VisualID visualID; - - LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData; - XcmsIntensityMap *pNewMap; - - /* - * Allocate memory for pScreenData - */ - if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) - Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { - return(XcmsFailure); - } - - /* - * 1. Get the XYZ->RGB and RGB->XYZ matrices - */ - - if (MatrixAtom == None || - !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, - &format_return, &nitems, &nbytes_return, &property_return) || - nitems != 18 || format_return != 32) { - /* - * As per the XDCCC, there must be 18 data items and each must be - * in 32 bits ! - */ - goto FreeSCCData; - - } else { - - /* - * RGBtoXYZ and XYZtoRGB matrices - */ - pValue = (XcmsFloat *) pScreenData; - pChar = property_return; - for (count = 0; count < 18; count++) { - *pValue++ = (long)_XcmsGetElement(format_return, &pChar, - &nitems) / (XcmsFloat)XDCCC_NUMBER; - } - Xfree ((char *)property_return); - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = - pScreenData->RGBtoXYZmatrix[0][0] + - pScreenData->RGBtoXYZmatrix[0][1] + - pScreenData->RGBtoXYZmatrix[0][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = - pScreenData->RGBtoXYZmatrix[1][0] + - pScreenData->RGBtoXYZmatrix[1][1] + - pScreenData->RGBtoXYZmatrix[1][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = - pScreenData->RGBtoXYZmatrix[2][0] + - pScreenData->RGBtoXYZmatrix[2][1] + - pScreenData->RGBtoXYZmatrix[2][2]; - - /* - * Compute the Screen White Point - */ - if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) - || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { - goto FreeSCCData; - } else { - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; - } - pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; - pPerScrnInfo->screenWhitePt.pixel = 0; - -#ifdef PDEBUG - printf ("RGB to XYZ Matrix values:\n"); - printf (" %f %f %f\n %f %f %f\n %f %f %f\n", - pScreenData->RGBtoXYZmatrix[0][0], - pScreenData->RGBtoXYZmatrix[0][1], - pScreenData->RGBtoXYZmatrix[0][2], - pScreenData->RGBtoXYZmatrix[1][0], - pScreenData->RGBtoXYZmatrix[1][1], - pScreenData->RGBtoXYZmatrix[1][2], - pScreenData->RGBtoXYZmatrix[2][0], - pScreenData->RGBtoXYZmatrix[2][1], - pScreenData->RGBtoXYZmatrix[2][2]); - printf ("XYZ to RGB Matrix values:\n"); - printf (" %f %f %f\n %f %f %f\n %f %f %f\n", - pScreenData->XYZtoRGBmatrix[0][0], - pScreenData->XYZtoRGBmatrix[0][1], - pScreenData->XYZtoRGBmatrix[0][2], - pScreenData->XYZtoRGBmatrix[1][0], - pScreenData->XYZtoRGBmatrix[1][1], - pScreenData->XYZtoRGBmatrix[1][2], - pScreenData->XYZtoRGBmatrix[2][0], - pScreenData->XYZtoRGBmatrix[2][1], - pScreenData->XYZtoRGBmatrix[2][2]); - printf ("Screen White Pt value: %f %f %f\n", - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X, - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y, - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z); -#endif /* PDEBUG */ - } - - /* - * 2. Get the Intensity Profile - */ - if (CorrectAtom == None || - !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom, - &format_return, &nitems, &nbytes_return, &property_return)) { - Xfree ((char *)property_return); - goto FreeSCCData; - } - - pChar = property_return; - - while (nitems) { - switch (format_return) { - case 8: - /* - * Must have at least: - * VisualID0 - * VisualID1 - * VisualID2 - * VisualID3 - * type - * count - * length - * intensity1 - * intensity2 - */ - if (nitems < 9) { - 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)))) { - return(XcmsFailure); - } - /* copy matrices */ - memcpy((char *)pScreenData, (char *)pScreenDefaultData, - 18 * sizeof(XcmsFloat)); - - /* Create, initialize, and add map */ - if (!(pNewMap = (XcmsIntensityMap *) - Xcalloc (1, sizeof(XcmsIntensityMap)))) { - Xfree((char *)pScreenData); - return(XcmsFailure); - } - pNewMap->visualID = visualID; - pNewMap->screenData = (XPointer)pScreenData; - pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData; - pNewMap->pNext = - (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; - dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap; - dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps; - } - - cType = _XcmsGetElement(format_return, &pChar, &nitems); - nTables = _XcmsGetElement(format_return, &pChar, &nitems); - - if (cType == 0) { - - /* Red Intensity Table */ - if (!(pScreenData->pRedTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto 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; - - 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; - return(XcmsFailure); -} - - -/* - * NAME - * LINEAR_RGB_FreeSCCData() - * - * SYNOPSIS - */ -static void -LINEAR_RGB_FreeSCCData( - XPointer pScreenDataTemp) -/* - * DESCRIPTION - * - * RETURNS - * 0 if failed. - * 1 if succeeded with no modifications. - * - */ -{ - LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp; - - if (pScreenData && pScreenData != &Default_RGB_SCCData) { - if (pScreenData->pRedTbl) { - if (pScreenData->pGreenTbl) { - if (pScreenData->pRedTbl->pBase != - pScreenData->pGreenTbl->pBase) { - if (pScreenData->pGreenTbl->pBase) { - Xfree ((char *)pScreenData->pGreenTbl->pBase); - } - } - if (pScreenData->pGreenTbl != pScreenData->pRedTbl) { - Xfree ((char *)pScreenData->pGreenTbl); - } - } - if (pScreenData->pBlueTbl) { - if (pScreenData->pRedTbl->pBase != - pScreenData->pBlueTbl->pBase) { - if (pScreenData->pBlueTbl->pBase) { - Xfree ((char *)pScreenData->pBlueTbl->pBase); - } - } - if (pScreenData->pBlueTbl != pScreenData->pRedTbl) { - Xfree ((char *)pScreenData->pBlueTbl); - } - } - if (pScreenData->pRedTbl->pBase) { - Xfree ((char *)pScreenData->pRedTbl->pBase); - } - Xfree ((char *)pScreenData->pRedTbl); - } - Xfree ((char *)pScreenData); - } -} - - - -/************************************************************************ - * * - * API PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * _XcmsGetTableType0 - * - * SYNOPSIS - */ -static Status -_XcmsGetTableType0( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - unsigned int nElements; - IntensityRec *pIRec; - - nElements = pTbl->nEntries = - _XcmsGetElement(format, pChar, pCount) + 1; - if (!(pIRec = pTbl->pBase = (IntensityRec *) - Xcalloc (nElements, sizeof(IntensityRec)))) { - return(XcmsFailure); - } - - switch (format) { - case 8: - for (; nElements--; pIRec++) { - /* 0xFFFF/0xFF = 0x101 */ - pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; - pIRec->intensity = - _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; - } - break; - case 16: - for (; nElements--; pIRec++) { - pIRec->value = _XcmsGetElement (format, pChar, pCount); - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)65535.0; - } - break; - case 32: - for (; nElements--; pIRec++) { - pIRec->value = _XcmsGetElement (format, pChar, pCount); - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)4294967295.0; - } - break; - default: - return(XcmsFailure); - } - return(XcmsSuccess); -} - - -/* - * NAME - * _XcmsGetTableType1 - * - * SYNOPSIS - */ -static Status -_XcmsGetTableType1( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - int count; - unsigned int max_index; - IntensityRec *pIRec; - - max_index = _XcmsGetElement(format, pChar, pCount); - pTbl->nEntries = max_index + 1; - if (!(pIRec = pTbl->pBase = (IntensityRec *) - Xcalloc (max_index+1, sizeof(IntensityRec)))) { - return(XcmsFailure); - } - - switch (format) { - case 8: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)255.0; - } - break; - case 16: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)65535.0; - } - break; - case 32: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)4294967295.0; - } - break; - default: - return(XcmsFailure); - } - - return(XcmsSuccess); -} - - -/* - * NAME - * ValueCmp - * - * SYNOPSIS - */ -static int -_XcmsValueCmp( - IntensityRec *p1, IntensityRec *p2) -/* - * DESCRIPTION - * Compares the value component of two IntensityRec - * structures. - * - * RETURNS - * 0 if p1->value is equal to p2->value - * < 0 if p1->value is less than p2->value - * > 0 if p1->value is greater than p2->value - * - */ -{ - return (p1->value - p2->value); -} - - -/* - * NAME - * IntensityCmp - * - * SYNOPSIS - */ -static int -_XcmsIntensityCmp( - IntensityRec *p1, IntensityRec *p2) -/* - * DESCRIPTION - * Compares the intensity component of two IntensityRec - * structures. - * - * RETURNS - * 0 if equal; - * < 0 if first precedes second - * > 0 if first succeeds second - * - */ -{ - if (p1->intensity < p2->intensity) { - return (-1); - } - if (p1->intensity > p2->intensity) { - return (XcmsSuccess); - } - return (XcmsFailure); -} - -/* - * NAME - * ValueInterpolation - * - * SYNOPSIS - */ -/* ARGSUSED */ -static int -_XcmsValueInterpolation( - IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, - int bitsPerRGB) -/* - * DESCRIPTION - * Based on a given value, performs a linear interpolation - * on the intensities between two IntensityRec structures. - * Note that the bitsPerRGB parameter is ignored. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - */ -{ - XcmsFloat ratio; - - ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / - ((XcmsFloat)hi->value - (XcmsFloat)lo->value); - answer->value = key->value; - answer->intensity = (hi->intensity - lo->intensity) * ratio; - answer->intensity += lo->intensity; - return (XcmsSuccess); -} - -/* - * NAME - * IntensityInterpolation - * - * SYNOPSIS - */ -static int -_XcmsIntensityInterpolation( - IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, - int bitsPerRGB) -/* - * DESCRIPTION - * Based on a given intensity, performs a linear interpolation - * on the values between two IntensityRec structures. - * The bitsPerRGB parameter is necessary to perform rounding - * to the correct number of significant bits. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - */ -{ - XcmsFloat ratio; - long target, up, down; - int shift = 16 - bitsPerRGB; - int max_color = (1 << bitsPerRGB) - 1; - - ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); - answer->intensity = key->intensity; - target = hi->value - lo->value; - target *= ratio; - target += lo->value; - - /* - * Ok now, lets find the closest in respects to bits per RGB - */ - up = ((target >> shift) * 0xFFFF) / max_color; - if (up < target) { - down = up; - up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; - } else { - down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; - } - answer->value = ((up - target) < (target - down) ? up : down); - answer->value &= MASK[bitsPerRGB]; - return (XcmsSuccess); -} - - - -typedef int (*comparProcp)( - char *p1, - char *p2); -typedef int (*interpolProcp)( - char *key, - char *lo, - char *hi, - char *answer, - int bitsPerRGB); - -/* - * NAME - * _XcmsTableSearch - * - * SYNOPSIS - */ -static int -_XcmsTableSearch( - char *key, - int bitsPerRGB, - char *base, - unsigned nel, - unsigned nKeyPtrSize, - int (*compar)( - char *p1, - char *p2), - int (*interpol)( - char *key, - char *lo, - char *hi, - char *answer, - int bitsPerRGB), - char *answer) - -/* - * DESCRIPTION - * A binary search through the specificied table. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - * - */ -{ - char *hi, *lo, *mid, *last; - int result; - - last = hi = base + ((nel - 1) * nKeyPtrSize); - mid = lo = base; - - /* use only the significants bits, then scale into 16 bits */ - ((IntensityRec *)key)->value = ((unsigned long) - (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) - / ((1 << bitsPerRGB) - 1); - - /* Special case so that zero intensity always maps to zero value */ - if ((*compar) (key,lo) <= 0) { - memcpy (answer, lo, nKeyPtrSize); - ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; - return XcmsSuccess; - } - while (mid != last) { - last = mid; - mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; - result = (*compar) (key, mid); - if (result == 0) { - - memcpy(answer, mid, nKeyPtrSize); - ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; - return (XcmsSuccess); - } else if (result < 0) { - hi = mid; - } else { - lo = mid; - } - } - - /* - * If we got to here, we didn't find a solution, so we - * need to apply interpolation. - */ - return ((*interpol)(key, lo, hi, answer, bitsPerRGB)); -} - - -/* - * NAME - * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector - * - * SYNOPSIS - */ -static void _XcmsMatVec( - XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut) -/* - * DESCRIPTION - * Multiply the passed vector by the passed matrix to return a - * vector. Matrix is 3x3, vectors are of length 3. - * - * RETURNS - * void - */ -{ - int i, j; - - for (i = 0; i < 3; i++) { - pOut[i] = 0.0; - for (j = 0; j < 3; j++) - pOut[i] += *(pMat+(i*3)+j) * pIn[j]; - } -} - - -/************************************************************************ - * * - * PUBLIC ROUTINES * - * * - ************************************************************************/ - - -/* - * NAME - * XcmsLRGB_RGB_ParseString - * - * SYNOPSIS - */ -static int -XcmsLRGB_RGB_ParseString( - register char *spec, - XcmsColor *pColor) -/* - * DESCRIPTION - * This routines takes a string and attempts to convert - * it into a XcmsColor structure with XcmsRGBFormat. - * - * RETURNS - * 0 if failed, non-zero otherwise. - */ -{ - register int n, i; - unsigned short r, g, b; - char c; - char *pchar; - unsigned short *pShort; - - /* - * Check for old # format - */ - if (*spec == '#') { - /* - * Attempt to parse the value portion. - */ - spec++; - n = strlen(spec); - if (n != 3 && n != 6 && n != 9 && n != 12) { - return(XcmsFailure); - } - - n /= 3; - g = b = 0; - do { - r = g; - g = b; - b = 0; - for (i = n; --i >= 0; ) { - c = *spec++; - b <<= 4; - if (c >= '0' && c <= '9') - b |= c - '0'; - /* assume string in lowercase - else if (c >= 'A' && c <= 'F') - b |= c - ('A' - 10); - */ - else if (c >= 'a' && c <= 'f') - b |= c - ('a' - 10); - else return (XcmsFailure); - } - } while (*spec != '\0'); - - /* - * Succeeded ! - */ - n <<= 2; - n = 16 - n; - /* shift instead of scale, to match old broken semantics */ - pColor->spec.RGB.red = r << n; - pColor->spec.RGB.green = g << n; - pColor->spec.RGB.blue = b << n; - } else { - if ((pchar = strchr(spec, ':')) == NULL) { - return(XcmsFailure); - } - n = (int)(pchar - spec); - - /* - * Check for proper prefix. - */ - if (strncmp(spec, _XcmsRGB_prefix, n) != 0) { - return(XcmsFailure); - } - - /* - * Attempt to parse the value portion. - */ - spec += (n + 1); - pShort = &pColor->spec.RGB.red; - for (i = 0; i < 3; i++, pShort++, spec++) { - n = 0; - *pShort = 0; - while (*spec != '/' && *spec != '\0') { - if (++n > 4) { - return(XcmsFailure); - } - c = *spec++; - *pShort <<= 4; - if (c >= '0' && c <= '9') - *pShort |= c - '0'; - /* assume string in lowercase - else if (c >= 'A' && c <= 'F') - *pShort |= c - ('A' - 10); - */ - else if (c >= 'a' && c <= 'f') - *pShort |= c - ('a' - 10); - else return (XcmsFailure); - } - if (n == 0) - return (XcmsFailure); - if (n < 4) { - *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); - } - } - } - pColor->format = XcmsRGBFormat; - pColor->pixel = 0; - return (XcmsSuccess); -} - - -/* - * NAME - * XcmsLRGB_RGBi_ParseString - * - * SYNOPSIS - */ -static int -XcmsLRGB_RGBi_ParseString( - register char *spec, - XcmsColor *pColor) -/* - * DESCRIPTION - * This routines takes a string and attempts to convert - * it into a XcmsColor structure with XcmsRGBiFormat. - * The assumed RGBi string syntax is: - * RGBi:// - * Where r, g, and b are in string input format for floats - * consisting of: - * a. an optional sign - * b. a string of numbers possibly containing a decimal point, - * c. an optional exponent field containing an 'E' or 'e' - * followed by a possibly signed integer string. - * - * RETURNS - * 0 if failed, non-zero otherwise. - */ -{ - int n; - char *pchar; - - if ((pchar = strchr(spec, ':')) == NULL) { - return(XcmsFailure); - } - n = (int)(pchar - spec); - - /* - * Check for proper prefix. - */ - if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) { - return(XcmsFailure); - } - - /* - * Attempt to parse the value portion. - */ - if (sscanf(spec + n + 1, "%lf/%lf/%lf", - &pColor->spec.RGBi.red, - &pColor->spec.RGBi.green, - &pColor->spec.RGBi.blue) != 3) { - char *s; /* Maybe failed due to locale */ - int f; - if ((s = strdup(spec))) { - for (f = 0; s[f]; ++f) - if (s[f] == '.') - s[f] = ','; - else if (s[f] == ',') - s[f] = '.'; - if (sscanf(s + n + 1, "%lf/%lf/%lf", - &pColor->spec.RGBi.red, - &pColor->spec.RGBi.green, - &pColor->spec.RGBi.blue) != 3) { - free(s); - return(XcmsFailure); - } - free(s); - } else - return(XcmsFailure); - } - - /* - * Succeeded ! - */ - pColor->format = XcmsRGBiFormat; - pColor->pixel = 0; - return (XcmsSuccess); -} - - -/* - * NAME - * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsCIEXYZToRGBi( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to an array of Bool */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGB format to RGBi format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded without gamut compression. - * XcmsSuccessWithCompression if succeeded with gamut - * compression. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsFloat tmp[3]; - int hasCompressed = 0; - unsigned int i; - XcmsColor *pColor = pXcmsColors_in_out; - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - /* - * XcmsColors should be White Point Adjusted, if necessary, by now! - */ - - /* - * NEW!!! for extended gamut compression - * - * 1. Need to zero out pCompressed - * - * 2. Need to save initial address of pColor - * - * 3. Need to save initial address of pCompressed - */ - - for (i = 0; i < nColors; i++) { - - /* Make sure format is XcmsCIEXYZFormat */ - if (pColor->format != XcmsCIEXYZFormat) { - return(XcmsFailure); - } - - /* Multiply [A]-1 * [XYZ] to get RGB intensity */ - _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, - (XcmsFloat *) &pColor->spec, tmp); - - if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || - (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { - - /* - * RGBi out of screen's gamut - */ - - if (ccc->gamutCompProc == NULL) { - /* - * Aha!! Here's that little trick that will allow - * gamut compression routines to get the out of bound - * RGBi. - */ - memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); - pColor->format = XcmsRGBiFormat; - return(XcmsFailure); - } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors, - i, pCompressed) == 0) { - return(XcmsFailure); - } - - /* - * The gamut compression function should return colors in CIEXYZ - * Also check again to if the new color is within gamut. - */ - if (pColor->format != XcmsCIEXYZFormat) { - return(XcmsFailure); - } - _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, - (XcmsFloat *) &pColor->spec, tmp); - if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || - (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { - return(XcmsFailure); - } - hasCompressed++; - } - memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); - /* These if statements are done to ensure the fudge factor is */ - /* is taken into account. */ - if (pColor->spec.RGBi.red < 0.0) { - pColor->spec.RGBi.red = 0.0; - } else if (pColor->spec.RGBi.red > 1.0) { - pColor->spec.RGBi.red = 1.0; - } - if (pColor->spec.RGBi.green < 0.0) { - pColor->spec.RGBi.green = 0.0; - } else if (pColor->spec.RGBi.green > 1.0) { - pColor->spec.RGBi.green = 1.0; - } - if (pColor->spec.RGBi.blue < 0.0) { - pColor->spec.RGBi.blue = 0.0; - } else if (pColor->spec.RGBi.blue > 1.0) { - pColor->spec.RGBi.blue = 1.0; - } - (pColor++)->format = XcmsRGBiFormat; - } - return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); -} - - -/* - * NAME - * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToCIEXYZ( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGBi format to CIEXYZ format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsFloat tmp[3]; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - /* - * XcmsColors should be White Point Adjusted, if necessary, by now! - */ - - while (nColors--) { - - /* Multiply [A]-1 * [XYZ] to get RGB intensity */ - _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix, - (XcmsFloat *) &pXcmsColors_in_out->spec, tmp); - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp)); - (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat; - } - return(XcmsSuccess); -} - - -/* - * NAME - * XcmsRGBiToRGB - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToRGB( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGBi format to RGB format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded without gamut compression. - * XcmsSuccessWithCompression if succeeded with gamut - * compression. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsRGB tmpRGB; - IntensityRec keyIRec, answerIRec; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - while (nColors--) { - - /* Make sure format is XcmsRGBiFormat */ - if (pXcmsColors_in_out->format != XcmsRGBiFormat) { - return(XcmsFailure); - } - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pRedTbl->pBase, - (unsigned)pScreenData->pRedTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.red = answerIRec.value; - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pGreenTbl->pBase, - (unsigned)pScreenData->pGreenTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.green = answerIRec.value; - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pBlueTbl->pBase, - (unsigned)pScreenData->pBlueTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.blue = answerIRec.value; - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB)); - (pXcmsColors_in_out++)->format = XcmsRGBFormat; - } - return(XcmsSuccess); -} - - -/* - * NAME - * XcmsRGBToRGBi - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBToRGBi( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGB format to RGBi format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsRGBi tmpRGBi; - IntensityRec keyIRec, answerIRec; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - while (nColors--) { - - /* Make sure format is XcmsRGBFormat */ - if (pXcmsColors_in_out->format != XcmsRGBFormat) { - return(XcmsFailure); - } - - keyIRec.value = pXcmsColors_in_out->spec.RGB.red; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pRedTbl->pBase, - (unsigned)pScreenData->pRedTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.red = answerIRec.intensity; - - keyIRec.value = pXcmsColors_in_out->spec.RGB.green; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pGreenTbl->pBase, - (unsigned)pScreenData->pGreenTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.green = answerIRec.intensity; - - keyIRec.value = pXcmsColors_in_out->spec.RGB.blue; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pBlueTbl->pBase, - (unsigned)pScreenData->pBlueTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.blue = answerIRec.intensity; - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi)); - (pXcmsColors_in_out++)->format = XcmsRGBiFormat; - } - return(XcmsSuccess); -} - -/* - * NAME - * _XcmsInitScrnDefaultInfo - * - * SYNOPSIS - */ -/* ARGSUSED */ -int -_XcmsLRGB_InitScrnDefault( - Display *dpy, - int screenNumber, - XcmsPerScrnInfo *pPerScrnInfo) -/* - * DESCRIPTION - * Given a display and screen number, this routine attempts - * to initialize the Xcms per Screen Info structure - * (XcmsPerScrnInfo) with defaults. - * - * RETURNS - * Returns zero if initialization failed; non-zero otherwise. - */ -{ - pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = - Default_RGB_SCCData.RGBtoXYZmatrix[0][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[0][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[0][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = - Default_RGB_SCCData.RGBtoXYZmatrix[1][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[1][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[1][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = - Default_RGB_SCCData.RGBtoXYZmatrix[2][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[2][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[2][2]; - if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) - || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { - pPerScrnInfo->screenData = (XPointer)NULL; - pPerScrnInfo->state = XcmsInitNone; - return(0); - } - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; - pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; - pPerScrnInfo->screenWhitePt.pixel = 0; - pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet; - pPerScrnInfo->state = XcmsInitFailure; /* default initialization */ - return(1); -} + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsLRGB.c + * + * DESCRIPTION + * This file contains the conversion routines: + * 1. CIE XYZ to RGB intensity + * 2. RGB intensity to device RGB + * 3. device RGB to RGB intensity + * 4. RGB intensity to CIE XYZ + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include "Xlibint.h" +#include "Xcmsint.h" +#include "Cv.h" + +/* + * LOCAL DEFINES + * #define declarations local to this package. + */ +#define EPS 0.001 +#ifndef MIN +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#endif /* MIN */ +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif /* MAX */ +#ifndef MIN3 +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#endif /* MIN3 */ +#ifndef MAX3 +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#endif /* MAX3 */ + +/* + * LOCAL TYPEDEFS + * typedefs local to this package (for use with local vars). + * + */ + +/* + * FORWARD DECLARATIONS + */ +static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp); +static int LINEAR_RGB_InitSCCData(Display *dpy, + int screenNumber, XcmsPerScrnInfo *pPerScrnInfo); +static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor); +static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor); +static Status +_XcmsGetTableType0( + IntensityTbl *pTbl, + int format, + char **pChar, + unsigned long *pCount); +static Status +_XcmsGetTableType1( + IntensityTbl *pTbl, + int format, + char **pChar, + unsigned long *pCount); + +/* + * LOCALS VARIABLES + * Variables local to this package. + * Usage example: + * static int ExampleLocalVar; + */ + +static unsigned short const MASK[17] = { + 0x0000, /* 0 bitsPerRGB */ + 0x8000, /* 1 bitsPerRGB */ + 0xc000, /* 2 bitsPerRGB */ + 0xe000, /* 3 bitsPerRGB */ + 0xf000, /* 4 bitsPerRGB */ + 0xf800, /* 5 bitsPerRGB */ + 0xfc00, /* 6 bitsPerRGB */ + 0xfe00, /* 7 bitsPerRGB */ + 0xff00, /* 8 bitsPerRGB */ + 0xff80, /* 9 bitsPerRGB */ + 0xffc0, /* 10 bitsPerRGB */ + 0xffe0, /* 11 bitsPerRGB */ + 0xfff0, /* 12 bitsPerRGB */ + 0xfff8, /* 13 bitsPerRGB */ + 0xfffc, /* 14 bitsPerRGB */ + 0xfffe, /* 15 bitsPerRGB */ + 0xffff /* 16 bitsPerRGB */ +}; + + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsRGBFormat + * to XcmsCIEXYZFormat. + */ +static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = { + (XcmsConversionProc)XcmsRGBToRGBi, + (XcmsConversionProc)XcmsRGBiToCIEXYZ, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsCIEXYZFormat + * to XcmsRGBFormat. + */ +static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = { + (XcmsConversionProc)XcmsCIEXYZToRGBi, + (XcmsConversionProc)XcmsRGBiToRGB, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsRGBiFormat + * to XcmsCIEXYZFormat. + */ +static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = { + (XcmsConversionProc)XcmsRGBiToCIEXYZ, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsCIEXYZFormat + * to XcmsRGBiFormat. + */ +static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = { + (XcmsConversionProc)XcmsCIEXYZToRGBi, + NULL +}; + + /* + * RGBi Color Spaces + */ +XcmsColorSpace XcmsRGBiColorSpace = + { + _XcmsRGBi_prefix, /* prefix */ + XcmsRGBiFormat, /* id */ + XcmsLRGB_RGBi_ParseString, /* parseString */ + Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */ + 1 + }; + + /* + * RGB Color Spaces + */ +XcmsColorSpace XcmsRGBColorSpace = + { + _XcmsRGB_prefix, /* prefix */ + XcmsRGBFormat, /* id */ + XcmsLRGB_RGB_ParseString, /* parseString */ + Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */ + 1 + }; + + /* + * Device-Independent Color Spaces known to the + * LINEAR_RGB Screen Color Characteristics Function Set. + */ +static XcmsColorSpace *DDColorSpaces[] = { + &XcmsRGBColorSpace, + &XcmsRGBiColorSpace, + NULL +}; + + +/* + * GLOBALS + * Variables declared in this package that are allowed + * to be used globally. + */ + + /* + * LINEAR_RGB Screen Color Characteristics Function Set. + */ +XcmsFunctionSet XcmsLinearRGBFunctionSet = + { + &DDColorSpaces[0], /* pDDColorSpaces */ + LINEAR_RGB_InitSCCData, /* pInitScrnFunc */ + LINEAR_RGB_FreeSCCData /* pFreeSCCData */ + }; + +/* + * DESCRIPTION + * Contents of Default SCCData should be replaced if other + * data should be used as default. + * + * + */ + +/* + * NAME Tektronix 19" (Sony) CRT + * PART_NUMBER 119-2451-00 + * MODEL Tek4300, Tek4800 + */ + +static IntensityRec const Default_RGB_RedTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + { 0x0000, 0.000000 }, + { 0x0909, 0.000000 }, + { 0x0a0a, 0.000936 }, + { 0x0f0f, 0.001481 }, + { 0x1414, 0.002329 }, + { 0x1919, 0.003529 }, + { 0x1e1e, 0.005127 }, + { 0x2323, 0.007169 }, + { 0x2828, 0.009699 }, + { 0x2d2d, 0.012759 }, + { 0x3232, 0.016392 }, + { 0x3737, 0.020637 }, + { 0x3c3c, 0.025533 }, + { 0x4141, 0.031119 }, + { 0x4646, 0.037431 }, + { 0x4b4b, 0.044504 }, + { 0x5050, 0.052373 }, + { 0x5555, 0.061069 }, + { 0x5a5a, 0.070624 }, + { 0x5f5f, 0.081070 }, + { 0x6464, 0.092433 }, + { 0x6969, 0.104744 }, + { 0x6e6e, 0.118026 }, + { 0x7373, 0.132307 }, + { 0x7878, 0.147610 }, + { 0x7d7d, 0.163958 }, + { 0x8282, 0.181371 }, + { 0x8787, 0.199871 }, + { 0x8c8c, 0.219475 }, + { 0x9191, 0.240202 }, + { 0x9696, 0.262069 }, + { 0x9b9b, 0.285089 }, + { 0xa0a0, 0.309278 }, + { 0xa5a5, 0.334647 }, + { 0xaaaa, 0.361208 }, + { 0xafaf, 0.388971 }, + { 0xb4b4, 0.417945 }, + { 0xb9b9, 0.448138 }, + { 0xbebe, 0.479555 }, + { 0xc3c3, 0.512202 }, + { 0xc8c8, 0.546082 }, + { 0xcdcd, 0.581199 }, + { 0xd2d2, 0.617552 }, + { 0xd7d7, 0.655144 }, + { 0xdcdc, 0.693971 }, + { 0xe1e1, 0.734031 }, + { 0xe6e6, 0.775322 }, + { 0xebeb, 0.817837 }, + { 0xf0f0, 0.861571 }, + { 0xf5f5, 0.906515 }, + { 0xfafa, 0.952662 }, + { 0xffff, 1.000000 } +}; + +static IntensityRec const Default_RGB_GreenTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + { 0x0000, 0.000000 }, + { 0x1313, 0.000000 }, + { 0x1414, 0.000832 }, + { 0x1919, 0.001998 }, + { 0x1e1e, 0.003612 }, + { 0x2323, 0.005736 }, + { 0x2828, 0.008428 }, + { 0x2d2d, 0.011745 }, + { 0x3232, 0.015740 }, + { 0x3737, 0.020463 }, + { 0x3c3c, 0.025960 }, + { 0x4141, 0.032275 }, + { 0x4646, 0.039449 }, + { 0x4b4b, 0.047519 }, + { 0x5050, 0.056520 }, + { 0x5555, 0.066484 }, + { 0x5a5a, 0.077439 }, + { 0x5f5f, 0.089409 }, + { 0x6464, 0.102418 }, + { 0x6969, 0.116485 }, + { 0x6e6e, 0.131625 }, + { 0x7373, 0.147853 }, + { 0x7878, 0.165176 }, + { 0x7d7d, 0.183604 }, + { 0x8282, 0.203140 }, + { 0x8787, 0.223783 }, + { 0x8c8c, 0.245533 }, + { 0x9191, 0.268384 }, + { 0x9696, 0.292327 }, + { 0x9b9b, 0.317351 }, + { 0xa0a0, 0.343441 }, + { 0xa5a5, 0.370580 }, + { 0xaaaa, 0.398747 }, + { 0xafaf, 0.427919 }, + { 0xb4b4, 0.458068 }, + { 0xb9b9, 0.489165 }, + { 0xbebe, 0.521176 }, + { 0xc3c3, 0.554067 }, + { 0xc8c8, 0.587797 }, + { 0xcdcd, 0.622324 }, + { 0xd2d2, 0.657604 }, + { 0xd7d7, 0.693588 }, + { 0xdcdc, 0.730225 }, + { 0xe1e1, 0.767459 }, + { 0xe6e6, 0.805235 }, + { 0xebeb, 0.843491 }, + { 0xf0f0, 0.882164 }, + { 0xf5f5, 0.921187 }, + { 0xfafa, 0.960490 }, + { 0xffff, 1.000000 } +}; + +static IntensityRec const Default_RGB_BlueTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + { 0x0000, 0.000000 }, + { 0x0e0e, 0.000000 }, + { 0x0f0f, 0.001341 }, + { 0x1414, 0.002080 }, + { 0x1919, 0.003188 }, + { 0x1e1e, 0.004729 }, + { 0x2323, 0.006766 }, + { 0x2828, 0.009357 }, + { 0x2d2d, 0.012559 }, + { 0x3232, 0.016424 }, + { 0x3737, 0.021004 }, + { 0x3c3c, 0.026344 }, + { 0x4141, 0.032489 }, + { 0x4646, 0.039481 }, + { 0x4b4b, 0.047357 }, + { 0x5050, 0.056154 }, + { 0x5555, 0.065903 }, + { 0x5a5a, 0.076634 }, + { 0x5f5f, 0.088373 }, + { 0x6464, 0.101145 }, + { 0x6969, 0.114968 }, + { 0x6e6e, 0.129862 }, + { 0x7373, 0.145841 }, + { 0x7878, 0.162915 }, + { 0x7d7d, 0.181095 }, + { 0x8282, 0.200386 }, + { 0x8787, 0.220791 }, + { 0x8c8c, 0.242309 }, + { 0x9191, 0.264937 }, + { 0x9696, 0.288670 }, + { 0x9b9b, 0.313499 }, + { 0xa0a0, 0.339410 }, + { 0xa5a5, 0.366390 }, + { 0xaaaa, 0.394421 }, + { 0xafaf, 0.423481 }, + { 0xb4b4, 0.453547 }, + { 0xb9b9, 0.484592 }, + { 0xbebe, 0.516587 }, + { 0xc3c3, 0.549498 }, + { 0xc8c8, 0.583291 }, + { 0xcdcd, 0.617925 }, + { 0xd2d2, 0.653361 }, + { 0xd7d7, 0.689553 }, + { 0xdcdc, 0.726454 }, + { 0xe1e1, 0.764013 }, + { 0xe6e6, 0.802178 }, + { 0xebeb, 0.840891 }, + { 0xf0f0, 0.880093 }, + { 0xf5f5, 0.919723 }, + { 0xfafa, 0.959715 }, + { 0xffff, 1.00000 } +}; + +static IntensityTbl Default_RGB_RedTbl = { + /* IntensityRec *pBase */ + (IntensityRec *) Default_RGB_RedTuples, + /* unsigned int nEntries */ + 52 +}; + +static IntensityTbl Default_RGB_GreenTbl = { + /* IntensityRec *pBase */ + (IntensityRec *)Default_RGB_GreenTuples, + /* unsigned int nEntries */ + 50 +}; + +static IntensityTbl Default_RGB_BlueTbl = { + /* IntensityRec *pBase */ + (IntensityRec *)Default_RGB_BlueTuples, + /* unsigned int nEntries */ + 51 +}; + +static LINEAR_RGB_SCCData Default_RGB_SCCData = { + /* XcmsFloat XYZtoRGBmatrix[3][3] */ + { + { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 }, + {-1.07152751306193600, 1.96593795204372400, 0.03673691339553462 }, + { 0.06351179790497788, -0.20020501000496480, 0.81070942031648220 } + }, + + /* XcmsFloat RGBtoXYZmatrix[3][3] */ + { + { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 }, + { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 }, + { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 } + }, + + /* IntensityTbl *pRedTbl */ + &Default_RGB_RedTbl, + + /* IntensityTbl *pGreenTbl */ + &Default_RGB_GreenTbl, + + /* IntensityTbl *pBlueTbl */ + &Default_RGB_BlueTbl +}; + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * LINEAR_RGB_InitSCCData() + * + * SYNOPSIS + */ +static Status +LINEAR_RGB_InitSCCData( + Display *dpy, + int screenNumber, + XcmsPerScrnInfo *pPerScrnInfo) +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); + Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); + int format_return, count, cType, nTables; + unsigned long nitems, nbytes_return; + char *property_return, *pChar; + XcmsFloat *pValue; +#ifdef ALLDEBUG + IntensityRec *pIRec; +#endif /* ALLDEBUG */ + VisualID visualID; + + LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData; + XcmsIntensityMap *pNewMap; + + /* + * Allocate memory for pScreenData + */ + if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) + Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { + return(XcmsFailure); + } + + /* + * 1. Get the XYZ->RGB and RGB->XYZ matrices + */ + + if (MatrixAtom == None || + !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, + &format_return, &nitems, &nbytes_return, &property_return) || + nitems != 18 || format_return != 32) { + /* + * As per the XDCCC, there must be 18 data items and each must be + * in 32 bits ! + */ + goto FreeSCCData; + + } else { + + /* + * RGBtoXYZ and XYZtoRGB matrices + */ + pValue = (XcmsFloat *) pScreenData; + pChar = property_return; + for (count = 0; count < 18; count++) { + *pValue++ = (long)_XcmsGetElement(format_return, &pChar, + &nitems) / (XcmsFloat)XDCCC_NUMBER; + } + Xfree ((char *)property_return); + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = + pScreenData->RGBtoXYZmatrix[0][0] + + pScreenData->RGBtoXYZmatrix[0][1] + + pScreenData->RGBtoXYZmatrix[0][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = + pScreenData->RGBtoXYZmatrix[1][0] + + pScreenData->RGBtoXYZmatrix[1][1] + + pScreenData->RGBtoXYZmatrix[1][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = + pScreenData->RGBtoXYZmatrix[2][0] + + pScreenData->RGBtoXYZmatrix[2][1] + + pScreenData->RGBtoXYZmatrix[2][2]; + + /* + * Compute the Screen White Point + */ + if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) + || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { + goto FreeSCCData; + } else { + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; + } + pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; + pPerScrnInfo->screenWhitePt.pixel = 0; + +#ifdef PDEBUG + printf ("RGB to XYZ Matrix values:\n"); + printf (" %f %f %f\n %f %f %f\n %f %f %f\n", + pScreenData->RGBtoXYZmatrix[0][0], + pScreenData->RGBtoXYZmatrix[0][1], + pScreenData->RGBtoXYZmatrix[0][2], + pScreenData->RGBtoXYZmatrix[1][0], + pScreenData->RGBtoXYZmatrix[1][1], + pScreenData->RGBtoXYZmatrix[1][2], + pScreenData->RGBtoXYZmatrix[2][0], + pScreenData->RGBtoXYZmatrix[2][1], + pScreenData->RGBtoXYZmatrix[2][2]); + printf ("XYZ to RGB Matrix values:\n"); + printf (" %f %f %f\n %f %f %f\n %f %f %f\n", + pScreenData->XYZtoRGBmatrix[0][0], + pScreenData->XYZtoRGBmatrix[0][1], + pScreenData->XYZtoRGBmatrix[0][2], + pScreenData->XYZtoRGBmatrix[1][0], + pScreenData->XYZtoRGBmatrix[1][1], + pScreenData->XYZtoRGBmatrix[1][2], + pScreenData->XYZtoRGBmatrix[2][0], + pScreenData->XYZtoRGBmatrix[2][1], + pScreenData->XYZtoRGBmatrix[2][2]); + printf ("Screen White Pt value: %f %f %f\n", + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X, + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y, + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z); +#endif /* PDEBUG */ + } + + /* + * 2. Get the Intensity Profile + */ + if (CorrectAtom == None || + !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom, + &format_return, &nitems, &nbytes_return, &property_return)) { + Xfree ((char *)property_return); + goto FreeSCCData; + } + + pChar = property_return; + + while (nitems) { + switch (format_return) { + case 8: + /* + * Must have at least: + * VisualID0 + * VisualID1 + * VisualID2 + * VisualID3 + * type + * count + * length + * intensity1 + * intensity2 + */ + if (nitems < 9) { + 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)))) { + return(XcmsFailure); + } + /* copy matrices */ + memcpy((char *)pScreenData, (char *)pScreenDefaultData, + 18 * sizeof(XcmsFloat)); + + /* Create, initialize, and add map */ + if (!(pNewMap = (XcmsIntensityMap *) + Xcalloc (1, sizeof(XcmsIntensityMap)))) { + Xfree((char *)pScreenData); + return(XcmsFailure); + } + pNewMap->visualID = visualID; + pNewMap->screenData = (XPointer)pScreenData; + pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData; + pNewMap->pNext = + (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; + dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap; + dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps; + } + + cType = _XcmsGetElement(format_return, &pChar, &nitems); + nTables = _XcmsGetElement(format_return, &pChar, &nitems); + + if (cType == 0) { + + /* Red Intensity Table */ + if (!(pScreenData->pRedTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto 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 FreeGreenTblElements; + } + 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; + + 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; + return(XcmsFailure); +} + + +/* + * NAME + * LINEAR_RGB_FreeSCCData() + * + * SYNOPSIS + */ +static void +LINEAR_RGB_FreeSCCData( + XPointer pScreenDataTemp) +/* + * DESCRIPTION + * + * RETURNS + * 0 if failed. + * 1 if succeeded with no modifications. + * + */ +{ + LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp; + + if (pScreenData && pScreenData != &Default_RGB_SCCData) { + if (pScreenData->pRedTbl) { + if (pScreenData->pGreenTbl) { + if (pScreenData->pRedTbl->pBase != + pScreenData->pGreenTbl->pBase) { + if (pScreenData->pGreenTbl->pBase) { + Xfree ((char *)pScreenData->pGreenTbl->pBase); + } + } + if (pScreenData->pGreenTbl != pScreenData->pRedTbl) { + Xfree ((char *)pScreenData->pGreenTbl); + } + } + if (pScreenData->pBlueTbl) { + if (pScreenData->pRedTbl->pBase != + pScreenData->pBlueTbl->pBase) { + if (pScreenData->pBlueTbl->pBase) { + Xfree ((char *)pScreenData->pBlueTbl->pBase); + } + } + if (pScreenData->pBlueTbl != pScreenData->pRedTbl) { + Xfree ((char *)pScreenData->pBlueTbl); + } + } + if (pScreenData->pRedTbl->pBase) { + Xfree ((char *)pScreenData->pRedTbl->pBase); + } + Xfree ((char *)pScreenData->pRedTbl); + } + Xfree ((char *)pScreenData); + } +} + + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsGetTableType0 + * + * SYNOPSIS + */ +static Status +_XcmsGetTableType0( + IntensityTbl *pTbl, + int format, + char **pChar, + unsigned long *pCount) +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + unsigned int nElements; + IntensityRec *pIRec; + + nElements = pTbl->nEntries = + _XcmsGetElement(format, pChar, pCount) + 1; + if (!(pIRec = pTbl->pBase = (IntensityRec *) + Xcalloc (nElements, sizeof(IntensityRec)))) { + return(XcmsFailure); + } + + switch (format) { + case 8: + for (; nElements--; pIRec++) { + /* 0xFFFF/0xFF = 0x101 */ + pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; + pIRec->intensity = + _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; + } + break; + case 16: + for (; nElements--; pIRec++) { + pIRec->value = _XcmsGetElement (format, pChar, pCount); + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)65535.0; + } + break; + case 32: + for (; nElements--; pIRec++) { + pIRec->value = _XcmsGetElement (format, pChar, pCount); + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)4294967295.0; + } + break; + default: + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * _XcmsGetTableType1 + * + * SYNOPSIS + */ +static Status +_XcmsGetTableType1( + IntensityTbl *pTbl, + int format, + char **pChar, + unsigned long *pCount) +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + int count; + unsigned int max_index; + IntensityRec *pIRec; + + max_index = _XcmsGetElement(format, pChar, pCount); + pTbl->nEntries = max_index + 1; + if (!(pIRec = pTbl->pBase = (IntensityRec *) + Xcalloc (max_index+1, sizeof(IntensityRec)))) { + return(XcmsFailure); + } + + switch (format) { + case 8: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)255.0; + } + break; + case 16: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)65535.0; + } + break; + case 32: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)4294967295.0; + } + break; + default: + return(XcmsFailure); + } + + return(XcmsSuccess); +} + + +/* + * NAME + * ValueCmp + * + * SYNOPSIS + */ +static int +_XcmsValueCmp( + IntensityRec *p1, IntensityRec *p2) +/* + * DESCRIPTION + * Compares the value component of two IntensityRec + * structures. + * + * RETURNS + * 0 if p1->value is equal to p2->value + * < 0 if p1->value is less than p2->value + * > 0 if p1->value is greater than p2->value + * + */ +{ + return (p1->value - p2->value); +} + + +/* + * NAME + * IntensityCmp + * + * SYNOPSIS + */ +static int +_XcmsIntensityCmp( + IntensityRec *p1, IntensityRec *p2) +/* + * DESCRIPTION + * Compares the intensity component of two IntensityRec + * structures. + * + * RETURNS + * 0 if equal; + * < 0 if first precedes second + * > 0 if first succeeds second + * + */ +{ + if (p1->intensity < p2->intensity) { + return (-1); + } + if (p1->intensity > p2->intensity) { + return (XcmsSuccess); + } + return (XcmsFailure); +} + +/* + * NAME + * ValueInterpolation + * + * SYNOPSIS + */ +/* ARGSUSED */ +static int +_XcmsValueInterpolation( + IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, + int bitsPerRGB) +/* + * DESCRIPTION + * Based on a given value, performs a linear interpolation + * on the intensities between two IntensityRec structures. + * Note that the bitsPerRGB parameter is ignored. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + */ +{ + XcmsFloat ratio; + + ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / + ((XcmsFloat)hi->value - (XcmsFloat)lo->value); + answer->value = key->value; + answer->intensity = (hi->intensity - lo->intensity) * ratio; + answer->intensity += lo->intensity; + return (XcmsSuccess); +} + +/* + * NAME + * IntensityInterpolation + * + * SYNOPSIS + */ +static int +_XcmsIntensityInterpolation( + IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, + int bitsPerRGB) +/* + * DESCRIPTION + * Based on a given intensity, performs a linear interpolation + * on the values between two IntensityRec structures. + * The bitsPerRGB parameter is necessary to perform rounding + * to the correct number of significant bits. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + */ +{ + XcmsFloat ratio; + long target, up, down; + int shift = 16 - bitsPerRGB; + int max_color = (1 << bitsPerRGB) - 1; + + ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); + answer->intensity = key->intensity; + target = hi->value - lo->value; + target *= ratio; + target += lo->value; + + /* + * Ok now, lets find the closest in respects to bits per RGB + */ + up = ((target >> shift) * 0xFFFF) / max_color; + if (up < target) { + down = up; + up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; + } else { + down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; + } + answer->value = ((up - target) < (target - down) ? up : down); + answer->value &= MASK[bitsPerRGB]; + return (XcmsSuccess); +} + + + +typedef int (*comparProcp)( + char *p1, + char *p2); +typedef int (*interpolProcp)( + char *key, + char *lo, + char *hi, + char *answer, + int bitsPerRGB); + +/* + * NAME + * _XcmsTableSearch + * + * SYNOPSIS + */ +static int +_XcmsTableSearch( + char *key, + int bitsPerRGB, + char *base, + unsigned nel, + unsigned nKeyPtrSize, + int (*compar)( + char *p1, + char *p2), + int (*interpol)( + char *key, + char *lo, + char *hi, + char *answer, + int bitsPerRGB), + char *answer) + +/* + * DESCRIPTION + * A binary search through the specificied table. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + * + */ +{ + char *hi, *lo, *mid, *last; + int result; + + last = hi = base + ((nel - 1) * nKeyPtrSize); + mid = lo = base; + + /* use only the significants bits, then scale into 16 bits */ + ((IntensityRec *)key)->value = ((unsigned long) + (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) + / ((1 << bitsPerRGB) - 1); + + /* Special case so that zero intensity always maps to zero value */ + if ((*compar) (key,lo) <= 0) { + memcpy (answer, lo, nKeyPtrSize); + ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; + return XcmsSuccess; + } + while (mid != last) { + last = mid; + mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; + result = (*compar) (key, mid); + if (result == 0) { + + memcpy(answer, mid, nKeyPtrSize); + ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; + return (XcmsSuccess); + } else if (result < 0) { + hi = mid; + } else { + lo = mid; + } + } + + /* + * If we got to here, we didn't find a solution, so we + * need to apply interpolation. + */ + return ((*interpol)(key, lo, hi, answer, bitsPerRGB)); +} + + +/* + * NAME + * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector + * + * SYNOPSIS + */ +static void _XcmsMatVec( + XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut) +/* + * DESCRIPTION + * Multiply the passed vector by the passed matrix to return a + * vector. Matrix is 3x3, vectors are of length 3. + * + * RETURNS + * void + */ +{ + int i, j; + + for (i = 0; i < 3; i++) { + pOut[i] = 0.0; + for (j = 0; j < 3; j++) + pOut[i] += *(pMat+(i*3)+j) * pIn[j]; + } +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + + +/* + * NAME + * XcmsLRGB_RGB_ParseString + * + * SYNOPSIS + */ +static int +XcmsLRGB_RGB_ParseString( + register char *spec, + XcmsColor *pColor) +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsRGBFormat. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + register int n, i; + unsigned short r, g, b; + char c; + char *pchar; + unsigned short *pShort; + + /* + * Check for old # format + */ + if (*spec == '#') { + /* + * Attempt to parse the value portion. + */ + spec++; + n = strlen(spec); + if (n != 3 && n != 6 && n != 9 && n != 12) { + return(XcmsFailure); + } + + n /= 3; + g = b = 0; + do { + r = g; + g = b; + b = 0; + for (i = n; --i >= 0; ) { + c = *spec++; + b <<= 4; + if (c >= '0' && c <= '9') + b |= c - '0'; + /* assume string in lowercase + else if (c >= 'A' && c <= 'F') + b |= c - ('A' - 10); + */ + else if (c >= 'a' && c <= 'f') + b |= c - ('a' - 10); + else return (XcmsFailure); + } + } while (*spec != '\0'); + + /* + * Succeeded ! + */ + n <<= 2; + n = 16 - n; + /* shift instead of scale, to match old broken semantics */ + pColor->spec.RGB.red = r << n; + pColor->spec.RGB.green = g << n; + pColor->spec.RGB.blue = b << n; + } else { + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsRGB_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + spec += (n + 1); + pShort = &pColor->spec.RGB.red; + for (i = 0; i < 3; i++, pShort++, spec++) { + n = 0; + *pShort = 0; + while (*spec != '/' && *spec != '\0') { + if (++n > 4) { + return(XcmsFailure); + } + c = *spec++; + *pShort <<= 4; + if (c >= '0' && c <= '9') + *pShort |= c - '0'; + /* assume string in lowercase + else if (c >= 'A' && c <= 'F') + *pShort |= c - ('A' - 10); + */ + else if (c >= 'a' && c <= 'f') + *pShort |= c - ('a' - 10); + else return (XcmsFailure); + } + if (n == 0) + return (XcmsFailure); + if (n < 4) { + *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); + } + } + } + pColor->format = XcmsRGBFormat; + pColor->pixel = 0; + return (XcmsSuccess); +} + + +/* + * NAME + * XcmsLRGB_RGBi_ParseString + * + * SYNOPSIS + */ +static int +XcmsLRGB_RGBi_ParseString( + register char *spec, + XcmsColor *pColor) +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsRGBiFormat. + * The assumed RGBi string syntax is: + * RGBi:// + * Where r, g, and b are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.RGBi.red, + &pColor->spec.RGBi.green, + &pColor->spec.RGBi.blue) != 3) { + char *s; /* Maybe failed due to locale */ + int f; + if ((s = strdup(spec))) { + for (f = 0; s[f]; ++f) + if (s[f] == '.') + s[f] = ','; + else if (s[f] == ',') + s[f] = '.'; + if (sscanf(s + n + 1, "%lf/%lf/%lf", + &pColor->spec.RGBi.red, + &pColor->spec.RGBi.green, + &pColor->spec.RGBi.blue) != 3) { + free(s); + return(XcmsFailure); + } + free(s); + } else + return(XcmsFailure); + } + + /* + * Succeeded ! + */ + pColor->format = XcmsRGBiFormat; + pColor->pixel = 0; + return (XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIEXYZToRGBi( + XcmsCCC ccc, + XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ + unsigned int nColors, /* Number of colors */ + Bool *pCompressed) /* pointer to an array of Bool */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGB format to RGBi format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression. + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsFloat tmp[3]; + int hasCompressed = 0; + unsigned int i; + XcmsColor *pColor = pXcmsColors_in_out; + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + /* + * XcmsColors should be White Point Adjusted, if necessary, by now! + */ + + /* + * NEW!!! for extended gamut compression + * + * 1. Need to zero out pCompressed + * + * 2. Need to save initial address of pColor + * + * 3. Need to save initial address of pCompressed + */ + + for (i = 0; i < nColors; i++) { + + /* Make sure format is XcmsCIEXYZFormat */ + if (pColor->format != XcmsCIEXYZFormat) { + return(XcmsFailure); + } + + /* Multiply [A]-1 * [XYZ] to get RGB intensity */ + _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, + (XcmsFloat *) &pColor->spec, tmp); + + if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || + (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { + + /* + * RGBi out of screen's gamut + */ + + if (ccc->gamutCompProc == NULL) { + /* + * Aha!! Here's that little trick that will allow + * gamut compression routines to get the out of bound + * RGBi. + */ + memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); + pColor->format = XcmsRGBiFormat; + return(XcmsFailure); + } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors, + i, pCompressed) == 0) { + return(XcmsFailure); + } + + /* + * The gamut compression function should return colors in CIEXYZ + * Also check again to if the new color is within gamut. + */ + if (pColor->format != XcmsCIEXYZFormat) { + return(XcmsFailure); + } + _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, + (XcmsFloat *) &pColor->spec, tmp); + if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || + (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { + return(XcmsFailure); + } + hasCompressed++; + } + memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); + /* These if statements are done to ensure the fudge factor is */ + /* is taken into account. */ + if (pColor->spec.RGBi.red < 0.0) { + pColor->spec.RGBi.red = 0.0; + } else if (pColor->spec.RGBi.red > 1.0) { + pColor->spec.RGBi.red = 1.0; + } + if (pColor->spec.RGBi.green < 0.0) { + pColor->spec.RGBi.green = 0.0; + } else if (pColor->spec.RGBi.green > 1.0) { + pColor->spec.RGBi.green = 1.0; + } + if (pColor->spec.RGBi.blue < 0.0) { + pColor->spec.RGBi.blue = 0.0; + } else if (pColor->spec.RGBi.blue > 1.0) { + pColor->spec.RGBi.blue = 1.0; + } + (pColor++)->format = XcmsRGBiFormat; + } + return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); +} + + +/* + * NAME + * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBiToCIEXYZ( + XcmsCCC ccc, + XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ + unsigned int nColors, /* Number of colors */ + Bool *pCompressed) /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGBi format to CIEXYZ format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsFloat tmp[3]; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + /* + * XcmsColors should be White Point Adjusted, if necessary, by now! + */ + + while (nColors--) { + + /* Multiply [A]-1 * [XYZ] to get RGB intensity */ + _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix, + (XcmsFloat *) &pXcmsColors_in_out->spec, tmp); + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp)); + (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsRGBiToRGB + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBiToRGB( + XcmsCCC ccc, + XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ + unsigned int nColors, /* Number of colors */ + Bool *pCompressed) /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGBi format to RGB format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression. + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsRGB tmpRGB; + IntensityRec keyIRec, answerIRec; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + while (nColors--) { + + /* Make sure format is XcmsRGBiFormat */ + if (pXcmsColors_in_out->format != XcmsRGBiFormat) { + return(XcmsFailure); + } + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pRedTbl->pBase, + (unsigned)pScreenData->pRedTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.red = answerIRec.value; + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pGreenTbl->pBase, + (unsigned)pScreenData->pGreenTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.green = answerIRec.value; + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pBlueTbl->pBase, + (unsigned)pScreenData->pBlueTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.blue = answerIRec.value; + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB)); + (pXcmsColors_in_out++)->format = XcmsRGBFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsRGBToRGBi + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBToRGBi( + XcmsCCC ccc, + XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ + unsigned int nColors, /* Number of colors */ + Bool *pCompressed) /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGB format to RGBi format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsRGBi tmpRGBi; + IntensityRec keyIRec, answerIRec; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + while (nColors--) { + + /* Make sure format is XcmsRGBFormat */ + if (pXcmsColors_in_out->format != XcmsRGBFormat) { + return(XcmsFailure); + } + + keyIRec.value = pXcmsColors_in_out->spec.RGB.red; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pRedTbl->pBase, + (unsigned)pScreenData->pRedTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.red = answerIRec.intensity; + + keyIRec.value = pXcmsColors_in_out->spec.RGB.green; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pGreenTbl->pBase, + (unsigned)pScreenData->pGreenTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.green = answerIRec.intensity; + + keyIRec.value = pXcmsColors_in_out->spec.RGB.blue; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pBlueTbl->pBase, + (unsigned)pScreenData->pBlueTbl->nEntries, + (unsigned)sizeof(IntensityRec), + (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.blue = answerIRec.intensity; + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi)); + (pXcmsColors_in_out++)->format = XcmsRGBiFormat; + } + return(XcmsSuccess); +} + +/* + * NAME + * _XcmsInitScrnDefaultInfo + * + * SYNOPSIS + */ +/* ARGSUSED */ +int +_XcmsLRGB_InitScrnDefault( + Display *dpy, + int screenNumber, + XcmsPerScrnInfo *pPerScrnInfo) +/* + * DESCRIPTION + * Given a display and screen number, this routine attempts + * to initialize the Xcms per Screen Info structure + * (XcmsPerScrnInfo) with defaults. + * + * RETURNS + * Returns zero if initialization failed; non-zero otherwise. + */ +{ + pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = + Default_RGB_SCCData.RGBtoXYZmatrix[0][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[0][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[0][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = + Default_RGB_SCCData.RGBtoXYZmatrix[1][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[1][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[1][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = + Default_RGB_SCCData.RGBtoXYZmatrix[2][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[2][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[2][2]; + if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) + || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { + pPerScrnInfo->screenData = (XPointer)NULL; + pPerScrnInfo->state = XcmsInitNone; + return(0); + } + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; + pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; + pPerScrnInfo->screenWhitePt.pixel = 0; + pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet; + pPerScrnInfo->state = XcmsInitFailure; /* default initialization */ + return(1); +} -- cgit v1.2.3