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));
127 swf->taglist = taglist_new2(swf->swf.firstTag);
128 if(swf->taglist == NULL) {
132 swf_FreeTags(&swf->swf);
133 swf->swf.firstTag = 0;
135 return (PyObject*)swf;
137 //----------------------------------------------------------------------------
138 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
140 static char *kwlist[] = {"name", "compress", NULL};
150 swfo = (SWFObject*)self;
153 filename = swfo->filename;
155 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
158 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
160 // keyword arg compress (=1) forces compression
164 swf->firstTag = taglist_getTAGs(swfo->taglist);
168 // fix the file, in case it is empty or not terminated properly
170 TAG*tag = swf->firstTag;
172 tag = swf->firstTag = swf_InsertTag(0,ST_END);
173 while(tag && tag->next) {
176 if(tag->id != ST_END) {
177 tag = swf_InsertTag(tag,ST_END);
181 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
183 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
186 if(swf->compressed) {
187 if(swf_WriteSWC(fi, swf)<0) {
189 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
193 if(swf_WriteSWF(fi, swf)<0) {
195 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
202 /*{ TAG * t = swf->firstTag;
205 mylog("tag: %08x\n",t);
206 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
207 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
208 mylog(" next: %08x\n", t->next);
209 TAG * tnew = t->next;
210 mylog("->free data\n");
211 if (t->data) free(t->data);
212 mylog("->free tag\n");
221 //----------------------------------------------------------------------------
222 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
224 SWFObject*swf = (SWFObject*)self;
225 if(!self || !PyArg_ParseTuple(args,""))
227 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
228 if(!swf->swf.firstTag)
230 swf_WriteCGI(&swf->swf);
231 swf_FreeTags(&swf->swf);
232 swf->swf.firstTag = 0;
235 //----------------------------------------------------------------------------
237 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
239 static PyMethodDef swf_functions[] =
240 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
241 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
242 {NULL, NULL, 0, NULL}
245 //----------------------------------------------------------------------------
246 static void swf_dealloc(PyObject* self)
248 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
251 swfo = (SWFObject*)self;
254 free(swfo->filename);
257 Py_DECREF(swfo->taglist);
261 //----------------------------------------------------------------------------
262 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
264 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
265 SWFObject*swf = (SWFObject*)self;
266 swf_DumpHeader(fi, &swf->swf);
267 //void swf_DumpSWF(FILE * f,SWF*swf);
270 //----------------------------------------------------------------------------
271 static PyObject* swf_getattr(PyObject * self, char* a)
273 SWFObject*swf = (SWFObject*)self;
276 if(!strcmp(a, "fps")) {
277 double fps = swf->swf.frameRate/256.0;
278 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
279 return Py_BuildValue("d", fps);
280 } else if(!strcmp(a, "version")) {
281 int version = swf->swf.fileVersion;;
282 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
283 return Py_BuildValue("i", version);
284 } else if(!strcmp(a, "name")) {
285 char*filename = swf->filename;
286 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
287 return Py_BuildValue("s", filename);
288 } else if(!strcmp(a, "bbox")) {
289 int xmin,ymin,xmax,ymax;
290 xmin = swf->swf.movieSize.xmin;
291 ymin = swf->swf.movieSize.ymin;
292 xmax = swf->swf.movieSize.xmax;
293 ymax = swf->swf.movieSize.ymax;
294 mylog(" %08x(%d) swf_getattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
295 return Py_BuildValue("(iiii)", xmin, ymin, xmax, ymax);
296 } else if(!strcmp(a, "tags")) {
297 PyObject*ret = (PyObject*)(swf->taglist);
299 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
303 ret = Py_FindMethod(swf_functions, self, a);
304 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
307 //----------------------------------------------------------------------------
308 static int swf_setattr(PyObject * self, char* a, PyObject * o)
310 SWFObject*swf = (SWFObject*)self;
311 if(!strcmp(a, "fps")) {
313 if (!PyArg_Parse(o, "d", &fps))
315 swf->swf.frameRate = (int)(fps*0x100);
316 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
318 } else if(!strcmp(a, "version")) {
320 if (!PyArg_Parse(o, "i", &version))
322 swf->swf.fileVersion = version;
323 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
325 } else if(!strcmp(a, "name")) {
327 if (!PyArg_Parse(o, "s", &filename))
330 free(swf->filename);swf->filename=0;
332 swf->filename = strdup(filename);
333 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
335 } else if(!strcmp(a, "bbox")) {
336 int xmin=0,ymin=0,xmax=0,ymax=0;
337 if (!PyArg_Parse(o, "(iiii)", &xmin, &ymin, &xmax, &ymax))
340 swf->swf.movieSize.xmin = xmin;
341 swf->swf.movieSize.ymin = ymin;
342 swf->swf.movieSize.xmax = xmax;
343 swf->swf.movieSize.ymax = ymax;
344 mylog(" %08x(%d) swf_setattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
346 } else if(!strcmp(a, "tags")) {
349 PY_ASSERT_TYPE(taglist,&TagListClass);
350 Py_DECREF(swf->taglist);
351 swf->taglist = taglist;
352 Py_INCREF(swf->taglist);
353 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
357 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
361 //----------------------------------------------------------------------------
362 static PyTypeObject SWFClass =
364 PyObject_HEAD_INIT(NULL)
367 tp_basicsize: sizeof(SWFObject),
369 tp_dealloc: swf_dealloc,
371 tp_getattr: swf_getattr,
372 tp_setattr: swf_setattr,
374 //----------------------------------------------------------------------------
376 static PyMethodDef SWFMethods[] =
379 {"load", f_load, METH_VARARGS, "Load a SWF from disc."},
380 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
382 // save is a member function
384 PyMethodDef* swf_getMethods()
386 SWFClass.ob_type = &PyType_Type;
390 // =============================================================================
392 #include "primitives.h"
397 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
400 static char *kwlist[] = {"verbosity", NULL};
401 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &verbose))
403 setVerbosity(_verbose);
405 return Py_BuildValue("s", 0);
408 static PyMethodDef LoggingMethods[] =
410 /* Module functions */
411 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
418 PyMethodDef* primitive_methods = primitive_getMethods();
419 PyMethodDef* tag_methods = tag_getMethods();
420 PyMethodDef* action_methods = action_getMethods();
421 PyMethodDef* swf_methods = swf_getMethods();
423 PyMethodDef* all_methods = 0;
424 all_methods = addMethods(all_methods, primitive_methods);
425 all_methods = addMethods(all_methods, tag_methods);
426 all_methods = addMethods(all_methods, action_methods);
427 all_methods = addMethods(all_methods, swf_methods);
429 all_methods = addMethods(all_methods, LoggingMethods);
431 module = Py_InitModule("SWF", all_methods);
433 /* Python doesn't copy the PyMethodDef struct, so we need