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 */
24 #include <sys/types.h>
27 #include "../rfxswf.h"
29 #include "./pyutils.h"
31 #include "./taglist.h"
32 #include "./primitives.h"
37 1) taglist is rfxswflib's linked list. It should maybe implemented as Python
38 list, which would, however, mean that we would have to convert the list
39 back and forth for the following functions:
40 load, save, writeCGI, unfoldAll, foldAll, optimizeOrder
41 2) taglist should have an ID handler. Every time a tag is inserted, it's ID
42 is stored in a lookup list.
46 //-------------------------- Types -------------------------------------------
48 staticforward PyTypeObject SWFClass
;
54 SWF swf
; //swf.firstTag is not used
60 //----------------------------------------------------------------------------
61 static PyObject
* f_create(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
63 static char *kwlist
[] = {"version", "fps", "bbox", "name", NULL
};
66 double framerate
= 25;
68 SRECT bbox
= {0,0,0,0};
71 swf
= PyObject_New(SWFObject
, &SWFClass
);
72 mylog("+%08x(%d) create\n", (int)swf
, swf
->ob_refcnt
);
74 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|idOs",
75 kwlist
, &version
, &framerate
,
80 if (!PY_CHECK_TYPE(obbox
, &BBoxClass
)) {
81 obbox
= f_BBox(0, obbox
, 0);
85 bbox
= bbox_getSRECT(obbox
);
88 memset(&swf
->swf
, 0, sizeof(SWF
));
90 swf
->filename
= strdup(filename
);
94 swf
->swf
.fileVersion
= version
;
95 swf
->swf
.frameRate
= (int)(framerate
*0x100);
96 swf
->swf
.movieSize
= bbox
;
97 swf
->taglist
= taglist_new();
99 if(swf
->swf
.fileVersion
>=6)
100 swf
->swf
.compressed
= 1;
102 mylog(" %08x(%d) create: done\n", (int)swf
, swf
->ob_refcnt
);
103 return (PyObject
*)swf
;
105 //----------------------------------------------------------------------------
106 static PyObject
* f_load(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
108 static char *kwlist1
[] = {"filename", NULL
};
109 static char *kwlist2
[] = {"data", NULL
};
116 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s", kwlist1
, &filename
)) {
118 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s#", kwlist2
, &data
, &len
)) {
120 PyArg_ParseTupleAndKeywords(args
, kwargs
, "s:load", kwlist1
, &filename
);
125 swf
= PyObject_New(SWFObject
, &SWFClass
);
126 mylog("+%08x(%d) f_load\n", (int)swf
, swf
->ob_refcnt
);
128 memset(&swf
->swf
, 0, sizeof(SWF
));
132 PyErr_SetString(PyExc_Exception
, setError("Couldn't open file %s", filename
));
135 swf
->filename
= strdup(filename
);
136 fi
= open(filename
,O_RDONLY
|O_BINARY
);
138 return PY_ERROR("Couldn't open file %s", filename
);
140 if(swf_ReadSWF(fi
,&swf
->swf
)<0) {
142 return PY_ERROR("%s is not a valid SWF file or contains errors",filename
);
147 reader_init_memreader(&r
, data
, len
);
149 if(swf_ReadSWF2(&r
, &swf
->swf
)<0) {
150 return PY_ERROR("<data> is not a valid SWF file or contains errors");
154 swf_FoldAll(&swf
->swf
);
156 swf
->taglist
= taglist_new2(swf
->swf
.firstTag
);
157 if(swf
->taglist
== NULL
) {
161 swf_FreeTags(&swf
->swf
);
162 swf
->swf
.firstTag
= 0;
164 return (PyObject
*)swf
;
166 //----------------------------------------------------------------------------
167 static PyObject
* swf_save(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
169 static char *kwlist
[] = {"name", "compress", NULL
};
179 swfo
= (SWFObject
*)self
;
182 filename
= swfo
->filename
;
184 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|si", kwlist
, &filename
, &compress
))
187 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self
, self
->ob_refcnt
, filename
, compress
);
189 // keyword arg compress (=1) forces compression
193 swf
->firstTag
= taglist_getTAGs(swfo
->taglist
);
198 // fix the file, in case it is empty or not terminated properly
200 TAG
*tag
= swf
->firstTag
;
202 tag
= swf
->firstTag
= swf_InsertTag(0,ST_END
);
203 while(tag
&& tag
->next
) {
206 if(tag
->id
!= ST_END
) {
207 tag
= swf_InsertTag(tag
,ST_END
);
211 fi
= open(filename
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_BINARY
, 0644);
213 PyErr_SetString(PyExc_Exception
, setError("couldn't create output file %s", filename
));
216 if(swf_WriteSWF(fi
, swf
)<0) {
218 PyErr_SetString(PyExc_Exception
, setError("WriteSWC() failed."));
224 /*{ TAG * t = swf->firstTag;
227 mylog("tag: %08x\n",t);
228 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
229 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
230 mylog(" next: %08x\n", t->next);
231 TAG * tnew = t->next;
232 mylog("->free data\n");
233 if (t->data) free(t->data);
234 mylog("->free tag\n");
241 mylog(" %08x(%d) f_save filename=%s done\n", (int)self
, self
->ob_refcnt
, filename
);
245 //----------------------------------------------------------------------------
246 static PyObject
* swf_writeCGI(PyObject
* self
, PyObject
* args
)
248 SWFObject
*swf
= (SWFObject
*)self
;
249 if(!self
|| !PyArg_ParseTuple(args
,""))
251 swf
->swf
.firstTag
= taglist_getTAGs(swf
->taglist
);
252 if(!swf
->swf
.firstTag
)
254 swf_WriteCGI(&swf
->swf
);
255 swf_FreeTags(&swf
->swf
);
256 swf
->swf
.firstTag
= 0;
259 //----------------------------------------------------------------------------
261 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
263 static PyMethodDef swf_functions
[] =
264 {{"save", (PyCFunction
)swf_save
, METH_KEYWORDS
, "Save SWF to disk"},
265 {"writeCGI", (PyCFunction
)swf_writeCGI
, METH_VARARGS
, "print SWF as CGI to stdout"},
266 {NULL
, NULL
, 0, NULL
}
269 //----------------------------------------------------------------------------
270 static void swf_dealloc(PyObject
* self
)
272 mylog("-%08x(%d) swf_dealloc\n", (int)self
, self
->ob_refcnt
);
275 swfo
= (SWFObject
*)self
;
278 free(swfo
->filename
);
281 Py_DECREF(swfo
->taglist
);
285 //----------------------------------------------------------------------------
286 static int swf_print(PyObject
* self
, FILE *fi
, int flags
) //flags&Py_PRINT_RAW
288 mylog(" %08x(%d) print \n", (int)self
, self
->ob_refcnt
);
289 SWFObject
*swf
= (SWFObject
*)self
;
290 swf_DumpHeader(fi
, &swf
->swf
);
291 //void swf_DumpSWF(FILE * f,SWF*swf);
294 //----------------------------------------------------------------------------
295 static PyObject
* swf_getattr(PyObject
* self
, char* a
)
297 SWFObject
*swf
= (SWFObject
*)self
;
300 if(!strcmp(a
, "fps")) {
301 double fps
= swf
->swf
.frameRate
/256.0;
302 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self
, self
->ob_refcnt
, a
, fps
);
303 return Py_BuildValue("d", fps
);
304 } else if(!strcmp(a
, "version")) {
305 int version
= swf
->swf
.fileVersion
;;
306 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self
, self
->ob_refcnt
, a
, version
);
307 return Py_BuildValue("i", version
);
308 } else if(!strcmp(a
, "name")) {
309 char*filename
= swf
->filename
;
310 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self
, self
->ob_refcnt
, a
, filename
);
311 return Py_BuildValue("s", filename
);
312 } else if(!strcmp(a
, "bbox")) {
313 return f_BBox2(swf
->swf
.movieSize
);
314 } else if(!strcmp(a
, "tags")) {
315 PyObject
*ret
= (PyObject
*)(swf
->taglist
);
317 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self
, self
->ob_refcnt
, a
, ret
, ret
->ob_refcnt
);
319 } else if(!strcmp(a
, "filesize")) {
320 int s
= swf
->swf
.fileSize
;
321 return Py_BuildValue("i", s
);
322 } else if(!strcmp(a
, "width")) {
323 int w
= (swf
->swf
.movieSize
.xmax
- swf
->swf
.movieSize
.xmin
) / 20;
324 return Py_BuildValue("i", w
);
325 } else if(!strcmp(a
, "height")) {
326 int h
= (swf
->swf
.movieSize
.ymax
- swf
->swf
.movieSize
.ymin
) / 20;
327 return Py_BuildValue("i", h
);
328 } else if(!strcmp(a
, "framecount")) {
329 int f
= swf
->swf
.frameCount
;
330 return Py_BuildValue("i", f
);
333 ret
= Py_FindMethod(swf_functions
, self
, a
);
334 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self
, self
->ob_refcnt
, a
, ret
);
337 //----------------------------------------------------------------------------
338 static int swf_setattr(PyObject
* self
, char* a
, PyObject
* o
)
340 SWFObject
*swf
= (SWFObject
*)self
;
341 if(!strcmp(a
, "fps")) {
343 if (!PyArg_Parse(o
, "d", &fps
))
345 swf
->swf
.frameRate
= (int)(fps
*0x100);
346 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self
, self
->ob_refcnt
, a
, fps
);
348 } else if(!strcmp(a
, "version")) {
350 if (!PyArg_Parse(o
, "i", &version
))
352 swf
->swf
.fileVersion
= version
;
353 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self
, self
->ob_refcnt
, a
, version
);
355 } else if(!strcmp(a
, "name")) {
357 if (!PyArg_Parse(o
, "s", &filename
))
360 free(swf
->filename
);swf
->filename
=0;
362 swf
->filename
= strdup(filename
);
363 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self
, self
->ob_refcnt
, a
, filename
);
365 } else if(!strcmp(a
, "bbox")) {
367 if (!PY_CHECK_TYPE(obbox
, &BBoxClass
)) {
368 obbox
= f_BBox(0, o
, 0);
372 SRECT bbox
= bbox_getSRECT(obbox
);
374 swf
->swf
.movieSize
= bbox
;
375 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
);
377 } else if(!strcmp(a
, "tags")) {
380 PY_ASSERT_TYPE(taglist
,&TagListClass
);
381 Py_DECREF(swf
->taglist
);
382 swf
->taglist
= taglist
;
383 Py_INCREF(swf
->taglist
);
384 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self
, self
->ob_refcnt
, a
, swf
->taglist
);
388 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self
, self
->ob_refcnt
, a
, o
);
392 //----------------------------------------------------------------------------
393 static PyTypeObject SWFClass
=
395 PyObject_HEAD_INIT(NULL
)
398 tp_basicsize
: sizeof(SWFObject
),
400 tp_dealloc
: swf_dealloc
,
402 tp_getattr
: swf_getattr
,
403 tp_setattr
: swf_setattr
,
405 //----------------------------------------------------------------------------
407 static PyMethodDef SWFMethods
[] =
410 {"load", (PyCFunction
)f_load
, METH_KEYWORDS
, "Load a SWF from disc."},
411 {"create", (PyCFunction
)f_create
, METH_KEYWORDS
, "Create a new SWF from scratch."},
413 // save is a member function
415 PyMethodDef
* swf_getMethods()
417 SWFClass
.ob_type
= &PyType_Type
;
421 // =============================================================================
423 #include "primitives.h"
428 static PyObject
* module_verbose(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
431 static char *kwlist
[] = {"verbosity", NULL
};
432 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i", kwlist
, &_verbose
))
434 setVerbosity(_verbose
);
436 return Py_BuildValue("s", 0);
439 static PyMethodDef LoggingMethods
[] =
441 /* Module functions */
442 {"verbose", (PyCFunction
)module_verbose
, METH_KEYWORDS
, "Set the module verbosity"},
448 srand48(time(0)*getpid());
451 PyMethodDef
* primitive_methods
= primitive_getMethods();
452 PyMethodDef
* tag_methods
= tags_getMethods();
453 PyMethodDef
* action_methods
= action_getMethods();
454 PyMethodDef
* swf_methods
= swf_getMethods();
456 PyMethodDef
* all_methods
= 0;
457 all_methods
= addMethods(all_methods
, primitive_methods
);
458 all_methods
= addMethods(all_methods
, tag_methods
);
459 all_methods
= addMethods(all_methods
, action_methods
);
460 all_methods
= addMethods(all_methods
, swf_methods
);
462 all_methods
= addMethods(all_methods
, LoggingMethods
);
464 module
= Py_InitModule("SWF", all_methods
);
466 /* Python doesn't copy the PyMethodDef struct, so we need