diff options
Diffstat (limited to 'SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c')
-rwxr-xr-x | SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c b/SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c new file mode 100755 index 0000000..1f6a98b --- /dev/null +++ b/SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c | |||
@@ -0,0 +1,494 @@ | |||
1 | /* | ||
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
3 | ;;; File: edges.c | ||
4 | ;;; Author: Eero Simoncelli | ||
5 | ;;; Description: Boundary handling routines for use with convolve.c | ||
6 | ;;; Creation Date: Spring 1987. | ||
7 | ;;; MODIFIED, 6/96, to operate on double float arrays. | ||
8 | ;;; MODIFIED by dgp, 4/1/97, to support THINK C. | ||
9 | ;;; ---------------------------------------------------------------- | ||
10 | ;;; Object-Based Vision and Image Understanding System (OBVIUS), | ||
11 | ;;; Copyright 1988, Vision Science Group, Media Laboratory, | ||
12 | ;;; Massachusetts Institute of Technology. | ||
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | This file contains functions which determine how edges are to be | ||
18 | handled when performing convolutions of images with linear filters. | ||
19 | Any edge handling function which is local and linear may be defined, | ||
20 | except (unfortunately) constants cannot be added. So to treat the | ||
21 | edges as if the image is surrounded by a gray field, you must paste it | ||
22 | into a gray image, convolve, and crop it out... | ||
23 | The main convolution function is called internal_filter and is defined | ||
24 | in the file convolve.c. The idea is that the convolution function | ||
25 | calls the edge handling function which computes a new filter based on | ||
26 | the old filter and the distance to the edge of the image. For | ||
27 | example, reflection is done by reflecting the filter through the | ||
28 | appropriate axis and summing. Currently defined functions are listed | ||
29 | below. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | #define DEBUG | ||
34 | */ | ||
35 | |||
36 | #include <stdio.h> | ||
37 | #include <math.h> | ||
38 | #include <string.h> | ||
39 | #include "convolve.h" | ||
40 | |||
41 | #define sgn(a) ( ((a)>0)?1:(((a)<0)?-1:0) ) | ||
42 | #define clip(a,mn,mx) ( ((a)<(mn))?(mn):(((a)>=(mx))?(mx-1):(a)) ) | ||
43 | |||
44 | int reflect1(), reflect2(), repeat(), zero(), Extend(), nocompute(); | ||
45 | int ereflect(), predict(); | ||
46 | |||
47 | /* Lookup table matching a descriptive string to the edge-handling function */ | ||
48 | #if !THINK_C | ||
49 | static EDGE_HANDLER edge_foos[] = | ||
50 | { | ||
51 | { "dont-compute", nocompute }, /* zero output for filter touching edge */ | ||
52 | { "zero", zero }, /* zero outside of image */ | ||
53 | { "repeat", repeat }, /* repeat edge pixel */ | ||
54 | { "reflect1", reflect1 }, /* reflect about edge pixels */ | ||
55 | { "reflect2", reflect2 }, /* reflect image, including edge pixels */ | ||
56 | { "extend", Extend }, /* extend (reflect & invert) */ | ||
57 | { "predict", predict }, /* predict based on portion covered by filt */ | ||
58 | { "ereflect", ereflect }, /* orthogonal QMF reflection */ | ||
59 | }; | ||
60 | #else | ||
61 | /* | ||
62 | This is really stupid, but THINK C won't allow initialization of static variables in | ||
63 | a code resource with string addresses. So we do it this way. | ||
64 | The 68K code for a MATLAB 4 MEX file can only be created by THINK C. | ||
65 | However, for MATLAB 5, we'll be able to use Metrowerks CodeWarrior for both 68K and PPC, so this | ||
66 | cludge can be dropped when we drop support for MATLAB 4. | ||
67 | Denis Pelli, 4/1/97. | ||
68 | */ | ||
69 | static EDGE_HANDLER edge_foos[8]; | ||
70 | |||
71 | void InitializeTable(EDGE_HANDLER edge_foos[]) | ||
72 | { | ||
73 | static int i=0; | ||
74 | |||
75 | if(i>0) return; | ||
76 | edge_foos[i].name="dont-compute"; | ||
77 | edge_foos[i++].func=nocompute; | ||
78 | edge_foos[i].name="zero"; | ||
79 | edge_foos[i++].func=zero; | ||
80 | edge_foos[i].name="repeat"; | ||
81 | edge_foos[i++].func=repeat; | ||
82 | edge_foos[i].name="reflect1"; | ||
83 | edge_foos[i++].func=reflect1; | ||
84 | edge_foos[i].name="reflect2"; | ||
85 | edge_foos[i++].func=reflect2; | ||
86 | edge_foos[i].name="extend"; | ||
87 | edge_foos[i++].func=Extend; | ||
88 | edge_foos[i].name="predict"; | ||
89 | edge_foos[i++].func=predict; | ||
90 | edge_foos[i].name="ereflect"; | ||
91 | edge_foos[i++].func=ereflect; | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | /* | ||
96 | Function looks up an edge handler id string in the structure above, and | ||
97 | returns the associated function | ||
98 | */ | ||
99 | fptr edge_function(char *edges) | ||
100 | { | ||
101 | int i; | ||
102 | |||
103 | #if THINK_C | ||
104 | InitializeTable(edge_foos); | ||
105 | #endif | ||
106 | for (i = 0; i<sizeof(edge_foos)/sizeof(EDGE_HANDLER); i++) | ||
107 | if (strcmp(edges,edge_foos[i].name) == 0) | ||
108 | return(edge_foos[i].func); | ||
109 | printf("Error: '%s' is not the name of a valid edge-handler!\n",edges); | ||
110 | for (i=0; i<sizeof(edge_foos)/sizeof(EDGE_HANDLER); i++) | ||
111 | { | ||
112 | if (i==0) printf(" Options are: "); | ||
113 | else printf(", "); | ||
114 | printf("%s",edge_foos[i].name); | ||
115 | } | ||
116 | printf("\n"); | ||
117 | return(0); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | ---------------- EDGE HANDLER ARGUMENTS ------------------------ | ||
122 | filt - array of filter taps. | ||
123 | x_dim, y_dim - x and y dimensions of filt. | ||
124 | x_pos - position of filter relative to the horizontal image edges. Negative | ||
125 | values indicate left edge, positive indicate right edge. Zero | ||
126 | indicates that the filter is not touching either edge. An absolute | ||
127 | value of 1 indicates that the edge tap of the filter is over the | ||
128 | edge pixel of the image. | ||
129 | y_pos - analogous to x_pos. | ||
130 | result - array where the resulting filter will go. The edge | ||
131 | of this filter will be aligned with the image for application... | ||
132 | f_or_e - equal to one of the two constants EXPAND or FILTER. | ||
133 | -------------------------------------------------------------------- | ||
134 | */ | ||
135 | |||
136 | |||
137 | /* -------------------------------------------------------------------- | ||
138 | nocompute() - Return zero for values where filter hangs over the edge. | ||
139 | */ | ||
140 | |||
141 | int nocompute(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
142 | register double *filt, *result; | ||
143 | register int x_dim; | ||
144 | int y_dim, x_pos, y_pos, f_or_e; | ||
145 | { | ||
146 | register int i; | ||
147 | register int size = x_dim*y_dim; | ||
148 | |||
149 | if ( (x_pos>1) OR (x_pos<-1) OR (y_pos>1) OR (y_pos<-1) ) | ||
150 | for (i=0; i<size; i++) result[i] = 0.0; | ||
151 | else | ||
152 | for (i=0; i<size; i++) result[i] = filt[i]; | ||
153 | return(0); | ||
154 | } | ||
155 | |||
156 | /* -------------------------------------------------------------------- | ||
157 | zero() - Zero outside of image. Discontinuous, but adds zero energy. */ | ||
158 | |||
159 | int zero(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
160 | register double *filt, *result; | ||
161 | register int x_dim; | ||
162 | int y_dim, x_pos, y_pos, f_or_e; | ||
163 | { | ||
164 | register int y_filt,x_filt, y_res,x_res; | ||
165 | int filt_sz = x_dim*y_dim; | ||
166 | int x_start = ((x_pos>0)?(x_pos-1):((x_pos<0)?(x_pos+1):0)); | ||
167 | int y_start = x_dim * ((y_pos>0)?(y_pos-1):((y_pos<0)?(y_pos+1):0)); | ||
168 | int i; | ||
169 | |||
170 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
171 | |||
172 | for (y_filt=0, y_res=y_start; | ||
173 | y_filt<filt_sz; | ||
174 | y_filt+=x_dim, y_res+=x_dim) | ||
175 | if ((y_res >= 0) AND (y_res < filt_sz)) | ||
176 | for (x_filt=y_filt, x_res=x_start; | ||
177 | x_filt<y_filt+x_dim; | ||
178 | x_filt++, x_res++) | ||
179 | if ((x_res >= 0) AND (x_res < x_dim)) | ||
180 | result[y_res+x_res] = filt[x_filt]; | ||
181 | return(0); | ||
182 | } | ||
183 | |||
184 | /* -------------------------------------------------------------------- | ||
185 | repeat() - repeat edge pixel. Continuous, but content is usually | ||
186 | different from image. | ||
187 | */ | ||
188 | |||
189 | int repeat(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
190 | register double *filt, *result; | ||
191 | register int x_dim; | ||
192 | int y_dim, x_pos, y_pos, f_or_e; | ||
193 | { | ||
194 | register int y_filt,x_filt, y_res,x_res; | ||
195 | int filt_sz = x_dim*y_dim; | ||
196 | int x_start = ((x_pos>0)?(x_pos-1):((x_pos<0)?(x_pos+1):0)); | ||
197 | int y_start = x_dim * ((y_pos>0)?(y_pos-1):((y_pos<0)?(y_pos+1):0)); | ||
198 | int i; | ||
199 | |||
200 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
201 | |||
202 | for (y_filt=0, y_res=y_start; | ||
203 | y_filt<filt_sz; | ||
204 | y_filt+=x_dim, y_res+=x_dim) | ||
205 | for (x_filt=y_filt, x_res=x_start; | ||
206 | x_filt<y_filt+x_dim; | ||
207 | x_filt++, x_res++) | ||
208 | result[((y_res>=0)?((y_res<filt_sz)?y_res:(filt_sz-x_dim)):0) | ||
209 | + ((x_res>=0)?((x_res<x_dim)?x_res:(x_dim-1)):0)] | ||
210 | += filt[x_filt]; | ||
211 | return(0); | ||
212 | } | ||
213 | |||
214 | /* -------------------------------------------------------------------- | ||
215 | reflect2() - "Normal" image reflection. The edge pixel is repeated, | ||
216 | then the next pixel, etc. Continuous, attempting to maintain | ||
217 | "similar" content, but discontinuous first derivative. | ||
218 | */ | ||
219 | |||
220 | int reflect2(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
221 | register double *filt, *result; | ||
222 | register int x_dim; | ||
223 | int y_dim, x_pos, y_pos, f_or_e; | ||
224 | { | ||
225 | register int y_filt,x_filt, y_edge,x_edge; | ||
226 | register int x_base = (x_pos>0)?(x_dim-1):0; | ||
227 | register int y_base = (y_pos>0)?(x_dim*(y_dim-1)):0; | ||
228 | int filt_sz = x_dim*y_dim; | ||
229 | int x_edge_dist = (x_pos>0)?(x_pos-x_dim-1):(x_pos+1); | ||
230 | int y_edge_dist = x_dim * ((y_pos>0)?(y_pos-y_dim-1):(y_pos+1)); | ||
231 | int i; | ||
232 | |||
233 | #ifdef DEBUG | ||
234 | printf("(%d,%d) ",y_pos,x_pos); | ||
235 | if (x_pos==0) printf("\n"); | ||
236 | #endif | ||
237 | |||
238 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
239 | |||
240 | for (y_filt=0, y_edge=y_edge_dist; | ||
241 | y_filt<filt_sz; | ||
242 | y_filt+=x_dim, y_edge+=x_dim) | ||
243 | { | ||
244 | if (y_edge IS 0) y_edge+=x_dim; | ||
245 | for (x_filt=y_filt, x_edge=x_edge_dist; | ||
246 | x_filt<y_filt+x_dim; | ||
247 | x_filt++, x_edge++) | ||
248 | { | ||
249 | if (x_edge IS 0) x_edge++; | ||
250 | result[ABS(y_base-ABS(y_edge)+x_dim) + ABS(x_base-ABS(x_edge)+1)] | ||
251 | += filt[x_filt]; | ||
252 | } | ||
253 | } | ||
254 | return(0); | ||
255 | } | ||
256 | |||
257 | /* -------------------------------------------------------------------- | ||
258 | reflect1() - Reflection through the edge pixels. This is the right thing | ||
259 | to do if you are subsampling by 2, since it maintains parity (even | ||
260 | pixels positions remain even, odd ones remain odd). (note: procedure differs | ||
261 | depending on f_or_e parameter). */ | ||
262 | |||
263 | int reflect1(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
264 | register double *filt, *result; | ||
265 | register int x_dim; | ||
266 | int y_dim, x_pos, y_pos, f_or_e; | ||
267 | { | ||
268 | int filt_sz = x_dim*y_dim; | ||
269 | register int x_start = 0, y_start = 0, x_stop = x_dim, y_stop = filt_sz; | ||
270 | register int y_filt,x_filt, y_edge,x_edge; | ||
271 | register int x_base = (x_pos>0)?(x_dim-1):0; | ||
272 | register int y_base = (y_pos>0)?(x_dim*(y_dim-1)):0; | ||
273 | int x_edge_dist = (x_pos>0)?(x_pos-x_dim):((x_pos<0)?(x_pos+1):0); | ||
274 | int y_edge_dist = x_dim * ((y_pos>0)?(y_pos-y_dim):((y_pos<0)?(y_pos+1):0)); | ||
275 | int i; | ||
276 | int mx_pos = (x_dim/2)+1; | ||
277 | int my_pos = (y_dim/2)+1; | ||
278 | |||
279 | #ifdef DEBUG | ||
280 | printf("(%d,%d) ",y_pos,x_pos); | ||
281 | if (x_pos==0) printf("\n"); | ||
282 | #endif | ||
283 | |||
284 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
285 | |||
286 | /* if EXPAND and filter is centered on image edge, do not reflect */ | ||
287 | if (f_or_e IS EXPAND) | ||
288 | { | ||
289 | if (x_pos IS mx_pos) x_stop = (x_dim+1)/2; | ||
290 | else if (x_pos IS -mx_pos) { x_start = x_dim/2; x_edge_dist = 0; } | ||
291 | |||
292 | if (y_pos IS my_pos) y_stop = x_dim*((y_dim+1)/2); | ||
293 | else if (y_pos IS -my_pos) { y_start = x_dim*(y_dim/2); y_edge_dist = 0;} | ||
294 | } | ||
295 | |||
296 | /* reflect at boundary of image */ | ||
297 | for (y_filt=y_start, y_edge=y_edge_dist; | ||
298 | y_filt<y_stop; | ||
299 | y_filt+=x_dim, y_edge+=x_dim) | ||
300 | for (x_filt=y_filt+x_start, x_edge=x_edge_dist; | ||
301 | x_filt<y_filt+x_stop; | ||
302 | x_filt++, x_edge++) | ||
303 | result[ABS(y_base-ABS(y_edge)) + ABS(x_base-ABS(x_edge))] | ||
304 | += filt[x_filt]; | ||
305 | |||
306 | /* if EXPAND and filter is not centered on image edge, mult edge by 2 */ | ||
307 | if (f_or_e IS EXPAND) | ||
308 | { | ||
309 | if ( (ABS(x_pos) ISNT mx_pos) AND (x_pos ISNT 0) ) | ||
310 | for (y_filt=x_base; y_filt<filt_sz; y_filt+=x_dim) | ||
311 | result[y_filt] += result[y_filt]; | ||
312 | if ( (ABS(y_pos) ISNT my_pos) AND (y_pos ISNT 0) ) | ||
313 | for (x_filt=y_base; x_filt<y_base+x_dim; x_filt++) | ||
314 | result[x_filt] += result[x_filt]; | ||
315 | } | ||
316 | return(0); | ||
317 | } | ||
318 | |||
319 | /* -------------------------------------------------------------------- | ||
320 | Extend() - Extend image by reflecting and inverting about edge pixel | ||
321 | value. Maintains continuity in intensity AND first derivative (but | ||
322 | not higher derivs). | ||
323 | */ | ||
324 | |||
325 | int Extend(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
326 | register double *filt, *result; | ||
327 | register int x_dim; | ||
328 | int y_dim, x_pos, y_pos, f_or_e; | ||
329 | { | ||
330 | int filt_sz = x_dim*y_dim; | ||
331 | register int x_start = 0, y_start = 0, x_stop = x_dim, y_stop = filt_sz; | ||
332 | register int y_filt,x_filt, y_edge,x_edge; | ||
333 | register int x_base = (x_pos>0)?(x_dim-1):0; | ||
334 | register int y_base = (y_pos>0)?(x_dim*(y_dim-1)):0; | ||
335 | int x_edge_dist = (x_pos>0)?(x_pos-x_dim):((x_pos<-1)?(x_pos+1):0); | ||
336 | int y_edge_dist = x_dim * ((y_pos>0)?(y_pos-y_dim):((y_pos<-1)?(y_pos+1):0)); | ||
337 | int i; | ||
338 | int mx_pos = (x_dim/2)+1; | ||
339 | int my_pos = (y_dim/2)+1; | ||
340 | |||
341 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
342 | |||
343 | /* if EXPAND and filter is centered on image edge, do not reflect */ | ||
344 | if (f_or_e IS EXPAND) | ||
345 | { | ||
346 | if (x_pos IS mx_pos) x_stop = (x_dim+1)/2; | ||
347 | else if (x_pos IS -mx_pos) { x_start = x_dim/2; x_edge_dist = 0; } | ||
348 | |||
349 | if (y_pos IS my_pos) y_stop = x_dim*((y_dim+1)/2); | ||
350 | else if (y_pos IS -my_pos) { y_start = x_dim*(y_dim/2); y_edge_dist = 0;} | ||
351 | } | ||
352 | |||
353 | /* reflect at boundary of image */ | ||
354 | for (y_filt=y_start, y_edge=y_edge_dist; | ||
355 | y_filt<y_stop; | ||
356 | y_filt+=x_dim, y_edge+=x_dim) | ||
357 | for (x_filt=y_filt+x_start, x_edge=x_edge_dist; | ||
358 | x_filt<y_filt+x_stop; | ||
359 | x_filt++, x_edge++) | ||
360 | if (((!y_base AND (sgn(y_edge) IS -1)) /* y overhanging */ | ||
361 | OR | ||
362 | (y_base AND (sgn(y_edge) IS 1))) | ||
363 | ISNT /* XOR */ | ||
364 | ((!x_base AND (sgn(x_edge) IS -1)) /* x overhanging */ | ||
365 | OR | ||
366 | (x_base AND (sgn(x_edge) IS 1)))) | ||
367 | { | ||
368 | result[ABS(y_base-ABS(y_edge)) + ABS(x_base-ABS(x_edge))] | ||
369 | -= filt[x_filt]; | ||
370 | result[clip(y_base+y_edge,0,y_dim) + clip(x_base+x_edge,0,x_dim)] | ||
371 | += filt[x_filt] + filt[x_filt]; | ||
372 | } | ||
373 | else result[ABS(y_base-ABS(y_edge)) + ABS(x_base-ABS(x_edge))] | ||
374 | += filt[x_filt]; | ||
375 | return(0); | ||
376 | } | ||
377 | |||
378 | /* -------------------------------------------------------------------- | ||
379 | predict() - Simple prediction. Like zero, but multiplies the result | ||
380 | by the reciprocal of the percentage of filter being used. (i.e. if | ||
381 | 50% of the filter is hanging over the edge of the image, multiply the | ||
382 | taps being used by 2). */ | ||
383 | |||
384 | int predict(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
385 | register double *filt, *result; | ||
386 | register int x_dim; | ||
387 | int y_dim, x_pos, y_pos, f_or_e; | ||
388 | { | ||
389 | register int y_filt,x_filt, y_res,x_res; | ||
390 | register double taps_used = 0.0; /* int *** */ | ||
391 | register double fraction = 0.0; | ||
392 | int filt_sz = x_dim*y_dim; | ||
393 | int x_start = ((x_pos>0)?(x_pos-1):((x_pos<0)?(x_pos+1):0)); | ||
394 | int y_start = x_dim * ((y_pos>0)?(y_pos-1):((y_pos<0)?(y_pos+1):0)); | ||
395 | int i; | ||
396 | |||
397 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
398 | |||
399 | for (y_filt=0, y_res=y_start; | ||
400 | y_filt<filt_sz; | ||
401 | y_filt+=x_dim, y_res+=x_dim) | ||
402 | if ((y_res >= 0) AND (y_res < filt_sz)) | ||
403 | for (x_filt=y_filt, x_res=x_start; | ||
404 | x_filt<y_filt+x_dim; | ||
405 | x_filt++, x_res++) | ||
406 | if ((x_res >= 0) AND (x_res < x_dim)) | ||
407 | { | ||
408 | result[y_res+x_res] = filt[x_filt]; | ||
409 | taps_used += ABS(filt[x_filt]); | ||
410 | } | ||
411 | printf("TU: %f\n",taps_used); | ||
412 | if (f_or_e IS FILTER) | ||
413 | { | ||
414 | /* fraction = ( (double) filt_sz ) / ( (double) taps_used ); */ | ||
415 | for (i=0; i<filt_sz; i++) fraction += ABS(filt[i]); | ||
416 | fraction = ( fraction / taps_used ); | ||
417 | for (i=0; i<filt_sz; i++) result[i] *= fraction; | ||
418 | } | ||
419 | return(0); | ||
420 | } | ||
421 | |||
422 | |||
423 | /* -------------------------------------------------------------------- | ||
424 | Reflect, multiplying tap of filter which is at the edge of the image | ||
425 | by root 2. This maintains orthogonality of odd-length linear-phase | ||
426 | QMF filters, but it is not useful for most applications, since it | ||
427 | alters the DC level. */ | ||
428 | |||
429 | int ereflect(filt,x_dim,y_dim,x_pos,y_pos,result,f_or_e) | ||
430 | register double *filt, *result; | ||
431 | register int x_dim; | ||
432 | int y_dim, x_pos, y_pos, f_or_e; | ||
433 | { | ||
434 | register int y_filt,x_filt, y_edge,x_edge; | ||
435 | register int x_base = (x_pos>0)?(x_dim-1):0; | ||
436 | register int y_base = x_dim * ( (y_pos>0)?(y_dim-1):0 ); | ||
437 | int filt_sz = x_dim*y_dim; | ||
438 | int x_edge_dist = (x_pos>1)?(x_pos-x_dim):((x_pos<-1)?(x_pos+1):0); | ||
439 | int y_edge_dist = x_dim * ( (y_pos>1)?(y_pos-y_dim):((y_pos<-1)?(y_pos+1):0) ); | ||
440 | int i; | ||
441 | double norm,onorm; | ||
442 | |||
443 | for (i=0; i<filt_sz; i++) result[i] = 0.0; | ||
444 | |||
445 | /* reflect at boundary */ | ||
446 | for (y_filt=0, y_edge=y_edge_dist; | ||
447 | y_filt<filt_sz; | ||
448 | y_filt+=x_dim, y_edge+=x_dim) | ||
449 | for (x_filt=y_filt, x_edge=x_edge_dist; | ||
450 | x_filt<y_filt+x_dim; | ||
451 | x_filt++, x_edge++) | ||
452 | result[ABS(y_base-ABS(y_edge)) + ABS(x_base-ABS(x_edge))] | ||
453 | += filt[x_filt]; | ||
454 | |||
455 | /* now multiply edge by root 2 */ | ||
456 | if (x_pos ISNT 0) | ||
457 | for (y_filt=x_base; y_filt<filt_sz; y_filt+=x_dim) | ||
458 | result[y_filt] *= ROOT2; | ||
459 | if (y_pos ISNT 0) | ||
460 | for (x_filt=y_base; x_filt<y_base+x_dim; x_filt++) | ||
461 | result[x_filt] *= ROOT2; | ||
462 | |||
463 | /* now normalize to norm of original filter */ | ||
464 | for (norm=0.0,i=0; i<filt_sz; i++) | ||
465 | norm += (result[i]*result[i]); | ||
466 | norm=sqrt(norm); | ||
467 | |||
468 | for (onorm=0.0,i=0; i<filt_sz; i++) | ||
469 | onorm += (filt[i]*filt[i]); | ||
470 | onorm = sqrt(onorm); | ||
471 | |||
472 | norm = norm/onorm; | ||
473 | for (i=0; i<filt_sz; i++) | ||
474 | result[i] /= norm; | ||
475 | return(0); | ||
476 | } | ||
477 | |||
478 | |||
479 | /* ------- printout stuff for testing ------------------------------ | ||
480 | printf("Xpos: %d, Ypos: %d", x_pos, y_pos); | ||
481 | for (y_filt=0; y_filt<y_dim; y_filt++) | ||
482 | { | ||
483 | printf("\n"); | ||
484 | for (x_filt=0; x_filt<x_dim; x_filt++) | ||
485 | printf("%6.1f", result[y_filt*x_dim+x_filt]); | ||
486 | } | ||
487 | printf("\n"); | ||
488 | */ | ||
489 | |||
490 | |||
491 | |||
492 | /* Local Variables: */ | ||
493 | /* buffer-read-only: t */ | ||
494 | /* End: */ | ||