3 Python wrapper for librfxswf- module core.
5 Part of the swftools package.
7 Copyright (c) 2003 Matthias Kramm <kramm@quiss.org>
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.
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.
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 */
25 #include "../rfxswf.h"
27 #include "./pyutils.h"
29 #include "./taglist.h"
33 1) taglist is rfxswflib's linked list. It should maybe implemented as Python
34 list, which would, however, mean that we would have to convert the list
35 back and forth for the following functions:
36 load, save, writeCGI, unfoldAll, foldAll, optimizeOrder
37 2) taglist should have an ID handler. Every time a tag is inserted, it's ID
38 is stored in a lookup list.
42 //-------------------------- Types -------------------------------------------
44 staticforward PyTypeObject SWFClass;
50 SWF swf; //swf.firstTag ist not used
56 //----------------------------------------------------------------------------
57 static PyObject* f_create(PyObject* self, PyObject* args, PyObject* kwargs)
59 static char *kwlist[] = {"version", "fps", "bbox", "name", NULL};
62 double framerate = 25;
64 SRECT bbox = {0,0,0,0};
67 swf = PyObject_New(SWFObject, &SWFClass);
68 mylog("+%08x(%d) create\n", (int)swf, swf->ob_refcnt);
70 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|idOs",
71 kwlist, &version, &framerate,
75 if (!PyArg_Parse(obbox, "(iiii)", &bbox.xmin, &bbox.ymin, &bbox.xmax, &bbox.ymax))
78 memset(&swf->swf, 0, sizeof(SWF));
80 swf->filename = strdup(filename);
84 swf->swf.fileVersion = version;
85 swf->swf.frameRate = (int)(framerate*0x100);
86 swf->swf.movieSize = bbox;
87 swf->taglist = taglist_new();
89 if(swf->swf.fileVersion>=6)
90 swf->swf.compressed = 1;
92 mylog(" %08x(%d) create: done\n", (int)swf, swf->ob_refcnt);
93 return (PyObject*)swf;
95 //----------------------------------------------------------------------------
96 static PyObject* f_load(PyObject* self, PyObject* args)
102 if (!PyArg_ParseTuple(args,"s:load", &filename))
105 swf = PyObject_New(SWFObject, &SWFClass);
106 mylog("+%08x(%d) f_load\n", (int)swf, swf->ob_refcnt);
108 memset(&swf->swf, 0, sizeof(SWF));
111 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
114 swf->filename = strdup(filename);
115 fi = open(filename,O_RDONLY|O_BINARY);
117 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
120 if(swf_ReadSWF(fi,&swf->swf)<0) {
122 PyErr_SetString(PyExc_Exception, setError("%s is not a valid SWF file or contains errors",filename));
126 swf_FoldAll(&swf->swf);
128 swf->taglist = taglist_new2(swf->swf.firstTag);
129 if(swf->taglist == NULL) {
133 swf_FreeTags(&swf->swf);
134 swf->swf.firstTag = 0;
136 return (PyObject*)swf;
138 //----------------------------------------------------------------------------
139 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
141 static char *kwlist[] = {"name", "compress", NULL};
151 swfo = (SWFObject*)self;
154 filename = swfo->filename;
156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
159 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
161 // keyword arg compress (=1) forces compression
165 swf->firstTag = taglist_getTAGs(swfo->taglist);
169 // fix the file, in case it is empty or not terminated properly
171 TAG*tag = swf->firstTag;
173 tag = swf->firstTag = swf_InsertTag(0,ST_END);
174 while(tag && tag->next) {
177 if(tag->id != ST_END) {
178 tag = swf_InsertTag(tag,ST_END);
182 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
184 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
187 if(swf->compressed) {
188 if(swf_WriteSWC(fi, swf)<0) {
190 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
194 if(swf_WriteSWF(fi, swf)<0) {
196 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
203 /*{ TAG * t = swf->firstTag;
206 mylog("tag: %08x\n",t);
207 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
208 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
209 mylog(" next: %08x\n", t->next);
210 TAG * tnew = t->next;
211 mylog("->free data\n");
212 if (t->data) free(t->data);
213 mylog("->free tag\n");
222 //----------------------------------------------------------------------------
223 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
225 SWFObject*swf = (SWFObject*)self;
226 if(!self || !PyArg_ParseTuple(args,""))
228 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
229 if(!swf->swf.firstTag)
231 swf_WriteCGI(&swf->swf);
232 swf_FreeTags(&swf->swf);
233 swf->swf.firstTag = 0;
236 //----------------------------------------------------------------------------
238 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
240 static PyMethodDef swf_functions[] =
241 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
242 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
243 {NULL, NULL, 0, NULL}
246 //----------------------------------------------------------------------------
247 static void swf_dealloc(PyObject* self)
249 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
252 swfo = (SWFObject*)self;
255 free(swfo->filename);
258 Py_DECREF(swfo->taglist);
262 //----------------------------------------------------------------------------
263 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
265 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
266 SWFObject*swf = (SWFObject*)self;
267 swf_DumpHeader(fi, &swf->swf);
268 //void swf_DumpSWF(FILE * f,SWF*swf);
271 //----------------------------------------------------------------------------
272 static PyObject* swf_getattr(PyObject * self, char* a)
274 SWFObject*swf = (SWFObject*)self;
277 if(!strcmp(a, "fps")) {
278 double fps = swf->swf.frameRate/256.0;
279 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
280 return Py_BuildValue("d", fps);
281 } else if(!strcmp(a, "version")) {
282 int version = swf->swf.fileVersion;;
283 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
284 return Py_BuildValue("i", version);
285 } else if(!strcmp(a, "name")) {
286 char*filename = swf->filename;
287 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
288 return Py_BuildValue("s", filename);
289 } else if(!strcmp(a, "bbox")) {
290 int xmin,ymin,xmax,ymax;
291 xmin = swf->swf.movieSize.xmin;
292 ymin = swf->swf.movieSize.ymin;
293 xmax = swf->swf.movieSize.xmax;
294 ymax = swf->swf.movieSize.ymax;
295 mylog(" %08x(%d) swf_getattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
296 return Py_BuildValue("(iiii)", xmin, ymin, xmax, ymax);
297 } else if(!strcmp(a, "tags")) {
298 PyObject*ret = (PyObject*)(swf->taglist);
300 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
304 ret = Py_FindMethod(swf_functions, self, a);
305 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
308 //----------------------------------------------------------------------------
309 static int swf_setattr(PyObject * self, char* a, PyObject * o)
311 SWFObject*swf = (SWFObject*)self;
312 if(!strcmp(a, "fps")) {
314 if (!PyArg_Parse(o, "d", &fps))
316 swf->swf.frameRate = (int)(fps*0x100);
317 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
319 } else if(!strcmp(a, "version")) {
321 if (!PyArg_Parse(o, "i", &version))
323 swf->swf.fileVersion = version;
324 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
326 } else if(!strcmp(a, "name")) {
328 if (!PyArg_Parse(o, "s", &filename))
331 free(swf->filename);swf->filename=0;
333 swf->filename = strdup(filename);
334 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
336 } else if(!strcmp(a, "bbox")) {
337 int xmin=0,ymin=0,xmax=0,ymax=0;
338 if (!PyArg_Parse(o, "(iiii)", &xmin, &ymin, &xmax, &ymax))
341 swf->swf.movieSize.xmin = xmin;
342 swf->swf.movieSize.ymin = ymin;
343 swf->swf.movieSize.xmax = xmax;
344 swf->swf.movieSize.ymax = ymax;
345 mylog(" %08x(%d) swf_setattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
347 } else if(!strcmp(a, "tags")) {
350 PY_ASSERT_TYPE(taglist,&TagListClass);
351 Py_DECREF(swf->taglist);
352 swf->taglist = taglist;
353 Py_INCREF(swf->taglist);
354 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
358 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
362 //----------------------------------------------------------------------------
363 static PyTypeObject SWFClass =
365 PyObject_HEAD_INIT(NULL)
368 tp_basicsize: sizeof(SWFObject),
370 tp_dealloc: swf_dealloc,
372 tp_getattr: swf_getattr,
373 tp_setattr: swf_setattr,
375 //----------------------------------------------------------------------------
377 static PyMethodDef SWFMethods[] =
380 {"load", f_load, METH_VARARGS, "Load a SWF from disc."},
381 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
383 // save is a member function
385 PyMethodDef* swf_getMethods()
387 SWFClass.ob_type = &PyType_Type;
391 // =============================================================================
393 #include "primitives.h"
398 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
401 static char *kwlist[] = {"verbosity", NULL};
402 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &verbose))
404 setVerbosity(_verbose);
406 return Py_BuildValue("s", 0);
409 static PyMethodDef LoggingMethods[] =
411 /* Module functions */
412 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
419 PyMethodDef* primitive_methods = primitive_getMethods();
420 PyMethodDef* tag_methods = tags_getMethods();
421 PyMethodDef* action_methods = action_getMethods();
422 PyMethodDef* swf_methods = swf_getMethods();
424 PyMethodDef* all_methods = 0;
425 all_methods = addMethods(all_methods, primitive_methods);
426 all_methods = addMethods(all_methods, tag_methods);
427 all_methods = addMethods(all_methods, action_methods);
428 all_methods = addMethods(all_methods, swf_methods);
430 all_methods = addMethods(all_methods, LoggingMethods);
432 module = Py_InitModule("SWF", all_methods);
434 /* Python doesn't copy the PyMethodDef struct, so we need