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"; |
13 |
|
|
14 |
|
RGBPRIMS stdprims = STDPRIMS; /* standard primary chromaticities */ |
15 |
|
|
16 |
+ |
COLOR cblack = BLKCOLOR; /* global black color */ |
17 |
+ |
COLOR cwhite = WHTCOLOR; /* global white color */ |
18 |
+ |
|
19 |
|
/* |
20 |
|
* The following table contains the CIE tristimulus integrals |
21 |
|
* for X, Y, and Z. The table is cumulative, so that |
112 |
|
} |
113 |
|
|
114 |
|
|
115 |
+ |
cie_rgb(rgb, xyz) /* convert CIE color to standard RGB */ |
116 |
+ |
COLOR rgb, xyz; |
117 |
+ |
{ |
118 |
+ |
colortrans(rgb, xyz2rgbmat, xyz); |
119 |
+ |
clipgamut(rgb, xyz[CIEY], CGAMUT_LOWER, cblack, cwhite); |
120 |
+ |
} |
121 |
+ |
|
122 |
+ |
|
123 |
+ |
int |
124 |
+ |
clipgamut(col, brt, gamut, lower, upper) /* clip to gamut cube */ |
125 |
+ |
COLOR col; |
126 |
+ |
double brt; |
127 |
+ |
int gamut; |
128 |
+ |
COLOR lower, upper; |
129 |
+ |
{ |
130 |
+ |
int rflags = 0; |
131 |
+ |
double brtmin, brtmax, v, vv; |
132 |
+ |
COLOR cgry; |
133 |
+ |
register int i; |
134 |
+ |
/* check for no check */ |
135 |
+ |
if (gamut == 0) return(0); |
136 |
+ |
/* check brightness limits */ |
137 |
+ |
brtmin = 1./3.*(lower[0]+lower[1]+lower[2]); |
138 |
+ |
if (gamut & CGAMUT_LOWER && brt < brtmin) { |
139 |
+ |
copycolor(col, lower); |
140 |
+ |
return(CGAMUT_LOWER); |
141 |
+ |
} |
142 |
+ |
brtmax = 1./3.*(upper[0]+upper[1]+upper[2]); |
143 |
+ |
if (gamut & CGAMUT_UPPER && brt > brtmax) { |
144 |
+ |
copycolor(col, upper); |
145 |
+ |
return(CGAMUT_UPPER); |
146 |
+ |
} |
147 |
+ |
/* compute equivalent grey */ |
148 |
+ |
v = (brt - brtmin)/(brtmax - brtmin); |
149 |
+ |
for (i = 0; i < 3; i++) |
150 |
+ |
cgry[i] = v*upper[i] + (1.-v)*lower[i]; |
151 |
+ |
vv = 1.; /* check each limit */ |
152 |
+ |
for (i = 0; i < 3; i++) |
153 |
+ |
if (gamut & CGAMUT_LOWER && col[i] < lower[i]) { |
154 |
+ |
v = (lower[i] - cgry[i])/(col[i] - cgry[i]); |
155 |
+ |
if (v < vv) vv = v; |
156 |
+ |
rflags |= CGAMUT_LOWER; |
157 |
+ |
} else if (gamut & CGAMUT_UPPER && col[i] > upper[i]) { |
158 |
+ |
v = (upper[i] - cgry[i])/(col[i] - cgry[i]); |
159 |
+ |
if (v < vv) vv = v; |
160 |
+ |
rflags |= CGAMUT_UPPER; |
161 |
+ |
} |
162 |
+ |
if (rflags) /* desaturate to cube face */ |
163 |
+ |
for (i = 0; i < 3; i++) |
164 |
+ |
col[i] = vv*col[i] + (1.-vv)*cgry[i]; |
165 |
+ |
return(rflags); |
166 |
+ |
} |
167 |
+ |
|
168 |
+ |
|
169 |
|
colortrans(c2, mat, c1) /* convert c1 by mat and put into c2 */ |
170 |
|
register COLORMAT mat; |
171 |
|
register COLOR c1, c2; |
172 |
|
{ |
173 |
< |
static float cout[3]; |
174 |
< |
|
175 |
< |
cout[0] = mat[0][0]*c1[0] + mat[0][1]*c1[1] + mat[0][2]*c1[2]; |
119 |
< |
cout[1] = mat[1][0]*c1[0] + mat[1][1]*c1[1] + mat[1][2]*c1[2]; |
120 |
< |
cout[2] = mat[2][0]*c1[0] + mat[2][1]*c1[1] + mat[2][2]*c1[2]; |
121 |
< |
if((c2[0] = cout[0]) < 0.) c2[0] = 0.; |
122 |
< |
if((c2[1] = cout[1]) < 0.) c2[1] = 0.; |
123 |
< |
if((c2[2] = cout[2]) < 0.) c2[2] = 0.; |
173 |
> |
c2[0] = mat[0][0]*c1[0] + mat[0][1]*c1[1] + mat[0][2]*c1[2]; |
174 |
> |
c2[1] = mat[1][0]*c1[0] + mat[1][1]*c1[1] + mat[1][2]*c1[2]; |
175 |
> |
c2[2] = mat[2][0]*c1[0] + mat[2][1]*c1[1] + mat[2][2]*c1[2]; |
176 |
|
} |
177 |
|
|
178 |
|
|
197 |
|
{ |
198 |
|
double C_rD, C_gD, C_bD; |
199 |
|
|
200 |
+ |
if (pr == stdprims) { /* can use xyz2rgbmat */ |
201 |
+ |
cpcolormat(mat, xyz2rgbmat); |
202 |
+ |
return; |
203 |
+ |
} |
204 |
|
C_rD = (1./pr[WHT][CIEY]) * |
205 |
|
( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) - |
206 |
|
pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) + |
247 |
|
{ |
248 |
|
double C_rD, C_gD, C_bD, D; |
249 |
|
|
250 |
+ |
if (pr == stdprims) { /* can use rgb2xyzmat */ |
251 |
+ |
cpcolormat(mat, rgb2xyzmat); |
252 |
+ |
return; |
253 |
+ |
} |
254 |
|
C_rD = (1./pr[WHT][CIEY]) * |
255 |
|
( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) - |
256 |
|
pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) + |
284 |
|
{ |
285 |
|
COLORMAT pr1toxyz, xyztopr2; |
286 |
|
|
287 |
< |
if (pr1 == stdprims) /* can use rgb2xyzmat */ |
288 |
< |
cpcolormat(pr1toxyz, rgb2xyzmat); |
289 |
< |
else /* otherwise compute it */ |
290 |
< |
comprgb2xyzmat(pr1toxyz, pr1); |
291 |
< |
if (pr2 == stdprims) /* can use xyz2rgbmat */ |
292 |
< |
cpcolormat(xyztopr2, xyz2rgbmat); |
293 |
< |
else /* otherwise compute it */ |
294 |
< |
compxyz2rgbmat(xyztopr2, pr2); |
287 |
> |
if (pr1 == pr2) { |
288 |
> |
mat[0][0] = mat[1][1] = mat[2][2] = 1.0; |
289 |
> |
mat[0][1] = mat[0][2] = mat[1][0] = |
290 |
> |
mat[1][2] = mat[2][0] = mat[2][1] = 0.0; |
291 |
> |
return; |
292 |
> |
} |
293 |
> |
comprgb2xyzmat(pr1toxyz, pr1); |
294 |
> |
compxyz2rgbmat(xyztopr2, pr2); |
295 |
|
/* combine transforms */ |
296 |
|
multcolormat(mat, pr1toxyz, xyztopr2); |
297 |
|
} |