/* SV module -- interface to the Indigo video board */

/* WARNING! This module is for hardware that we don't have any more,
   so it hasn't been tested.  It has been converted to the new coding
   style, and it is possible that this conversion has broken something
   -- user beware! */

#include <sys/time.h>
#include <svideo.h>
#include "Python.h"
#include "compile.h"
#include "yuv.h"                /* for YUV conversion functions */

typedef struct {
    PyObject_HEAD
    SV_nodeP ob_svideo;
    svCaptureInfo ob_info;
} svobject;

typedef struct {
    PyObject_HEAD
    void *ob_capture;
    int ob_mustunlock;
    svCaptureInfo ob_info;
    svobject *ob_svideo;
} captureobject;

static PyObject *SvError;               /* exception sv.error */

static PyObject *newcaptureobject(svobject *, void *, int);

/* Set a SV-specific error from svideo_errno and return NULL */
static PyObject *
sv_error(void)
{
    PyErr_SetString(SvError, svStrerror(svideo_errno));
    return NULL;
}

static PyObject *
svc_conversion(captureobject *self, PyObject *args, void (*function)(), float factor)
{
    PyObject *output;
    int invert;
    char* outstr;

    if (!PyArg_Parse(args, "i", &invert))
        return NULL;

    if (!(output = PyString_FromStringAndSize(
        NULL,
        (int)(self->ob_info.width * self->ob_info.height * factor))))
    {
        return NULL;
    }
    if (!(outstr = PyString_AsString(output))) {
        Py_DECREF(output);
        return NULL;
    }

    (*function)((boolean)invert, self->ob_capture,
                outstr,
                self->ob_info.width, self->ob_info.height);

    return output;
}

/*
 * 3 functions to convert from Starter Video YUV 4:1:1 format to
 * Compression Library 4:2:2 Duplicate Chroma format.
 */
static PyObject *
svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}

static PyObject *
svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args,
                          yuv_sv411_to_cl422dc_quartersize, 0.5);
}

static PyObject *
svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args,
                          yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}

static PyObject *
svc_YUVtoRGB(captureobject *self, PyObject *args)
{
    switch (self->ob_info.format) {
    case SV_YUV411_FRAMES:
    case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
        break;
    default:
        PyErr_SetString(SvError, "data had bad format");
        return NULL;
    }
    return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}

static PyObject *
svc_RGB8toRGB32(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}

static PyObject *
svc_InterleaveFields(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, svInterleaveFields, 1.0);
}

static PyObject *
svc_GetFields(captureobject *self, PyObject *args)
{
    PyObject *f1 = NULL;
    PyObject *f2 = NULL;
    PyObject *ret = NULL;
    int fieldsize;
    char* obcapture;

    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }

    fieldsize = self->ob_info.width * self->ob_info.height / 2;
    obcapture = (char*)self->ob_capture;

    if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
        goto finally;
    if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
                                          fieldsize)))
        goto finally;
    ret = PyTuple_Pack(2, f1, f2);

  finally:
    Py_XDECREF(f1);
    Py_XDECREF(f2);
    return ret;
}

static PyObject *
svc_UnlockCaptureData(captureobject *self, PyObject *args)
{
    if (!PyArg_Parse(args, ""))
        return NULL;

    if (!self->ob_mustunlock) {
        PyErr_SetString(SvError, "buffer should not be unlocked");
        return NULL;
    }

    if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
        return sv_error();

    self->ob_mustunlock = 0;

    Py_INCREF(Py_None);
    return Py_None;
}

#ifdef USE_GL
#include <gl.h>

static PyObject *
svc_lrectwrite(captureobject *self, PyObject *args)
{
    Screencoord x1, x2, y1, y2;

    if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
        return NULL;

    lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);

    Py_INCREF(Py_None);
    return Py_None;
}
#endif

static PyObject *
svc_writefile(captureobject *self, PyObject *args)
{
    PyObject *file;
    int size;
    FILE* fp;

    if (!PyArg_Parse(args, "O", &file))
        return NULL;

    if (!PyFile_Check(file)) {
        PyErr_SetString(SvError, "not a file object");
        return NULL;
    }

    if (!(fp = PyFile_AsFile(file)))
        return NULL;

    size = self->ob_info.width * self->ob_info.height;

    if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
        PyErr_SetString(SvError, "writing failed");
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
svc_FindVisibleRegion(captureobject *self, PyObject *args)
{
    void *visible;
    int width;

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
                            self->ob_capture, &visible,
                            self->ob_info.width))
        return sv_error();

    if (visible == NULL) {
        PyErr_SetString(SvError, "data in wrong format");
        return NULL;
    }

    return newcaptureobject(self->ob_svideo, visible, 0);
}

