-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcorrDn.c
152 lines (130 loc) · 4.5 KB
/
corrDn.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
RES = corrDn(IM, FILT, EDGES, STEP, START, STOP);
>>> See corrDn.m for documentation <<<
This is a matlab interface to the internal_reduce function.
EPS, 7/96.
*/
/* Matlab V4 types should be changed as follows:
Matrix -> mxArray
REAL -> mxREAL
mxCreateFull -> mxCreateDoubleMatrix
mxIsString -> mxIsChar
*/
/* #define V4_COMPAT */
#include <matrix.h> /* Matlab matrices */
#include <mex.h>
#include "convolve.h"
#define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
void mexFunction(int nlhs, /* Num return vals on lhs */
mxArray *plhs[], /* Matrices on lhs */
int nrhs, /* Num args on rhs */
const mxArray *prhs[] /* Matrices on rhs */
)
{
double *image,*filt, *temp, *result;
int x_fdim, y_fdim, x_idim, y_idim;
int x_rdim, y_rdim;
int x_start = 1;
int x_step = 1;
int y_start = 1;
int y_step = 1;
int x_stop, y_stop;
mxArray *arg;
double *mxMat;
char edges[15] = "reflect1";
if (nrhs<2) mexErrMsgTxt("requres at least 2 args.");
/* ARG 1: IMAGE */
arg = (mxArray*) prhs[0];
if notDblMtx(arg) mexErrMsgTxt("IMAGE arg must be a non-sparse double float matrix.");
image = mxGetPr(arg);
x_idim = (int) mxGetM(arg); /* X is inner index! */
y_idim = (int) mxGetN(arg);
/* ARG 2: FILTER */
arg = (mxArray*) prhs[1];
if notDblMtx(arg) mexErrMsgTxt("FILTER arg must be non-sparse double float matrix.");
filt = mxGetPr(arg);
x_fdim = (int) mxGetM(arg);
y_fdim = (int) mxGetN(arg);
if ((x_fdim > x_idim) || (y_fdim > y_idim))
{
mexPrintf("Filter: [%d %d], Image: [%d %d]\n",x_fdim,y_fdim,x_idim,y_idim);
mexErrMsgTxt("FILTER dimensions larger than IMAGE dimensions.");
}
/* ARG 3 (optional): EDGES */
if (nrhs>2)
{
if (!mxIsChar(prhs[2]))
mexErrMsgTxt("EDGES arg must be a string.");
mxGetString(prhs[2],edges,15);
}
/* ARG 4 (optional): STEP */
if (nrhs>3)
{
arg = (mxArray*) prhs[3];
if notDblMtx(arg) mexErrMsgTxt("STEP arg must be a double float matrix.");
if (mxGetM(arg) * mxGetN(arg) != 2)
mexErrMsgTxt("STEP arg must contain two elements.");
mxMat = mxGetPr(arg);
x_step = (int) mxMat[0];
y_step = (int) mxMat[1];
if ((x_step<1) || (y_step<1))
mexErrMsgTxt("STEP values must be greater than zero.");
}
/* ARG 5 (optional): START */
if (nrhs>4)
{
arg = (mxArray*) prhs[4];
if notDblMtx(arg) mexErrMsgTxt("START arg must be a double float matrix.");
if (mxGetM(arg) * mxGetN(arg) != 2)
mexErrMsgTxt("START arg must contain two elements.");
mxMat = mxGetPr(arg);
x_start = (int) mxMat[0];
y_start = (int) mxMat[1];
if ((x_start<1) || (x_start>x_idim) ||
(y_start<1) || (y_start>y_idim))
mexErrMsgTxt("START values must lie between 1 and the image dimensions.");
}
x_start--; /* convert to standard C indexes */
y_start--;
/* ARG 6 (optional): STOP */
if (nrhs>5)
{
if notDblMtx(prhs[5]) mexErrMsgTxt("STOP arg must be double float matrix.");
if (mxGetM(prhs[5]) * mxGetN(prhs[5]) != 2)
mexErrMsgTxt("STOP arg must contain two elements.");
mxMat = mxGetPr(prhs[5]);
x_stop = (int) mxMat[0];
y_stop = (int) mxMat[1];
if ((x_stop<x_start) || (x_stop>x_idim) ||
(y_stop<y_start) || (y_stop>y_idim))
mexErrMsgTxt("STOP values must lie between START and the image dimensions.");
}
else
{
x_stop = x_idim;
y_stop = y_idim;
}
x_rdim = (x_stop-x_start+x_step-1) / x_step;
y_rdim = (y_stop-y_start+y_step-1) / y_step;
/* mxFreeMatrix(plhs[0]); */
plhs[0] = (mxArray *) mxCreateDoubleMatrix(x_rdim,y_rdim,mxREAL);
if (plhs[0] == NULL) mexErrMsgTxt("Cannot allocate result matrix");
result = mxGetPr(plhs[0]);
temp = mxCalloc(x_fdim*y_fdim, sizeof(double));
if (temp == NULL)
mexErrMsgTxt("Cannot allocate necessary temporary space");
/*
printf("i(%d, %d), f(%d, %d), r(%d, %d), X(%d, %d, %d), Y(%d, %d, %d), %s\n",
x_idim,y_idim,x_fdim,y_fdim,x_rdim,y_rdim,
x_start,x_step,x_stop,y_start,y_step,y_stop,edges);
*/
if (strcmp(edges,"circular") == 0)
internal_wrap_reduce(image, x_idim, y_idim, filt, x_fdim, y_fdim,
x_start, x_step, x_stop, y_start, y_step, y_stop,
result);
else internal_reduce(image, x_idim, y_idim, filt, temp, x_fdim, y_fdim,
x_start, x_step, x_stop, y_start, y_step, y_stop,
result, edges);
mxFree((char *) temp);
return;
}