Update the trunk to the OpenCV's CVS (2008-07-14)
[opencv] / cvaux / include / cvmat.hpp
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 #ifndef _CVMAT_HPP_
43 #define _CVMAT_HPP_
44
45 #if 0 && (defined __cplusplus && (_MSC_VER>=1200 || defined __BORLANDC__ || defined __GNUC__))
46
47 #if _MSC_VER >= 1200
48 #pragma warning( disable: 4710 ) /* suppress "function ... is not inlined" */
49 #endif
50
51 #include <string.h>
52 #include <stdio.h>
53
54 #undef min
55 #undef max
56
57 /****************************************************************************************\
58 *                            C++ - like operations on CvScalar                           *
59 \****************************************************************************************/
60
61 inline CvScalar& operator += ( CvScalar& a, const CvScalar& b )
62 {
63     double t0 = a.val[0] + b.val[0];
64     double t1 = a.val[1] + b.val[1];
65     a.val[0] = t0;
66     a.val[1] = t1;
67
68     t0 = a.val[2] + b.val[2];
69     t1 = a.val[3] + b.val[3];
70     a.val[2] = t0;
71     a.val[3] = t1;
72
73     return a;
74 }
75
76
77 inline CvScalar& operator -= ( CvScalar& a, const CvScalar& b )
78 {
79     double t0 = a.val[0] - b.val[0];
80     double t1 = a.val[1] - b.val[1];
81     a.val[0] = t0;
82     a.val[1] = t1;
83
84     t0 = a.val[2] - b.val[2];
85     t1 = a.val[3] - b.val[3];
86     a.val[2] = t0;
87     a.val[3] = t1;
88
89     return a;
90 }
91
92
93 inline CvScalar& operator *= ( CvScalar& a, double b )
94 {
95     double t0 = a.val[0] * b;
96     double t1 = a.val[1] * b;
97     a.val[0] = t0;
98     a.val[1] = t1;
99
100     t0 = a.val[2] * b;
101     t1 = a.val[3] * b;
102     a.val[2] = t0;
103     a.val[3] = t1;
104
105     return a;
106 }
107
108
109 inline CvScalar& operator /= ( CvScalar& a, double b )
110 {
111     double inv_b = 1./b;
112     double t0 = a.val[0] * inv_b;
113     double t1 = a.val[1] * inv_b;
114     a.val[0] = t0;
115     a.val[1] = t1;
116
117     t0 = a.val[2] * inv_b;
118     t1 = a.val[3] * inv_b;
119     a.val[2] = t0;
120     a.val[3] = t1;
121
122     return a;
123 }
124
125
126 inline CvScalar& operator *= ( CvScalar& a, const CvScalar& b )
127 {
128     double t0 = a.val[0]*b.val[0] - a.val[1]*b.val[1] -
129                 a.val[2]*b.val[2] - a.val[3]*b.val[3];
130
131     double t1 = a.val[0]*b.val[1] + a.val[1]*b.val[0] +
132                 a.val[2]*b.val[3] - a.val[3]*b.val[2];
133
134     double t2 = a.val[0]*b.val[2] - a.val[1]*b.val[3] +
135                 a.val[2]*b.val[0] + a.val[3]*b.val[1];
136
137     double t3 = a.val[0]*b.val[3] + a.val[1]*b.val[2] -
138                 a.val[2]*b.val[1] + a.val[3]*b.val[0];
139
140     a.val[0] = t0;
141     a.val[1] = t1;
142     a.val[2] = t2;
143     a.val[3] = t3;
144
145     return a;
146 }
147
148
149 inline CvScalar& operator /= ( CvScalar& a, const CvScalar& b )
150 {
151     double inv_d = -1./(b.val[0]*b.val[0] + b.val[1]*b.val[1] +
152                         b.val[2]*b.val[2] + b.val[3]*b.val[3]);
153     return a *= cvScalar( b.val[0] * -inv_d, b.val[1] * inv_d,
154                           b.val[2] * inv_d, b.val[3] * inv_d );
155 }
156
157
158 inline CvScalar& operator += ( CvScalar& a, double b )
159 {
160     a.val[0] += b;
161     return a;
162 }
163
164
165 inline CvScalar& operator -= ( CvScalar& a, double b )
166 {
167     a.val[0] -= b;
168     return a;
169 }
170
171
172 inline CvScalar operator + ( const CvScalar& a, const CvScalar& b )
173 {
174     return cvScalar( a.val[0] + b.val[0], a.val[1] + b.val[1],
175                      a.val[2] + b.val[2], a.val[3] + b.val[3] );
176 }
177
178
179 inline CvScalar operator - ( const CvScalar& a, const CvScalar& b )
180 {
181     return cvScalar( a.val[0] - b.val[0], a.val[1] - b.val[1],
182                      a.val[2] - b.val[2], a.val[3] - b.val[3] );
183 }
184
185
186 inline CvScalar operator + ( const CvScalar& a, double b )
187 {
188     return cvScalar( a.val[0] + b, a.val[1], a.val[2], a.val[3] );
189 }
190
191
192 inline CvScalar operator - ( const CvScalar& a, double b )
193 {
194     return cvScalar( a.val[0] - b, a.val[1], a.val[2], a.val[3] );
195 }
196
197
198 inline CvScalar operator + ( double a, const CvScalar& b )
199 {
200     return cvScalar( a + b.val[0], b.val[1], b.val[2], b.val[3] );
201 }
202
203
204 inline CvScalar operator - ( double a, const CvScalar& b )
205 {
206     return cvScalar( a - b.val[0], -b.val[1], -b.val[2], -b.val[3] );
207 }
208
209
210 inline CvScalar operator - ( const CvScalar& b )
211 {
212     return cvScalar( -b.val[0], -b.val[1], -b.val[2], -b.val[3] );
213 }
214
215
216 inline CvScalar operator * ( const CvScalar& a, const CvScalar& b )
217 {
218     CvScalar c = a;
219
220     return (c *= b);
221 }
222
223
224 inline CvScalar operator * ( const CvScalar& a, double b )
225 {
226     return cvScalar( a.val[0]*b, a.val[1]*b, a.val[2]*b, a.val[3]*b );
227 }
228
229
230 inline CvScalar operator * ( double a, const CvScalar& b )
231 {
232     return cvScalar( b.val[0]*a, b.val[1]*a, b.val[2]*a, b.val[3]*a );
233 }
234
235
236 inline CvScalar operator / ( const CvScalar& a, const CvScalar& b )
237 {
238     CvScalar c = a;
239     return (c /= b);
240 }
241
242
243 inline CvScalar operator / ( const CvScalar& a, double b )
244 {
245     double inv_b = 1./b;
246     return cvScalar( a.val[0]*inv_b, a.val[1]*inv_b,
247                      a.val[2]*inv_b, a.val[3]*inv_b );
248 }
249
250
251 inline CvScalar operator / ( double a, const CvScalar& b )
252 {
253     double inv_d = -a/(b.val[0]*b.val[0] + b.val[1]*b.val[1] +
254                        b.val[2]*b.val[2] + b.val[3]*b.val[3]);
255     return cvScalar( b.val[0] * -inv_d, b.val[1] * inv_d,
256                      b.val[2] * inv_d, b.val[3] * inv_d );
257 }
258
259
260 inline CvScalar& operator &= ( CvScalar& a, const CvScalar& b )
261 {
262     int t0 = cvRound(a.val[0]) & cvRound(b.val[0]);
263     int t1 = cvRound(a.val[1]) & cvRound(b.val[1]);
264     a.val[0] = t0;
265     a.val[1] = t1;
266
267     t0 = cvRound(a.val[2]) & cvRound(b.val[2]);
268     t1 = cvRound(a.val[3]) & cvRound(b.val[3]);
269     a.val[2] = t0;
270     a.val[3] = t1;
271
272     return a;
273 }
274
275
276 inline CvScalar& operator |= ( CvScalar& a, const CvScalar& b )
277 {
278     int t0 = cvRound(a.val[0]) | cvRound(b.val[0]);
279     int t1 = cvRound(a.val[1]) | cvRound(b.val[1]);
280     a.val[0] = t0;
281     a.val[1] = t1;
282
283     t0 = cvRound(a.val[2]) | cvRound(b.val[2]);
284     t1 = cvRound(a.val[3]) | cvRound(b.val[3]);
285     a.val[2] = t0;
286     a.val[3] = t1;
287
288     return a;
289 }
290
291
292 inline CvScalar& operator ^= ( CvScalar& a, const CvScalar& b )
293 {
294     int t0 = cvRound(a.val[0]) ^ cvRound(b.val[0]);
295     int t1 = cvRound(a.val[1]) ^ cvRound(b.val[1]);
296     a.val[0] = t0;
297     a.val[1] = t1;
298
299     t0 = cvRound(a.val[2]) ^ cvRound(b.val[2]);
300     t1 = cvRound(a.val[3]) ^ cvRound(b.val[3]);
301     a.val[2] = t0;
302     a.val[3] = t1;
303
304     return a;
305 }
306
307
308 inline CvScalar operator & ( const CvScalar& a, const CvScalar& b )
309 {
310     CvScalar c = a;
311     return (c &= b);
312 }
313
314
315 inline CvScalar operator | ( const CvScalar& a, const CvScalar& b )
316 {
317     CvScalar c = a;
318     return (c |= b);
319 }
320
321
322 inline CvScalar operator ^ ( const CvScalar& a, const CvScalar& b )
323 {
324     CvScalar c = a;
325     return (c ^= b);
326 }
327
328
329 inline CvScalar operator ~ ( const CvScalar& a )
330 {
331     return cvScalar( ~cvRound(a.val[0]), ~cvRound(a.val[1]),
332                      ~cvRound(a.val[2]), ~cvRound(a.val[3])); 
333 }
334
335
336 /****************************************************************************************\
337 *                                   C++ Matrix Class                                     *
338 \****************************************************************************************/
339
340 struct  _CvMATConstElem_;
341 struct  _CvMATElem_;
342 struct  _CvMATElemCn_;
343
344 struct  _CvMAT_T_;
345 struct  _CvMAT_MUL_;
346 struct  _CvMAT_INV_;
347 struct  _CvMAT_SCALE_;
348 struct  _CvMAT_SCALE_SHIFT_;
349 struct  _CvMAT_ADD_;
350 struct  _CvMAT_ADD_EX_;
351 struct  _CvMAT_MUL_ADD_;
352 struct  _CvMAT_LOGIC_;
353 struct  _CvMAT_UN_LOGIC_;
354 struct  _CvMAT_NOT_;
355 struct  _CvMAT_CVT_;
356 struct  _CvMAT_COPY_;
357 struct  _CvMAT_DOT_OP_;
358 struct  _CvMAT_SOLVE_;
359 struct  _CvMAT_CMP_;
360
361 class CV_EXPORTS CvMAT : public CvMat
362 {
363 protected:
364
365 public:
366     /* helper methods for retrieving/setting matrix elements */
367     static double get( const uchar* ptr, int type, int coi = 0 );
368     static void set( uchar* ptr, int type, int coi, double d );
369     static void set( uchar* ptr, int type, int coi, int i );
370     static void set( uchar* ptr, int type, double d );
371     static void set( uchar* ptr, int type, int i );
372
373     /******************* constructors ********************/
374     /* empty */
375     explicit CvMAT();
376
377     /* creation */
378     explicit CvMAT( int rows, int cols, int type, void* data, int step = CV_AUTOSTEP );
379     explicit CvMAT( int rows, int type, void* data, int step = CV_AUTOSTEP );
380     explicit CvMAT( int rows, int cols, int type );
381     explicit CvMAT( int rows, int type );
382     
383     /* extracting part of an existing matrix */
384     explicit CvMAT( const CvMat& mat, CvRect rect ); /* submatrix */
385     explicit CvMAT( const CvMat& mat, int k, int i ); /* submatrix:
386                                                     k == 0 - i-th row
387                                                     k > 0 - i-th column
388                                                     k < 0 - i-th diagonal */
389     /* copying */
390     CvMAT( const CvMat& mat );
391     CvMAT( const CvMAT& mat );
392     CvMAT( const IplImage& img );
393
394     /* CvMAT b = op(a1,a2,...) */
395     explicit CvMAT( const _CvMAT_T_& mat_t );
396     explicit CvMAT( const _CvMAT_INV_& inv_mat );
397     explicit CvMAT( const _CvMAT_ADD_& mat_add );
398     explicit CvMAT( const _CvMAT_ADD_EX_& mat_add );
399     explicit CvMAT( const _CvMAT_SCALE_& scale_mat );
400     explicit CvMAT( const _CvMAT_SCALE_SHIFT_& scale_shift_mat );
401     explicit CvMAT( const _CvMAT_MUL_& mmul );
402     explicit CvMAT( const _CvMAT_MUL_ADD_& mmuladd );
403     explicit CvMAT( const _CvMAT_LOGIC_& mat_logic );
404     explicit CvMAT( const _CvMAT_UN_LOGIC_& mat_logic );
405     explicit CvMAT( const _CvMAT_NOT_& not_mat );
406     explicit CvMAT( const _CvMAT_COPY_& mat_copy );
407     explicit CvMAT( const _CvMAT_CVT_& mat_copy );
408     explicit CvMAT( const _CvMAT_DOT_OP_& dot_mul );
409     explicit CvMAT( const _CvMAT_SOLVE_& solve_mat );
410     explicit CvMAT( const _CvMAT_CMP_& cmp_mat );
411
412     /* desctructor */
413     ~CvMAT();
414
415     /* copying and filling with a constant */
416     CvMAT& operator = ( const CvMAT& mat );
417     CvMAT& operator = ( const CvMat& mat );
418     CvMAT& operator = ( const IplImage& img );
419     CvMAT& operator = ( double fillval );
420     CvMAT& operator = ( const CvScalar& fillval );
421     
422     /* b = op(a1, a2,...) */
423     CvMAT& operator = ( const _CvMAT_T_& mat_t );
424     CvMAT& operator = ( const _CvMAT_INV_& inv_mat );
425     CvMAT& operator = ( const _CvMAT_ADD_& mat_add );
426     CvMAT& operator = ( const _CvMAT_ADD_EX_& mat_add );
427     CvMAT& operator = ( const _CvMAT_SCALE_& scale_mat );
428     CvMAT& operator = ( const _CvMAT_SCALE_SHIFT_& scale_shift_mat );
429     CvMAT& operator = ( const _CvMAT_MUL_& mmul );
430     CvMAT& operator = ( const _CvMAT_MUL_ADD_& mmuladd );
431     CvMAT& operator = ( const _CvMAT_LOGIC_& mat_logic );
432     CvMAT& operator = ( const _CvMAT_UN_LOGIC_& mat_logic );
433     CvMAT& operator = ( const _CvMAT_NOT_& not_mat );
434     CvMAT& operator = ( const _CvMAT_DOT_OP_& dot_mul );
435     CvMAT& operator = ( const _CvMAT_SOLVE_& solve_mat );
436     CvMAT& operator = ( const _CvMAT_CMP_& cmp_mat );
437     CvMAT& operator = ( const _CvMAT_CVT_& mat_cvt );
438
439     /* copy matrix data, not only matrix header */
440     CvMAT& operator = ( const _CvMAT_COPY_& mat_copy );
441
442     /* augmented assignments */
443     CvMAT& operator += ( const CvMat& mat );
444     CvMAT& operator += ( double val );
445     CvMAT& operator += ( const CvScalar& val );
446     CvMAT& operator += ( const _CvMAT_SCALE_& scale_mat );
447     CvMAT& operator += ( const _CvMAT_SCALE_SHIFT_& scale_mat );
448     CvMAT& operator += ( const _CvMAT_MUL_& mmul );
449
450     CvMAT& operator -= ( const CvMat& mat );
451     CvMAT& operator -= ( double val );
452     CvMAT& operator -= ( const CvScalar& val );
453     CvMAT& operator -= ( const _CvMAT_SCALE_& scale_mat );
454     CvMAT& operator -= ( const _CvMAT_SCALE_SHIFT_& scale_mat );
455     CvMAT& operator -= ( const _CvMAT_MUL_& mmul );
456
457     CvMAT& operator *= ( const CvMat& mat );
458     CvMAT& operator *= ( double val );
459     CvMAT& operator *= ( const CvScalar& val );
460     CvMAT& operator *= ( const _CvMAT_SCALE_& scale_mat );
461     CvMAT& operator *= ( const _CvMAT_SCALE_SHIFT_& scale_mat );
462
463     CvMAT& operator &= ( const CvMat& mat );
464     CvMAT& operator &= ( double val );
465     CvMAT& operator &= ( const CvScalar& val );
466
467     CvMAT& operator |= ( const CvMat& mat );
468     CvMAT& operator |= ( double val );
469     CvMAT& operator |= ( const CvScalar& val );
470
471     CvMAT& operator ^= ( const CvMat& mat );
472     CvMAT& operator ^= ( double val );
473     CvMAT& operator ^= ( const CvScalar& val );
474
475     /* various scalar charactertics */
476     double norm( int norm_type = CV_L2 ) const;
477     double norm( CvMat& mat, int norm_type = CV_L2 ) const;
478     CvScalar sum() const;
479
480     double det() const;
481     double trace() const;
482
483     _CvMAT_T_  t() const; /* transposition */
484     _CvMAT_INV_ inv(int method = 0) const;
485     /* inversion using one of the following methods:
486           method = 0 - Gaussian elimination,
487           method = 1 - SVD */
488
489     _CvMAT_DOT_OP_  mul( const CvMAT& mat ) const;
490     _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& mat ) const;
491
492     _CvMAT_DOT_OP_  div( const CvMAT& mat ) const;
493     _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& mat ) const;
494
495     _CvMAT_DOT_OP_  min( const CvMAT& mat ) const;
496     _CvMAT_DOT_OP_  max( const CvMAT& mat ) const;
497     _CvMAT_DOT_OP_  min( double value ) const;
498     _CvMAT_DOT_OP_  max( double value ) const;
499     double          min( CvPoint* minloc = 0 ) const;
500     double          max( CvPoint* maxloc = 0 ) const;
501
502     _CvMAT_DOT_OP_  abs() const;
503     
504     /* accessing matrix elements */
505     _CvMATElem_ operator ()( int row );
506     _CvMATConstElem_ operator ()( int row ) const;
507
508     _CvMATElem_ operator ()( int row, int col );
509     _CvMATConstElem_ operator ()( int row, int col ) const;
510
511     _CvMATElem_ operator ()( CvPoint loc );
512     _CvMATConstElem_ operator ()( CvPoint loc ) const;
513
514     _CvMATElemCn_ operator()( int row, int col, int coi );
515     double operator()( int row, int col, int coi ) const;
516
517     _CvMATElemCn_ operator()( CvPoint pt, int coi );
518     double operator()( CvPoint pt, int coi ) const;
519
520     void* ptr( int row );
521     const void* ptr( int row ) const;
522
523     void* ptr( int row, int col );
524     const void* ptr( int row, int col ) const;
525
526     void* ptr( CvPoint pt );
527     const void* ptr( CvPoint pt ) const;
528
529     /* accessing matrix parts */
530     CvMAT row( int row ) const;
531     CvMAT rowrange( int row1, int row2 ) const;
532     CvMAT col( int col ) const;
533     CvMAT colrange( int col1, int col2 ) const;
534     CvMAT rect( CvRect rect ) const;
535     CvMAT diag( int diag = 0 ) const;
536
537     _CvMAT_COPY_ clone() const;
538
539     /* convert matrix */
540     _CvMAT_CVT_ cvt( int newdepth = -1, double scale = 1,
541                      double shift = 0 ) const;
542
543     /* matrix transformation */
544     void  reshape( int newcn, int newrows = 0 );
545     void  flipX();
546     void  flipY();
547     void  flipXY();
548
549     /* matrix I/O: use dynamically linked runtime libraries */
550     void  write( const char* name = 0, FILE* f = 0, const char* fmt = 0 );
551     void  read( char** name = 0, FILE* f = 0 );
552
553     /* decrease matrix data reference counter and clear data pointer */
554     void  release();
555 protected:
556     
557     void  create( int rows, int cols, int type );
558 };
559
560
561 /* !!! Internal Use Only !!! */
562 /* proxies for matrix elements */
563
564 /* const_A(i,j) */
565 struct  CV_EXPORTS _CvMATConstElem_
566 {
567     explicit _CvMATConstElem_( const uchar* ptr, int type );
568     operator CvScalar () const;
569     double operator ()( int coi = 0 ) const;
570
571     uchar* ptr;
572     int type;
573 };
574
575
576 /* A(i,j,cn) or A(i,j)(cn) */
577 struct  CV_EXPORTS _CvMATElemCn_
578 {
579     explicit _CvMATElemCn_( uchar* ptr, int type, int coi );
580     operator double() const;
581     
582     _CvMATElemCn_& operator = ( const _CvMATConstElem_& elem );
583     _CvMATElemCn_& operator = ( const _CvMATElemCn_& elem );
584     _CvMATElemCn_& operator = ( const CvScalar& scalar );
585     _CvMATElemCn_& operator = ( double d );
586     _CvMATElemCn_& operator = ( float f );
587     _CvMATElemCn_& operator = ( int i );
588
589     uchar* ptr;
590     int type;
591 };
592
593
594 /* A(i,j) */
595 struct  CV_EXPORTS _CvMATElem_ : public _CvMATConstElem_
596 {
597     explicit _CvMATElem_( uchar* ptr, int type );
598     _CvMATElemCn_ operator ()( int coi = 0 );
599
600     _CvMATElem_& operator = ( const _CvMATConstElem_& elem );
601     _CvMATElem_& operator = ( const _CvMATElem_& elem );
602     _CvMATElem_& operator = ( const _CvMATElemCn_& elem );
603     _CvMATElem_& operator = ( const CvScalar& val );
604     _CvMATElem_& operator = ( double d );
605     _CvMATElem_& operator = ( float f );
606     _CvMATElem_& operator = ( int i );
607 };
608
609
610 struct  CV_EXPORTS _CvMAT_BASE_OP_
611 {
612     _CvMAT_BASE_OP_() {};
613     virtual operator CvMAT() const = 0;
614
615     _CvMAT_DOT_OP_  mul( const CvMAT& a ) const;
616     _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& a ) const;
617
618     _CvMAT_DOT_OP_  div( const CvMAT& a ) const;
619     _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& a ) const;
620
621     _CvMAT_DOT_OP_  max( const CvMAT& a ) const;
622     _CvMAT_DOT_OP_  min( const CvMAT& a ) const;
623
624     _CvMAT_DOT_OP_  max( double value ) const;
625     _CvMAT_DOT_OP_  min( double value ) const;
626
627     double          max( CvPoint* maxloc = 0 ) const;
628     double          min( CvPoint* minloc = 0 ) const;
629
630     _CvMAT_DOT_OP_  abs() const;
631
632     _CvMAT_INV_     inv( int method = 0 ) const;
633     _CvMAT_T_       t() const;
634
635     CvMAT     row( int row ) const;
636     CvMAT     rowrange( int row1, int row2 ) const;
637     CvMAT     col( int col ) const;
638     CvMAT     colrange( int col1, int col2 ) const;
639     CvMAT     rect( CvRect rect ) const;
640     CvMAT     diag( int diag = 0 ) const;
641     _CvMAT_CVT_     cvt( int newdepth = -1, double scale = 1, double shift = 0 ) const;
642     
643     double          norm( int norm_type = CV_L2 ) const;
644     double          det() const;
645     double          trace() const;
646     CvScalar        sum() const;
647 };
648
649
650 /* (A^t)*alpha */
651 struct  CV_EXPORTS _CvMAT_T_ : public _CvMAT_BASE_OP_
652 {
653     explicit _CvMAT_T_( const CvMAT* a );
654     explicit _CvMAT_T_( const CvMAT* a, double alpha );
655     
656     double det() const;
657     double norm( int normType = CV_L2 ) const;
658     operator CvMAT() const;
659
660     CvMAT  a;
661     double alpha;
662 };
663
664
665 /* inv(A) */
666 struct  CV_EXPORTS _CvMAT_INV_ : public _CvMAT_BASE_OP_
667 {
668     explicit _CvMAT_INV_( const CvMAT* mat, int method );
669     operator CvMAT() const;
670
671     CvMAT a;
672     int method;
673 };
674
675
676 /* (A^ta)*(B^tb)*alpha */
677 struct  CV_EXPORTS _CvMAT_MUL_ : public _CvMAT_BASE_OP_
678 {
679     explicit _CvMAT_MUL_( const CvMAT* a, const CvMAT* b, int t_ab );
680     explicit _CvMAT_MUL_( const CvMAT* a, const CvMAT* b,
681                           double alpha, int t_abc );
682     operator CvMAT() const;
683
684     double alpha;
685     CvMAT* a;
686     CvMAT* b;
687     int t_ab; /* (t_ab & 1) = ta, (t_ab & 2) = tb */
688 };
689
690
691 /* (A^ta)*(B^tb)*alpha + (C^tc)*beta */
692 struct  CV_EXPORTS _CvMAT_MUL_ADD_ : public _CvMAT_BASE_OP_
693 {
694     explicit _CvMAT_MUL_ADD_( const CvMAT* a, const CvMAT* b,
695                               const CvMAT* c, int t_abc );
696     explicit _CvMAT_MUL_ADD_( const CvMAT* a, const CvMAT* b, double alpha,
697                               const CvMAT* c, double beta, int t_abc );
698     operator CvMAT() const;
699
700     double alpha, beta;
701     CvMAT* a;
702     CvMAT* b;
703     CvMAT* c;
704     int t_abc; /* (t_abc & 1) = ta, (t_abc & 2) = tb, (t_abc & 4) = tc */
705 };
706
707
708 /* A + B*beta */
709 struct  CV_EXPORTS _CvMAT_ADD_ : public _CvMAT_BASE_OP_
710 {
711     explicit _CvMAT_ADD_( const CvMAT* a, const CvMAT* b, double beta = 1 );
712     operator CvMAT() const;
713
714     double   norm( int norm_type = CV_L2 ) const;
715     _CvMAT_DOT_OP_ abs() const;
716
717     double beta;
718     CvMAT* a;
719     CvMAT* b;
720 };
721
722
723 /* A*alpha + B*beta + gamma */
724 struct  CV_EXPORTS _CvMAT_ADD_EX_ : public _CvMAT_BASE_OP_
725 {
726     explicit _CvMAT_ADD_EX_( const CvMAT* a, double alpha,
727                              const CvMAT* b, double beta, double gamma = 0 );
728     operator CvMAT() const;
729
730     double alpha, beta, gamma;
731     CvMAT* a;
732     CvMAT* b;
733 };
734
735
736 /* A*alpha */
737 struct  CV_EXPORTS _CvMAT_SCALE_ : public _CvMAT_BASE_OP_
738 {
739     explicit _CvMAT_SCALE_( const CvMAT* a, double alpha );
740     operator CvMAT() const;
741
742     _CvMAT_DOT_OP_  mul( const CvMAT& a ) const;
743     _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& a ) const;
744
745     _CvMAT_DOT_OP_  div( const CvMAT& a ) const;
746     _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& a ) const;
747
748     double alpha;
749     CvMAT* a;
750 };
751
752
753 /* A*alpha + beta */
754 struct  CV_EXPORTS _CvMAT_SCALE_SHIFT_ : public _CvMAT_BASE_OP_
755 {
756     explicit _CvMAT_SCALE_SHIFT_( const CvMAT* a, double alpha, double beta );
757     operator CvMAT() const;
758
759     _CvMAT_DOT_OP_  abs() const;
760
761     double alpha, beta;
762     CvMAT* a;
763 };
764
765
766 /* (A & B), (A | B) or (A ^ B) */
767 struct  CV_EXPORTS _CvMAT_LOGIC_ : public _CvMAT_BASE_OP_
768 {
769     enum Op { AND = 0, OR = 1, XOR = 2 };
770     explicit _CvMAT_LOGIC_( const CvMAT* a, const CvMAT* b, Op op, int flags = 0 );
771     operator CvMAT() const;
772
773     CvMAT* a;
774     CvMAT* b;
775     Op op;
776     int flags;
777 };
778
779
780 /* (A & scalar), (A | scalar) or (A ^ scalar) */
781 struct  CV_EXPORTS _CvMAT_UN_LOGIC_ : public _CvMAT_BASE_OP_
782 {
783     explicit _CvMAT_UN_LOGIC_( const CvMAT* a, double alpha,
784                                _CvMAT_LOGIC_::Op op, int flags = 0 );
785     operator CvMAT() const;
786
787     CvMAT* a;
788     double alpha;
789     _CvMAT_LOGIC_::Op op;
790     int flags;
791 };
792
793
794 /* ~A */
795 struct  CV_EXPORTS _CvMAT_NOT_ : public _CvMAT_BASE_OP_
796 {
797     explicit _CvMAT_NOT_( const CvMAT* a );
798     operator CvMAT() const;
799
800     CvMAT* a;
801 };
802
803
804 /* conversion of data type */
805 struct  CV_EXPORTS _CvMAT_CVT_ : public _CvMAT_BASE_OP_
806 {
807     explicit _CvMAT_CVT_( const CvMAT* a, int newdepth = -1,
808                           double scale = 1, double shift = 0 );
809     operator CvMAT() const;
810
811     CvMAT a;
812     int newdepth;
813     double scale, shift;
814 };
815
816
817 /* conversion of data type */
818 struct  CV_EXPORTS _CvMAT_COPY_
819 {
820     explicit _CvMAT_COPY_( const CvMAT* a );
821     operator CvMAT() const;
822     CvMAT* a;
823 };
824
825
826 /* a.op(b), where op = mul, div, min, max ... */
827 struct  CV_EXPORTS _CvMAT_DOT_OP_ : public _CvMAT_BASE_OP_
828 {
829     explicit _CvMAT_DOT_OP_( const CvMAT* a, const CvMAT* b,
830                              int op, double alpha = 1 );
831     operator CvMAT() const;
832
833     CvMAT a; /* keep the left operand copy */
834     CvMAT* b;
835     double alpha;
836     int op;
837 };
838
839
840 /* A.inv()*B or A.pinv()*B */
841 struct  CV_EXPORTS _CvMAT_SOLVE_ : public _CvMAT_BASE_OP_
842 {
843     explicit _CvMAT_SOLVE_( const CvMAT* a, const CvMAT* b, int method );
844     operator CvMAT() const;
845
846     CvMAT* a;
847     CvMAT* b;
848     int method;
849 };
850
851
852 /* A <=> B */
853 struct  CV_EXPORTS _CvMAT_CMP_ : public _CvMAT_BASE_OP_
854 {
855     explicit _CvMAT_CMP_( const CvMAT* a, const CvMAT* b, int cmp_op );
856     explicit _CvMAT_CMP_( const CvMAT* a, double alpha, int cmp_op );
857     operator CvMAT() const;
858
859     CvMAT* a;
860     CvMAT* b;
861     double alpha;
862     int cmp_op;
863 };
864
865
866 /************************* _CvMATConstElem_ inline methods ******************************/
867
868 inline _CvMATConstElem_::_CvMATConstElem_(const uchar* p, int t) : ptr((uchar*)p), type(t)
869 {}
870
871
872 inline _CvMATConstElem_::operator CvScalar() const
873 {
874     CvScalar scalar;
875     cvRawDataToScalar( ptr, type, &scalar );
876
877     return scalar;
878 }
879
880
881 inline double _CvMATConstElem_::operator ()( int coi ) const
882 {   return CvMAT::get( ptr, type, coi );    }
883
884
885 inline _CvMATElemCn_::_CvMATElemCn_( uchar* p, int t, int coi ) :
886     ptr(p), type(CV_MAT_DEPTH(t))
887 {
888     if( coi )
889     {
890         assert( (unsigned)coi < (unsigned)CV_MAT_CN(t) );
891         ptr += coi * CV_ELEM_SIZE(type);
892     }
893 }
894
895
896 inline _CvMATElemCn_::operator double() const
897 {   return CvMAT::get( ptr, type ); }
898
899
900 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const _CvMATConstElem_& elem )
901 {
902     if( type == elem.type )
903         memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
904     else
905     {
906         assert( CV_MAT_CN(elem.type) == 1 );
907         CvMAT::set( ptr, type, 0, elem(0));
908     }
909
910     return *this;
911 }
912
913
914 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const _CvMATElemCn_& elem )
915 {
916     if( type == elem.type )
917         memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
918     else
919         CvMAT::set( ptr, type, 0, (double)elem );
920     return *this;
921 }
922
923
924 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const CvScalar& scalar )
925 {   
926     CvMAT::set( ptr, type, 0, scalar.val[0] );
927     return *this;
928 }
929
930
931 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( double d )
932 {   
933     CvMAT::set( ptr, type, 0, d );
934     return *this;
935 }
936
937
938 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( float f )
939 {   
940     CvMAT::set( ptr, type, 0, (double)f );
941     return *this;
942 }
943
944
945 inline _CvMATElemCn_& _CvMATElemCn_::operator = ( int i )
946 {   
947     CvMAT::set( ptr, type, 0, i );
948     return *this;
949 }
950
951
952 inline _CvMATElem_::_CvMATElem_( uchar* p, int t ) : _CvMATConstElem_( (const uchar*)p, t )
953 {}
954
955
956 inline _CvMATElemCn_ _CvMATElem_::operator ()( int coi )
957 {   return _CvMATElemCn_( ptr, type, coi ); }
958
959
960 inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATConstElem_& elem )
961 {
962     if( type == elem.type )
963         memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
964     else
965     {
966         assert( CV_MAT_CN( type ^ elem.type ) == 0 );
967         CvScalar sc = (CvScalar)elem;
968         cvScalarToRawData( &sc, ptr, type, 0 );
969     }
970
971     return *this;
972 }
973
974
975 inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATElem_& elem )
976 {
977     *this = (const _CvMATConstElem_&)elem;
978     return *this;
979 }
980
981
982 inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATElemCn_& elem )
983 {
984     if( type == elem.type )
985         memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
986     else
987         CvMAT::set( ptr, type, (double)elem );
988
989     return *this;
990 }
991
992
993 inline _CvMATElem_& _CvMATElem_::operator = ( const CvScalar& scalar )
994 {
995     cvScalarToRawData( &scalar, ptr, type, 0 );
996     return *this;
997 }
998
999
1000 inline _CvMATElem_& _CvMATElem_::operator = ( double d )
1001 {
1002     CvMAT::set( ptr, type, d );
1003     return *this;
1004 }
1005
1006
1007 inline _CvMATElem_& _CvMATElem_::operator = ( float f )
1008 {
1009     CvMAT::set( ptr, type, (double)f );
1010     return *this;
1011 }
1012
1013
1014 inline _CvMATElem_& _CvMATElem_::operator = ( int i )
1015 {
1016     CvMAT::set( ptr, type, i );
1017     return *this;
1018 }
1019
1020
1021 /********************************** CvMAT inline methods ********************************/
1022
1023 inline CvMAT::CvMAT()
1024 {
1025     memset( this, 0, sizeof(*this));
1026 }
1027
1028
1029 inline CvMAT::CvMAT( int rows, int cols, int type, void* data, int step )
1030 {
1031     cvInitMatHeader( this, rows, cols, type, data, step );
1032 }
1033
1034
1035 inline CvMAT::CvMAT( int rows, int type, void* data, int step )
1036 {
1037     cvInitMatHeader( this, rows, 1, type, data, step );
1038 }
1039
1040
1041 inline void CvMAT::create( int rows, int cols, int type )
1042 {
1043     int step = cols*CV_ELEM_SIZE(type), total_size = step*rows;
1044     this->rows = rows;
1045     this->cols = cols;
1046     this->step = rows == 1 ? 0 : step;
1047     this->type = CV_MAT_MAGIC_VAL | (type & CV_MAT_TYPE_MASK) | CV_MAT_CONT_FLAG;
1048     refcount = (int*)cvAlloc((size_t)total_size + 8);
1049     data.ptr = (uchar*)(((size_t)(refcount + 1) + 7) & -8);
1050     *refcount = 1;
1051 }
1052
1053
1054 inline CvMAT::CvMAT( int rows, int cols, int type )
1055 {
1056     create( rows, cols, type );
1057 }
1058
1059
1060 inline CvMAT::CvMAT( int rows, int type )
1061 {
1062     create( rows, 1, type );
1063 }
1064
1065
1066 inline CvMAT::CvMAT( const CvMat& mat )
1067 {
1068     memcpy( this, &mat, sizeof(mat));
1069     if( refcount )
1070         (*refcount)++;
1071 }
1072
1073
1074 inline CvMAT::CvMAT( const CvMAT& mat )
1075 {
1076     memcpy( this, &mat, sizeof(mat));
1077     if( refcount )
1078         (*refcount)++;
1079 }
1080
1081
1082 inline CvMAT::CvMAT( const IplImage& img )
1083 {
1084     cvGetMat( &img, this );
1085 }
1086
1087
1088 inline void CvMAT::release()
1089 {
1090     data.ptr = NULL;
1091     if( refcount != NULL && --*refcount == 0 )
1092         cvFree( (void**)&refcount );
1093     refcount = 0;
1094 }
1095
1096
1097 inline CvMAT::~CvMAT()
1098 {
1099     release();
1100 }
1101
1102
1103 inline CvMAT& CvMAT::operator = ( const CvMAT& mat )
1104 {
1105     if( this != &mat )
1106     {
1107         release();
1108         memcpy( this, &mat, sizeof(mat));
1109         if( refcount )
1110             (*refcount)++;
1111     }
1112     return *this;
1113 }
1114
1115
1116 inline CvMAT& CvMAT::operator = ( const CvMat& mat )
1117 {
1118     *this = (const CvMAT&)mat;
1119     return *this;
1120 }
1121
1122
1123 inline CvMAT& CvMAT::operator = ( const IplImage& img )
1124 {
1125     release();
1126     cvGetMat( &img, this );
1127
1128     return *this;
1129 }
1130
1131
1132 inline CvMAT& CvMAT::operator = ( double fillval )
1133 {
1134     cvFillImage( this, fillval );
1135     return *this;
1136 }
1137
1138
1139 inline CvMAT& CvMAT::operator = ( const CvScalar& fillval )
1140 {
1141     cvSet( this, fillval );
1142     return *this;
1143 }
1144
1145
1146 inline CvMAT& CvMAT::operator += ( const CvMat& mat )
1147 {
1148     cvAdd( this, &mat, this );
1149     return *this;
1150 }
1151
1152
1153 inline CvMAT& CvMAT::operator += ( double val )
1154 {
1155     cvAddS( this, cvScalar(val), this );
1156     return *this;
1157 }
1158
1159
1160 inline CvMAT& CvMAT::operator += ( const CvScalar& val )
1161 {
1162     cvAddS( this, val, this );
1163     return *this;
1164 }
1165
1166
1167 inline CvMAT& CvMAT::operator -= ( const CvMat& mat )
1168 {
1169     cvSub( this, &mat, this );
1170     return *this;
1171 }
1172
1173
1174 inline CvMAT& CvMAT::operator -= ( double val )
1175 {
1176     cvSubS( this, cvScalar(val), this );
1177     return *this;
1178 }
1179
1180
1181 inline CvMAT& CvMAT::operator -= ( const CvScalar& val )
1182 {
1183     cvSubS( this, val, this );
1184     return *this;
1185 }
1186
1187
1188 inline CvMAT& CvMAT::operator *= ( const CvMat& mat )
1189 {
1190     cvMul( this, &mat, this );
1191     return *this;    
1192 }
1193
1194
1195 inline CvMAT& CvMAT::operator *= ( double val )
1196 {
1197     cvScale( this, this, val, 0 );
1198     return *this;
1199 }
1200
1201
1202 inline CvMAT& CvMAT::operator *= ( const CvScalar& val )
1203 {
1204     cvScaleAdd( this, val, 0, this );
1205     return *this;
1206 }
1207
1208
1209 inline CvMAT& CvMAT::operator &= ( const CvMat& mat )
1210 {
1211     cvAnd( this, &mat, this );
1212     return *this;
1213 }
1214
1215
1216 inline CvMAT& CvMAT::operator &= ( double val )
1217 {
1218     cvAndS( this, cvScalarAll(val), this );
1219     return *this;
1220 }
1221
1222
1223 inline CvMAT& CvMAT::operator &= ( const CvScalar& val )
1224 {
1225     cvAndS( this, val, this );
1226     return *this;
1227 }
1228
1229
1230 inline CvMAT& CvMAT::operator |= ( const CvMat& mat )
1231 {
1232     cvOr( this, &mat, this );
1233     return *this;
1234 }
1235
1236
1237 inline CvMAT& CvMAT::operator |= ( double val )
1238 {
1239     cvOrS( this, cvScalarAll(val), this );
1240     return *this;
1241 }
1242
1243
1244 inline CvMAT& CvMAT::operator |= ( const CvScalar& val )
1245 {
1246     cvOrS( this, val, this );
1247     return *this;
1248 }
1249
1250
1251 inline CvMAT& CvMAT::operator ^= ( const CvMat& mat )
1252 {
1253     cvXor( this, &mat, this );
1254     return *this;
1255 }
1256
1257
1258 inline CvMAT& CvMAT::operator ^= ( double val )
1259 {
1260     cvXorS( this, cvScalarAll(val), this );
1261     return *this;
1262 }
1263
1264
1265 inline CvMAT& CvMAT::operator ^= ( const CvScalar& val )
1266 {
1267     cvXorS( this, val, this );
1268     return *this;
1269 }
1270
1271
1272 inline double CvMAT::norm( int normType ) const
1273 {   return cvNorm( this, 0, normType ); }
1274
1275
1276 inline double CvMAT::min( CvPoint* minloc ) const
1277 {   
1278     double t;
1279     cvMinMaxLoc( this, &t, 0, minloc, 0, 0 );
1280     return t;
1281 }
1282
1283 inline double CvMAT::max( CvPoint* maxloc ) const
1284 {   
1285     double t;
1286     cvMinMaxLoc( this, 0, &t, 0, maxloc, 0 );
1287     return t;
1288 }
1289
1290
1291 inline double CvMAT::norm( CvMat& mat, int normType ) const
1292 {   return cvNorm( this, &mat, normType );  }
1293
1294
1295 inline CvScalar CvMAT::sum() const
1296 {   return cvSum( this );   }
1297
1298
1299 inline double CvMAT::det() const
1300 {   return cvDet( this );   }
1301
1302
1303 inline void CvMAT::reshape( int newcn, int newrows )
1304 {   cvReshape( this, this, newcn, newrows );    }
1305
1306
1307 inline void CvMAT::flipX()
1308 {   cvFlip( this, this, 1 );    }
1309
1310
1311 inline void CvMAT::flipY()
1312 {   cvFlip( this, this, 0 );    }
1313
1314
1315 inline void CvMAT::flipXY()
1316 {   cvFlip( this, this, -1 );   }
1317
1318
1319 inline _CvMATElem_ CvMAT::operator ()( int row )
1320 {   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, row, 0 ), type );   }
1321
1322
1323 inline _CvMATConstElem_ CvMAT::operator ()( int row ) const
1324 {   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, row, 0 ), type ); }
1325
1326
1327 inline _CvMATElem_ CvMAT::operator ()( int row, int col )
1328 {   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, row, col ), type ); }
1329
1330
1331 inline _CvMATConstElem_ CvMAT::operator ()( int row, int col ) const
1332 {   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, row, col ), type ); }
1333
1334
1335 inline _CvMATElemCn_ CvMAT::operator()( int row, int col, int coi )
1336 {   return _CvMATElemCn_( CV_MAT_ELEM_PTR( *this, row, col ), type, coi );  }
1337
1338
1339 inline _CvMATElemCn_ CvMAT::operator()( CvPoint pt, int coi )
1340 {   return _CvMATElemCn_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type, coi );  }
1341
1342
1343 inline double CvMAT::operator()( int row, int col, int coi ) const
1344 {   return get( CV_MAT_ELEM_PTR( *this, row, col ), type, coi );    }
1345
1346
1347 inline _CvMATElem_ CvMAT::operator ()( CvPoint pt )
1348 {   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type ); }
1349
1350
1351 inline _CvMATConstElem_ CvMAT::operator ()( CvPoint pt ) const
1352 {   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type ); }
1353
1354
1355 inline double CvMAT::operator()( CvPoint pt, int coi ) const
1356 {   return get( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type, coi );    }
1357
1358
1359 inline void* CvMAT::ptr( int row )
1360 {   return CV_MAT_ELEM_PTR( *this, row, 0 );    }
1361
1362
1363 inline const void* CvMAT::ptr( int row ) const
1364 {   return (const void*)CV_MAT_ELEM_PTR( *this, row, 0 );   }
1365
1366
1367 inline void* CvMAT::ptr( int row, int col )
1368 {   return CV_MAT_ELEM_PTR( *this, row, col );  }
1369
1370
1371 inline const void* CvMAT::ptr( int row, int col ) const
1372 {   return (const void*)CV_MAT_ELEM_PTR( *this, row, col ); }
1373
1374
1375 inline void* CvMAT::ptr( CvPoint pt )
1376 {   return CV_MAT_ELEM_PTR( *this, pt.y, pt.x );    }
1377
1378
1379 inline const void* CvMAT::ptr( CvPoint pt ) const
1380 {   return (const void*)CV_MAT_ELEM_PTR( *this, pt.y, pt.x ); }
1381
1382
1383 inline _CvMAT_INV_ CvMAT::inv( int method ) const
1384 {   return _CvMAT_INV_( this, method ); }
1385
1386
1387 inline _CvMAT_T_ CvMAT::t() const
1388 {   return _CvMAT_T_( this );   }
1389
1390
1391 inline _CvMAT_COPY_ CvMAT::clone() const
1392 {   return _CvMAT_COPY_( this ); }
1393
1394 inline _CvMAT_CVT_ CvMAT::cvt( int newdepth, double scale, double shift ) const
1395 {   return _CvMAT_CVT_( this, newdepth, scale, shift ); }
1396
1397
1398 inline CvMAT::CvMAT( const CvMat& mat, CvRect rect )
1399 {   
1400     type = 0;
1401     cvGetSubArr( &mat, this, rect );
1402     cvIncRefData( this );
1403 }
1404
1405
1406 /* submatrix:
1407      k == 0 - i-th row
1408      k > 0 - i-th column
1409      k < 0 - i-th diagonal */
1410 inline CvMAT::CvMAT( const CvMat& mat, int k, int i )
1411 {
1412     type = 0;
1413     if( k == 0 )
1414         cvGetRow( &mat, this, i );
1415     else if( k > 0 )
1416         cvGetCol( &mat, this, i );
1417     else
1418         cvGetDiag( &mat, this, i );
1419     cvIncRefData( this );
1420 }
1421
1422
1423 inline CvMAT CvMAT::row( int r ) const
1424 {   return CvMAT( *this, 0, r );  }
1425
1426
1427 inline CvMAT CvMAT::col( int c ) const
1428 {   return CvMAT( *this, 1, c );  }
1429
1430
1431 inline CvMAT CvMAT::diag( int d ) const
1432 {   return CvMAT( *this, -1, d );  }
1433
1434
1435 inline CvMAT CvMAT::rect( CvRect rect ) const
1436 {   return CvMAT( *this, rect );    }
1437
1438 inline CvMAT CvMAT::rowrange( int row1, int row2 ) const
1439 {   
1440     assert( 0 <= row1 && row1 < row2 && row2 <= height );
1441     return CvMAT( *this, cvRect( 0, row1, width, row2 - row1 ));
1442 }
1443
1444 inline CvMAT CvMAT::colrange( int col1, int col2 ) const
1445 {   
1446     assert( 0 <= col1 && col1 < col2 && col2 <= width );
1447     return CvMAT( *this, cvRect( col1, 0, col2 - col1, height ));
1448 }
1449
1450 inline _CvMAT_DOT_OP_ CvMAT::mul( const CvMAT& mat ) const
1451 {   return _CvMAT_DOT_OP_( this, &mat, '*' );   }
1452
1453 inline _CvMAT_DOT_OP_ CvMAT::mul( const _CvMAT_SCALE_& mat ) const
1454 {   return _CvMAT_DOT_OP_( this, mat.a, '*', mat.alpha );   }
1455
1456 inline _CvMAT_DOT_OP_ CvMAT::div( const CvMAT& mat ) const
1457 {   return _CvMAT_DOT_OP_( this, &mat, '/' );  }
1458
1459 inline _CvMAT_DOT_OP_ CvMAT::div( const _CvMAT_SCALE_& mat ) const
1460 {   return _CvMAT_DOT_OP_( this, mat.a, '/', 1./mat.alpha );    }
1461
1462 inline _CvMAT_DOT_OP_ CvMAT::min( const CvMAT& mat ) const
1463 {   return _CvMAT_DOT_OP_( this, &mat, 'm' );   }
1464
1465 inline _CvMAT_DOT_OP_ CvMAT::max( const CvMAT& mat ) const
1466 {   return _CvMAT_DOT_OP_( this, &mat, 'M' );   }
1467
1468 inline _CvMAT_DOT_OP_ CvMAT::min( double value ) const
1469 {   return _CvMAT_DOT_OP_( this, 0, 'm', value );   }
1470
1471 inline _CvMAT_DOT_OP_ CvMAT::max( double value ) const
1472 {   return _CvMAT_DOT_OP_( this, 0, 'M', value );   }
1473
1474 inline _CvMAT_DOT_OP_ CvMAT::abs() const
1475 {   return _CvMAT_DOT_OP_( this, 0, 'a', 0 );   }
1476
1477 /****************************************************************************************\
1478 *                               binary operations (+,-,*)                                *
1479 \****************************************************************************************/
1480
1481 /*
1482 * PART I. Scaling, shifting, addition/subtraction operations
1483 */
1484
1485 /* (mat2^t) = (mat1^t) * scalar */
1486 inline _CvMAT_T_ operator * ( const _CvMAT_T_& a, double alpha )
1487 {   return _CvMAT_T_( &a.a, a.alpha*alpha );  }
1488
1489 /* (mat2^t) = scalar * (mat1^t) */
1490 inline _CvMAT_T_ operator * ( double alpha, const _CvMAT_T_& a )
1491 {   return _CvMAT_T_( &a.a, a.alpha*alpha );  }
1492
1493 /* -(mat^t) */
1494 inline _CvMAT_T_ operator - ( const _CvMAT_T_& a )
1495 {   return _CvMAT_T_( &a.a, -a.alpha ); }
1496
1497 /* mat_scaled = mat * scalar */
1498 inline _CvMAT_SCALE_ operator * ( const CvMAT& a, double alpha )
1499 {   return _CvMAT_SCALE_( &a, alpha );  }
1500
1501 /* mat_scaled = scalar * mat */
1502 inline _CvMAT_SCALE_ operator * ( double alpha, const CvMAT& a )
1503 {   return _CvMAT_SCALE_( &a, alpha );  }
1504
1505 /* mat_scaled2 = mat_scaled1 * scalar */
1506 inline _CvMAT_SCALE_ operator * ( const _CvMAT_SCALE_& a, double alpha )
1507 {   return _CvMAT_SCALE_( a.a, a.alpha*alpha ); }
1508
1509 /* mat_scaled2 = scalar * mat_scaled1 */
1510 inline _CvMAT_SCALE_ operator * ( double alpha, const _CvMAT_SCALE_& a )
1511 {   return _CvMAT_SCALE_( a.a, a.alpha*alpha ); }
1512
1513 /* -mat_scaled */
1514 inline _CvMAT_SCALE_ operator - ( const _CvMAT_SCALE_& a )
1515 {   return _CvMAT_SCALE_( a.a, -a.alpha ); }
1516
1517
1518 /* mat_scaled_shifted = mat + scalar */
1519 inline _CvMAT_SCALE_SHIFT_ operator + ( const CvMAT& a, double beta )
1520 {   return _CvMAT_SCALE_SHIFT_( &a, 1, beta );  }
1521
1522 /* mat_scaled_shifted = scalar + mat */
1523 inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const CvMAT& a )
1524 {   return _CvMAT_SCALE_SHIFT_( &a, 1, beta );  }
1525
1526 /* mat_scaled_shifted = mat - scalar */
1527 inline _CvMAT_SCALE_SHIFT_ operator - ( const CvMAT& a, double beta )
1528 {   return _CvMAT_SCALE_SHIFT_( &a, 1, -beta ); }
1529
1530 /* mat_scaled_shifted = scalar - mat */
1531 inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const CvMAT& a )
1532 {   return _CvMAT_SCALE_SHIFT_( &a, -1, beta ); }
1533
1534 /* mat_scaled_shifted = mat_scaled + scalar */
1535 inline _CvMAT_SCALE_SHIFT_ operator + ( const _CvMAT_SCALE_& a, double beta )
1536 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, beta );   }
1537
1538 /* mat_scaled_shifted = scalar + mat_scaled */
1539 inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const _CvMAT_SCALE_& a )
1540 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, beta );   }
1541
1542 /* mat_scaled_shifted = mat_scaled - scalar */
1543 inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_& a, double beta )
1544 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, -beta );  }
1545
1546 /* mat_scaled_shifted = scalar - mat_scaled */
1547 inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const _CvMAT_SCALE_& a )
1548 {   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, beta );  }
1549
1550 /* mat_scaled_shifted2 = mat_scaled_shifted1 + scalar */
1551 inline _CvMAT_SCALE_SHIFT_ operator + ( const _CvMAT_SCALE_SHIFT_& a, double beta )
1552 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta + beta );  }
1553
1554 /* mat_scaled_shifted2 = scalar + mat_scaled_shifted1 */
1555 inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const _CvMAT_SCALE_SHIFT_& a )
1556 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta + beta );  }
1557
1558 /* mat_scaled_shifted2 = mat_scaled_shifted1 - scalar */
1559 inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_SHIFT_& a, double beta )
1560 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta - beta );  }
1561
1562 /* mat_scaled_shifted2 = scalar - mat_scaled_shifted1 */
1563 inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const _CvMAT_SCALE_SHIFT_& a )
1564 {   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, beta - a.beta ); }
1565
1566 /* mat_scaled_shifted2 = mat_scaled_shifted1 * scalar */
1567 inline _CvMAT_SCALE_SHIFT_ operator * ( const _CvMAT_SCALE_SHIFT_& a, double alpha )
1568 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha*alpha, a.beta*alpha ); }
1569
1570 /* mat_scaled_shifted2 = scalar * mat_scaled_shifted1 */
1571 inline _CvMAT_SCALE_SHIFT_ operator * ( double alpha, const _CvMAT_SCALE_SHIFT_& a )
1572 {   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha*alpha, a.beta*alpha ); }
1573
1574 /* -mat_scaled_shifted */
1575 inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_SHIFT_& a )
1576 {   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, -a.beta ); }
1577
1578
1579 /* -mat1 */
1580 inline _CvMAT_SCALE_ operator - ( const CvMAT& a )
1581 {   return _CvMAT_SCALE_( &a, -1 );   }
1582
1583 /* mat_add = mat1 + mat2 */
1584 inline _CvMAT_ADD_ operator + ( const CvMAT& a, const CvMAT& b )
1585 {   return _CvMAT_ADD_( &a, &b );   }
1586
1587 /* mat_add = mat1 - mat2 */
1588 inline _CvMAT_ADD_ operator - ( const CvMAT& a, const CvMAT& b )
1589 {   return _CvMAT_ADD_( &a, &b, -1 );    }
1590
1591 /* mat_add = mat_scaled1 + mat2 */
1592 inline _CvMAT_ADD_ operator + ( const _CvMAT_SCALE_& a, const CvMAT& b )
1593 {   return _CvMAT_ADD_( &b, a.a, a.alpha );  }
1594
1595 /* mat_add = mat1 + mat_scaled2 */
1596 inline _CvMAT_ADD_ operator + ( const CvMAT& b, const _CvMAT_SCALE_& a )
1597 {   return _CvMAT_ADD_( &b, a.a, a.alpha );  }
1598
1599 /* -mat_add */
1600 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_& a )
1601 {   return _CvMAT_ADD_EX_( a.a, -1, a.b, -a.beta ); }
1602
1603 /* mat_add = mat_scaled1 - mat2 */
1604 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& a, const CvMAT& b )
1605 {   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, -1 ); }
1606
1607 /* mat_add = mat1 - mat_scaled2 */
1608 inline _CvMAT_ADD_ operator - ( const CvMAT& b, const _CvMAT_SCALE_& a )
1609 {   return _CvMAT_ADD_( &b, a.a, -a.alpha ); }
1610
1611 /* mat_add = mat_scaled_shifted1 + mat2 */
1612 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1613 {   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, 1, a.beta ); }
1614
1615 /* mat_add = mat1 + mat_scaled_shifted2 */
1616 inline _CvMAT_ADD_EX_ operator + ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1617 {   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, 1, a.beta ); }
1618
1619 /* mat_add = mat_scaled_shifted1 - mat2 */
1620 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1621 {   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, -1, a.beta ); }
1622
1623 /* mat_add = mat1 - mat_scaled_shifted2 */
1624 inline _CvMAT_ADD_EX_ operator - ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1625 {   return _CvMAT_ADD_EX_( a.a, -a.alpha, &b, 1, -a.beta ); }
1626
1627 /* mat_add = mat_scaled_shifted1 + mat_scaled2 */
1628 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1629 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta ); }
1630
1631 /* mat_add = mat_scaled1 + mat_scaled_shifted2 */
1632 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1633 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta ); }
1634
1635 /* mat_add = mat_scaled_shifted1 - mat_scaled2 */
1636 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1637 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha, a.beta ); }
1638
1639 /* mat_add = mat_scaled1 - mat_scaled_shifted2 */
1640 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1641 {   return _CvMAT_ADD_EX_( a.a, -a.alpha, b.a, b.alpha, -a.beta ); }
1642
1643 /* mat_add = mat_scaled1 + mat_scaled2 */
1644 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1645 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha ); }
1646
1647 /* mat_add = mat_scaled1 - mat_scaled2 */
1648 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1649 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha ); }
1650
1651 /* mat_add = mat_scaled_shifted1 + mat_scaled_shifted2 */
1652 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a,
1653                                 const _CvMAT_SCALE_SHIFT_& b )
1654 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta + b.beta ); }
1655
1656 /* mat_add = mat_scaled_shifted1 - mat_scaled_shifted2 */
1657 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a,
1658                                 const _CvMAT_SCALE_SHIFT_& b )
1659 {   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha, a.beta - b.beta ); }
1660
1661 /* mat_add2 = mat_add1 + scalar */
1662 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_ADD_EX_& a, double gamma )
1663 {   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma + gamma ); }
1664
1665 /* mat_add2 = scalar + mat_add1 */
1666 inline _CvMAT_ADD_EX_ operator + ( double gamma, const _CvMAT_ADD_EX_& a )
1667 {   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma + gamma ); }
1668
1669 /* mat_add2 = mat_add1 - scalar */
1670 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_EX_& a, double gamma )
1671 {   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma - gamma ); }
1672
1673 /* mat_add2 = scalar - mat_add1 */
1674 inline _CvMAT_ADD_EX_ operator - ( double gamma, const _CvMAT_ADD_EX_& a )
1675 {   return _CvMAT_ADD_EX_( a.a, -a.alpha, a.b, -a.beta, gamma - a.gamma ); }
1676
1677 /* mat_add2 = mat_add1 * scalar */
1678 inline _CvMAT_ADD_EX_ operator * ( const _CvMAT_ADD_EX_& a, double alpha )
1679 {   return _CvMAT_ADD_EX_( a.a, a.alpha*alpha, a.b, a.beta*alpha, a.gamma*alpha ); }
1680
1681 /* mat_add2 = scalar * mat_add1 */
1682 inline _CvMAT_ADD_EX_ operator * ( double alpha, const _CvMAT_ADD_EX_& a )
1683 {   return _CvMAT_ADD_EX_( a.a, a.alpha*alpha, a.b, a.beta*alpha, a.gamma*alpha ); }
1684
1685 /* mat_add2 = mat_add1 + scalar */
1686 inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_ADD_& a, double gamma )
1687 {   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, gamma ); }
1688
1689 /* mat_add2 = scalar + mat_add1 */
1690 inline _CvMAT_ADD_EX_ operator + ( double gamma, const _CvMAT_ADD_& a )
1691 {   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, gamma ); }
1692
1693 /* mat_add2 = mat_add1 - scalar */
1694 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_& a, double gamma )
1695 {   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, -gamma ); }
1696
1697 /* mat_add2 = scalar - mat_add1 */
1698 inline _CvMAT_ADD_EX_ operator - ( double gamma, const _CvMAT_ADD_& a )
1699 {   return _CvMAT_ADD_EX_( a.a, -1, a.b, -a.beta, gamma ); }
1700
1701 /* mat_add2 = mat_add1 * scalar */
1702 inline _CvMAT_ADD_EX_ operator * ( const _CvMAT_ADD_& a, double alpha )
1703 {   return _CvMAT_ADD_EX_( a.a, alpha, a.b, a.beta*alpha, 0 ); }
1704
1705 /* mat_add2 = scalar * mat_add1 */
1706 inline _CvMAT_ADD_EX_ operator * ( double alpha, const _CvMAT_ADD_& a )
1707 {   return _CvMAT_ADD_EX_( a.a, alpha, a.b, a.beta*alpha, 0 ); }
1708
1709 /* -mat_add_ex */
1710 inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_EX_& a )
1711 {   return _CvMAT_ADD_EX_( a.a, -a.alpha, a.b, -a.beta, -a.gamma ); }
1712
1713
1714 /*
1715 * PART II. Matrix multiplication.
1716 */
1717
1718 /* mmul = mat1 * mat2 */
1719 inline _CvMAT_MUL_ operator * ( const CvMAT& a, const CvMAT& b )
1720 {   return _CvMAT_MUL_( &a, &b, 0 );    }
1721
1722 /* mmul = (mat1^t) * mat2 */
1723 inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const CvMAT& b )
1724 {   return _CvMAT_MUL_( &a.a, &b, a.alpha, 1 );   }
1725
1726 /* mmul = mat1 * (mat2^t) */
1727 inline _CvMAT_MUL_ operator * ( const CvMAT& b, const _CvMAT_T_& a )
1728 {   return _CvMAT_MUL_( &b, &a.a, a.alpha, 2 );  }
1729
1730 /* mmul = (mat1^t) * (mat2^t) */
1731 inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const _CvMAT_T_& b )
1732 {   return _CvMAT_MUL_( &a.a, &b.a, a.alpha*b.alpha, 3 );  }
1733
1734 /* mmul = mat_scaled1 * mat2 */
1735 inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& a, const CvMAT& b )
1736 {   return _CvMAT_MUL_( a.a, &b, a.alpha, 0 ); }
1737
1738 /* mmul = mat1 * mat_scaled2 */
1739 inline _CvMAT_MUL_ operator * ( const CvMAT& b, const _CvMAT_SCALE_& a )
1740 {   return _CvMAT_MUL_( &b, a.a, a.alpha, 0 ); }
1741
1742 /* mmul = (mat1^t) * mat_scaled1 */
1743 inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const _CvMAT_SCALE_& b )
1744 {   return _CvMAT_MUL_( &a.a, b.a, a.alpha*b.alpha, 1 ); }
1745
1746 /* mmul = mat_scaled1 * (mat2^t) */
1747 inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& b, const _CvMAT_T_& a )
1748 {   return _CvMAT_MUL_( b.a, &a.a, a.alpha*b.alpha, 2 ); }
1749
1750 /* mmul = mat_scaled1 * mat_scaled2 */
1751 inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1752 {   return _CvMAT_MUL_( a.a, b.a, a.alpha*b.alpha, 0 ); }
1753
1754 /* mmul2 = mmul1 * scalar */
1755 inline _CvMAT_MUL_ operator * ( const _CvMAT_MUL_& a, double alpha )
1756 {   return _CvMAT_MUL_( a.a, a.b, a.alpha*alpha, a.t_ab ); }
1757
1758 /* mmul2 = scalar * mmul1 */
1759 inline _CvMAT_MUL_ operator * ( double alpha, const _CvMAT_MUL_& a )
1760 {   return _CvMAT_MUL_( a.a, a.b, a.alpha*alpha, a.t_ab ); }
1761
1762 /* -mmul */
1763 inline _CvMAT_MUL_ operator - ( const _CvMAT_MUL_& a )
1764 {   return _CvMAT_MUL_( a.a, a.b, -a.alpha, a.t_ab ); }
1765
1766 /* mmuladd = mmul + mat */
1767 inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const CvMAT& b )
1768 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, 1, a.t_ab ); }
1769
1770 /* !!! Comment this off because of ambigous conversion error !!!
1771    mmuladd = mat + mmul */
1772 /* inline _CvMAT_MUL_ADD_ operator + ( const CvMAT& b, const _CvMAT_MUL_& a )
1773 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, 1, a.t_ab ); }*/
1774
1775 /* mmuladd = mmul - mat */
1776 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const CvMAT& b )
1777 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, -1, a.t_ab ); }
1778
1779 /* !!! Comment this off because of ambigous conversion error !!!
1780    mmuladd = mat - mmul */
1781 /*inline _CvMAT_MUL_ADD_ operator - ( const CvMAT& b, const _CvMAT_MUL_& a )
1782 {   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, &b, 1, a.t_ab ); }*/
1783
1784 /* mmuladd = mmul + mat_scaled */
1785 inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const _CvMAT_SCALE_& b )
1786 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, b.alpha, a.t_ab ); }
1787
1788 /* mmuladd = mat_scaled + mmul */
1789 inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_SCALE_& b, const _CvMAT_MUL_& a )
1790 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, b.alpha, a.t_ab ); }
1791
1792 /* mmuladd = mmul - mat_scaled */
1793 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const _CvMAT_SCALE_& b )
1794 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, -b.alpha, a.t_ab ); }
1795
1796 /* mmuladd = mat_scaled - mmul */
1797 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_SCALE_& b, const _CvMAT_MUL_& a )
1798 {   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, b.a, b.alpha, a.t_ab ); }
1799
1800 /* mmuladd = mmul + (mat^t) */
1801 inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const _CvMAT_T_& b )
1802 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1803
1804 /* mmuladd = (mat^t) + mmul */
1805 inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_T_& b, const _CvMAT_MUL_& a )
1806 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1807
1808 /* mmuladd = mmul - (mat^t) */
1809 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const _CvMAT_T_& b )
1810 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, -b.alpha, a.t_ab + 4 );  }
1811
1812 /* mmuladd = (mat^t) - mmul */
1813 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_T_& b, const _CvMAT_MUL_& a )
1814 {   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1815
1816
1817 /* mmuladd = mat_scaled_shifted * mat */
1818 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1819 {   return _CvMAT_MUL_ADD_( a.a, &b, a.alpha, &b, a.beta, 0 );  }
1820
1821 /* mmuladd = mat * mat_scaled_shifted */
1822 inline _CvMAT_MUL_ADD_ operator * ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1823 {   return _CvMAT_MUL_ADD_( &b, a.a, a.alpha, &b, a.beta, 0 );  }
1824
1825 /* mmuladd = mat_scaled_shifted * mat_scaled */
1826 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1827 {   return _CvMAT_MUL_ADD_( a.a, b.a, a.alpha*b.alpha, b.a, a.beta*b.alpha, 0 );  }
1828
1829 /* mmuladd = mat_scaled * mat_scaled_shifted */
1830 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1831 {   return _CvMAT_MUL_ADD_( b.a, a.a, a.alpha*b.alpha, b.a, a.beta*b.alpha, 0 );  }
1832
1833 /* mmuladd = mat_scaled_shifted * (mat^t) */
1834 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_T_& b )
1835 {   return _CvMAT_MUL_ADD_( a.a, &b.a, a.alpha*b.alpha, &b.a, a.beta*b.alpha, 6 );  }
1836
1837 /* mmuladd = (mat^t) * mat_scaled_shifted */
1838 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_T_& b, const _CvMAT_SCALE_SHIFT_& a )
1839 {   return _CvMAT_MUL_ADD_( &b.a, a.a, a.alpha*b.alpha, &b.a, a.beta*b.alpha, 5 );  }
1840
1841 /* mmuladd2 = mmuladd1 * scalar */
1842 inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_MUL_ADD_& a, double alpha )
1843 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha*alpha, a.c, a.beta*alpha, a.t_abc ); }
1844
1845 /* mmuladd2 = scalar * mmuladd1 */
1846 inline _CvMAT_MUL_ADD_ operator * ( double alpha, const _CvMAT_MUL_ADD_& a )
1847 {   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha*alpha, a.c, a.beta*alpha, a.t_abc ); }
1848
1849 /* -mmuladd */
1850 inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_ADD_& a )
1851 {   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, a.c, -a.beta, a.t_abc ); }
1852
1853 /* inv(a)*b, i.e. solve a*x = b */
1854 inline _CvMAT_SOLVE_ operator * ( const _CvMAT_INV_& a, const CvMAT& b )
1855 {   return _CvMAT_SOLVE_( &a.a, &b, a.method );    }
1856
1857
1858 /*
1859 * PART III. Logical operations
1860 */
1861 inline _CvMAT_NOT_ operator ~ ( const CvMAT& a )
1862 {   return _CvMAT_NOT_(&a); }
1863
1864 inline _CvMAT_LOGIC_ operator & ( const CvMAT& a, const CvMAT& b )
1865 {   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::AND, 0 ); }
1866
1867 inline _CvMAT_LOGIC_ operator & ( const _CvMAT_NOT_& a, const CvMAT& b )
1868 {   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::AND, 1 ); }
1869
1870 inline _CvMAT_LOGIC_ operator & ( const CvMAT& a, const _CvMAT_NOT_& b )
1871 {   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::AND, 2 ); }
1872
1873 inline _CvMAT_LOGIC_ operator & ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1874 {   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::AND, 3 ); }
1875
1876
1877 inline _CvMAT_LOGIC_ operator | ( const CvMAT& a, const CvMAT& b )
1878 {   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::OR, 0 ); }
1879
1880 inline _CvMAT_LOGIC_ operator | ( const _CvMAT_NOT_& a, const CvMAT& b )
1881 {   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::OR, 1 ); }
1882
1883 inline _CvMAT_LOGIC_ operator | ( const CvMAT& a, const _CvMAT_NOT_& b )
1884 {   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::OR, 2 ); }
1885
1886 inline _CvMAT_LOGIC_ operator | ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1887 {   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::OR, 3 ); }
1888
1889
1890 inline _CvMAT_LOGIC_ operator ^ ( const CvMAT& a, const CvMAT& b )
1891 {   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::XOR, 0 ); }
1892
1893 inline _CvMAT_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, const CvMAT& b )
1894 {   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::XOR, 1 ); }
1895
1896 inline _CvMAT_LOGIC_ operator ^ ( const CvMAT& a, const _CvMAT_NOT_& b )
1897 {   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::XOR, 2 ); }
1898
1899 inline _CvMAT_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1900 {   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::XOR, 3 ); }
1901
1902
1903 inline _CvMAT_UN_LOGIC_ operator & ( const CvMAT& a, double alpha )
1904 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::AND, 0 ); }
1905
1906 inline _CvMAT_UN_LOGIC_ operator & ( double alpha, const CvMAT& a )
1907 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::AND, 0 ); }
1908
1909 inline _CvMAT_UN_LOGIC_ operator & ( const _CvMAT_NOT_& a, double alpha )
1910 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::AND, 1 ); }
1911
1912 inline _CvMAT_UN_LOGIC_ operator & ( double alpha, const _CvMAT_NOT_& a )
1913 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::AND, 1 ); }
1914
1915
1916 inline _CvMAT_UN_LOGIC_ operator | ( const CvMAT& a, double alpha )
1917 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::OR, 0 ); }
1918
1919 inline _CvMAT_UN_LOGIC_ operator | ( double alpha, const CvMAT& a )
1920 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::OR, 0 ); }
1921
1922 inline _CvMAT_UN_LOGIC_ operator | ( const _CvMAT_NOT_& a, double alpha )
1923 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::OR, 1 ); }
1924
1925 inline _CvMAT_UN_LOGIC_ operator | ( double alpha, const _CvMAT_NOT_& a )
1926 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::OR, 1 ); }
1927
1928
1929 inline _CvMAT_UN_LOGIC_ operator ^ ( const CvMAT& a, double alpha )
1930 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::XOR, 0 ); }
1931
1932 inline _CvMAT_UN_LOGIC_ operator ^ ( double alpha, const CvMAT& a )
1933 {   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::XOR, 0 ); }
1934
1935 inline _CvMAT_UN_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, double alpha )
1936 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::XOR, 1 ); }
1937
1938 inline _CvMAT_UN_LOGIC_ operator ^ ( double alpha, const _CvMAT_NOT_& a )
1939 {   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::XOR, 1 ); }
1940
1941
1942 /*
1943 * PART IV. Comparison operations
1944 */
1945 inline _CvMAT_CMP_ operator > ( const CvMAT& a, const CvMAT& b )
1946 {   return _CvMAT_CMP_( &a, &b, CV_CMP_GT ); }
1947
1948 inline _CvMAT_CMP_ operator >= ( const CvMAT& a, const CvMAT& b )
1949 {   return _CvMAT_CMP_( &a, &b, CV_CMP_GE ); }
1950
1951 inline _CvMAT_CMP_ operator < ( const CvMAT& a, const CvMAT& b )
1952 {   return _CvMAT_CMP_( &a, &b, CV_CMP_LT ); }
1953
1954 inline _CvMAT_CMP_ operator <= ( const CvMAT& a, const CvMAT& b )
1955 {   return _CvMAT_CMP_( &a, &b, CV_CMP_LE ); }
1956
1957 inline _CvMAT_CMP_ operator == ( const CvMAT& a, const CvMAT& b )
1958 {   return _CvMAT_CMP_( &a, &b, CV_CMP_EQ ); }
1959
1960 inline _CvMAT_CMP_ operator != ( const CvMAT& a, const CvMAT& b )
1961 {   return _CvMAT_CMP_( &a, &b, CV_CMP_NE ); }
1962
1963
1964 inline _CvMAT_CMP_ operator > ( const CvMAT& a, double alpha )
1965 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_GT ); }
1966
1967 inline _CvMAT_CMP_ operator > ( double alpha, const CvMAT& a )
1968 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_LT ); }
1969
1970 inline _CvMAT_CMP_ operator >= ( const CvMAT& a, double alpha )
1971 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_GE ); }
1972
1973 inline _CvMAT_CMP_ operator >= ( double alpha, const CvMAT& a )
1974 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_LE ); }
1975
1976 inline _CvMAT_CMP_ operator < ( const CvMAT& a, double alpha )
1977 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_LT ); }
1978
1979 inline _CvMAT_CMP_ operator < ( double alpha, const CvMAT& a )
1980 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_GT ); }
1981
1982 inline _CvMAT_CMP_ operator <= ( const CvMAT& a, double alpha )
1983 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_LE ); }
1984
1985 inline _CvMAT_CMP_ operator <= ( double alpha, const CvMAT& a )
1986 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_GE ); }
1987
1988 inline _CvMAT_CMP_ operator == ( const CvMAT& a, double alpha )
1989 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_EQ ); }
1990
1991 inline _CvMAT_CMP_ operator == ( double alpha, const CvMAT& a )
1992 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_EQ ); }
1993
1994 inline _CvMAT_CMP_ operator != ( const CvMAT& a, double alpha )
1995 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_NE ); }
1996
1997 inline _CvMAT_CMP_ operator != ( double alpha, const CvMAT& a )
1998 {   return _CvMAT_CMP_( &a, alpha, CV_CMP_NE ); }
1999
2000
2001 /*
2002 * PART V. Speedup for some augmented assignments to CvMAT
2003 */
2004
2005 inline CvMAT& CvMAT::operator += ( const _CvMAT_SCALE_& scale_mat )
2006 {   return (*this = *this + scale_mat); }
2007
2008 inline CvMAT& CvMAT::operator += ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2009 {   return (*this = *this + scale_mat); }
2010
2011 inline CvMAT& CvMAT::operator += ( const _CvMAT_MUL_& mmul )
2012 {   return (*this = mmul + *this);  }
2013
2014 inline CvMAT& CvMAT::operator -= ( const _CvMAT_SCALE_& scale_mat )
2015 {   return (*this = *this - scale_mat);  }
2016
2017 inline CvMAT& CvMAT::operator -= ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2018 {   return (*this = *this - scale_mat);  }
2019
2020 inline CvMAT& CvMAT::operator -= ( const _CvMAT_MUL_& mmul )
2021 {   return (*this = -mmul + *this);  }
2022
2023 inline CvMAT& CvMAT::operator *= ( const _CvMAT_SCALE_& scale_mat )
2024 {   return (*this = *this * scale_mat);  }
2025
2026 inline CvMAT& CvMAT::operator *= ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2027 {   return (*this = *this * scale_mat);  }
2028
2029 /****************************************************************************************\
2030 *                        misc. operations on temporary matrices (+,-,*)                  *
2031 \****************************************************************************************/
2032
2033 /*
2034 * the base proxy class implementation
2035 */
2036
2037 /* a.*b */
2038 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::mul( const CvMAT& a ) const
2039 {   return ((CvMAT)*this).mul(a);  }
2040
2041 /* a.*b*alpha */
2042 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::mul( const _CvMAT_SCALE_& a ) const
2043 {   return ((CvMAT)*this).mul(a);  }
2044
2045 /* a./b */
2046 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::div( const CvMAT& a ) const
2047 {   return ((CvMAT)*this).div(a);  }
2048
2049 /* a./(b*alpha) */
2050 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::div( const _CvMAT_SCALE_& a ) const
2051 {   return ((CvMAT)*this).div(a);  }
2052
2053 /* a.max(b) */
2054 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::min( const CvMAT& a ) const
2055 {   return ((CvMAT)*this).min(a);  }
2056
2057 /* a.min(b) */
2058 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::max( const CvMAT& a ) const
2059 {   return ((CvMAT)*this).max(a);  }
2060
2061 /* a.max(alpha) */
2062 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::min( double alpha ) const
2063 {   return ((CvMAT)*this).min(alpha);  }
2064
2065 /* a.min(alpha) */
2066 inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::max( double alpha ) const
2067 {   return ((CvMAT)*this).max(alpha);  }
2068
2069
2070 inline _CvMAT_INV_  _CvMAT_BASE_OP_::inv( int method ) const
2071 {   return ((CvMAT)*this).inv(method);  }
2072
2073 inline _CvMAT_T_  _CvMAT_BASE_OP_::t() const
2074 {   return ((CvMAT)*this).t();  }
2075
2076 inline _CvMAT_CVT_ _CvMAT_BASE_OP_::cvt( int newdepth, double scale, double shift ) const
2077 {   return ((CvMAT)*this).cvt( newdepth, scale, shift ); }
2078
2079 inline CvMAT  _CvMAT_BASE_OP_::row( int r ) const
2080 {   return CvMAT((CvMAT)*this, 0, r ); }
2081
2082 inline CvMAT  _CvMAT_BASE_OP_::rowrange( int row1, int row2 ) const
2083 {   
2084     CvMAT m = (CvMAT)*this;
2085     assert( 0 <= row1 && row1 < row2 && row2 <= m.height );
2086     return CvMAT( m, cvRect( 0, row1, m.width, row2 - row1 ));
2087 }
2088
2089 inline CvMAT  _CvMAT_BASE_OP_::col( int c ) const
2090 {   return CvMAT( (CvMAT)*this, 1, c ); }
2091
2092 inline CvMAT  _CvMAT_BASE_OP_::colrange( int col1, int col2 ) const
2093 {   
2094     CvMAT m = (CvMAT)*this;
2095     assert( 0 <= col1 && col1 < col2 && col2 <= m.width );
2096     return CvMAT( m, cvRect( col1, 0, col2 - col1, m.height ));
2097 }
2098
2099 inline CvMAT  _CvMAT_BASE_OP_::rect( CvRect r ) const
2100 {   return CvMAT( (CvMAT)*this, r ); }
2101
2102 inline CvMAT  _CvMAT_BASE_OP_::diag( int d ) const
2103 {   return CvMAT( (CvMAT)*this, -1, d ); }
2104
2105 inline double _CvMAT_BASE_OP_::det() const
2106 {   return ((CvMAT)*this).det(); }
2107
2108 inline double _CvMAT_BASE_OP_::norm( int norm_type ) const
2109 {   return ((CvMAT)*this).norm( norm_type ); }
2110
2111 inline CvScalar _CvMAT_BASE_OP_::sum() const
2112 {   return ((CvMAT)*this).sum(); }
2113
2114 inline double _CvMAT_BASE_OP_::min( CvPoint* minloc ) const
2115 {   return ((CvMAT)*this).min( minloc ); }
2116
2117 inline double _CvMAT_BASE_OP_::max( CvPoint* maxloc ) const
2118 {   return ((CvMAT)*this).max( maxloc ); }
2119
2120
2121 /****************************************************************************************/
2122 /*                              proxy classes implementation.                           */
2123 /*                              part I. constructors                                    */
2124 /****************************************************************************************/
2125
2126 /* constructors */
2127 inline _CvMAT_COPY_::_CvMAT_COPY_( const CvMAT* _a ) : a((CvMAT*)_a)  {}
2128
2129 inline _CvMAT_CVT_::_CvMAT_CVT_( const CvMAT* _a, int _newdepth,
2130                                  double _scale, double _shift ) :
2131     a(*(CvMAT*)_a), newdepth(_newdepth), scale(_scale), shift(_shift)  {}
2132
2133 inline _CvMAT_T_::_CvMAT_T_( const CvMAT* _a ) : a(*(CvMAT*)_a), alpha(1)  {}
2134
2135
2136 inline _CvMAT_T_::_CvMAT_T_( const CvMAT* _a, double _alpha ) :
2137     a(*(CvMAT*)_a), alpha(_alpha)  {}
2138
2139
2140 inline _CvMAT_INV_::_CvMAT_INV_( const CvMAT* _a, int _method ) :
2141     a(*(CvMAT*)_a), method(_method) {}
2142
2143
2144 inline _CvMAT_MUL_::_CvMAT_MUL_( const CvMAT* _a, const CvMAT* _b, int _t_ab ) :
2145     a((CvMAT*)_a), b((CvMAT*)_b), alpha(1), t_ab(_t_ab) {}
2146
2147
2148 inline _CvMAT_MUL_::_CvMAT_MUL_( const CvMAT* _a, const CvMAT* _b,
2149                                  double _alpha, int _t_ab ) :
2150     a((CvMAT*)_a), b((CvMAT*)_b), alpha(_alpha), t_ab(_t_ab) {}
2151
2152
2153 inline _CvMAT_MUL_ADD_::_CvMAT_MUL_ADD_( const CvMAT* _a, const CvMAT* _b,
2154                                          const CvMAT* _c, int _t_abc ) :
2155     a((CvMAT*)_a), b((CvMAT*)_b), c((CvMAT*)_c), t_abc(_t_abc) {}
2156
2157
2158 inline _CvMAT_MUL_ADD_::_CvMAT_MUL_ADD_( const CvMAT* _a, const CvMAT* _b, double _alpha,
2159                                          const CvMAT* _c, double _beta, int _t_abc ) :
2160     a((CvMAT*)_a), b((CvMAT*)_b), alpha(_alpha),
2161     c((CvMAT*)_c), beta(_beta), t_abc(_t_abc) {}
2162
2163
2164 inline _CvMAT_ADD_::_CvMAT_ADD_( const CvMAT* _a, const CvMAT* _b, double _beta ) :
2165     a((CvMAT*)_a), b((CvMAT*)_b), beta(_beta) {}
2166
2167
2168 inline _CvMAT_ADD_EX_::_CvMAT_ADD_EX_( const CvMAT* _a, double _alpha,
2169                                        const CvMAT* _b, double _beta, double _gamma ) :
2170     a((CvMAT*)_a), alpha(_alpha), b((CvMAT*)_b), beta(_beta), gamma(_gamma) {}
2171
2172
2173 inline _CvMAT_SCALE_::_CvMAT_SCALE_( const CvMAT* _a, double _alpha ) :
2174     a((CvMAT*)_a), alpha(_alpha) {}
2175
2176
2177 inline _CvMAT_SCALE_SHIFT_::_CvMAT_SCALE_SHIFT_( const CvMAT* _a,
2178                                                  double _alpha, double _beta ) :
2179     a((CvMAT*)_a), alpha(_alpha), beta(_beta) {}
2180
2181
2182 inline _CvMAT_LOGIC_::_CvMAT_LOGIC_( const CvMAT* _a, const CvMAT* _b,
2183                                             _CvMAT_LOGIC_::Op _op, int _flags ) :
2184     a((CvMAT*)_a), b((CvMAT*)_b), op(_op), flags(_flags) {}
2185
2186
2187 inline _CvMAT_UN_LOGIC_::_CvMAT_UN_LOGIC_( const CvMAT* _a, double _alpha,
2188                                            _CvMAT_LOGIC_::Op _op, int _flags ) :
2189     a((CvMAT*)_a), alpha(_alpha), op(_op), flags(_flags) {}
2190
2191
2192 inline _CvMAT_NOT_::_CvMAT_NOT_( const CvMAT* _a ) :
2193     a((CvMAT*)_a) {}
2194
2195
2196 inline _CvMAT_DOT_OP_::_CvMAT_DOT_OP_( const CvMAT* _a, const CvMAT* _b,
2197                                        int _op, double _alpha ) :
2198     a(*_a), b((CvMAT*)_b), op(_op), alpha(_alpha) {}
2199
2200
2201 inline _CvMAT_SOLVE_::_CvMAT_SOLVE_( const CvMAT* _a, const CvMAT* _b, int _method ) :
2202     a((CvMAT*)_a), b((CvMAT*)_b), method(_method) {}
2203
2204 inline _CvMAT_CMP_::_CvMAT_CMP_( const CvMAT* _a, const CvMAT* _b, int _cmp_op ) :
2205     a((CvMAT*)_a), b((CvMAT*)_b), alpha(0), cmp_op(_cmp_op) {}
2206
2207 inline _CvMAT_CMP_::_CvMAT_CMP_( const CvMAT* _a, double _alpha, int _cmp_op ) :
2208     a((CvMAT*)_a), b(0), alpha(_alpha), cmp_op(_cmp_op) {}
2209
2210 /****************************************************************************************/
2211 /*                              proxy classes implementation.                           */
2212 /*                              part II. conversion to CvMAT                      */
2213 /****************************************************************************************/
2214
2215 inline _CvMAT_T_::operator CvMAT() const
2216 {   return CvMAT( *this );    }
2217
2218 inline _CvMAT_INV_::operator CvMAT() const
2219 {   return CvMAT( *this );    }
2220
2221 inline _CvMAT_MUL_::operator CvMAT() const
2222 {   return CvMAT( *this );    }
2223
2224 inline _CvMAT_SCALE_::operator CvMAT() const
2225 {   return CvMAT( *this );    }
2226
2227 inline _CvMAT_SCALE_SHIFT_::operator CvMAT() const
2228 {   return CvMAT( *this );    }
2229
2230 inline _CvMAT_ADD_::operator CvMAT() const
2231 {   return CvMAT( *this );    }
2232
2233 inline _CvMAT_ADD_EX_::operator CvMAT() const
2234 {   return CvMAT( *this );    }
2235
2236 inline _CvMAT_MUL_ADD_::operator CvMAT() const
2237 {   return CvMAT( *this );    }
2238
2239 inline _CvMAT_LOGIC_::operator CvMAT() const
2240 {   return CvMAT( *this );    }
2241
2242 inline _CvMAT_UN_LOGIC_::operator CvMAT() const
2243 {   return CvMAT( *this );    }
2244
2245 inline _CvMAT_NOT_::operator CvMAT() const
2246 {   return CvMAT( *this );    }
2247
2248 inline _CvMAT_DOT_OP_::operator CvMAT() const
2249 {   return CvMAT( *this );    }
2250
2251 inline _CvMAT_SOLVE_::operator CvMAT() const
2252 {   return CvMAT( *this );    }
2253
2254 inline _CvMAT_CMP_::operator CvMAT() const
2255 {   return CvMAT( *this );    }
2256
2257 inline _CvMAT_CVT_::operator CvMAT() const
2258 {   return CvMAT(*this);   }
2259
2260 inline _CvMAT_COPY_::operator CvMAT() const
2261 {   return *a;   }
2262
2263 /****************************************************************************************/
2264 /*                              proxy classes implementation.                           */
2265 /*                              part III. custom overrided methods                      */
2266 /****************************************************************************************/
2267
2268 inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::mul( const CvMAT& mat ) const
2269 {   return _CvMAT_DOT_OP_( a, &mat, '*', alpha );   }
2270
2271 inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::mul( const _CvMAT_SCALE_& mat ) const
2272 {   return _CvMAT_DOT_OP_( a, mat.a, '*', alpha*mat.alpha );   }
2273
2274 inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::div( const CvMAT& mat ) const
2275 {   return _CvMAT_DOT_OP_( a, &mat, '/', alpha );   }
2276
2277 inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::div( const _CvMAT_SCALE_& mat ) const
2278 {   return _CvMAT_DOT_OP_( a, mat.a, '/', alpha/mat.alpha );   }
2279
2280 inline _CvMAT_DOT_OP_ operator * ( const _CvMAT_DOT_OP_& dot_op, double alpha )
2281 {   return _CvMAT_DOT_OP_( &dot_op.a, dot_op.b, dot_op.op, dot_op.alpha * alpha );  }
2282
2283 inline _CvMAT_DOT_OP_ operator * ( double alpha, const _CvMAT_DOT_OP_& dot_op )
2284 {   return _CvMAT_DOT_OP_( &dot_op.a, dot_op.b, dot_op.op, dot_op.alpha * alpha );  }
2285
2286 inline _CvMAT_DOT_OP_ operator / ( double alpha, const CvMAT& mat )
2287 {   return _CvMAT_DOT_OP_( &mat, 0, '/', alpha );  }
2288
2289 inline _CvMAT_DOT_OP_ operator / ( double alpha, const _CvMAT_SCALE_& mat )
2290 {   return _CvMAT_DOT_OP_( mat.a, 0, '/', alpha/mat.alpha );  }
2291
2292
2293 inline double _CvMAT_T_::det() const
2294 {   return a.det();     }
2295
2296 inline double _CvMAT_T_::norm( int norm_type ) const
2297 {   return a.norm( norm_type );    }
2298
2299 inline double _CvMAT_ADD_::norm( int norm_type ) const
2300 {
2301     if( beta == -1 )
2302         return cvNorm( a, b, norm_type );
2303     else
2304         return ((CvMAT)*this).norm( norm_type );
2305 }
2306
2307 inline _CvMAT_DOT_OP_ _CvMAT_ADD_::abs() const
2308 {
2309     if( beta == -1 )
2310         return _CvMAT_DOT_OP_( a, b, 'a', 0 );
2311     else
2312         return ((CvMAT)*this).abs();
2313 }
2314
2315 inline _CvMAT_DOT_OP_ _CvMAT_SCALE_SHIFT_::abs() const
2316 {
2317     if( alpha == 1 )
2318         return _CvMAT_DOT_OP_( a, 0, 'a', -beta );
2319     else
2320         return ((CvMAT)*this).abs();
2321 }
2322
2323 #endif /* __cplusplus */
2324
2325 #endif /*_CVMAT_HPP_*/
2326