added image and shape tags.
[swftools.git] / lib / python / tags.c
index 54625e6..e642125 100644 (file)
@@ -3,6 +3,7 @@
 #include "action.h"
 #include "tag.h"
 #include "tags.h"
+#include "image.h"
 
 //----------------------------------------------------------------------------
 
@@ -317,12 +318,133 @@ static tag_internals_t text_tag =
     datasize: sizeof(text_internal_t),
 };
 //----------------------------------------------------------------------------
+staticforward tag_internals_t image_tag;
+
+typedef struct _image_internal
+{
+    RGBA*rgba;
+    int size;
+    int width;
+    int height;
+    int bpp;
+    char isindexed;
+    char islossless;
+} image_internal_t;
+staticforward tag_internals_t image_tag;
+
+static int image_fillTAG(tag_internals_t*self)
+{
+    image_internal_t*ti = (image_internal_t*)self->data;
+    self->tag= swf_InsertTag(0, ST_DEFINEBITSLOSSLESS2);
+    swf_SetU16(self->tag, /*ID*/0);
+    swf_SetLosslessBits(self->tag, ti->width, ti->height, ti->rgba, BMF_32BIT);
+    return 1;
+}
+static void image_dealloc(tag_internals_t*self)
+{
+    image_internal_t*pi = (image_internal_t*)self->data;
+    if(pi->rgba) {
+       free(pi->rgba);pi->rgba = 0;
+    }
+}
+static PyObject* f_DefineImage(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"image"};
+    PyObject*image = 0;
+    PyObject*tag = tag_new(&image_tag);
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &image))
+       return NULL;
+    
+    tag = tag_new(&image_tag);
+    tag_internals_t* itag = tag_getinternals(tag);
+    image_internal_t*ti = (image_internal_t*)itag->data;
+
+    ti->rgba = image_toRGBA(image);
+    if(!ti->rgba) // pass through exception
+       return 0;
+    ti->width = image_getWidth(image);
+    ti->height = image_getHeight(image);
+    ti->isindexed = 0;
+    ti->islossless = 1;
+    ti->bpp = 32;
+    ti->size = ti->width*ti->height;
+
+    return (PyObject*)tag;
+}
+static tag_internals_t image_tag =
+{
+    parse: 0,
+    fillTAG: image_fillTAG,
+    dealloc: image_dealloc,
+    tagfunctions: 0,
+    datasize: sizeof(image_internal_t),
+};
+//----------------------------------------------------------------------------
+staticforward tag_internals_t shape_tag;
+
+typedef struct _shape_internal
+{
+    SHAPE2*shape;
+} shape_internal_t;
+staticforward tag_internals_t shape_tag;
+
+static int shape_fillTAG(tag_internals_t*self)
+{
+    shape_internal_t*ti = (shape_internal_t*)self->data;
+    self->tag= swf_InsertTag(0, ST_DEFINESHAPE3);
+    swf_SetU16(self->tag, /*ID*/0);
+    swf_SetShape2(self->tag, ti->shape);
+    return 1;
+}
+static void shape_dealloc(tag_internals_t*self)
+{
+    shape_internal_t*pi = (shape_internal_t*)self->data;
+    if(pi->shape) {
+       swf_Shape2Free(pi->shape);
+       pi->shape = 0;
+    }
+}
+static PyObject* f_DefineImageShape(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"image"};
+    PyObject*shape = 0;
+    PyObject*tag = tag_new(&shape_tag);
+    PyObject*image = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &TagClass, &image))
+       return NULL;
+    
+    tag = tag_new(&shape_tag);
+    tag_internals_t* itag = tag_getinternals(tag);
+    shape_internal_t*ti = (shape_internal_t*)itag->data;
+    ti->shape = 0; /*HACK*/
+
+    int width = image_getWidth(image);
+    int height = image_getHeight(image);
+    int id = tagmap_add(itag->tagmap, image);
+    itag->tag= swf_InsertTag(0, ST_DEFINESHAPE3);
+    swf_SetU16(itag->tag, 0);
+    swf_ShapeSetBitmapRect(itag->tag, id, width, height);
+    return (PyObject*)tag;
+}
+static tag_internals_t shape_tag =
+{
+    parse: 0,
+    fillTAG: shape_fillTAG,
+    dealloc: shape_dealloc,
+    tagfunctions: 0,
+    datasize: sizeof(shape_internal_t),
+};
+//----------------------------------------------------------------------------
 
 typedef struct _videostream_internal
 {
     VIDEOSTREAM* stream;
+    int lastiframe;
 } videostream_internal_t;
 staticforward tag_internals_t videostream_tag;
