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"
30 #include "./primitives.h"
35 1) taglist is rfxswflib's linked list. It should maybe implemented as Python
36 list, which would, however, mean that we would have to convert the list
37 back and forth for the following functions:
38 load, save, writeCGI, unfoldAll, foldAll, optimizeOrder
39 2) taglist should have an ID handler. Every time a tag is inserted, it's ID
40 is stored in a lookup list.
44 //-------------------------- Types -------------------------------------------
46 staticforward PyTypeObject SWFClass;
52 SWF swf; //swf.firstTag is not used
58 //----------------------------------------------------------------------------
59 static PyObject* f_create(PyObject* self, PyObject* args, PyObject* kwargs)
61 static char *kwlist[] = {"version", "fps", "bbox", "name", NULL};
64 double framerate = 25;
66 SRECT bbox = {0,0,0,0};
69 swf = PyObject_New(SWFObject, &SWFClass);
70 mylog("+%08x(%d) create\n", (int)swf, swf->ob_refcnt);
72 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|idOs",
73 kwlist, &version, &framerate,
78 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
79 obbox = f_BBox(0, obbox, 0);
83 bbox = bbox_getSRECT(obbox);
86 memset(&swf->swf, 0, sizeof(SWF));
88 swf->filename = strdup(filename);
92 swf->swf.fileVersion = version;
93 swf->swf.frameRate = (int)(framerate*0x100);
94 swf->swf.movieSize = bbox;
95 swf->taglist = taglist_new();
97 if(swf->swf.fileVersion>=6)
98 swf->swf.compressed = 1;
100 mylog(" %08x(%d) create: done\n", (int)swf, swf->ob_refcnt);
101 return (PyObject*)swf;
103 //----------------------------------------------------------------------------
104 static PyObject* f_load(PyObject* self, PyObject* args, PyObject* kwargs)
106 static char *kwlist1[] = {"filename", NULL};
107 static char *kwlist2[] = {"data", NULL};
114 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist1, &filename)) {
116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#", kwlist2, &data, &len)) {
118 PyArg_ParseTupleAndKeywords(args, kwargs, "s:load", kwlist1, &filename);
123 swf = PyObject_New(SWFObject, &SWFClass);
124 mylog("+%08x(%d) f_load\n", (int)swf, swf->ob_refcnt);
126 memset(&swf->swf, 0, sizeof(SWF));
130 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
133 swf->filename = strdup(filename);
134 fi = open(filename,O_RDONLY|O_BINARY);
136 return PY_ERROR("Couldn't open file %s", filename);
138 if(swf_ReadSWF(fi,&swf->swf)<0) {
140 return PY_ERROR("%s is not a valid SWF file or contains errors",filename);
145 reader_init_memreader(&r, data, len);
147 if(swf_ReadSWF2(&r, &swf->swf)<0) {
148 return PY_ERROR("<data> is not a valid SWF file or contains errors");
152 swf_FoldAll(&swf->swf);
154 swf->taglist = taglist_new2(swf->swf.firstTag);
155 if(swf->taglist == NULL) {
159 swf_FreeTags(&swf->swf);
160 swf->swf.firstTag = 0;
162 return (PyObject*)swf;
164 //----------------------------------------------------------------------------
165 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
167 static char *kwlist[] = {"name", "compress", NULL};
177 swfo = (SWFObject*)self;
180 filename = swfo->filename;
182 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
185 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
187 // keyword arg compress (=1) forces compression
191 swf->firstTag = taglist_getTAGs(swfo->taglist);
196 // fix the file, in case it is empty or not terminated properly
198 TAG*tag = swf->firstTag;
200 tag = swf->firstTag = swf_InsertTag(0,ST_END);
201 while(tag && tag->next) {
204 if(tag->id != ST_END) {
205 tag = swf_InsertTag(tag,ST_END);
209 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
211 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
214 if(swf->compressed) {
215 if(swf_WriteSWC(fi, swf)<0) {
217 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
221 if(swf_WriteSWF(fi, swf)<0) {
223 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
230 /*{ TAG * t = swf->firstTag;
233 mylog("tag: %08x\n",t);
234 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
235 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
236 mylog(" next: %08x\n", t->next);
237 TAG * tnew = t->next;
238 mylog("->free data\n");
239 if (t->data) free(t->data);
240 mylog("->free tag\n");
247 mylog(" %08x(%d) f_save filename=%s done\n", (int)self, self->ob_refcnt, filename);
251 //----------------------------------------------------------------------------
252 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
254 SWFObject*swf = (SWFObject*)self;
255 if(!self || !PyArg_ParseTuple(args,""))
257 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
258 if(!swf->swf.firstTag)
260 swf_WriteCGI(&swf->swf);
261 swf_FreeTags(&swf->swf);
262 swf->swf.firstTag = 0;
265 //----------------------------------------------------------------------------
267 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
269 static PyMethodDef swf_functions[] =
270 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
271 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
272 {NULL, NULL, 0, NULL}
275 //----------------------------------------------------------------------------
276 static void swf_dealloc(PyObject* self)
278 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
281 swfo = (SWFObject*)self;
284 free(swfo->filename);
287 Py_DECREF(swfo->taglist);
291 //----------------------------------------------------------------------------
292 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
294 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
295 SWFObject*swf = (SWFObject*)self;
296 swf_DumpHeader(fi, &swf->swf);
297 //void swf_DumpSWF(FILE * f,SWF*swf);
300 //----------------------------------------------------------------------------
301 static PyObject* swf_getattr(PyObject * self, char* a)
303 SWFObject*swf = (SWFObject*)self;
306 if(!strcmp(a, "fps")) {
307 double fps = swf->swf.frameRate/256.0;
308 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
309 return Py_BuildValue("d", fps);
310 } else if(!strcmp(a, "version")) {
311 int version = swf->swf.fileVersion;;
312 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
313 return Py_BuildValue("i", version);
314 } else if(!strcmp(a, "name")) {
315 char*filename = swf->filename;
316 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
317 return Py_BuildValue("s", filename);
318 } else if(!strcmp(a, "bbox")) {
319 return f_BBox2(swf->swf.movieSize);
320 } else if(!strcmp(a, "tags")) {
321 PyObject*ret = (PyObject*)(swf->taglist);
323 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
325 } else if(!strcmp(a, "filesize")) {
326 int s = swf->swf.fileSize;
327 return Py_BuildValue("i", s);
328 } else if(!strcmp(a, "width")) {
329 int w = (swf->swf.movieSize.xmax - swf->swf.movieSize.xmin) / 20;
330 return Py_BuildValue("i", w);
331 } else if(!strcmp(a, "height")) {
332 int h = (swf->swf.movieSize.ymax - swf->swf.movieSize.ymin) / 20;
333 return Py_BuildValue("i", h);
334 } else if(!strcmp(a, "framecount")) {
335 int f = swf->swf.frameCount;
336 return Py_BuildValue("i", f);
339 ret = Py_FindMethod(swf_functions, self, a);
340 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
343 //----------------------------------------------------------------------------
344 static int swf_setattr(PyObject * self, char* a, PyObject * o)
346 SWFObject*swf = (SWFObject*)self;
347 if(!strcmp(a, "fps")) {
349 if (!PyArg_Parse(o, "d", &fps))
351 swf->swf.frameRate = (int)(fps*0x100);
352 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
354 } else if(!strcmp(a, "version")) {
356 if (!PyArg_Parse(o, "i", &version))
358 swf->swf.fileVersion = version;
359 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
361 } else if(!strcmp(a, "name")) {
363 if (!PyArg_Parse(o, "s", &filename))
366 free(swf->filename);swf->filename=0;
368 swf->filename = strdup(filename);
369 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
371 } else if(!strcmp(a, "bbox")) {
373 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
374 obbox = f_BBox(0, o, 0);
378 SRECT bbox = bbox_getSRECT(obbox);
380 swf->swf.movieSize = bbox;
381 mylog(" %08x(%d) swf_setattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, bbox.xmin,bbox.ymin,bbox.xmax,bbox.ymax);
383 } else if(!strcmp(a, "tags")) {
386 PY_ASSERT_TYPE(taglist,&TagListClass);
387 Py_DECREF(swf->taglist);
388 swf->taglist = taglist;
389 Py_INCREF(swf->taglist);
390 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
394 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
398 //----------------------------------------------------------------------------
399 static PyTypeObject SWFClass =
401 PyObject_HEAD_INIT(NULL)
404 tp_basicsize: sizeof(SWFObject),
406 tp_dealloc: swf_dealloc,
408 tp_getattr: swf_getattr,
409 tp_setattr: swf_setattr,
411 //----------------------------------------------------------------------------
413 static PyMethodDef SWFMethods[] =
416 {"load", (PyCFunction)f_load, METH_KEYWORDS, "Load a SWF from disc."},
417 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
419 // save is a member function
421 PyMethodDef* swf_getMethods()
423 SWFClass.ob_type = &PyType_Type;
427 // =============================================================================
429 #include "primitives.h"
434 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
437 static char *kwlist[] = {"verbosity", NULL};
438 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &_verbose))
440 setVerbosity(_verbose);
442 return Py_BuildValue("s", 0);
445 static PyMethodDef LoggingMethods[] =
447 /* Module functions */
448 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
455 PyMethodDef* primitive_methods = primitive_getMethods();
456 PyMethodDef* tag_methods = tags_getMethods();
457 PyMethodDef* action_methods = action_getMethods();
458 PyMethodDef* swf_methods = swf_getMethods();
460 PyMethodDef* all_methods = 0;
461 all_methods = addMethods(all_methods, primitive_methods);
462 all_methods = addMethods(all_methods, tag_methods);
463 all_methods = addMethods(all_methods, action_methods);
464 all_methods = addMethods(all_methods, swf_methods);
466 all_methods = addMethods(all_methods, LoggingMethods);
468 module = Py_InitModule("SWF", all_methods);
470 /* Python doesn't copy the PyMethodDef struct, so we need