VideoTexture: use PyObjectPlus.h instead of Python.h for compatibility with Python2.3
[blender.git] / source / gameengine / VideoTexture / FilterColor.cpp
1 /* $Id$
2 -----------------------------------------------------------------------------
3 This source file is part of VideoTexture library
4
5 Copyright (c) 2007 The Zdeno Ash Miklas
6
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19 http://www.gnu.org/copyleft/lesser.txt.
20 -----------------------------------------------------------------------------
21 */
22
23
24 #include <PyObjectPlus.h>
25 #include <structmember.h>
26
27 #include "FilterColor.h"
28
29 #include "FilterBase.h"
30 #include "PyTypeList.h"
31
32 // implementation FilterGray
33
34 // attributes structure
35 static PyGetSetDef filterGrayGetSets[] =
36 { // attributes from FilterBase class
37         {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
38         {NULL}
39 };
40
41 // define python type
42 PyTypeObject FilterGrayType =
43
44         PyObject_HEAD_INIT(NULL)
45         0,                         /*ob_size*/
46         "VideoTexture.FilterGray",   /*tp_name*/
47         sizeof(PyFilter),          /*tp_basicsize*/
48         0,                         /*tp_itemsize*/
49         (destructor)Filter_dealloc,/*tp_dealloc*/
50         0,                         /*tp_print*/
51         0,                         /*tp_getattr*/
52         0,                         /*tp_setattr*/
53         0,                         /*tp_compare*/
54         0,                         /*tp_repr*/
55         0,                         /*tp_as_number*/
56         0,                         /*tp_as_sequence*/
57         0,                         /*tp_as_mapping*/
58         0,                         /*tp_hash */
59         0,                         /*tp_call*/
60         0,                         /*tp_str*/
61         0,                         /*tp_getattro*/
62         0,                         /*tp_setattro*/
63         0,                         /*tp_as_buffer*/
64         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
65         "Filter for gray scale effect",       /* tp_doc */
66         0,                             /* tp_traverse */
67         0,                             /* tp_clear */
68         0,                             /* tp_richcompare */
69         0,                             /* tp_weaklistoffset */
70         0,                             /* tp_iter */
71         0,                             /* tp_iternext */
72         NULL,                /* tp_methods */
73         0,                   /* tp_members */
74         filterGrayGetSets,           /* tp_getset */
75         0,                         /* tp_base */
76         0,                         /* tp_dict */
77         0,                         /* tp_descr_get */
78         0,                         /* tp_descr_set */
79         0,                         /* tp_dictoffset */
80         (initproc)Filter_init<FilterGray>,     /* tp_init */
81         0,                         /* tp_alloc */
82         Filter_allocNew,           /* tp_new */
83 };
84
85
86 // implementation FilterColor
87
88 // constructor
89 FilterColor::FilterColor (void)
90 {
91         // reset color matrix to identity
92         for (int r = 0; r < 4; ++r)
93                 for (int c = 0; c < 5; ++c)
94                         m_matrix[r][c] = (r == c) ? 256 : 0; 
95 }
96
97 // set color matrix
98 void FilterColor::setMatrix (ColorMatrix & mat)
99 {
100         // copy matrix
101         for (int r = 0; r < 4; ++r)
102                 for (int c = 0; c < 5; ++c)
103                         m_matrix[r][c] = mat[r][c]; 
104 }
105
106
107
108 // cast Filter pointer to FilterColor
109 inline FilterColor * getFilterColor (PyFilter * self)
110 { return static_cast<FilterColor*>(self->m_filter); }
111
112
113 // python methods and get/sets
114
115 // get color matrix
116 static PyObject * getMatrix (PyFilter * self, void * closure)
117 {
118         ColorMatrix & mat = getFilterColor(self)->getMatrix();
119         return Py_BuildValue("((hhhhh)(hhhhh)(hhhhh)(hhhhh))",
120                 mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat[0][4],
121                 mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat[1][4],
122                 mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat[2][4],
123                 mat[3][0], mat[3][1], mat[3][2], mat[3][3], mat[3][4]);
124 }
125
126 // set color matrix
127 static int setMatrix (PyFilter * self, PyObject * value, void * closure)
128 {
129         // matrix to store items
130         ColorMatrix mat;
131         // check validity of parameter
132         bool valid = value != NULL && PySequence_Check(value)
133                 && PySequence_Length(value) == 4;
134         // check rows
135         for (int r = 0; valid && r < 4; ++r)
136         {
137                 // get row object
138                 PyObject * row = PySequence_Fast_GET_ITEM(value, r);
139                 // check sequence
140                 valid = PySequence_Check(row) && PySequence_Length(row) == 5;
141                 // check items
142                 for (int c = 0; valid && c < 5; ++c)
143                 {
144                         // item must be int
145                         valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c));
146                         // if it is valid, save it in matrix
147                         if (valid)
148                                 mat[r][c] = short(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c)));
149                 }
150         }
151         // if parameter is not valid, report error
152         if (!valid)
153         {
154                 PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][5] of ints");
155                 return -1;
156         }
157         // set color matrix
158         getFilterColor(self)->setMatrix(mat);
159         // success
160         return 0;
161 }
162
163
164 // attributes structure
165 static PyGetSetDef filterColorGetSets[] =
166
167         {"matrix", (getter)getMatrix, (setter)setMatrix, "matrix [4][5] for color calculation", NULL},
168         // attributes from FilterBase class
169         {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
170         {NULL}
171 };
172
173 // define python type
174 PyTypeObject FilterColorType =
175
176         PyObject_HEAD_INIT(NULL)
177         0,                         /*ob_size*/
178         "VideoTexture.FilterColor",   /*tp_name*/
179         sizeof(PyFilter),          /*tp_basicsize*/
180         0,                         /*tp_itemsize*/
181         (destructor)Filter_dealloc,/*tp_dealloc*/
182         0,                         /*tp_print*/
183         0,                         /*tp_getattr*/
184         0,                         /*tp_setattr*/
185         0,                         /*tp_compare*/
186         0,                         /*tp_repr*/
187         0,                         /*tp_as_number*/
188         0,                         /*tp_as_sequence*/
189         0,                         /*tp_as_mapping*/
190         0,                         /*tp_hash */
191         0,                         /*tp_call*/
192         0,                         /*tp_str*/
193         0,                         /*tp_getattro*/
194         0,                         /*tp_setattro*/
195         0,                         /*tp_as_buffer*/
196         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
197         "Filter for color calculations",       /* tp_doc */
198         0,                             /* tp_traverse */
199         0,                             /* tp_clear */
200         0,                             /* tp_richcompare */
201         0,                             /* tp_weaklistoffset */
202         0,                             /* tp_iter */
203         0,                             /* tp_iternext */
204         NULL,                /* tp_methods */
205         0,                   /* tp_members */
206         filterColorGetSets,           /* tp_getset */
207         0,                         /* tp_base */
208         0,                         /* tp_dict */
209         0,                         /* tp_descr_get */
210         0,                         /* tp_descr_set */
211         0,                         /* tp_dictoffset */
212         (initproc)Filter_init<FilterColor>,     /* tp_init */
213         0,                         /* tp_alloc */
214         Filter_allocNew,           /* tp_new */
215 };
216
217 // implementation FilterLevel
218
219 // constructor
220 FilterLevel::FilterLevel (void)
221 {
222         // reset color levels
223         for (int r = 0; r < 4; ++r)
224         {
225                 levels[r][0] = 0;
226                 levels[r][1] = 0xFF << (r << 3);
227                 levels[r][2] = 0xFF;
228         }
229 }
230
231 // set color levels
232 void FilterLevel::setLevels (ColorLevel & lev)
233 {
234         // copy levels
235         for (int r = 0; r < 4; ++r)
236         {
237                 for (int c = 0; c < 2; ++c)
238                         levels[r][c] = lev[r][c] << (r << 3);
239                 levels[r][2] = lev[r][0] < lev[r][1] ? lev[r][1] - lev[r][0] : 1;
240         }
241 }
242
243
244 // cast Filter pointer to FilterLevel
245 inline FilterLevel * getFilterLevel (PyFilter * self)
246 { return static_cast<FilterLevel*>(self->m_filter); }
247
248
249 // python methods and get/sets
250
251 // get color levels
252 static PyObject * getLevels (PyFilter * self, void * closure)
253 {
254         ColorLevel & lev = getFilterLevel(self)->getLevels();
255         return Py_BuildValue("((kk)(kk)(kk)(kk))",
256                 lev[0][0], lev[0][1], lev[1][0] >> 8, lev[1][1] >> 8,
257                 lev[2][0] >> 16, lev[2][1] >> 16, lev[3][0] >> 24, lev[3][1] >> 24);
258 }
259
260 // set color levels
261 static int setLevels (PyFilter * self, PyObject * value, void * closure)
262 {
263         // matrix to store items
264         ColorLevel lev;
265         // check validity of parameter
266         bool valid = value != NULL && PySequence_Check(value)
267                 && PySequence_Length(value) == 4;
268         // check rows
269         for (int r = 0; valid && r < 4; ++r)
270         {
271                 // get row object
272                 PyObject * row = PySequence_Fast_GET_ITEM(value, r);
273                 // check sequence
274                 valid = PySequence_Check(row) && PySequence_Length(row) == 2;
275                 // check items
276                 for (int c = 0; valid && c < 2; ++c)
277                 {
278                         // item must be int
279                         valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c));
280                         // if it is valid, save it in matrix
281                         if (valid)
282                                 lev[r][c] = (unsigned long)(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c)));
283                 }
284         }
285         // if parameter is not valid, report error
286         if (!valid)
287         {
288                 PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][2] of ints");
289                 return -1;
290         }
291         // set color matrix
292         getFilterLevel(self)->setLevels(lev);
293         // success
294         return 0;
295 }
296
297
298 // attributes structure
299 static PyGetSetDef filterLevelGetSets[] =
300
301         {"levels", (getter)getLevels, (setter)setLevels, "levels matrix [4] (min, max)", NULL},
302         // attributes from FilterBase class
303         {"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, "previous pixel filter", NULL},
304         {NULL}
305 };
306
307 // define python type
308 PyTypeObject FilterLevelType =
309
310         PyObject_HEAD_INIT(NULL)
311         0,                         /*ob_size*/
312         "VideoTexture.FilterLevel",   /*tp_name*/
313         sizeof(PyFilter),          /*tp_basicsize*/
314         0,                         /*tp_itemsize*/
315         (destructor)Filter_dealloc,/*tp_dealloc*/
316         0,                         /*tp_print*/
317         0,                         /*tp_getattr*/
318         0,                         /*tp_setattr*/
319         0,                         /*tp_compare*/
320         0,                         /*tp_repr*/
321         0,                         /*tp_as_number*/
322         0,                         /*tp_as_sequence*/
323         0,                         /*tp_as_mapping*/
324         0,                         /*tp_hash */
325         0,                         /*tp_call*/
326         0,                         /*tp_str*/
327         0,                         /*tp_getattro*/
328         0,                         /*tp_setattro*/
329         0,                         /*tp_as_buffer*/
330         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
331         "Filter for levels calculations",       /* tp_doc */
332         0,                             /* tp_traverse */
333         0,                             /* tp_clear */
334         0,                             /* tp_richcompare */
335         0,                             /* tp_weaklistoffset */
336         0,                             /* tp_iter */
337         0,                             /* tp_iternext */
338         NULL,                /* tp_methods */
339         0,                   /* tp_members */
340         filterLevelGetSets,           /* tp_getset */
341         0,                         /* tp_base */
342         0,                         /* tp_dict */
343         0,                         /* tp_descr_get */
344         0,                         /* tp_descr_set */
345         0,                         /* tp_dictoffset */
346         (initproc)Filter_init<FilterLevel>,     /* tp_init */
347         0,                         /* tp_alloc */
348         Filter_allocNew,           /* tp_new */
349 };
350