ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond3.c
Revision: 3.6
Committed: Fri Jan 10 16:48:21 1997 UTC (27 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.5: +0 -10 lines
Log Message:
removed shiftdir() function, which is no longer needed

File Contents

# Content
1 /* Copyright (c) 1996 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 mkcumf() /* make cumulative distribution function */
24 {
25 register int i;
26 register double sum;
27
28 mhistot = 0.; /* compute modified total */
29 for (i = 0; i < HISTRES; i++)
30 mhistot += modhist[i];
31
32 sum = 0.; /* compute cumulative function */
33 for (i = 0; i < HISTRES; i++) {
34 cumf[i] = sum/mhistot;
35 sum += modhist[i];
36 }
37 cumf[HISTRES] = 1.;
38 }
39
40
41 double
42 cf(b) /* return cumulative function at b */
43 double b;
44 {
45 double x;
46 register int i;
47
48 i = x = HISTRES*(b - bwmin)/(bwmax - bwmin);
49 x -= (double)i;
50 return(cumf[i]*(1.-x) + cumf[i+1]*x);
51 }
52
53
54 double
55 BLw(Lw) /* map world luminance to display brightness */
56 double Lw;
57 {
58 double b;
59
60 if (Lw <= LMIN || (b = Bl(Lw)) <= bwmin+FTINY)
61 return(Bldmin);
62 if (b >= bwmax-FTINY)
63 return(Bldmax);
64 return(Bldmin + cf(b)*(Bldmax-Bldmin));
65 }
66
67
68 double
69 htcontrs(La) /* human threshold contrast sensitivity, dL(La) */
70 double La;
71 {
72 double l10La, l10dL;
73 /* formula taken from Ferwerda et al. [SG96] */
74 if (La < 1.148e-4)
75 return(1.38e-3);
76 l10La = log10(La);
77 if (l10La < -1.44) /* rod response regime */
78 l10dL = pow(.405*l10La + 1.6, 2.18) - 2.86;
79 else if (l10La < -.0184)
80 l10dL = l10La - .395;
81 else if (l10La < 1.9) /* cone response regime */
82 l10dL = pow(.249*l10La + .65, 2.7) - .72;
83 else
84 l10dL = l10La - 1.255;
85
86 return(exp10(l10dL));
87 }
88
89
90 double
91 clampf(Lw) /* derivative clamping function */
92 double Lw;
93 {
94 double bLw, ratio;
95
96 bLw = BLw(Lw); /* apply current brightness map */
97 ratio = what2do&DO_HSENS ? htcontrs(Lb(bLw))/htcontrs(Lw) : Lb(bLw)/Lw;
98 return(ratio/(Lb1(bLw)*(Bldmax-Bldmin)*Bl1(Lw)));
99 }
100
101
102 int
103 mkbrmap() /* make dynamic range map */
104 {
105 double T, b, s;
106 double ceiling, trimmings;
107 register int i;
108 /* copy initial histogram */
109 bcopy((char *)bwhist, (char *)modhist, sizeof(modhist));
110 s = (bwmax - bwmin)/HISTRES;
111 /* loop until satisfactory */
112 do {
113 mkcumf(); /* sync brightness mapping */
114 if (mhistot <= histot*CVRATIO)
115 return(-1); /* no compression needed! */
116 T = mhistot * (bwmax - bwmin) / HISTRES;
117 trimmings = 0.; /* clip to envelope */
118 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
119 ceiling = T*clampf(Lb(b));
120 if (modhist[i] > ceiling) {
121 trimmings += modhist[i] - ceiling;
122 modhist[i] = ceiling;
123 }
124 }
125 } while (trimmings > histot*CVRATIO);
126
127 return(0); /* we got it */
128 }
129
130
131 scotscan(scan, xres) /* apply scotopic color sensitivity loss */
132 COLOR *scan;
133 int xres;
134 {
135 COLOR ctmp;
136 double incolor, b, Lw;
137 register int i;
138
139 for (i = 0; i < xres; i++) {
140 Lw = plum(scan[i]);
141 if (Lw >= TopMesopic)
142 incolor = 1.;
143 else if (Lw <= BotMesopic)
144 incolor = 0.;
145 else
146 incolor = (Lw - BotMesopic) /
147 (TopMesopic - BotMesopic);
148 if (incolor < 1.-FTINY) {
149 b = (1.-incolor)*slum(scan[i])*inpexp/SWNORM;
150 if (lumf == rgblum) b /= WHTEFFICACY;
151 setcolor(ctmp, b, b, b);
152 if (incolor <= FTINY)
153 setcolor(scan[i], 0., 0., 0.);
154 else
155 scalecolor(scan[i], incolor);
156 addcolor(scan[i], ctmp);
157 }
158 }
159 }
160
161
162 mapscan(scan, xres) /* apply tone mapping operator to scanline */
163 COLOR *scan;
164 int xres;
165 {
166 double mult, Lw, b;
167 register int i;
168
169 for (i = 0; i < xres; i++) {
170 Lw = plum(scan[i]);
171 if (Lw < LMIN) {
172 setcolor(scan[i], 0., 0., 0.);
173 continue;
174 }
175 b = BLw(Lw);
176 mult = (Lb(b) - ldmin)/(ldmax - ldmin) / (Lw*inpexp);
177 if (lumf == rgblum) mult *= WHTEFFICACY;
178 scalecolor(scan[i], mult);
179 }
180 }
181
182
183 putmapping(fp) /* put out mapping function */
184 FILE *fp;
185 {
186 double b, s;
187 register int i;
188 double wlum, sf;
189
190 sf = scalef*inpexp;
191 if (lumf == cielum) sf *= WHTEFFICACY;
192 s = (bwmax - bwmin)/HISTRES;
193 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
194 wlum = Lb(b);
195 if (what2do&DO_LINEAR)
196 fprintf(fp, "%e %e\n", wlum, sf*wlum);
197 else
198 fprintf(fp, "%e %e\n", wlum, Lb(BLw(wlum)));
199 }
200 }