ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond3.c
Revision: 3.8
Committed: Wed Jan 29 13:22:13 1997 UTC (27 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.7: +131 -0 lines
Log Message:
added -i option to take fixation points on standard input

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 * Routines for computing and applying brightness mapping.
9 */
10
11 #include "pcond.h"
12
13
14 #define CVRATIO 0.025 /* fraction of samples allowed > env. */
15
16 #define exp10(x) exp(2.302585093*(x))
17
18 float modhist[HISTRES]; /* modified histogram */
19 double mhistot; /* modified histogram total */
20 float cumf[HISTRES+1]; /* cumulative distribution function */
21
22
23 getfixations(fp) /* load fixation history list */
24 FILE *fp;
25 {
26 #define FIXHUNK 128
27 RESOLU fvres;
28 int pos[2];
29 register int px, py, i;
30 /* initialize our resolution struct */
31 if ((fvres.or=inpres.or)&YMAJOR) {
32 fvres.xr = fvxr;
33 fvres.yr = fvyr;
34 } else {
35 fvres.xr = fvyr;
36 fvres.yr = fvxr;
37 }
38 /* read each picture position */
39 while (fscanf(fp, "%d %d", &pos[0], &pos[1]) == 2) {
40 /* convert to closest index in foveal image */
41 loc2pix(pos, &fvres,
42 (pos[0]+.5)/inpres.xr, (pos[1]+.5)/inpres.yr);
43 /* include nine neighborhood samples */
44 for (px = pos[0]-1; px <= pos[0]+1; px++) {
45 if (px < 0 || px >= fvxr)
46 continue;
47 for (py = pos[1]-1; py <= pos[1]+1; py++) {
48 if (py < 0 || py >= fvyr)
49 continue;
50 for (i = nfixations; i-- > 0; )
51 if (fixlst[i][0] == px &&
52 fixlst[i][1] == py)
53 break;
54 if (i >= 0)
55 continue; /* already there */
56 if (nfixations % FIXHUNK == 0) {
57 if (nfixations)
58 fixlst = (short (*)[2])
59 realloc((char *)fixlst,
60 (nfixations+FIXHUNK)*
61 2*sizeof(short));
62 else
63 fixlst = (short (*)[2])malloc(
64 FIXHUNK*2*sizeof(short)
65 );
66 if (fixlst == NULL)
67 syserror("malloc");
68 }
69 fixlst[nfixations][0] = px;
70 fixlst[nfixations][1] = py;
71 nfixations++;
72 }
73 }
74 }
75 if (!feof(fp)) {
76 fprintf(stderr, "%s: format error reading fixation data\n",
77 progname);
78 exit(1);
79 }
80 #undef FIXHUNK
81 }
82
83
84 double
85 centprob(x, y) /* center-weighting probability function */
86 int x, y;
87 {
88 double xr, yr, p;
89 /* paraboloid, 0 at 90 degrees from center */
90 xr = (x - .5*(fvxr-1))/90.; /* 180 degree fisheye has fv?r == 90 */
91 yr = (y - .5*(fvyr-1))/90.;
92 p = 1. - xr*xr - yr*yr;
93 return(p < 0. ? 0. : p);
94 }
95
96
97 comphist() /* create foveal sampling histogram */
98 {
99 double l, b, w, lwmin, lwmax;
100 register int x, y;
101
102 lwmin = 1e10; /* find extrema */
103 lwmax = 0.;
104 for (y = 0; y < fvyr; y++)
105 for (x = 0; x < fvxr; x++) {
106 l = plum(fovscan(y)[x]);
107 if (l < lwmin) lwmin = l;
108 if (l > lwmax) lwmax = l;
109 }
110 lwmin -= FTINY;
111 lwmax += FTINY;
112 if (lwmin < LMIN) lwmin = LMIN;
113 if (lwmax > LMAX) lwmax = LMAX;
114 bwmin = Bl(lwmin);
115 bwmax = Bl(lwmax);
116 /* (re)compute histogram */
117 bwavg = 0.;
118 histot = 0.;
119 for (x = 0; x < HISTRES; x++)
120 bwhist[x] = 0.;
121 /* global average */
122 if (!(what2do&DO_FIXHIST) || fixfrac < 1.-FTINY)
123 for (y = 0; y < fvyr; y++)
124 for (x = 0; x < fvxr; x++) {
125 l = plum(fovscan(y)[x]);
126 if (l < lwmin) continue;
127 if (l > lwmax) continue;
128 b = Bl(l);
129 bwavg += b;
130 w = what2do&DO_CWEIGHT ? centprob(x,y) : 1.;
131 bwhist[bwhi(b)] += w;
132 histot += w;
133 }
134 /* average fixation points */
135 if (what2do&DO_FIXHIST && nfixations > 0) {
136 if (histot > FTINY)
137 w = fixfrac/(1.-fixfrac)*histot/nfixations;
138 else
139 w = 1.;
140 for (x = 0; x < nfixations; x++) {
141 l = plum(fovscan(fixlst[x][1])[fixlst[x][0]]);
142 if (l < lwmin) continue;
143 if (l > lwmax) continue;
144 b = Bl(l);
145 bwavg += b;
146 bwhist[bwhi(b)] += w;
147 histot += w;
148 }
149 }
150 bwavg /= histot;
151 }
152
153
154 mkcumf() /* make cumulative distribution function */
155 {
156 register int i;
157 register double sum;
158
159 mhistot = 0.; /* compute modified total */
160 for (i = 0; i < HISTRES; i++)
161 mhistot += modhist[i];
162
163 sum = 0.; /* compute cumulative function */
164 for (i = 0; i < HISTRES; i++) {
165 cumf[i] = sum/mhistot;
166 sum += modhist[i];
167 }
168 cumf[HISTRES] = 1.;
169 }
170
171
172 double
173 cf(b) /* return cumulative function at b */
174 double b;
175 {
176 double x;
177 register int i;
178
179 i = x = HISTRES*(b - bwmin)/(bwmax - bwmin);
180 x -= (double)i;
181 return(cumf[i]*(1.-x) + cumf[i+1]*x);
182 }
183
184
185 double
186 BLw(Lw) /* map world luminance to display brightness */
187 double Lw;
188 {
189 double b;
190
191 if (Lw <= LMIN || (b = Bl(Lw)) <= bwmin+FTINY)
192 return(Bldmin);
193 if (b >= bwmax-FTINY)
194 return(Bldmax);
195 return(Bldmin + cf(b)*(Bldmax-Bldmin));
196 }
197
198
199 double
200 htcontrs(La) /* human threshold contrast sensitivity, dL(La) */
201 double La;
202 {
203 double l10La, l10dL;
204 /* formula taken from Ferwerda et al. [SG96] */
205 if (La < 1.148e-4)
206 return(1.38e-3);
207 l10La = log10(La);
208 if (l10La < -1.44) /* rod response regime */
209 l10dL = pow(.405*l10La + 1.6, 2.18) - 2.86;
210 else if (l10La < -.0184)
211 l10dL = l10La - .395;
212 else if (l10La < 1.9) /* cone response regime */
213 l10dL = pow(.249*l10La + .65, 2.7) - .72;
214 else
215 l10dL = l10La - 1.255;
216
217 return(exp10(l10dL));
218 }
219
220
221 double
222 clampf(Lw) /* derivative clamping function */
223 double Lw;
224 {
225 double bLw, ratio;
226
227 bLw = BLw(Lw); /* apply current brightness map */
228 ratio = what2do&DO_HSENS ? htcontrs(Lb(bLw))/htcontrs(Lw) : Lb(bLw)/Lw;
229 return(ratio/(Lb1(bLw)*(Bldmax-Bldmin)*Bl1(Lw)));
230 }
231
232
233 int
234 mkbrmap() /* make dynamic range map */
235 {
236 double T, b, s;
237 double ceiling, trimmings;
238 register int i;
239 /* copy initial histogram */
240 bcopy((char *)bwhist, (char *)modhist, sizeof(modhist));
241 s = (bwmax - bwmin)/HISTRES;
242 /* loop until satisfactory */
243 do {
244 mkcumf(); /* sync brightness mapping */
245 if (mhistot <= histot*CVRATIO)
246 return(-1); /* no compression needed! */
247 T = mhistot * (bwmax - bwmin) / HISTRES;
248 trimmings = 0.; /* clip to envelope */
249 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
250 ceiling = T*clampf(Lb(b));
251 if (modhist[i] > ceiling) {
252 trimmings += modhist[i] - ceiling;
253 modhist[i] = ceiling;
254 }
255 }
256 } while (trimmings > histot*CVRATIO);
257
258 return(0); /* we got it */
259 }
260
261
262 scotscan(scan, xres) /* apply scotopic color sensitivity loss */
263 COLOR *scan;
264 int xres;
265 {
266 COLOR ctmp;
267 double incolor, b, Lw;
268 register int i;
269
270 for (i = 0; i < xres; i++) {
271 Lw = plum(scan[i]);
272 if (Lw >= TopMesopic)
273 incolor = 1.;
274 else if (Lw <= BotMesopic)
275 incolor = 0.;
276 else
277 incolor = (Lw - BotMesopic) /
278 (TopMesopic - BotMesopic);
279 if (incolor < 1.-FTINY) {
280 b = (1.-incolor)*slum(scan[i])*inpexp/SWNORM;
281 if (lumf == rgblum) b /= WHTEFFICACY;
282 setcolor(ctmp, b, b, b);
283 if (incolor <= FTINY)
284 setcolor(scan[i], 0., 0., 0.);
285 else
286 scalecolor(scan[i], incolor);
287 addcolor(scan[i], ctmp);
288 }
289 }
290 }
291
292
293 mapscan(scan, xres) /* apply tone mapping operator to scanline */
294 COLOR *scan;
295 int xres;
296 {
297 double mult, Lw, b;
298 register int i;
299
300 for (i = 0; i < xres; i++) {
301 Lw = plum(scan[i]);
302 if (Lw < LMIN) {
303 setcolor(scan[i], 0., 0., 0.);
304 continue;
305 }
306 b = BLw(Lw);
307 mult = (Lb(b) - ldmin)/(ldmax - ldmin) / (Lw*inpexp);
308 if (lumf == rgblum) mult *= WHTEFFICACY;
309 scalecolor(scan[i], mult);
310 }
311 }
312
313
314 putmapping(fp) /* put out mapping function */
315 FILE *fp;
316 {
317 double b, s;
318 register int i;
319 double wlum, sf, dlum;
320
321 sf = scalef*inpexp;
322 if (lumf == cielum) sf *= WHTEFFICACY;
323 s = (bwmax - bwmin)/HISTRES;
324 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
325 wlum = Lb(b);
326 if (what2do&DO_LINEAR) {
327 dlum = sf*wlum;
328 if (dlum > ldmax) dlum = ldmax;
329 else if (dlum < ldmin) dlum = ldmin;
330 fprintf(fp, "%e %e\n", wlum, dlum);
331 } else
332 fprintf(fp, "%e %e\n", wlum, Lb(BLw(wlum)));
333 }
334 }