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_WriteSWF(fi, swf)<0) {
216 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
222 /*{ TAG * t = swf->firstTag;
225 mylog("tag: %08x\n",t);
226 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
227 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
228 mylog(" next: %08x\n", t->next);
229 TAG * tnew = t->next;
230 mylog("->free data\n");
231 if (t->data) free(t->data);
232 mylog("->free tag\n");
239 mylog(" %08x(%d) f_save filename=%s done\n", (int)self, self->ob_refcnt, filename);
243 //----------------------------------------------------------------------------
244 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
246 SWFObject*swf = (SWFObject*)self;
247 if(!self || !PyArg_ParseTuple(args,""))
249 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
250 if(!swf->swf.firstTag)
252 swf_WriteCGI(&swf->swf);
253 swf_FreeTags(&swf->swf);
254 swf->swf.firstTag = 0;
257 //----------------------------------------------------------------------------
259 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
261 static PyMethodDef swf_functions[] =
262 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
263 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
264 {NULL, NULL, 0, NULL}
267 //----------------------------------------------------------------------------
268 static void swf_dealloc(PyObject* self)
270 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
273 swfo = (SWFObject*)self;
276 free(swfo->filename);
279 Py_DECREF(swfo->taglist);
283 //----------------------------------------------------------------------------
284 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
286 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
287 SWFObject*swf = (SWFObject*)self;
288 swf_DumpHeader(fi, &swf->swf);
289 //void swf_DumpSWF(FILE * f,SWF*swf);
292 //----------------------------------------------------------------------------
293 static PyObject* swf_getattr(PyObject * self, char* a)
295 SWFObject*swf = (SWFObject*)self;
298 if(!strcmp(a, "fps")) {
299 double fps = swf->swf.frameRate/256.0;
300 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
301 return Py_BuildValue("d", fps);
302 } else if(!strcmp(a, "version")) {
303 int version = swf->swf.fileVersion;;
304 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
305 return Py_BuildValue("i", version);
306 } else if(!strcmp(a, "name")) {
307 char*filename = swf->filename;
308 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
309 return Py_BuildValue("s", filename);
310 } else if(!strcmp(a, "bbox")) {
311 return f_BBox2(swf->swf.movieSize);
312 } else if(!strcmp(a, "tags")) {
313 PyObject*ret = (PyObject*)(swf->taglist);
315 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
317 } else if(!strcmp(a, "filesize")) {
318 int s = swf->swf.fileSize;
319 return Py_BuildValue("i", s);
320 } else if(!strcmp(a, "width")) {
321 int w = (swf->swf.movieSize.xmax - swf->swf.movieSize.xmin) / 20;
322 return Py_BuildValue("i", w);
323 } else if(!strcmp(a, "height")) {
324 int h = (swf->swf.movieSize.ymax - swf->swf.movieSize.ymin) / 20;
325 return Py_BuildValue("i", h);
326 } else if(!strcmp(a, "framecount")) {
327 int f = swf->swf.frameCount;
328 return Py_BuildValue("i", f);
331 ret = Py_FindMethod(swf_functions, self, a);
332 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
335 //----------------------------------------------------------------------------
336 static int swf_setattr(PyObject * self, char* a, PyObject * o)
338 SWFObject*swf = (SWFObject*)self;
339 if(!strcmp(a, "fps")) {
341 if (!PyArg_Parse(o, "d", &fps))
343 swf->swf.frameRate = (int)(fps*0x100);
344 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
346 } else if(!strcmp(a, "version")) {
348 if (!PyArg_Parse(o, "i", &version))
350 swf->swf.fileVersion = version;
351 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
353 } else if(!strcmp(a, "name")) {
355 if (!PyArg_Parse(o, "s", &filename))
358 free(swf->filename);swf->filename=0;
360 swf->filename = strdup(filename);
361 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
363 } else if(!strcmp(a, "bbox")) {
365 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
366 obbox = f_BBox(0, o, 0);
370 SRECT bbox = bbox_getSRECT(obbox);
372 swf->swf.movieSize = bbox;
373 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);
375 } else if(!strcmp(a, "tags")) {
378 PY_ASSERT_TYPE(taglist,&TagListClass);
379 Py_DECREF(swf->taglist);
380 swf->taglist = taglist;
381 Py_INCREF(swf->taglist);
382 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
386 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
390 //----------------------------------------------------------------------------
391 static PyTypeObject SWFClass =
393 PyObject_HEAD_INIT(NULL)
396 tp_basicsize: sizeof(SWFObject),
398 tp_dealloc: swf_dealloc,
400 tp_getattr: swf_getattr,
401 tp_setattr: swf_setattr,
403 //----------------------------------------------------------------------------
405 static PyMethodDef SWFMethods[] =
408 {"load", (PyCFunction)f_load, METH_KEYWORDS, "Load a SWF from disc."},
409 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
411 // save is a member function
413 PyMethodDef* swf_getMethods()
415 SWFClass.ob_type = &PyType_Type;
419 // =============================================================================
421 #include "primitives.h"
426 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
429 static char *kwlist[] = {"verbosity", NULL};
430 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &_verbose))
432 setVerbosity(_verbose);
434 return Py_BuildValue("s", 0);
437 static PyMethodDef LoggingMethods[] =
439 /* Module functions */
440 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
447 PyMethodDef* primitive_methods = primitive_getMethods();
448 PyMethodDef* tag_methods = tags_getMethods();
449 PyMethodDef* action_methods = action_getMethods();
450 PyMethodDef* swf_methods = swf_getMethods();
452 PyMethodDef* all_methods = 0;
453 all_methods = addMethods(all_methods, primitive_methods);
454 all_methods = addMethods(all_methods, tag_methods);
455 all_methods = addMethods(all_methods, action_methods);
456 all_methods = addMethods(all_methods, swf_methods);
458 all_methods = addMethods(all_methods, LoggingMethods);
460 module = Py_InitModule("SWF", all_methods);
462 /* Python doesn't copy the PyMethodDef struct, so we need