ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond3.c
Revision: 3.3
Committed: Fri Oct 11 10:47:00 1996 UTC (27 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.2: +0 -3 lines
Log Message:
corrected tests in check2do()

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 pixels allowed > env. */
15
16 #define exp10(x) exp(2.302585093*(x))
17
18 int modhist[HISTRES]; /* modified histogram */
19 float cumf[HISTRES+1]; /* cumulative distribution function */
20
21
22 mkcumf() /* make cumulative distribution function */
23 {
24 register int i;
25 register long sum;
26
27 cumf[0] = 0.;
28 sum = modhist[0];
29 for (i = 1; i < HISTRES; i++) {
30 cumf[i] = (double)sum/histot;
31 sum += modhist[i];
32 }
33 cumf[HISTRES] = 1.;
34 }
35
36
37 double
38 cf(b) /* return cumulative function at b */
39 double b;
40 {
41 double x;
42 register int i;
43
44 i = x = HISTRES*(b - bwmin)/(bwmax - bwmin);
45 x -= (double)i;
46 return(cumf[i]*(1.-x) + cumf[i+1]*x);
47 }
48
49
50 double
51 BLw(Lw) /* map world luminance to display brightness */
52 double Lw;
53 {
54 double b;
55
56 if (Lw <= LMIN || (b = Bl(Lw)) <= bwmin+FTINY)
57 return(Bldmin);
58 if (b >= bwmax-FTINY)
59 return(Bldmax);
60 return(Bldmin + cf(Bl(Lw))*(Bldmax-Bldmin));
61 }
62
63
64 double
65 htcontrs(La) /* human threshold contrast sensitivity, dL(La) */
66 double La;
67 {
68 double l10La, l10dL;
69 /* formula taken from Ferwerda et al. [SG96] */
70 if (La < 1.148e-4)
71 return(1.38e-3);
72 l10La = log10(La);
73 if (l10La < -1.44) /* rod response regime */
74 l10dL = pow(.405*l10La + 1.6, 2.18) - 2.86;
75 else if (l10La < -.0184)
76 l10dL = l10La - .395;
77 else if (l10La < 1.9) /* cone response regime */
78 l10dL = pow(.249*l10La + .65, 2.7) - .72;
79 else
80 l10dL = l10La - 1.255;
81
82 return(exp10(l10dL));
83 }
84
85
86 double
87 clampf(Lw) /* derivative clamping function */
88 double Lw;
89 {
90 double bLw, ratio;
91
92 bLw = BLw(Lw); /* apply current brightness map */
93 ratio = what2do&DO_HSENS ? htcontrs(Lb(bLw))/htcontrs(Lw) : Lb(bLw)/Lw;
94 return(ratio/(Lb1(bLw)*(Bldmax-Bldmin)*Bl1(Lw)));
95 }
96
97
98 int
99 shiftdir(bw) /* compute shift direction for histogram */
100 double bw;
101 {
102 if (what2do&DO_HSENS && cf(bw) - (bw - bwmin)/(Bldmax - bwmin))
103 return(1);
104 return(-1);
105 }
106
107
108 int
109 mkbrmap() /* make dynamic range map */
110 {
111 int hdiffs[HISTRES], above, below;
112 double T, b, s;
113 int maxd, maxi, sd;
114 register int i;
115 /* copy initial histogram */
116 for (i = 0; i < HISTRES; i++)
117 modhist[i] = bwhist[i];
118 T = histot * (bwmax - bwmin) / HISTRES;
119 s = (bwmax - bwmin)/HISTRES;
120 /* loop until satisfactory */
121 for ( ; ; ) {
122 mkcumf(); /* sync brightness mapping */
123 above = below = 0; /* compute visibility overflow */
124 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
125 hdiffs[i] = modhist[i] - (int)(T*clampf(Lb(b)) + .5);
126 if (hdiffs[i] > 0) above += hdiffs[i];
127 else below -= hdiffs[i];
128 }
129 if (above <= histot*CVRATIO)
130 break; /* close enough */
131 if (above-below >= 0)
132 return(-1); /* Houston, we have a problem.... */
133 /* original looped here as well (BEGIN_L2) */
134 maxd = 0; /* find largest overvis */
135 for (i = 0; i < HISTRES; i++)
136 if (hdiffs[i] > maxd)
137 maxd = hdiffs[maxi=i];
138 /* broke loop here when (maxd == 0) (BREAK_L2) */
139 for (sd = shiftdir((maxi+.5)/HISTRES*(bwmax-bwmin)+bwmin);
140 hdiffs[maxi] == maxd; sd = -sd)
141 for (i = maxi+sd; i >= 0 & i < HISTRES; i += sd)
142 if (hdiffs[i] < 0) {
143 if (hdiffs[i] <= -maxd) {
144 modhist[i] += maxd;
145 modhist[maxi] -= maxd;
146 hdiffs[i] += maxd;
147 hdiffs[maxi] = 0;
148 } else {
149 modhist[maxi] += hdiffs[i];
150 modhist[i] -= hdiffs[i];
151 hdiffs[maxi] += hdiffs[i];
152 hdiffs[i] = 0;
153 }
154 break;
155 }
156 /* (END_L2) */
157 }
158 return(0);
159 }
160
161
162 scotscan(scan, xres) /* apply scotopic color sensitivity loss */
163 COLOR *scan;
164 int xres;
165 {
166 COLOR ctmp;
167 double incolor, b, Lw;
168 register int i;
169
170 for (i = 0; i < xres; i++) {
171 Lw = plum(scan[i]);
172 if (Lw >= TopMesopic)
173 incolor = 1.;
174 else if (Lw <= BotMesopic)
175 incolor = 0.;
176 else
177 incolor = (Lw - BotMesopic) /
178 (TopMesopic - BotMesopic);
179 if (incolor < 1.-FTINY) {
180 b = (1.-incolor)*slum(scan[i])*inpexp/SWNORM;
181 if (lumf == rgblum) b /= WHTEFFICACY;
182 setcolor(ctmp, b, b, b);
183 if (incolor <= FTINY)
184 setcolor(scan[i], 0., 0., 0.);
185 else
186 scalecolor(scan[i], incolor);
187 addcolor(scan[i], ctmp);
188 }
189 }
190 }
191
192
193 mapscan(scan, xres) /* apply tone mapping operator to scanline */
194 COLOR *scan;
195 int xres;
196 {
197 double mult, Lw, b;
198 register int i;
199
200 for (i = 0; i < xres; i++) {
201 Lw = plum(scan[i]);
202 if (Lw < LMIN) {
203 setcolor(scan[i], 0., 0., 0.);
204 continue;
205 }
206 b = BLw(Lw);
207 mult = (Lb(b) - ldmin)/(ldmax - ldmin) / (Lw*inpexp);
208 if (lumf == rgblum) mult *= WHTEFFICACY;
209 scalecolor(scan[i], mult);
210 }
211 }
212
213
214 #ifdef DEBUG
215 doplots() /* generate debugging plots */
216 {
217 double T, b, s;
218 FILE *fp;
219 char fname[128];
220 register int i;
221
222 T = histot * (bwmax - bwmin) / HISTRES;
223 s = (bwmax - bwmin)/HISTRES;
224
225 sprintf(fname, "%s_hist.plt", infn);
226 if ((fp = fopen(fname, "w")) == NULL)
227 syserror(fname);
228 fputs("include=curve.plt\n", fp);
229 fputs("title=\"Brightness Frequency Distribution\"\n", fp);
230 fprintf(fp, "subtitle=%s\n", infn);
231 fputs("ymin=0\n", fp);
232 fputs("xlabel=\"Perceptual Brightness B(Lw)\"\n", fp);
233 fputs("ylabel=\"Frequency Count\"\n", fp);
234 fputs("Alabel=\"Histogram\"\n", fp);
235 fputs("Alintype=0\n", fp);
236 fputs("Blabel=\"Envelope\"\n", fp);
237 fputs("Bsymsize=0\n", fp);
238 fputs("Adata=\n", fp);
239 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s)
240 fprintf(fp, "\t%f %d\n", b, modhist[i]);
241 fputs(";\nBdata=\n", fp);
242 for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s)
243 fprintf(fp, "\t%f %f\n", b, T*clampf(Lb(b)));
244 fputs(";\n", fp);
245 fclose(fp);
246 }
247 #endif