Update to 2.0.0 tree from current Fremantle build
[opencv] / interfaces / swig / python / pyhelpers.i
1 /* These functions need the SWIG_* functions defined in the wrapper */
2 %{
3
4 #include "pyhelpers.h"
5
6 static CvArr * PyObject_to_CvArr(PyObject * obj, bool * freearg);
7
8 // convert a python sequence/array/list object into a c-array
9 #define PyObject_AsArrayImpl(func, ctype, ptype)                              \
10   int func(PyObject * obj, ctype * array, int len){                         \
11   void * mat_vptr=NULL;                                                     \
12   void * im_vptr=NULL;                                                      \
13   if(PyNumber_Check(obj)){                                                  \
14     memset( array, 0, sizeof(ctype)*len );                                \
15     array[0] = PyObject_As##ptype( obj );                                 \
16   }                                                                         \
17   else if(PyList_Check(obj) || PyTuple_Check(obj)){                         \
18     int seqsize = PySequence_Size(obj);                                   \
19     for(int i=0; i<len && i<seqsize; i++){                                \
20       if(i<seqsize){                                                    \
21               array[i] =  PyObject_As##ptype( PySequence_GetItem(obj, i) ); \
22       }                                                                 \
23       else{                                                             \
24         array[i] = 0;                                                 \
25       }                                                                 \
26     }                                                                     \
27   }                                                                         \
28   else if( SWIG_ConvertPtr(obj, &mat_vptr, SWIGTYPE_p_CvMat, 0)!=-1 ||      \
29            SWIG_ConvertPtr(obj, &im_vptr, SWIGTYPE_p__IplImage, 0)!=-1)     \
30   {                                                                         \
31     CvMat * mat = (CvMat *) mat_vptr;                                     \
32     CvMat stub;                                                           \
33     if(im_vptr) mat = cvGetMat(im_vptr, &stub);                           \
34     if( mat->rows!=1 && mat->cols!=1 ){                                   \
35       PyErr_SetString( PyExc_TypeError,                                 \
36            "PyObject_As*Array: CvArr must be row or column vector" );   \
37       return -1;                                                        \
38     }                                                                     \
39     if( mat->rows==1 && mat->cols==1 ){                                   \
40       CvScalar val;                                                     \
41       if( len!=CV_MAT_CN(mat->type) ){                                  \
42         PyErr_SetString( PyExc_TypeError,                             \
43         "PyObject_As*Array: CvArr channels != length" );              \
44         return -1;                                                    \
45       }                                                                 \
46       val = cvGet1D(mat, 0);                                            \
47       for(int i=0; i<len; i++){                                         \
48         array[i] = (ctype) val.val[i];                                \
49       }                                                                 \
50     }                                                                     \
51     else{                                                                 \
52       mat = cvReshape(mat, &stub, -1, mat->rows*mat->cols);             \
53       if( mat->rows != len ){                                           \
54         PyErr_SetString( PyExc_TypeError,                             \
55          "PyObject_As*Array: CvArr rows or cols must equal length" ); \
56          return -1;                                                   \
57       }                                                                 \
58       for(int i=0; i<len; i++){                                         \
59         CvScalar val = cvGet1D(mat, i);                               \
60         array[i] = (ctype) val.val[0];                                \
61       }                                                                 \
62     }                                                                     \
63   }                                                                         \
64   else{                                                                     \
65     PyErr_SetString( PyExc_TypeError,                                     \
66         "PyObject_As*Array: Expected a number, sequence or CvArr" );  \
67     return -1;                                                            \
68   }                                                                         \
69   return 0;                                                                 \
70 }
71
72 PyObject_AsArrayImpl( PyObject_AsFloatArray, float, Double );
73 PyObject_AsArrayImpl( PyObject_AsDoubleArray, double, Double );
74 PyObject_AsArrayImpl( PyObject_AsLongArray, int, Long );
75
76 static CvPoint PyObject_to_CvPoint(PyObject * obj){
77   CvPoint val;
78   CvPoint *ptr;
79   CvPoint2D32f * ptr2D32f;
80   CvScalar * scalar;
81
82   if( SWIG_ConvertPtr(obj, (void**)&ptr, SWIGTYPE_p_CvPoint, 0) != -1) {
83     return *ptr;
84   }
85   if( SWIG_ConvertPtr(obj, (void**)&ptr2D32f, SWIGTYPE_p_CvPoint2D32f, 0) != -1) {
86     return cvPointFrom32f( *ptr2D32f );
87   }
88   if( SWIG_ConvertPtr(obj, (void**)&scalar, SWIGTYPE_p_CvScalar, 0) != -1) {
89     return cvPointFrom32f(cvPoint2D32f( scalar->val[0], scalar->val[1] ));
90   }
91   if(PyObject_AsLongArray(obj, (int *) &val, 2) != -1){
92     return val;
93   }
94
95   PyErr_SetString( PyExc_TypeError, "could not convert to CvPoint");
96   return cvPoint(0,0);
97 }
98
99 static CvPoint2D32f PyObject_to_CvPoint2D32f(PyObject * obj){
100     CvPoint2D32f val;
101     CvPoint2D32f *ptr2D32f;
102   CvPoint *ptr;
103   CvScalar * scalar;
104     if( SWIG_ConvertPtr(obj, (void**)&ptr2D32f, SWIGTYPE_p_CvPoint2D32f, 0) != -1) {
105     return *ptr2D32f;
106   }
107   if( SWIG_ConvertPtr(obj, (void**)&ptr, SWIGTYPE_p_CvPoint, 0) != -1) {
108     return cvPointTo32f(*ptr);
109   }
110   if( SWIG_ConvertPtr(obj, (void**)&scalar, SWIGTYPE_p_CvScalar, 0) != -1) {
111     return cvPoint2D32f( scalar->val[0], scalar->val[1] );
112   }
113   if(PyObject_AsFloatArray(obj, (float *) &val, 2) != -1){
114     return val;
115   }
116   PyErr_SetString(PyExc_TypeError, "could not convert to CvPoint2D32f");
117   return cvPoint2D32f(0,0);
118 }
119
120 /* Check if this object can be interpreted as a CvScalar */
121 static bool CvScalar_Check(PyObject * obj){
122   void * vptr;
123     CvScalar val;
124   return SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvScalar,     0 ) != -1 ||
125          SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint2D32f, 0 ) != -1 ||
126            SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint,      0 ) != -1 ||
127          PyObject_AsDoubleArray(obj, val.val, 4) !=-1;
128 }
129
130 static CvScalar PyObject_to_CvScalar(PyObject * obj){
131   CvScalar val;
132   CvScalar * ptr;
133     CvPoint2D32f *ptr2D32f;
134   CvPoint *pt_ptr;
135   void * vptr;
136   if( SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvScalar, 0 ) != -1)
137   {
138     ptr = (CvScalar *) vptr;
139     return *ptr;
140   }
141   if( SWIG_ConvertPtr(obj, (void**)&ptr2D32f, SWIGTYPE_p_CvPoint2D32f, 0) != -1) {
142         return cvScalar(ptr2D32f->x, ptr2D32f->y);
143     }
144     if( SWIG_ConvertPtr(obj, (void**)&pt_ptr, SWIGTYPE_p_CvPoint, 0) != -1) {
145         return cvScalar(pt_ptr->x, pt_ptr->y);
146     }
147   if(PyObject_AsDoubleArray(obj, val.val, 4)!=-1){
148     return val;
149   }
150   return cvScalar(-1,-1,-1,-1); 
151 }
152
153 static int CvArr_Check( PyObject * obj )
154 {
155         void *ptr;
156         if( obj == Py_None ||
157             SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_void,       0) ) ||
158             SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_CvMat,       0) ) ||
159         SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_CvSeq,       0) ) ||
160         SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_CvContour,   0) ) ||
161         SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_CvSparseMat, 0) ) ||
162         SWIG_IsOK( SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_CvMatND,     0) ) ||
163         PyObject_HasAttrString(obj, "__array_interface__") ||
164         PySequence_Check(obj) ) 
165     { 
166         return 1;
167         }
168     PyErr_Clear();
169     return 0;
170 }
171
172 /* if python sequence type, convert to CvMat or CvMatND */
173 static CvArr * PyObject_to_CvArr (PyObject * obj, bool * freearg)
174 {
175   CvArr * cvarr = NULL;
176   *freearg = false;
177
178   if ( obj == Py_None )
179   {
180     // Interpret None as NULL pointer 
181     return NULL;
182   }
183   else if( SWIG_IsOK( SWIG_ConvertPtr(obj, (void **)& cvarr, SWIGTYPE_p_void,       0) ) ||
184       SWIG_IsOK( SWIG_ConvertPtr (obj, (void** )& cvarr, SWIGTYPE_p_CvMat, 0) ) ||
185       SWIG_IsOK( SWIG_ConvertPtr (obj, (void **)& cvarr, SWIGTYPE_p_CvSeq, 0) ) ||
186       SWIG_IsOK( SWIG_ConvertPtr (obj, (void **)& cvarr, SWIGTYPE_p_CvContour, 0) ) ||
187       SWIG_IsOK( SWIG_ConvertPtr (obj, (void **)& cvarr, SWIGTYPE_p_CvSparseMat, 0) ) ||
188       SWIG_IsOK( SWIG_ConvertPtr (obj, (void **)& cvarr, SWIGTYPE_p_CvMatND, 0) ))
189   {
190     // we got a directly wrapped void * pointer, OpenCV array or sequence type
191     return cvarr;
192   }
193   else if (PyObject_HasAttrString (obj, "__array_interface__"))
194   {
195     // if we didn't get our own datatype, let's see if it supports the array protocol
196     // array protocol is great because we just have to create another header but can
197     // use the original data without copying
198     cvarr = PyArray_to_CvArr (obj);
199     *freearg = (cvarr != NULL);
200   }
201   else if (PySequence_Check (obj))
202   {
203     // our next bet is a tuple or list of tuples or lists this has to be copied over, however
204     cvarr = PySequence_to_CvArr (obj);
205     *freearg = (cvarr != NULL);
206   }
207   else if (PyLong_Check (obj) && PyLong_AsLong (obj) == 0)
208   {
209     // Interpret a '0' integer as a NULL pointer
210     * freearg = false;
211     return NULL;
212   }
213   else 
214   {
215     // TODO, throw an error here
216     return NULL;
217   }
218   
219   return cvarr;
220 }
221
222
223 static int PyObject_GetElemType(PyObject * obj){
224   void *vptr;
225   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint, 0) != -1) return CV_32SC2; 
226   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvSize, 0) != -1) return CV_32SC2;  
227   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvRect, 0) != -1) return CV_32SC4;  
228   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvSize2D32f, 0) != -1) return CV_32FC2; 
229   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint2D32f, 0) != -1) return CV_32FC2;  
230   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint3D32f, 0) != -1) return CV_32FC3;  
231   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint2D64f, 0) != -1) return CV_64FC2;  
232   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint3D64f, 0) != -1) return CV_64FC3;  
233   if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvScalar, 0) != -1) return CV_64FC4;  
234   if(PyTuple_Check(obj) || PyList_Check(obj)) return CV_MAKE_TYPE(CV_32F, PySequence_Size( obj ));
235   if(PyLong_Check(obj)) return CV_32S;
236   return CV_32F;
237 }
238
239 %}