+staticforward tag_internals_t videoframe_tag;
 
 static int videostream_parse(tag_internals_t*self)
 {
@@ -353,9 +475,9 @@ static PyObject* f_DefineVideoStream(PyObject* self, PyObject* args, PyObject* k
 {
     PyObject*tag = tag_new(&videostream_tag);
    
-    int width=0,height=0,quant=7,frames=65535;
-    static char *kwlist[] = {"width", "height", "quant", "frames", NULL};
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &TagClass, &width, &height, &quant, &frames))
+    int width=0,height=0,frames=65535;
+    static char *kwlist[] = {"width", "height", "frames", NULL};
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i", kwlist, &TagClass, &width, &height, &frames))
        return NULL;
     
     tag_internals_t*itag = tag_getinternals(tag);
@@ -365,6 +487,7 @@ static PyObject* f_DefineVideoStream(PyObject* self, PyObject* args, PyObject* k
 
     TAG*t = swf_InsertTag(0, ST_DEFINEVIDEOSTREAM);
     swf_SetVideoStreamDefine(t, fi->stream, frames, width, height);
+    fi->lastiframe = -65536;
     return (PyObject*)tag;
 }
 static VIDEOSTREAM* videostream_getVIDEOSTREAM(PyObject*self)
@@ -388,33 +511,54 @@ static PyObject* videostream_getbheight(PyObject*self, PyObject*args)
     int height = fi->stream->bby;
     return Py_BuildValue("i", height);
 }
