/**********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* 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 Py_PROTO((svobject *, void *, int));

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

static PyObject *
svc_conversion(self, args, function, factor)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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 = Py_BuildValue("(OO)", f1, f2);

  finally:
	Py_XDECREF(f1);
	Py_XDECREF(f2);
	return ret;
}
	
static PyObject *
svc_UnlockCaptureData(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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},
	{"RGB8toRGB32",		(PyCFunction)svc_RGB8toRGB32},
	{"InterleaveFields",	(PyCFunction)svc_InterleaveFields},
	{"UnlockCaptureData",	(PyCFunction)svc_UnlockCaptureData},
	{"FindVisibleRegion",	(PyCFunction)svc_FindVisibleRegion},
	{"GetFields",		(PyCFunction)svc_GetFields},
	{"YUVtoYUV422DC",	(PyCFunction)svc_YUVtoYUV422DC},
	{"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter},
	{"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth},
#ifdef USE_GL
	{"lrectwrite",		(PyCFunction)svc_lrectwrite},
#endif
	{"writefile",		(PyCFunction)svc_writefile},
	{NULL,			NULL} 		/* sentinel */
};

static void
capture_dealloc(self)
	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;
	}
	PyMem_DEL(self);
}

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

PyTypeObject Capturetype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"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(self, ptr, mustunlock)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args)
	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(self, args, func, modified)
	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(self, args)
	PyObject *self, *args;
{
	return doParams(self, args, svGetParam, 1);
}

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

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

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

static PyObject *
sv_conversion(self, args, function, inputfactor, factor)
	PyObject *self, *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(self, args)
	PyObject *self, *args;
{
	return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

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

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

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

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

PyTypeObject Svtype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,			/*ob_size*/
	"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(svp)
	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(self, args)
	PyObject *self, *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},
	{"RGB8toRGB32",		(PyCFunction)sv_RGB8toRGB32},
	{"YUVtoRGB",		(PyCFunction)sv_YUVtoRGB},
	{"OpenVideo",		(PyCFunction)sv_OpenVideo},
	{NULL,			NULL}	/* Sentinel */
};

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

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

	SvError = PyString_FromString("sv.error");
	if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
		Py_FatalError("can't define sv.error");
}
