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