1
2/*
3 * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
4 * 	All Rights Reserved
5 *
6 * This file is a component of an X Window System-specific implementation
7 * of Xcms based on the TekColor Color Management System.  Permission is
8 * hereby granted to use, copy, modify, sell, and otherwise distribute this
9 * software and its documentation for any purpose and without fee, provided
10 * that this copyright, permission, and disclaimer notice is reproduced in
11 * all copies of this software and in supporting documentation.  TekColor
12 * is a trademark of Tektronix, Inc.
13 *
14 * Tektronix makes no representation about the suitability of this software
15 * for any purpose.  It is provided "as is" and with all faults.
16 *
17 * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
18 * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19 * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21 * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
22 * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
24 *
25 *
26 *	NAME
27 *		XcmsRtoX.c
28 *
29 *	DESCRIPTION
30 *		Convert color specifications in XcmsRGB format in one array of
31 *		XcmsColor structures to RGB in an array of XColor structures.
32 *
33 *
34 */
35
36#ifdef HAVE_CONFIG_H
37#include <config.h>
38#endif
39#include "Xlibint.h"
40#include "Xcmsint.h"
41#include "Cv.h"
42
43/*
44 *      LOCAL VARIABLES
45 */
46
47static unsigned short const MASK[17] = {
48    0x0000,	/*  0 bitsPerRGB */
49    0x8000,	/*  1 bitsPerRGB */
50    0xc000,	/*  2 bitsPerRGB */
51    0xe000,	/*  3 bitsPerRGB */
52    0xf000,	/*  4 bitsPerRGB */
53    0xf800,	/*  5 bitsPerRGB */
54    0xfc00,	/*  6 bitsPerRGB */
55    0xfe00,	/*  7 bitsPerRGB */
56    0xff00,	/*  8 bitsPerRGB */
57    0xff80,	/*  9 bitsPerRGB */
58    0xffc0,	/* 10 bitsPerRGB */
59    0xffe0,	/* 11 bitsPerRGB */
60    0xfff0,	/* 12 bitsPerRGB */
61    0xfff8,	/* 13 bitsPerRGB */
62    0xfffc,	/* 14 bitsPerRGB */
63    0xfffe,	/* 15 bitsPerRGB */
64    0xffff	/* 16 bitsPerRGB */
65};
66
67
68
69/************************************************************************
70 *									*
71 *			API PRIVATE ROUTINES				*
72 *									*
73 ************************************************************************/
74
75/*
76 *	NAME
77 *		_XcmsRGB_to_XColor -
78 *
79 *	SYNOPSIS
80 */
81void
82_XcmsRGB_to_XColor(
83    XcmsColor *pColors,
84    XColor *pXColors,
85    unsigned int nColors)
86/*
87 *	DESCRIPTION
88 *	    Translates a color specification in XcmsRGBFormat in a XcmsColor
89 * 	    structure to an XColor structure.
90 *
91 *	RETURNS
92 *		void.
93 */
94{
95    for (; nColors--; pXColors++, pColors++) {
96	pXColors->pixel = pColors->pixel;
97	pXColors->red = pColors->spec.RGB.red;
98	pXColors->green = pColors->spec.RGB.green;
99	pXColors->blue  = pColors->spec.RGB.blue;
100	pXColors->flags = (DoRed | DoGreen | DoBlue);
101    }
102}
103
104
105/*
106 *	NAME
107 *		_XColor_to_XcmsRGB
108 *
109 *	SYNOPSIS
110 */
111void
112_XColor_to_XcmsRGB(
113    XcmsCCC ccc,
114    XColor *pXColors,
115    XcmsColor *pColors,
116    unsigned int nColors)
117/*
118 *	DESCRIPTION
119 *		Translates an RGB color specification in an XColor
120 *		structure to an XcmsRGB structure.
121 *
122 *		IMPORTANT NOTE:  Bit replication that may have been caused
123 *		with ResolveColor() routine in the X Server is undone
124 *		here if requested!  For example, if red = 0xcaca and the
125 *		bits_per_rgb is 8, then spec.RGB.red will be 0xca00.
126 *
127 *	RETURNS
128 *		void
129 */
130{
131    int bits_per_rgb = ccc->visual->bits_per_rgb;
132
133    for (; nColors--; pXColors++, pColors++) {
134	pColors->spec.RGB.red = (pXColors->red & MASK[bits_per_rgb]);
135	pColors->spec.RGB.green = (pXColors->green & MASK[bits_per_rgb]);
136	pColors->spec.RGB.blue = (pXColors->blue & MASK[bits_per_rgb]);
137	pColors->format = XcmsRGBFormat;
138	pColors->pixel = pXColors->pixel;
139    }
140}
141
142
143/*
144 *	NAME
145 *		_XcmsResolveColor
146 *
147 *	SYNOPSIS
148 */
149void
150_XcmsResolveColor(
151    XcmsCCC ccc,
152    XcmsColor *pXcmsColor)
153/*
154 *	DESCRIPTION
155 *	    Uses the X Server ResolveColor() algorithm to
156 *	    modify values to closest values supported by hardware.
157 *	    Old algorithm simply masked low-order bits.  The new algorithm
158 *	    has the effect of replicating significant bits into lower order
159 *	    bits in order to stretch the hardware value into all 16 bits.
160 *
161 *	    On a display with N-bit DACs, the "hardware" color is computed as:
162 *
163 *	    ((unsignedlong)(ClientValue >> (16-N)) * 0xFFFF) / ((1 << N) - 1)
164 *
165 *
166 *	RETURNS
167 *		void.
168 */
169{
170    int shift;
171    int max_color;
172
173    shift = 16 - ccc->visual->bits_per_rgb;
174    max_color = (1 << ccc->visual->bits_per_rgb) - 1;
175
176
177    pXcmsColor->spec.RGB.red =
178	    ((unsigned long)(pXcmsColor->spec.RGB.red >> shift) * 0xFFFF)
179	    / max_color;
180    pXcmsColor->spec.RGB.green =
181	    ((unsigned long)(pXcmsColor->spec.RGB.green >> shift) * 0xFFFF)
182	    / max_color;
183    pXcmsColor->spec.RGB.blue =
184	    ((unsigned long)(pXcmsColor->spec.RGB.blue  >> shift) * 0xFFFF)
185	    / max_color;
186}
187
188
189/*
190 *	NAME
191 *		_XcmsUnresolveColor
192 *
193 *	SYNOPSIS
194 */
195void
196_XcmsUnresolveColor(
197    XcmsCCC ccc,
198    XcmsColor *pColor)
199/*
200 *	DESCRIPTION
201 *		Masks out insignificant bits.
202 *
203 *	RETURNS
204 *		void.
205 *
206 *	ASSUMPTIONS
207 *		format == XcmsRGBFormat
208 */
209{
210    int bits_per_rgb = ccc->visual->bits_per_rgb;
211
212    pColor->spec.RGB.red &= MASK[bits_per_rgb];
213    pColor->spec.RGB.green &= MASK[bits_per_rgb];
214    pColor->spec.RGB.blue &= MASK[bits_per_rgb];
215}
216
217
218/*
219 *	NAME
220 *		_XUnresolveColor
221 *
222 *	SYNOPSIS
223 */
224void
225_XUnresolveColor(
226    XcmsCCC ccc,
227    XColor *pXColor)
228/*
229 *	DESCRIPTION
230 *		Masks out insignificant bits.
231 *
232 *	RETURNS
233 *		void.
234 */
235{
236    int bits_per_rgb = ccc->visual->bits_per_rgb;
237
238    pXColor->red &= MASK[bits_per_rgb];
239    pXColor->green &= MASK[bits_per_rgb];
240    pXColor->blue &= MASK[bits_per_rgb];
241}
242
243