int NI_RankFilter(PyArrayObject* input, int rank, PyArrayObject* footprint, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { 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; Bool *pf = NULL; double *buffer = NULL; int ll, err = 0; NPY_BEGIN_THREADS_DEF; /* 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; } } /* buffer for rank calculation: */ buffer = (double*)malloc(filter_size * sizeof(double)); if (!buffer) { PyErr_NoMemory(); goto exit; } /* iterator over the elements: */ oo = offsets; /* 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; NPY_BEGIN_THREADS; /* 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]; /* iterator over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (NI_NormalizeType(input->descr->type_num)) { CASE_RANK_POINT(pi, oo, filter_size, cvalue, Bool, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, UInt8, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, UInt16, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, UInt32, rank, buffer, tmp, border_flag_value); #if HAS_UINT64 CASE_RANK_POINT(pi, oo, filter_size, cvalue, UInt64, rank, buffer, tmp, border_flag_value); #endif CASE_RANK_POINT(pi, oo, filter_size, cvalue, Int8, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, Int16, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, Int32, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, Int64, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, Float32, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(pi, oo, filter_size, cvalue, Float64, rank, buffer, tmp, border_flag_value); default: err = 1; 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: err = 1; goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: NPY_END_THREADS; if (err == 1) { PyErr_SetString(PyExc_RuntimeError, "array type not supported"); } if (offsets) free(offsets); if (buffer) free(buffer); return PyErr_Occurred() ? 0 : 1; }
int NI_RankFilter(PyArrayObject* input, int rank, PyArrayObject* footprint, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { 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; npy_bool *pf = NULL; double *buffer = NULL; int err = 0; NPY_BEGIN_THREADS_DEF; /* 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; } } /* buffer for rank calculation: */ buffer = malloc(filter_size * sizeof(double)); if (!buffer) { PyErr_NoMemory(); goto exit; } /* iterator over the elements: */ oo = offsets; /* 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; NPY_BEGIN_THREADS; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* iterator over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (PyArray_TYPE(input)) { CASE_RANK_POINT(NPY_BOOL, npy_bool, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_UBYTE, npy_ubyte, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_USHORT, npy_ushort, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_UINT, npy_uint, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_ULONG, npy_ulong, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_ULONGLONG, npy_ulonglong, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_BYTE, npy_byte, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_SHORT, npy_short, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_INT, npy_int, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_LONG, npy_long, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_LONGLONG, npy_longlong, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_FLOAT, npy_float, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); CASE_RANK_POINT(NPY_DOUBLE, npy_double, pi, oo, filter_size, cvalue, rank, buffer, tmp, border_flag_value); default: err = 1; 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: err = 1; goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: NPY_END_THREADS; if (err == 1) { PyErr_SetString(PyExc_RuntimeError, "array type not supported"); } free(offsets); free(buffer); return PyErr_Occurred() ? 0 : 1; }