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-
175static 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
4061static PyObject * SpamError = NULL ;
4162
4263static 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
7998PyMODINIT_FUNC
8099PyInit_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