memory management and logging fixes
[swftools.git] / lib / python / primitives.c
1 /* primitives.c
2
3    Python wrapper for librfxswf- primitive objects (implementation)
4
5    Part of the swftools package.
6
7    Copyright (c) 2003 Matthias Kramm <kramm@quiss.org>
8  
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
22
23 #include <Python.h>
24 #undef HAVE_STAT
25 #include "../rfxswf.h"
26 #include "../log.h"
27 #include "./pyutils.h"
28 #include "primitives.h"
29
30 //----------------------------------------------------------------------------
31 typedef struct {
32     PyObject_HEAD
33     RGBA rgba;
34 } ColorObject;
35
36 PyObject* f_Color(PyObject* self, PyObject* args, PyObject* kwargs)
37 {
38     static char *kwlist[] = {"r", "g", "b", "a", NULL};
39     ColorObject* color;
40     int r=0,g=0,b=0,a=255;
41     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|i", kwlist, &r,&g,&b,&a))
42         return NULL;
43     color = PyObject_New(ColorObject, &ColorClass);
44     mylog("+%08x(%d) color_new(%d,%d,%d,%d)\n", (int)color, color->ob_refcnt, r,g,b,a);
45     color->rgba.r = r;
46     color->rgba.g = g;
47     color->rgba.b = b;
48     color->rgba.a = a;
49     return (PyObject*)color;
50 }
51 static PyObject* color_getattr(PyObject * self, char* a)
52 {
53     ColorObject*color = (ColorObject*)self;
54     if(!strcmp(a, "r")) {
55         return Py_BuildValue("r", color->rgba.r);
56     } else if(!strcmp(a, "g")) {
57         return Py_BuildValue("g", color->rgba.g);
58     } else if(!strcmp(a, "b")) {
59         return Py_BuildValue("b", color->rgba.b);
60     } else if(!strcmp(a, "a")) {
61         return Py_BuildValue("a", color->rgba.a);
62     }
63     return NULL;
64 }
65 static int color_setattr(PyObject * self, char* attr, PyObject* o)
66 {
67     ColorObject*color = (ColorObject*)self;
68     if(!strcmp(attr, "r")) {
69         if (!PyArg_Parse(o, "d", &color->rgba.r)) goto err;
70         return 0;
71     } else if(!strcmp(attr, "g")) {
72         if (!PyArg_Parse(o, "d", &color->rgba.g)) goto err;
73         return 0;
74     } else if(!strcmp(attr, "b")) {
75         if (!PyArg_Parse(o, "d", &color->rgba.b)) goto err;
76         return 0;
77     } else if(!strcmp(attr, "a")) {
78         if (!PyArg_Parse(o, "d", &color->rgba.a)) goto err;
79         return 0;
80     } 
81 err:
82     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, attr, o);
83     return 1;
84 }
85 RGBA color_getRGBA(PyObject*self)
86 {
87     ColorObject*color = 0;
88     if (!PyArg_Parse(self, "O!", &ColorClass, &color)) {
89         RGBA dummy;
90         memset(&dummy, 0, sizeof(dummy));
91         mylog("Error: wrong type for function color_getRGBA");
92         return dummy;
93     }
94     return color->rgba;
95 }
96 void color_dealloc(PyObject* self)
97 {
98     mylog("-%08x(%d) color_dealloc\n", (int)self, self->ob_refcnt);
99     PyObject_Del(self);
100 }
101 PyTypeObject ColorClass = 
102 {
103     PyObject_HEAD_INIT(NULL)
104     0,
105     tp_name: "Color",
106     tp_basicsize: sizeof(ColorObject),
107     tp_itemsize: 0,
108     tp_dealloc: color_dealloc,
109     tp_print: 0,
110     tp_getattr: color_getattr,
111     tp_setattr: color_setattr,
112 };
113 //----------------------------------------------------------------------------
114 typedef struct {
115     PyObject_HEAD
116     SRECT bbox;
117 } BBoxObject;
118
119 PyObject* f_BBox(PyObject* self, PyObject* args, PyObject* kwargs)
120 {
121     static char *kwlist[] = {"xmin", "ymin", "xmax", "ymax", NULL};
122     BBoxObject* bbox;
123     SRECT box;
124     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii", kwlist, 
125                 &box.xmin,
126                 &box.ymin,
127                 &box.xmax,
128                 &box.ymax));
129         return NULL;
130     mylog("+%08x(%d) bbox_new(%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, box.xmin, box.ymin, box.xmax,box.ymax);
131     bbox = PyObject_New(BBoxObject, &BBoxClass);
132     bbox->bbox = box;
133     return (PyObject*)bbox;
134 }
135 static PyObject* bbox_getattr(PyObject * self, char* a)
136 {
137     BBoxObject*bbox = (BBoxObject*)self;
138     if(!strcmp(a, "xmin")) {
139         return Py_BuildValue("i", bbox->bbox.xmin);
140     } else if(!strcmp(a, "ymin")) {
141         return Py_BuildValue("i", bbox->bbox.ymin);
142     } else if(!strcmp(a, "xmax")) {
143         return Py_BuildValue("i", bbox->bbox.xmax);
144     } else if(!strcmp(a, "ymax")) {
145         return Py_BuildValue("i", bbox->bbox.ymax);
146     }
147     return NULL;
148 }
149 static int bbox_setattr(PyObject * self, char* a, PyObject* o)
150 {
151     BBoxObject*bbox= (BBoxObject*)self;
152     if(!strcmp(a, "xmin")) {
153         if (!PyArg_Parse(o, "i", &bbox->bbox.xmin)) goto err;
154         return 0;
155     } else if(!strcmp(a, "ymin")) {
156         if (!PyArg_Parse(o, "i", &bbox->bbox.ymin)) goto err;
157         return 0;
158     } else if(!strcmp(a, "xmax")) {
159         if (!PyArg_Parse(o, "i", &bbox->bbox.xmax)) goto err;
160         return 0;
161     } else if(!strcmp(a, "ymax")) {
162         if (!PyArg_Parse(o, "i", &bbox->bbox.ymax)) goto err;
163         return 0;
164     } 
165 err:
166     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
167     return 1;
168 }
169 void bbox_dealloc(PyObject* self)
170 {
171     mylog("-%08x(%d) bbox_dealloc\n", (int)self, self->ob_refcnt);
172     PyObject_Del(self);
173 }
174 SRECT bbox_getBBox(PyObject*self)
175 {
176     BBoxObject*bbox= 0;
177     if (!PyArg_Parse(self, "O!", &BBoxClass, &bbox)) {
178         SRECT dummy;
179         memset(&dummy, 0, sizeof(dummy));
180         mylog("Error: wrong type for function color_getRGBA");
181         return dummy;
182     }
183     return bbox->bbox;
184 }
185 PyTypeObject BBoxClass = 
186 {
187     PyObject_HEAD_INIT(NULL)
188     0,
189     tp_name: "BBox",
190     tp_basicsize: sizeof(BBoxObject),
191     tp_itemsize: 0,
192     tp_dealloc: bbox_dealloc,
193     tp_print: 0,
194     tp_getattr: bbox_getattr,
195     tp_setattr: bbox_setattr,
196 };
197 SRECT bbox_getBBox(PyObject*self);
198 //----------------------------------------------------------------------------
199 typedef struct {
200     PyObject_HEAD
201     MATRIX matrix;
202 } MatrixObject;
203
204 PyObject* f_Matrix(PyObject* _self, PyObject* args, PyObject* kwargs)
205 {
206     PyObject*self = (PyObject*)PyObject_New(MatrixObject, &MatrixClass);
207     MatrixObject*matrix = (MatrixObject*)self;
208     mylog("+%08x(%d) f_Matrix", self, self->ob_refcnt);
209     static char *kwlist[] = {"x", "y", "scale", "rotate", NULL};
210     float x=0,y=0,scale=1.0,rotate=0;
211     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ffff", kwlist, &x,&y,&scale,&rotate))
212         return NULL;
213     mylog(" %08x(%d) f_Matrix: x=%f y=%f scale=%f rotate=%f", self, self->ob_refcnt, x,y,scale,rotate);
214     swf_GetMatrix(0, &matrix->matrix);
215     matrix->matrix.tx = (int)(x*20);
216     matrix->matrix.ty = (int)(y*20);
217     matrix->matrix.sx = (int)(scale*65536);
218     matrix->matrix.sy = (int)(scale*65536);
219     /* TODO: rotate */
220     return self;
221 }
222 static PyObject* matrix_getattr(PyObject * self, char* a)
223 {
224     PY_ASSERT_TYPE(self,&MatrixClass);
225     return NULL;
226 }
227 static int matrix_setattr(PyObject * self, char* a, PyObject* o)
228 {
229     PY_ASSERT_TYPE(self,&MatrixClass);
230     return 0;
231 }
232 MATRIX matrix_getMatrix(PyObject*self)
233 {
234     mylog(" %08x(%d) matrix_getMatrix", self, self->ob_refcnt);
235     PY_ASSERT_TYPE(self,&MatrixClass);
236     MatrixObject*matrix = (MatrixObject*)self;
237     return matrix->matrix;
238 }
239 void matrix_dealloc(PyObject* self)
240 {
241     mylog("-%08x(%d) matrix_dealloc", self, self->ob_refcnt);
242     PyObject_Del(self);
243 }
244 PyTypeObject MatrixClass = 
245 {
246     PyObject_HEAD_INIT(NULL)
247     0,
248     tp_name: "Matrix",
249     tp_basicsize: sizeof(MatrixObject),
250     tp_itemsize: 0,
251     tp_dealloc: matrix_dealloc,
252     tp_print: 0,
253     tp_getattr: matrix_getattr,
254     tp_setattr: matrix_setattr,
255     tp_compare: 0,
256     tp_repr: 0,
257     tp_as_number: 0,
258     tp_as_sequence: 0,
259     tp_as_mapping: 0,
260     tp_hash: 0,     // dict(x)
261     tp_call: 0,     // x()
262     tp_str: 0       // str(x)
263 };
264 //----------------------------------------------------------------------------
265 typedef struct {
266     PyObject_HEAD
267     CXFORM cxform;
268 } CXFormObject;
269
270 PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs)
271 {
272     return NULL;
273 }
274 static PyObject* colortransform_getattr(PyObject * self, char* a)
275 {
276     return NULL;
277 }
278 static int colortransform_setattr(PyObject * self, char* a, PyObject* o)
279 {
280     return 0;
281 }
282 CXFORM colortransform_getCXForm(PyObject*self)
283 {
284     CXFormObject*cxform= 0;
285     if (!PyArg_Parse(self, "O!", &CXFormClass, &cxform)) {
286         CXFORM dummy;
287         memset(&dummy, 0, sizeof(dummy));
288         mylog("Error: wrong type for function color_getRGBA");
289         return dummy;
290     }
291     return cxform->cxform;
292 }
293 void colortransform_dealloc(PyObject* self)
294 {
295     mylog("-%08x(%d) colortransform_dealloc", self, self->ob_refcnt);
296     PyObject_Del(self);
297 }
298 PyTypeObject CXFormClass = 
299 {
300     PyObject_HEAD_INIT(NULL)
301     0,
302     tp_name: "ColorTransform",
303     tp_basicsize: sizeof(CXFormObject),
304     tp_itemsize: 0,
305     tp_dealloc: colortransform_dealloc,
306     tp_print: 0,
307     tp_getattr: colortransform_getattr,
308     tp_setattr: colortransform_setattr,
309 };
310 //----------------------------------------------------------------------------
311 typedef struct {
312     PyObject_HEAD
313     GRADIENT gradient;
314 } GradientObject;
315
316 PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs)
317 {
318     return NULL;
319 }
320 static PyObject* gradient_getattr(PyObject * self, char* a)
321 {
322     return NULL;
323 }
324 static int gradient_setattr(PyObject * self, char* a, PyObject* o)
325 {
326     return 0;
327 }
328 GRADIENT gradient_getGradient(PyObject*self)
329 {
330     GradientObject*gradient = 0;
331     if (!PyArg_Parse(self, "O!", &gradient, &gradient)) {
332         GRADIENT dummy;
333         memset(&dummy, 0, sizeof(dummy));
334         mylog("Error: wrong type for function color_getRGBA");
335         return dummy;
336     }
337     return gradient->gradient;
338 }
339 void gradient_dealloc(PyObject* self)
340 {
341     mylog("-%08x(%d) gradient_dealloc", self, self->ob_refcnt);
342     PyObject_Del(self);
343 }
344 PyTypeObject GradientClass = 
345 {
346     PyObject_HEAD_INIT(NULL)
347     0,
348     tp_name: "Gradient",
349     tp_basicsize: sizeof(GradientObject),
350     tp_itemsize: 0,
351     tp_dealloc: gradient_dealloc,
352     tp_print: 0,
353     tp_getattr: gradient_getattr,
354     tp_setattr: gradient_setattr,
355 };
356 //----------------------------------------------------------------------------
357
358 static PyMethodDef primitive_methods[] = 
359 {
360     {"Color", (PyCFunction)f_Color, METH_KEYWORDS, "Create a new color object."},
361     {"Gradient", (PyCFunction)f_Gradient, METH_KEYWORDS, "Create a new gradient object."},
362     {"ColorTransform", (PyCFunction)f_ColorTransform, METH_KEYWORDS, "Create a new colortransform object."},
363     {"Matrix", (PyCFunction)f_Matrix, METH_KEYWORDS, "Create a new matrix object."},
364     {"BBox", (PyCFunction)f_BBox, METH_KEYWORDS, "Create a new bounding box object."},
365     {NULL, NULL, 0, NULL}
366 };
367
368 PyMethodDef* primitive_getMethods()
369 {
370     GradientClass.ob_type = &PyType_Type;
371     CXFormClass.ob_type = &PyType_Type;
372     BBoxClass.ob_type = &PyType_Type;
373     MatrixClass.ob_type = &PyType_Type;
374     return primitive_methods;
375 }
376
377