summaryrefslogtreecommitdiffstats
path: root/SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c
diff options
context:
space:
mode:
Diffstat (limited to 'SD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c')
-rwxr-xr-xSD-VBS/benchmarks/texture_synthesis/src/matlab/edges-orig.c494
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/*
17This file contains functions which determine how edges are to be
18handled when performing convolutions of images with linear filters.
19Any edge handling function which is local and linear may be defined,
20except (unfortunately) constants cannot be added. So to treat the
21edges as if the image is surrounded by a gray field, you must paste it
22into a gray image, convolve, and crop it out...
23The main convolution function is called internal_filter and is defined
24in the file convolve.c. The idea is that the convolution function
25calls the edge handling function which computes a new filter based on
26the old filter and the distance to the edge of the image. For
27example, reflection is done by reflecting the filter through the
28appropriate axis and summing. Currently defined functions are listed
29below.
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
44int reflect1(), reflect2(), repeat(), zero(), Extend(), nocompute();
45int 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/*
96Function looks up an edge handler id string in the structure above, and
97returns the associated function
98*/
99fptr 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 ------------------------
122filt - array of filter taps.
123x_dim, y_dim - x and y dimensions of filt.
124x_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.
129y_pos - analogous to x_pos.
130result - array where the resulting filter will go. The edge
131 of this filter will be aligned with the image for application...
132f_or_e - equal to one of the two constants EXPAND or FILTER.
133--------------------------------------------------------------------
134*/
135
136
137/* --------------------------------------------------------------------
138nocompute() - Return zero for values where filter hangs over the edge.
139*/
140
141int 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/* --------------------------------------------------------------------
157zero() - Zero outside of image. Discontinuous, but adds zero energy. */
158
159int 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/* --------------------------------------------------------------------
185repeat() - repeat edge pixel. Continuous, but content is usually
186different from image.
187*/
188
189int 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/* --------------------------------------------------------------------
215reflect2() - "Normal" image reflection. The edge pixel is repeated,
216then the next pixel, etc. Continuous, attempting to maintain
217"similar" content, but discontinuous first derivative.
218*/
219
220int 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/* --------------------------------------------------------------------
258reflect1() - Reflection through the edge pixels. This is the right thing
259to do if you are subsampling by 2, since it maintains parity (even
260pixels positions remain even, odd ones remain odd). (note: procedure differs
261depending on f_or_e parameter). */
262
263int 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/* --------------------------------------------------------------------
320Extend() - Extend image by reflecting and inverting about edge pixel
321value. Maintains continuity in intensity AND first derivative (but
322not higher derivs).
323*/
324
325int 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/* --------------------------------------------------------------------
379predict() - Simple prediction. Like zero, but multiplies the result
380by the reciprocal of the percentage of filter being used. (i.e. if
38150% of the filter is hanging over the edge of the image, multiply the
382taps being used by 2). */
383
384int 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/* --------------------------------------------------------------------
424Reflect, multiplying tap of filter which is at the edge of the image
425by root 2. This maintains orthogonality of odd-length linear-phase
426QMF filters, but it is not useful for most applications, since it
427alters the DC level. */
428
429int 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: */