Move the sources to trunk
[opencv] / interfaces / matlab / src / tmacro.h
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
42 #if _MSC_VER > 1000
43 #pragma once
44 #endif
45
46 #ifndef _TMACRO_H_
47 #define _TMACRO_H_
48
49 template< class T >
50 class CArray
51 {
52         public:
53                 CArray() : data( 0 ), bReleaseData( false ) {}
54                 ~CArray()
55                 {
56                         if( bReleaseData && data )
57                         {
58                                 delete[] data;
59                                 data = 0;
60                         }
61                 }
62
63                 // create data array of size _num
64                 void create( int _num = 0 )
65                 {
66                         assert( !data );
67                         if( _num > 0 )
68                         {
69                                 data = new T[_num];
70                         }
71                         bReleaseData = true;
72                 }
73
74                 // Set external data
75                 void set( T *_data )
76                 {
77                         assert( !data );
78                         data = _data;
79                         bReleaseData = false;
80                 }
81
82                 operator T *() { return( data ); }
83                 T *getData() { return( data ); }
84                 operator T() { return( data[0] ); }
85
86                 T operator=( T val ) { data[0] = val; return( val ); }
87                 
88                 T &operator[]( int index ) { return( data[index] ); }
89
90         protected:
91                 T *data;
92                 bool bReleaseData;
93                 
94                 // prevent from copying
95                 CArray( const CArray &arr );
96                 CArray &operator=( const CArray &arr );
97 };
98
99 class CImage
100 {
101         public:
102                 CImage() : header( 0 ), bReleaseData( false ) {}
103                 ~CImage()
104                 {
105                         if( header )
106                         {
107                                 if( bReleaseData )
108                                 {
109                                         cvReleaseData( header );
110                                         bReleaseData = false;
111                                 }
112                                 cvReleaseImageHeader( & header );
113                                 header = 0;
114                         }
115                 }
116                 
117                 void  createHeader( CvSize size, int depth, int channels )
118                 {
119                         assert( !header );
120                         header = cvCreateImageHeader( size, depth, channels );
121                 }
122                 
123                 // Set external data
124                 void setData( void *data, int step )
125                 {
126                         assert( header );
127                         assert( !bReleaseData );
128                         cvSetData( header, data, step );
129                 }
130
131                 // Create own data. It will be automatically released
132                 void createData()
133                 {
134                         assert( header );
135                         assert( !bReleaseData );
136                         cvCreateData( header );
137                         bReleaseData = true;
138                 }
139                 operator IplImage *() { return( header ); }
140
141         private:
142                 IplImage *header;
143                 bool bReleaseData;
144
145                 // prevent from copying
146                 CImage( const CImage &arr );
147                 CImage &operator=( const CImage &arr );
148 };
149
150 class CStorage
151 {
152         public:
153                 CStorage() { storage = cvCreateMemStorage(); }
154                 ~CStorage() { cvReleaseMemStorage( &storage ); }
155                 operator CvMemStorage *() { return( storage ); }
156         private:
157                 CvMemStorage *storage;
158
159                 // prevent from copying
160                 CStorage( const CStorage &obj );
161                 CStorage &operator=( const CStorage &obj );
162 };
163
164 class CStructElem
165 {
166         public:
167                 CStructElem() : structElem( 0 ) {}
168                 ~CStructElem()
169                 {
170                         if( structElem )
171                         {
172                                 cvReleaseStructuringElement( &structElem );
173                                 structElem = 0;
174                         }
175                 }
176                 
177                 void create( int cols, int rows, int anchorX, int anchorY, 
178                         CvElementShape shape, int *values = 0 )
179                 {
180                         assert( !structElem );
181                         structElem = cvCreateStructuringElementEx( cols, rows, 
182                                 anchorX, anchorY, shape, values );
183                 }
184
185                 operator IplConvKernel *() { return( structElem ); }
186         private:
187                 IplConvKernel *structElem;
188
189                 // prevent from copying
190                 CStructElem( const CStructElem &obj );
191                 CStructElem &operator=( const CStructElem &obj );
192 };
193
194 // castCopy
195 template< class T1, class T2 >
196 void castCopy( T1 *src, T2 *dst, int rowNum, int colNum,
197                            int srcRowStep, int srcColStep,
198                            int dstRowStep, int dstColStep )
199 {
200         for( int r = 0; r < rowNum; r++ )
201         {
202                 for( int c = 0; c < colNum; c++ )
203                 {
204                         dst[r * dstRowStep + c * dstColStep] = 
205                                 static_cast< T2 > ( src[r * srcRowStep + c * srcColStep] );
206                 }
207         }
208 }
209
210 #define MXTYPE_DATAPTR( type, part1, ptrName, part2 ) \
211         switch( type ) \
212         { \
213                 case mxDOUBLE_CLASS: \
214                 { \
215                         part1; \
216                         double *ptrName = (double *)part2; \
217                         break; \
218                 } \
219                 case mxSINGLE_CLASS: \
220                 { \
221                         part1; \
222                         float *ptrName = (float *)part2; \
223                         break; \
224                 } \
225                 case mxINT32_CLASS: \
226                 { \
227                         part1; \
228                         signed int *ptrName = (signed int *)part2; \
229                         break; \
230                 } \
231                 case mxUINT32_CLASS: \
232                 { \
233                         part1; \
234                         unsigned int *ptrName = (unsigned int *)part2; \
235                         break; \
236                 } \
237                 case mxINT16_CLASS: \
238                 { \
239                         part1; \
240                         signed short *ptrName = (signed short *)part2; \
241                         break; \
242                 } \
243                 case mxUINT16_CLASS: \
244                 { \
245                         part1; \
246                         unsigned short *ptrName = (unsigned short *)part2; \
247                         break; \
248                 } \
249                 case mxINT8_CLASS: \
250                 { \
251                         part1; \
252                         signed char *ptrName = (signed char *)part2; \
253                         break; \
254                 } \
255                 case mxUINT8_CLASS: \
256                 { \
257                         part1; \
258                         unsigned char *ptrName = (unsigned char *)part2; \
259                         break; \
260                 } \
261                 default: \
262                         throw_error( "Parameter should be numeric." ); \
263                         break; \
264         } 
265
266 // Execute callfun. If an error occured, add to the error
267 // #name and rethrow it.
268 #define _ENHANCE_ERROR( callfun, name ) \
269         try \
270         { \
271                 callfun; \
272         } \
273         catch( Error _e ) \
274         { \
275                 std::ostringstream ostr; \
276                 ostr << _e.get_error_messages() << " Parameter: " << #name; \
277                 throw_error( ostr.str() ); \
278         }
279
280 #define _CREATE_MATRIX( n, rows, cols, class ) \
281         plhs[n] = mxCreateNumericMatrix( rows, cols, class, mxREAL );
282
283 #define _CREATE_VECTOR( name ) \
284         int _m = ( name##_vecType == any || name##_vecType == row ) ? \
285                 1 : name##_num; \
286         int _n = ( name##_vecType == any || name##_vecType == row ) ? \
287                 name##_num : 1; \
288         _CREATE_MATRIX( name##_n, _m, _n, name##_class ); 
289
290 #define _CREATE_IMAGE( name ) \
291         if( name##_channels == 3 ) \
292         { \
293                 const int ndim = 3; \
294                 int dims[ndim]; \
295                 dims[0] = name##_size.width; \
296                 dims[1] = name##_size.height; \
297                 dims[2] = name##_channels; \
298                 plhs[name##_n] = \
299                         mxCreateNumericArray(ndim, dims, name##_class, mxREAL );\
300         } \
301         else \
302         { \
303                 _CREATE_MATRIX( name##_n, name##_size.width, name##_size.height, \
304                     name##_class ); \
305         }
306
307 /* Macro for convert functions of certain type */
308 #define FUNC_CONVERT( type, \
309         getDecl, getParam, getAssign, \
310         putDecl, putAssign, putParam ) \
311          \
312         template< class T1 > \
313         void convert( T1 *src, type *dst, int num ) \
314         { \
315                 \
316                 getDecl; \
317                 \
318                 int nelem = 0; \
319                 for( nelem = 0; nelem < num; nelem++ ) \
320                 { \
321                         castCopy( src+nelem, getParam, 1, type##NUMFIELDS, 1, num, 1, 1 ); \
322                         \
323                         getAssign; \
324                         \
325                 } /* for each elem in arr */ \
326         } \
327          \
328         template< class T2 > \
329         void convert( type *src, T2 *dst, int num ) \
330         { \
331                 \
332                 putDecl; \
333                 \
334                 int nelem = 0; \
335                 for( nelem = 0; nelem < num; nelem++ ) \
336                 { \
337                         \
338                         putAssign; \
339                         \
340                         castCopy( putParam, dst+nelem, 1, type##NUMFIELDS, 1, 1, 1, num ); \
341                 } /* for each elem in arr */ \
342         }
343
344 // type CvPoint
345 #define CvPointNUMFIELDS 2
346 FUNC_CONVERT( CvPoint,
347                           ;,
348                           (int *)(dst+nelem),
349                           ;,
350                           ;,
351                           ;,
352                           (int *)(src + nelem) )
353
354 // type CvPoint0S
355 // Convert from 1-based to 0-based and swap coordinates 
356 struct CvPoint0S : public CvPoint {};
357 #define CvPoint0SNUMFIELDS 2
358 FUNC_CONVERT( CvPoint0S,
359                           int _tmp,
360                           (int *)(dst+nelem),
361                           _tmp = dst[nelem].x - 1; dst[nelem].x = dst[nelem].y - 1;
362                           dst[nelem].y = _tmp;,
363                           CvPoint point,
364                           point.x = src[nelem].y + 1; point.y = src[nelem].x + 1;,
365                           (int *)&point )
366
367 // type CvSizeS
368 // Swap coordinates 
369 struct CvSizeS : public CvSize {};
370 #define CvSizeSNUMFIELDS 2
371 FUNC_CONVERT( CvSizeS,
372                           int _tmp,
373                           (int *)(dst+nelem),
374                           _tmp = dst[nelem].width; dst[nelem].width = dst[nelem].height;
375                           dst[nelem].height = _tmp;,
376                           CvSize elem,
377                           elem.width = src[nelem].height; elem.height = src[nelem].width;,
378                           (int *)&elem )
379
380 // type CvSlice0
381 // Convert from 1-based to 0-based
382 struct CvSlice0 : public CvSlice {};
383 #define CvSlice0NUMFIELDS 2
384 FUNC_CONVERT( CvSlice0,
385                           ;,
386                           (int *)(dst+nelem),
387                           dst[nelem].startIndex = ( dst[nelem].startIndex > 0 ) ?
388                                   dst[nelem].startIndex - 1 : dst[nelem].startIndex;
389                           dst[nelem].endIndex = ( dst[nelem].endIndex > 0 ) ?
390                                   dst[nelem].endIndex - 1 : dst[nelem].endIndex;,
391                           CvSlice slice,
392                           slice.startIndex = src[nelem].startIndex + 
393                                   ( src[nelem].startIndex >= 0 ) ? 1 : 0;
394                           slice.endIndex = src[nelem].endIndex + 
395                                   ( src[nelem].endIndex >= 0 ) ? 1 : 0;,
396                           (int *)&slice )
397
398 // type CvPoint2D32f
399 #define CvPoint2D32fNUMFIELDS 2
400 FUNC_CONVERT( CvPoint2D32f,
401                           ;,
402                           (float *)(dst+nelem),
403                           ;,
404                           ;,
405                           ;,
406                           (float *)(src + nelem) )
407
408 // type CvPoint2D32fS
409 // Swap coordinates 
410 struct CvPoint2D32fS : public CvPoint2D32f {};
411 #define CvPoint2D32fSNUMFIELDS 2
412 FUNC_CONVERT( CvPoint2D32fS,
413                           float _tmp,
414                           (float *)(dst+nelem),
415                           _tmp = dst[nelem].x; dst[nelem].x = dst[nelem].y;
416                           dst[nelem].y = _tmp;,
417                           CvPoint2D32f point,
418                           point.x = src[nelem].y; point.y = src[nelem].x;,
419                           (float *)&point )
420
421 // type CvRect
422 #define CvRectNUMFIELDS 4
423 FUNC_CONVERT( CvRect,
424                           ;,
425                           (int *)(dst+nelem),
426                           ;,
427                           ;,
428                           ;,
429                           (int *)(src+nelem) )
430
431 // type CvRect0S
432 // Convert from 1-based to 0-based and swap coordinates 
433 struct CvRect0S : public CvRect {};
434 #define CvRect0SNUMFIELDS 4
435 FUNC_CONVERT( CvRect0S,
436                           int _tmp,
437                           (int *)(dst+nelem),
438                           _tmp = dst[nelem].x - 1; dst[nelem].x = dst[nelem].y - 1;
439                           dst[nelem].y = _tmp;
440                           _tmp = dst[nelem].width - 1;
441                           dst[nelem].width = dst[nelem].height - 1;
442                           dst[nelem].height = _tmp;,
443                           CvRect elem,
444                           elem.x = src[nelem].y + 1; elem.y = src[nelem].x + 1;
445                           elem.width = src[nelem].height;
446                           elem.height = src[nelem].width;,
447                           (int *)&elem )
448
449 // type CvTermCriteria
450 #define CvTermCriteriaNUMFIELDS 2
451 FUNC_CONVERT( CvTermCriteria,
452                           double elem[2];,
453                           (double *)elem,
454                           dst[nelem].type = 0;
455                           dst[nelem].maxIter = 0;
456                           dst[nelem].epsilon = 0.0f;
457                           if( elem[0] > 0.0 )
458                           {
459                                   dst[nelem].type |= CV_TERMCRIT_ITER;
460                                   dst[nelem].maxIter = static_cast< int > ( elem[0] );
461                           }
462                           if( elem[1] > 0.0 )
463                           {
464                                   dst[nelem].type |= CV_TERMCRIT_EPS;
465                                   dst[nelem].epsilon = static_cast< float > ( elem[1] );
466                           },
467                           double elem[2];,
468                           elem[0] = ( ( src[nelem].type & CV_TERMCRIT_ITER ) ? 
469                           static_cast< double > ( src[nelem].maxIter ) : 0.0 );
470                           elem[1] = ( ( src[nelem].type & CV_TERMCRIT_EPS ) ? 
471                           static_cast< double > ( src[nelem].epsilon ) : 0.0 );,
472                           (double *)elem )
473
474 #endif /* _TMACRO_H_ */