• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SV module -- interface to the Indigo video board */
2 
3 /* WARNING! This module is for hardware that we don't have any more,
4    so it hasn't been tested.  It has been converted to the new coding
5    style, and it is possible that this conversion has broken something
6    -- user beware! */
7 
8 #include <sys/time.h>
9 #include <svideo.h>
10 #include "Python.h"
11 #include "compile.h"
12 #include "yuv.h"                /* for YUV conversion functions */
13 
14 typedef struct {
15     PyObject_HEAD
16     SV_nodeP ob_svideo;
17     svCaptureInfo ob_info;
18 } svobject;
19 
20 typedef struct {
21     PyObject_HEAD
22     void *ob_capture;
23     int ob_mustunlock;
24     svCaptureInfo ob_info;
25     svobject *ob_svideo;
26 } captureobject;
27 
28 static PyObject *SvError;               /* exception sv.error */
29 
30 static PyObject *newcaptureobject(svobject *, void *, int);
31 
32 /* Set a SV-specific error from svideo_errno and return NULL */
33 static PyObject *
sv_error(void)34 sv_error(void)
35 {
36     PyErr_SetString(SvError, svStrerror(svideo_errno));
37     return NULL;
38 }
39 
40 static PyObject *
svc_conversion(captureobject * self,PyObject * args,void (* function)(),float factor)41 svc_conversion(captureobject *self, PyObject *args, void (*function)(), float factor)
42 {
43     PyObject *output;
44     int invert;
45     char* outstr;
46 
47     if (!PyArg_Parse(args, "i", &invert))
48         return NULL;
49 
50     if (!(output = PyString_FromStringAndSize(
51         NULL,
52         (int)(self->ob_info.width * self->ob_info.height * factor))))
53     {
54         return NULL;
55     }
56     if (!(outstr = PyString_AsString(output))) {
57         Py_DECREF(output);
58         return NULL;
59     }
60 
61     (*function)((boolean)invert, self->ob_capture,
62                 outstr,
63                 self->ob_info.width, self->ob_info.height);
64 
65     return output;
66 }
67 
68 /*
69  * 3 functions to convert from Starter Video YUV 4:1:1 format to
70  * Compression Library 4:2:2 Duplicate Chroma format.
71  */
72 static PyObject *
svc_YUVtoYUV422DC(captureobject * self,PyObject * args)73 svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
74 {
75     if (self->ob_info.format != SV_YUV411_FRAMES) {
76         PyErr_SetString(SvError, "data has bad format");
77         return NULL;
78     }
79     return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
80 }
81 
82 static PyObject *
svc_YUVtoYUV422DC_quarter(captureobject * self,PyObject * args)83 svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
84 {
85     if (self->ob_info.format != SV_YUV411_FRAMES) {
86         PyErr_SetString(SvError, "data has bad format");
87         return NULL;
88     }
89     return svc_conversion(self, args,
90                           yuv_sv411_to_cl422dc_quartersize, 0.5);
91 }
92 
93 static PyObject *
svc_YUVtoYUV422DC_sixteenth(captureobject * self,PyObject * args)94 svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
95 {
96     if (self->ob_info.format != SV_YUV411_FRAMES) {
97         PyErr_SetString(SvError, "data has bad format");
98         return NULL;
99     }
100     return svc_conversion(self, args,
101                           yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
102 }
103 
104 static PyObject *
svc_YUVtoRGB(captureobject * self,PyObject * args)105 svc_YUVtoRGB(captureobject *self, PyObject *args)
106 {
107     switch (self->ob_info.format) {
108     case SV_YUV411_FRAMES:
109     case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
110         break;
111     default:
112         PyErr_SetString(SvError, "data had bad format");
113         return NULL;
114     }
115     return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
116 }
117 
118 static PyObject *
svc_RGB8toRGB32(captureobject * self,PyObject * args)119 svc_RGB8toRGB32(captureobject *self, PyObject *args)
120 {
121     if (self->ob_info.format != SV_RGB8_FRAMES) {
122         PyErr_SetString(SvError, "data has bad format");
123         return NULL;
124     }
125     return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
126 }
127 
128 static PyObject *
svc_InterleaveFields(captureobject * self,PyObject * args)129 svc_InterleaveFields(captureobject *self, PyObject *args)
130 {
131     if (self->ob_info.format != SV_RGB8_FRAMES) {
132         PyErr_SetString(SvError, "data has bad format");
133         return NULL;
134     }
135     return svc_conversion(self, args, svInterleaveFields, 1.0);
136 }
137 
138 static PyObject *
svc_GetFields(captureobject * self,PyObject * args)139 svc_GetFields(captureobject *self, PyObject *args)
140 {
141     PyObject *f1 = NULL;
142     PyObject *f2 = NULL;
143     PyObject *ret = NULL;
144     int fieldsize;
145     char* obcapture;
146 
147     if (self->ob_info.format != SV_RGB8_FRAMES) {
148         PyErr_SetString(SvError, "data has bad format");
149         return NULL;
150     }
151 
152     fieldsize = self->ob_info.width * self->ob_info.height / 2;
153     obcapture = (char*)self->ob_capture;
154 
155     if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
156         goto finally;
157     if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
158                                           fieldsize)))
159         goto finally;
160     ret = PyTuple_Pack(2, f1, f2);
161 
162   finally:
163     Py_XDECREF(f1);
164     Py_XDECREF(f2);
165     return ret;
166 }
167 
168 static PyObject *
svc_UnlockCaptureData(captureobject * self,PyObject * args)169 svc_UnlockCaptureData(captureobject *self, PyObject *args)
170 {
171     if (!PyArg_Parse(args, ""))
172         return NULL;
173 
174     if (!self->ob_mustunlock) {
175         PyErr_SetString(SvError, "buffer should not be unlocked");
176         return NULL;
177     }
178 
179     if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
180         return sv_error();
181 
182     self->ob_mustunlock = 0;
183 
184     Py_INCREF(Py_None);
185     return Py_None;
186 }
187 
188 #ifdef USE_GL
189 #include <gl.h>
190 
191 static PyObject *
svc_lrectwrite(captureobject * self,PyObject * args)192 svc_lrectwrite(captureobject *self, PyObject *args)
193 {
194     Screencoord x1, x2, y1, y2;
195 
196     if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
197         return NULL;
198 
199     lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);
200 
201     Py_INCREF(Py_None);
202     return Py_None;
203 }
204 #endif
205 
206 static PyObject *
svc_writefile(captureobject * self,PyObject * args)207 svc_writefile(captureobject *self, PyObject *args)
208 {
209     PyObject *file;
210     int size;
211     FILE* fp;
212 
213     if (!PyArg_Parse(args, "O", &file))
214         return NULL;
215 
216     if (!PyFile_Check(file)) {
217         PyErr_SetString(SvError, "not a file object");
218         return NULL;
219     }
220 
221     if (!(fp = PyFile_AsFile(file)))
222         return NULL;
223 
224     size = self->ob_info.width * self->ob_info.height;
225 
226     if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
227         PyErr_SetString(SvError, "writing failed");
228         return NULL;
229     }
230 
231     Py_INCREF(Py_None);
232     return Py_None;
233 }
234 
235 static PyObject *
svc_FindVisibleRegion(captureobject * self,PyObject * args)236 svc_FindVisibleRegion(captureobject *self, PyObject *args)
237 {
238     void *visible;
239     int width;
240 
241     if (!PyArg_Parse(args, ""))
242         return NULL;
243 
244     if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
245                             self->ob_capture, &visible,
246                             self->ob_info.width))
247         return sv_error();
248 
249     if (visible == NULL) {
250         PyErr_SetString(SvError, "data in wrong format");
251         return NULL;
252     }
253 
254     return newcaptureobject(self->ob_svideo, visible, 0);
255 }
256 
257 static PyMethodDef capture_methods[] = {
258     {"YUVtoRGB",                (PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
259     {"RGB8toRGB32",             (PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
260     {"InterleaveFields",        (PyCFunction)svc_InterleaveFields, METH_OLDARGS},
261     {"UnlockCaptureData",       (PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
262     {"FindVisibleRegion",       (PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
263     {"GetFields",               (PyCFunction)svc_GetFields, METH_OLDARGS},
264     {"YUVtoYUV422DC",           (PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
265     {"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
266     {"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
267 #ifdef USE_GL
268     {"lrectwrite",              (PyCFunction)svc_lrectwrite, METH_OLDARGS},
269 #endif
270     {"writefile",               (PyCFunction)svc_writefile, METH_OLDARGS},
271     {NULL,                      NULL}           /* sentinel */
272 };
273 
274 static void
capture_dealloc(captureobject * self)275 capture_dealloc(captureobject *self)
276 {
277     if (self->ob_capture != NULL) {
278         if (self->ob_mustunlock)
279             (void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
280                                       self->ob_capture);
281         self->ob_capture = NULL;
282         Py_CLEAR(self->ob_svideo);
283     }
284     PyObject_Del(self);
285 }
286 
287 static PyObject *
capture_getattr(svobject * self,char * name)288 capture_getattr(svobject *self, char *name)
289 {
290     return Py_FindMethod(capture_methods, (PyObject *)self, name);
291 }
292 
293 PyTypeObject Capturetype = {
294     PyObject_HEAD_INIT(&PyType_Type)
295     0,                                  /*ob_size*/
296     "sv.capture",                       /*tp_name*/
297     sizeof(captureobject),              /*tp_size*/
298     0,                                  /*tp_itemsize*/
299     /* methods */
300     (destructor)capture_dealloc,        /*tp_dealloc*/
301     0,                                  /*tp_print*/
302     (getattrfunc)capture_getattr,       /*tp_getattr*/
303     0,                                  /*tp_setattr*/
304     0,                                  /*tp_compare*/
305     0,                                  /*tp_repr*/
306 };
307 
308 static PyObject *
newcaptureobject(svobject * self,void * ptr,int mustunlock)309 newcaptureobject(svobject *self, void *ptr, int mustunlock)
310 {
311     captureobject *p;
312 
313     p = PyObject_New(captureobject, &Capturetype);
314     if (p == NULL)
315         return NULL;
316     p->ob_svideo = self;
317     Py_INCREF(self);
318     p->ob_capture = ptr;
319     p->ob_mustunlock = mustunlock;
320     p->ob_info = self->ob_info;
321     return (PyObject *) p;
322 }
323 
324 static PyObject *
sv_GetCaptureData(svobject * self,PyObject * args)325 sv_GetCaptureData(svobject *self, PyObject *args)
326 {
327     void *ptr;
328     long fieldID;
329     PyObject *res, *c;
330 
331     if (!PyArg_Parse(args, ""))
332         return NULL;
333 
334     if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
335         return sv_error();
336 
337     if (ptr == NULL) {
338         PyErr_SetString(SvError, "no data available");
339         return NULL;
340     }
341 
342     c = newcaptureobject(self, ptr, 1);
343     if (c == NULL)
344         return NULL;
345     res = Py_BuildValue("(Oi)", c, fieldID);
346     Py_DECREF(c);
347     return res;
348 }
349 
350 static PyObject *
sv_BindGLWindow(svobject * self,PyObject * args)351 sv_BindGLWindow(svobject *self, PyObject *args)
352 {
353     long wid;
354     int mode;
355 
356     if (!PyArg_Parse(args, "(ii)", &wid, &mode))
357         return NULL;
358 
359     if (svBindGLWindow(self->ob_svideo, wid, mode))
360         return sv_error();
361 
362     Py_INCREF(Py_None);
363     return Py_None;
364 }
365 
366 static PyObject *
sv_EndContinuousCapture(svobject * self,PyObject * args)367 sv_EndContinuousCapture(svobject *self, PyObject *args)
368 {
369 
370     if (!PyArg_Parse(args, ""))
371         return NULL;
372 
373     if (svEndContinuousCapture(self->ob_svideo))
374         return sv_error();
375 
376     Py_INCREF(Py_None);
377     return Py_None;
378 }
379 
380 static PyObject *
sv_IsVideoDisplayed(svobject * self,PyObject * args)381 sv_IsVideoDisplayed(svobject *self, PyObject *args)
382 {
383     int v;
384 
385     if (!PyArg_Parse(args, ""))
386         return NULL;
387 
388     v = svIsVideoDisplayed(self->ob_svideo);
389     if (v == -1)
390         return sv_error();
391 
392     return PyInt_FromLong((long) v);
393 }
394 
395 static PyObject *
sv_OutputOffset(svobject * self,PyObject * args)396 sv_OutputOffset(svobject *self, PyObject *args)
397 {
398     int x_offset;
399     int y_offset;
400 
401     if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
402         return NULL;
403 
404     if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
405         return sv_error();
406 
407     Py_INCREF(Py_None);
408     return Py_None;
409 }
410 
411 static PyObject *
sv_PutFrame(svobject * self,PyObject * args)412 sv_PutFrame(svobject *self, PyObject *args)
413 {
414     char *buffer;
415 
416     if (!PyArg_Parse(args, "s", &buffer))
417         return NULL;
418 
419     if (svPutFrame(self->ob_svideo, buffer))
420         return sv_error();
421 
422     Py_INCREF(Py_None);
423     return Py_None;
424 }
425 
426 static PyObject *
sv_QuerySize(svobject * self,PyObject * args)427 sv_QuerySize(svobject *self, PyObject *args)
428 {
429     int w;
430     int h;
431     int rw;
432     int rh;
433 
434     if (!PyArg_Parse(args, "(ii)", &w, &h))
435         return NULL;
436 
437     if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
438         return sv_error();
439 
440     return Py_BuildValue("(ii)", (long) rw, (long) rh);
441 }
442 
443 static PyObject *
sv_SetSize(svobject * self,PyObject * args)444 sv_SetSize(svobject *self, PyObject *args)
445 {
446     int w;
447     int h;
448 
449     if (!PyArg_Parse(args, "(ii)", &w, &h))
450         return NULL;
451 
452     if (svSetSize(self->ob_svideo, w, h))
453         return sv_error();
454 
455     Py_INCREF(Py_None);
456     return Py_None;
457 }
458 
459 static PyObject *
sv_SetStdDefaults(svobject * self,PyObject * args)460 sv_SetStdDefaults(svobject *self, PyObject *args)
461 {
462 
463     if (!PyArg_Parse(args, ""))
464         return NULL;
465 
466     if (svSetStdDefaults(self->ob_svideo))
467         return sv_error();
468 
469     Py_INCREF(Py_None);
470     return Py_None;
471 }
472 
473 static PyObject *
sv_UseExclusive(svobject * self,PyObject * args)474 sv_UseExclusive(svobject *self, PyObject *args)
475 {
476     boolean onoff;
477     int mode;
478 
479     if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
480         return NULL;
481 
482     if (svUseExclusive(self->ob_svideo, onoff, mode))
483         return sv_error();
484 
485     Py_INCREF(Py_None);
486     return Py_None;
487 }
488 
489 static PyObject *
sv_WindowOffset(svobject * self,PyObject * args)490 sv_WindowOffset(svobject *self, PyObject *args)
491 {
492     int x_offset;
493     int y_offset;
494 
495     if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
496         return NULL;
497 
498     if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
499         return sv_error();
500 
501     Py_INCREF(Py_None);
502     return Py_None;
503 }
504 
505 static PyObject *
sv_CaptureBurst(svobject * self,PyObject * args)506 sv_CaptureBurst(svobject *self, PyObject *args)
507 {
508     int bytes, i;
509     svCaptureInfo info;
510     void *bitvector = NULL;
511     PyObject *videodata = NULL;
512     PyObject *bitvecobj = NULL;
513     PyObject *res = NULL;
514     static PyObject *evenitem, *odditem;
515 
516     if (!PyArg_Parse(args, "(iiiii)", &info.format,
517                      &info.width, &info.height,
518                      &info.size, &info.samplingrate))
519         return NULL;
520 
521     switch (info.format) {
522     case SV_RGB8_FRAMES:
523         bitvector = malloc(SV_BITVEC_SIZE(info.size));
524         break;
525     case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
526         break;
527     default:
528         PyErr_SetString(SvError, "illegal format specified");
529         return NULL;
530     }
531 
532     if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
533         res = sv_error();
534         goto finally;
535     }
536 
537     if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
538         goto finally;
539 
540     /* XXX -- need to do something about the bitvector */
541     {
542         char* str = PyString_AsString(videodata);
543         if (!str)
544             goto finally;
545 
546         if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
547             res = sv_error();
548             goto finally;
549         }
550     }
551 
552     if (bitvector) {
553         if (evenitem == NULL) {
554             if (!(evenitem = PyInt_FromLong(0)))
555                 goto finally;
556         }
557         if (odditem == NULL) {
558             if (!(odditem = PyInt_FromLong(1)))
559                 goto finally;
560         }
561         if (!(bitvecobj = PyTuple_New(2 * info.size)))
562             goto finally;
563 
564         for (i = 0; i < 2 * info.size; i++) {
565             int sts;
566 
567             if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
568                 Py_INCREF(evenitem);
569                 sts = PyTuple_SetItem(bitvecobj, i, evenitem);
570             } else {
571                 Py_INCREF(odditem);
572                 sts = PyTuple_SetItem(bitvecobj, i, odditem);
573             }
574             if (sts < 0)
575                 goto finally;
576         }
577     } else {
578         bitvecobj = Py_None;
579         Py_INCREF(Py_None);
580     }
581 
582     res = Py_BuildValue("((iiiii)OO)", info.format,
583                         info.width, info.height,
584                         info.size, info.samplingrate,
585                         videodata, bitvecobj);
586 
587   finally:
588     if (bitvector)
589         free(bitvector);
590 
591     Py_XDECREF(videodata);
592     Py_XDECREF(bitvecobj);
593     return res;
594 }
595 
596 static PyObject *
sv_CaptureOneFrame(svobject * self,PyObject * args)597 sv_CaptureOneFrame(svobject *self, PyObject *args)
598 {
599     svCaptureInfo info;
600     int format, width, height;
601     int bytes;
602     PyObject *videodata = NULL;
603     PyObject *res = NULL;
604     char *str;
605 
606     if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
607         return NULL;
608 
609     info.format = format;
610     info.width = width;
611     info.height = height;
612     info.size = 0;
613     info.samplingrate = 0;
614     if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
615         return sv_error();
616 
617     if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
618         return NULL;
619 
620     str = PyString_AsString(videodata);
621     if (!str)
622         goto finally;
623 
624     if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
625         res = sv_error();
626         goto finally;
627     }
628 
629     res = Py_BuildValue("(iiO)", width, height, videodata);
630 
631   finally:
632     Py_XDECREF(videodata);
633     return res;
634 }
635 
636 static PyObject *
sv_InitContinuousCapture(svobject * self,PyObject * args)637 sv_InitContinuousCapture(svobject *self, PyObject *args)
638 {
639     svCaptureInfo info;
640 
641     if (!PyArg_Parse(args, "(iiiii)", &info.format,
642                      &info.width, &info.height,
643                      &info.size, &info.samplingrate))
644         return NULL;
645 
646     if (svInitContinuousCapture(self->ob_svideo, &info))
647         return sv_error();
648 
649     self->ob_info = info;
650 
651     return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
652                          info.size, info.samplingrate);
653 }
654 
655 static PyObject *
sv_LoadMap(svobject * self,PyObject * args)656 sv_LoadMap(svobject *self, PyObject *args)
657 {
658     PyObject *rgb;
659     PyObject *res = NULL;
660     rgb_tuple *mapp = NULL;
661     int maptype;
662     int i, j;                                /* indices */
663 
664     if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
665         return NULL;
666 
667     if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
668         PyErr_BadArgument();
669         return NULL;
670     }
671 
672     if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
673         return PyErr_NoMemory();
674 
675     for (i = 0; i < 256; i++) {
676         PyObject* v = PyList_GetItem(rgb, i);
677         if (!v)
678             goto finally;
679 
680         if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
681             PyErr_BadArgument();
682             goto finally;
683         }
684         for (j = 0; j < 3; j++) {
685             PyObject* cell = PyTuple_GetItem(v, j);
686             if (!cell)
687                 goto finally;
688 
689             if (!_PyAnyInt_Check(cell)) {
690                 PyErr_BadArgument();
691                 goto finally;
692             }
693             switch (j) {
694             case 0: mapp[i].red = PyInt_AsLong(cell); break;
695             case 1: mapp[i].blue = PyInt_AsLong(cell); break;
696             case 2: mapp[i].green = PyInt_AsLong(cell); break;
697             }
698             if (PyErr_Occurred())
699                 goto finally;
700         }
701     }
702 
703     if (svLoadMap(self->ob_svideo, maptype, mapp)) {
704         res = sv_error();
705         goto finally;
706     }
707 
708     Py_INCREF(Py_None);
709     res = Py_None;
710 
711   finally:
712     PyMem_DEL(mapp);
713     return res;
714 }
715 
716 static PyObject *
sv_CloseVideo(svobject * self,PyObject * args)717 sv_CloseVideo(svobject *self, PyObject *args)
718 {
719     if (!PyArg_Parse(args, ""))
720         return NULL;
721 
722     if (svCloseVideo(self->ob_svideo))
723         return sv_error();
724 
725     self->ob_svideo = NULL;
726     Py_INCREF(Py_None);
727     return Py_None;
728 }
729 
730 static PyObject *
doParams(svobject * self,PyObject * args,int (* func)(SV_nodeP,long *,int),int modified)731 doParams(svobject *self, PyObject *args,
732          int (*func)(SV_nodeP, long *, int), int modified)
733 {
734     PyObject *list;
735     PyObject *res = NULL;
736     long *PVbuffer = NULL;
737     long length;
738     int i;
739 
740     if (!PyArg_Parse(args, "O", &list))
741         return NULL;
742 
743     if (!PyList_Check(list)) {
744         PyErr_BadArgument();
745         return NULL;
746     }
747 
748     if ((length = PyList_Size(list)) < 0)
749         return NULL;
750 
751     PVbuffer = PyMem_NEW(long, length);
752     if (PVbuffer == NULL)
753         return PyErr_NoMemory();
754 
755     for (i = 0; i < length; i++) {
756         PyObject *v = PyList_GetItem(list, i);
757         if (!v)
758             goto finally;
759 
760         if (!_PyAnyInt_Check(v)) {
761             PyErr_BadArgument();
762             goto finally;
763         }
764         PVbuffer[i] = PyInt_AsLong(v);
765         /* can't just test the return value, because what if the
766            value was -1?!
767         */
768         if (PVbuffer[i] == -1 && PyErr_Occurred())
769             goto finally;
770     }
771 
772     if ((*func)(self->ob_svideo, PVbuffer, length)) {
773         res = sv_error();
774         goto finally;
775     }
776 
777     if (modified) {
778         for (i = 0; i < length; i++) {
779             PyObject* v = PyInt_FromLong(PVbuffer[i]);
780             if (!v || PyList_SetItem(list, i, v) < 0)
781                 goto finally;
782         }
783     }
784 
785     Py_INCREF(Py_None);
786     res = Py_None;
787 
788   finally:
789     PyMem_DEL(PVbuffer);
790     return res;
791 }
792 
793 static PyObject *
sv_GetParam(PyObject * self,PyObject * args)794 sv_GetParam(PyObject *self, PyObject *args)
795 {
796     return doParams(self, args, svGetParam, 1);
797 }
798 
799 static PyObject *
sv_GetParamRange(PyObject * self,PyObject * args)800 sv_GetParamRange(PyObject *self, PyObject *args)
801 {
802     return doParams(self, args, svGetParamRange, 1);
803 }
804 
805 static PyObject *
sv_SetParam(PyObject * self,PyObject * args)806 sv_SetParam(PyObject *self, PyObject *args)
807 {
808     return doParams(self, args, svSetParam, 0);
809 }
810 
811 static PyMethodDef svideo_methods[] = {
812     {"BindGLWindow",            (PyCFunction)sv_BindGLWindow, METH_OLDARGS},
813     {"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
814     {"IsVideoDisplayed",        (PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
815     {"OutputOffset",            (PyCFunction)sv_OutputOffset, METH_OLDARGS},
816     {"PutFrame",                (PyCFunction)sv_PutFrame, METH_OLDARGS},
817     {"QuerySize",               (PyCFunction)sv_QuerySize, METH_OLDARGS},
818     {"SetSize",                 (PyCFunction)sv_SetSize, METH_OLDARGS},
819     {"SetStdDefaults",          (PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
820     {"UseExclusive",            (PyCFunction)sv_UseExclusive, METH_OLDARGS},
821     {"WindowOffset",            (PyCFunction)sv_WindowOffset, METH_OLDARGS},
822     {"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
823     {"CaptureBurst",            (PyCFunction)sv_CaptureBurst, METH_OLDARGS},
824     {"CaptureOneFrame",         (PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
825     {"GetCaptureData",          (PyCFunction)sv_GetCaptureData, METH_OLDARGS},
826     {"CloseVideo",              (PyCFunction)sv_CloseVideo, METH_OLDARGS},
827     {"LoadMap",                 (PyCFunction)sv_LoadMap, METH_OLDARGS},
828     {"GetParam",                (PyCFunction)sv_GetParam, METH_OLDARGS},
829     {"GetParamRange",           (PyCFunction)sv_GetParamRange, METH_OLDARGS},
830     {"SetParam",                (PyCFunction)sv_SetParam, METH_OLDARGS},
831     {NULL,                      NULL}           /* sentinel */
832 };
833 
834 static PyObject *
sv_conversion(PyObject * self,PyObject * args,void (* function)(),int inputfactor,float factor)835 sv_conversion(PyObject *self, PyObject *args, void (*function)(),
836               int inputfactor, float factor)
837 {
838     int invert, width, height, inputlength;
839     char *input, *str;
840     PyObject *output;
841 
842     if (!PyArg_Parse(args, "(is#ii)", &invert,
843                      &input, &inputlength, &width, &height))
844         return NULL;
845 
846     if (width * height * inputfactor > inputlength) {
847         PyErr_SetString(SvError, "input buffer not long enough");
848         return NULL;
849     }
850 
851     if (!(output = PyString_FromStringAndSize(NULL,
852                                           (int)(width * height * factor))))
853         return NULL;
854 
855     str = PyString_AsString(output);
856     if (!str) {
857         Py_DECREF(output);
858         return NULL;
859     }
860     (*function)(invert, input, str, width, height);
861 
862     return output;
863 }
864 
865 static PyObject *
sv_InterleaveFields(PyObject * self,PyObject * args)866 sv_InterleaveFields(PyObject *self, PyObject *args)
867 {
868     return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
869 }
870 
871 static PyObject *
sv_RGB8toRGB32(PyObject * self,PyObject * args)872 sv_RGB8toRGB32(PyObject *self, PyObject *args)
873 {
874     return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
875 }
876 
877 static PyObject *
sv_YUVtoRGB(PyObject * self,PyObject * args)878 sv_YUVtoRGB(PyObject *self, PyObject *args)
879 {
880     return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
881 }
882 
883 static void
svideo_dealloc(svobject * self)884 svideo_dealloc(svobject *self)
885 {
886     if (self->ob_svideo != NULL)
887         (void) svCloseVideo(self->ob_svideo);
888     PyObject_Del(self);
889 }
890 
891 static PyObject *
svideo_getattr(svobject * self,char * name)892 svideo_getattr(svobject *self, char *name)
893 {
894     return Py_FindMethod(svideo_methods, (PyObject *)self, name);
895 }
896 
897 PyTypeObject Svtype = {
898     PyObject_HEAD_INIT(&PyType_Type)
899     0,                          /*ob_size*/
900     "sv.sv",                    /*tp_name*/
901     sizeof(svobject),           /*tp_size*/
902     0,                          /*tp_itemsize*/
903     /* methods */
904     (destructor)svideo_dealloc, /*tp_dealloc*/
905     0,                          /*tp_print*/
906     (getattrfunc)svideo_getattr, /*tp_getattr*/
907     0,                          /*tp_setattr*/
908     0,                          /*tp_compare*/
909     0,                          /*tp_repr*/
910 };
911 
912 static PyObject *
newsvobject(SV_nodeP svp)913 newsvobject(SV_nodeP svp)
914 {
915     svobject *p;
916 
917     p = PyObject_New(svobject, &Svtype);
918     if (p == NULL)
919         return NULL;
920     p->ob_svideo = svp;
921     p->ob_info.format = 0;
922     p->ob_info.size = 0;
923     p->ob_info.width = 0;
924     p->ob_info.height = 0;
925     p->ob_info.samplingrate = 0;
926     return (PyObject *) p;
927 }
928 
929 static PyObject *
sv_OpenVideo(PyObject * self,PyObject * args)930 sv_OpenVideo(PyObject *self, PyObject *args)
931 {
932     SV_nodeP svp;
933 
934     if (!PyArg_Parse(args, ""))
935         return NULL;
936 
937     svp = svOpenVideo();
938     if (svp == NULL)
939         return sv_error();
940 
941     return newsvobject(svp);
942 }
943 
944 static PyMethodDef sv_methods[] = {
945     {"InterleaveFields",        (PyCFunction)sv_InterleaveFields, METH_OLDARGS},
946     {"RGB8toRGB32",             (PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
947     {"YUVtoRGB",                (PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
948     {"OpenVideo",               (PyCFunction)sv_OpenVideo, METH_OLDARGS},
949     {NULL,                      NULL}   /* Sentinel */
950 };
951 
952 void
initsv(void)953 initsv(void)
954 {
955     PyObject *m, *d;
956 
957     if (PyErr_WarnPy3k("the sv module has been removed in "
958                        "Python 3.0", 2) < 0)
959         return;
960 
961     m = Py_InitModule("sv", sv_methods);
962     if (m == NULL)
963         return;
964     d = PyModule_GetDict(m);
965 
966     SvError = PyErr_NewException("sv.error", NULL, NULL);
967     if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
968         return;
969 }
970