upgrade to xpdf 3.00.
[swftools.git] / lib / python / SWF.c
blob2ed67f391d7d9fb2d6daebb7fd7885c2715621dd
1 /* SWF.c
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 */
23 #include <Python.h>
24 #undef HAVE_STAT
25 #include "../rfxswf.h"
26 #include "../log.h"
27 #include "./pyutils.h"
28 #include "./tags.h"
29 #include "./taglist.h"
30 #include "./primitives.h"
31 #include "./action.h"
34 TODO:
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.
41 3)
44 //-------------------------- Types -------------------------------------------
46 staticforward PyTypeObject SWFClass;
48 /* Tags, Objects */
50 typedef struct {
51 PyObject_HEAD
52 SWF swf; //swf.firstTag ist not used
53 PyObject*taglist;
54 char*filename;
55 } SWFObject;
58 //----------------------------------------------------------------------------
59 static PyObject* f_create(PyObject* self, PyObject* args, PyObject* kwargs)
61 static char *kwlist[] = {"version", "fps", "bbox", "name", NULL};
62 SWFObject* swf;
63 int version = 6;
64 double framerate = 25;
65 PyObject * obbox = 0;
66 SRECT bbox = {0,0,0,0};
67 char* filename = 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,
74 &obbox, &filename))
75 return NULL;
77 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
78 obbox = f_BBox(0, obbox, 0);
79 if(!obbox)
80 return NULL;
82 bbox = bbox_getSRECT(obbox);
84 memset(&swf->swf, 0, sizeof(SWF));
85 if(filename)
86 swf->filename = strdup(filename);
87 else
88 swf->filename = 0;
90 swf->swf.fileVersion = version;
91 swf->swf.frameRate = (int)(framerate*0x100);
92 swf->swf.movieSize = bbox;
93 swf->taglist = taglist_new();
95 if(swf->swf.fileVersion>=6)
96 swf->swf.compressed = 1;
98 mylog(" %08x(%d) create: done\n", (int)swf, swf->ob_refcnt);
99 return (PyObject*)swf;
101 //----------------------------------------------------------------------------
102 static PyObject* f_load(PyObject* self, PyObject* args)
104 char* filename;
105 SWFObject* swf;
106 int fi;
108 if (!PyArg_ParseTuple(args,"s:load", &filename))
109 return NULL;
111 swf = PyObject_New(SWFObject, &SWFClass);
112 mylog("+%08x(%d) f_load\n", (int)swf, swf->ob_refcnt);
114 memset(&swf->swf, 0, sizeof(SWF));
116 if(!filename) {
117 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
118 return 0;
120 swf->filename = strdup(filename);
121 fi = open(filename,O_RDONLY|O_BINARY);
122 if (fi<0) {
123 PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename));
124 return 0;
126 if(swf_ReadSWF(fi,&swf->swf)<0) {
127 close(fi);
128 PyErr_SetString(PyExc_Exception, setError("%s is not a valid SWF file or contains errors",filename));
129 return 0;
131 close(fi);
132 swf_FoldAll(&swf->swf);
134 swf->taglist = taglist_new2(swf->swf.firstTag);
135 if(swf->taglist == NULL) {
136 return NULL;
139 swf_FreeTags(&swf->swf);
140 swf->swf.firstTag = 0;
142 return (PyObject*)swf;
144 //----------------------------------------------------------------------------
145 static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs)
147 static char *kwlist[] = {"name", "compress", NULL};
148 SWFObject*swfo;
149 SWF*swf;
150 int fi;
151 char*filename = 0;
152 int compress = 0;
154 if(!self)
155 return NULL;
157 swfo = (SWFObject*)self;
158 swf = &swfo->swf;
160 filename = swfo->filename;
162 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress))
163 return NULL;
165 mylog(" %08x(%d) f_save filename=%s compress=%d\n", (int)self, self->ob_refcnt, filename, compress);
167 // keyword arg compress (=1) forces compression
168 if(compress)
169 swf->compressed = 1;
171 swf->firstTag = taglist_getTAGs(swfo->taglist);
172 if(!swf->firstTag)
173 return NULL;
175 // fix the file, in case it is empty or not terminated properly
177 TAG*tag = swf->firstTag;
178 if(!tag)
179 tag = swf->firstTag = swf_InsertTag(0,ST_END);
180 while(tag && tag->next) {
181 tag = tag->next;
183 if(tag->id != ST_END) {
184 tag = swf_InsertTag(tag,ST_END);
188 fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
189 if(fi<0) {
190 PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename));
191 return 0;
193 if(swf->compressed) {
194 if(swf_WriteSWC(fi, swf)<0) {
195 close(fi);
196 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
197 return 0;
199 } else {
200 if(swf_WriteSWF(fi, swf)<0) {
201 close(fi);
202 PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed."));
203 return 0;
206 close(fi);
208 swf_FreeTags(swf);
209 /*{ TAG * t = swf->firstTag;
210 while (t)
212 mylog("tag: %08x\n",t);
213 mylog(" id: %d (%s)\n", t->id, swf_TagGetName(t));
214 mylog(" data: %08x (%d bytes)\n", t->data, t->len);
215 mylog(" next: %08x\n", t->next);
216 TAG * tnew = t->next;
217 mylog("->free data\n");
218 if (t->data) free(t->data);
219 mylog("->free tag\n");
220 free(t);
221 t = tnew;
224 swf->firstTag = 0;
226 mylog(" %08x(%d) f_save filename=%s done\n", (int)self, self->ob_refcnt, filename);
228 return PY_NONE;
230 //----------------------------------------------------------------------------
231 static PyObject * swf_writeCGI(PyObject* self, PyObject* args)
233 SWFObject*swf = (SWFObject*)self;
234 if(!self || !PyArg_ParseTuple(args,""))
235 return NULL;
236 swf->swf.firstTag = taglist_getTAGs(swf->taglist);
237 if(!swf->swf.firstTag)
238 return NULL;
239 swf_WriteCGI(&swf->swf);
240 swf_FreeTags(&swf->swf);
241 swf->swf.firstTag = 0;
242 return PY_NONE;
244 //----------------------------------------------------------------------------
246 //TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free
248 static PyMethodDef swf_functions[] =
249 {{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"},
250 {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"},
251 {NULL, NULL, 0, NULL}
254 //----------------------------------------------------------------------------
255 static void swf_dealloc(PyObject* self)
257 mylog("-%08x(%d) swf_dealloc\n", (int)self, self->ob_refcnt);
258 SWFObject*swfo;
259 SWF*swf;
260 swfo = (SWFObject*)self;
261 swf = &swfo->swf;
262 if(swfo->filename) {
263 free(swfo->filename);
264 swfo->filename = 0;
266 Py_DECREF(swfo->taglist);
267 swfo->taglist = 0;
268 PyObject_Del(self);
270 //----------------------------------------------------------------------------
271 static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW
273 mylog(" %08x(%d) print \n", (int)self, self->ob_refcnt);
274 SWFObject*swf = (SWFObject*)self;
275 swf_DumpHeader(fi, &swf->swf);
276 //void swf_DumpSWF(FILE * f,SWF*swf);
277 return 0;
279 //----------------------------------------------------------------------------
280 static PyObject* swf_getattr(PyObject * self, char* a)
282 SWFObject*swf = (SWFObject*)self;
283 PyObject* ret;
285 if(!strcmp(a, "fps")) {
286 double fps = swf->swf.frameRate/256.0;
287 mylog(" %08x(%d) swf_getattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
288 return Py_BuildValue("d", fps);
289 } else if(!strcmp(a, "version")) {
290 int version = swf->swf.fileVersion;;
291 mylog(" %08x(%d) swf_getattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
292 return Py_BuildValue("i", version);
293 } else if(!strcmp(a, "name")) {
294 char*filename = swf->filename;
295 mylog(" %08x(%d) swf_getattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
296 return Py_BuildValue("s", filename);
297 } else if(!strcmp(a, "bbox")) {
298 return f_BBox2(swf->swf.movieSize);
299 } else if(!strcmp(a, "tags")) {
300 PyObject*ret = (PyObject*)(swf->taglist);
301 Py_INCREF(ret);
302 mylog(" %08x(%d) swf_getattr %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt);
303 return ret;
306 ret = Py_FindMethod(swf_functions, self, a);
307 mylog(" %08x(%d) swf_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
308 return ret;
310 //----------------------------------------------------------------------------
311 static int swf_setattr(PyObject * self, char* a, PyObject * o)
313 SWFObject*swf = (SWFObject*)self;
314 if(!strcmp(a, "fps")) {
315 double fps;
316 if (!PyArg_Parse(o, "d", &fps))
317 goto err;
318 swf->swf.frameRate = (int)(fps*0x100);
319 mylog(" %08x(%d) swf_setattr %s = %f\n", (int)self, self->ob_refcnt, a, fps);
320 return 0;
321 } else if(!strcmp(a, "version")) {
322 int version;
323 if (!PyArg_Parse(o, "i", &version))
324 goto err;
325 swf->swf.fileVersion = version;
326 mylog(" %08x(%d) swf_setattr %s = %d\n", (int)self, self->ob_refcnt, a, version);
327 return 0;
328 } else if(!strcmp(a, "name")) {
329 char*filename;
330 if (!PyArg_Parse(o, "s", &filename))
331 goto err;
332 if(swf->filename) {
333 free(swf->filename);swf->filename=0;
335 swf->filename = strdup(filename);
336 mylog(" %08x(%d) swf_setattr %s = %s\n", (int)self, self->ob_refcnt, a, filename);
337 return 0;
338 } else if(!strcmp(a, "bbox")) {
339 PyObject *obbox = o;
340 if (!PY_CHECK_TYPE(obbox, &BBoxClass)) {
341 obbox = f_BBox(0, o, 0);
342 if(!obbox)
343 return 1;
345 SRECT bbox = bbox_getSRECT(obbox);
347 swf->swf.movieSize = bbox;
348 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);
349 return 0;
350 } else if(!strcmp(a, "tags")) {
351 PyObject* taglist;
352 taglist = o;
353 PY_ASSERT_TYPE(taglist,&TagListClass);
354 Py_DECREF(swf->taglist);
355 swf->taglist = taglist;
356 Py_INCREF(swf->taglist);
357 mylog(" %08x(%d) swf_setattr %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist);
358 return 0;
360 err:
361 mylog(" %08x(%d) swf_setattr %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
362 return 1;
365 //----------------------------------------------------------------------------
366 static PyTypeObject SWFClass =
368 PyObject_HEAD_INIT(NULL)
370 tp_name: "SWF",
371 tp_basicsize: sizeof(SWFObject),
372 tp_itemsize: 0,
373 tp_dealloc: swf_dealloc,
374 tp_print: swf_print,
375 tp_getattr: swf_getattr,
376 tp_setattr: swf_setattr,
378 //----------------------------------------------------------------------------
380 static PyMethodDef SWFMethods[] =
382 /* SWF creation*/
383 {"load", f_load, METH_VARARGS, "Load a SWF from disc."},
384 {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."},
385 {0,0,0,0}
386 // save is a member function
388 PyMethodDef* swf_getMethods()
390 SWFClass.ob_type = &PyType_Type;
391 return SWFMethods;
394 // =============================================================================
396 #include "primitives.h"
397 #include "action.h"
398 #include "tag.h"
399 #include "taglist.h"
401 static PyObject* module_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
403 int _verbose = 0;
404 static char *kwlist[] = {"verbosity", NULL};
405 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &_verbose))
406 return NULL;
407 setVerbosity(_verbose);
409 return Py_BuildValue("s", 0);
412 static PyMethodDef LoggingMethods[] =
414 /* Module functions */
415 {"verbose", (PyCFunction)module_verbose, METH_KEYWORDS, "Set the module verbosity"},
416 {0,0,0,0}
419 void initSWF(void)
421 PyObject*module;
422 PyMethodDef* primitive_methods = primitive_getMethods();
423 PyMethodDef* tag_methods = tags_getMethods();
424 PyMethodDef* action_methods = action_getMethods();
425 PyMethodDef* swf_methods = swf_getMethods();
427 PyMethodDef* all_methods = 0;
428 all_methods = addMethods(all_methods, primitive_methods);
429 all_methods = addMethods(all_methods, tag_methods);
430 all_methods = addMethods(all_methods, action_methods);
431 all_methods = addMethods(all_methods, swf_methods);
433 all_methods = addMethods(all_methods, LoggingMethods);
435 module = Py_InitModule("SWF", all_methods);
437 /* Python doesn't copy the PyMethodDef struct, so we need
438 to keep it around */
439 // free(all_methods)