NLA SoC: Merge from 2.5
[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         {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
38         {NULL}
39 };
40
41 // define python type
42 PyTypeObject FilterGrayType =
43
44 #if (PY_VERSION_HEX >= 0x02060000)
45         PyVarObject_HEAD_INIT(NULL, 0)
46 #else
47         /* python 2.5 and below */
48         PyObject_HEAD_INIT( NULL )  /* required py macro */
49         0,                         /*ob_size*/
50 #endif
51         "VideoTexture.FilterGray",   /*tp_name*/
52         sizeof(PyFilter),          /*tp_basicsize*/
53         0,                         /*tp_itemsize*/
54         (destructor)Filter_dealloc,/*tp_dealloc*/
55         0,                         /*tp_print*/
56         0,                         /*tp_getattr*/
57         0,                         /*tp_setattr*/
58         0,                         /*tp_compare*/
59         0,                         /*tp_repr*/
60         0,                         /*tp_as_number*/
61         0,                         /*tp_as_sequence*/
62         0,                         /*tp_as_mapping*/
63         0,                         /*tp_hash */
64         0,                         /*tp_call*/
65         0,                         /*tp_str*/
66         0,                         /*tp_getattro*/
67         0,                         /*tp_setattro*/
68         0,                         /*tp_as_buffer*/
69         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
70         "Filter for gray scale effect",       /* tp_doc */
71         0,                             /* tp_traverse */
72         0,                             /* tp_clear */
73         0,                             /* tp_richcompare */
74         0,                             /* tp_weaklistoffset */
75         0,                             /* tp_iter */
76         0,                             /* tp_iternext */
77         NULL,                /* tp_methods */
78         0,                   /* tp_members */
79         filterGrayGetSets,           /* tp_getset */
80         0,                         /* tp_base */
81         0,                         /* tp_dict */
82         0,                         /* tp_descr_get */
83         0,                         /* tp_descr_set */
84         0,                         /* tp_dictoffset */
85         (initproc)Filter_init<FilterGray>,     /* tp_init */
86         0,                         /* tp_alloc */
87         Filter_allocNew,           /* tp_new */
88 };
89
90
91 // implementation FilterColor
92
93 // constructor
94 FilterColor::FilterColor (void)
95 {
96         // reset color matrix to identity
97         for (int r = 0; r < 4; ++r)
98                 for (int c = 0; c < 5; ++c)
99                         m_matrix[r][c] = (r == c) ? 256 : 0; 
100 }
101
102 // set color matrix
103 void FilterColor::setMatrix (ColorMatrix & mat)
104 {
105         // copy matrix
106         for (int r = 0; r < 4; ++r)
107                 for (int c = 0; c < 5; ++c)
108                         m_matrix[r][c] = mat[r][c]; 
109 }
110
111
112
113 // cast Filter pointer to FilterColor
114 inline FilterColor * getFilterColor (PyFilter * self)
115 { return static_cast<FilterColor*>(self->m_filter); }
116
117
118 // python methods and get/sets
119
120 // get color matrix
121 static PyObject * getMatrix (PyFilter * self, void * closure)
122 {
123         ColorMatrix & mat = getFilterColor(self)->getMatrix();
124         return Py_BuildValue("((hhhhh)(hhhhh)(hhhhh)(hhhhh))",
125                 mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat[0][4],
126                 mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat[1][4],
127                 mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat[2][4],
128                 mat[3][0], mat[3][1], mat[3][2], mat[3][3], mat[3][4]);
129 }
130
131 // set color matrix
132 static int setMatrix (PyFilter * self, PyObject * value, void * closure)
133 {
134         // matrix to store items
135         ColorMatrix mat;
136         // check validity of parameter
137         bool valid = value != NULL && PySequence_Check(value)
138                 && PySequence_Length(value) == 4;
139         // check rows
140         for (int r = 0; valid && r < 4; ++r)
141         {
142                 // get row object
143                 PyObject * row = PySequence_Fast_GET_ITEM(value, r);
144                 // check sequence
145                 valid = PySequence_Check(row) && PySequence_Length(row) == 5;
146                 // check items
147                 for (int c = 0; valid && c < 5; ++c)
148                 {
149                         // item must be int
150                         valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c));
151                         // if it is valid, save it in matrix
152                         if (valid)
153                                 mat[r][c] = short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c)));
154                 }
155         }
156         // if parameter is not valid, report error
157         if (!valid)
158         {
159                 PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][5] of ints");
160                 return -1;
161         }
162         // set color matrix
163         getFilterColor(self)->setMatrix(mat);
164         // success
165         return 0;
166 }
167
168
169 // attributes structure
170 static PyGetSetDef filterColorGetSets[] =
171
172         {(char*)"matrix", (getter)getMatrix, (setter)setMatrix, (char*)"matrix [4][5] for color calculation", NULL},
173         // attributes from FilterBase class
174         {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
175         {NULL}
176 };
177
178 // define python type
179 PyTypeObject FilterColorType =
180
181 #if (PY_VERSION_HEX >= 0x02060000)
182         PyVarObject_HEAD_INIT(NULL, 0)
183 #else
184         /* python 2.5 and below */
185         PyObject_HEAD_INIT( NULL )  /* required py macro */
186         0,                         /*ob_size*/
187 #endif
188         "VideoTexture.FilterColor",   /*tp_name*/
189         sizeof(PyFilter),          /*tp_basicsize*/
190         0,                         /*tp_itemsize*/
191         (destructor)Filter_dealloc,/*tp_dealloc*/
192         0,                         /*tp_print*/
193         0,                         /*tp_getattr*/
194         0,                         /*tp_setattr*/
195         0,                         /*tp_compare*/
196         0,                         /*tp_repr*/
197         0,                         /*tp_as_number*/
198         0,                         /*tp_as_sequence*/
199         0,                         /*tp_as_mapping*/
200         0,                         /*tp_hash */
201         0,                         /*tp_call*/
202         0,                         /*tp_str*/
203         0,                         /*tp_getattro*/
204         0,                         /*tp_setattro*/
205         0,                         /*tp_as_buffer*/
206         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
207         "Filter for color calculations",       /* tp_doc */
208         0,                             /* tp_traverse */
209         0,                             /* tp_clear */
210         0,                             /* tp_richcompare */
211         0,                             /* tp_weaklistoffset */
212         0,                             /* tp_iter */
213         0,                             /* tp_iternext */
214         NULL,                /* tp_methods */
215         0,                   /* tp_members */
216         filterColorGetSets,           /* tp_getset */
217         0,                         /* tp_base */
218         0,                         /* tp_dict */
219         0,                         /* tp_descr_get */
220         0,                         /* tp_descr_set */
221         0,                         /* tp_dictoffset */
222         (initproc)Filter_init<FilterColor>,     /* tp_init */
223         0,                         /* tp_alloc */
224         Filter_allocNew,           /* tp_new */
225 };
226
227 // implementation FilterLevel
228
229 // constructor
230 FilterLevel::FilterLevel (void)
231 {
232         // reset color levels
233         for (int r = 0; r < 4; ++r)
234         {
235                 levels[r][0] = 0;
236                 levels[r][1] = 0xFF;
237                 levels[r][2] = 0xFF;
238         }
239 }
240
241 // set color levels
242 void FilterLevel::setLevels (ColorLevel & lev)
243 {
244         // copy levels
245         for (int r = 0; r < 4; ++r)
246         {
247                 for (int c = 0; c < 2; ++c)
248                         levels[r][c] = lev[r][c];
249                 levels[r][2] = lev[r][0] < lev[r][1] ? lev[r][1] - lev[r][0] : 1;
250         }
251 }
252
253
254 // cast Filter pointer to FilterLevel
255 inline FilterLevel * getFilterLevel (PyFilter * self)
256 { return static_cast<FilterLevel*>(self->m_filter); }
257
258
259 // python methods and get/sets
260
261 // get color levels
262 static PyObject * getLevels (PyFilter * self, void * closure)
263 {
264         ColorLevel & lev = getFilterLevel(self)->getLevels();
265         return Py_BuildValue("((HH)(HH)(HH)(HH))",
266                 lev[0][0], lev[0][1], lev[1][0], lev[1][1],
267                 lev[2][0], lev[2][1], lev[3][0], lev[3][1]);
268 }
269
270 // set color levels
271 static int setLevels (PyFilter * self, PyObject * value, void * closure)
272 {
273         // matrix to store items
274         ColorLevel lev;
275         // check validity of parameter
276         bool valid = value != NULL && PySequence_Check(value)
277                 && PySequence_Length(value) == 4;
278         // check rows
279         for (int r = 0; valid && r < 4; ++r)
280         {
281                 // get row object
282                 PyObject * row = PySequence_Fast_GET_ITEM(value, r);
283                 // check sequence
284                 valid = PySequence_Check(row) && PySequence_Length(row) == 2;
285                 // check items
286                 for (int c = 0; valid && c < 2; ++c)
287                 {
288                         // item must be int
289                         valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c));
290                         // if it is valid, save it in matrix
291                         if (valid)
292                                 lev[r][c] = (unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c)));
293                 }
294         }
295         // if parameter is not valid, report error
296         if (!valid)
297         {
298                 PyErr_SetString(PyExc_TypeError, "The value must be a matrix [4][2] of ints");
299                 return -1;
300         }
301         // set color matrix
302         getFilterLevel(self)->setLevels(lev);
303         // success
304         return 0;
305 }
306
307
308 // attributes structure
309 static PyGetSetDef filterLevelGetSets[] =
310
311         {(char*)"levels", (getter)getLevels, (setter)setLevels, (char*)"levels matrix [4] (min, max)", NULL},
312         // attributes from FilterBase class
313         {(char*)"previous", (getter)Filter_getPrevious, (setter)Filter_setPrevious, (char*)"previous pixel filter", NULL},
314         {NULL}
315 };
316
317 // define python type
318 PyTypeObject FilterLevelType =
319
320 #if (PY_VERSION_HEX >= 0x02060000)
321         PyVarObject_HEAD_INIT(NULL, 0)
322 #else
323         /* python 2.5 and below */
324         PyObject_HEAD_INIT( NULL )  /* required py macro */
325         0,                         /*ob_size*/
326 #endif
327         "VideoTexture.FilterLevel",   /*tp_name*/
328         sizeof(PyFilter),          /*tp_basicsize*/
329         0,                         /*tp_itemsize*/
330         (destructor)Filter_dealloc,/*tp_dealloc*/
331         0,                         /*tp_print*/
332         0,                         /*tp_getattr*/
333         0,                         /*tp_setattr*/
334         0,                         /*tp_compare*/
335         0,                         /*tp_repr*/
336         0,                         /*tp_as_number*/
337         0,                         /*tp_as_sequence*/
338         0,                         /*tp_as_mapping*/
339         0,                         /*tp_hash */
340         0,                         /*tp_call*/
341         0,                         /*tp_str*/
342         0,                         /*tp_getattro*/
343         0,                         /*tp_setattro*/
344         0,                         /*tp_as_buffer*/
345         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
346         "Filter for levels calculations",       /* tp_doc */
347         0,                             /* tp_traverse */
348         0,                             /* tp_clear */
349         0,                             /* tp_richcompare */
350         0,                             /* tp_weaklistoffset */
351         0,                             /* tp_iter */
352         0,                             /* tp_iternext */
353         NULL,                /* tp_methods */
354         0,                   /* tp_members */
355         filterLevelGetSets,           /* tp_getset */
356         0,                         /* tp_base */
357         0,                         /* tp_dict */
358         0,                         /* tp_descr_get */
359         0,                         /* tp_descr_set */
360         0,                         /* tp_dictoffset */
361         (initproc)Filter_init<FilterLevel>,     /* tp_init */
362         0,                         /* tp_alloc */
363         Filter_allocNew,           /* tp_new */
364 };
365