/* 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_DECREF(self->ob_svideo);
        self->ob_svideo = NULL;
    }
    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)) {
                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)) {
            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;
}
