38 { |
38 { |
39 static const int gridsamples[] = {1,5,9,16}; |
39 static const int gridsamples[] = {1,5,9,16}; |
40 const int samples = gridsamples[oversample]; |
40 const int samples = gridsamples[oversample]; |
41 if ( phase == 0 ) |
41 if ( phase == 0 ) |
42 { |
42 { |
43 phase++; |
43 if (subsample > 1) |
|
44 { |
|
45 phase = 1; |
|
46 sx = -1; |
|
47 return (w/subsample+1)*(h/subsample+1); |
|
48 } |
|
49 else |
|
50 { |
|
51 phase = 2; |
|
52 sx = -1; |
|
53 return w*h*samples; |
|
54 } |
|
55 } |
|
56 if ( phase == 1 ) |
|
57 { |
|
58 // finalize subsampling |
|
59 const Float subsample2 = 1.0/(subsample*subsample); |
|
60 int num_samples = 0; |
|
61 Colour ic; |
|
62 phase = 2; |
44 sx = -1; |
63 sx = -1; |
45 return w*h*samples; |
64 for (int y = 0; y < h/subsample; y++) |
46 } |
65 for (int x = 0; x < w/subsample; x++) |
47 else if ( phase == 1 && oversample ) |
66 { |
48 { |
67 int x1 = x*subsample; |
49 phase = -1; |
68 int y1 = y*subsample; |
|
69 int x2 = (x+1)*subsample; |
|
70 int y2 = (y+1)*subsample; |
|
71 if (x2 > w-1) x2 = w-1; |
|
72 if (y2 > h-1) y2 = h-1; |
|
73 if (x1 == x2 || y1 == y2) |
|
74 continue; |
|
75 Float *p; |
|
76 p = buffer + 3*(y1*w + x1); |
|
77 Colour c1(*p, *(p+1), *(p+2)); |
|
78 p = buffer + 3*(y1*w + x2); |
|
79 Colour c2(*p, *(p+1), *(p+2)); |
|
80 p = buffer + 3*(y2*w + x1); |
|
81 Colour c3(*p, *(p+1), *(p+2)); |
|
82 p = buffer + 3*(y2*w + x2); |
|
83 Colour c4(*p, *(p+1), *(p+2)); |
|
84 Float m = (c1-c2).mag2(); |
|
85 m = max(m, (c2-c3).mag2()); |
|
86 m = max(m, (c3-c4).mag2()); |
|
87 m = max(m, (c4-c1).mag2()); |
|
88 if (m < 0.002) |
|
89 { |
|
90 // interpolate |
|
91 for (int i = 0; i < subsample; i++) |
|
92 for (int j = 0; j < subsample; j++) |
|
93 { |
|
94 ic = c1*(subsample-i)*(subsample-j)*subsample2 |
|
95 + c2*(i)*(subsample-j)*subsample2 |
|
96 + c3*(subsample-i)*(j)*subsample2 |
|
97 + c4*(i)*(j)*subsample2; |
|
98 p = buffer + 3*((y1+j)*w + x1+i); |
|
99 *(p + 0) = ic.r; |
|
100 *(p + 1) = oversample ? -ic.g : ic.g; |
|
101 *(p + 2) = ic.b; |
|
102 } |
|
103 } |
|
104 else |
|
105 { |
|
106 // mark as to be computed |
|
107 num_samples += subsample * subsample; |
|
108 for (int i = 0; i < subsample; i++) |
|
109 for (int j = 0; j < subsample; j++) |
|
110 if (oversample || i != 0 || j != 0) |
|
111 *(buffer + 3*((y1+j)*w + x1+i)) = -1.; |
|
112 } |
|
113 } |
|
114 return num_samples; |
|
115 } |
|
116 if ( phase == 2 && oversample ) |
|
117 { |
|
118 // finalize oversampling |
50 Float *buf; |
119 Float *buf; |
51 for (buf = buffer; buf != buffer + w*h*3; buf++) |
120 if (subsample > 1) |
52 *buf = *buf * (1.0/samples); |
121 for (buf = buffer; buf != buffer + w*h*3; buf += 3) |
53 return 0; |
122 if (*(buf+1) < 0) |
54 } |
123 { |
55 else |
124 // interpolated |
56 { |
125 *(buf+1) = -*(buf+1); |
57 phase = -1; |
126 } |
58 return 0; |
127 else |
59 } |
128 { |
|
129 *buf = *buf * (1.0/samples); |
|
130 *(buf+1) = *(buf+1) * (1.0/samples); |
|
131 *(buf+2) = *(buf+2) * (1.0/samples); |
|
132 } |
|
133 else |
|
134 for (buf = buffer; buf != buffer + w*h*3; buf++) |
|
135 *buf = *buf * (1.0/samples); |
|
136 } |
|
137 phase = -1; |
|
138 return 0; |
60 } |
139 } |
61 |
140 |
62 bool DefaultSampler::nextSample(Sample* s) |
141 bool DefaultSampler::nextSample(Sample* s) |
63 { |
142 { |
64 /* grid oversampling */ |
143 if (phase == 1) |
65 static const int gridsamples[] = {1,5,9,16}; |
144 { |
66 static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4}; |
145 // subsampling |
67 static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4}; |
146 if (sx < 0) |
68 static const Float osa9x[] = {-0.34, 0.00, +0.34, |
147 { |
69 -0.34, 0.00, +0.34, -0.34, 0.00, +0.34}; |
148 // first sample |
70 static const Float osa9y[] = {-0.34, -0.34, -0.34, |
149 s->x = -(Float)w/h/2.0; |
71 0.00, 0.00, 0.00, +0.34, +0.34, +0.34}; |
150 s->y = -0.5; |
72 static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375, |
151 sx = 0; |
73 -0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375, |
152 sy = 0; |
74 -0.375, -0.125, +0.125, +0.375}; |
153 osa_samp = 0; |
75 static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375, |
154 } |
76 -0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125, |
155 else |
77 +0.375, +0.375, +0.375, +0.375}; |
156 { |
78 static const Float *osaSx[] = {NULL, osa5x, osa9x, osa16x}; |
157 if (sx == w-1) |
79 static const Float *osaSy[] = {NULL, osa5y, osa9y, osa16y}; |
158 { |
80 const int samples = gridsamples[oversample]; |
159 if (sy == h-1) |
81 const Float *osax = osaSx[oversample]; |
160 return false; |
82 const Float *osay = osaSy[oversample]; |
161 sy += subsample; |
83 |
162 if (sy > h-1) |
84 if (sx < 0) |
163 sy = h-1; |
85 { |
|
86 // first sample |
|
87 s->x = -(Float)w/h/2.0; |
|
88 s->y = -0.5; |
|
89 sx = 0; |
|
90 sy = 0; |
|
91 osa_samp = 0; |
|
92 } |
|
93 else |
|
94 { |
|
95 osa_samp++; |
|
96 |
|
97 if (oversample && oversample <= 3 && osa_samp < samples) |
|
98 { |
|
99 s->x = osax[osa_samp]/h + (Float)sx/h - (Float)w/h/2.0; |
|
100 s->y = osay[osa_samp]/h + (Float)sy/h - 0.5; |
|
101 } |
|
102 else |
|
103 { |
|
104 sx++; |
|
105 if (sx >= w) |
|
106 { |
|
107 sx = 0; |
164 sx = 0; |
108 sy++; |
165 } |
109 } |
166 else |
110 |
167 { |
111 if (sy >= h) |
168 sx += subsample; |
112 return false; |
169 if (sx > w-1) |
|
170 sx = w-1; |
|
171 } |
113 |
172 |
114 s->x = (Float)sx/h - (Float)w/h/2.0; |
173 s->x = (Float)sx/h - (Float)w/h/2.0; |
115 s->y = (Float)sy/h - 0.5; |
174 s->y = (Float)sy/h - 0.5; |
|
175 } |
|
176 } |
|
177 else if (phase == 2) |
|
178 { |
|
179 /* grid oversampling */ |
|
180 static const int gridsamples[] = {1,5,9,16}; |
|
181 static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4}; |
|
182 static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4}; |
|
183 static const Float osa9x[] = {-0.34, 0.00, +0.34, |
|
184 -0.34, 0.00, +0.34, -0.34, 0.00, +0.34}; |
|
185 static const Float osa9y[] = {-0.34, -0.34, -0.34, |
|
186 0.00, 0.00, 0.00, +0.34, +0.34, +0.34}; |
|
187 static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375, |
|
188 -0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375, |
|
189 -0.375, -0.125, +0.125, +0.375}; |
|
190 static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375, |
|
191 -0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125, |
|
192 +0.375, +0.375, +0.375, +0.375}; |
|
193 static const Float *osaSx[] = {NULL, osa5x, osa9x, osa16x}; |
|
194 static const Float *osaSy[] = {NULL, osa5y, osa9y, osa16y}; |
|
195 const int samples = gridsamples[oversample]; |
|
196 const Float *osax = osaSx[oversample]; |
|
197 const Float *osay = osaSy[oversample]; |
|
198 |
|
199 if (sx < 0) |
|
200 { |
|
201 // first sample |
|
202 s->x = -(Float)w/h/2.0; |
|
203 s->y = -0.5; |
|
204 sx = 0; |
|
205 sy = 0; |
116 osa_samp = 0; |
206 osa_samp = 0; |
117 } |
207 } |
118 } |
208 else |
119 |
209 { |
120 if (osa_samp == 0 && oversample && oversample <= 3) |
210 osa_samp++; |
121 { |
211 |
122 s->x += osax[0]/h; |
212 if (oversample && oversample <= 3 && osa_samp < samples) |
123 s->y += osay[0]/h; |
213 { |
124 Float *buf = buffer + 3*(sy*w + sx); |
214 s->x = osax[osa_samp]/h + (Float)sx/h - (Float)w/h/2.0; |
125 *(buf++) = 0; |
215 s->y = osay[osa_samp]/h + (Float)sy/h - 0.5; |
126 *(buf++) = 0; |
216 } |
127 *(buf++) = 0; |
217 else |
|
218 { |
|
219 sx++; |
|
220 if (sx >= w) |
|
221 { |
|
222 sx = 0; |
|
223 sy++; |
|
224 } |
|
225 if (sy >= h) |
|
226 return false; |
|
227 |
|
228 if (subsample > 1) |
|
229 { |
|
230 // find next not interpolated pixel |
|
231 while ( *(buffer + 3*(sy*w + sx)) >= 0. ) |
|
232 { |
|
233 sx++; |
|
234 if (sx >= w) |
|
235 { |
|
236 sx = 0; |
|
237 sy++; |
|
238 } |
|
239 if (sy >= h) |
|
240 return false; |
|
241 } |
|
242 } |
|
243 |
|
244 s->x = (Float)sx/h - (Float)w/h/2.0; |
|
245 s->y = (Float)sy/h - 0.5; |
|
246 osa_samp = 0; |
|
247 } |
|
248 } |
|
249 |
|
250 if (osa_samp == 0 && oversample && oversample <= 3) |
|
251 { |
|
252 s->x += osax[0]/h; |
|
253 s->y += osay[0]/h; |
|
254 Float *buf = buffer + 3*(sy*w + sx); |
|
255 *(buf++) = 0; |
|
256 *(buf++) = 0; |
|
257 *(buf++) = 0; |
|
258 } |
128 } |
259 } |
129 |
260 |
130 s->sx = sx; |
261 s->sx = sx; |
131 s->sy = sy; |
262 s->sy = sy; |
132 s->osa_samp = osa_samp; |
263 s->osa_samp = osa_samp; |