ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pf2.c
Revision: 2.11
Committed: Fri Dec 8 17:56:26 2023 UTC (4 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.10: +13 -13 lines
Log Message:
feat(pfilt): Added support for hyperspectral image filtering

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pf2.c,v 2.10 2023/12/07 21:15:54 greg Exp $";
3 #endif
4 /*
5 * pf2.c - routines used by pfilt.
6 */
7
8 #include "pfilt.h"
9 #include "random.h"
10
11 #define AVGLVL 0.5 /* target mean brightness */
12
13 double avgbrt; /* average picture brightness */
14 long npix; /* # pixels in average */
15
16 typedef struct hotpix { /* structure for avgbrt pixels */
17 struct hotpix *next; /* next in list */
18 COLOR val; /* pixel color */
19 short x, y; /* pixel position */
20 float slope; /* random slope for diffraction */
21 } HOTPIX;
22
23 HOTPIX *head; /* head of avgbrt pixel list */
24
25 double sprdfact; /* computed spread factor */
26
27 static void starpoint(SCOLOR fcol, int x, int y, HOTPIX *hp);
28
29
30 void
31 pass1init(void) /* prepare for first pass */
32 {
33 avgbrt = 0.0;
34 npix = 0;
35 head = NULL;
36 }
37
38
39 void
40 pass1default(void) /* for single pass */
41 {
42 avgbrt = AVGLVL;
43 npix = 1;
44 head = NULL;
45 }
46
47
48 void
49 pass1scan( /* process first pass scanline */
50 COLORV *scan,
51 int y
52 )
53 {
54 double cbrt;
55 int x;
56 HOTPIX *hp;
57
58 for (x = 0; x < xres; x++) {
59
60 cbrt = (*ourbright)(scan+x*NCSAMP);
61
62 if (cbrt <= 0)
63 continue;
64
65 if (avghot || cbrt < hotlvl) {
66 avgbrt += cbrt;
67 npix++;
68 }
69 if (npts && cbrt >= hotlvl) {
70 hp = (HOTPIX *)malloc(sizeof(HOTPIX));
71 if (hp == NULL) {
72 fprintf(stderr, "%s: out of memory\n",
73 progname);
74 quit(1);
75 }
76 scolor_color(hp->val, scan+x*NCSAMP);
77 hp->x = x;
78 hp->y = y;
79 hp->slope = ttan(PI*(0.5-(irandom(npts)+0.5)/npts));
80 hp->next = head;
81 head = hp;
82 }
83 }
84 }
85
86
87 void
88 pass2init(void) /* prepare for final pass */
89 {
90 if (!npix) {
91 fprintf(stderr, "%s: picture too dark or too bright\n",
92 progname);
93 quit(1);
94 }
95 avgbrt /= (double)npix;
96
97 scalecolor(exposure, AVGLVL/avgbrt);
98
99 sprdfact = spread / (hotlvl * bright(exposure))
100 * ((double)xres*xres + (double)yres*yres) / 4.0;
101 }
102
103
104 void
105 pass2scan( /* process final pass scanline */
106 COLORV *scan,
107 int y
108 )
109 {
110 int xmin, xmax;
111 int x;
112 HOTPIX *hp;
113
114 for (hp = head; hp != NULL; hp = hp->next) {
115 if (hp->slope > FTINY) {
116 xmin = (y - hp->y - 0.5)/hp->slope + hp->x;
117 xmax = (y - hp->y + 0.5)/hp->slope + hp->x;
118 } else if (hp->slope < -FTINY) {
119 xmin = (y - hp->y + 0.5)/hp->slope + hp->x;
120 xmax = (y - hp->y - 0.5)/hp->slope + hp->x;
121 } else if (y == hp->y) {
122 xmin = 0;
123 xmax = xres-1;
124 } else {
125 xmin = 1;
126 xmax = 0;
127 }
128 if (xmin < 0)
129 xmin = 0;
130 if (xmax >= xres)
131 xmax = xres-1;
132 for (x = xmin; x <= xmax; x++)
133 starpoint(scan+x*NCSAMP, x, y, hp);
134 }
135 for (x = 0; x < xres; x++)
136 smultcolor(scan+x*NCSAMP, exposure);
137 }
138
139
140 static void
141 starpoint( /* pixel is on the star's point */
142 SCOLOR fcol,
143 int x,
144 int y,
145 HOTPIX *hp
146 )
147 {
148 COLOR ctmp;
149 double d2;
150
151 d2 = (double)(x - hp->x)*(x - hp->x) + (double)(y - hp->y)*(y - hp->y);
152 if (d2 > sprdfact) {
153 d2 = sprdfact / d2;
154 if (d2 < FTINY)
155 return;
156 copycolor(ctmp, hp->val);
157 scalecolor(ctmp, d2);
158 saddcolor(fcol, ctmp);
159 } else if (d2 > FTINY) {
160 saddcolor(fcol, hp->val);
161 }
162 }