[1422d3]: / util / im2colstep.c

Download this file

132 lines (94 with data), 3.4 kB

  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
/**************************************************************************
*
* File name: im2colstep.c
*
* Ron Rubinstein
* Computer Science Department
* Technion, Haifa 32000 Israel
* ronrubin@cs
*
* Last Updated: 31.8.2009
*
*************************************************************************/
#include "mex.h"
#include <string.h>
/* Input Arguments */
#define X_IN prhs[0]
#define SZ_IN prhs[1]
#define S_IN prhs[2]
/* Output Arguments */
#define B_OUT plhs[0]
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray*prhs[])
{
double *x, *b, *s;
mwSize sz[3], stepsize[3], n[3], ndims;
mwIndex i, j, k, l, m, blocknum;
/* Check for proper number of arguments */
if (nrhs < 2 || nrhs > 3) {
mexErrMsgTxt("Invalid number of input arguments.");
} else if (nlhs > 1) {
mexErrMsgTxt("Too many output arguments.");
}
/* Check the the input dimensions */
ndims = mxGetNumberOfDimensions(X_IN);
if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ndims>3) {
mexErrMsgTxt("X should be a 2-D or 3-D double matrix.");
}
if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) {
mexErrMsgTxt("Invalid block size.");
}
if (nrhs == 3) {
if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) {
mexErrMsgTxt("Invalid step size.");
}
}
/* Get parameters */
s = mxGetPr(SZ_IN);
if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) {
mexErrMsgTxt("Invalid block size.");
}
sz[0] = (mwSize)(s[0] + 0.01);
sz[1] = (mwSize)(s[1] + 0.01);
sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1;
if (nrhs == 3) {
s = mxGetPr(S_IN);
if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) {
mexErrMsgTxt("Invalid step size.");
}
stepsize[0] = (mwSize)(s[0] + 0.01);
stepsize[1] = (mwSize)(s[1] + 0.01);
stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1;
}
else {
stepsize[0] = stepsize[1] = stepsize[2] = 1;
}
n[0] = (mxGetDimensions(X_IN))[0];
n[1] = (mxGetDimensions(X_IN))[1];
n[2] = ndims==3 ? (mxGetDimensions(X_IN))[2] : 1;
if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) {
mexErrMsgTxt("Block size too large.");
}
/* Create a matrix for the return argument */
B_OUT = mxCreateDoubleMatrix(sz[0]*sz[1]*sz[2], ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1), mxREAL);
/* Assign pointers */
x = mxGetPr(X_IN);
b = mxGetPr(B_OUT);
/* Do the actual computation */
blocknum = 0;
/* iterate over all blocks */
for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) {
for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) {
for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) {
/* copy single block */
for (m=0; m<sz[2]; m++) {
for (l=0; l<sz[1]; l++) {
memcpy(b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0], x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i, sz[0]*sizeof(double));
}
}
blocknum++;
}
}
}
return;
}