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

# User Rev Content
1 greg 3.7 /* Copyright (c) 1997 Regents of the University of California */
2 greg 3.1
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 greg 3.5 #define CVRATIO 0.025 /* fraction of samples allowed > env. */
15 greg 3.1
16     #define exp10(x) exp(2.302585093*(x))
17    
18 greg 3.5 float modhist[HISTRES]; /* modified histogram */
19     double mhistot; /* modified histogram total */
20 greg 3.1 float cumf[HISTRES+1]; /* cumulative distribution function */
21    
22    
23 greg 3.8 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 greg 3.1 mkcumf() /* make cumulative distribution function */
155     {
156     register int i;
157 greg 3.5 register double sum;
158 greg 3.1
159 greg 3.5 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 greg 3.1 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 greg 3.4 return(Bldmin + cf(b)*(Bldmax-Bldmin));
196 greg 3.1 }
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 greg 3.5 double ceiling, trimmings;
238 greg 3.1 register int i;
239     /* copy initial histogram */
240 greg 3.5 bcopy((char *)bwhist, (char *)modhist, sizeof(modhist));
241 greg 3.1 s = (bwmax - bwmin)/HISTRES;
242     /* loop until satisfactory */
243 greg 3.5 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 greg 3.1 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
250 greg 3.5 ceiling = T*clampf(Lb(b));
251     if (modhist[i] > ceiling) {
252     trimmings += modhist[i] - ceiling;
253     modhist[i] = ceiling;
254     }
255 greg 3.1 }
256 greg 3.5 } while (trimmings > histot*CVRATIO);
257    
258     return(0); /* we got it */
259 greg 3.1 }
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 greg 3.2 b = (1.-incolor)*slum(scan[i])*inpexp/SWNORM;
281     if (lumf == rgblum) b /= WHTEFFICACY;
282     setcolor(ctmp, b, b, b);
283 greg 3.1 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 greg 3.4 }
311     }
312    
313    
314     putmapping(fp) /* put out mapping function */
315     FILE *fp;
316     {
317     double b, s;
318     register int i;
319 greg 3.7 double wlum, sf, dlum;
320 greg 3.4
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 greg 3.7 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 greg 3.4 fprintf(fp, "%e %e\n", wlum, Lb(BLw(wlum)));
333 greg 3.1 }
334     }