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