]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/interfaces/python/cv.cpp
numpy support
[opencv.git] / opencv / interfaces / python / cv.cpp
1 #include <Python.h>
2
3 #include <assert.h>
4
5 #include <opencv/cxcore.h>
6 #include <opencv/cv.h>
7 #include <opencv/cvaux.h>
8 #include <opencv/cvwimage.h>
9 #include <opencv/highgui.h>
10
11 #define MODULESTR "cv"
12
13 #define PYTHON_NUMPY 1
14
15 static PyObject *opencv_error;
16
17 struct memtrack_t {
18   PyObject_HEAD
19   void *ptr;
20   Py_ssize_t size;
21 };
22
23 struct iplimage_t {
24   PyObject_HEAD
25   IplImage *a;
26   PyObject *data;
27   size_t offset;
28 };
29
30 struct cvmat_t {
31   PyObject_HEAD
32   CvMat *a;
33   PyObject *data;
34   size_t offset;
35 };
36
37 struct cvmatnd_t {
38   PyObject_HEAD
39   CvMatND *a;
40   PyObject *data;
41   size_t offset;
42 };
43
44 struct cvhistogram_t {
45   PyObject_HEAD
46   CvHistogram h;
47   PyObject *bins;
48 };
49
50 struct cvmemstorage_t {
51   PyObject_HEAD
52   CvMemStorage *a;
53 };
54
55 struct cvseq_t {
56   PyObject_HEAD
57   CvSeq *a;
58   PyObject *container;  // Containing cvmemstorage_t
59 };
60
61 struct cvset_t {
62   PyObject_HEAD
63   CvSet *a;
64   PyObject *container;  // Containing cvmemstorage_t
65   int i;
66 };
67
68 struct cvsubdiv2d_t {
69   PyObject_HEAD
70   CvSubdiv2D *a;
71   PyObject *container;  // Containing cvmemstorage_t
72 };
73
74 struct cvsubdiv2dpoint_t {
75   PyObject_HEAD
76   CvSubdiv2DPoint *a;
77   PyObject *container;  // Containing cvmemstorage_t
78 };
79
80 struct cvsubdiv2dedge_t {
81   PyObject_HEAD
82   CvSubdiv2DEdge a;
83   PyObject *container;  // Containing cvmemstorage_t
84 };
85
86 struct cvlineiterator_t {
87   PyObject_HEAD
88   CvLineIterator iter;
89   int count;
90   int type;
91 };
92
93 struct iplconvkernel_t {
94   PyObject_HEAD
95   IplConvKernel *a;
96 };
97
98 struct cvcapture_t {
99   PyObject_HEAD
100   CvCapture *a;
101 };
102
103 struct cvvideowriter_t {
104   PyObject_HEAD
105   CvVideoWriter *a;
106 };
107
108 typedef IplImage ROIplImage;
109
110 struct cvmoments_t {
111   PyObject_HEAD
112   CvMoments a;
113 };
114
115 struct cvfont_t {
116   PyObject_HEAD
117   CvFont a;
118 };
119
120 struct cvhaarclassifiercascade_t {
121   PyObject_HEAD
122   CvHaarClassifierCascade *a;
123 };
124
125 struct cvcontourtree_t {
126   PyObject_HEAD
127   CvContourTree *a;
128 };
129
130 struct cvpositobject_t {
131   PyObject_HEAD
132   CvPOSITObject *a;
133 };
134
135 struct cvrng_t {
136   PyObject_HEAD
137   CvRNG a;
138 };
139
140 static int is_iplimage(PyObject *o);
141 static int is_cvmat(PyObject *o);
142 static int is_cvmatnd(PyObject *o);
143 static int convert_to_CvArr(PyObject *o, CvArr **dst, const char *name = "no_name");
144 static int convert_to_IplImage(PyObject *o, IplImage **dst, const char *name = "no_name");
145 static int convert_to_CvMat(PyObject *o, CvMat **dst, const char *name = "no_name");
146 static int convert_to_CvMatND(PyObject *o, CvMatND **dst, const char *name = "no_name");
147 static PyObject *what_data(PyObject *o);
148
149 static void translate_error_to_exception(void)
150 {
151   PyErr_SetString(opencv_error, cvErrorStr(cvGetErrStatus()));
152   cvSetErrStatus(0);
153 }
154
155 #define ERRCHK do { if (cvGetErrStatus() != 0) { translate_error_to_exception(); return NULL; } } while (0)
156 #define ERRWRAP(F) \
157     do { \
158         try \
159         { \
160             F; \
161         } \
162         catch (const cv::Exception &e) \
163         { \
164            PyErr_SetString(opencv_error, e.err.c_str()); \
165            return NULL; \
166         } \
167         ERRCHK; \
168     } while(0)
169
170 /************************************************************************/
171
172 static int failmsg(const char *fmt, ...)
173 {
174   char str[1000];
175
176   va_list ap;
177   va_start(ap, fmt);
178   vsnprintf(str, sizeof(str), fmt, ap);
179   va_end(ap);
180
181   PyErr_SetString(PyExc_TypeError, str);
182   return 0;
183 }
184
185 /************************************************************************/
186
187 /* These get/setters are polymorphic, used in both iplimage and cvmat */
188
189 static PyObject *PyObject_FromCvScalar(CvScalar s, int type)
190 {
191   int i, spe = CV_MAT_CN(type);
192   PyObject *r;
193   if (spe > 1) {
194     r = PyTuple_New(spe);
195     for (i = 0; i < spe; i++)
196       PyTuple_SET_ITEM(r, i, PyFloat_FromDouble(s.val[i]));
197   } else {
198     r = PyFloat_FromDouble(s.val[0]);
199   }
200   return r;
201 }
202
203 static PyObject *cvarr_GetItem(PyObject *o, PyObject *key);
204 static int cvarr_SetItem(PyObject *o, PyObject *key, PyObject *v);
205
206 // o is a Python string or buffer object.  Return its size.
207
208 static Py_ssize_t what_size(PyObject *o)
209 {
210   void *buffer;
211   Py_ssize_t buffer_len;
212
213   if (PyString_Check(o)) {
214     return PyString_Size(o);
215   } else if (PyObject_AsWriteBuffer(o, &buffer, &buffer_len) == 0) {
216     return buffer_len;
217   } else {
218     assert(0);  // argument must be string or buffer.
219     return 0;
220   }
221 }
222
223
224 /************************************************************************/
225
226 /* iplimage */
227
228 static void iplimage_dealloc(PyObject *self)
229 {
230   iplimage_t *pc = (iplimage_t*)self;
231   cvReleaseImageHeader((IplImage**)&pc->a);
232   Py_DECREF(pc->data);
233   PyObject_Del(self);
234 }
235
236 static PyObject *iplimage_repr(PyObject *self)
237 {
238   iplimage_t *cva = (iplimage_t*)self;
239   IplImage* ipl = (IplImage*)(cva->a);
240   char str[1000];
241   sprintf(str, "<iplimage(");
242   char *d = str + strlen(str);
243   sprintf(d, "nChannels=%d ", ipl->nChannels);
244   d += strlen(d);
245   sprintf(d, "width=%d ", ipl->width);
246   d += strlen(d);
247   sprintf(d, "height=%d ", ipl->height);
248   d += strlen(d);
249   sprintf(d, "widthStep=%d ", ipl->widthStep);
250   d += strlen(d);
251   sprintf(d, ")>");
252   return PyString_FromString(str);
253 }
254
255 static PyObject *iplimage_tostring(PyObject *self, PyObject *args)
256 {
257   iplimage_t *pc = (iplimage_t*)self;
258   IplImage *i;
259   if (!convert_to_IplImage(self, &i, "self"))
260     return NULL;
261   if (i == NULL)
262     return NULL;
263   int bps;
264   switch (i->depth) {
265   case IPL_DEPTH_8U:
266   case IPL_DEPTH_8S:
267     bps = 1;
268     break;
269   case IPL_DEPTH_16U:
270   case IPL_DEPTH_16S:
271     bps = 2;
272     break;
273   case IPL_DEPTH_32S:
274   case IPL_DEPTH_32F:
275     bps = 4;
276     break;
277   case IPL_DEPTH_64F:
278     bps = 8;
279     break;
280   default:
281     return (PyObject*)failmsg("Unrecognised depth %d", i->depth);
282   }
283   int bpl = i->width * i->nChannels * bps;
284   if (PyString_Check(pc->data) && bpl == i->widthStep && pc->offset == 0 && ((bpl * i->height) == what_size(pc->data))) {
285     Py_INCREF(pc->data);
286     return pc->data;
287   } else {
288     int l = bpl * i->height;
289     char *s = new char[l];
290     int y;
291     for (y = 0; y < i->height; y++) {
292       memcpy(s + y * bpl, i->imageData + y * i->widthStep, bpl);
293     }
294     PyObject *r = PyString_FromStringAndSize(s, l);
295     delete s;
296     return r;
297   }
298 }
299
300 static struct PyMethodDef iplimage_methods[] =
301 {
302   {"tostring", iplimage_tostring, METH_VARARGS},
303   {NULL,          NULL}
304 };
305
306 static PyObject *iplimage_getnChannels(iplimage_t *cva)
307 {
308   return PyInt_FromLong(((IplImage*)(cva->a))->nChannels);
309 }
310 static PyObject *iplimage_getwidth(iplimage_t *cva)
311 {
312   return PyInt_FromLong(((IplImage*)(cva->a))->width);
313 }
314 static PyObject *iplimage_getheight(iplimage_t *cva)
315 {
316   return PyInt_FromLong(((IplImage*)(cva->a))->height);
317 }
318 static PyObject *iplimage_getdepth(iplimage_t *cva)
319 {
320   return PyLong_FromUnsignedLong((unsigned)((IplImage*)(cva->a))->depth);
321 }
322 static PyObject *iplimage_getorigin(iplimage_t *cva)
323 {
324   return PyInt_FromLong(((IplImage*)(cva->a))->origin);
325 }
326 static void iplimage_setorigin(iplimage_t *cva, PyObject *v)
327 {
328   ((IplImage*)(cva->a))->origin = PyInt_AsLong(v);
329 }
330
331 static PyGetSetDef iplimage_getseters[] = {
332   {(char*)"nChannels", (getter)iplimage_getnChannels, (setter)NULL, (char*)"nChannels", NULL},
333   {(char*)"width", (getter)iplimage_getwidth, (setter)NULL, (char*)"width", NULL},
334   {(char*)"height", (getter)iplimage_getheight, (setter)NULL, (char*)"height", NULL},
335   {(char*)"depth", (getter)iplimage_getdepth, (setter)NULL, (char*)"depth", NULL},
336   {(char*)"origin", (getter)iplimage_getorigin, (setter)iplimage_setorigin, (char*)"origin", NULL},
337   {NULL}  /* Sentinel */
338 };
339
340 static PyMappingMethods iplimage_as_map = {
341   NULL,
342   &cvarr_GetItem,
343   &cvarr_SetItem,
344 };
345
346 static PyTypeObject iplimage_Type = {
347   PyObject_HEAD_INIT(&PyType_Type)
348   0,                                      /*size*/
349   MODULESTR".iplimage",                          /*name*/
350   sizeof(iplimage_t),                        /*basicsize*/
351 };
352
353 static void iplimage_specials(void)
354 {
355   iplimage_Type.tp_dealloc = iplimage_dealloc;
356   iplimage_Type.tp_as_mapping = &iplimage_as_map;
357   iplimage_Type.tp_repr = iplimage_repr;
358   iplimage_Type.tp_methods = iplimage_methods;
359   iplimage_Type.tp_getset = iplimage_getseters;
360 }
361
362 static int is_iplimage(PyObject *o)
363 {
364   return PyType_IsSubtype(o->ob_type, &iplimage_Type);
365 }
366
367 /************************************************************************/
368
369 /* cvmat */
370
371 static void cvmat_dealloc(PyObject *self)
372 {
373   cvmat_t *pc = (cvmat_t*)self;
374   Py_DECREF(pc->data);
375   cvFree((void**)&pc->a);
376   PyObject_Del(self);
377 }
378
379 static PyObject *cvmat_repr(PyObject *self)
380 {
381   CvMat *m = ((cvmat_t*)self)->a;
382   char str[1000];
383   sprintf(str, "<cvmat(");
384   char *d = str + strlen(str);
385   sprintf(d, "type=%08x ", m->type);
386   d += strlen(d);
387   sprintf(d, "rows=%d ", m->rows);
388   d += strlen(d);
389   sprintf(d, "cols=%d ", m->cols);
390   d += strlen(d);
391   sprintf(d, "step=%d ", m->step);
392   d += strlen(d);
393   sprintf(d, ")>");
394   return PyString_FromString(str);
395 }
396
397 static PyObject *cvmat_tostring(PyObject *self, PyObject *args)
398 {
399   CvMat *m;
400   if (!convert_to_CvMat(self, &m, "self"))
401     return NULL;
402
403   int bps;                     // bytes per sample
404
405   switch (CV_MAT_DEPTH(m->type)) {
406   case CV_8U:
407   case CV_8S:
408     bps = CV_MAT_CN(m->type) * 1;
409     break;
410   case CV_16U:
411   case CV_16S:
412     bps = CV_MAT_CN(m->type) * 2;
413     break;
414   case CV_32S:
415   case CV_32F:
416     bps = CV_MAT_CN(m->type) * 4;
417     break;
418   case CV_64F:
419     bps = CV_MAT_CN(m->type) * 8;
420     break;
421   default:
422     return (PyObject*)failmsg("Unrecognised depth %d", CV_MAT_DEPTH(m->type));
423   }
424
425   int bpl = m->cols * bps; // bytes per line
426   cvmat_t *pc = (cvmat_t*)self;
427   if (PyString_Check(pc->data) && bpl == m->step && pc->offset == 0 && ((bpl * m->rows) == what_size(pc->data))) {
428     Py_INCREF(pc->data);
429     return pc->data;
430   } else {
431     int l = bpl * m->rows;
432     char *s = new char[l];
433     int y;
434     for (y = 0; y < m->rows; y++) {
435       memcpy(s + y * bpl, m->data.ptr + y * m->step, bpl);
436     }
437     PyObject *r = PyString_FromStringAndSize(s, l);
438     delete s;
439     return r;
440   }
441 }
442
443 static struct PyMethodDef cvmat_methods[] =
444 {
445   {"tostring", cvmat_tostring, METH_VARARGS},
446   {NULL,          NULL}
447 };
448
449 static PyObject *cvmat_gettype(cvmat_t *cva)
450 {
451   return PyInt_FromLong(cvGetElemType(cva->a));
452 }
453
454 static PyObject *cvmat_getstep(cvmat_t *cva)
455 {
456   return PyInt_FromLong(cva->a->step);
457 }
458
459 static PyObject *cvmat_getrows(cvmat_t *cva)
460 {
461   return PyInt_FromLong(cva->a->rows);
462 }
463
464 static PyObject *cvmat_getcols(cvmat_t *cva)
465 {
466   return PyInt_FromLong(cva->a->cols);
467 }
468
469 #if PYTHON_NUMPY
470 #include "numpy/ndarrayobject.h"
471
472 // A PyArrayInterface, with an associated python object that should be DECREF'ed on release
473 struct arrayTrack {
474   PyArrayInterface s;
475   PyObject *o;
476 };
477
478 static void arrayTrackDtor(void *p)
479 {
480   struct arrayTrack *at = (struct arrayTrack *)p;
481   delete at->s.shape;
482   delete at->s.strides;
483   if (at->s.descr)
484     Py_DECREF(at->s.descr);
485   Py_DECREF(at->o);
486 }
487
488 // Fill in fields of PyArrayInterface s using mtype.  This code is common
489 // to cvmat and cvmatnd
490
491 static void arrayinterface_common(PyArrayInterface *s, int mtype)
492 {
493   s->two = 2;
494
495   switch (CV_MAT_DEPTH(mtype)) {
496   case CV_8U:
497     s->typekind = 'u';
498     s->itemsize = 1;
499     break;
500   case CV_8S:
501     s->typekind = 'i';
502     s->itemsize = 1;
503     break;
504   case CV_16U:
505     s->typekind = 'u';
506     s->itemsize = 2;
507     break;
508   case CV_16S:
509     s->typekind = 'i';
510     s->itemsize = 2;
511     break;
512   case CV_32S:
513     s->typekind = 'i';
514     s->itemsize = 4;
515     break;
516   case CV_32F:
517     s->typekind = 'f';
518     s->itemsize = 4;
519     break;
520   case CV_64F:
521     s->typekind = 'f';
522     s->itemsize = 8;
523     break;
524   default:
525     assert(0);
526   }
527
528   s->flags = NPY_WRITEABLE | NPY_NOTSWAPPED;
529 }
530
531 static PyObject *cvmat_array_struct(cvmat_t *cva)
532 {
533   CvMat *m;
534   convert_to_CvMat((PyObject *)cva, &m, "");
535
536   arrayTrack *at = new arrayTrack;
537   PyArrayInterface *s = &at->s;
538
539   at->o = cva->data;
540   Py_INCREF(at->o);
541
542   arrayinterface_common(s, m->type);
543
544   if (CV_MAT_CN(m->type) == 1) {
545     s->nd = 2;
546     s->shape = new npy_intp[2];
547     s->shape[0] = m->rows;
548     s->shape[1] = m->cols;
549     s->strides = new npy_intp[2];
550     s->strides[0] = m->step;
551     s->strides[1] = s->itemsize;
552   } else {
553     s->nd = 3;
554     s->shape = new npy_intp[3];
555     s->shape[0] = m->rows;
556     s->shape[1] = m->cols;
557     s->shape[2] = CV_MAT_CN(m->type);
558     s->strides = new npy_intp[3];
559     s->strides[0] = m->step;
560     s->strides[1] = s->itemsize * CV_MAT_CN(m->type);
561     s->strides[2] = s->itemsize;
562   }
563   s->data = (void*)(m->data.ptr);
564   s->descr = PyList_New(1);
565   char typestr[10];
566   sprintf(typestr, "<%c%d", s->typekind, s->itemsize);
567   PyList_SetItem(s->descr, 0, Py_BuildValue("(ss)", "x", typestr));
568
569   return PyCObject_FromVoidPtr(s, arrayTrackDtor);
570 }
571
572 static PyObject *cvmatnd_array_struct(cvmatnd_t *cva)
573 {
574   CvMatND *m;
575   convert_to_CvMatND((PyObject *)cva, &m, "");
576
577   arrayTrack *at = new arrayTrack;
578   PyArrayInterface *s = &at->s;
579
580   at->o = cva->data;
581   Py_INCREF(at->o);
582
583   arrayinterface_common(s, m->type);
584
585   int i;
586   if (CV_MAT_CN(m->type) == 1) {
587     s->nd = m->dims;
588     s->shape = new npy_intp[s->nd];
589     for (i = 0; i < s->nd; i++)
590       s->shape[i] = m->dim[i].size;
591     s->strides = new npy_intp[s->nd];
592     for (i = 0; i < (s->nd - 1); i++)
593       s->strides[i] = m->dim[i].step;
594     s->strides[s->nd - 1] = s->itemsize;
595   } else {
596     s->nd = m->dims + 1;
597     s->shape = new npy_intp[s->nd];
598     for (i = 0; i < (s->nd - 1); i++)
599       s->shape[i] = m->dim[i].size;
600     s->shape[s->nd - 1] = CV_MAT_CN(m->type);
601
602     s->strides = new npy_intp[s->nd];
603     for (i = 0; i < (s->nd - 2); i++)
604       s->strides[i] = m->dim[i].step;
605     s->strides[s->nd - 2] = s->itemsize * CV_MAT_CN(m->type);
606     s->strides[s->nd - 1] = s->itemsize;
607   }
608   s->data = (void*)(m->data.ptr);
609   s->descr = PyList_New(1);
610   char typestr[10];
611   sprintf(typestr, "<%c%d", s->typekind, s->itemsize);
612   PyList_SetItem(s->descr, 0, Py_BuildValue("(ss)", "x", typestr));
613
614   return PyCObject_FromVoidPtr(s, arrayTrackDtor);
615 }
616 #endif
617
618 static PyGetSetDef cvmat_getseters[] = {
619   {(char*)"type",   (getter)cvmat_gettype, (setter)NULL, (char*)"type",   NULL},
620   {(char*)"step",   (getter)cvmat_getstep, (setter)NULL, (char*)"step",   NULL},
621   {(char*)"rows",   (getter)cvmat_getrows, (setter)NULL, (char*)"rows",   NULL},
622   {(char*)"cols",   (getter)cvmat_getcols, (setter)NULL, (char*)"cols",   NULL},
623   {(char*)"width",  (getter)cvmat_getcols, (setter)NULL, (char*)"width",  NULL},
624   {(char*)"height", (getter)cvmat_getrows, (setter)NULL, (char*)"height", NULL},
625 #if PYTHON_NUMPY
626   {(char*)"__array_struct__", (getter)cvmat_array_struct, (setter)NULL, (char*)"__array_struct__", NULL},
627 #endif
628   {NULL}  /* Sentinel */
629 };
630
631 static PyMappingMethods cvmat_as_map = {
632   NULL,
633   &cvarr_GetItem,
634   &cvarr_SetItem,
635 };
636
637 static PyTypeObject cvmat_Type = {
638   PyObject_HEAD_INIT(&PyType_Type)
639   0,                                      /*size*/
640   MODULESTR".cvmat",                      /*name*/
641   sizeof(cvmat_t),                        /*basicsize*/
642 };
643
644 static void cvmat_specials(void)
645 {
646   cvmat_Type.tp_dealloc = cvmat_dealloc;
647   cvmat_Type.tp_as_mapping = &cvmat_as_map;
648   cvmat_Type.tp_repr = cvmat_repr;
649   cvmat_Type.tp_methods = cvmat_methods;
650   cvmat_Type.tp_getset = cvmat_getseters;
651 }
652
653 static int is_cvmat(PyObject *o)
654 {
655   return PyType_IsSubtype(o->ob_type, &cvmat_Type);
656 }
657
658 /************************************************************************/
659
660 /* cvmatnd */
661
662 static void cvmatnd_dealloc(PyObject *self)
663 {
664   cvmatnd_t *pc = (cvmatnd_t*)self;
665   Py_DECREF(pc->data);
666   PyObject_Del(self);
667 }
668
669 static PyObject *cvmatnd_repr(PyObject *self)
670 {
671   CvMatND *m = ((cvmatnd_t*)self)->a;
672   char str[1000];
673   sprintf(str, "<cvmatnd(");
674   char *d = str + strlen(str);
675   sprintf(d, "type=%08x ", m->type);
676   d += strlen(d);
677   sprintf(d, ")>");
678   return PyString_FromString(str);
679 }
680
681 static size_t cvmatnd_size(CvMatND *m)
682 {
683   int bps;
684   switch (CV_MAT_DEPTH(m->type)) {
685   case CV_8U:
686   case CV_8S:
687     bps = CV_MAT_CN(m->type) * 1;
688     break;
689   case CV_16U:
690   case CV_16S:
691     bps = CV_MAT_CN(m->type) * 2;
692     break;
693   case CV_32S:
694   case CV_32F:
695     bps = CV_MAT_CN(m->type) * 4;
696     break;
697   case CV_64F:
698     bps = CV_MAT_CN(m->type) * 8;
699     break;
700   default:
701     assert(0);
702   }
703   size_t l = bps;
704   for (int d = 0; d < m->dims; d++) {
705     l *= m->dim[d].size;
706   }
707   return l;
708 }
709
710 static PyObject *cvmatnd_tostring(PyObject *self, PyObject *args)
711 {
712   CvMatND *m;
713   if (!convert_to_CvMatND(self, &m, "self"))
714     return NULL;
715
716   int bps;
717   switch (CV_MAT_DEPTH(m->type)) {
718   case CV_8U:
719   case CV_8S:
720     bps = CV_MAT_CN(m->type) * 1;
721     break;
722   case CV_16U:
723   case CV_16S:
724     bps = CV_MAT_CN(m->type) * 2;
725     break;
726   case CV_32S:
727   case CV_32F:
728     bps = CV_MAT_CN(m->type) * 4;
729     break;
730   case CV_64F:
731     bps = CV_MAT_CN(m->type) * 8;
732     break;
733   default:
734     return (PyObject*)failmsg("Unrecognised depth %d", CV_MAT_DEPTH(m->type));
735   }
736
737   int l = bps;
738   for (int d = 0; d < m->dims; d++) {
739     l *= m->dim[d].size;
740   }
741   int i[CV_MAX_DIM];
742   int d;
743   for (d = 0; d < m->dims; d++) {
744     i[d] = 0;
745   }
746   int rowsize = m->dim[m->dims-1].size * bps;
747   char *s = new char[l];
748   char *ps = s;
749
750   int finished = 0;
751   while (!finished) {
752     memcpy(ps, cvPtrND(m, i), rowsize);
753     ps += rowsize;
754     for (d = m->dims - 2; 0 <= d; d--) {
755       if (++i[d] < cvGetDimSize(m, d)) {
756         break;
757       } else {
758         i[d] = 0;
759       }
760     }
761     if (d < 0)
762       finished = 1;
763   }
764
765   return PyString_FromStringAndSize(s, ps - s);
766 }
767
768 static struct PyMethodDef cvmatnd_methods[] =
769 {
770   {"tostring", cvmatnd_tostring, METH_VARARGS},
771   {NULL,          NULL}
772 };
773
774 static PyGetSetDef cvmatnd_getseters[] = {
775 #if PYTHON_NUMPY
776   {(char*)"__array_struct__", (getter)cvmatnd_array_struct, (setter)NULL, (char*)"__array_struct__", NULL},
777 #endif
778   {NULL}  /* Sentinel */
779 };
780
781 static PyMappingMethods cvmatnd_as_map = {
782   NULL,
783   &cvarr_GetItem,
784   &cvarr_SetItem,
785 };
786
787 static PyTypeObject cvmatnd_Type = {
788   PyObject_HEAD_INIT(&PyType_Type)
789   0,                                      /*size*/
790   MODULESTR".cvmatnd",                          /*name*/
791   sizeof(cvmatnd_t),                        /*basicsize*/
792 };
793
794 static void cvmatnd_specials(void)
795 {
796   cvmatnd_Type.tp_dealloc = cvmatnd_dealloc;
797   cvmatnd_Type.tp_as_mapping = &cvmatnd_as_map;
798   cvmatnd_Type.tp_repr = cvmatnd_repr;
799   cvmatnd_Type.tp_methods = cvmatnd_methods;
800   cvmatnd_Type.tp_getset = cvmatnd_getseters;
801 }
802
803 static int is_cvmatnd(PyObject *o)
804 {
805   return PyType_IsSubtype(o->ob_type, &cvmatnd_Type);
806 }
807
808 /************************************************************************/
809
810 /* cvhistogram */
811
812 static void cvhistogram_dealloc(PyObject *self)
813 {
814   cvhistogram_t *cvh = (cvhistogram_t*)self;
815   Py_DECREF(cvh->bins);
816   PyObject_Del(self);
817 }
818
819 static PyTypeObject cvhistogram_Type = {
820   PyObject_HEAD_INIT(&PyType_Type)
821   0,                                      /*size*/
822   MODULESTR".cvhistogram",                /*name*/
823   sizeof(cvhistogram_t),                  /*basicsize*/
824 };
825
826 static PyObject *cvhistogram_getbins(cvhistogram_t *cvh)
827 {
828   Py_INCREF(cvh->bins);
829   return cvh->bins;
830 }
831
832 static PyGetSetDef cvhistogram_getseters[] = {
833   {(char*)"bins", (getter)cvhistogram_getbins, (setter)NULL, (char*)"bins", NULL},
834   {NULL}  /* Sentinel */
835 };
836
837 static void cvhistogram_specials(void)
838 {
839   cvhistogram_Type.tp_dealloc = cvhistogram_dealloc;
840   cvhistogram_Type.tp_getset = cvhistogram_getseters;
841 }
842
843 /************************************************************************/
844
845 /* cvlineiterator */
846
847 static PyObject *cvlineiterator_iter(PyObject *o)
848 {
849   Py_INCREF(o);
850   return o;
851 }
852
853 static PyObject *cvlineiterator_next(PyObject *o)
854 {
855   cvlineiterator_t *pi = (cvlineiterator_t*)o;
856
857   if (pi->count) {
858       pi->count--;
859
860       CvScalar r;
861       cvRawDataToScalar( (void*)(pi->iter.ptr), pi->type, &r);
862       PyObject *pr = PyObject_FromCvScalar(r, pi->type);
863
864       CV_NEXT_LINE_POINT(pi->iter);
865
866       return pr;
867   } else {
868     return NULL;
869   }
870 }
871
872 static PyTypeObject cvlineiterator_Type = {
873   PyObject_HEAD_INIT(&PyType_Type)
874   0,                                      /*size*/
875   MODULESTR".cvlineiterator",             /*name*/
876   sizeof(cvlineiterator_t),               /*basicsize*/
877 };
878
879 static void cvlineiterator_specials(void)
880 {
881   cvlineiterator_Type.tp_iter = cvlineiterator_iter;
882   cvlineiterator_Type.tp_iternext = cvlineiterator_next;
883 }
884
885 /************************************************************************/
886
887 /* memtrack */
888
889 static void memtrack_dealloc(PyObject *self)
890 {
891   memtrack_t *pi = (memtrack_t*)self;
892   // printf("===> memtrack_dealloc %p!\n", pi->ptr);
893   cvFree(&pi->ptr);
894   PyObject_Del(self);
895 }
896
897 static PyTypeObject memtrack_Type = {
898   PyObject_HEAD_INIT(&PyType_Type)
899   0,                                      /*size*/
900   MODULESTR".memtrack",                          /*name*/
901   sizeof(memtrack_t),                        /*basicsize*/
902 };
903
904 Py_ssize_t memtrack_getreadbuffer(PyObject *self, Py_ssize_t segment, void **ptrptr)
905 {
906   *ptrptr = &((memtrack_t*)self)->ptr;
907   return ((memtrack_t*)self)->size;
908 }
909
910 Py_ssize_t memtrack_getwritebuffer(PyObject *self, Py_ssize_t segment, void **ptrptr)
911 {
912   *ptrptr = ((memtrack_t*)self)->ptr;
913   return ((memtrack_t*)self)->size;
914 }
915
916 Py_ssize_t memtrack_getsegcount(PyObject *self, Py_ssize_t *lenp)
917 {
918   return (Py_ssize_t)1;
919 }
920
921 PyBufferProcs memtrack_as_buffer = {
922   memtrack_getreadbuffer,
923   memtrack_getwritebuffer,
924   memtrack_getsegcount
925 };
926
927 static void memtrack_specials(void)
928 {
929   memtrack_Type.tp_dealloc = memtrack_dealloc;
930   memtrack_Type.tp_as_buffer = &memtrack_as_buffer;
931 }
932
933 /************************************************************************/
934
935 /* iplconvkernel */
936
937 static void iplconvkernel_dealloc(PyObject *self)
938 {
939   iplconvkernel_t *pi = (iplconvkernel_t*)self;
940   cvReleaseStructuringElement(&(pi->a));
941   PyObject_Del(self);
942 }
943
944 static PyTypeObject iplconvkernel_Type = {
945   PyObject_HEAD_INIT(&PyType_Type)
946   0,                                      /*size*/
947   MODULESTR".iplconvkernel",                          /*name*/
948   sizeof(iplconvkernel_t),                        /*basicsize*/
949 };
950
951 static void iplconvkernel_specials(void)
952 {
953   iplconvkernel_Type.tp_dealloc = iplconvkernel_dealloc;
954 }
955
956 /************************************************************************/
957
958 /* cvcapture */
959
960 static void cvcapture_dealloc(PyObject *self)
961 {
962   cvcapture_t *pi = (cvcapture_t*)self;
963   cvReleaseCapture(&(pi->a));
964   PyObject_Del(self);
965 }
966
967 static PyTypeObject cvcapture_Type = {
968   PyObject_HEAD_INIT(&PyType_Type)
969   0,                                      /*size*/
970   MODULESTR".cvcapture",                  /*name*/
971   sizeof(cvcapture_t),                    /*basicsize*/
972 };
973
974 static void cvcapture_specials(void)
975 {
976   cvcapture_Type.tp_dealloc = cvcapture_dealloc;
977 }
978
979 /************************************************************************/
980
981 /* cvvideowriter */
982
983 static void cvvideowriter_dealloc(PyObject *self)
984 {
985   cvvideowriter_t *pi = (cvvideowriter_t*)self;
986   cvReleaseVideoWriter(&(pi->a));
987   PyObject_Del(self);
988 }
989
990 static PyTypeObject cvvideowriter_Type = {
991   PyObject_HEAD_INIT(&PyType_Type)
992   0,                                      /*size*/
993   MODULESTR".cvvideowriter",              /*name*/
994   sizeof(cvvideowriter_t),                /*basicsize*/
995 };
996
997 static void cvvideowriter_specials(void)
998 {
999   cvvideowriter_Type.tp_dealloc = cvvideowriter_dealloc;
1000 }
1001
1002
1003
1004 /************************************************************************/
1005
1006 /* cvmoments */
1007
1008 static PyTypeObject cvmoments_Type = {
1009   PyObject_HEAD_INIT(&PyType_Type)
1010   0,                                      /*size*/
1011   MODULESTR".cvmoments",                          /*name*/
1012   sizeof(cvmoments_t),                        /*basicsize*/
1013 };
1014
1015 static void cvmoments_specials(void)
1016 {
1017 }
1018
1019 /************************************************************************/
1020
1021 /* cvmemstorage */
1022
1023 static void cvmemstorage_dealloc(PyObject *self)
1024 {
1025   cvmemstorage_t *ps = (cvmemstorage_t*)self;
1026   cvReleaseMemStorage(&(ps->a));
1027   PyObject_Del(self);
1028 }
1029
1030 static PyTypeObject cvmemstorage_Type = {
1031   PyObject_HEAD_INIT(&PyType_Type)
1032   0,                                      /*size*/
1033   MODULESTR".cvmemstorage",               /*name*/
1034   sizeof(cvmemstorage_t),                 /*basicsize*/
1035 };
1036
1037 static void cvmemstorage_specials(void)
1038 {
1039   cvmemstorage_Type.tp_dealloc = cvmemstorage_dealloc;
1040 }
1041
1042 /************************************************************************/
1043
1044 /* cvfont */
1045
1046 static PyTypeObject cvfont_Type = {
1047   PyObject_HEAD_INIT(&PyType_Type)
1048   0,                                      /*size*/
1049   MODULESTR".cvfont",                     /*name*/
1050   sizeof(cvfont_t),                       /*basicsize*/
1051 };
1052
1053 static void cvfont_specials(void) { }
1054
1055 /************************************************************************/
1056
1057 /* cvpositobject */
1058
1059 static void cvpositobject_dealloc(PyObject *self)
1060 {
1061   cvpositobject_t *pi = (cvpositobject_t*)self;
1062   cvReleasePOSITObject(&(pi->a));
1063   PyObject_Del(self);
1064 }
1065
1066 static PyTypeObject cvpositobject_Type = {
1067   PyObject_HEAD_INIT(&PyType_Type)
1068   0,                                      /*size*/
1069   MODULESTR".cvpositobject",                     /*name*/
1070   sizeof(cvpositobject_t),                       /*basicsize*/
1071 };
1072
1073 static void cvpositobject_specials(void)
1074 {
1075   cvpositobject_Type.tp_dealloc = cvpositobject_dealloc;
1076 }
1077
1078 /************************************************************************/
1079
1080 /* cvrng */
1081
1082 static PyTypeObject cvrng_Type = {
1083   PyObject_HEAD_INIT(&PyType_Type)
1084   0,                                      /*size*/
1085   MODULESTR".cvrng",                     /*name*/
1086   sizeof(cvrng_t),                       /*basicsize*/
1087 };
1088
1089 static void cvrng_specials(void)
1090 {
1091 }
1092
1093 /************************************************************************/
1094
1095 /* cvhaarclassifiercascade */
1096
1097 static PyTypeObject cvhaarclassifiercascade_Type = {
1098   PyObject_HEAD_INIT(&PyType_Type)
1099   0,                                      /*size*/
1100   MODULESTR".cvhaarclassifiercascade",                     /*name*/
1101   sizeof(cvhaarclassifiercascade_t),                       /*basicsize*/
1102 };
1103
1104 static void cvhaarclassifiercascade_specials(void) { }
1105
1106 /************************************************************************/
1107
1108 /* cvcontourtree */
1109
1110 static PyTypeObject cvcontourtree_Type = {
1111   PyObject_HEAD_INIT(&PyType_Type)
1112   0,                                      /*size*/
1113   MODULESTR".cvcontourtree",                     /*name*/
1114   sizeof(cvcontourtree_t),                       /*basicsize*/
1115 };
1116
1117 static void cvcontourtree_specials(void) { }
1118
1119
1120 /************************************************************************/
1121
1122 /* cvsubdiv2dedge */
1123
1124 static PyTypeObject cvsubdiv2dedge_Type = {
1125   PyObject_HEAD_INIT(&PyType_Type)
1126   0,                                      /*size*/
1127   MODULESTR".cvsubdiv2dedge",                     /*name*/
1128   sizeof(cvsubdiv2dedge_t),                       /*basicsize*/
1129 };
1130
1131 static int cvsubdiv2dedge_compare(PyObject *o1, PyObject *o2)
1132 {
1133   cvsubdiv2dedge_t *e1 = (cvsubdiv2dedge_t*)o1;
1134   cvsubdiv2dedge_t *e2 = (cvsubdiv2dedge_t*)o2;
1135   if (e1->a < e2->a)
1136     return -1;
1137   else if (e1->a > e2->a)
1138     return 1;
1139   else
1140     return 0;
1141 }
1142
1143 static PyObject *cvquadedge_repr(PyObject *self)
1144 {
1145   CvSubdiv2DEdge m = ((cvsubdiv2dedge_t*)self)->a;
1146   char str[1000];
1147   sprintf(str, "<cvsubdiv2dedge(");
1148   char *d = str + strlen(str);
1149   sprintf(d, "%zx.%d", m & ~3, (int)(m & 3));
1150   d += strlen(d);
1151   sprintf(d, ")>");
1152   return PyString_FromString(str);
1153 }
1154
1155 static void cvsubdiv2dedge_specials(void) {
1156   cvsubdiv2dedge_Type.tp_compare = cvsubdiv2dedge_compare;
1157   cvsubdiv2dedge_Type.tp_repr = cvquadedge_repr;
1158 }
1159
1160 /************************************************************************/
1161
1162 /* cvseq */
1163
1164 static void cvseq_dealloc(PyObject *self)
1165 {
1166   cvseq_t *ps = (cvseq_t*)self;
1167   Py_DECREF(ps->container);
1168   PyObject_Del(self);
1169 }
1170
1171 static PyObject *cvseq_h_next(PyObject *self, PyObject *args);
1172 static PyObject *cvseq_h_prev(PyObject *self, PyObject *args);
1173 static PyObject *cvseq_v_next(PyObject *self, PyObject *args);
1174 static PyObject *cvseq_v_prev(PyObject *self, PyObject *args);
1175
1176 static struct PyMethodDef cvseq_methods[] =
1177 {
1178   {"h_next", cvseq_h_next, METH_VARARGS},
1179   {"h_prev", cvseq_h_prev, METH_VARARGS},
1180   {"v_next", cvseq_v_next, METH_VARARGS},
1181   {"v_prev", cvseq_v_prev, METH_VARARGS},
1182   {NULL,          NULL}
1183 };
1184
1185 static Py_ssize_t cvseq_seq_length(PyObject *o)
1186 {
1187   cvseq_t *ps = (cvseq_t*)o;
1188   if (ps->a == NULL)
1189     return (Py_ssize_t)0;
1190   else
1191     return (Py_ssize_t)(ps->a->total);
1192 }
1193
1194 static PyObject* cvseq_seq_getitem(PyObject *o, Py_ssize_t i)
1195 {
1196   cvseq_t *ps = (cvseq_t*)o;
1197   CvPoint *pt;
1198   struct pointpair{
1199     CvPoint a, b;
1200   } *pp;
1201   CvPoint2D32f *pt2;
1202   CvPoint3D32f *pt3;
1203
1204   if (i < cvseq_seq_length(o)) {
1205     switch (CV_SEQ_ELTYPE(ps->a)) {
1206
1207     case CV_SEQ_ELTYPE_POINT:
1208       pt = CV_GET_SEQ_ELEM(CvPoint, ps->a, i);
1209       return Py_BuildValue("ii", pt->x, pt->y);
1210
1211     case CV_SEQ_ELTYPE_GENERIC:
1212       switch (ps->a->elem_size) {
1213       case sizeof(CvQuadEdge2D):
1214         {
1215           cvsubdiv2dedge_t *r = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type);
1216           r->a = (CvSubdiv2DEdge)CV_GET_SEQ_ELEM(CvQuadEdge2D, ps->a, i);
1217           r->container = ps->container;
1218           Py_INCREF(r->container);
1219           return (PyObject*)r;
1220         }
1221       default:
1222         printf("seq elem size is %d\n", ps->a->elem_size);
1223         printf("KIND %d\n", CV_SEQ_KIND(ps->a));
1224         assert(0);
1225       }
1226       return PyInt_FromLong(*CV_GET_SEQ_ELEM(unsigned char, ps->a, i));
1227
1228     case CV_SEQ_ELTYPE_PTR:
1229     case CV_SEQ_ELTYPE_INDEX:
1230       return PyInt_FromLong(*CV_GET_SEQ_ELEM(int, ps->a, i));
1231
1232     case CV_32SC4:
1233       pp = CV_GET_SEQ_ELEM(pointpair, ps->a, i);
1234       return Py_BuildValue("(ii),(ii)", pp->a.x, pp->a.y, pp->b.x, pp->b.y);
1235
1236     case CV_32FC2:
1237       pt2 = CV_GET_SEQ_ELEM(CvPoint2D32f, ps->a, i);
1238       return Py_BuildValue("ff", pt2->x, pt2->y);
1239
1240     case CV_SEQ_ELTYPE_POINT3D:
1241       pt3 = CV_GET_SEQ_ELEM(CvPoint3D32f, ps->a, i);
1242       return Py_BuildValue("fff", pt3->x, pt3->y, pt3->z);
1243
1244     default:
1245       printf("Unknown element type %08x\n", CV_SEQ_ELTYPE(ps->a));
1246       assert(0);
1247       return NULL;
1248     }
1249   } else
1250     return NULL;
1251 }
1252
1253 static PyObject* cvseq_map_getitem(PyObject *o, PyObject *item)
1254 {
1255   if (PyInt_Check(item)) {
1256     long i = PyInt_AS_LONG(item);
1257     if (i < 0)
1258       i += cvseq_seq_length(o);
1259     return cvseq_seq_getitem(o, i);
1260   } else if (PySlice_Check(item)) {
1261     Py_ssize_t start, stop, step, slicelength, cur, i;
1262     PyObject* result;
1263
1264     if (PySlice_GetIndicesEx((PySliceObject*)item, cvseq_seq_length(o),
1265          &start, &stop, &step, &slicelength) < 0) {
1266       return NULL;
1267     }
1268
1269     if (slicelength <= 0) {
1270       return PyList_New(0);
1271     } else {
1272       result = PyList_New(slicelength);
1273       if (!result) return NULL;
1274
1275       for (cur = start, i = 0; i < slicelength;
1276            cur += step, i++) {
1277         PyList_SET_ITEM(result, i, cvseq_seq_getitem(o, cur));
1278       }
1279
1280       return result;
1281     }
1282   } else {
1283     PyErr_SetString(PyExc_TypeError, "CvSeq indices must be integers");
1284     return NULL;
1285   }
1286 }
1287
1288 static 
1289 PySequenceMethods cvseq_sequence = {
1290   cvseq_seq_length,
1291   NULL,
1292   NULL,
1293   cvseq_seq_getitem
1294 };
1295
1296 static PyMappingMethods cvseq_mapping = {
1297   cvseq_seq_length,
1298   cvseq_map_getitem,
1299   NULL,
1300 };
1301
1302 static PyTypeObject cvseq_Type = {
1303   PyObject_HEAD_INIT(&PyType_Type)
1304   0,                                      /*size*/
1305   MODULESTR".cvseq",                          /*name*/
1306   sizeof(cvseq_t),                        /*basicsize*/
1307 };
1308
1309 static void cvseq_specials(void)
1310 {
1311   cvseq_Type.tp_dealloc = cvseq_dealloc;
1312   cvseq_Type.tp_as_sequence = &cvseq_sequence;
1313   cvseq_Type.tp_as_mapping = &cvseq_mapping;
1314   cvseq_Type.tp_methods = cvseq_methods;
1315 }
1316
1317 #define MK_ACCESSOR(FIELD) \
1318 static PyObject *cvseq_##FIELD(PyObject *self, PyObject *args) \
1319 { \
1320   cvseq_t *ps = (cvseq_t*)self; \
1321   CvSeq *s = ps->a; \
1322   if (s->FIELD == NULL) { \
1323     Py_RETURN_NONE; \
1324   } else { \
1325     cvseq_t *r = PyObject_NEW(cvseq_t, &cvseq_Type); \
1326     r->a = s->FIELD; \
1327     r->container = ps->container; \
1328     Py_INCREF(r->container); \
1329     return (PyObject*)r; \
1330   } \
1331 }
1332
1333 MK_ACCESSOR(h_next)
1334 MK_ACCESSOR(h_prev)
1335 MK_ACCESSOR(v_next)
1336 MK_ACCESSOR(v_prev)
1337 #undef MK_ACCESSOR
1338
1339 /************************************************************************/
1340
1341 /* cvset */
1342
1343 static void cvset_dealloc(PyObject *self)
1344 {
1345   cvset_t *ps = (cvset_t*)self;
1346   Py_DECREF(ps->container);
1347   PyObject_Del(self);
1348 }
1349
1350 static PyTypeObject cvset_Type = {
1351   PyObject_HEAD_INIT(&PyType_Type)
1352   0,                                      /*size*/
1353   MODULESTR".cvset",                          /*name*/
1354   sizeof(cvset_t),                        /*basicsize*/
1355 };
1356
1357 static PyObject *cvset_iter(PyObject *o)
1358 {
1359   Py_INCREF(o);
1360   cvset_t *ps = (cvset_t*)o;
1361   ps->i = 0;
1362   return o;
1363 }
1364
1365 static PyObject *cvset_next(PyObject *o)
1366 {
1367   cvset_t *ps = (cvset_t*)o;
1368
1369   while (ps->i < ps->a->total) {
1370     CvSetElem *e = cvGetSetElem(ps->a, ps->i);
1371     int prev_i = ps->i++;
1372     if (e != NULL) {
1373       return cvseq_seq_getitem(o, prev_i);
1374     }
1375   }
1376   return NULL;
1377 }
1378
1379 static void cvset_specials(void)
1380 {
1381   cvset_Type.tp_dealloc = cvset_dealloc;
1382   cvset_Type.tp_iter = cvset_iter;
1383   cvset_Type.tp_iternext = cvset_next;
1384 }
1385
1386 /************************************************************************/
1387
1388 /* cvsubdiv2d */
1389
1390 static PyTypeObject cvsubdiv2d_Type = {
1391   PyObject_HEAD_INIT(&PyType_Type)
1392   0,                                      /*size*/
1393   MODULESTR".cvsubdiv2d",                     /*name*/
1394   sizeof(cvsubdiv2d_t),                       /*basicsize*/
1395 };
1396
1397 static PyObject *cvsubdiv2d_getattro(PyObject *o, PyObject *name)
1398 {
1399   cvsubdiv2d_t *p = (cvsubdiv2d_t*)o;
1400   if (strcmp(PyString_AsString(name), "edges") == 0) {
1401     cvset_t *r = PyObject_NEW(cvset_t, &cvset_Type);
1402     r->a = p->a->edges;
1403     r->container = p->container;
1404     Py_INCREF(r->container);
1405     return (PyObject*)r;
1406   } else {
1407     PyErr_SetString(PyExc_TypeError, "cvsubdiv2d has no such attribute");
1408     return NULL;
1409   }
1410 }
1411
1412 static void cvsubdiv2d_specials(void)
1413 {
1414   cvsubdiv2d_Type.tp_getattro = cvsubdiv2d_getattro;
1415 }
1416
1417 /************************************************************************/
1418
1419 /* cvsubdiv2dpoint */
1420
1421 static PyTypeObject cvsubdiv2dpoint_Type = {
1422   PyObject_HEAD_INIT(&PyType_Type)
1423   0,                                      /*size*/
1424   MODULESTR".cvsubdiv2dpoint",                     /*name*/
1425   sizeof(cvsubdiv2dpoint_t),                       /*basicsize*/
1426 };
1427
1428 static PyObject *cvsubdiv2dpoint_getattro(PyObject *o, PyObject *name)
1429 {
1430   cvsubdiv2dpoint_t *p = (cvsubdiv2dpoint_t*)o;
1431   if (strcmp(PyString_AsString(name), "first") == 0) {
1432     cvsubdiv2dedge_t *r = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type);
1433     r->a = p->a->first;
1434     r->container = p->container;
1435     Py_INCREF(r->container);
1436     return (PyObject*)r;
1437   } else if (strcmp(PyString_AsString(name), "pt") == 0) {
1438     return Py_BuildValue("(ff)", p->a->pt.x, p->a->pt.y);
1439   } else {
1440     PyErr_SetString(PyExc_TypeError, "cvsubdiv2dpoint has no such attribute");
1441     return NULL;
1442   }
1443 }
1444
1445 static void cvsubdiv2dpoint_specials(void)
1446 {
1447   cvsubdiv2dpoint_Type.tp_getattro = cvsubdiv2dpoint_getattro;
1448 }
1449
1450 /************************************************************************/
1451 /* convert_to_X: used after PyArg_ParseTuple in the generated code  */
1452
1453 static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
1454 {
1455   if (PyString_Check(o) && PyString_Size(o) == 1) {
1456     *dst = PyString_AsString(o)[0];
1457     return 1;
1458   } else {
1459     (*dst) = 0;
1460     return failmsg("Expected single character string for argument '%s'", name);
1461   }
1462 }
1463
1464 static int convert_to_CvMemStorage(PyObject *o, CvMemStorage **dst, const char *name = "no_name")
1465 {
1466   if (PyType_IsSubtype(o->ob_type, &cvmemstorage_Type)) {
1467     (*dst) = (((cvmemstorage_t*)o)->a);
1468     return 1;
1469   } else {
1470     (*dst) = (CvMemStorage*)NULL;
1471     return failmsg("Expected CvMemStorage for argument '%s'", name);
1472   }
1473 }
1474
1475 static int convert_to_CvSeq(PyObject *o, CvSeq **dst, const char *name = "no_name")
1476 {
1477   if (PyType_IsSubtype(o->ob_type, &cvseq_Type)) {
1478     (*dst) = (((cvseq_t*)o)->a);
1479     return 1;
1480   } else {
1481     (*dst) = (CvSeq*)NULL;
1482     return failmsg("Expected CvSeq for argument '%s'", name);
1483   }
1484 }
1485
1486 static int convert_to_CvSize(PyObject *o, CvSize *dst, const char *name = "no_name")
1487 {
1488   if (!PyArg_ParseTuple(o, "ii", &dst->width, &dst->height))
1489     return failmsg("CvSize argument '%s' expects two integers", name);
1490   else
1491     return 1;
1492 }
1493
1494 static int convert_to_CvScalar(PyObject *o, CvScalar *s, const char *name = "no_name")
1495 {
1496   if (PySequence_Check(o)) {
1497     PyObject *fi = PySequence_Fast(o, name);
1498     if (fi == NULL)
1499       return 0;
1500     if (4 < PySequence_Fast_GET_SIZE(fi))
1501         return failmsg("CvScalar value for argument '%s' is longer than 4", name);
1502     for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1503       PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1504       if (PyFloat_Check(item) || PyInt_Check(item)) {
1505         s->val[i] = PyFloat_AsDouble(item);
1506       } else {
1507         return failmsg("CvScalar value for argument '%s' is not numeric", name);
1508       }
1509     }
1510     Py_DECREF(fi);
1511   } else {
1512     if (PyFloat_Check(o) || PyInt_Check(o)) {
1513       s->val[0] = PyFloat_AsDouble(o);
1514     } else {
1515       return failmsg("CvScalar value for argument '%s' is not numeric", name);
1516     }
1517   }
1518   return 1;
1519 }
1520
1521 static int convert_to_CvPointPTR(PyObject *o, CvPoint **p, const char *name = "no_name")
1522 {
1523   if (!PySequence_Check(o))
1524     return failmsg("Expected sequence for point list argument '%s'", name);
1525   PyObject *fi = PySequence_Fast(o, name);
1526   if (fi == NULL)
1527     return 0;
1528   *p = new CvPoint[PySequence_Fast_GET_SIZE(fi)];
1529   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1530     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1531     if (!PyTuple_Check(item))
1532       return failmsg("Expected tuple for element in point list argument '%s'", name);
1533     if (!PyArg_ParseTuple(item, "ii", &((*p)[i].x), &((*p)[i].y))) {
1534       return 0;
1535     }
1536   }
1537   Py_DECREF(fi);
1538   return 1;
1539 }
1540
1541 static int convert_to_CvPoint2D32fPTR(PyObject *o, CvPoint2D32f **p, const char *name = "no_name")
1542 {
1543   PyObject *fi = PySequence_Fast(o, name);
1544   if (fi == NULL)
1545     return 0;
1546   *p = new CvPoint2D32f[PySequence_Fast_GET_SIZE(fi)];
1547   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1548     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1549     if (!PyTuple_Check(item))
1550       return failmsg("Expected tuple for CvPoint2D32f argument '%s'", name);
1551     if (!PyArg_ParseTuple(item, "ff", &((*p)[i].x), &((*p)[i].y))) {
1552       return 0;
1553     }
1554   }
1555   Py_DECREF(fi);
1556   return 1;
1557 }
1558
1559 #if 0 // not used
1560 static int convert_to_CvPoint3D32fPTR(PyObject *o, CvPoint3D32f **p, const char *name = "no_name")
1561 {
1562   PyObject *fi = PySequence_Fast(o, name);
1563   if (fi == NULL)
1564     return 0;
1565   *p = new CvPoint3D32f[PySequence_Fast_GET_SIZE(fi)];
1566   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1567     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1568     if (!PyTuple_Check(item))
1569       return failmsg("Expected tuple for CvPoint3D32f argument '%s'", name);
1570     if (!PyArg_ParseTuple(item, "fff", &((*p)[i].x), &((*p)[i].y), &((*p)[i].z))) {
1571       return 0;
1572     }
1573   }
1574   Py_DECREF(fi);
1575   return 1;
1576 }
1577 #endif
1578
1579 static int convert_to_CvStarDetectorParams(PyObject *o, CvStarDetectorParams *dst, const char *name = "no_name")
1580 {
1581   if (!PyArg_ParseTuple(o,
1582                         "iiiii",
1583                         &dst->maxSize,
1584                         &dst->responseThreshold,
1585                         &dst->lineThresholdProjected,
1586                         &dst->lineThresholdBinarized,
1587                         &dst->suppressNonmaxSize))
1588     return failmsg("CvRect argument '%s' expects four integers", name);
1589   else
1590     return 1;
1591 }
1592
1593 static int convert_to_CvRect(PyObject *o, CvRect *dst, const char *name = "no_name")
1594 {
1595   if (!PyArg_ParseTuple(o, "iiii", &dst->x, &dst->y, &dst->width, &dst->height))
1596     return failmsg("CvRect argument '%s' expects four integers", name);
1597   else
1598     return 1;
1599 }
1600
1601 static int convert_to_CvRectPTR(PyObject *o, CvRect **dst, const char *name = "no_name")
1602 {
1603   *dst = new CvRect;
1604   if (!PyArg_ParseTuple(o, "iiii", &(*dst)->x, &(*dst)->y, &(*dst)->width, &(*dst)->height))
1605     return failmsg("CvRect argument '%s' expects four integers", name);
1606   else
1607     return 1;
1608 }
1609
1610 static int convert_to_CvSlice(PyObject *o, CvSlice *dst, const char *name = "no_name")
1611 {
1612   if (!PyArg_ParseTuple(o, "ii", &dst->start_index, &dst->end_index))
1613     return failmsg("CvSlice argument '%s' expects two integers", name);
1614   else
1615     return 1;
1616 }
1617
1618 static int convert_to_CvPoint(PyObject *o, CvPoint *dst, const char *name = "no_name")
1619 {
1620   if (!PyArg_ParseTuple(o, "ii", &dst->x, &dst->y))
1621     return failmsg("CvPoint argument '%s' expects two integers", name);
1622   else
1623     return 1;
1624 }
1625
1626 static int convert_to_CvPoint2D32f(PyObject *o, CvPoint2D32f *dst, const char *name = "no_name")
1627 {
1628   if (!PyArg_ParseTuple(o, "ff", &dst->x, &dst->y))
1629     return failmsg("CvPoint2D32f argument '%s' expects two floats", name);
1630   else
1631     return 1;
1632 }
1633
1634 static int convert_to_CvPoint3D32f(PyObject *o, CvPoint3D32f *dst, const char *name = "no_name")
1635 {
1636   if (!PyArg_ParseTuple(o, "fff", &dst->x, &dst->y, &dst->z))
1637     return failmsg("CvPoint3D32f argument '%s' expects three floats", name);
1638   else
1639     return 1;
1640 }
1641
1642 static int convert_to_IplImage(PyObject *o, IplImage **dst, const char *name)
1643 {
1644   iplimage_t *ipl = (iplimage_t*)o;
1645   void *buffer;
1646   Py_ssize_t buffer_len;
1647
1648   if (!is_iplimage(o)) {
1649     return failmsg("Argument '%s' must be IplImage", name);
1650   } else if (PyString_Check(ipl->data)) {
1651     cvSetData(ipl->a, PyString_AsString(ipl->data) + ipl->offset, ipl->a->widthStep);
1652     assert(cvGetErrStatus() == 0);
1653     *dst = ipl->a;
1654     return 1;
1655   } else if (ipl->data && PyObject_AsWriteBuffer(ipl->data, &buffer, &buffer_len) == 0) {
1656     cvSetData(ipl->a, (void*)((char*)buffer + ipl->offset), ipl->a->widthStep);
1657     assert(cvGetErrStatus() == 0);
1658     *dst = ipl->a;
1659     return 1;
1660   } else {
1661     return failmsg("IplImage argument '%s' has no data", name);
1662   }
1663 }
1664
1665 static int convert_to_CvMat(PyObject *o, CvMat **dst, const char *name)
1666 {
1667   cvmat_t *m = (cvmat_t*)o;
1668   void *buffer;
1669   Py_ssize_t buffer_len;
1670
1671   if (!is_cvmat(o)) {
1672     return failmsg("Argument '%s' must be CvMat", name);
1673   } else {
1674     m->a->refcount = NULL;
1675     if (m->data && PyString_Check(m->data)) {
1676       assert(cvGetErrStatus() == 0);
1677       char *ptr = PyString_AsString(m->data) + m->offset;
1678       cvSetData(m->a, ptr, m->a->step);
1679       assert(cvGetErrStatus() == 0);
1680       *dst = m->a;
1681       return 1;
1682     } else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0) {
1683       cvSetData(m->a, (void*)((char*)buffer + m->offset), m->a->step);
1684       assert(cvGetErrStatus() == 0);
1685       *dst = m->a;
1686       return 1;
1687     } else {
1688       return failmsg("CvMat argument '%s' has no data", name);
1689     }
1690   }
1691 }
1692
1693 static int convert_to_CvMatND(PyObject *o, CvMatND **dst, const char *name)
1694 {
1695   cvmatnd_t *m = (cvmatnd_t*)o;
1696   void *buffer;
1697   Py_ssize_t buffer_len;
1698
1699   if (!is_cvmatnd(o)) {
1700     return failmsg("Argument '%s' must be CvMatND", name);
1701   } else if (m->data && PyString_Check(m->data)) {
1702     m->a->data.ptr = ((uchar*)PyString_AsString(m->data)) + m->offset;
1703     *dst = m->a;
1704     return 1;
1705   } else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0) {
1706     m->a->data.ptr = ((uchar*)buffer + m->offset);
1707     *dst = m->a;
1708     return 1;
1709   } else {
1710     return failmsg("CvMatND argument '%s' has no data", name);
1711   }
1712 }
1713
1714 static int convert_to_CvArr(PyObject *o, CvArr **dst, const char *name)
1715 {
1716   if (o == Py_None) {
1717     *dst = (void*)NULL;
1718     return 1;
1719   } else if (is_iplimage(o)) {
1720     return convert_to_IplImage(o, (IplImage**)dst, name);
1721   } else if (is_cvmat(o)) {
1722     return convert_to_CvMat(o, (CvMat**)dst, name);
1723   } else if (is_cvmatnd(o)) {
1724     return convert_to_CvMatND(o, (CvMatND**)dst, name);
1725   } else {
1726     return failmsg("CvArr argument '%s' must be IplImage, CvMat or CvMatND", name);
1727   }
1728 }
1729
1730 static int convert_to_CvHistogram(PyObject *o, CvHistogram **dst, const char *name = "no_name")
1731 {
1732   if (PyType_IsSubtype(o->ob_type, &cvhistogram_Type)) {
1733     cvhistogram_t *ht = (cvhistogram_t*)o;
1734     *dst = &ht->h;
1735     return convert_to_CvArr(ht->bins, &(ht->h.bins), "bins");
1736   } else {
1737     *dst = (CvHistogram *)NULL;
1738     return failmsg("Expected CvHistogram for argument '%s'", name);
1739   }
1740 }
1741
1742 // Used by FillPoly, FillConvexPoly, PolyLine
1743 struct pts_npts_contours {
1744   CvPoint** pts;
1745   int* npts;
1746   int contours;
1747 };
1748
1749 static int convert_to_pts_npts_contours(PyObject *o, pts_npts_contours *dst, const char *name = "no_name")
1750 {
1751   PyObject *fi = PySequence_Fast(o, name);
1752   if (fi == NULL)
1753     return 0;
1754   dst->contours = PySequence_Fast_GET_SIZE(fi);
1755   dst->pts = new CvPoint*[dst->contours];
1756   dst->npts = new int[dst->contours];
1757   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1758     if (!convert_to_CvPointPTR(PySequence_Fast_GET_ITEM(fi, i), &dst->pts[i], name))
1759       return 0;
1760     dst->npts[i] = PySequence_Size(PySequence_Fast_GET_ITEM(fi, i)); // safe because convert_ just succeeded
1761   }
1762   Py_DECREF(fi);
1763   return 1;
1764 }
1765
1766 struct cvarrseq {
1767   void *v;
1768 };
1769
1770 static int convert_to_cvarrseq(PyObject *o, cvarrseq *dst, const char *name = "no_name")
1771 {
1772   if (PyType_IsSubtype(o->ob_type, &cvseq_Type)) {
1773     return convert_to_CvSeq(o, (CvSeq**)&(dst->v), name);
1774   } else if (PySequence_Check(o)) {
1775     PyObject *fi = PySequence_Fast(o, name);
1776     if (fi == NULL)
1777       return 0;
1778     Py_ssize_t size = -1;
1779     // Make a pass through the sequence, checking that each element is
1780     // a sequence and that they are all the same size
1781     for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1782       PyObject *e = PySequence_Fast_GET_ITEM(fi, i);
1783
1784       if (!PySequence_Check(e))
1785         return failmsg("Sequence '%s' must contain sequences", name);
1786       if (i == 0)
1787         size = (int)PySequence_Size(e);
1788       else if (size != PySequence_Size(e))
1789         return failmsg("All elements of sequence '%s' must be same size", name);
1790     }
1791     assert(size != -1);
1792     CvMat *mt = cvCreateMat((int)PySequence_Fast_GET_SIZE(fi), 1, CV_32SC(size));
1793     for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1794       PyObject *e = PySequence_Fast_GET_ITEM(fi, i);
1795       PyObject *fe = PySequence_Fast(e, name);
1796       assert(fe != NULL);
1797       int *pdst = (int*)cvPtr2D(mt, i, 0);
1798       for (Py_ssize_t j = 0; j < size; j++) {
1799         *pdst++ = PyInt_AsLong(PySequence_Fast_GET_ITEM(fe, j));
1800       }
1801       Py_DECREF(fe);
1802     }
1803     Py_DECREF(fi);
1804     dst->v = mt;
1805     return 1;
1806   } else {
1807     return convert_to_CvArr(o, (CvArr**)&(dst->v), name);
1808   }
1809 }
1810
1811 struct cvarr_count {
1812   CvArr **cvarr;
1813   int count;
1814 };
1815
1816 static int convert_to_cvarr_count(PyObject *o, cvarr_count *dst, const char *name = "no_name")
1817 {
1818   PyObject *fi = PySequence_Fast(o, name);
1819   if (fi == NULL)
1820     return 0;
1821   dst->count = PySequence_Fast_GET_SIZE(fi);
1822   dst->cvarr = new CvArr*[dst->count];
1823   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1824     if (!convert_to_CvArr(PySequence_Fast_GET_ITEM(fi, i), &dst->cvarr[i], name))
1825       return 0;
1826   }
1827   Py_DECREF(fi);
1828   return 1;
1829 }
1830
1831 struct intpair
1832 {
1833   int *pairs;
1834   int count;
1835 };
1836
1837 static int convert_to_intpair(PyObject *o, intpair *dst, const char *name = "no_name")
1838 {
1839   PyObject *fi = PySequence_Fast(o, name);
1840   if (fi == NULL)
1841     return 0;
1842   dst->count = PySequence_Fast_GET_SIZE(fi);
1843   dst->pairs = new int[2 * dst->count];
1844   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1845     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1846     if (!PyArg_ParseTuple(item, "ii", &dst->pairs[2 * i], &dst->pairs[2 * i + 1])) {
1847       return 0;
1848     }
1849   }
1850   Py_DECREF(fi);
1851   return 1;
1852 }
1853
1854 struct cvpoint2d32f_count {
1855   CvPoint2D32f* points;
1856   int count;
1857 };
1858
1859 static int convert_to_cvpoint2d32f_count(PyObject *o, cvpoint2d32f_count *dst, const char *name = "no_name")
1860 {
1861   if (PyInt_Check(o)) {
1862     dst->count = PyInt_AsLong(o);
1863     dst->points = new CvPoint2D32f[dst->count];
1864     return 1;
1865   } else {
1866     return failmsg("Expected integer for CvPoint2D32f count");
1867   }
1868 }
1869
1870 struct floats {
1871   float *f;
1872   int count;
1873 };
1874 static int convert_to_floats(PyObject *o, floats *dst, const char *name = "no_name")
1875 {
1876   PyObject *fi = PySequence_Fast(o, name);
1877   if (fi == NULL)
1878     return 0;
1879   dst->count = PySequence_Fast_GET_SIZE(fi);
1880   dst->f = new float[dst->count];
1881   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1882     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1883     dst->f[i] = (float)PyFloat_AsDouble(item);
1884   }
1885   Py_DECREF(fi);
1886   return 1;
1887 }
1888
1889 struct chars {
1890   char *f;
1891   int count;
1892 };
1893 /// convert_to_chars not used
1894
1895 struct CvPoints {
1896   CvPoint *p;
1897   int count;
1898 };
1899 static int convert_to_CvPoints(PyObject *o, CvPoints *dst, const char *name = "no_name")
1900 {
1901   PyObject *fi = PySequence_Fast(o, name);
1902   if (fi == NULL)
1903     return 0;
1904   dst->count = PySequence_Fast_GET_SIZE(fi);
1905   dst->p = new CvPoint[dst->count];
1906   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1907     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1908     convert_to_CvPoint(item, &dst->p[i], name);
1909   }
1910   Py_DECREF(fi);
1911   return 1;
1912 }
1913
1914 struct CvPoint3D32fs {
1915   CvPoint3D32f *p;
1916   int count;
1917 };
1918 static int convert_to_CvPoint3D32fs(PyObject *o, CvPoint3D32fs *dst, const char *name = "no_name")
1919 {
1920   PyObject *fi = PySequence_Fast(o, name);
1921   if (fi == NULL)
1922     return 0;
1923   dst->count = PySequence_Fast_GET_SIZE(fi);
1924   dst->p = new CvPoint3D32f[dst->count];
1925   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1926     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1927     convert_to_CvPoint3D32f(item, &dst->p[i], name);
1928   }
1929   Py_DECREF(fi);
1930   return 1;
1931 }
1932
1933 struct CvPoint2D32fs {
1934   CvPoint2D32f *p;
1935   int count;
1936 };
1937 static int convert_to_CvPoint2D32fs(PyObject *o, CvPoint2D32fs *dst, const char *name = "no_name")
1938 {
1939   PyObject *fi = PySequence_Fast(o, name);
1940   if (fi == NULL)
1941     return 0;
1942   dst->count = PySequence_Fast_GET_SIZE(fi);
1943   dst->p = new CvPoint2D32f[dst->count];
1944   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1945     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1946     convert_to_CvPoint2D32f(item, &dst->p[i], name);
1947   }
1948   Py_DECREF(fi);
1949   return 1;
1950 }
1951
1952 struct ints {
1953   int *i;
1954   int count;
1955 };
1956 static int convert_to_ints(PyObject *o, ints *dst, const char *name = "no_name")
1957 {
1958   PyObject *fi = PySequence_Fast(o, name);
1959   if (fi == NULL)
1960     return 0;
1961   dst->count = PySequence_Fast_GET_SIZE(fi);
1962   dst->i = new int[dst->count];
1963   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1964     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1965     dst->i[i] = PyInt_AsLong(item);
1966   }
1967   Py_DECREF(fi);
1968   return 1;
1969 }
1970
1971 struct ints0 {
1972   int *i;
1973   int count;
1974 };
1975 static int convert_to_ints0(PyObject *o, ints0 *dst, const char *name = "no_name")
1976 {
1977   PyObject *fi = PySequence_Fast(o, name);
1978   if (fi == NULL)
1979     return 0;
1980   dst->count = PySequence_Fast_GET_SIZE(fi);
1981   dst->i = new int[dst->count + 1];
1982   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
1983     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
1984     dst->i[i] = PyInt_AsLong(item);
1985   }
1986   dst->i[dst->count] = 0;
1987   Py_DECREF(fi);
1988   return 1;
1989 }
1990
1991 struct dims
1992 {
1993   int count;
1994   int i[CV_MAX_DIM];
1995   int step[CV_MAX_DIM];
1996   int length[CV_MAX_DIM];
1997 };
1998
1999 static int convert_to_dim(PyObject *item, int i, dims *dst, CvArr *cva, const char *name = "no_name")
2000 {
2001   if (PySlice_Check(item)) {
2002     Py_ssize_t start, stop, step, slicelength;
2003     PySlice_GetIndicesEx((PySliceObject*)item, cvGetDimSize(cva, i), &start, &stop, &step, &slicelength);
2004     dst->i[i] = start;
2005     dst->step[i] = step;
2006     dst->length[i] = slicelength;
2007   } else {
2008     int index = PyInt_AsLong(item);
2009     if (0 <= index)
2010       dst->i[i] = index;
2011     else
2012       dst->i[i] = cvGetDimSize(cva, i) + index;
2013     dst->step[i] = 0;
2014     dst->length[i] = 1;
2015   }
2016   return 1;
2017 }
2018
2019 static int convert_to_dims(PyObject *o, dims *dst, CvArr *cva, const char *name = "no_name")
2020 {
2021   if (!PyTuple_Check(o)) {
2022     dst->count = 1;
2023     return convert_to_dim(o, 0, dst, cva, name);
2024   } else {
2025     PyObject *fi = PySequence_Fast(o, name);
2026     if (fi == NULL) {
2027       PyErr_SetString(PyExc_TypeError, "Expected tuple for index");
2028       return 0;
2029     }
2030     dst->count = PySequence_Fast_GET_SIZE(fi);
2031     for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
2032       if (i >= cvGetDims(cva)) {
2033         return failmsg("Access specifies %d dimensions, but array only has %d", PySequence_Fast_GET_SIZE(fi), cvGetDims(cva));
2034       }
2035       PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
2036       if (!convert_to_dim(item, i, dst, cva, name))
2037         return 0;
2038     }
2039     Py_DECREF(fi);
2040     return 1;
2041   }
2042 }
2043
2044 struct IplImages {
2045   IplImage **ims;
2046   int count;
2047 };
2048 static int convert_to_IplImages(PyObject *o, IplImages *dst, const char *name = "no_name")
2049 {
2050   PyObject *fi = PySequence_Fast(o, name);
2051   if (fi == NULL)
2052     return 0;
2053   dst->count = PySequence_Fast_GET_SIZE(fi);
2054   dst->ims = new IplImage*[dst->count];
2055   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
2056     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
2057     if (!convert_to_IplImage(item, &dst->ims[i]))
2058       return 0;
2059   }
2060   Py_DECREF(fi);
2061   return 1;
2062 }
2063
2064 struct CvArrs {
2065   CvArr **ims;
2066   int count;
2067 };
2068 static int convert_to_CvArrs(PyObject *o, CvArrs *dst, const char *name = "no_name")
2069 {
2070   PyObject *fi = PySequence_Fast(o, name);
2071   if (fi == NULL)
2072     return 0;
2073   dst->count = PySequence_Fast_GET_SIZE(fi);
2074   dst->ims = new CvArr*[dst->count];
2075   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
2076     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
2077     if (!convert_to_CvArr(item, &dst->ims[i]))
2078       return 0;
2079   }
2080   Py_DECREF(fi);
2081   return 1;
2082 }
2083
2084 static int convert_to_floatPTRPTR(PyObject *o, float*** dst, const char *name = "no_name")
2085 {
2086   PyObject *fi = PySequence_Fast(o, name);
2087   if (fi == NULL)
2088     return 0;
2089   Py_ssize_t sz = PySequence_Fast_GET_SIZE(fi);
2090   float **r = new float*[sz];
2091   for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
2092     PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
2093     floats ff;
2094     if (!convert_to_floats(item, &ff))
2095       return 0;
2096     r[i] = ff.f;
2097   }
2098   *dst = r;
2099   return 1;
2100 }
2101
2102 static int convert_to_IplConvKernelPTR(PyObject *o, IplConvKernel** dst, const char *name = "no_name")
2103 {
2104   if (PyType_IsSubtype(o->ob_type, &iplconvkernel_Type)) {
2105     *dst = ((iplconvkernel_t*)o)->a;
2106     return 1;
2107   } else {
2108     (*dst) = (IplConvKernel*)NULL;
2109     return failmsg("Expected IplConvKernel for argument '%s'", name);
2110   }
2111 }
2112
2113 static int convert_to_CvCapturePTR(PyObject *o, CvCapture** dst, const char *name = "no_name")
2114 {
2115   if (PyType_IsSubtype(o->ob_type, &cvcapture_Type)) {
2116     *dst = ((cvcapture_t*)o)->a;
2117     return 1;
2118   } else {
2119     (*dst) = (CvCapture*)NULL;
2120     return failmsg("Expected CvCapture for argument '%s'", name);
2121   }
2122 }
2123
2124 static int convert_to_CvVideoWriterPTR(PyObject *o, CvVideoWriter** dst, const char *name = "no_name")
2125 {
2126   if (PyType_IsSubtype(o->ob_type, &cvvideowriter_Type)) {
2127     *dst = ((cvvideowriter_t*)o)->a;
2128     return 1;
2129   } else {
2130     (*dst) = (CvVideoWriter*)NULL;
2131     return failmsg("Expected CvVideoWriter for argument '%s'", name);
2132   }
2133 }
2134
2135 static int convert_to_CvMomentsPTR(PyObject *o, CvMoments** dst, const char *name = "no_name")
2136 {
2137   if (PyType_IsSubtype(o->ob_type, &cvmoments_Type)) {
2138     (*dst) = &(((cvmoments_t*)o)->a);
2139     return 1;
2140   } else {
2141     (*dst) = (CvMoments*)NULL;
2142     return failmsg("Expected CvMoments for argument '%s'", name);
2143   }
2144 }
2145
2146 static int convert_to_CvFontPTR(PyObject *o, CvFont** dst, const char *name = "no_name")
2147 {
2148   if (PyType_IsSubtype(o->ob_type, &cvfont_Type)) {
2149     (*dst) = &(((cvfont_t*)o)->a);
2150     return 1;
2151   } else {
2152     (*dst) = (CvFont*)NULL;
2153     return failmsg("Expected CvFont for argument '%s'", name);
2154   }
2155 }
2156
2157 static int convert_to_CvHaarClassifierCascadePTR(PyObject *o, CvHaarClassifierCascade** dst, const char *name = "no_name")
2158 {
2159   if (PyType_IsSubtype(o->ob_type, &cvhaarclassifiercascade_Type)) {
2160     (*dst) = ((cvhaarclassifiercascade_t*)o)->a;
2161     return 1;
2162   } else {
2163     (*dst) = (CvHaarClassifierCascade*)NULL;
2164     return failmsg("Expected CvHaarClassifierCascade for argument '%s'", name);
2165   }
2166 }
2167
2168 static int convert_to_CvContourTreePTR(PyObject *o, CvContourTree** dst, const char *name = "no_name")
2169 {
2170   if (PyType_IsSubtype(o->ob_type, &cvcontourtree_Type)) {
2171     (*dst) = ((cvcontourtree_t*)o)->a;
2172     return 1;
2173   } else {
2174     (*dst) = NULL;
2175     return failmsg("Expected CvContourTree for argument '%s'", name);
2176   }
2177 }
2178
2179 static int convert_to_CvPOSITObjectPTR(PyObject *o, CvPOSITObject** dst, const char *name = "no_name")
2180 {
2181   if (PyType_IsSubtype(o->ob_type, &cvpositobject_Type)) {
2182     (*dst) = ((cvpositobject_t*)o)->a;
2183     return 1;
2184   } else {
2185     (*dst) = (CvPOSITObject*)NULL;
2186     return failmsg("Expected CvPOSITObject for argument '%s'", name);
2187   }
2188 }
2189
2190 static int convert_to_CvRNGPTR(PyObject *o, CvRNG** dst, const char *name = "no_name")
2191 {
2192   if (PyType_IsSubtype(o->ob_type, &cvrng_Type)) {
2193     (*dst) = &(((cvrng_t*)o)->a);
2194     return 1;
2195   } else {
2196     (*dst) = (CvRNG*)NULL;
2197     return failmsg("Expected CvRNG for argument '%s'", name);
2198   }
2199 }
2200
2201 typedef void* generic;
2202 static int convert_to_generic(PyObject *o, generic *dst, const char *name = "no_name")
2203 {
2204   if (PyType_IsSubtype(o->ob_type, &iplimage_Type))
2205     return convert_to_IplImage(o, (IplImage**)dst, name);
2206   else if (PyType_IsSubtype(o->ob_type, &cvmat_Type))
2207     return convert_to_CvMat(o, (CvMat**)dst, name);
2208   else if (PyType_IsSubtype(o->ob_type, &cvmatnd_Type))
2209     return convert_to_CvMatND(o, (CvMatND**)dst, name);
2210   else {
2211     return failmsg("Cannot identify type of '%s'", name);
2212   }
2213 }
2214
2215 static int convert_to_CvTermCriteria(PyObject *o, CvTermCriteria* dst, const char *name = "no_name")
2216 {
2217   if (!PyArg_ParseTuple(o, "iid", &dst->type, &dst->max_iter, &dst->epsilon))
2218     return 0;
2219   return 1;
2220 }
2221
2222 static int convert_to_CvBox2D(PyObject *o, CvBox2D* dst, const char *name = "no_name")
2223 {
2224   if (!PyArg_ParseTuple(o, "(ff)(ff)f", &dst->center.x, &dst->center.y, &dst->size.width, &dst->size.height, &dst->angle))
2225     return 0;
2226   return 1;
2227 }
2228
2229 static int convert_to_CvSubdiv2DPTR(PyObject *o, CvSubdiv2D** dst, const char *name = "no_name")
2230 {
2231   if (PyType_IsSubtype(o->ob_type, &cvsubdiv2d_Type)) {
2232     (*dst) = (((cvsubdiv2d_t*)o)->a);
2233     return 1;
2234   } else {
2235     (*dst) = (CvSubdiv2D*)NULL;
2236     return failmsg("Expected CvSubdiv2D for argument '%s'", name);
2237   }
2238 }
2239
2240 static int convert_to_CvNextEdgeType(PyObject *o, CvNextEdgeType *dst, const char *name = "no_name")
2241 {
2242   if (!PyInt_Check(o)) {
2243     *dst = (CvNextEdgeType)NULL;
2244     return failmsg("Expected number for CvNextEdgeType argument '%s'", name);
2245   } else {
2246     *dst = (CvNextEdgeType)PyInt_AsLong(o);
2247     return 1;
2248   }
2249 }
2250
2251 static int convert_to_CvSubdiv2DEdge(PyObject *o, CvSubdiv2DEdge *dst, const char *name = "no_name")
2252 {
2253   if (PyType_IsSubtype(o->ob_type, &cvsubdiv2dedge_Type)) {
2254     (*dst) = (((cvsubdiv2dedge_t*)o)->a);
2255     return 1;
2256   } else {
2257     *dst = 0L;
2258     return failmsg("Expected CvSubdiv2DEdge for argument '%s'", name);
2259   }
2260 }
2261
2262 /************************************************************************/
2263
2264 static PyObject *pythonize_CvMat(cvmat_t *m)
2265 {
2266   // Need to make this CvMat look like any other, with a Python 
2267   // buffer object as its data.
2268   // So copy the image data into a Python string object, then release 
2269   // the original.
2270   CvMat *mat = m->a;
2271   assert(mat->step != 0);
2272 #if 0
2273   PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->rows * mat->step);
2274 #else
2275   memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
2276   size_t gap = mat->data.ptr - (uchar*)mat->refcount;
2277   o->ptr = mat->refcount;
2278   o->size = gap + mat->rows * mat->step;
2279   PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)gap, mat->rows * mat->step);
2280   if (data == NULL)
2281     return NULL;
2282 #endif
2283   m->data = data;
2284   m->offset = 0;
2285   Py_DECREF(o);
2286
2287   // Now m has a reference to data, which has a reference to o.
2288
2289   // cvDecRefData(mat); // Ref count should be zero here, so this is a release
2290   return (PyObject*)m;
2291 }
2292
2293 static PyObject *pythonize_IplImage(iplimage_t *cva)
2294 {
2295   // Need to make this iplimage look like any other, with a Python 
2296   // string as its data.
2297   // So copy the image data into a Python string object, then release 
2298   // it.
2299
2300   IplImage *ipl = (IplImage*)(cva->a);
2301   // PyObject *data = PyString_FromStringAndSize(ipl->imageData, ipl->imageSize);
2302
2303   memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
2304   assert(ipl->imageDataOrigin == ipl->imageData);
2305   o->ptr = ipl->imageDataOrigin;
2306   o->size = ipl->height * ipl->widthStep;
2307   PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size);
2308   if (data == NULL)
2309     return NULL;
2310   Py_DECREF(o);
2311   cva->data = data;
2312   cva->offset = 0;
2313
2314   return (PyObject*)cva;
2315 }
2316
2317 static PyObject *pythonize_CvMatND(cvmatnd_t *m)
2318 {
2319   //
2320   // Need to make this CvMatND look like any other, with a Python 
2321   // string as its data.
2322   // So copy the image data into a Python string object, then release 
2323   // it.
2324   //
2325
2326   CvMatND *mat = m->a;
2327   assert(mat->dim[0].step != 0);
2328 #if 0
2329   PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->dim[0].size * mat->dim[0].step);
2330 #else
2331   memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
2332   o->ptr = cvPtr1D(mat, 0);
2333   o->size = cvmatnd_size(mat);
2334   PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size);
2335   if (data == NULL)
2336     return NULL;
2337 #endif
2338   m->data = data;
2339   m->offset = 0;
2340   // cvDecRefData(mat); // Ref count should be zero here, so this is a release
2341
2342   return (PyObject*)m;
2343 }
2344
2345 /************************************************************************/
2346 /* FROM_xxx:   C -> Python converters.
2347  *
2348  * Turn various OpenCV types (and some aggregate types above)
2349  * into Python objects.  Used by the generated code.
2350  *
2351  * All these functions and macros return a new reference.
2352  */
2353
2354 #define FROM_double(r)  PyFloat_FromDouble(r)
2355 #define FROM_float(r)  PyFloat_FromDouble(r)
2356 #define FROM_int(r)  PyInt_FromLong(r)
2357 #define FROM_unsigned(r)  PyLong_FromUnsignedLong(r)
2358 #define FROM_CvBox2D(r) Py_BuildValue("(ff)(ff)f", r.center.x, r.center.y, r.size.width, r.size.height, r.angle)
2359 #define FROM_CvScalar(r)  Py_BuildValue("(ffff)", r.val[0], r.val[1], r.val[2], r.val[3])
2360 #define FROM_CvPoint(r)  Py_BuildValue("(ii)", r.x, r.y)
2361 #define FROM_CvConnectedComp(r) Py_BuildValue("(fNN)", r.area, FROM_CvScalar(r.value), FROM_CvRect(r.rect))
2362 #define FROM_CvPoint2D32f(r) Py_BuildValue("(ff)", r.x, r.y)
2363 #define FROM_CvSize(r) Py_BuildValue("(ii)", r.width, r.height)
2364 #define FROM_CvRect(r) Py_BuildValue("(iiii)", r.x, r.y, r.width, r.height)
2365 #define FROM_CvSeqPTR(r) _FROM_CvSeqPTR(r, pyobj_storage)
2366 #define FROM_CvSubdiv2DPTR(r) _FROM_CvSubdiv2DPTR(r, pyobj_storage)
2367 #define FROM_CvPoint2D64f(r) Py_BuildValue("(ff)", r.x, r.y)
2368
2369 static PyObject *_FROM_CvSeqPTR(CvSeq *s, PyObject *storage)
2370 {
2371   cvseq_t *ps = PyObject_NEW(cvseq_t, &cvseq_Type);
2372   ps->a = s;
2373   ps->container = storage;
2374   Py_INCREF(ps->container);
2375   return (PyObject*)ps;
2376 }
2377
2378 static PyObject *_FROM_CvSubdiv2DPTR(CvSubdiv2D *s, PyObject *storage)
2379 {
2380   cvsubdiv2d_t *ps = PyObject_NEW(cvsubdiv2d_t, &cvsubdiv2d_Type);
2381   ps->a = s;
2382   ps->container = storage;
2383   Py_INCREF(ps->container);
2384   return (PyObject*)ps;
2385 }
2386
2387 static PyObject *FROM_floats(floats r)
2388 {
2389   PyObject *pr;
2390
2391   pr = PyList_New(r.count);
2392   for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) {
2393     PyList_SetItem(pr, i, PyFloat_FromDouble(r.f[i]));
2394   }
2395   return pr;
2396 }
2397
2398 static PyObject *FROM_chars(chars r)
2399 {
2400   PyObject *pr;
2401
2402   pr = PyList_New(r.count);
2403   for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) {
2404     PyList_SetItem(pr, i, PyInt_FromLong(r.f[i]));
2405   }
2406   return pr;
2407 }
2408
2409 static PyObject *FROM_cvpoint2d32f_count(cvpoint2d32f_count r)
2410 {
2411   PyObject *pr;
2412
2413   pr = PyList_New(r.count);
2414   for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) {
2415     PyList_SetItem(pr, i, FROM_CvPoint2D32f(r.points[i]));
2416   }
2417   return pr;
2418 }
2419
2420 static PyObject *FROM_CvPoint2D32fs(CvPoint2D32fs r)
2421 {
2422   PyObject *pr;
2423
2424   pr = PyList_New(r.count);
2425   for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) {
2426     PyList_SetItem(pr, i, FROM_CvPoint2D32f(r.p[i]));
2427   }
2428   return pr;
2429 }
2430
2431 typedef CvSeq CvSeqOfCvConvexityDefect;
2432 static PyObject *FROM_CvSeqOfCvConvexityDefectPTR(CvSeqOfCvConvexityDefect *r)
2433 {
2434   PyObject *pr;
2435   pr = PyList_New(r->total);
2436   for (int i = 0; i < r->total; i++) {
2437     CvConvexityDefect *pd = CV_GET_SEQ_ELEM(CvConvexityDefect, r, i);
2438     PyList_SetItem(pr, i, Py_BuildValue("(ii)(ii)(ii)f",
2439                                         pd->start->x, pd->start->y, 
2440                                         pd->end->x, pd->end->y, 
2441                                         pd->depth_point->x, pd->depth_point->y, 
2442                                         pd->depth));
2443   }
2444   // This function has copied the CvSeq data into a list.  Hence the
2445   // CvSeq is not being returned to the caller.  Hence, no reference
2446   // count increase for the storage, unlike _FROM_CvSeqPTR.
2447   return pr;
2448 }
2449
2450 typedef CvSeq CvSeqOfCvAvgComp;
2451 static PyObject *FROM_CvSeqOfCvAvgCompPTR(CvSeqOfCvAvgComp *r)
2452 {
2453   PyObject *pr;
2454   pr = PyList_New(r->total);
2455   for (int i = 0; i < r->total; i++) {
2456     CvAvgComp *pd = CV_GET_SEQ_ELEM(CvAvgComp, r, i);
2457     PyList_SetItem(pr, i, Py_BuildValue("(iiii)i",
2458                                         pd->rect.x, pd->rect.y, 
2459                                         pd->rect.width, pd->rect.height, 
2460                                         pd->neighbors));
2461   }
2462   // This function has copied the CvSeq data into a list.  Hence the
2463   // CvSeq is not being returned to the caller.  Hence, no reference
2464   // count increase for the storage, unlike _FROM_CvSeqPTR.
2465   return pr;
2466 }
2467
2468 typedef CvSeq CvSeqOfCvStarKeypoint;
2469 static PyObject *FROM_CvSeqOfCvStarKeypointPTR(CvSeqOfCvStarKeypoint *r)
2470 {
2471   PyObject *pr;
2472   pr = PyList_New(r->total);
2473   for (int i = 0; i < r->total; i++) {
2474     CvStarKeypoint *pd = CV_GET_SEQ_ELEM(CvStarKeypoint, r, i);
2475     PyList_SetItem(pr, i, Py_BuildValue("(ii)if",
2476                                         pd->pt.x, pd->pt.y, 
2477                                         pd->size,
2478                                         pd->response));
2479   }
2480   // This function has copied the CvSeq data into a list.  Hence the
2481   // CvSeq is not being returned to the caller.  Hence, no reference
2482   // count increase for the storage, unlike _FROM_CvSeqPTR.
2483   return pr;
2484 }
2485
2486 typedef CvSeq CvSeqOfCvSURFPoint;
2487 static PyObject *FROM_CvSeqOfCvSURFPointPTR(CvSeqOfCvSURFPoint *r)
2488 {
2489   PyObject *pr;
2490   pr = PyList_New(r->total);
2491   for (int i = 0; i < r->total; i++) {
2492     CvSURFPoint *pd = CV_GET_SEQ_ELEM(CvSURFPoint, r, i);
2493     PyList_SetItem(pr, i, Py_BuildValue("(ff)iiff",
2494                                         pd->pt.x, pd->pt.y, 
2495                                         pd->laplacian,
2496                                         pd->size,
2497                                         pd->dir,
2498                                         pd->hessian));
2499   }
2500   // This function has copied the CvSeq data into a list.  Hence the
2501   // CvSeq is not being returned to the caller.  Hence, no reference
2502   // count increase for the storage, unlike _FROM_CvSeqPTR.
2503   return pr;
2504 }
2505
2506 typedef CvSeq CvSeqOfCvSURFDescriptor;
2507 static PyObject *FROM_CvSeqOfCvSURFDescriptorPTR(CvSeqOfCvSURFDescriptor *r)
2508 {
2509   PyObject *pr;
2510   pr = PyList_New(r->total);
2511   for (int i = 0; i < r->total; i++) {
2512     float *pd = (float*)cvGetSeqElem(r, i);
2513     int count = r->elem_size / sizeof(float);
2514     PyObject *oi = PyList_New(count);
2515     for (int j = 0; j < count; j++) {
2516       PyList_SetItem(oi, j, PyFloat_FromDouble(pd[j]));
2517     }
2518     PyList_SetItem(pr, i, oi);
2519   }
2520   // This function has copied the CvSeq data into a list.  Hence the
2521   // CvSeq is not being returned to the caller.  Hence, no reference
2522   // count increase for the storage, unlike _FROM_CvSeqPTR.
2523   return pr;
2524 }
2525
2526 static PyObject *FROM_IplConvKernelPTR(IplConvKernel *r)
2527 {
2528   iplconvkernel_t *ick = PyObject_NEW(iplconvkernel_t, &iplconvkernel_Type);
2529   ick->a = r;
2530   return (PyObject*)ick;
2531 }
2532
2533 static PyObject *FROM_CvCapturePTR(CvCapture *r)
2534 {
2535   cvcapture_t *c = PyObject_NEW(cvcapture_t, &cvcapture_Type);
2536   c->a = r;
2537   return (PyObject*)c;
2538 }
2539
2540 static PyObject *FROM_CvVideoWriterPTR(CvVideoWriter *r)
2541 {
2542   cvvideowriter_t *c = PyObject_NEW(cvvideowriter_t, &cvvideowriter_Type);
2543   c->a = r;
2544   return (PyObject*)c;
2545 }
2546
2547 typedef CvPoint2D32f CvPoint2D32f_4[4];
2548 static PyObject *FROM_CvPoint2D32f_4(CvPoint2D32f* r)
2549 {
2550   return Py_BuildValue("(ff)(ff)(ff)(ff)",
2551                        r[0].x, r[0].y,
2552                        r[1].x, r[1].y,
2553                        r[2].x, r[2].y,
2554                        r[3].x, r[3].y);
2555 }
2556
2557 typedef float CvMatr32f_i[9];
2558
2559 static PyObject *FROM_CvMatr32f_i(CvMatr32f_i r)
2560 {
2561   return Py_BuildValue("(fff)(fff)(fff)",
2562     r[0], r[1], r[2],
2563     r[3], r[4], r[5],
2564     r[6], r[7], r[8]);
2565 }
2566
2567 typedef float CvVect32f_i[3];
2568 static PyObject *FROM_CvVect32f_i(CvVect32f_i r)
2569 {
2570   return Py_BuildValue("fff",
2571     r[0], r[1], r[2]);
2572 }
2573
2574 static PyObject *FROM_CvFont(CvFont r)
2575 {
2576   cvfont_t *cf = PyObject_NEW(cvfont_t, &cvfont_Type);
2577   cf->a = r;
2578   return (PyObject*)cf;
2579 }
2580
2581 static PyObject *FROM_CvSubdiv2DPointPTR(CvSubdiv2DPoint* r)
2582 {
2583   if (r != NULL) {
2584     cvsubdiv2dpoint_t *cf = PyObject_NEW(cvsubdiv2dpoint_t, &cvsubdiv2dpoint_Type);
2585     cf->a = r;
2586     return (PyObject*)cf;
2587   } else {
2588     Py_INCREF(Py_None);
2589     return Py_None;
2590   }
2591 }
2592
2593 static PyObject *FROM_IplImagePTR(IplImage *r)
2594 {
2595   iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type);
2596   cva->a = r;
2597   return pythonize_IplImage(cva);
2598 }
2599
2600 static PyObject *FROM_ROIplImagePTR(ROIplImage *r)
2601 {
2602   if (r != NULL) {
2603     iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type);
2604     cva->a = cvCreateImageHeader(cvSize(100,100), 8, 1);
2605     *(cva->a) = *r;
2606     cva->data = PyBuffer_FromReadWriteMemory(r->imageData, r->height * r->widthStep);
2607     cva->offset = 0;
2608     return (PyObject*)cva;
2609   } else {
2610     Py_RETURN_NONE;
2611   }
2612 }
2613
2614 static PyObject *FROM_CvMatPTR(CvMat *r)
2615 {
2616   cvmat_t *cvm = PyObject_NEW(cvmat_t, &cvmat_Type);
2617   cvm->a = r;
2618
2619   return pythonize_CvMat(cvm);
2620 }
2621
2622 static PyObject *FROM_CvMat(CvMat *r)
2623 {
2624   cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type);
2625   m->a = r;
2626   return pythonize_CvMat(m);
2627 }
2628
2629 static PyObject *FROM_CvMatNDPTR(CvMatND *r)
2630 {
2631   cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
2632   m->a = r;
2633   return pythonize_CvMatND(m);
2634 }
2635
2636 static PyObject *FROM_CvPOSITObjectPTR(CvPOSITObject *r)
2637 {
2638   cvpositobject_t *m = PyObject_NEW(cvpositobject_t, &cvpositobject_Type);
2639   m->a = r;
2640   return (PyObject*)m;
2641 }
2642
2643 static PyObject *FROM_CvRNG(CvRNG r)
2644 {
2645   cvrng_t *m = PyObject_NEW(cvrng_t, &cvrng_Type);
2646   m->a = r;
2647   return (PyObject*)m;
2648 }
2649
2650 static PyObject *FROM_CvHaarClassifierCascade(CvHaarClassifierCascade *r)
2651 {
2652   cvhaarclassifiercascade_t *m = PyObject_NEW(cvhaarclassifiercascade_t, &cvhaarclassifiercascade_Type);
2653   m->a = r;
2654   return (PyObject*)m;
2655 }
2656
2657 static PyObject *FROM_CvMoments(CvMoments r)
2658 {
2659   cvmoments_t *m = PyObject_NEW(cvmoments_t, &cvmoments_Type);
2660   m->a = r;
2661   return (PyObject*)m;
2662 }
2663
2664 static PyObject *FROM_CvContourTreePTR(CvContourTree *r)
2665 {
2666   cvcontourtree_t *m = PyObject_NEW(cvcontourtree_t, &cvcontourtree_Type);
2667   m->a = r;
2668   return (PyObject*)m;
2669 }
2670
2671 static PyObject *FROM_generic(generic r)
2672 {
2673   CvTypeInfo* t = cvTypeOf(r);
2674   if (r == NULL) {
2675     failmsg("OpenCV returned NULL");
2676     return NULL;
2677   } if (strcmp(t->type_name, "opencv-image") == 0)
2678     return FROM_IplImagePTR((IplImage*)r);
2679   else if (strcmp(t->type_name, "opencv-matrix") == 0)
2680     return FROM_CvMat((CvMat*)r);
2681   else if (strcmp(t->type_name, "opencv-haar-classifier") == 0)
2682     return FROM_CvHaarClassifierCascade((CvHaarClassifierCascade*)r);
2683   else {
2684     failmsg("Unknown OpenCV type '%s'", t->type_name);
2685     return NULL;
2686   }
2687 }
2688
2689 static PyObject *FROM_CvSubdiv2DEdge(CvSubdiv2DEdge r)
2690 {
2691   cvsubdiv2dedge_t *m = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type);
2692   m->a = r;
2693   m->container = Py_None; // XXX
2694   Py_INCREF(m->container);
2695   return (PyObject*)m;
2696 }
2697
2698 /************************************************************************/
2699
2700 /* A few functions are too odd to be generated, 
2701  * so are handwritten here */
2702
2703 static PyObject *pycvWaitKey(PyObject *self, PyObject *args, PyObject *kw)
2704 {
2705   int delay = 0;
2706
2707   const char *keywords[] = { "delay", NULL };
2708   if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", (char**)keywords, &delay))
2709     return NULL;
2710   int r;
2711   Py_BEGIN_ALLOW_THREADS
2712   r = cvWaitKey(delay);
2713   Py_END_ALLOW_THREADS
2714   return FROM_int(r);
2715 }
2716
2717 static PyObject *pycvLoadImage(PyObject *self, PyObject *args, PyObject *kw)
2718 {
2719   const char *keywords[] = { "filename", "iscolor", NULL };
2720   char *filename;
2721   int iscolor = CV_LOAD_IMAGE_COLOR;
2722
2723   if (!PyArg_ParseTupleAndKeywords(args, kw, "s|i", (char**)keywords, &filename, &iscolor))
2724     return NULL;
2725
2726   // Inside ALLOW_THREADS, must not reference 'filename' because it might move.
2727   // So make a local copy 'filename_copy'.
2728   char filename_copy[2048];
2729   strncpy(filename_copy, filename, sizeof(filename_copy));
2730
2731   IplImage *r;
2732   Py_BEGIN_ALLOW_THREADS
2733   r = cvLoadImage(filename_copy, iscolor);
2734   Py_END_ALLOW_THREADS
2735
2736   if (r == NULL) {
2737     PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
2738     return NULL;
2739   } else {
2740     return FROM_IplImagePTR(r);
2741   }
2742 }
2743
2744 static PyObject *pycvCreateImageHeader(PyObject *self, PyObject *args)
2745 {
2746   int w, h, depth, channels;
2747   if (!PyArg_ParseTuple(args, "(ii)Ii", &w, &h, &depth, &channels))
2748     return NULL;
2749   iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type);
2750   cva->a = cvCreateImageHeader(cvSize(w, h), depth, channels);
2751   if (cva->a == NULL) {
2752     PyErr_SetString(PyExc_TypeError, "CreateImage failed");
2753     return NULL;
2754   } else {
2755     cva->data = Py_None;
2756     Py_INCREF(cva->data);
2757     cva->offset = 0;
2758
2759     return (PyObject*)cva;
2760   }
2761 }
2762
2763 static PyObject *pycvCreateImage(PyObject *self, PyObject *args)
2764 {
2765   int w, h, depth, channels;
2766   if (!PyArg_ParseTuple(args, "(ii)Ii:CreateImage", &w, &h, &depth, &channels))
2767     return NULL;
2768   iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type);
2769   ERRWRAP(cva->a = cvCreateImage(cvSize(w, h), depth, channels));
2770   if (cva->a == NULL) {
2771     PyErr_SetString(PyExc_TypeError, "CreateImage failed");
2772     return NULL;
2773   } else {
2774     return pythonize_IplImage(cva);
2775   }
2776 }
2777
2778 static PyObject *pycvCreateMatHeader(PyObject *self, PyObject *args)
2779 {
2780   int rows, cols, type;
2781   if (!PyArg_ParseTuple(args, "iii", &rows, &cols, &type))
2782     return NULL;
2783   cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type);
2784   ERRWRAP(m->a = cvCreateMatHeader(rows, cols, type));
2785   if (m->a == NULL) {
2786     PyErr_SetString(PyExc_TypeError, "CreateMat failed");
2787     return NULL;
2788   } else {
2789     m->data = Py_None;
2790     Py_INCREF(m->data);
2791     m->offset = 0;
2792     return (PyObject*)m;
2793   }
2794 }
2795
2796 static PyObject *pycvCreateMat(PyObject *self, PyObject *args)
2797 {
2798   int rows, cols, type;
2799   if (!PyArg_ParseTuple(args, "iii", &rows, &cols, &type))
2800     return NULL;
2801   cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type);
2802   ERRWRAP(m->a = cvCreateMat(rows, cols, type));
2803   if (m->a == NULL) {
2804     PyErr_SetString(PyExc_TypeError, "CreateMat failed");
2805     return NULL;
2806   } else {
2807     return pythonize_CvMat(m);
2808   }
2809 }
2810
2811 static PyObject *pycvCreateMatNDHeader(PyObject *self, PyObject *args)
2812 {
2813   ints dims;
2814   int type;
2815
2816   if (!PyArg_ParseTuple(args, "O&i", convert_to_ints, (void*)&dims, &type))
2817     return NULL;
2818   cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
2819   ERRWRAP(m->a = cvCreateMatNDHeader(dims.count, dims.i, type));
2820
2821   m->data = Py_None;
2822   Py_INCREF(m->data);
2823   return (PyObject*)m;
2824 }
2825
2826
2827 static PyObject *pycvCreateMatND(PyObject *self, PyObject *args)
2828 {
2829   ints dims;
2830   int type;
2831
2832   if (!PyArg_ParseTuple(args, "O&i", convert_to_ints, (void*)&dims, &type))
2833     return NULL;
2834   cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
2835   ERRWRAP(m->a = cvCreateMatND(dims.count, dims.i, type));
2836   return pythonize_CvMatND(m);
2837 }
2838
2839 #if PYTHON_NUMPY
2840 static PyObject *pycvfromarray(PyObject *self, PyObject *args)
2841 {
2842   PyObject *o;
2843   if (!PyArg_ParseTuple(args, "O", &o)) {
2844     return NULL;
2845   }
2846
2847   PyObject *ao = PyObject_GetAttrString(o, "__array_struct__");
2848   if ((ao == NULL) || !PyCObject_Check(ao)) {
2849     PyErr_SetString(PyExc_TypeError, "object does not have array interface");
2850     return NULL;
2851   }
2852   PyArrayInterface *pai = (PyArrayInterface*)PyCObject_AsVoidPtr(ao);
2853   if (pai->two != 2) {
2854     PyErr_SetString(PyExc_TypeError, "object does not have array interface");
2855     return NULL;
2856   }
2857
2858   cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
2859   int type = -1;
2860
2861   switch (pai->typekind) {
2862   case 'i':
2863     if (pai->itemsize == 1)
2864       type = CV_8SC1;
2865     else if (pai->itemsize == 2)
2866       type = CV_16SC1;
2867     else if (pai->itemsize == 4)
2868       type = CV_32SC1;
2869     break;
2870
2871   case 'u':
2872     if (pai->itemsize == 1)
2873       type = CV_8UC1;
2874     else if (pai->itemsize == 2)
2875       type = CV_16UC1;
2876     break;
2877
2878   case 'f':
2879     if (pai->itemsize == 4)
2880       type = CV_32FC1;
2881     else if (pai->itemsize == 8)
2882       type = CV_64FC1;
2883     break;
2884   }
2885   ERRWRAP(m->a = cvCreateMatND(pai->nd, pai->shape, type));
2886   m->a->data.ptr = (uchar*)pai->data;
2887   return pythonize_CvMatND(m);
2888 }
2889 #endif
2890
2891 static PyObject *pycvCreateHist(PyObject *self, PyObject *args)
2892 {
2893   PyObject *dims;
2894   int type;
2895   float **ranges = NULL;
2896   int uniform = 1;
2897
2898   if (!PyArg_ParseTuple(args, "Oi|O&i", &dims, &type, convert_to_floatPTRPTR, (void*)&ranges, &uniform)) {
2899     return NULL;
2900   }
2901   cvhistogram_t *h = PyObject_NEW(cvhistogram_t, &cvhistogram_Type);
2902   args = Py_BuildValue("Oi", dims, CV_32FC1);
2903   h->bins = pycvCreateMatND(self, args);
2904   Py_DECREF(args);
2905   if (h->bins == NULL) {
2906     return NULL;
2907   }
2908   h->h.type = CV_HIST_MAGIC_VAL;
2909   if (!convert_to_CvArr(h->bins, &(h->h.bins), "bins"))
2910     return NULL;
2911
2912   ERRWRAP(cvSetHistBinRanges(&(h->h), ranges, uniform));
2913
2914   return (PyObject*)h;
2915 }
2916
2917 static PyObject *pycvInitLineIterator(PyObject *self, PyObject *args)
2918 {
2919   CvArr *image;
2920   CvPoint pt1;
2921   CvPoint pt2;
2922   int connectivity = 8;
2923   int left_to_right = 0;
2924
2925   if (!PyArg_ParseTuple(args, "O&O&O&|ii",
2926                         convert_to_CvArr, &image,
2927                         convert_to_CvPoint, &pt1,
2928                         convert_to_CvPoint, &pt2,
2929                         &connectivity,
2930                         &left_to_right))
2931     return NULL;
2932
2933   cvlineiterator_t *pi = PyObject_NEW(cvlineiterator_t, &cvlineiterator_Type);
2934   pi->count = cvInitLineIterator(image, pt1, pt2, &pi->iter, connectivity, left_to_right);
2935   ERRWRAP(pi->type = cvGetElemType(image));
2936   return (PyObject*)pi;
2937 }
2938
2939 static PyObject *pycvCreateMemStorage(PyObject *self, PyObject *args)
2940 {
2941   int block_size = 0;
2942   if (!PyArg_ParseTuple(args, "|i", &block_size))
2943     return NULL;
2944   cvmemstorage_t *pm = PyObject_NEW(cvmemstorage_t, &cvmemstorage_Type);
2945   pm->a = cvCreateMemStorage(block_size);
2946   return (PyObject*)pm;
2947 }
2948
2949 // single index: return row
2950 // 2 indices: row, column
2951 // both row and column can be slices.  column slice must have a step of 1.
2952 //
2953 // returns a scalar when all dimensions are specified and all are integers.  Otherwise returns a CvMat.
2954 //
2955 static PyObject *cvarr_GetItem(PyObject *o, PyObject *key)
2956 {
2957   dims dd;
2958
2959   CvArr *cva;
2960   if (!convert_to_CvArr(o, &cva, "src"))
2961     return NULL;
2962
2963   if (!convert_to_dims(key, &dd, cva, "key")) {
2964     return NULL;
2965   }
2966
2967   // Figure out if all supplied indices have a stride of zero - means they are not slices
2968   // and if all indices are positive
2969   int all0 = 1;
2970   for (int i = 0; i < dd.count; i++) {
2971     all0 &= (dd.step[i] == 0) && (0 <= dd.i[i]);
2972   }
2973
2974   // if every dimension supplied, and none are slices, return the scalar
2975   if ((cvGetDims(cva) == dd.count) && all0) {
2976     CvScalar s;
2977     ERRWRAP(s = cvGetND(cva, dd.i));
2978     return PyObject_FromCvScalar(s, cvGetElemType(cva));
2979   } else {
2980     // pad missing dimensions
2981     for (int i = dd.count; i < cvGetDims(cva); i++) {
2982       dd.i[i] = 0;
2983       dd.step[i] = 1;
2984       dd.length[i] = cvGetDimSize(cva, i);
2985     }
2986     dd.count = cvGetDims(cva);
2987
2988     // negative steps are illegal for OpenCV
2989     for (int i = 0; i < dd.count; i++) {
2990       if (dd.step[i] < 0)
2991         return (PyObject*)failmsg("Negative step is illegal");
2992     }
2993
2994     // zero length illegal for OpenCV
2995     for (int i = 0; i < dd.count; i++) {
2996       if (dd.length[i] == 0)
2997         return (PyObject*)failmsg("Zero sized dimension is illegal");
2998     }
2999
3000     // column step can only be 0 or 1
3001     if ((dd.step[dd.count-1] != 0) && (dd.step[dd.count-1] != 1))
3002         return (PyObject*)failmsg("Column step is illegal");
3003
3004     if (is_cvmat(o) || is_iplimage(o)) {
3005       cvmat_t *sub = PyObject_NEW(cvmat_t, &cvmat_Type);
3006       sub->a = cvCreateMatHeader(dd.length[0], dd.length[1], cvGetElemType(cva));
3007       uchar *old0;  // pointer to first element in old mat
3008       int oldstep;
3009       cvGetRawData(cva, &old0, &oldstep);
3010       uchar *new0;  // pointer to first element in new mat
3011       ERRWRAP(new0 = cvPtrND(cva, dd.i));
3012
3013       sub->a->step = oldstep * dd.step[0];
3014       sub->data = what_data(o);
3015       Py_INCREF(sub->data);
3016       sub->offset = new0 - old0;
3017       return (PyObject*)sub;
3018     } else {
3019       cvmatnd_t *sub = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
3020       sub->a = cvCreateMatNDHeader(dd.count, dd.length, cvGetElemType(cva));
3021       uchar *old0;  // pointer to first element in old mat
3022       cvGetRawData(cva, &old0);
3023       uchar *new0;  // pointer to first element in new mat
3024       ERRWRAP(new0 = cvPtrND(cva, dd.i));
3025
3026       for (int d = 0; d < dd.count; d++) {
3027         int stp = dd.step[d];
3028         sub->a->dim[d].step = ((CvMatND*)cva)->dim[d].step * ((stp == 0) ? 1 : stp);
3029         sub->a->dim[d].size = dd.length[d];
3030       }
3031       sub->data = what_data(o);
3032       Py_INCREF(sub->data);
3033       sub->offset = new0 - old0;
3034       return (PyObject*)sub;
3035     }
3036   }
3037 }
3038
3039 static int cvarr_SetItem(PyObject *o, PyObject *key, PyObject *v)
3040 {
3041   dims dd;
3042
3043   CvArr *cva;
3044   if (!convert_to_CvArr(o, &cva, "src"))
3045     return -1;
3046
3047   if (!convert_to_dims(key, &dd, cva, "key")) {
3048     return -1;
3049   }
3050
3051   if (cvGetDims(cva) != dd.count) {
3052     PyErr_SetString(PyExc_TypeError, "key length does not match array dimension");
3053     return -1;
3054   }
3055
3056   CvScalar s;
3057   if (PySequence_Check(v)) {
3058     PyObject *fi = PySequence_Fast(v, "v");
3059     if (fi == NULL)
3060       return -1;
3061     if (PySequence_Fast_GET_SIZE(fi) != CV_MAT_CN(cvGetElemType(cva))) {
3062       PyErr_SetString(PyExc_TypeError, "sequence size must be same as channel count");
3063       return -1;
3064     }
3065     for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++)
3066       s.val[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(fi, i));
3067     Py_DECREF(fi);
3068   } else {
3069     if (1 != CV_MAT_CN(cvGetElemType(cva))) {
3070       PyErr_SetString(PyExc_TypeError, "scalar supplied but channel count does not equal 1");
3071       return -1;
3072     }
3073     s.val[0] = PyFloat_AsDouble(v);
3074   }
3075   switch (dd.count) {
3076   case 1:
3077     cvSet1D(cva, dd.i[0], s);
3078     break;
3079   case 2:
3080     cvSet2D(cva, dd.i[0], dd.i[1], s);
3081     break;
3082   case 3:
3083     cvSet3D(cva, dd.i[0], dd.i[1], dd.i[2], s);
3084     break;
3085   default:
3086     cvSetND(cva, dd.i, s);
3087     // XXX - OpenCV bug? - seems as if an error in cvSetND does not set error status?
3088     break;
3089   }
3090   if (cvGetErrStatus() != 0) {
3091     translate_error_to_exception();
3092     return -1;
3093   }
3094
3095   return 0;
3096 }
3097
3098
3099 static PyObject *pycvSetData(PyObject *self, PyObject *args)
3100 {
3101   PyObject *o, *s;
3102   int step = -1;
3103
3104   if (!PyArg_ParseTuple(args, "OOi", &o, &s, &step))
3105     return NULL;
3106   if (is_iplimage(o)) {
3107     iplimage_t *ipl = (iplimage_t*)o;
3108     ipl->a->widthStep = step;
3109     Py_DECREF(ipl->data);
3110     ipl->data = s;
3111     Py_INCREF(ipl->data);
3112   } else if (is_cvmat(o)) {
3113     cvmat_t *m = (cvmat_t*)o;
3114     m->a->step = step;
3115     Py_DECREF(m->data);
3116     m->data = s;
3117     Py_INCREF(m->data);
3118   } else if (is_cvmatnd(o)) {
3119     cvmatnd_t *m = (cvmatnd_t*)o;
3120     Py_DECREF(m->data);
3121     m->data = s;
3122     Py_INCREF(m->data);
3123   } else {
3124     PyErr_SetString(PyExc_TypeError, "SetData argument must be either IplImage, CvMat or CvMatND");
3125     return NULL;
3126   }
3127
3128   Py_RETURN_NONE;
3129 }
3130
3131 static PyObject *what_data(PyObject *o)
3132 {
3133   if (is_iplimage(o)) {
3134     iplimage_t *ipl = (iplimage_t*)o;
3135     return ipl->data;
3136   } else if (is_cvmat(o)) {
3137     cvmat_t *m = (cvmat_t*)o;
3138     return m->data;
3139   } else if (is_cvmatnd(o)) {
3140     cvmatnd_t *m = (cvmatnd_t*)o;
3141     return m->data;
3142   } else {
3143     assert(0);
3144     return NULL;
3145   }
3146 }
3147
3148 static PyObject *pycvCreateData(PyObject *self, PyObject *args)
3149 {
3150   PyObject *o;
3151
3152   if (!PyArg_ParseTuple(args, "O", &o))
3153     return NULL;
3154
3155   CvArr *a;
3156   if (!convert_to_CvArr(o, &a, "arr"))
3157     return NULL;
3158   ERRWRAP(cvCreateData(a));
3159
3160   Py_DECREF(what_data(o));
3161   if (is_iplimage(o)) {
3162     iplimage_t *ipl = (iplimage_t*)o;
3163     pythonize_IplImage(ipl);
3164   } else if (is_cvmat(o)) {
3165     cvmat_t *m = (cvmat_t*)o;
3166     pythonize_CvMat(m);
3167   } else if (is_cvmatnd(o)) {
3168     cvmatnd_t *m = (cvmatnd_t*)o;
3169     pythonize_CvMatND(m);
3170   } else {
3171     PyErr_SetString(PyExc_TypeError, "CreateData argument must be either IplImage, CvMat or CvMatND");
3172     return NULL;
3173   }
3174
3175   Py_RETURN_NONE;
3176 }
3177
3178 static PyObject *pycvGetDims(PyObject *self, PyObject *args)
3179 {
3180   PyObject *o;
3181
3182   if (!PyArg_ParseTuple(args, "O", &o))
3183     return NULL;
3184   CvArr *cva;
3185   if (!convert_to_CvArr(o, &cva, "src"))
3186     return NULL;
3187
3188   int i, nd;
3189   ERRWRAP(nd = cvGetDims(cva));
3190   PyObject *r = PyTuple_New(nd);
3191   for (i = 0; i < nd; i++)
3192     PyTuple_SetItem(r, i, PyInt_FromLong(cvGetDimSize(cva, i)));
3193   return r;
3194 }
3195
3196 static PyObject *pycvGetImage(PyObject *self, PyObject *args)
3197 {
3198   PyObject *o, *r;
3199
3200   if (!PyArg_ParseTuple(args, "O", &o))
3201     return NULL;
3202   if (is_iplimage(o)) {
3203     r = o;
3204     Py_INCREF(o);
3205   } else {
3206     IplImage *ipl = cvCreateImageHeader(cvSize(100,100), 8, 1); // these args do not matter, because overwritten
3207     CvArr *cva;
3208     if (!convert_to_CvArr(o, &cva, "src"))
3209       return NULL;
3210     ERRWRAP(cvGetImage(cva, ipl));
3211
3212     iplimage_t *oipl = PyObject_NEW(iplimage_t, &iplimage_Type);
3213     oipl->a = ipl;
3214     oipl->data = what_data(o);
3215     Py_INCREF(oipl->data);
3216     oipl->offset = 0;
3217
3218     r = (PyObject*)oipl;
3219   }
3220   return r;
3221 }
3222
3223 static PyObject *pycvGetMat(PyObject *self, PyObject *args, PyObject *kw)
3224 {
3225   const char *keywords[] = { "arr", "allowND", NULL };
3226   PyObject *o, *r;
3227   int allowND = 0;
3228
3229   if (!PyArg_ParseTupleAndKeywords(args, kw, "O|i", (char**)keywords, &o, &allowND))
3230     return NULL;
3231   if (is_cvmat(o)) {
3232     r = o;
3233     Py_INCREF(o);
3234   } else {
3235     CvMat *m = cvCreateMatHeader(100,100, 1); // these args do not matter, because overwritten
3236     CvArr *cva;
3237     if (!convert_to_CvArr(o, &cva, "src"))
3238       return NULL;
3239     ERRWRAP(cvGetMat(cva, m, NULL, allowND));
3240
3241     cvmat_t *om = PyObject_NEW(cvmat_t, &cvmat_Type);
3242     om->a = m;
3243     om->data = what_data(o);
3244     Py_INCREF(om->data);
3245     om->offset = 0;
3246
3247     r = (PyObject*)om;
3248   }
3249   return r;
3250 }
3251
3252 static PyObject *pycvReshape(PyObject *self, PyObject *args)
3253 {
3254   PyObject *o;
3255   int new_cn;
3256   int new_rows = 0;
3257
3258   if (!PyArg_ParseTuple(args, "Oi|i", &o, &new_cn, &new_rows))
3259     return NULL;
3260
3261   CvMat *m = cvCreateMatHeader(100,100, 1); // these args do not matter, because overwritten
3262   CvArr *cva;
3263   if (!convert_to_CvArr(o, &cva, "src"))
3264     return NULL;
3265   ERRWRAP(cvReshape(cva, m, new_cn, new_rows));
3266
3267   cvmat_t *om = PyObject_NEW(cvmat_t, &cvmat_Type);
3268   om->a = m;
3269   om->data = what_data(o);
3270   Py_INCREF(om->data);
3271   om->offset = 0;
3272
3273   return (PyObject*)om;
3274 }
3275
3276 static void OnMouse(int event, int x, int y, int flags, void* param)
3277 {
3278   PyGILState_STATE gstate;
3279   gstate = PyGILState_Ensure();
3280
3281   PyObject *o = (PyObject*)param;
3282   PyObject *args = Py_BuildValue("iiiiO", event, x, y, flags, PyTuple_GetItem(o, 1));
3283
3284   PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
3285   if (r == NULL)
3286     PyErr_Print();
3287   else
3288     Py_DECREF(r);
3289   Py_DECREF(args);
3290   PyGILState_Release(gstate);
3291 }
3292
3293 static PyObject *pycvSetMouseCallback(PyObject *self, PyObject *args, PyObject *kw)
3294 {
3295   const char *keywords[] = { "window_name", "on_mouse", "param", NULL };
3296   char* name;
3297   PyObject *on_mouse;
3298   PyObject *param = NULL;
3299
3300   if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|O", (char**)keywords, &name, &on_mouse, &param))
3301     return NULL;
3302   if (!PyCallable_Check(on_mouse)) {
3303     PyErr_SetString(PyExc_TypeError, "on_mouse must be callable");
3304     return NULL;
3305   }
3306   if (param == NULL) {
3307     param = Py_None;
3308   }
3309   ERRWRAP(cvSetMouseCallback(name, OnMouse, Py_BuildValue("OO", on_mouse, param)));
3310   Py_RETURN_NONE;
3311 }
3312
3313 void OnChange(int pos, void *param)
3314 {
3315   PyGILState_STATE gstate;
3316   gstate = PyGILState_Ensure();
3317
3318   PyObject *o = (PyObject*)param;
3319   PyObject *args = Py_BuildValue("(i)", pos);
3320   PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
3321   if (r == NULL)
3322     PyErr_Print();
3323   Py_DECREF(args);
3324   PyGILState_Release(gstate);
3325 }
3326
3327 static PyObject *pycvCreateTrackbar(PyObject *self, PyObject *args, PyObject *kw)
3328 {
3329   const char *keywords[] = { "trackbar_name", "window_name", "value", "count", "on_change", NULL };
3330   PyObject *on_change;
3331   char* trackbar_name;
3332   char* window_name;
3333   int *value = new int;
3334   int count;
3335
3336   if (!PyArg_ParseTupleAndKeywords(args, kw, "ssiiO", (char**)keywords, &trackbar_name, &window_name, value, &count, &on_change))
3337     return NULL;
3338   if (!PyCallable_Check(on_change)) {
3339     PyErr_SetString(PyExc_TypeError, "on_change must be callable");
3340     return NULL;
3341   }
3342   ERRWRAP(cvCreateTrackbar2(trackbar_name, window_name, value, count, OnChange, Py_BuildValue("OO", on_change, Py_None)));
3343   Py_RETURN_NONE;
3344 }
3345
3346 static PyObject *pycvFindContours(PyObject *self, PyObject *args, PyObject *kw)
3347 {
3348   CvArr* image;
3349   PyObject *pyobj_image = NULL;
3350   CvMemStorage* storage;
3351   PyObject *pyobj_storage = NULL;
3352   CvSeq* first_contour;
3353   int header_size = sizeof(CvContour);
3354   int mode = CV_RETR_LIST;
3355   int method = CV_CHAIN_APPROX_SIMPLE;
3356   CvPoint offset = cvPoint(0,0);
3357   PyObject *pyobj_offset = NULL;
3358
3359   const char *keywords[] = { "image", "storage", "mode", "method", "offset", NULL };
3360   if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|iiO", (char**)keywords, &pyobj_image, &pyobj_storage, &mode, &method, &pyobj_offset))
3361     return NULL;
3362   if (!convert_to_CvArr(pyobj_image, &image, "image")) return NULL;
3363   if (!convert_to_CvMemStorage(pyobj_storage, &storage, "storage")) return NULL;
3364   if ((pyobj_offset != NULL) && !convert_to_CvPoint(pyobj_offset, &offset, "offset")) return NULL;
3365   ERRWRAP(cvFindContours(image, storage, &first_contour, header_size, mode, method, offset));
3366   cvseq_t *ps = PyObject_NEW(cvseq_t, &cvseq_Type);
3367   ps->a = first_contour;
3368   ps->container = PyTuple_GetItem(args, 1); // storage
3369   Py_INCREF(ps->container);
3370   return (PyObject*)ps;
3371 }
3372
3373 static PyObject *pycvApproxPoly(PyObject *self, PyObject *args, PyObject *kw)
3374 {
3375   cvarrseq src_seq;
3376   PyObject *pyobj_src_seq = NULL;
3377   int header_size = sizeof(CvContour);
3378   CvMemStorage* storage;
3379   PyObject *pyobj_storage = NULL;
3380   int method;
3381   double parameter = 0;
3382   int parameter2 = 0;
3383
3384   const char *keywords[] = { "src_seq", "storage", "method", "parameter", "parameter2", NULL };
3385   if (!PyArg_ParseTupleAndKeywords(args, kw, "OOi|di", (char**)keywords, &pyobj_src_seq, &pyobj_storage, &method, &parameter, &parameter2))
3386     return NULL;
3387   if (!convert_to_cvarrseq(pyobj_src_seq, &src_seq, "src_seq")) return NULL;
3388   if (!convert_to_CvMemStorage(pyobj_storage, &storage, "storage")) return NULL;
3389   CvSeq* r;
3390   ERRWRAP(r = cvApproxPoly(src_seq.v, header_size, storage, method, parameter, parameter2));
3391   return FROM_CvSeqPTR(r);
3392 }
3393
3394 static float distance_function_glue( const float* a, const float* b, void* user_param )
3395 {
3396   PyObject *o = (PyObject*)user_param;
3397   PyObject *args = Py_BuildValue("(ff)(ff)O", a[0], a[1], b[0], b[1], PyTuple_GetItem(o, 1));
3398   PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
3399   Py_DECREF(args);
3400   return (float)PyFloat_AsDouble(r);
3401 }
3402
3403 static PyObject *pycvCalcEMD2(PyObject *self, PyObject *args, PyObject *kw)
3404 {
3405   const char *keywords[] = { "signature1", "signature2", "distance_type", "distance_func", "cost_matrix", "flow", "lower_bound", "userdata", NULL };
3406   CvArr* signature1;
3407   PyObject *pyobj_signature1;
3408   CvArr* signature2;
3409   PyObject *pyobj_signature2;
3410   int distance_type;
3411   PyObject *distance_func = NULL;
3412   CvArr* cost_matrix=NULL;
3413   PyObject *pyobj_cost_matrix = NULL;
3414   CvArr* flow=NULL;
3415   PyObject *pyobj_flow = NULL;
3416   float lower_bound = 0.0;
3417   PyObject *userdata = NULL;
3418
3419   if (!PyArg_ParseTupleAndKeywords(args, kw, "OOi|OOOfO", (char**)keywords,
3420                                    &pyobj_signature1,
3421                                    &pyobj_signature2,
3422                                    &distance_type,
3423                                    &distance_func,
3424                                    &pyobj_cost_matrix,
3425                                    &pyobj_flow,
3426                                    &lower_bound,
3427                                    &userdata))
3428     return NULL;
3429   if (!convert_to_CvArr(pyobj_signature1, &signature1, "signature1")) return NULL;
3430   if (!convert_to_CvArr(pyobj_signature2, &signature2, "signature2")) return NULL;
3431   if (pyobj_cost_matrix && !convert_to_CvArr(pyobj_cost_matrix, &cost_matrix, "cost_matrix")) return NULL;
3432   if (pyobj_flow && !convert_to_CvArr(pyobj_flow, &flow, "flow")) return NULL;
3433
3434   if (distance_func == NULL) {
3435     distance_func = Py_None;
3436   }
3437   if (userdata == NULL) {
3438     userdata = Py_None;
3439   }
3440
3441   PyObject *ud = Py_BuildValue("OO", distance_func, userdata);
3442   float r;
3443   ERRWRAP(r = cvCalcEMD2(signature1, signature2, distance_type, distance_function_glue, cost_matrix, flow, &lower_bound, (void*)ud));
3444   Py_DECREF(ud);
3445
3446   return PyFloat_FromDouble(r);
3447 }
3448
3449 static PyObject *pycvSubdiv2DLocate(PyObject *self, PyObject *args)
3450 {
3451   PyObject *pyobj_subdiv;
3452   PyObject *pyobj_pt;
3453   CvSubdiv2D *subdiv;
3454   CvPoint2D32f pt;
3455   CvSubdiv2DEdge edge;
3456   CvSubdiv2DPoint* vertex;
3457
3458   if (!PyArg_ParseTuple(args, "OO", &pyobj_subdiv, &pyobj_pt))
3459     return NULL;
3460   if (!convert_to_CvSubdiv2DPTR(pyobj_subdiv, &subdiv, "subdiv"))
3461     return NULL;
3462   if (!convert_to_CvPoint2D32f(pyobj_pt, &pt, "pt"))
3463     return NULL;
3464
3465   CvSubdiv2DPointLocation loc = cvSubdiv2DLocate(subdiv, pt, &edge, &vertex);
3466   PyObject *r;
3467   switch (loc) {
3468   case CV_PTLOC_INSIDE:
3469   case CV_PTLOC_ON_EDGE:
3470     r = FROM_CvSubdiv2DEdge(edge);
3471     break;
3472   case CV_PTLOC_VERTEX:
3473     r = FROM_CvSubdiv2DPointPTR(vertex);
3474     break;
3475   case CV_PTLOC_OUTSIDE_RECT:
3476     r = Py_None;
3477     Py_INCREF(Py_None);
3478     break;
3479   default:
3480     return (PyObject*)failmsg("Unexpected loc from cvSubdiv2DLocate");
3481   }
3482   return Py_BuildValue("iO", (int)loc, r);;
3483 }
3484
3485 static PyObject *pycvCalcOpticalFlowPyrLK(PyObject *self, PyObject *args)
3486 {
3487   CvArr* prev;
3488   PyObject *pyobj_prev = NULL;
3489   CvArr* curr;
3490   PyObject *pyobj_curr = NULL;
3491   CvArr* prev_pyr;
3492   PyObject *pyobj_prev_pyr = NULL;
3493   CvArr* curr_pyr;
3494   PyObject *pyobj_curr_pyr = NULL;
3495   CvPoint2D32f* prev_features;
3496   PyObject *pyobj_prev_features = NULL;
3497   PyObject *pyobj_curr_features = NULL;
3498   CvPoint2D32f* curr_features;
3499   CvSize win_size;
3500   int level;
3501   CvTermCriteria criteria;
3502   int flags;
3503
3504   if (!PyArg_ParseTuple(args, "OOOOO(ii)i(iif)i|O",
3505     &pyobj_prev, &pyobj_curr, &pyobj_prev_pyr, &pyobj_curr_pyr,
3506     &pyobj_prev_features,
3507     &win_size.width, &win_size.height, &level,
3508     &criteria.type, &criteria.max_iter, &criteria.epsilon,
3509     &flags,
3510     &pyobj_curr_features))
3511     return NULL;
3512   if (!convert_to_CvArr(pyobj_prev, &prev, "prev")) return NULL;
3513   if (!convert_to_CvArr(pyobj_curr, &curr, "curr")) return NULL;
3514   if (!convert_to_CvArr(pyobj_prev_pyr, &prev_pyr, "prev_pyr")) return NULL;
3515   if (!convert_to_CvArr(pyobj_curr_pyr, &curr_pyr, "curr_pyr")) return NULL;
3516   if (!convert_to_CvPoint2D32fPTR(pyobj_prev_features, &prev_features, "prev_features")) return NULL;
3517   int count = (int)PySequence_Length(pyobj_prev_features);
3518   if (flags & CV_LKFLOW_INITIAL_GUESSES) {
3519     failmsg("flag CV_LKFLOW_INITIAL_GUESSES is determined automatically from function arguments - it is not required");
3520     return NULL;
3521   }
3522   if (!pyobj_curr_features) {
3523     curr_features = new CvPoint2D32f[count];
3524   } else {
3525     if (PySequence_Length(pyobj_curr_features) != count) {
3526       failmsg("curr_features must have same length as prev_features");
3527       return NULL;
3528     }
3529     if (!convert_to_CvPoint2D32fPTR(pyobj_curr_features, &curr_features, "curr_features")) return NULL;
3530     flags |= CV_LKFLOW_INITIAL_GUESSES;
3531   }
3532   float *track_error = new float[count];
3533   char* status = new char[count];
3534   ERRWRAP(cvCalcOpticalFlowPyrLK(prev, curr, prev_pyr, curr_pyr, prev_features, curr_features, count, win_size, level, status, track_error, criteria, flags));
3535
3536   cvpoint2d32f_count r0;
3537   r0.points = curr_features;
3538   r0.count = count;
3539
3540   chars r1;
3541   r1.f = status;
3542   r1.count = count;
3543
3544   floats r2;
3545   r2.f = track_error;
3546   r2.count = count;
3547
3548   return Py_BuildValue("NNN", FROM_cvpoint2d32f_count(r0), FROM_chars(r1), FROM_floats(r2));
3549 }
3550
3551 static PyObject *pycvClipLine(PyObject *self, PyObject *args, PyObject *kw)
3552 {
3553   CvSize img_size;
3554   PyObject *pyobj_img_size = NULL;
3555   CvPoint pt1;
3556   PyObject *pyobj_pt1 = NULL;
3557   CvPoint pt2;
3558   PyObject *pyobj_pt2 = NULL;
3559
3560   if (!PyArg_ParseTuple(args, "OOO", &pyobj_img_size, &pyobj_pt1, &pyobj_pt2))
3561     return NULL;
3562   if (!convert_to_CvSize(pyobj_img_size, &img_size, "img_size")) return NULL;
3563   if (!convert_to_CvPoint(pyobj_pt1, &pt1, "pt1")) return NULL;
3564   if (!convert_to_CvPoint(pyobj_pt2, &pt2, "pt2")) return NULL;
3565   int r;
3566   ERRWRAP(r = cvClipLine(img_size, &pt1, &pt2));
3567   if (r == 0) {
3568     Py_RETURN_NONE;
3569   } else {
3570     return Py_BuildValue("NN", FROM_CvPoint(pt1), FROM_CvPoint(pt2));
3571   }
3572 }
3573
3574 static PyObject *temp_test(PyObject *self, PyObject *args)
3575 {
3576 #if 0
3577   CvArr *im = cvLoadImage("../samples/c/lena.jpg", 0);
3578   printf("im=%p\n", im);
3579   CvMat *m = cvEncodeImage(".jpeg", im);
3580 #endif
3581 #if 0
3582   CvArr *im = cvLoadImage("lena.jpg", 0);
3583   float r0[] = { 0, 255 };
3584   float *ranges[] = { r0 };
3585   int hist_size[] = { 256 };
3586   CvHistogram *hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1);
3587   cvCalcHist(im, hist, 0, 0);
3588 #endif
3589
3590 #if 0
3591   CvMat* mat = cvCreateMat( 3, 3, CV_32F );
3592   CvMat row_header, *row;
3593   row = cvReshape( mat, &row_header, 0, 1 );
3594   printf("%d,%d\n", row_header.rows, row_header.cols);
3595   printf("ge %08x\n", cvGetElemType(mat));
3596 #endif
3597
3598 #if 0
3599   CvMat *m = cvCreateMat(1, 10, CV_8UC1);
3600   printf("CvMat stride ===> %d\n", m->step);
3601 #endif
3602
3603 #if 0
3604   CvPoint2D32f src[3] = { { 0,0 }, { 1,0 }, { 0,1 } };
3605   CvPoint2D32f dst[3] = { { 0,0 }, { 17,0 }, { 0,17 } };
3606
3607   CvMat* mapping = cvCreateMat(2, 3, CV_32FC1);
3608   cvGetAffineTransform(src, dst, mapping);
3609   printf("===> %f\n", cvGetReal2D(mapping, 0, 0));
3610 #endif
3611
3612 #if 0
3613   CvArr *im = cvLoadImage("checker77.png");
3614   CvPoint2D32f corners[49];
3615   int count;
3616   cvFindChessboardCorners(im, cvSize(7,7), corners, &count, 0);
3617   printf("count=%d\n", count);
3618 #endif
3619
3620   return PyFloat_FromDouble(0.0);
3621 }
3622
3623 static PyObject *pycvFindChessboardCorners(PyObject *self, PyObject *args, PyObject *kw)
3624 {
3625   CvArr* image;
3626   PyObject *pyobj_image = NULL;
3627   CvSize pattern_size;
3628   PyObject *pyobj_pattern_size = NULL;
3629   cvpoint2d32f_count corners;
3630   int flags = CV_CALIB_CB_ADAPTIVE_THRESH;
3631
3632   const char *keywords[] = { "image", "pattern_size", "flags", NULL };
3633   if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i", (char**)keywords, &pyobj_image, &pyobj_pattern_size, &flags))
3634     return NULL;
3635   if (!convert_to_CvArr(pyobj_image, &image, "image")) return NULL;
3636   if (!convert_to_CvSize(pyobj_pattern_size, &pattern_size, "pattern_size")) return NULL;
3637   int r;
3638   corners.points = new CvPoint2D32f[pattern_size.width * pattern_size.height];
3639   ERRWRAP(r = cvFindChessboardCorners(image, pattern_size, corners.points,&corners.count, flags));
3640   return Py_BuildValue("NN", FROM_int(r), FROM_cvpoint2d32f_count(corners));
3641 }
3642
3643 // For functions GetSubRect, GetRow, GetCol.
3644 // recipient has a view into donor's data, and needs to share it.
3645 // make recipient use the donor's data, compute the offset,
3646 // and manage reference counts.
3647
3648 static void preShareData(CvArr *donor, CvMat **recipient)
3649 {
3650   *recipient = cvCreateMatHeader(4, 4, cvGetElemType(donor));
3651 }
3652
3653 static PyObject *shareData(PyObject *donor, CvArr *pdonor, CvMat *precipient)
3654 {
3655   PyObject *recipient = (PyObject*)PyObject_NEW(cvmat_t, &cvmat_Type);
3656   ((cvmat_t*)recipient)->a = precipient;
3657   ((cvmat_t*)recipient)->offset = cvPtr1D(precipient, 0) - cvPtr1D(pdonor, 0);
3658
3659   PyObject *arr_data;
3660   if (is_cvmat(donor)) {
3661     arr_data = ((cvmat_t*)donor)->data;
3662   } else if (is_iplimage(donor)) {
3663     arr_data = ((iplimage_t*)donor)->data;
3664   } else {
3665     return (PyObject*)failmsg("Argument 'mat' must be either IplImage or CvMat");
3666   }
3667   ((cvmat_t*)recipient)->data = arr_data;
3668   Py_INCREF(arr_data);
3669   return recipient;
3670 }
3671
3672 static PyObject *pycvGetHuMoments(PyObject *self, PyObject *args, PyObject *kw)
3673 {
3674   CvMoments* moments;
3675   PyObject *pyobj_moments = NULL;
3676
3677   if (!PyArg_ParseTuple(args, "O", &pyobj_moments))
3678     return NULL;
3679   if (!convert_to_CvMomentsPTR(pyobj_moments, &moments, "moments")) return NULL;
3680   CvHuMoments r;
3681   ERRWRAP(cvGetHuMoments(moments, &r));
3682   return Py_BuildValue("ddddddd", r.hu1, r.hu2, r.hu3, r.hu4, r.hu5, r.hu6, r.hu7);
3683 }
3684
3685 static PyObject *pycvFitLine(PyObject *self, PyObject *args, PyObject *kw)
3686 {
3687   cvarrseq points;
3688   PyObject *pyobj_points = NULL;
3689   int dist_type;
3690   float param;
3691   float reps;
3692   float aeps;
3693   float r[6];
3694
3695   if (!PyArg_ParseTuple(args, "Oifff", &pyobj_points, &dist_type, &param, &reps, &aeps))
3696     return NULL;
3697   if (!convert_to_cvarrseq(pyobj_points, &points, "points")) return NULL;
3698   ERRWRAP(cvFitLine(points.v, dist_type, param, reps, aeps, r));
3699   int dimension;
3700   if (strcmp("opencv-matrix", cvTypeOf(points.v)->type_name) == 0)
3701     dimension = CV_MAT_CN(cvGetElemType(points.v));
3702   else {
3703     // sequence case... don't think there is a sequence of 3d points,
3704     // so assume 2D
3705     dimension = 2;
3706   }
3707   if (dimension == 2)
3708     return Py_BuildValue("dddd", r[0], r[1], r[2], r[3]);
3709   else
3710     return Py_BuildValue("dddddd", r[0], r[1], r[2], r[3], r[4], r[5]);
3711 }
3712
3713 static PyObject *pycvGetMinMaxHistValue(PyObject *self, PyObject *args, PyObject *kw)
3714 {
3715   CvHistogram* hist;
3716   PyObject *pyobj_hist = NULL;
3717   float min_val;
3718   float max_val;
3719   int min_loc[CV_MAX_DIM];
3720   int max_loc[CV_MAX_DIM];
3721
3722   if (!PyArg_ParseTuple(args, "O", &pyobj_hist))
3723     return NULL;
3724   if (!convert_to_CvHistogram(pyobj_hist, &hist, "hist")) return NULL;
3725   ERRWRAP(cvGetMinMaxHistValue(hist, &min_val, &max_val, min_loc, max_loc));
3726   int d = cvGetDims(hist->bins);
3727   PyObject *pminloc = PyTuple_New(d), *pmaxloc = PyTuple_New(d);
3728   for (int i = 0; i < d; i++) {
3729     PyTuple_SetItem(pminloc, i, PyInt_FromLong(min_loc[i]));
3730     PyTuple_SetItem(pmaxloc, i, PyInt_FromLong(max_loc[i]));
3731   }
3732   return Py_BuildValue("ffNN", min_val, max_val, pminloc, pmaxloc);
3733 }
3734
3735 static CvSeq* cvHOGDetectMultiScale( const CvArr* image, CvMemStorage* storage,
3736   const CvArr* svm_classifier=NULL, CvSize win_stride=cvSize(0,0),
3737   double hit_threshold=0, double scale=1.05,
3738   int group_threshold=2, CvSize padding=cvSize(0,0),
3739   CvSize win_size=cvSize(64,128), CvSize block_size=cvSize(16,16),
3740   CvSize block_stride=cvSize(8,8), CvSize cell_size=cvSize(8,8),
3741   int nbins=9, int gammaCorrection=1 )
3742 {
3743     cv::HOGDescriptor hog(win_size, block_size, block_stride, cell_size, nbins, 1, -1, cv::HOGDescriptor::L2Hys, 0.2, gammaCorrection!=0);
3744     if(win_stride.width == 0 && win_stride.height == 0)
3745         win_stride = block_stride;
3746     cv::Mat img = cv::cvarrToMat(image);
3747     std::vector<cv::Rect> found;
3748     if(svm_classifier)
3749     {
3750         CvMat stub, *m = cvGetMat(svm_classifier, &stub);
3751         int sz = m->cols*m->rows;
3752         CV_Assert(CV_IS_MAT_CONT(m->type) && (m->cols == 1 || m->rows == 1) && CV_MAT_TYPE(m->type) == CV_32FC1);
3753         std::vector<float> w(sz);
3754         std::copy(m->data.fl, m->data.fl + sz, w.begin());
3755         hog.setSVMDetector(w);
3756     }
3757     else
3758         hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
3759     hog.detectMultiScale(img, found, hit_threshold, win_stride, padding, scale, group_threshold);
3760     CvSeq* seq = cvCreateSeq(cv::DataType<cv::Rect>::type, sizeof(CvSeq), sizeof(cv::Rect), storage);
3761     if(found.size())
3762         cvSeqPushMulti(seq, &found[0], (int)found.size());
3763     return seq;
3764 }
3765
3766 static int zero = 0;
3767
3768 /************************************************************************/
3769 /* Custom Validators */
3770
3771 #define CVPY_VALIDATE_DrawChessboardCorners() do { \
3772   if ((pattern_size.width * pattern_size.height) != corners.count) \
3773     return (PyObject*)failmsg("Size is %dx%d, but corner list is length %d", pattern_size.width, pattern_size.height, corners.count); \
3774   } while (0)
3775
3776 #define cvGetRotationMatrix2D cv2DRotationMatrix
3777
3778 /************************************************************************/
3779 /* Generated functions */
3780
3781 #include "generated0.i"
3782
3783 static PyMethodDef methods[] = {
3784
3785 #if PYTHON_NUMPY
3786   {"fromarray", pycvfromarray, METH_VARARGS, "fromarray(array) -> cvmatnd"},
3787 #endif
3788
3789   {"CreateHist", pycvCreateHist, METH_VARARGS, "CreateHist(dims, type, ranges, uniform = 1) -> hist"},
3790   {"CreateImage", pycvCreateImage, METH_VARARGS, "CreateImage(size, depth, channels) -> image"},
3791   {"CreateImageHeader", pycvCreateImageHeader, METH_VARARGS, "CreateImageHeader(size, depth, channels) -> image"},
3792   {"CreateMat", pycvCreateMat, METH_VARARGS, "CreateMat(row, cols, type) -> mat"},
3793   {"CreateMatHeader", pycvCreateMatHeader, METH_VARARGS, "CreateMatHeader(rows, cols, type) -> mat"},
3794   {"CreateMatND", pycvCreateMatND, METH_VARARGS, "CreateMatND(dims, type) -> matnd"},
3795   {"CreateMatNDHeader", pycvCreateMatNDHeader, METH_VARARGS, "CreateMatNDHeader(dims, type) -> matnd"},
3796   {"CreateMemStorage", pycvCreateMemStorage, METH_VARARGS, "CreateMemStorage(block_size) -> memstorage"},
3797   {"FindContours", (PyCFunction)pycvFindContours, METH_KEYWORDS, "FindContours(image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0)) -> cvseq"},
3798   {"ApproxPoly", (PyCFunction)pycvApproxPoly, METH_KEYWORDS, "ApproxPoly(src_seq, storage, method, parameter=0, parameter2=0) -> None"},
3799   {"CreateData", pycvCreateData, METH_VARARGS, "CreateData(arr) -> None"},
3800   {"GetDims", pycvGetDims, METH_VARARGS, "GetDims(arr) -> dims"},
3801   {"GetImage", pycvGetImage, METH_VARARGS, "GetImage(cvmat) -> image"},
3802   {"GetMat", (PyCFunction)pycvGetMat, METH_KEYWORDS, "GetMat(image, allowND=0) -> cvmat"},
3803   {"Reshape", pycvReshape, METH_VARARGS, "Reshape(arr, new_cn, new_rows=0) -> cvmat"},
3804   {"InitLineIterator", pycvInitLineIterator, METH_VARARGS, "InitLineIterator(image, pt1, pt2, connectivity=8, left_to_right=0) -> None"},
3805   {"LoadImage", (PyCFunction)pycvLoadImage, METH_KEYWORDS, "LoadImage(filename, iscolor=CV_LOAD_IMAGE_COLOR)"},
3806   {"SetData", pycvSetData, METH_VARARGS, "SetData(arr, data, step)"},
3807   {"SetMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_KEYWORDS, "SetMouseCallback(window_name, on_mouse, param) -> None"},
3808   {"CreateTrackbar", (PyCFunction)pycvCreateTrackbar, METH_KEYWORDS, "CreateTrackbar(trackbar_name, window_name, value, count, on_change) -> None"},
3809   {"CalcEMD2", (PyCFunction)pycvCalcEMD2, METH_KEYWORDS, "CalcEMD2(signature1, signature2, distance_type, distance_func = None, cost_matrix=None, flow=None, lower_bound=None, userdata = None) -> float"},
3810   {"FindChessboardCorners", (PyCFunction)pycvFindChessboardCorners, METH_KEYWORDS, "FindChessboardCorners(image, pattern_size, flags=CV_CALIB_CB_ADAPTIVE_THRESH) -> success,corners"},
3811   {"FitLine", (PyCFunction)pycvFitLine, METH_KEYWORDS, "FitLine(points, dist_type, param, reps, aeps) -> line"},
3812   {"Subdiv2DLocate", pycvSubdiv2DLocate, METH_VARARGS, "Subdiv2DLocate(subdiv, pt) -> (loc, where)"},
3813   {"CalcOpticalFlowPyrLK", pycvCalcOpticalFlowPyrLK, METH_VARARGS, "CalcOpticalFlowPyrLK(prev, curr, prev_pyr, curr_pyr, prev_features, CvSize win_size, int level, criteria, flags, guesses = None) -> (curr_features, status, track_error)"},
3814   {"ClipLine", (PyCFunction)pycvClipLine, METH_KEYWORDS, "ClipLine(img, pt1, pt2) -> (clipped_pt1, clipped_pt2)"},
3815   {"GetHuMoments", (PyCFunction)pycvGetHuMoments, METH_KEYWORDS, "GetHuMoments(cvmoments) -> (h1, h2, h3, h4, h5, h5, h7)"},
3816   {"GetMinMaxHistValue", (PyCFunction)pycvGetMinMaxHistValue, METH_KEYWORDS, "GetMinMaxHistValue(hist) -> min_val,max_val,min_loc,max_loc"},
3817   {"WaitKey", (PyCFunction)pycvWaitKey, METH_KEYWORDS, "WaitKey(delay=0) -> int"},
3818   //{"CalcOpticalFlowFarneback", (PyCFunction)pycvCalcOpticalFlowFarneback, METH_KEYWORDS, "CalcOpticalFlowFarneback(prev, next, flow, pyr_scale=0.5, levels=3, win_size=15, iterations=3, poly_n=7, poly_sigma=1.5, flags=0) -> None"},
3819   //{"_HOGComputeDescriptors", (PyCFunction)pycvHOGComputeDescriptors, METH_KEYWORDS, "_HOGComputeDescriptors(image, win_stride=block_stride, locations=None, padding=(0,0), win_size=(64,128), block_size=(16,16), block_stride=(8,8), cell_size=(8,8), nbins=9, gammaCorrection=true) -> list_of_descriptors"},
3820   //{"_HOGDetect", (PyCFunction)pycvHOGDetect, METH_KEYWORDS, "_HOGDetect(image, svm_classifier, win_stride=block_stride, locations=None, padding=(0,0), win_size=(64,128), block_size=(16,16), block_stride=(8,8), cell_size=(8,8), nbins=9, gammaCorrection=true) -> list_of_points"},
3821   //{"_HOGDetectMultiScale", (PyCFunction)pycvHOGDetectMultiScale, METH_KEYWORDS, "_HOGDetectMultiScale(image, svm_classifier, win_stride=block_stride, scale=1.05, group_threshold=2, padding=(0,0), win_size=(64,128), block_size=(16,16), block_stride=(8,8), cell_size=(8,8), nbins=9, gammaCorrection=true) -> list_of_points"},
3822
3823   {"temp_test", temp_test, METH_VARARGS},
3824
3825 #include "generated1.i"
3826
3827   {NULL, NULL},
3828 };
3829
3830 /************************************************************************/
3831 /* Module init */
3832
3833 static int to_ok(PyTypeObject *to)
3834 {
3835   to->tp_alloc = PyType_GenericAlloc;
3836   to->tp_new = PyType_GenericNew;
3837   to->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
3838   return (PyType_Ready(to) == 0);
3839 }
3840
3841 #define MKTYPE(NAME)  do { NAME##_specials(); if (!to_ok(&NAME##_Type)) return; } while (0)
3842
3843 extern "C"
3844 #if defined WIN32 || defined _WIN32
3845 __declspec(dllexport)
3846 #endif
3847 void initcv()
3848 {
3849   PyObject *m, *d;
3850
3851   cvSetErrMode(CV_ErrModeParent);
3852
3853   MKTYPE(cvcapture);
3854   MKTYPE(cvcontourtree);
3855   MKTYPE(cvfont);
3856   MKTYPE(cvhaarclassifiercascade);
3857   MKTYPE(cvhistogram);
3858   MKTYPE(cvlineiterator);
3859   MKTYPE(cvmat);
3860   MKTYPE(cvmatnd);
3861   MKTYPE(cvmemstorage);
3862   MKTYPE(cvmoments);
3863   MKTYPE(cvpositobject);
3864   MKTYPE(cvsubdiv2dedge);
3865   MKTYPE(cvrng);
3866   MKTYPE(cvseq);
3867   MKTYPE(cvset);
3868   MKTYPE(cvsubdiv2d);
3869   MKTYPE(cvsubdiv2dpoint);
3870   MKTYPE(cvvideowriter);
3871   MKTYPE(iplconvkernel);
3872   MKTYPE(iplimage);
3873   MKTYPE(memtrack);
3874
3875   m = Py_InitModule(MODULESTR"", methods);
3876   d = PyModule_GetDict(m);
3877
3878   opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL);
3879   PyDict_SetItemString(d, "error", opencv_error);
3880
3881   PyDict_SetItemString(d, "iplimage", (PyObject*)&iplimage_Type);
3882   PyDict_SetItemString(d, "cvmat", (PyObject*)&cvmat_Type);
3883
3884 #define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
3885 #define PUBLISHU(I) PyDict_SetItemString(d, #I, PyLong_FromUnsignedLong(I))
3886
3887   PUBLISHU(IPL_DEPTH_8U);
3888   PUBLISHU(IPL_DEPTH_8S);
3889   PUBLISHU(IPL_DEPTH_16U);
3890   PUBLISHU(IPL_DEPTH_16S);
3891   PUBLISHU(IPL_DEPTH_32S);
3892   PUBLISHU(IPL_DEPTH_32F);
3893   PUBLISHU(IPL_DEPTH_64F);
3894
3895   PUBLISH(CV_LOAD_IMAGE_COLOR);
3896   PUBLISH(CV_LOAD_IMAGE_GRAYSCALE);
3897   PUBLISH(CV_LOAD_IMAGE_UNCHANGED);
3898   PUBLISH(CV_HIST_ARRAY);
3899   PUBLISH(CV_HIST_SPARSE);
3900   PUBLISH(CV_8UC1);
3901   PUBLISH(CV_8UC2);
3902   PUBLISH(CV_8UC3);
3903   PUBLISH(CV_8UC4);
3904   PUBLISH(CV_8SC1);
3905   PUBLISH(CV_8SC2);
3906   PUBLISH(CV_8SC3);
3907   PUBLISH(CV_8SC4);
3908   PUBLISH(CV_16UC1);
3909   PUBLISH(CV_16UC2);
3910   PUBLISH(CV_16UC3);
3911   PUBLISH(CV_16UC4);
3912   PUBLISH(CV_16SC1);
3913   PUBLISH(CV_16SC2);
3914   PUBLISH(CV_16SC3);
3915   PUBLISH(CV_16SC4);
3916   PUBLISH(CV_32SC1);
3917   PUBLISH(CV_32SC2);
3918   PUBLISH(CV_32SC3);
3919   PUBLISH(CV_32SC4);
3920   PUBLISH(CV_32FC1);
3921   PUBLISH(CV_32FC2);
3922   PUBLISH(CV_32FC3);
3923   PUBLISH(CV_32FC4);
3924   PUBLISH(CV_64FC1);
3925   PUBLISH(CV_64FC2);
3926   PUBLISH(CV_64FC3);
3927   PUBLISH(CV_64FC4);
3928   PUBLISH(CV_NEXT_AROUND_ORG);
3929   PUBLISH(CV_NEXT_AROUND_DST);
3930   PUBLISH(CV_PREV_AROUND_ORG);
3931   PUBLISH(CV_PREV_AROUND_DST);
3932   PUBLISH(CV_NEXT_AROUND_LEFT);
3933   PUBLISH(CV_NEXT_AROUND_RIGHT);
3934   PUBLISH(CV_PREV_AROUND_LEFT);
3935   PUBLISH(CV_PREV_AROUND_RIGHT);
3936
3937   PUBLISH(CV_WINDOW_AUTOSIZE);
3938
3939   PUBLISH(CV_PTLOC_INSIDE);
3940   PUBLISH(CV_PTLOC_ON_EDGE);
3941   PUBLISH(CV_PTLOC_VERTEX);
3942   PUBLISH(CV_PTLOC_OUTSIDE_RECT);
3943
3944 #include "generated2.i"
3945
3946 #if 0
3947   {
3948     int sizes[] = { 10 } ;
3949     float ranges[] = { 0.0, 1.0 };
3950     // CvHistogram*h = cvCreateHist(1, sizes, CV_HIST_ARRAY);
3951     CvHistogram H;
3952     float data[10];
3953     CvHistogram*h = cvMakeHistHeaderForArray(1, sizes, &H, data);
3954     printf("h->type = %08x\n", h->type);
3955     printf("h->bins = %p\n", h->bins);
3956     printf("h->mat = %p\n", &(h->mat));
3957   }
3958 #endif
3959 }
3960