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