works without pygame, where not needed
[imago.git] / pcf.c
1 #include <Python.h>
2 #include <math.h>
3
4 /* TODO delete or document this
5  *
6  */
7 static PyObject* py_combine(PyObject* self, PyObject* args)
8 {
9         const unsigned char *im_bg;
10         const unsigned char *im_fg;
11         int size;
12
13         int i;
14         long int sum;
15         int area;
16
17         if (!PyArg_ParseTuple(args, "s#s#", &im_bg, &size, &im_fg, &size)) return NULL;
18
19         sum = 0;
20         area = 0;
21         for (i=0; i < size; i++) {
22                 if (im_fg[i]){
23                         sum += im_bg[i];
24                         area++;
25                 }
26         }
27
28         return Py_BuildValue("d", ((double) sum) / area);
29 }
30
31 /* Hough transform
32  *
33  * Takes dimentions of the image, the image, initial angle and TODO dt is what?.
34  * Computes Hough transform of the image. TODO size etc.
35  *
36  */
37 static PyObject* py_hough(PyObject* self, PyObject* args)
38 {
39         const unsigned char *image;
40         int x;
41         int y;
42         int size;
43         double init_angle;
44         double dt;
45
46         int i;
47         int j;
48         int a;
49
50         double distance;
51         int column;
52         int minimum;
53         int maximum;
54
55         int *matrix;
56         unsigned char *n_image;
57         PyObject *result;
58
59         if (!PyArg_ParseTuple(args, "(ii)s#dd", &x, &y, &image, &size, &init_angle, &dt)) return NULL;
60         // x and y are width and height of the image as ints
61         // Python sends image as (byte)string and since it is not null-terminated, must send its size
62         // init_angle and dt are doubles
63         
64
65         matrix = (int*) malloc(size * sizeof(int));
66         for (i=0; i < x * y; i++) {
67                 matrix[i] = 0;
68         }
69
70
71
72         for (i=0; i < x; i++) {
73                 for (j=0; j < y; j++) {
74                         if (image[j * x + i]){
75                                 for (a=0; a < y; a++){
76                                         distance = (((i - x / 2) * sin((dt * a) + init_angle)) +
77                                                         ((j - y / 2) * -cos((dt * a) + init_angle)) +
78                                                         x / 2);
79                                         column = (int) round(distance);
80                                         if ((0 <= column) && (column < x)){
81                                                 matrix[a * x + column]++;
82                                         }
83                                 }
84                         }
85                 }
86         }
87         
88
89
90
91         n_image = (char*) malloc(size * sizeof(char));
92         minimum = matrix[0];
93         maximum = matrix[0];
94         for (i=1; i < x * y; i++){
95                 if (matrix[i] < minimum) minimum = matrix[i];
96                 if (matrix[i] > maximum) maximum = matrix[i];
97         }
98         maximum = maximum - minimum + 1;
99         for (i=0; i < x * y; i++){
100                 n_image[i] = (char) ((((float) (matrix[i] - minimum)) / maximum) * 256);
101         }
102
103         free(matrix);
104
105         result = Py_BuildValue("s#", n_image, size);
106         free(n_image);
107         return result;
108 }
109
110 /* Edge detection
111  *
112  * Takes image size, the image, and the size of TODO what?
113  */
114 static PyObject* py_edge(PyObject* self, PyObject* args)
115 {
116         const unsigned char *image;
117         int x;
118         int y;
119         int size;
120
121         int i;
122         int j;
123         int sum;
124
125         unsigned char *n_image;
126         PyObject *result;
127
128         if (!PyArg_ParseTuple(args, "(ii)s#", &x, &y, &image, &size)) return NULL;
129         // x and y are width and height of the image as ints
130         // Python sends image as (byte)string and since it is not null-terminated, must send its size
131
132         n_image = (char*) malloc(size);
133         for (i=0; i < 2 * x; i++) {
134                 n_image[i] = 0;
135                 n_image[(y - 2) * x + i] = 0;
136         }
137         for (i=0; i < y; i++) {
138                 n_image[x * i] = 0;
139                 n_image[x * i + 1] = 0;
140                 n_image[x * i + x - 2] = 0;
141                 n_image[x * i + x - 1] = 0;
142         }
143
144
145
146         for (i=2; i < x - 2; i++) {
147                 for (j=2; j < y - 2; j++) {
148                         sum = image[x * j + i - 2] + image[x * j + i - 1] + image[x * j + i + 1] + image[x * j + i + 2] + 
149                                 image[x * (j - 2) + i - 2] + image[x * (j - 2) + i - 1] + image[x * (j - 2) + i] + 
150                                 image[x * (j - 2) + i + 1] + image[x * (j - 2) + i + 2] + 
151                                 image[x * (j - 1) + i - 2] + image[x * (j - 1) + i - 1] + image[x * (j - 1) + i] + 
152                                 image[x * (j - 1) + i + 1] + image[x * (j - 1) + i + 2] +
153                                 image[x * (j + 2) + i - 2] + image[x * (j + 2) + i - 1] + image[x * (j + 2) + i] + 
154                                 image[x * (j + 2) + i + 1] + image[x * (j + 2) + i + 2] +
155                                 image[x * (j + 1) + i - 2] + image[x * (j + 1) + i - 1] + image[x * (j + 1) + i] + 
156                                 image[x * (j + 1) + i + 1] + image[x * (j + 1) + i + 2] 
157                                 - (24 * image[x * j + i]);
158                         if (sum < 0) sum = 0;
159                         if (sum > 255) sum = 255;
160                         n_image[x * j + i] = sum;
161                 }
162         }
163
164
165
166         result = Py_BuildValue("s#", n_image, size);
167         free(n_image);
168         return result;
169 }
170
171
172 static PyMethodDef myModule_methods[] = {
173         {"combine", py_combine, METH_VARARGS},
174         {"edge", py_edge, METH_VARARGS},
175         {"hough", py_hough, METH_VARARGS},
176         {NULL, NULL}
177 };
178
179 void initpcf()
180 {
181                 (void) Py_InitModule("pcf", myModule_methods);
182 }