ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond2.c
Revision: 3.10
Committed: Sat Feb 22 02:07:27 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 3.9: +5 -7 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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