1 |
< |
/* Copyright (c) 1990 Regents of the University of California */ |
1 |
> |
/* Copyright (c) 1997 Regents of the University of California */ |
2 |
|
|
3 |
|
#ifndef lint |
4 |
|
static char SCCSid[] = "$SunId$ LBL"; |
10 |
|
|
11 |
|
#include "color.h" |
12 |
|
|
13 |
+ |
#define CEPS 1e-7 /* color epsilon */ |
14 |
|
|
15 |
+ |
|
16 |
|
RGBPRIMS stdprims = STDPRIMS; /* standard primary chromaticities */ |
17 |
|
|
18 |
+ |
COLOR cblack = BLKCOLOR; /* global black color */ |
19 |
+ |
COLOR cwhite = WHTCOLOR; /* global white color */ |
20 |
+ |
|
21 |
|
/* |
22 |
|
* The following table contains the CIE tristimulus integrals |
23 |
|
* for X, Y, and Z. The table is cumulative, so that |
114 |
|
} |
115 |
|
|
116 |
|
|
117 |
+ |
cie_rgb(rgb, xyz) /* convert CIE color to standard RGB */ |
118 |
+ |
COLOR rgb, xyz; |
119 |
+ |
{ |
120 |
+ |
colortrans(rgb, xyz2rgbmat, xyz); |
121 |
+ |
clipgamut(rgb, xyz[CIEY], CGAMUT_LOWER, cblack, cwhite); |
122 |
+ |
} |
123 |
+ |
|
124 |
+ |
|
125 |
+ |
int |
126 |
+ |
clipgamut(col, brt, gamut, lower, upper) /* clip to gamut cube */ |
127 |
+ |
COLOR col; |
128 |
+ |
double brt; |
129 |
+ |
int gamut; |
130 |
+ |
COLOR lower, upper; |
131 |
+ |
{ |
132 |
+ |
int rflags = 0; |
133 |
+ |
double brtmin, brtmax, v, vv; |
134 |
+ |
COLOR cgry; |
135 |
+ |
register int i; |
136 |
+ |
/* check for no check */ |
137 |
+ |
if (gamut == 0) return(0); |
138 |
+ |
/* check brightness limits */ |
139 |
+ |
brtmin = 1./3.*(lower[0]+lower[1]+lower[2]); |
140 |
+ |
if (gamut & CGAMUT_LOWER && brt < brtmin) { |
141 |
+ |
copycolor(col, lower); |
142 |
+ |
return(CGAMUT_LOWER); |
143 |
+ |
} |
144 |
+ |
brtmax = 1./3.*(upper[0]+upper[1]+upper[2]); |
145 |
+ |
if (gamut & CGAMUT_UPPER && brt > brtmax) { |
146 |
+ |
copycolor(col, upper); |
147 |
+ |
return(CGAMUT_UPPER); |
148 |
+ |
} |
149 |
+ |
/* compute equivalent grey */ |
150 |
+ |
v = (brt - brtmin)/(brtmax - brtmin); |
151 |
+ |
for (i = 0; i < 3; i++) |
152 |
+ |
cgry[i] = v*upper[i] + (1.-v)*lower[i]; |
153 |
+ |
vv = 1.; /* check each limit */ |
154 |
+ |
for (i = 0; i < 3; i++) |
155 |
+ |
if (gamut & CGAMUT_LOWER && col[i] < lower[i]) { |
156 |
+ |
v = (lower[i]+CEPS - cgry[i])/(col[i] - cgry[i]); |
157 |
+ |
if (v < vv) vv = v; |
158 |
+ |
rflags |= CGAMUT_LOWER; |
159 |
+ |
} else if (gamut & CGAMUT_UPPER && col[i] > upper[i]) { |
160 |
+ |
v = (upper[i]-CEPS - cgry[i])/(col[i] - cgry[i]); |
161 |
+ |
if (v < vv) vv = v; |
162 |
+ |
rflags |= CGAMUT_UPPER; |
163 |
+ |
} |
164 |
+ |
if (rflags) /* desaturate to cube face */ |
165 |
+ |
for (i = 0; i < 3; i++) |
166 |
+ |
col[i] = vv*col[i] + (1.-vv)*cgry[i]; |
167 |
+ |
return(rflags); |
168 |
+ |
} |
169 |
+ |
|
170 |
+ |
|
171 |
|
colortrans(c2, mat, c1) /* convert c1 by mat and put into c2 */ |
172 |
|
register COLORMAT mat; |
173 |
|
register COLOR c1, c2; |
174 |
|
{ |
175 |
< |
static float cout[3]; |
175 |
> |
COLOR cout; |
176 |
|
|
177 |
|
cout[0] = mat[0][0]*c1[0] + mat[0][1]*c1[1] + mat[0][2]*c1[2]; |
178 |
|
cout[1] = mat[1][0]*c1[0] + mat[1][1]*c1[1] + mat[1][2]*c1[2]; |
179 |
|
cout[2] = mat[2][0]*c1[0] + mat[2][1]*c1[1] + mat[2][2]*c1[2]; |
180 |
< |
if((c2[0] = cout[0]) < 0.) c2[0] = 0.; |
181 |
< |
if((c2[1] = cout[1]) < 0.) c2[1] = 0.; |
123 |
< |
if((c2[2] = cout[2]) < 0.) c2[2] = 0.; |
180 |
> |
|
181 |
> |
copycolor(c2, cout); |
182 |
|
} |
183 |
|
|
184 |
|
|
203 |
|
{ |
204 |
|
double C_rD, C_gD, C_bD; |
205 |
|
|
206 |
+ |
if (pr == stdprims) { /* can use xyz2rgbmat */ |
207 |
+ |
cpcolormat(mat, xyz2rgbmat); |
208 |
+ |
return; |
209 |
+ |
} |
210 |
|
C_rD = (1./pr[WHT][CIEY]) * |
211 |
|
( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) - |
212 |
|
pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) + |
253 |
|
{ |
254 |
|
double C_rD, C_gD, C_bD, D; |
255 |
|
|
256 |
+ |
if (pr == stdprims) { /* can use rgb2xyzmat */ |
257 |
+ |
cpcolormat(mat, rgb2xyzmat); |
258 |
+ |
return; |
259 |
+ |
} |
260 |
|
C_rD = (1./pr[WHT][CIEY]) * |
261 |
|
( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) - |
262 |
|
pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) + |
290 |
|
{ |
291 |
|
COLORMAT pr1toxyz, xyztopr2; |
292 |
|
|
293 |
< |
if (pr1 == stdprims) /* can use rgb2xyzmat */ |
294 |
< |
cpcolormat(pr1toxyz, rgb2xyzmat); |
295 |
< |
else /* otherwise compute it */ |
296 |
< |
comprgb2xyzmat(pr1toxyz, pr1); |
297 |
< |
if (pr2 == stdprims) /* can use xyz2rgbmat */ |
298 |
< |
cpcolormat(xyztopr2, xyz2rgbmat); |
299 |
< |
else /* otherwise compute it */ |
300 |
< |
compxyz2rgbmat(xyztopr2, pr2); |
293 |
> |
if (pr1 == pr2) { |
294 |
> |
mat[0][0] = mat[1][1] = mat[2][2] = 1.0; |
295 |
> |
mat[0][1] = mat[0][2] = mat[1][0] = |
296 |
> |
mat[1][2] = mat[2][0] = mat[2][1] = 0.0; |
297 |
> |
return; |
298 |
> |
} |
299 |
> |
comprgb2xyzmat(pr1toxyz, pr1); |
300 |
> |
compxyz2rgbmat(xyztopr2, pr2); |
301 |
|
/* combine transforms */ |
302 |
|
multcolormat(mat, pr1toxyz, xyztopr2); |
303 |
|
} |