int NI_GenericFilter(PyArrayObject* input, int (*function)(double*, npy_intp, double*, void*), void *data, PyArrayObject* footprint, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { Bool *pf = NULL; npy_intp fsize, jj, filter_size = 0, border_flag_value; npy_intp *offsets = NULL, *oo, size; NI_FilterIterator fi; NI_Iterator ii, io; char *pi, *po; double *buffer = NULL; int ll; /* get the the footprint: */ fsize = 1; for(ll = 0; ll < footprint->nd; ll++) fsize *= footprint->dimensions[ll]; pf = (Bool*)PyArray_DATA(footprint); for(jj = 0; jj < fsize; jj++) { if (pf[jj]) ++filter_size; } /* initialize filter offsets: */ if (!NI_InitFilterOffsets(input, pf, footprint->dimensions, origins, mode, &offsets, &border_flag_value, NULL)) goto exit; /* initialize filter iterator: */ if (!NI_InitFilterIterator(input->nd, footprint->dimensions, filter_size, input->dimensions, origins, &fi)) goto exit; /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = 1; for(ll = 0; ll < input->nd; ll++) size *= input->dimensions[ll]; /* buffer for filter calculation: */ buffer = (double*)malloc(filter_size * sizeof(double)); if (!buffer) { PyErr_NoMemory(); goto exit; } /* iterate over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (NI_NormalizeType(input->descr->type_num)) { CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Bool, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt8, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt16, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt32, tmp, border_flag_value, function, data, buffer); #if HAS_UINT64 CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt64, tmp, border_flag_value, function, data, buffer); #endif CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int8, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int16, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int32, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int64, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Float32, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Float64, tmp, border_flag_value, function, data, buffer); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } switch (NI_NormalizeType(output->descr->type_num)) { CASE_FILTER_OUT(po, tmp, Bool); CASE_FILTER_OUT(po, tmp, UInt8); CASE_FILTER_OUT(po, tmp, UInt16); CASE_FILTER_OUT(po, tmp, UInt32); #if HAS_UINT64 CASE_FILTER_OUT(po, tmp, UInt64); #endif CASE_FILTER_OUT(po, tmp, Int8); CASE_FILTER_OUT(po, tmp, Int16); CASE_FILTER_OUT(po, tmp, Int32); CASE_FILTER_OUT(po, tmp, Int64); CASE_FILTER_OUT(po, tmp, Float32); CASE_FILTER_OUT(po, tmp, Float64); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: if (offsets) free(offsets); if (buffer) free(buffer); return PyErr_Occurred() ? 0 : 1; }
int NI_GenericFilter(PyArrayObject* input, int (*function)(double*, npy_intp, double*, void*), void *data, PyArrayObject* footprint, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { npy_bool *pf = NULL; npy_intp fsize, jj, filter_size = 0, border_flag_value; npy_intp *offsets = NULL, *oo, size; NI_FilterIterator fi; NI_Iterator ii, io; char *pi, *po; double *buffer = NULL; /* get the the footprint: */ fsize = PyArray_SIZE(footprint); pf = (npy_bool*)PyArray_DATA(footprint); for(jj = 0; jj < fsize; jj++) { if (pf[jj]) ++filter_size; } /* initialize filter offsets: */ if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(footprint), origins, mode, &offsets, &border_flag_value, NULL)) { goto exit; } /* initialize filter iterator: */ if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(footprint), filter_size, PyArray_DIMS(input), origins, &fi)) { goto exit; } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* buffer for filter calculation: */ buffer = malloc(filter_size * sizeof(double)); if (!buffer) { PyErr_NoMemory(); goto exit; } /* iterate over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (PyArray_TYPE(input)) { CASE_FILTER_POINT(NPY_BOOL, npy_bool, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_UBYTE, npy_ubyte, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_USHORT, npy_ushort, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_UINT, npy_uint, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_ULONG, npy_ulong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_ULONGLONG, npy_ulonglong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_BYTE, npy_byte, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_SHORT, npy_short, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_INT, npy_int, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_LONG, npy_long, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_LONGLONG, npy_longlong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_FLOAT, npy_float, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_DOUBLE, npy_double, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp); CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp); CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp); CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp); CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp); CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp); CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp); CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp); CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp); CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp); CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp); CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp); CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: free(offsets); free(buffer); return PyErr_Occurred() ? 0 : 1; }