ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond2.c
Revision: 3.7
Committed: Fri Jan 31 15:56:20 1997 UTC (27 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.6: +17 -2 lines
Log Message:
added gamut mapping for display devices (doesn't work w/ pcomb)

File Contents

# Content
1 /* Copyright (c) 1997 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Input and output conditioning routines for pcond.
9 */
10
11 #include "pcond.h"
12
13
14 RGBPRIMP inprims = stdprims; /* input primaries */
15 COLORMAT inrgb2xyz; /* convert input RGB to XYZ */
16 RGBPRIMP outprims = stdprims; /* output primaries */
17
18 double (*lumf)() = rgblum; /* input luminance function */
19 double inpexp = 1.0; /* input exposure value */
20
21 char *mbcalfile = NULL; /* macbethcal mapping file */
22
23 static struct mbc {
24 COLORMAT cmat;
25 float xa[3][6], ya[3][6];
26 COLOR cmin, cmax;
27 } mbcond; /* macbethcal conditioning struct */
28
29 static COLOR *scanbuf; /* scanline processing buffer */
30 static int nread; /* number of scanlines processed */
31
32
33 double
34 rgblum(clr, scotopic) /* compute (scotopic) luminance of RGB color */
35 COLOR clr;
36 int scotopic;
37 {
38 if (scotopic) /* approximate */
39 return( WHTSEFFICACY * (colval(clr,RED)*.062 +
40 colval(clr,GRN)*.608 + colval(clr,BLU)*.330) );
41 return( WHTEFFICACY * (colval(clr,RED)*inrgb2xyz[1][0] +
42 colval(clr,GRN)*inrgb2xyz[1][1] +
43 colval(clr,BLU)*inrgb2xyz[1][2]) );
44 }
45
46
47 double
48 cielum(xyz, scotopic) /* compute (scotopic) luminance of CIE color */
49 COLOR xyz;
50 int scotopic;
51 {
52 if (scotopic) /* approximate */
53 return(colval(xyz,CIEY) *
54 (1.33*(1. + (colval(xyz,CIEY)+colval(xyz,CIEZ))/
55 colval(xyz,CIEX)) - 1.68));
56 return(colval(xyz,CIEY));
57 }
58
59
60 COLOR *
61 nextscan() /* read and condition next scanline */
62 {
63 if (nread >= numscans(&inpres)) {
64 free((char *)scanbuf);
65 return(scanbuf = NULL);
66 }
67 if (what2do&DO_ACUITY)
68 acuscan(scanbuf, nread);
69 else if (freadscan(scanbuf, scanlen(&inpres), infp) < 0) {
70 fprintf(stderr, "%s: %s: scanline read error\n",
71 progname, infn);
72 exit(1);
73 }
74 if (what2do&DO_VEIL) /* add veiling */
75 addveil(scanbuf, nread);
76 if (what2do&DO_COLOR) /* scotopic color loss */
77 scotscan(scanbuf, scanlen(&inpres));
78 if (what2do&DO_LINEAR) /* map luminances */
79 sfscan(scanbuf, scanlen(&inpres), scalef);
80 else
81 mapscan(scanbuf, scanlen(&inpres));
82 if (mbcalfile != NULL) /* device color correction */
83 mbscan(scanbuf, scanlen(&inpres), &mbcond);
84 else if (lumf == cielum | inprims != outprims)
85 matscan(scanbuf, scanlen(&inpres), mbcond.cmat);
86 nread++;
87 return(scanbuf);
88 }
89
90
91 COLOR *
92 firstscan() /* return first processed scanline */
93 {
94 if (mbcalfile != NULL) /* load macbethcal file */
95 getmbcalfile(mbcalfile, &mbcond);
96 else
97 if (lumf == rgblum)
98 comprgb2rgbmat(mbcond.cmat, inprims, outprims);
99 else
100 compxyz2rgbmat(mbcond.cmat, outprims);
101 if (what2do&DO_ACUITY)
102 initacuity();
103 scanbuf = (COLOR *)malloc(scanlen(&inpres)*sizeof(COLOR));
104 if (scanbuf == NULL)
105 syserror("malloc");
106 nread = 0;
107 return(nextscan());
108 }
109
110
111 sfscan(sl, len, sf) /* apply scalefactor to scanline */
112 register COLOR *sl;
113 int len;
114 double sf;
115 {
116 while (len--) {
117 scalecolor(sl[0], sf);
118 sl++;
119 }
120 }
121
122
123 matscan(sl, len, mat) /* apply color matrix to scaline */
124 register COLOR *sl;
125 int len;
126 COLORMAT mat;
127 {
128 while (len--) {
129 colortrans(sl[0], mat, sl[0]);
130 clipgamut(sl[0], bright(sl[0]), CGAMUT, cblack, cwhite);
131 sl++;
132 }
133 }
134
135
136 mbscan(sl, len, mb) /* apply macbethcal adj. to scaline */
137 COLOR *sl;
138 int len;
139 register struct mbc *mb;
140 {
141 double d;
142 register int i, j;
143
144 while (len--) {
145 colortrans(sl[0], mb->cmat, sl[0]);
146 clipgamut(sl[0], bright(sl[0]), CGAMUT, mb->cmin, mb->cmax);
147 for (i = 0; i < 3; i++) {
148 d = colval(sl[0],i);
149 for (j = 0; j < 4 && mb->xa[i][j+1] <= d; j++)
150 ;
151 colval(sl[0],i) = ( (mb->xa[i][j+1] - d)*mb->ya[i][j] +
152 (d - mb->xa[i][j])*mb->ya[i][j+1] ) /
153 (mb->xa[i][j+1] - mb->xa[i][j]);
154 }
155 sl++;
156 }
157 }
158
159
160 getmbcalfile(fn, mb) /* load macbethcal file */
161 char *fn;
162 register struct mbc *mb;
163 {
164 extern char *fgets();
165 char buf[128];
166 FILE *fp;
167 int inpflags = 0;
168 register int i;
169
170 if ((fp = fopen(fn, "r")) == NULL)
171 syserror(fn);
172 while (fgets(buf, sizeof(buf), fp) != NULL) {
173 if (!(inpflags & 01) &&
174 sscanf(buf,
175 "rxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
176 &mb->xa[0][0], &mb->xa[0][1],
177 &mb->xa[0][2], &mb->xa[0][3],
178 &mb->xa[0][4], &mb->xa[0][5]
179 ) == 6)
180 inpflags |= 01;
181 else if (!(inpflags & 02) &&
182 sscanf(buf,
183 "rya(i) : select(i,%f,%f,%f,%f,%f,%f)",
184 &mb->ya[0][0], &mb->ya[0][1],
185 &mb->ya[0][2], &mb->ya[0][3],
186 &mb->ya[0][4], &mb->ya[0][5]
187 ) == 6)
188 inpflags |= 02;
189 else if (!(inpflags & 04) &&
190 sscanf(buf,
191 "gxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
192 &mb->xa[1][0], &mb->xa[1][1],
193 &mb->xa[1][2], &mb->xa[1][3],
194 &mb->xa[1][4], &mb->xa[1][5]
195 ) == 6)
196 inpflags |= 04;
197 else if (!(inpflags & 010) &&
198 sscanf(buf,
199 "gya(i) : select(i,%f,%f,%f,%f,%f,%f)",
200 &mb->ya[1][0], &mb->ya[1][1],
201 &mb->ya[1][2], &mb->ya[1][3],
202 &mb->ya[1][4], &mb->ya[1][5]
203 ) == 6)
204 inpflags |= 010;
205 else if (!(inpflags & 020) &&
206 sscanf(buf,
207 "bxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
208 &mb->xa[2][0], &mb->xa[2][1],
209 &mb->xa[2][2], &mb->xa[2][3],
210 &mb->xa[2][4], &mb->xa[2][5]
211 ) == 6)
212 inpflags |= 020;
213 else if (!(inpflags & 040) &&
214 sscanf(buf,
215 "bya(i) : select(i,%f,%f,%f,%f,%f,%f)",
216 &mb->ya[2][0], &mb->ya[2][1],
217 &mb->ya[2][2], &mb->ya[2][3],
218 &mb->ya[2][4], &mb->ya[2][5]
219 ) == 6)
220 inpflags |= 040;
221 else if (!(inpflags & 0100) &&
222 sscanf(buf,
223 "r = %f*r1 + %f*g1 + %f*b1",
224 &mb->cmat[0][0], &mb->cmat[0][1],
225 &mb->cmat[0][2]) == 3)
226 inpflags |= 0100;
227 else if (!(inpflags & 0200) &&
228 sscanf(buf,
229 "g = %f*r1 + %f*g1 + %f*b1",
230 &mb->cmat[1][0], &mb->cmat[1][1],
231 &mb->cmat[1][2]) == 3)
232 inpflags |= 0200;
233 else if (!(inpflags & 0400) &&
234 sscanf(buf,
235 "b = %f*r1 + %f*g1 + %f*b1",
236 &mb->cmat[2][0], &mb->cmat[2][1],
237 &mb->cmat[2][2]) == 3)
238 inpflags |= 0400;
239 }
240 if (inpflags != 0777) {
241 fprintf(stderr,
242 "%s: cannot grok macbethcal file \"%s\" (inpflags==0%o)\n",
243 progname, fn, inpflags);
244 exit(1);
245 }
246 fclose(fp);
247 /* compute gamut */
248 for (i = 0; i < 3; i++) {
249 colval(mb->cmin,i) = mb->xa[i][0] -
250 mb->ya[i][0] *
251 (mb->xa[i][1]-mb->xa[i][0]) /
252 (mb->ya[i][1]-mb->ya[i][0]);
253 colval(mb->cmax,i) = mb->xa[i][4] +
254 (1.-mb->ya[i][4]) *
255 (mb->xa[i][5] - mb->xa[i][4]) /
256 (mb->ya[i][5] - mb->ya[i][4]);
257 }
258 }