Update to 2.0.0 tree from current Fremantle build
[opencv] / interfaces / swig / octave / octtypemaps.i
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 %include "exception.i"
42 %include "./octhelpers.i"
43
44 %typemap(in) (CvArr *) (bool freearg=false){
45   $1 = OctObject_to_CvArr($input, &freearg);
46 }
47 %typemap(freearg) (CvArr *) {
48   if($1!=NULL && freearg$argnum){
49     cvReleaseData( $1 );
50     cvFree(&($1));
51   }
52 }
53 %typecheck(SWIG_TYPECHECK_POINTER) CvArr * {
54   void *ptr;
55   if(OctList_Check($input) || OctTuple_Check($input)) {
56     $1 = 1;
57   }
58   else if (SWIG_ConvertPtr($input, &ptr, 0, 0) == -1) {
59     $1 = 0;
60   }
61   else{
62     $1 = 1;
63   }
64 }
65
66 // for cvReshape, cvGetRow, where header is passed, then filled in
67 %typemap(in, numinputs=0) CvMat * OUTPUT (CvMat * header) {
68   header = (CvMat *)cvAlloc(sizeof(CvMat));
69   $1 = header;
70 }
71 %newobject cvReshape;
72 %newobject cvGetRow;
73 %newobject cvGetRows;
74 %newobject cvGetCol;
75 %newobject cvGetCols;
76 %newobject cvGetSubRect;
77 %newobject cvGetDiag;
78
79 %apply CvMat *OUTPUT {CvMat * header};
80 %apply CvMat *OUTPUT {CvMat * submat};
81
82 // In C, these functions assume input will always be around at least as long as header,
83 // presumably because the most common usage is to pass in a reference to a stack object.  
84 // i.e
85 // CvMat row;
86 // cvGetRow(A, &row, 0);
87 //
88 // As a result, the header is not refcounted (see the C source for cvGetRow, Reshape, in cxarray.cpp)
89 // However, in octave, the header parameter is implicitly created so it is easier to create
90 // situations where the sub-array outlives the original header.  A simple example is:
91 // A = cvReshape(A, -1, A.rows*A.cols)
92 //
93 // since octave doesn't have an assignment operator, the new header simply replaces the original,
94 // the refcount of the original goes to zero, and cvReleaseMat is called on the original, freeing both
95 // the header and data.  The new header is left pointing to invalid data.  To avoid this, need to add
96 // refcount field to the returned header.
97 %typemap(argout) (const CvArr* arr, CvMat* header) {
98   $2->hdr_refcount = ((CvMat *)$1)->hdr_refcount;
99   $2->refcount = ((CvMat *)$1)->refcount;
100   cvIncRefData($2);
101 }
102 %typemap(argout) (const CvArr* arr, CvMat* submat) {
103   $2->hdr_refcount = ((CvMat *)$1)->hdr_refcount;
104   $2->refcount = ((CvMat *)$1)->refcount;
105   cvIncRefData($2);
106 }
107
108 // map scalar or sequence to CvScalar, CvPoint2D32f, CvPoint
109 %typemap(in) (CvScalar) {
110   $1 = OctObject_to_CvScalar( $input );
111 }
112 %typemap(in) (CvPoint) {
113   $1 = OctObject_to_CvPoint($input);
114 }
115 %typemap(in) (CvPoint2D32f) {
116   $1 = OctObject_to_CvPoint2D32f($input);
117 }
118
119
120 // typemap for cvGetDims
121 %typemap(in) (const CvArr * arr, int * sizes = NULL) (void * myarr, int mysizes[CV_MAX_DIM]){
122   SWIG_Octave_ConvertPtr($input, &myarr, 0, SWIG_POINTER_EXCEPTION);
123   $1=(CvArr *)myarr;
124   $2=mysizes;
125 }
126
127 %typemap(argout) (const CvArr * arr, int * sizes = NULL) {
128   int len = OctInt_AsLong( $result );
129   octave_value obj = OctTuple_FromIntArray( $2, len );
130   %append_output(obj);
131 }
132                                 
133 // map one list of integer to the two parameters dimension/sizes
134 %typemap(in) (int dims, int* sizes) {
135   int i;
136
137   // get the size of the dimention array
138   $1 = OctList_Size ($input);
139
140   // allocate the needed memory
141   $2 = (int *)malloc ($1 * sizeof (int));
142
143   // extract all the integer values from the list
144   for (i = 0; i < $1; i++) {
145     octave_value item = OctList_GetItem ($input, i);
146     $2 [i] = (int)OctInt_AsLong (item);
147   }
148 }
149
150 // map one list of integer to the parameter idx of
151 //   cvGetND, cvSetND, cvClearND, cvGetRealND, cvSetRealND and cvClearRealND
152 %typemap(in) (int* idx) {
153   int i;
154   int size;
155
156   // get the size of the dimention array
157   size = OctList_Size ($input);
158
159   // allocate the needed memory
160   $1 = (int *)malloc (size * sizeof (int));
161
162   // extract all the integer values from the list
163   for (i = 0; i < size; i++) {
164     octave_value item = OctList_GetItem ($input, i);
165     $1 [i] = (int)OctInt_AsLong (item);
166   }
167 }
168
169 // map a list of list of float to an matrix of floats
170 %typemap(in) float** ranges {
171   int i1;
172   int i2;
173   int size1;
174   int size2 = 0;
175
176   // get the number of lines of the matrix
177   size1 = OctList_Size ($input);
178
179   // allocate the correct number of lines for the destination matrix
180   $1 = (float **)malloc (size1 * sizeof (float *));
181
182   for (i1 = 0; i1 < size1; i1++) {
183
184     // extract all the lines of the matrix
185     octave_value list = OctList_GetItem ($input, i1);
186
187     if (size2 == 0) {
188       // size 2 wasn't computed before
189       size2 = OctList_Size (list);
190     } else if (size2 != OctList_Size (list)) {
191       // the current line as a different size than the previous one
192       // so, generate an exception
193       SWIG_exception (SWIG_ValueError, "Lines must be the same size");
194     }
195
196     // allocate the correct number of rows for the current line
197     $1 [i1] = (float *)malloc (size2 * sizeof (float));
198
199     // extract all the float values of this row
200     for (i2 = 0; i2 < size2; i2++) {
201       octave_value item = OctList_GetItem (list, i2);
202       $1 [i1][i2] = (float)OctFloat_AsDouble (item);
203     }
204   }
205 }
206
207 //
208 // map the output parameter of the cvGetMinMaxHistValue()
209 // so, we can call cvGetMinMaxHistValue() in Octave like:
210 // min_value, max_value = cvGetMinMaxHistValue (hist, None, None)
211 //
212 %apply int *OUTPUT {int *min_idx};                                                                   
213 %apply int *OUTPUT {int *max_idx}; 
214 %apply float *OUTPUT {float *min_value};
215 %apply float *OUTPUT {float *max_value};
216 //
217 // map output parameters of cvMinMaxLoc
218 //
219 %apply double *OUTPUT {double* min_val, double* max_val};
220
221 //
222 // the input argument of cvPolyLine "CvPoint** pts" is converted from 
223 // a "list of list" (aka. an array) of CvPoint().
224 // The next parameters "int* npts" and "int contours" are computed from
225 // the givne list.
226 //
227 %typemap(in) (CvPoint** pts, int* npts, int contours){
228   int i;
229   int j;
230   int size2 = -1;
231   CvPoint **points = NULL;
232   int *nb_vertex = NULL;
233
234   if(!OctSequence_Check($input)){
235     SWIG_exception(SWIG_TypeError, "Expected a list for argument $argnum\n");
236     SWIG_fail;
237   }
238
239   // get the number of polylines input array
240   int size1 = OctSequence_Size ($input);
241   $3 = size1;
242
243   if(size1>0){
244     // create the points array
245     points = (CvPoint **)malloc (size1 * sizeof (CvPoint *));
246
247     // point to the created array for passing info to the C function
248     $1 = points;
249
250     // create the array for memorizing the vertex
251     nb_vertex = (int *)malloc (size1 * sizeof (int));
252     $2 = nb_vertex;
253   }
254   for (i = 0; i < size1; i++) {
255
256     // get the current item
257     octave_value line = OctSequence_GetItem ($input, i);
258
259     if(!OctSequence_Check(line)){
260       SWIG_exception(SWIG_TypeError, "Expected a sequence of sequences of integers for argument $argnum\n");
261       // TODO: cleanup here
262     }
263
264     // get the size of the current polyline
265     size2 = OctSequence_Size (line);
266
267
268     if(size2>0){
269       // allocate the necessary memory to store the points
270       points [i] = (CvPoint *)malloc (size2 * sizeof (CvPoint));
271     }
272
273     // memorize the size of the polyline in the vertex list
274     nb_vertex [i] = size2;
275
276     for (j = 0; j < size2; j++) {
277       // get the current item
278       octave_value item = OctSequence_GetItem (line, j);
279       points[i][j] = OctObject_to_CvPoint( item );
280     }
281   }
282 }
283 // Free arguments allocated before the function call
284 %typemap(freearg) (CvPoint **pts, int* npts, int contours){
285   int i;
286   for(i=0;i<$3;i++){
287     free($1[i]);
288   }
289   free($1);
290   free($2);
291 }
292
293 // Macro to define typemaps to convert a octave list of CvPoints to a C array of CvPoints
294 %define %typemap_CvPoint_CArr(points_arg, numpoints_arg)
295
296      %typemap(in, numinputs=1) (CvPoint * points_arg, int numpoints_arg){
297   int i;
298   if(!OctSequence_Check($input)){
299     SWIG_exception(SWIG_TypeError, "Expected a list for argument $argnum\n");
300     SWIG_fail;
301   }
302   int size = OctSequence_Size($input);
303   CvPoint * points = (CvPoint *)malloc(size*sizeof(CvPoint));
304   for(i=0; i<size; i++){
305     octave_value item = OctSequence_GetItem($input, i);
306     points[i] = OctObject_to_CvPoint( item );
307   }
308   $1 = points;
309   $2 = size;
310 }
311 %typemap(freearg) (CvPoint *points_arg, int numpoints_arg){
312   free((char *)$1);
313 }
314 %enddef
315
316 // apply to cvFillConvexPoly
317 %typemap_CvPoint_CArr(pts, npts)
318
319      //
320      // this is mainly an "output parameter"
321      // So, just allocate the memory as input
322      //
323      %typemap (in, numinputs=0) (CvSeq ** OUTPUT) (CvSeq * seq) {
324   $1 = &seq;
325 }
326
327 //
328 // return the finded contours with all the others parametres
329 //
330 %typemap(argout) (CvSeq ** OUTPUT) {
331   octave_value to_add;
332
333   // extract the pointer we want to add to the returned tuple
334   // sequence is allocated in CvMemStorage, so octave_ownership=0
335   to_add = SWIG_NewPointerObj (*$1, $descriptor(CvSeq*), 0); 
336
337   $result = SWIG_AppendResult($result, &to_add, 1);
338 }
339 %apply CvSeq **OUTPUT {CvSeq **first_contour};
340 %apply CvSeq **OUTPUT {CvSeq **comp};
341
342 //
343 // CvArr ** image can be either one CvArr or one array of CvArr
344 // (for example like in cvCalcHist() )
345 // From Octave, the array of CvArr can be a tuple.
346 //
347 %typemap(in) (CvArr ** INPUT) (
348                                CvArr * one_image=NULL, 
349                                bool free_one_arg=false, 
350                                CvArr ** many_images=NULL, 
351                                bool *free_many_args=NULL, 
352                                int nimages=0 ) {
353   // first, check if this is a tuple
354   if (OctTuple_Check ($input)) {
355     // This is a tuple, so we need to test each element and pass
356     // them to the called function
357
358     int i;
359
360     // get the size of the tuple
361     nimages = OctTuple_Size ($input);
362
363     // allocate the necessary place
364     many_images = (CvArr **)malloc (nimages * sizeof (CvArr *));
365     free_many_args = (bool *)malloc(nimages * sizeof(bool));
366
367     for (i = 0; i < nimages; i++) {
368
369       // convert the current tuple element to a CvArr *, and
370       // store to many_images [i]
371       many_images[i] = OctObject_to_CvArr (OctTuple_GetItem ($input, i),
372                                            free_many_args+i);
373
374       // check that the current item is a correct type
375       if(!many_images[i]) {
376         // incorrect !
377         SWIG_fail;
378       }
379     }
380
381     // what to give to the called function
382     $1 = many_images;
383
384   } else if((one_image = OctObject_to_CvArr( $input, &free_one_arg ))){
385
386     // this is just one CvArr *, so one_image will receive it
387     $1 = &one_image;
388
389   } else {
390     // not a CvArr *, not a tuple, this is wrong
391     SWIG_fail;
392   }
393 }
394 %apply CvArr ** INPUT {CvArr ** img};
395 %apply CvArr ** INPUT {CvArr ** image};
396 %apply CvArr ** INPUT {CvArr ** arr};
397 %apply CvArr ** INPUT {CvArr ** vects};
398
399 %typemap(freearg) (CvArr ** FREEARG) {
400   if(free_one_arg$argnum){
401     cvFree(&(one_image$argnum));
402   }
403   else if(free_many_args$argnum){
404     int i;
405     for (i=0; i<nimages$argnum; i++){
406       if(free_many_args$argnum[i]){
407         cvReleaseData(many_images$argnum[i]);
408         cvFree(many_images$argnum+i);
409       }
410     }
411     free(many_images$argnum);
412     free(free_many_args$argnum);
413   }
414 }
415 %apply CvArr ** FREEARG {CvArr ** img};
416 %apply CvArr ** FREEARG {CvArr ** image};
417 %apply CvArr ** FREEARG {CvArr ** arr};
418 %apply CvArr ** FREEARG {CvArr ** vects};
419
420 //
421 // Map the CvFont * parameter from the cvInitFont() as an output parameter
422 //
423 %typemap (in, numinputs=1) (CvFont* font, int font_face) {
424   $1 = (CvFont *)malloc (sizeof (CvFont));
425   $2 = (int)OctInt_AsLong ($input); 
426   if (SWIG_arg_fail($argnum)) SWIG_fail;
427 }
428 %typemap(argout) (CvFont* font, int font_face) {
429   octave_value to_add;
430
431   // extract the pointer we want to add to the returned tuple
432   to_add = SWIG_NewPointerObj ($1, $descriptor(CvFont *), 0);
433
434   $result = SWIG_AppendResult($result, &to_add, 1);
435 }
436
437 //
438 // these are output parameters for cvGetTextSize
439 //
440 %typemap (in, numinputs=0) (CvSize* text_size, int* baseline) {
441   CvSize *size = (CvSize *)malloc (sizeof (CvSize));
442   int *baseline = (int *)malloc (sizeof (int));
443   $1 = size;
444   $2 = baseline;
445 }
446
447 //
448 // return the finded parameters for cvGetTextSize
449 //
450 %typemap(argout) (CvSize* text_size, int* baseline) {
451   octave_value to_add[2];
452
453   // extract the pointers we want to add to the returned tuple
454   to_add [0] = SWIG_NewPointerObj ($1, $descriptor(CvSize *), 0);
455   to_add [1] = OctInt_FromLong (*$2);
456
457   $result = SWIG_AppendResult($result, to_add, 2);
458 }
459
460
461 //
462 // curr_features is output parameter for cvCalcOpticalFlowPyrLK
463 //
464 %typemap (in, numinputs=1) (CvPoint2D32f* curr_features, int count)
465      (int tmpCount) {
466   // as input, we only need the size of the wanted features
467
468   // memorize the size of the wanted features
469   tmpCount = (int)OctInt_AsLong ($input);
470
471   // create the array for the C call
472   $1 = (CvPoint2D32f *) malloc(tmpCount * sizeof (CvPoint2D32f));
473
474   // the size of the array for the C call
475   $2 = tmpCount;
476 }
477
478 //
479 // the features returned by cvCalcOpticalFlowPyrLK
480 //
481 %typemap(argout) (CvPoint2D32f* curr_features, int count) {
482   int i;
483   octave_value to_add;
484     
485   // create the list to return
486   to_add = OctList_New (tmpCount$argnum);
487
488   // extract all the points values of the result, and add it to the
489   // final resulting list
490   for (i = 0; i < tmpCount$argnum; i++) {
491     OctList_SetItem (to_add, i,
492                      SWIG_NewPointerObj (&($1 [i]),
493                                          $descriptor(CvPoint2D32f *), 0));
494   }
495
496   $result = SWIG_AppendResult($result, &to_add, 1);
497 }
498
499 //
500 // status is an output parameters for cvCalcOpticalFlowPyrLK
501 //
502 %typemap (in, numinputs=1) (char *status) (int tmpCountStatus){
503   // as input, we still need the size of the status array
504
505   // memorize the size of the status array
506   tmpCountStatus = (int)OctInt_AsLong ($input);
507
508   // create the status array for the C call
509   $1 = (char *)malloc (tmpCountStatus * sizeof (char));
510 }
511
512 //
513 // the status returned by cvCalcOpticalFlowPyrLK
514 //
515 %typemap(argout) (char *status) {
516   int i;
517   octave_value to_add;
518
519   // create the list to return
520   to_add = OctList_New (tmpCountStatus$argnum);
521
522   // extract all the integer values of the result, and add it to the
523   // final resulting list
524   for (i = 0; i < tmpCountStatus$argnum; i++) {
525     OctList_SetItem (to_add, i, OctBool_FromLong ($1 [i]));
526   }
527
528   $result = SWIG_AppendResult($result, &to_add, 1); 
529 }
530
531 // map one list of points to the two parameters dimenssion/sizes
532 // for cvCalcOpticalFlowPyrLK
533 %typemap(in) (CvPoint2D32f* prev_features) {
534   int i;
535   int size;
536
537   // get the size of the input array
538   size = OctList_Size ($input);
539
540   // allocate the needed memory
541   $1 = (CvPoint2D32f *)malloc (size * sizeof (CvPoint2D32f));
542
543   // extract all the points values from the list
544   for (i = 0; i < size; i++) {
545     octave_value item = OctList_GetItem ($input, i);
546
547     void * vptr;
548     SWIG_Octave_ConvertPtr (item, &vptr,
549                             $descriptor(CvPoint2D32f*),
550                             SWIG_POINTER_EXCEPTION);
551     CvPoint2D32f *p = (CvPoint2D32f *)vptr;
552     $1 [i].x = p->x;
553     $1 [i].y = p->y;
554   }
555 }
556
557 //
558 // the corners returned by cvGoodFeaturesToTrack
559 //
560 %typemap (in, numinputs=1) (CvPoint2D32f* corners, int* corner_count)
561      (int tmpCount) {
562   // as input, we still need the size of the corners array
563
564   // memorize the size of the status corners
565   tmpCount = (int)OctInt_AsLong ($input);
566
567   // create the corners array for the C call
568   $1 = (CvPoint2D32f *)malloc (tmpCount * sizeof (CvPoint2D32f));
569
570   // the size of the array for the C call
571   $2 = &tmpCount;
572 }
573
574 //
575 // the corners returned by cvGoodFeaturesToTrack
576 //
577 %typemap(argout) (CvPoint2D32f* corners, int* corner_count) {
578   int i;
579   octave_value to_add;
580     
581   // create the list to return
582   to_add = OctList_New (tmpCount$argnum);
583
584   // extract all the integer values of the result, and add it to the
585   // final resulting list
586   for (i = 0; i < tmpCount$argnum; i++) {
587     OctList_SetItem (to_add, i,
588                      SWIG_NewPointerObj (&($1 [i]),
589                                          $descriptor(CvPoint2D32f *), 0));
590   }
591
592   $result = SWIG_AppendResult($result, &to_add, 1);
593 }
594
595 // map one list of points to the two parameters dimension/sizes
596 // for cvFindCornerSubPix
597 %typemap(in, numinputs=1) (CvPoint2D32f* corners, int count)
598      (int cornersCount, CvPoint2D32f* corners){
599   int i;
600
601   if(!OctList_Check($input)){
602     error("Expected a list");
603     SWIG_fail;
604   }
605
606   // get the size of the input array
607   cornersCount = OctList_Size ($input);
608   $2 = cornersCount;
609
610   // allocate the needed memory
611   corners = (CvPoint2D32f *)malloc ($2 * sizeof (CvPoint2D32f));
612   $1 = corners;
613
614   // the size of the array for the C call
615
616   // extract all the points values from the list
617   for (i = 0; i < $2; i++) {
618     octave_value item = OctList_GetItem ($input, i);
619
620     void *vptr;
621     SWIG_Octave_ConvertPtr (item, &vptr,
622                             $descriptor(CvPoint2D32f*),
623                             SWIG_POINTER_EXCEPTION);
624     CvPoint2D32f *p = (CvPoint2D32f *) vptr;;
625     $1 [i].x = p->x;
626     $1 [i].y = p->y;
627   }
628 }
629
630 //
631 // the corners returned by cvFindCornerSubPix
632 //
633 %typemap(argout) (CvPoint2D32f* corners, int count) {
634   int i;
635   octave_value to_add;
636
637   // create the list to return
638   to_add = OctList_New (cornersCount$argnum);
639
640   // extract all the corner values of the result, and add it to the
641   // final resulting list
642   for (i = 0; i < cornersCount$argnum; i++) {
643     OctList_SetItem (to_add, i,
644                      SWIG_NewPointerObj (&(corners$argnum [i]),
645                                          $descriptor(CvPoint2D32f *), 0));
646   }
647
648   $result = SWIG_AppendResult( $result, &to_add, 1);
649 }
650
651 //
652 // return the corners for cvFindChessboardCorners
653 //
654 %typemap(in, numinputs=1) (CvSize pattern_size, CvPoint2D32f * corners, int * corner_count ) 
655      (CvSize * pattern_size, CvPoint2D32f * tmp_corners, int tmp_ncorners) {
656   void * vptr;
657   if( SWIG_ConvertPtr($input, &vptr, $descriptor( CvSize * ), SWIG_POINTER_EXCEPTION ) == -1){
658     SWIG_fail;
659   }
660   pattern_size=(CvSize *)vptr;
661   tmp_ncorners = pattern_size->width*pattern_size->height;
662
663   tmp_corners = (CvPoint2D32f *) malloc(sizeof(CvPoint2D32f)*tmp_ncorners);
664   $1 = *pattern_size;
665   $2 = tmp_corners;
666   $3 = &tmp_ncorners;
667 }
668
669 %typemap(argout) (CvSize pattern_size, CvPoint2D32f * corners, int * corner_count){
670   int i;
671   octave_value to_add;
672
673   // create the list to return
674   to_add = OctList_New ( tmp_ncorners$argnum );
675
676   // extract all the corner values of the result, and add it to the
677   // final resulting list
678   for (i = 0; i < tmp_ncorners$argnum; i++) {
679     CvPoint2D32f * pt = new CvPoint2D32f;
680     pt->x = tmp_corners$argnum[i].x;
681     pt->y = tmp_corners$argnum[i].y;
682                 
683     OctList_SetItem (to_add, i,
684                      SWIG_NewPointerObj( pt, $descriptor(CvPoint2D32f *), 0));
685   }
686
687   $result = SWIG_AppendResult( $result, &to_add, 1);
688   free(tmp_corners$argnum);
689 }
690
691 //
692 // return the matrices for cvCameraCalibrate
693 //
694 %typemap(in, numinputs=0) (CvMat * intrinsic_matrix, CvMat * distortion_coeffs)
695 {
696   $1 = cvCreateMat(3,3,CV_32F);
697   $2 = cvCreateMat(4,1,CV_32F);
698 }
699
700 %typemap(argout) (CvMat * intrinsic_matrix, CvMat * distortion_coeffs)
701 {
702   octave_value to_add[2];
703   to_add[0] = SWIG_NewPointerObj($1, $descriptor(CvMat *), 1);
704   to_add[1] = SWIG_NewPointerObj($2, $descriptor(CvMat *), 1);
705   $result = SWIG_AppendResult( $result, to_add, 2 );
706 }
707
708 //
709 // Fix OpenCV inheritance for CvSeq, CvSet, CvGraph
710 // Otherwise, can't call CvSeq functions on CvSet or CvGraph
711 //
712 %typemap(in, numinputs=1) (CvSeq *) (void * ptr)
713 {
714         
715   if( SWIG_ConvertPtr($input, &ptr, $descriptor(CvSeq *), 0) == -1 &&
716       SWIG_ConvertPtr($input, &ptr, $descriptor(CvSet *), 0) == -1 &&
717       SWIG_ConvertPtr($input, &ptr, $descriptor(CvGraph *), 0) == -1 &&
718       SWIG_ConvertPtr($input, &ptr, $descriptor(CvSubdiv2D *), 0) == -1 &&
719       SWIG_ConvertPtr($input, &ptr, $descriptor(CvChain *), 0) == -1 &&
720       SWIG_ConvertPtr($input, &ptr, $descriptor(CvContour *), 0) == -1 &&
721       SWIG_ConvertPtr($input, &ptr, $descriptor(CvContourTree *), 0) == -1 )
722     {
723       SWIG_exception (SWIG_TypeError, "could not convert to CvSeq");
724       SWIG_fail;
725     }
726   $1 = (CvSeq *) ptr;
727 }
728
729 %typemap(in, numinputs=1) (CvSet *) (void * ptr)
730 {
731   if( SWIG_ConvertPtr($input, &ptr, $descriptor(CvSet *), 0) == -1 &&
732       SWIG_ConvertPtr($input, &ptr, $descriptor(CvGraph *), 0) == -1 &&
733       SWIG_ConvertPtr($input, &ptr, $descriptor(CvSubdiv2D *), 0) == -1) 
734     {
735       SWIG_exception (SWIG_TypeError, "could not convert to CvSet");
736       SWIG_fail;
737     }
738   $1 = (CvSet *)ptr;
739 }
740
741 %typemap(in, numinputs=1) (CvGraph *) (void * ptr)
742 {
743   if( SWIG_ConvertPtr($input, &ptr, $descriptor(CvGraph *), 0) == -1 &&
744       SWIG_ConvertPtr($input, &ptr, $descriptor(CvSubdiv2D *), 0) == -1) 
745     {
746       SWIG_exception (SWIG_TypeError, "could not convert to CvGraph");
747       SWIG_fail;
748     }
749   $1 = (CvGraph *)ptr;
750 }
751
752 //
753 // Remap output arguments to multiple return values for cvMinEnclosingCircle
754 //
755 %typemap(in, numinputs=0) (CvPoint2D32f * center, float * radius) (CvPoint2D32f * tmp_center, float tmp_radius) 
756 {
757   tmp_center = (CvPoint2D32f *) malloc(sizeof(CvPoint2D32f));
758   $1 = tmp_center;
759   $2 = &tmp_radius;
760 }
761 %typemap(argout) (CvPoint2D32f * center, float * radius)
762 {
763   octave_value to_add[2];
764   to_add[0] = SWIG_NewPointerObj( tmp_center$argnum, $descriptor(CvPoint2D32f *), 1); 
765   to_add[1] = OctFloat_FromDouble( tmp_radius$argnum );
766
767   $result = SWIG_AppendResult($result, to_add, 2);
768 }
769
770 // BoxPoints
771 %typemap(in, numinputs=0) (CvPoint2D32f pt[4]) (CvPoint2D32f tmp_pts[4])
772 {
773   $1 = tmp_pts;
774 }
775 %typemap(argout) (CvPoint2D32f pt[4])
776 {
777   octave_value to_add = OctList_New(4);
778   int i;
779   for(i=0; i<4; i++){
780     CvPoint2D32f * p = new CvPoint2D32f;
781     *p = tmp_pts$argnum[i];
782     OctList_SetItem(to_add, i, SWIG_NewPointerObj( p, $descriptor(CvPoint2D32f *), 1 ) );
783   }
784   $result = SWIG_AppendResult($result, &to_add, 1);
785 }
786
787 // Macro to wrap a built-in type that is used as an object like CvRNG and CvSubdiv2DEdge
788 %define %wrap_builtin(type)
789      %inline %{
790   // Wrapper class
791   class type##_Wrapper {
792   private:
793     type m_val;
794   public:
795     type##_Wrapper( const type & val ) :
796       m_val(val)
797       {
798       }
799     type * ptr() { return &m_val; }
800     type & ref() { return m_val; }
801     bool operator==(const type##_Wrapper & x){
802       return m_val==x.m_val;
803     }
804     bool operator!=(const type##_Wrapper & x){
805       return m_val!=x.m_val;
806     }
807   };
808   %}
809 %typemap(out) type
810 {
811   type##_Wrapper * wrapper = new type##_Wrapper( $1 );
812   $result = SWIG_NewPointerObj( wrapper, $descriptor( type##_Wrapper * ), 1 );
813 }
814 %typemap(out) type *
815 {
816   type##_Wrapper * wrapper = new type##_Wrapper( *($1) );
817   $result = SWIG_NewPointerObj( wrapper, $descriptor( type##_Wrapper * ), 1 );
818 }
819
820 %typemap(in) (type *) (void * vptr, type##_Wrapper * wrapper){
821   if(SWIG_ConvertPtr($input, &vptr, $descriptor(type##_Wrapper *), 0)==-1){
822     SWIG_exception( SWIG_TypeError, "could not convert Octave object to C value");
823     SWIG_fail;
824   }
825   wrapper = (type##_Wrapper *) vptr;
826   $1 = wrapper->ptr();
827 }
828 %typemap(in) (type) (void * vptr, type##_Wrapper * wrapper){
829   if(SWIG_ConvertPtr($input, &vptr, $descriptor(type##_Wrapper *), 0)==-1){
830     SWIG_exception( SWIG_TypeError, "could not convert Octave object to C value");
831     SWIG_fail;
832   }
833   wrapper = (type##_Wrapper *) vptr;
834   $1 = wrapper->ref();
835 }
836 %enddef 
837
838 // Application of wrapper class to built-in types
839 %wrap_builtin(CvRNG);
840 %wrap_builtin(CvSubdiv2DEdge);
841
842 //
843 // Allow CvQuadEdge2D to be interpreted as CvSubdiv2DEdge
844 //
845 %typemap(in, numinputs=1) (CvSubdiv2DEdge) (CvSubdiv2DEdge_Wrapper * wrapper, CvQuadEdge2D * qedge, void *vptr)
846 {
847   if( SWIG_ConvertPtr($input, &vptr, $descriptor(CvSubdiv2DEdge_Wrapper *), 0) != -1 ){
848     wrapper = (CvSubdiv2DEdge_Wrapper *) vptr;
849     $1 = wrapper->ref();
850   }
851   else if( SWIG_ConvertPtr($input, &vptr, $descriptor(CvQuadEdge2D *), 0) != -1 ){
852     qedge = (CvQuadEdge2D *) vptr;
853     $1 = (CvSubdiv2DEdge)qedge;
854   }
855   else{
856     SWIG_exception( SWIG_TypeError, "could not convert to CvSubdiv2DEdge");
857     SWIG_fail;
858   }
859 }
860
861 //
862 // return the vertex and edge for cvSubdiv2DLocate
863 //
864 %typemap(in, numinputs=0) (CvSubdiv2DEdge * edge, CvSubdiv2DPoint ** vertex) 
865      (CvSubdiv2DEdge tmpEdge, CvSubdiv2DPoint * tmpVertex)
866 {
867   $1 = &tmpEdge;
868   $2 = &tmpVertex;
869 }
870 %typemap(argout) (CvSubdiv2DEdge * edge, CvSubdiv2DPoint ** vertex)
871 {
872   octave_value to_add[2];
873   if(result==CV_PTLOC_INSIDE || result==CV_PTLOC_ON_EDGE){
874     CvSubdiv2DEdge_Wrapper * wrapper = new CvSubdiv2DEdge_Wrapper( tmpEdge$argnum );
875     to_add[0] = SWIG_NewPointerObj( wrapper, $descriptor(CvSubdiv2DEdge_Wrapper *), 0);
876     to_add[1] = octave_value();
877   }
878   if(result==CV_PTLOC_VERTEX){
879     to_add[0] = octave_value();
880     to_add[1] = SWIG_NewPointerObj( tmpVertex$argnum, $descriptor(CvSubdiv2DPoint *), 0);
881   }
882         
883   $result = SWIG_AppendResult($result, to_add, 2);
884 }
885
886 //
887 // int *value  in cvCreateTrackbar() is only used for input in the Octave wrapper.
888 // for output, use the pos in the callback
889 // TODO: remove the memory leak introducted by the malloc () (if needed).
890 //
891 %typemap(in, numinputs=1) (int *value)
892 {
893   $1 = (int *)malloc (sizeof (int));
894   *$1 = OctInt_AsLong ($input);
895 }
896