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)
110 if (!PyArg_ParseTuple(args,"s:load", &filename))
113 swf = PyObject_New(SWFObject, &SWFClass);
114 mylog("+%08x(%d) f_load\n", (int)swf, swf->ob_refcnt);
116 memset(&swf->swf, 0, sizeof(SWF));
119 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
122 swf->filename = strdup(filename);
123 fi = open(filename,O_RDONLY|O_BINARY);
125 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
128 if(swf_ReadSWF(fi,&swf->swf)<0) {
130 PyErr_SetString(PyExc_Exception, setError("%s is not a valid SWF file or contains errors",filename));
134 swf_FoldAll(&swf->swf);
136 swf->taglist = taglist_new2(swf->swf.firstTag);
137 if(swf->taglist == NULL) {
141 swf_FreeTags(&swf->swf);
142 swf->swf.firstTag = 0;
144 return (PyObject*)swf;
146 //----------------------------------------------------------------------------
147 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
149 static char *kwlist[] = {"name", "compress", NULL};
159 swfo = (SWFObject*)self;
162 filename = swfo->filename;
164 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
167 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
169 // keyword arg compress (=1) forces compression
173 swf->firstTag = taglist_getTAGs(swfo->taglist);
178 // fix the file, in case it is empty or not terminated properly
180 TAG*tag = swf->firstTag;
182 tag = swf->firstTag = swf_InsertTag(0,ST_END);
183 while(tag && tag->next) {
186 if(tag->id != ST_END) {
187 tag = swf_InsertTag(tag,ST_END);
191 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
193 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
196 if(swf->compressed) {
197 if(swf_WriteSWC(fi, swf)<0) {
199 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
203 if(swf_WriteSWF(fi, swf)<0) {
205 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
212 /*{ TAG * t = swf->firstTag;
215 mylog("tag: %08x\n",t);
216 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
217 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
218 mylog(" next: %08x\n", t->next);
219 TAG * tnew = t->next;
220 mylog("->free data\n");
221 if (t->data) free(t->data);
222 mylog("->free tag\n");
229 mylog(" %08x(%d) f_save filename=%s done\n", (int)self, self->ob_refcnt, filename);
233 //----------------------------------------------------------------------------
234 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
236 SWFObject*swf = (SWFObject*)self;
237 if(!self || !PyArg_ParseTuple(args,""))
239 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
240 if(!swf->swf.firstTag)
242 swf_WriteCGI(&swf->swf);
243 swf_FreeTags(&swf->swf);
244 swf->swf.firstTag = 0;
247 //----------------------------------------------------------------------------
249 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
251 static PyMethodDef swf_functions[] =
252 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
253 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
254 {NULL, NULL, 0, NULL}
257 //----------------------------------------------------------------------------
258 static void swf_dealloc(PyObject* self)
260 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
263 swfo = (SWFObject*)self;
266 free(swfo->filename);
269 Py_DECREF(swfo->taglist);
273 //----------------------------------------------------------------------------
274 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
276 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
277 SWFObject*swf = (SWFObject*)self;
278 swf_DumpHeader(fi, &swf->swf);
279 //void swf_DumpSWF(FILE * f,SWF*swf);
282 //----------------------------------------------------------------------------
283 static PyObject* swf_getattr(PyObject * self, char* a)
285 SWFObject*swf = (SWFObject*)self;
288 if(!strcmp(a, "fps")) {
289 double fps = swf->swf.frameRate/256.0;
290 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
291 return Py_BuildValue("d", fps);
292 } else if(!strcmp(a, "version")) {
293 int version = swf->swf.fileVersion;;
294 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
295 return Py_BuildValue("i", version);
296 } else if(!strcmp(a, "name")) {
297 char*filename = swf->filename;
298 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
299 return Py_BuildValue("s", filename);
300 } else if(!strcmp(a, "bbox")) {
301 return f_BBox2(swf->swf.movieSize);
302 } else if(!strcmp(a, "tags")) {
303 PyObject*ret = (PyObject*)(swf->taglist);
305 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
307 } else if(!strcmp(a, "filesize")) {
308 int s = swf->swf.fileSize;
309 return Py_BuildValue("i", s);
310 } else if(!strcmp(a, "width")) {
311 int w = (swf->swf.movieSize.xmax - swf->swf.movieSize.xmin) / 20;
312 return Py_BuildValue("i", w);
313 } else if(!strcmp(a, "height")) {
314 int h = (swf->swf.movieSize.ymax - swf->swf.movieSize.ymin) / 20;
315 return Py_BuildValue("i", h);
316 } else if(!strcmp(a, "framecount")) {
317 int f = swf->swf.frameCount;
318 return Py_BuildValue("i", f);
321 ret = Py_FindMethod(swf_functions, self, a);
322 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
325 //----------------------------------------------------------------------------
326 static int swf_setattr(PyObject * self, char* a, PyObject * o)
328 SWFObject*swf = (SWFObject*)self;
329 if(!strcmp(a, "fps")) {
331 if (!PyArg_Parse(o, "d", &fps))
333 swf->swf.frameRate = (int)(fps*0x100);
334 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
336 } else if(!strcmp(a, "version")) {
338 if (!PyArg_Parse(o, "i", &version))
340 swf->swf.fileVersion = version;
341 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
343 } else if(!strcmp(a, "name")) {
345 if (!PyArg_Parse(o, "s", &filename))
348 free(swf->filename);swf->filename=0;
350 swf->filename = strdup(filename);
351 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
353 } else if(!strcmp(a, "bbox")) {
355 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
356 obbox = f_BBox(0, o, 0);
360 SRECT bbox = bbox_getSRECT(obbox);
362 swf->swf.movieSize = bbox;
363 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);
365 } else if(!strcmp(a, "tags")) {
368 PY_ASSERT_TYPE(taglist,&TagListClass);
369 Py_DECREF(swf->taglist);
370 swf->taglist = taglist;
371 Py_INCREF(swf->taglist);
372 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
376 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
380 //----------------------------------------------------------------------------
381 static PyTypeObject SWFClass =
383 PyObject_HEAD_INIT(NULL)
386 tp_basicsize: sizeof(SWFObject),
388 tp_dealloc: swf_dealloc,
390 tp_getattr: swf_getattr,
391 tp_setattr: swf_setattr,
393 //----------------------------------------------------------------------------
395 static PyMethodDef SWFMethods[] =
398 {"load", f_load, METH_VARARGS, "Load a SWF from disc."},
399 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
401 // save is a member function
403 PyMethodDef* swf_getMethods()
405 SWFClass.ob_type = &PyType_Type;
409 // =============================================================================
411 #include "primitives.h"
416 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
419 static char *kwlist[] = {"verbosity", NULL};
420 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &_verbose))
422 setVerbosity(_verbose);
424 return Py_BuildValue("s", 0);
427 static PyMethodDef LoggingMethods[] =
429 /* Module functions */
430 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
437 PyMethodDef* primitive_methods = primitive_getMethods();
438 PyMethodDef* tag_methods = tags_getMethods();
439 PyMethodDef* action_methods = action_getMethods();
440 PyMethodDef* swf_methods = swf_getMethods();
442 PyMethodDef* all_methods = 0;
443 all_methods = addMethods(all_methods, primitive_methods);
444 all_methods = addMethods(all_methods, tag_methods);
445 all_methods = addMethods(all_methods, action_methods);
446 all_methods = addMethods(all_methods, swf_methods);
448 all_methods = addMethods(all_methods, LoggingMethods);
450 module = Py_InitModule("SWF", all_methods);
452 /* Python doesn't copy the PyMethodDef struct, so we need