static PyMethodDef capture_methods[] = {
    {"YUVtoRGB",                (PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
    {"RGB8toRGB32",             (PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
    {"InterleaveFields",        (PyCFunction)svc_InterleaveFields, METH_OLDARGS},
    {"UnlockCaptureData",       (PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
    {"FindVisibleRegion",       (PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
    {"GetFields",               (PyCFunction)svc_GetFields, METH_OLDARGS},
    {"YUVtoYUV422DC",           (PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
    {"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
    {"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
#ifdef USE_GL
    {"lrectwrite",              (PyCFunction)svc_lrectwrite, METH_OLDARGS},
#endif
    {"writefile",               (PyCFunction)svc_writefile, METH_OLDARGS},
    {NULL,                      NULL}           /* sentinel */
};

static void
capture_dealloc(captureobject *self)
{
    if (self->ob_capture != NULL) {
        if (self->ob_mustunlock)
            (void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
                                      self->ob_capture);
        self->ob_capture = NULL;
        Py_CLEAR(self->ob_svideo);
    }
    PyObject_Del(self);
}

static PyObject *
capture_getattr(svobject *self, char *name)
{
    return Py_FindMethod(capture_methods, (PyObject *)self, name);
}

PyTypeObject Capturetype = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,                                  /*ob_size*/
    "sv.capture",                       /*tp_name*/
    sizeof(captureobject),              /*tp_size*/
    0,                                  /*tp_itemsize*/
    /* methods */
    (destructor)capture_dealloc,        /*tp_dealloc*/
    0,                                  /*tp_print*/
    (getattrfunc)capture_getattr,       /*tp_getattr*/
    0,                                  /*tp_setattr*/
    0,                                  /*tp_compare*/
    0,                                  /*tp_repr*/
};

static PyObject *
newcaptureobject(svobject *self, void *ptr, int mustunlock)
{
    captureobject *p;

    p = PyObject_New(captureobject, &Capturetype);
    if (p == NULL)
        return NULL;
    p->ob_svideo = self;
    Py_INCREF(self);
    p->ob_capture = ptr;
    p->ob_mustunlock = mustunlock;
    p->ob_info = self->ob_info;
    return (PyObject *) p;
}

static PyObject *
sv_GetCaptureData(svobject *self, PyObject *args)
{
    void *ptr;
    long fieldID;
    PyObject *res, *c;

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
        return sv_error();

    if (ptr == NULL) {
        PyErr_SetString(SvError, "no data available");
        return NULL;
    }

    c = newcaptureobject(self, ptr, 1);
    if (c == NULL)
        return NULL;
    res = Py_BuildValue("(Oi)", c, fieldID);
    Py_DECREF(c);
    return res;
}

static PyObject *
sv_BindGLWindow(svobject *self, PyObject *args)
{
    long wid;
    int mode;

    if (!PyArg_Parse(args, "(ii)", &wid, &mode))
        return NULL;

    if (svBindGLWindow(self->ob_svideo, wid, mode))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_EndContinuousCapture(svobject *self, PyObject *args)
{

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svEndContinuousCapture(self->ob_svideo))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_IsVideoDisplayed(svobject *self, PyObject *args)
{
    int v;

    if (!PyArg_Parse(args, ""))
        return NULL;

    v = svIsVideoDisplayed(self->ob_svideo);
    if (v == -1)
        return sv_error();

    return PyInt_FromLong((long) v);
}

static PyObject *
sv_OutputOffset(svobject *self, PyObject *args)
{
    int x_offset;
    int y_offset;

    if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
        return NULL;

    if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_PutFrame(svobject *self, PyObject *args)
{
    char *buffer;

    if (!PyArg_Parse(args, "s", &buffer))
        return NULL;

    if (svPutFrame(self->ob_svideo, buffer))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_QuerySize(svobject *self, PyObject *args)
{
    int w;
    int h;
    int rw;
    int rh;

    if (!PyArg_Parse(args, "(ii)", &w, &h))
        return NULL;

    if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
        return sv_error();

    return Py_BuildValue("(ii)", (long) rw, (long) rh);
}

static PyObject *
sv_SetSize(svobject *self, PyObject *args)
{
    int w;
    int h;

    if (!PyArg_Parse(args, "(ii)", &w, &h))
        return NULL;

    if (svSetSize(self->ob_svideo, w, h))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_SetStdDefaults(svobject *self, PyObject *args)
{

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svSetStdDefaults(self->ob_svideo))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_UseExclusive(svobject *self, PyObject *args)
{
    boolean onoff;
    int mode;

    if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
        return NULL;

    if (svUseExclusive(self->ob_svideo, onoff, mode))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_WindowOffset(svobject *self, PyObject *args)
{
    int x_offset;
    int y_offset;

    if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
        return NULL;

    if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_CaptureBurst(svobject *self, PyObject *args)
{
    int bytes, i;
    svCaptureInfo info;
    void *bitvector = NULL;
    PyObject *videodata = NULL;
    PyObject *bitvecobj = NULL;
    PyObject *res = NULL;
    static PyObject *evenitem, *odditem;

    if (!PyArg_Parse(args, "(iiiii)", &info.format,
                     &info.width, &info.height,
                     &info.size, &info.samplingrate))
        return NULL;

    switch (info.format) {
    case SV_RGB8_FRAMES:
        bitvector = malloc(SV_BITVEC_SIZE(info.size));
        break;
    case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
        break;
    default:
        PyErr_SetString(SvError, "illegal format specified");
        return NULL;
    }

    if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
        res = sv_error();
        goto finally;
    }

    if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
        goto finally;

    /* XXX -- need to do something about the bitvector */
    {
        char* str = PyString_AsString(videodata);
        if (!str)
            goto finally;

        if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
            res = sv_error();
            goto finally;
        }
    }

    if (bitvector) {
        if (evenitem == NULL) {
            if (!(evenitem = PyInt_FromLong(0)))
                goto finally;
        }
        if (odditem == NULL) {
            if (!(odditem = PyInt_FromLong(1)))
                goto finally;
        }
        if (!(bitvecobj = PyTuple_New(2 * info.size)))
            goto finally;

        for (i = 0; i < 2 * info.size; i++) {
            int sts;

            if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
                Py_INCREF(evenitem);
                sts = PyTuple_SetItem(bitvecobj, i, evenitem);
            } else {
                Py_INCREF(odditem);
                sts = PyTuple_SetItem(bitvecobj, i, odditem);
            }
            if (sts < 0)
                goto finally;
        }
    } else {
        bitvecobj = Py_None;
        Py_INCREF(Py_None);
    }

    res = Py_BuildValue("((iiiii)OO)", info.format,
                        info.width, info.height,
                        info.size, info.samplingrate,
                        videodata, bitvecobj);

  finally:
    if (bitvector)
        free(bitvector);

    Py_XDECREF(videodata);
    Py_XDECREF(bitvecobj);
    return res;
}

static PyObject *
sv_CaptureOneFrame(svobject *self, PyObject *args)
{
    svCaptureInfo info;
    int format, width, height;
    int bytes;
    PyObject *videodata = NULL;
    PyObject *res = NULL;
    char *str;

    if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
        return NULL;

    info.format = format;
    info.width = width;
    info.height = height;
    info.size = 0;
    info.samplingrate = 0;
    if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
        return sv_error();

    if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
        return NULL;

    str = PyString_AsString(videodata);
    if (!str)
        goto finally;

    if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
        res = sv_error();
        goto finally;
    }

    res = Py_BuildValue("(iiO)", width, height, videodata);

  finally:
    Py_XDECREF(videodata);
    return res;
}

static PyObject *
sv_InitContinuousCapture(svobject *self, PyObject *args)
{
    svCaptureInfo info;

    if (!PyArg_Parse(args, "(iiiii)", &info.format,
                     &info.width, &info.height,
                     &info.size, &info.samplingrate))
        return NULL;

    if (svInitContinuousCapture(self->ob_svideo, &info))
        return sv_error();

    self->ob_info = info;

    return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
                         info.size, info.samplingrate);
}

static PyObject *
sv_LoadMap(svobject *self, PyObject *args)
{
    PyObject *rgb;
    PyObject *res = NULL;
    rgb_tuple *mapp = NULL;
    int maptype;
    int i, j;                                /* indices */

    if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
        return NULL;

    if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
        PyErr_BadArgument();
        return NULL;
    }

    if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
        return PyErr_NoMemory();

    for (i = 0; i < 256; i++) {
        PyObject* v = PyList_GetItem(rgb, i);
        if (!v)
            goto finally;

        if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
            PyErr_BadArgument();
            goto finally;
        }
        for (j = 0; j < 3; j++) {
            PyObject* cell = PyTuple_GetItem(v, j);
            if (!cell)
                goto finally;

            if (!PyInt_Check(cell) && !PyLong_Check(cell)) {
                PyErr_BadArgument();
                goto finally;
            }
            switch (j) {
            case 0: mapp[i].red = PyInt_AsLong(cell); break;
            case 1: mapp[i].blue = PyInt_AsLong(cell); break;
            case 2: mapp[i].green = PyInt_AsLong(cell); break;
            }
            if (PyErr_Occurred())
                goto finally;
        }
    }

    if (svLoadMap(self->ob_svideo, maptype, mapp)) {
        res = sv_error();
        goto finally;
    }

    Py_INCREF(Py_None);
    res = Py_None;

  finally:
    PyMem_DEL(mapp);
    return res;
}

static PyObject *
sv_CloseVideo(svobject *self, PyObject *args)
{
    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svCloseVideo(self->ob_svideo))
        return sv_error();

    self->ob_svideo = NULL;
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
doParams(svobject *self, PyObject *args,
         int (*func)(SV_nodeP, long *, int), int modified)
{
    PyObject *list;
    PyObject *res = NULL;
    long *PVbuffer = NULL;
    long length;
    int i;

    if (!PyArg_Parse(args, "O", &list))
        return NULL;

    if (!PyList_Check(list)) {
        PyErr_BadArgument();
        return NULL;
    }

    if ((length = PyList_Size(list)) < 0)
        return NULL;

    PVbuffer = PyMem_NEW(long, length);
    if (PVbuffer == NULL)
        return PyErr_NoMemory();

    for (i = 0; i < length; i++) {
        PyObject *v = PyList_GetItem(list, i);
        if (!v)
            goto finally;

        if (!PyInt_Check(v) && !PyLong_Check(v)) {
            PyErr_BadArgument();
            goto finally;
        }
        PVbuffer[i] = PyInt_AsLong(v);
        /* can't just test the return value, because what if the
           value was -1?!
        */
        if (PVbuffer[i] == -1 && PyErr_Occurred())
            goto finally;
    }

    if ((*func)(self->ob_svideo, PVbuffer, length)) {
        res = sv_error();
        goto finally;
    }

    if (modified) {
        for (i = 0; i < length; i++) {
            PyObject* v = PyInt_FromLong(PVbuffer[i]);
            if (!v || PyList_SetItem(list, i, v) < 0)
                goto finally;
        }
    }

    Py_INCREF(Py_None);
    res = Py_None;

  finally:
    PyMem_DEL(PVbuffer);
    return res;
}

static PyObject *
sv_GetParam(PyObject *self, PyObject *args)
{
    return doParams(self, args, svGetParam, 1);
}

static PyObject *
sv_GetParamRange(PyObject *self, PyObject *args)
{
    return doParams(self, args, svGetParamRange, 1);
}

static PyObject *
sv_SetParam(PyObject *self, PyObject *args)
{
    return doParams(self, args, svSetParam, 0);
}

static PyMethodDef svideo_methods[] = {
    {"BindGLWindow",            (PyCFunction)sv_BindGLWindow, METH_OLDARGS},
    {"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
    {"IsVideoDisplayed",        (PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
    {"OutputOffset",            (PyCFunction)sv_OutputOffset, METH_OLDARGS},
    {"PutFrame",                (PyCFunction)sv_PutFrame, METH_OLDARGS},
    {"QuerySize",               (PyCFunction)sv_QuerySize, METH_OLDARGS},
    {"SetSize",                 (PyCFunction)sv_SetSize, METH_OLDARGS},
    {"SetStdDefaults",          (PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
    {"UseExclusive",            (PyCFunction)sv_UseExclusive, METH_OLDARGS},
    {"WindowOffset",            (PyCFunction)sv_WindowOffset, METH_OLDARGS},
    {"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
    {"CaptureBurst",            (PyCFunction)sv_CaptureBurst, METH_OLDARGS},
    {"CaptureOneFrame",         (PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
    {"GetCaptureData",          (PyCFunction)sv_GetCaptureData, METH_OLDARGS},
    {"CloseVideo",              (PyCFunction)sv_CloseVideo, METH_OLDARGS},
    {"LoadMap",                 (PyCFunction)sv_LoadMap, METH_OLDARGS},
    {"GetParam",                (PyCFunction)sv_GetParam, METH_OLDARGS},
    {"GetParamRange",           (PyCFunction)sv_GetParamRange, METH_OLDARGS},
    {"SetParam",                (PyCFunction)sv_SetParam, METH_OLDARGS},
    {NULL,                      NULL}           /* sentinel */
};

static PyObject *
sv_conversion(PyObject *self, PyObject *args, void (*function)(),
              int inputfactor, float factor)
{
    int invert, width, height, inputlength;
    char *input, *str;
    PyObject *output;

    if (!PyArg_Parse(args, "(is#ii)", &invert,
                     &input, &inputlength, &width, &height))
        return NULL;

    if (width * height * inputfactor > inputlength) {
        PyErr_SetString(SvError, "input buffer not long enough");
        return NULL;
    }

    if (!(output = PyString_FromStringAndSize(NULL,
                                          (int)(width * height * factor))))
        return NULL;

    str = PyString_AsString(output);
    if (!str) {
        Py_DECREF(output);
        return NULL;
    }
    (*function)(invert, input, str, width, height);

    return output;
}

static PyObject *
sv_InterleaveFields(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

static PyObject *
sv_RGB8toRGB32(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}

static PyObject *
sv_YUVtoRGB(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}

static void
svideo_dealloc(svobject *self)
{
    if (self->ob_svideo != NULL)
        (void) svCloseVideo(self->ob_svideo);
    PyObject_Del(self);
}

static PyObject *
svideo_getattr(svobject *self, char *name)
{
    return Py_FindMethod(svideo_methods, (PyObject *)self, name);
}

PyTypeObject Svtype = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,                          /*ob_size*/
    "sv.sv",                    /*tp_name*/
    sizeof(svobject),           /*tp_size*/
    0,                          /*tp_itemsize*/
    /* methods */
    (destructor)svideo_dealloc, /*tp_dealloc*/
    0,                          /*tp_print*/
    (getattrfunc)svideo_getattr, /*tp_getattr*/
    0,                          /*tp_setattr*/
    0,                          /*tp_compare*/
    0,                          /*tp_repr*/
};

static PyObject *
newsvobject(SV_nodeP svp)
{
    svobject *p;

    p = PyObject_New(svobject, &Svtype);
    if (p == NULL)
        return NULL;
    p->ob_svideo = svp;
    p->ob_info.format = 0;
    p->ob_info.size = 0;
    p->ob_info.width = 0;
    p->ob_info.height = 0;
    p->ob_info.samplingrate = 0;
    return (PyObject *) p;
}

static PyObject *
sv_OpenVideo(PyObject *self, PyObject *args)
{
    SV_nodeP svp;

    if (!PyArg_Parse(args, ""))
        return NULL;

    svp = svOpenVideo();
    if (svp == NULL)
        return sv_error();

    return newsvobject(svp);
}

static PyMethodDef sv_methods[] = {
    {"InterleaveFields",        (PyCFunction)sv_InterleaveFields, METH_OLDARGS},
    {"RGB8toRGB32",             (PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
    {"YUVtoRGB",                (PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
    {"OpenVideo",               (PyCFunction)sv_OpenVideo, METH_OLDARGS},
    {NULL,                      NULL}   /* Sentinel */
};

void
initsv(void)
{
    PyObject *m, *d;

    if (PyErr_WarnPy3k("the sv module has been removed in "
                       "Python 3.0", 2) < 0)
        return;

    m = Py_InitModule("sv", sv_methods);
    if (m == NULL)
        return;
    d = PyModule_GetDict(m);

    SvError = PyErr_NewException("sv.error", NULL, NULL);
    if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
        return;
}
