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 (7 months, 3 weeks 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

# User Rev Content
1 greg 3.1 #ifndef lint
2 greg 3.19 static const char RCSid[] = "$Id: pcond2.c,v 3.18 2015/08/21 05:48:28 greg Exp $";
3 greg 3.1 #endif
4     /*
5     * Input and output conditioning routines for pcond.
6 greg 3.10 * Added white-balance adjustment 10/01 (GW).
7 greg 3.1 */
8    
9     #include "pcond.h"
10 greg 3.8 #include "warp3d.h"
11 greg 3.1
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 greg 3.8 char *cwarpfile = NULL; /* color space warping file */
22 greg 3.1
23 greg 3.3 static struct mbc {
24 greg 3.7 COLORMAT cmat;
25 greg 3.3 float xa[3][6], ya[3][6];
26 greg 3.7 COLOR cmin, cmax;
27 greg 3.3 } mbcond; /* macbethcal conditioning struct */
28 greg 3.1
29 greg 3.8 static WARP3D *cwarp; /* color warping structure */
30    
31 greg 3.1 static COLOR *scanbuf; /* scanline processing buffer */
32     static int nread; /* number of scanlines processed */
33    
34 schorsch 3.12 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 greg 3.1
40 schorsch 3.12
41 greg 3.18 double
42 schorsch 3.12 rgblum( /* compute (scotopic) luminance of RGB color */
43     COLOR clr,
44     int scotopic
45     )
46 greg 3.1 {
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 greg 3.18 double
57 schorsch 3.12 cielum( /* compute (scotopic) luminance of CIE color */
58     COLOR xyz,
59     int scotopic
60     )
61 greg 3.1 {
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 greg 3.18 COLOR *
71 schorsch 3.12 nextscan(void) /* read and condition next scanline */
72 greg 3.1 {
73     if (nread >= numscans(&inpres)) {
74 greg 3.8 if (cwarpfile != NULL)
75     free3dw(cwarp);
76 greg 3.10 free((void *)scanbuf);
77 greg 3.4 return(scanbuf = NULL);
78 greg 3.1 }
79 greg 3.2 if (what2do&DO_ACUITY)
80     acuscan(scanbuf, nread);
81 greg 3.19 else if (fread2scan(scanbuf, scanlen(&inpres), infp,
82     NCSAMP, WLPART) < 0) {
83 greg 3.1 fprintf(stderr, "%s: %s: scanline read error\n",
84     progname, infn);
85     exit(1);
86     }
87     if (what2do&DO_VEIL) /* add veiling */
88 greg 3.2 addveil(scanbuf, nread);
89 greg 3.1 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 greg 3.8 else if (cwarpfile != NULL) /* device color space warp */
98     cwscan(scanbuf, scanlen(&inpres), cwarp);
99 schorsch 3.11 else if ((lumf == cielum) | (inprims != outprims))
100 greg 3.1 matscan(scanbuf, scanlen(&inpres), mbcond.cmat);
101 greg 3.2 nread++;
102 greg 3.1 return(scanbuf);
103     }
104    
105    
106 greg 3.18 COLOR *
107 schorsch 3.12 firstscan(void) /* return first processed scanline */
108 greg 3.1 {
109     if (mbcalfile != NULL) /* load macbethcal file */
110     getmbcalfile(mbcalfile, &mbcond);
111 greg 3.8 else if (cwarpfile != NULL) {
112     if ((cwarp = load3dw(cwarpfile, NULL)) == NULL)
113     syserror(cwarpfile);
114     } else
115 greg 3.1 if (lumf == rgblum)
116 greg 3.10 comprgb2rgbWBmat(mbcond.cmat, inprims, outprims);
117 greg 3.1 else
118 greg 3.10 compxyz2rgbWBmat(mbcond.cmat, outprims);
119 greg 3.14 if (what2do&DO_ACUITY)
120     initacuity();
121 greg 3.1 scanbuf = (COLOR *)malloc(scanlen(&inpres)*sizeof(COLOR));
122     if (scanbuf == NULL)
123     syserror("malloc");
124     nread = 0;
125     return(nextscan());
126     }
127    
128    
129 schorsch 3.12 static void
130     sfscan( /* apply scalefactor to scanline */
131 greg 3.18 COLOR *sl,
132 schorsch 3.12 int len,
133     double sf
134     )
135 greg 3.1 {
136     while (len--) {
137     scalecolor(sl[0], sf);
138     sl++;
139     }
140     }
141    
142    
143 greg 3.15 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 greg 3.17 if (gryc[i] > 1)
154     gryc[i] = 1;
155     else if (gryc[i] < 0)
156     gryc[i] = 0;
157     return(bright(gryc));
158 greg 3.15 }
159    
160    
161 schorsch 3.12 static void
162     matscan( /* apply color matrix to scaline */
163 greg 3.18 COLOR *sl,
164 schorsch 3.12 int len,
165     COLORMAT mat
166     )
167 greg 3.1 {
168     while (len--) {
169     colortrans(sl[0], mat, sl[0]);
170 greg 3.17 clipgamut(sl[0], greypoint(sl[0]), CGAMUT, cblack, cwhite);
171 greg 3.1 sl++;
172     }
173     }
174    
175    
176 schorsch 3.12 static void
177     mbscan( /* apply macbethcal adj. to scaline */
178     COLOR *sl,
179     int len,
180 greg 3.18 struct mbc *mb
181 schorsch 3.12 )
182 greg 3.1 {
183     double d;
184 greg 3.18 int i, j;
185 greg 3.1
186     while (len--) {
187 greg 3.6 colortrans(sl[0], mb->cmat, sl[0]);
188 greg 3.17 clipgamut(sl[0], greypoint(sl[0]), CGAMUT, mb->cmin, mb->cmax);
189 greg 3.1 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 greg 3.8 sl++;
198     }
199     }
200    
201    
202 schorsch 3.12 static void
203     cwscan( /* apply color space warp to scaline */
204     COLOR *sl,
205     int len,
206     WARP3D *wp
207     )
208 greg 3.8 {
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 greg 3.17 clipgamut(sl[0], greypoint(sl[0]), CGAMUT, cblack, cwhite);
221 greg 3.1 sl++;
222     }
223     }
224    
225    
226 schorsch 3.12 static void
227     getmbcalfile( /* load macbethcal file */
228     char *fn,
229 greg 3.18 struct mbc *mb
230 schorsch 3.12 )
231 greg 3.1 {
232     char buf[128];
233     FILE *fp;
234     int inpflags = 0;
235 greg 3.18 int i;
236 greg 3.1
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 gwlarson 3.9 "ro = %f*rn + %f*gn + %f*bn",
291 greg 3.1 &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 gwlarson 3.9 "go = %f*rn + %f*gn + %f*bn",
297 greg 3.1 &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 gwlarson 3.9 "bo = %f*rn + %f*gn + %f*bn",
303 greg 3.1 &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 greg 3.7 /* 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 greg 3.1 }