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"
34 1) taglist is rfxswflib's linked list. It should maybe implemented as Python
35 list, which would, however, mean that we would have to convert the list
36 back and forth for the following functions:
37 load, save, writeCGI, unfoldAll, foldAll, optimizeOrder
38 2) taglist should have an ID handler. Every time a tag is inserted, it's ID
39 is stored in a lookup list.
43 //-------------------------- Types -------------------------------------------
45 staticforward PyTypeObject SWFClass;
51 SWF swf; //swf.firstTag ist not used
57 //----------------------------------------------------------------------------
58 static PyObject* f_create(PyObject* self, PyObject* args, PyObject* kwargs)
60 static char *kwlist[] = {"version", "fps", "bbox", "name", NULL};
63 double framerate = 25;
65 SRECT bbox = {0,0,0,0};
68 swf = PyObject_New(SWFObject, &SWFClass);
69 mylog("+%08x(%d) create\n", (int)swf, swf->ob_refcnt);
71 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|idOs",
72 kwlist, &version, &framerate,
76 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
77 obbox = f_BBox(0, obbox, 0);
81 bbox = bbox_getSRECT(obbox);
83 memset(&swf->swf, 0, sizeof(SWF));
85 swf->filename = strdup(filename);
89 swf->swf.fileVersion = version;
90 swf->swf.frameRate = (int)(framerate*0x100);
91 swf->swf.movieSize = bbox;
92 swf->taglist = taglist_new();
94 if(swf->swf.fileVersion>=6)
95 swf->swf.compressed = 1;
97 mylog(" %08x(%d) create: done\n", (int)swf, swf->ob_refcnt);
98 return (PyObject*)swf;
100 //----------------------------------------------------------------------------
101 static PyObject* f_load(PyObject* self, PyObject* args)
107 if (!PyArg_ParseTuple(args,"s:load", &filename))
110 swf = PyObject_New(SWFObject, &SWFClass);
111 mylog("+%08x(%d) f_load\n", (int)swf, swf->ob_refcnt);
113 memset(&swf->swf, 0, sizeof(SWF));
116 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
119 swf->filename = strdup(filename);
120 fi = open(filename,O_RDONLY|O_BINARY);
122 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
125 if(swf_ReadSWF(fi,&swf->swf)<0) {
127 PyErr_SetString(PyExc_Exception, setError("%s is not a valid SWF file or contains errors",filename));
131 swf_FoldAll(&swf->swf);
133 swf->taglist = taglist_new2(swf->swf.firstTag);
134 if(swf->taglist == NULL) {
138 swf_FreeTags(&swf->swf);
139 swf->swf.firstTag = 0;
141 return (PyObject*)swf;
143 //----------------------------------------------------------------------------
144 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
146 static char *kwlist[] = {"name", "compress", NULL};
156 swfo = (SWFObject*)self;
159 filename = swfo->filename;
161 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
164 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
166 // keyword arg compress (=1) forces compression
170 swf->firstTag = taglist_getTAGs(swfo->taglist);
174 // fix the file, in case it is empty or not terminated properly
176 TAG*tag = swf->firstTag;
178 tag = swf->firstTag = swf_InsertTag(0,ST_END);
179 while(tag && tag->next) {
182 if(tag->id != ST_END) {
183 tag = swf_InsertTag(tag,ST_END);
187 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
189 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
192 if(swf->compressed) {
193 if(swf_WriteSWC(fi, swf)<0) {
195 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
199 if(swf_WriteSWF(fi, swf)<0) {
201 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
208 /*{ TAG * t = swf->firstTag;
211 mylog("tag: %08x\n",t);
212 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
213 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
214 mylog(" next: %08x\n", t->next);
215 TAG * tnew = t->next;
216 mylog("->free data\n");
217 if (t->data) free(t->data);
218 mylog("->free tag\n");
225 mylog(" %08x(%d) f_save filename=%s done\n", (int)self, self->ob_refcnt, filename);
229 //----------------------------------------------------------------------------
230 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
232 SWFObject*swf = (SWFObject*)self;
233 if(!self || !PyArg_ParseTuple(args,""))
235 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
236 if(!swf->swf.firstTag)
238 swf_WriteCGI(&swf->swf);
239 swf_FreeTags(&swf->swf);
240 swf->swf.firstTag = 0;
243 //----------------------------------------------------------------------------
245 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
247 static PyMethodDef swf_functions[] =
248 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
249 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
250 {NULL, NULL, 0, NULL}
253 //----------------------------------------------------------------------------
254 static void swf_dealloc(PyObject* self)
256 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
259 swfo = (SWFObject*)self;
262 free(swfo->filename);
265 Py_DECREF(swfo->taglist);
269 //----------------------------------------------------------------------------
270 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
272 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
273 SWFObject*swf = (SWFObject*)self;
274 swf_DumpHeader(fi, &swf->swf);
275 //void swf_DumpSWF(FILE * f,SWF*swf);
278 //----------------------------------------------------------------------------
279 static PyObject* swf_getattr(PyObject * self, char* a)
281 SWFObject*swf = (SWFObject*)self;
284 if(!strcmp(a, "fps")) {
285 double fps = swf->swf.frameRate/256.0;
286 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
287 return Py_BuildValue("d", fps);
288 } else if(!strcmp(a, "version")) {
289 int version = swf->swf.fileVersion;;
290 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
291 return Py_BuildValue("i", version);
292 } else if(!strcmp(a, "name")) {
293 char*filename = swf->filename;
294 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
295 return Py_BuildValue("s", filename);
296 } else if(!strcmp(a, "bbox")) {
297 int xmin,ymin,xmax,ymax;
298 xmin = swf->swf.movieSize.xmin;
299 ymin = swf->swf.movieSize.ymin;
300 xmax = swf->swf.movieSize.xmax;
301 ymax = swf->swf.movieSize.ymax;
302 mylog(" %08x(%d) swf_getattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
303 return Py_BuildValue("(iiii)", xmin, ymin, xmax, ymax);
304 } else if(!strcmp(a, "tags")) {
305 PyObject*ret = (PyObject*)(swf->taglist);
307 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
311 ret = Py_FindMethod(swf_functions, self, a);
312 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
315 //----------------------------------------------------------------------------
316 static int swf_setattr(PyObject * self, char* a, PyObject * o)
318 SWFObject*swf = (SWFObject*)self;
319 if(!strcmp(a, "fps")) {
321 if (!PyArg_Parse(o, "d", &fps))
323 swf->swf.frameRate = (int)(fps*0x100);
324 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
326 } else if(!strcmp(a, "version")) {
328 if (!PyArg_Parse(o, "i", &version))
330 swf->swf.fileVersion = version;
331 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
333 } else if(!strcmp(a, "name")) {
335 if (!PyArg_Parse(o, "s", &filename))
338 free(swf->filename);swf->filename=0;
340 swf->filename = strdup(filename);
341 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
343 } else if(!strcmp(a, "bbox")) {
344 int xmin=0,ymin=0,xmax=0,ymax=0;
345 if (!PyArg_Parse(o, "(iiii)", &xmin, &ymin, &xmax, &ymax))
348 swf->swf.movieSize.xmin = xmin;
349 swf->swf.movieSize.ymin = ymin;
350 swf->swf.movieSize.xmax = xmax;
351 swf->swf.movieSize.ymax = ymax;
352 mylog(" %08x(%d) swf_setattr %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax);
354 } else if(!strcmp(a, "tags")) {
357 PY_ASSERT_TYPE(taglist,&TagListClass);
358 Py_DECREF(swf->taglist);
359 swf->taglist = taglist;
360 Py_INCREF(swf->taglist);
361 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
365 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
369 //----------------------------------------------------------------------------
370 static PyTypeObject SWFClass =
372 PyObject_HEAD_INIT(NULL)
375 tp_basicsize: sizeof(SWFObject),
377 tp_dealloc: swf_dealloc,
379 tp_getattr: swf_getattr,
380 tp_setattr: swf_setattr,
382 //----------------------------------------------------------------------------
384 static PyMethodDef SWFMethods[] =
387 {"load", f_load, METH_VARARGS, "Load a SWF from disc."},
388 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
390 // save is a member function
392 PyMethodDef* swf_getMethods()
394 SWFClass.ob_type = &PyType_Type;
398 // =============================================================================
400 #include "primitives.h"
405 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
408 static char *kwlist[] = {"verbosity", NULL};
409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &verbose))
411 setVerbosity(_verbose);
413 return Py_BuildValue("s", 0);
416 static PyMethodDef LoggingMethods[] =
418 /* Module functions */
419 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
426 PyMethodDef* primitive_methods = primitive_getMethods();
427 PyMethodDef* tag_methods = tags_getMethods();
428 PyMethodDef* action_methods = action_getMethods();
429 PyMethodDef* swf_methods = swf_getMethods();
431 PyMethodDef* all_methods = 0;
432 all_methods = addMethods(all_methods, primitive_methods);
433 all_methods = addMethods(all_methods, tag_methods);
434 all_methods = addMethods(all_methods, action_methods);
435 all_methods = addMethods(all_methods, swf_methods);
437 all_methods = addMethods(all_methods, LoggingMethods);
439 module = Py_InitModule("SWF", all_methods);
441 /* Python doesn't copy the PyMethodDef struct, so we need