Skip to content

Commit 170bfd2

Browse files
committed
feat: added grayscale function
1 parent a5759ad commit 170bfd2

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ python-install:
55
pip3 install .
66

77
python-install-editable:
8-
pip3 install -e .[development]
8+
pip3 install -e .[development]

src/app/fast/foo.c

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,103 @@
22
#include <Python.h>
33
#include <numpy/arrayobject.h>
44

5-
static PyObject *
6-
spam_system(PyObject *self, PyObject *args)
7-
{
8-
const char *command;
9-
int sts;
10-
11-
if (!PyArg_ParseTuple(args, "s", &command))
12-
return NULL;
13-
sts = system(command);
14-
return PyLong_FromLong(sts);
15-
}
16-
175
static PyObject *
18-
numpy_add(PyObject *self, PyObject *args){
6+
numpy_grayscale(PyObject *self, PyObject *args){
197
PyArrayObject *arr;
208
PyArg_ParseTuple(args, "O", &arr);
219
if(PyErr_Occurred()){
2210
return NULL;
2311
}
12+
2413
if(!PyArray_Check(arr) || PyArray_TYPE(arr) != NPY_DOUBLE) {
2514
PyErr_SetString(PyExc_TypeError, "Argument must be a numpy array of type double!");
2615
return NULL;
2716
}
17+
Py_INCREF(arr);
18+
19+
// PyObject* arr_copy = (PyArrayObject *)PyArray_NewCopy(arr, NPY_CORDER);
20+
21+
int src_nd = PyArray_NDIM(arr);
22+
if (src_nd != 3) {
23+
PyErr_SetString(PyExc_TypeError, "Array number of dimensions must be equal to 3");
24+
return NULL;
25+
}
26+
27+
npy_intp* src_shape = PyArray_SIZE(arr);
28+
if (src_shape[2] != 3) {
29+
PyErr_SetString(PyExc_TypeError, "Array number of must have 3 channels for colors");
30+
return NULL;
31+
}
32+
33+
npy_intp result[2] = {src_shape[0], src_shape[1]};
2834

35+
PyArrayObject *new_array = (PyArrayObject *)PyArray_SimpleNew(src_nd - 1, result, NPY_DOUBLE);
36+
37+
Py_DECREF(arr);
2938

3039
double *data = PyArray_DATA(arr);
3140
int64_t size = PyArray_SIZE(arr);
3241

33-
double total=0;
34-
for (int i=0; i < size; i++){
35-
total += data[i];
42+
double* new_data = PyArray_DATA(new_array);
43+
for (int i = 0; i < src_shape[0]; i++)
44+
{
45+
for (int j = 0; j < src_shape[1]; ++j)
46+
{
47+
for (int k = 0; k < src_shape[2]; ++k)
48+
{
49+
new_data[i * src_shape[1] + j] = (
50+
data[i * src_shape[1] * src_shape[2] + j * src_shape[2] + 0]
51+
+ data[i * src_shape[1] * src_shape[2] + j * src_shape[2] + 1]
52+
+ data[i * src_shape[1] * src_shape[2] + j * src_shape[2] + 2]
53+
) / 3;
54+
}
55+
}
3656
}
37-
return PyFloat_FromDouble(total);
57+
58+
return new_array;
3859
}
3960

4061
static PyObject *SpamError = NULL;
4162

4263
static int
43-
spam_module_exec(PyObject *m)
64+
fast_module_exec(PyObject *m)
4465
{
4566
if (SpamError != NULL) {
4667
PyErr_SetString(PyExc_ImportError,
47-
"cannot initialize spam module more than once");
68+
"cannot initialize fast module more than once");
4869
return -1;
4970
}
50-
SpamError = PyErr_NewException("spam.error", NULL, NULL);
71+
SpamError = PyErr_NewException("fast.error", NULL, NULL);
5172
if (PyModule_AddObjectRef(m, "SpamError", SpamError) < 0) {
5273
return -1;
5374
}
5475

5576
return 0;
5677
}
5778

58-
static PyMethodDef spam_methods[] = {
59-
{"system", spam_system, METH_VARARGS,
60-
"Execute a shell command."},
61-
{"numpy_add", numpy_add, METH_VARARGS,
62-
"Perform adding operation."},
79+
static PyMethodDef fast_methods[] = {
80+
{"grayscale", numpy_grayscale, METH_VARARGS,
81+
"Perform grayscale operation, return copy."},
6382
{NULL, NULL, 0, NULL} /* Sentinel */
6483
};
6584

66-
static PyModuleDef_Slot spam_module_slots[] = {
67-
{Py_mod_exec, spam_module_exec},
85+
static PyModuleDef_Slot fast_module_slots[] = {
86+
{Py_mod_exec, fast_module_exec},
6887
{0, NULL}
6988
};
7089

71-
static struct PyModuleDef spam_module = {
90+
static struct PyModuleDef fast_module = {
7291
.m_base = PyModuleDef_HEAD_INIT,
73-
.m_name = "spam",
92+
.m_name = "fast",
7493
.m_size = 0, // non-negative
75-
.m_slots = spam_module_slots,
76-
.m_methods = spam_methods
94+
.m_slots = fast_module_slots,
95+
.m_methods = fast_methods
7796
};
7897

7998
PyMODINIT_FUNC
8099
PyInit_fast(void)
81100
{
82-
PyObject* module_obj = PyModuleDef_Init(&spam_module);
101+
PyObject* module_obj = PyModuleDef_Init(&fast_module);
83102
import_array();
84103
return module_obj;
85104
}

0 commit comments

Comments
 (0)