1
#define NO_IMPORT_ARRAY
3
2
#include "sigtools.h"
5
#include "Python.h" /* only needed for defining unsigned types or not */
6
#include "Numeric/arrayobject.h"
8
static int elsizes[] = {sizeof(char),
4
static int elsizes[] = {sizeof(Bool),
12
#ifdef PyArray_UNSIGNED_TYPES
13
sizeof(unsigned short),
16
#ifdef PyArray_UNSIGNED_TYPES
26
24
typedef void (OneMultAddFunction) (char *, char *, char *);
30
28
(*((type *) sum)) += (*((type *) term1)) * \
31
29
(*((type *) term2)); return; }
33
#ifdef PyArray_UNSIGNED_TYPES
34
MAKE_ONEMULTADD(USHORT, unsigned short)
35
MAKE_ONEMULTADD(UINT, unsigned int)
37
MAKE_ONEMULTADD(UCHAR, unsigned char)
38
MAKE_ONEMULTADD(SCHAR, signed char)
31
MAKE_ONEMULTADD(UBYTE, ubyte)
32
MAKE_ONEMULTADD(USHORT, ushort)
33
MAKE_ONEMULTADD(UINT, uint)
34
MAKE_ONEMULTADD(ULONG, ulong)
35
MAKE_ONEMULTADD(ULONGLONG, ulonglong)
37
MAKE_ONEMULTADD(BYTE, byte)
39
38
MAKE_ONEMULTADD(SHORT, short)
40
39
MAKE_ONEMULTADD(INT, int)
41
40
MAKE_ONEMULTADD(LONG, long)
41
MAKE_ONEMULTADD(LONGLONG, longlong)
42
43
MAKE_ONEMULTADD(FLOAT, float)
43
44
MAKE_ONEMULTADD(DOUBLE, double)
45
MAKE_ONEMULTADD(LONGDOUBLE, longdouble)
46
48
MAKE_ONEMULTADD(CFLOAT, __complex__ float)
47
49
MAKE_ONEMULTADD(CDOUBLE, __complex__ double)
50
MAKE_ONEMULTADD(CLONGDOUBLE, __complex__ long double)
49
52
#define MAKE_C_ONEMULTADD(fname, type) \
50
53
static void fname ## _onemultadd(char *sum, char *term1, char *term2) { \
56
59
MAKE_C_ONEMULTADD(CFLOAT, float)
57
60
MAKE_C_ONEMULTADD(CDOUBLE, double)
61
MAKE_C_ONEMULTADD(CLONGDOUBLE, longdouble)
58
62
#endif /* __GNUC__ */
60
64
static OneMultAddFunction *OneMultAdd[]={NULL,
64
#ifdef PyArray_UNSIGNED_TYPES
68
#ifdef PyArray_UNSIGNED_TYPES
77
LONGDOUBLE_onemultadd,
75
79
CDOUBLE_onemultadd,
80
CLONGDOUBLE_onemultadd,
81
NULL, NULL, NULL, NULL};
79
84
/* This could definitely be more optimized... */
81
86
int pylab_convolve_2d (char *in, /* Input data Ns[0] x Ns[1] */
82
int *instr, /* Input strides */
87
intp *instr, /* Input strides */
83
88
char *out, /* Output data */
84
int *outstr, /* Ouput strides */
89
intp *outstr, /* Ouput strides */
85
90
char *hvals, /* coefficients in filter */
86
int *hstr, /* coefficients strides */
87
int *Nwin, /* Size of kernel Nwin[0] x Nwin[1] */
88
int *Ns, /* Size of image Ns[0] x Ns[1] */
91
intp *hstr, /* coefficients strides */
92
intp *Nwin, /* Size of kernel Nwin[0] x Nwin[1] */
93
intp *Ns, /* Size of image Ns[0] x Ns[1] */
89
94
int flag, /* convolution parameters */
90
95
char *fillvalue) /* fill value */
112
117
if ((sum = calloc(type_size,2))==NULL) return -3; /* No memory */
113
118
value = sum + type_size;
115
if (outsize == FULL) {Os[0] = Ns[0]+Nwin[0]-1; Os[1] = Ns[0]+Nwin[1]-1;}
120
if (outsize == FULL) {Os[0] = Ns[0]+Nwin[0]-1; Os[1] = Ns[1]+Nwin[1]-1;}
116
121
else if (outsize == SAME) {Os[0] = Ns[0]; Os[1] = Ns[1];}
117
122
else if (outsize == VALID) {Os[0] = Ns[0]-Nwin[0]+1; Os[1] = Ns[1]-Nwin[1]+1;}
118
123
else return -1; /* Invalid output flag */
120
125
if ((boundary != PAD) && (boundary != REFLECT) && (boundary != CIRCULAR))
121
126
return -2; /* Invalid boundary flag */
128
/* Speed this up by not doing any if statements in the for loop. Need 3*3*2=18 different
129
loops executed for different conditions */
123
131
for (m=0; m < Os[0]; m++) {
124
132
/* Reposition index into input image based on requested output size */
125
133
if (outsize == FULL) new_m = convolve ? m : (m-Nwin[0]+1);