ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond2.c
Revision: 3.19
Committed: Wed Sep 11 18:56:11 2024 UTC (6 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 3.18: +3 -2 lines
Log Message:
feat(pcond,pvalue): Added hyperspectral input handling

File Contents

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