-static PyObject* videostream_addIFrame(PyObject*self, PyObject*args)
+static PyObject* videostream_addFrame(PyObject*self, PyObject*args, PyObject*kwargs)
 {
-    tag_internals_t*itag = tag_getinternals(self);
-    videostream_internal_t*fi = (videostream_internal_t*)itag->data;
-    /* TODO */
-    return Py_BuildValue("s", 0);
-}
-static PyObject* videostream_addPFrame(PyObject*self, PyObject*args)
-{
-    tag_internals_t*itag = tag_getinternals(self);
-    videostream_internal_t*fi = (videostream_internal_t*)itag->data;
-    /* TODO */
+    tag_internals_t*_itag = tag_getinternals(self);
+    videostream_internal_t*fi = (videostream_internal_t*)_itag->data;
+   
+    PyObject*image = 0;
+    char*type=0; // none, "i", "p"
+    int quant=7;
+    static char *kwlist[] = {"image", "quant", "type", NULL};
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|is", kwlist, &image, &quant, &type))
+       return NULL;
+    if(fi->stream->width != image_getWidth(image)) {
+       PyErr_SetString(PyExc_Exception, setError("bad image width %d!=%d", image_getWidth(image), fi->stream->width));return 0;
+    }
+    if(fi->stream->height != image_getHeight(image)) {
+       PyErr_SetString(PyExc_Exception, setError("bad image width %d!=%d", image_getHeight(image), fi->stream->height));return 0;
+    }
+    PyObject*tag = tag_new(&videoframe_tag);
+    tag_internals_t*itag = tag_getinternals(tag);
+
+    RGBA*pic = image_toRGBA(image);
+    TAG* t = swf_InsertTag(0, ST_VIDEOFRAME);
+    if((type && (type[0]=='I' || type[0]=='i')) || (type==0 && fi->lastiframe+64 < fi->stream->frame)) {
+       swf_SetU16(t,0);
+       swf_SetVideoStreamIFrame(t, fi->stream, pic, quant);
+       fi->lastiframe = fi->stream->frame;
+    } else {
+       swf_SetU16(t,0);
+       swf_SetVideoStreamPFrame(t, fi->stream, pic, quant);
+    }
+    itag->tag = t;
+    tagmap_addMapping(itag->tagmap, 0, self);
+    free(pic);
     return Py_BuildValue("s", 0);
 }
 static PyObject* videostream_addDistortionFrame(PyObject*self, PyObject*args)
 {
     tag_internals_t*itag = tag_getinternals(self);
     videostream_internal_t*fi = (videostream_internal_t*)itag->data;
+    
     /* TODO */
     return Py_BuildValue("s", 0);
 }
 static PyMethodDef videostream_methods[] = 
 {{"xblocks", videostream_getbwidth, METH_VARARGS, "get's the number of horizontal blocks"},
  {"yblocks", videostream_getbheight, METH_VARARGS, "get's the number of vertical blocks"},
- {"addIFrame", videostream_addIFrame, METH_VARARGS, "add a I Video Frame"},
- {"addPFrame", videostream_addPFrame, METH_VARARGS, "add a P Video Frame"},
- {"addDistortionFrame", videostream_addDistortionFrame, METH_VARARGS, "add a MVD frame"},
+ {"addFrame", (PyCFunction)videostream_addFrame, METH_KEYWORDS, "add a Video Frame"},
+ {"addDistortionFrame", (PyCFunction)videostream_addDistortionFrame, METH_KEYWORDS, "add a MVD frame"},
  {NULL, NULL, 0, NULL}
 };
 
@@ -429,6 +573,17 @@ static tag_internals_t videostream_tag =
 
 //============================================================================
 
+static tag_internals_t videoframe_tag =
+{
+    parse: 0,
+    fillTAG: 0,
+    dealloc: 0,
+    tagfunctions: 0,
+    datasize: 0
+};
+
+//============================================================================
+
 static PyMethodDef TagMethods[] = 
 {
     /* TAGS */
@@ -438,6 +593,8 @@ static PyMethodDef TagMethods[] =
     {"Text", (PyCFunction)f_DefineText, METH_KEYWORDS, "Create a DefineText Tag."},
     {"PlaceObject", (PyCFunction)f_PlaceObject, METH_KEYWORDS, "Create a PlaceObject Tag."},
     {"VideoStream", (PyCFunction)f_DefineVideoStream, METH_KEYWORDS, "Create a Videostream."},
+    {"Image", (PyCFunction)f_DefineImage, METH_KEYWORDS, "Create an SWF Image Tag."},
+    {"ImageShape", (PyCFunction)f_DefineImageShape, METH_KEYWORDS, "Create an SWF Image Shape Tag."},
     {NULL, NULL, 0, NULL}
 };
 PyMethodDef* tags_getMethods()
@@ -450,6 +607,11 @@ PyMethodDef* tags_getMethods()
     register_tag(ST_DEFINEFONT,&font_tag);
     register_tag(ST_PROTECT,&protect_tag);
     register_tag(ST_DEFINETEXT,&text_tag);
+    register_tag(ST_DEFINEBITSJPEG,&image_tag);
+    register_tag(ST_DEFINEBITSJPEG2,&image_tag);
+    register_tag(ST_DEFINEBITSJPEG3,&image_tag);
+    register_tag(ST_DEFINEBITSLOSSLESS,&image_tag);
+    register_tag(ST_DEFINEBITSLOSSLESS2,&image_tag);
     register_tag(ST_END,&end_tag);
 
     return TagMethods;