Update to 2.0.0 tree from current Fremantle build
[opencv] / interfaces / swig / octave / octhelpers.i
1 /* These functions need the SWIG_* functions defined in the wrapper */
2 %{
3
4
5   static inline bool OctSwigObject_Check(const octave_value& ov) {
6     return ov.type_id()==octave_swig_ref::static_type_id();
7   }
8
9   static CvArr * OctObject_to_CvArr(octave_value obj, bool * freearg);
10   static CvArr * OctSequence_to_CvArr( octave_value obj );
11
12   // convert a octave sequence/array/list object into a c-array
13 #define OctObject_AsArrayImpl(func, ctype, ptype)                              \
14  int func(octave_value obj, ctype * array, int len){                         \
15    void * mat_vptr=NULL;                                                     \
16    void * im_vptr=NULL;                                                      \
17    if(OctNumber_Check(obj)){                                                  \
18      memset( array, 0, sizeof(ctype)*len );                                \
19      array[0] = OctObject_As##ptype( obj );                                 \
20    }                                                                         \
21    else if(OctList_Check(obj) || OctTuple_Check(obj)){                         \
22      int seqsize = OctSequence_Size(obj);                                   \
23      for(int i=0; i<len && i<seqsize; i++){                                \
24        if(i<seqsize){                                                    \
25          array[i] =  OctObject_As##ptype( OctSequence_GetItem(obj, i) ); \
26        }                                                                 \
27        else{                                                             \
28          array[i] = 0;                                                 \
29        }                                                                 \
30      }                                                                     \
31    }                                                                         \
32    else if( SWIG_ConvertPtr(obj, &mat_vptr, SWIGTYPE_p_CvMat, 0)!=-1 ||      \
33             SWIG_ConvertPtr(obj, &im_vptr, SWIGTYPE_p__IplImage, 0)!=-1)     \
34      {                                                                         \
35        CvMat * mat = (CvMat *) mat_vptr;                                     \
36        CvMat stub;                                                           \
37        if(im_vptr) mat = cvGetMat(im_vptr, &stub);                           \
38        if( mat->rows!=1 && mat->cols!=1 ){                                   \
39          error("OctObject_As*Array: CvArr must be row or column vector" );   \
40          return -1;                                                        \
41        }                                                                     \
42        if( mat->rows==1 && mat->cols==1 ){                                   \
43          CvScalar val;                                                     \
44          if( len!=CV_MAT_CN(mat->type) ){                                  \
45            error("OctObject_As*Array: CvArr channels != length" );              \
46            return -1;                                                    \
47          }                                                                 \
48          val = cvGet1D(mat, 0);                                            \
49          for(int i=0; i<len; i++){                                         \
50            array[i] = (ctype) val.val[i];                                \
51          }                                                                 \
52        }                                                                     \
53        else{                                                                 \
54          mat = cvReshape(mat, &stub, -1, mat->rows*mat->cols);             \
55          if( mat->rows != len ){                                           \
56            error("OctObject_As*Array: CvArr rows or cols must equal length" ); \
57            return -1;                                                   \
58          }                                                                 \
59          for(int i=0; i<len; i++){                                         \
60            CvScalar val = cvGet1D(mat, i);                               \
61            array[i] = (ctype) val.val[0];                                \
62          }                                                                 \
63        }                                                                     \
64      }                                                                         \
65    else{                                                                     \
66      error("OctObject_As*Array: Expected a number, sequence or CvArr" );  \
67      return -1;                                                            \
68    }                                                                         \
69    return 0;                                                                 \
70  }
71
72   OctObject_AsArrayImpl( OctObject_AsFloatArray, float, Double );
73   OctObject_AsArrayImpl( OctObject_AsDoubleArray, double, Double );
74   OctObject_AsArrayImpl( OctObject_AsLongArray, int, Long );
75
76   static CvPoint OctObject_to_CvPoint(octave_value 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(OctObject_AsLongArray(obj, (int *) &val, 2) != -1){
92       return val;
93     }
94
95     error("could not convert to CvPoint");
96     return cvPoint(0,0);
97   }
98
99   static CvPoint2D32f OctObject_to_CvPoint2D32f(octave_value 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(OctObject_AsFloatArray(obj, (float *) &val, 2) != -1){
114       return val;
115     }
116     error("could not convert to CvPoint2D32f");
117     return cvPoint2D32f(0,0);
118   }
119
120   static CvScalar OctObject_to_CvScalar(octave_value obj){
121     CvScalar val;
122     CvScalar * ptr;
123     CvPoint2D32f *ptr2D32f;
124     CvPoint *pt_ptr;
125     void * vptr;
126     if( SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvScalar, 0 ) != -1)
127       {
128         ptr = (CvScalar *) vptr;
129         return *ptr;
130       }
131     if( SWIG_ConvertPtr(obj, (void**)&ptr2D32f, SWIGTYPE_p_CvPoint2D32f, 0) != -1) {
132       return cvScalar(ptr2D32f->x, ptr2D32f->y);
133     }
134     if( SWIG_ConvertPtr(obj, (void**)&pt_ptr, SWIGTYPE_p_CvPoint, 0) != -1) {
135       return cvScalar(pt_ptr->x, pt_ptr->y);
136     }
137     if(OctObject_AsDoubleArray(obj, val.val, 4)!=-1){
138       return val;
139     }
140     return cvScalar(-1,-1,-1,-1); 
141   }
142
143   // if octave sequence type, convert to CvMat or CvMatND
144   static CvArr * OctObject_to_CvArr(octave_value obj, bool * freearg){
145     CvArr * cvarr;
146     *freearg = false;
147
148     // check if OpenCV type
149     if ( OctSwigObject_Check(obj) ){
150       SWIG_ConvertPtr(obj, &cvarr, 0, SWIG_POINTER_EXCEPTION);
151     }
152     else if (OctList_Check(obj) || OctTuple_Check(obj)){
153       cvarr = OctSequence_to_CvArr( obj );
154       *freearg = (cvarr != NULL);
155     }
156     else if (OctLong_Check(obj) && OctLong_AsLong(obj)==0){
157       return NULL;
158     }
159     else {
160       SWIG_ConvertPtr(obj, (void**)&cvarr, 0, SWIG_POINTER_EXCEPTION);
161     }
162     return cvarr;
163   }
164
165   static int OctObject_GetElemType(octave_value obj){
166     void *vptr;
167     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint, 0) != -1) return CV_32SC2;       
168     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvSize, 0) != -1) return CV_32SC2;        
169     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvRect, 0) != -1) return CV_32SC4;        
170     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvSize2D32f, 0) != -1) return CV_32FC2;   
171     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint2D32f, 0) != -1) return CV_32FC2;  
172     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint3D32f, 0) != -1) return CV_32FC3;  
173     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint2D64f, 0) != -1) return CV_64FC2;  
174     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvPoint3D64f, 0) != -1) return CV_64FC3;  
175     if(SWIG_ConvertPtr(obj, &vptr, SWIGTYPE_p_CvScalar, 0) != -1) return CV_64FC4;      
176     if(OctTuple_Check(obj) || OctList_Check(obj)) return CV_MAKE_TYPE(CV_32F, OctSequence_Size( obj ));
177     if(OctLong_Check(obj)) return CV_32S;
178     return CV_32F;
179   }
180
181   // Would like this to convert Octave lists to CvMat
182   // Also lists of CvPoints, CvScalars, CvMats? etc
183   static CvArr * OctSequence_to_CvArr( octave_value obj ){
184     int dims[CV_MAX_DIM] = {1,1,1};
185     int ndim=0;
186     int cvtype;
187     octave_value item;
188
189     // figure out dimensions
190     for(item = obj; 
191         (OctTuple_Check(item) || OctList_Check(item));
192         item = OctSequence_GetItem(item, 0))
193       {
194         dims[ndim] = OctSequence_Size( item ); 
195         ndim++;
196       }
197
198     if(ndim==0){
199       error("Cannot convert an empty octave object to a CvArr");
200       return NULL;
201     }
202
203     cvtype = OctObject_GetElemType(item);
204     // collapse last dim into NCH if we found a single channel, but the last dim is <=3
205     if(CV_MAT_CN(cvtype)==1 && dims[ndim-1]>1 && dims[ndim-1]<4){
206       cvtype=CV_MAKE_TYPE(cvtype, dims[ndim-1]);
207       dims[ndim-1]=1;   
208       ndim--;
209     }
210
211     if(cvtype==-1){
212       error("Could not determine OpenCV element type of Octave sequence");
213       return NULL;
214     }
215
216     // CvMat
217     if(ndim<=2){
218       CvMat *m = cvCreateMat(dims[0], dims[1], cvtype);
219       for(int i=0; i<dims[0]; i++){
220         octave_value rowobj = OctSequence_GetItem(obj, i);
221         if( dims[1] > 1 ){
222           // double check size
223           assert((OctTuple_Check(rowobj) || OctList_Check(rowobj)) && 
224                  OctSequence_Size(rowobj) == dims[1]);
225
226           for(int j=0; j<dims[1]; j++){
227             octave_value colobj = OctSequence_GetItem(rowobj, j);
228             cvSet2D( m, i, j, OctObject_to_CvScalar( colobj ) );
229           }
230         }
231         else{
232           cvSet1D(m, i, OctObject_to_CvScalar( rowobj ) );
233         }
234       }
235       return (CvArr *) m;
236     }
237
238     // CvMatND
239     error("Cannot convert Octave Object to CvArr -- ndim > 3");
240     return NULL;
241   }
242 %}