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#include "_cvaux.h"
43
44// temporarily remove it from build
45#if 0 && ((_MSC_VER>=1200) || defined __BORLANDC__)
46
47double CvMAT::get( const uchar* ptr, int type, int coi )
48{
49    double t = 0;
50    assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
51
52    switch( CV_MAT_DEPTH(type) )
53    {
54    case CV_8U:
55        t = ((uchar*)ptr)[coi];
56        break;
57    case CV_8S:
58        t = ((char*)ptr)[coi];
59        break;
60    case CV_16S:
61        t = ((short*)ptr)[coi];
62        break;
63    case CV_32S:
64        t = ((int*)ptr)[coi];
65        break;
66    case CV_32F:
67        t = ((float*)ptr)[coi];
68        break;
69    case CV_64F:
70        t = ((double*)ptr)[coi];
71        break;
72    }
73
74    return t;
75}
76
77void CvMAT::set( uchar* ptr, int type, int coi, double d )
78{
79    int i;
80    assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
81
82    switch( CV_MAT_DEPTH(type))
83    {
84    case CV_8U:
85        i = cvRound(d);
86        ((uchar*)ptr)[coi] = CV_CAST_8U(i);
87        break;
88    case CV_8S:
89        i = cvRound(d);
90        ((char*)ptr)[coi] = CV_CAST_8S(i);
91        break;
92    case CV_16S:
93        i = cvRound(d);
94        ((short*)ptr)[coi] = CV_CAST_16S(i);
95        break;
96    case CV_32S:
97        i = cvRound(d);
98        ((int*)ptr)[coi] = CV_CAST_32S(i);
99        break;
100    case CV_32F:
101        ((float*)ptr)[coi] = (float)d;
102        break;
103    case CV_64F:
104        ((double*)ptr)[coi] = d;
105        break;
106    }
107}
108
109
110void CvMAT::set( uchar* ptr, int type, int coi, int i )
111{
112    assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
113
114    switch( CV_MAT_DEPTH(type))
115    {
116    case CV_8U:
117        ((uchar*)ptr)[coi] = CV_CAST_8U(i);
118        break;
119    case CV_8S:
120        ((char*)ptr)[coi] = CV_CAST_8S(i);
121        break;
122    case CV_16S:
123        ((short*)ptr)[coi] = CV_CAST_16S(i);
124        break;
125    case CV_32S:
126        ((int*)ptr)[coi] = i;
127        break;
128    case CV_32F:
129        ((float*)ptr)[coi] = (float)i;
130        break;
131    case CV_64F:
132        ((double*)ptr)[coi] = (double)i;
133        break;
134    }
135}
136
137
138void CvMAT::set( uchar* ptr, int type, double d )
139{
140    int i, cn = CV_MAT_CN(type);
141
142    switch( CV_MAT_DEPTH(type))
143    {
144    case CV_8U:
145        i = cvRound(d);
146        ((uchar*)ptr)[0] = CV_CAST_8U(i);
147        i = cn;
148        while( --i ) ((uchar*)ptr)[i] = 0;
149        break;
150    case CV_8S:
151        i = cvRound(d);
152        ((char*)ptr)[0] = CV_CAST_8S(i);
153        i = cn;
154        while( --i ) ((char*)ptr)[i] = 0;
155        break;
156    case CV_16S:
157        i = cvRound(d);
158        ((short*)ptr)[0] = CV_CAST_16S(i);
159        i = cn;
160        while( --i ) ((short*)ptr)[i] = 0;
161        break;
162    case CV_32S:
163        i = cvRound(d);
164        ((int*)ptr)[0] = i;
165        i = cn;
166        while( --i ) ((int*)ptr)[i] = 0;
167        break;
168    case CV_32F:
169        ((float*)ptr)[0] = (float)d;
170        i = cn;
171        while( --i ) ((float*)ptr)[i] = 0;
172        break;
173    case CV_64F:
174        ((double*)ptr)[0] = d;
175        i = cn;
176        while( --i ) ((double*)ptr)[i] = 0;
177        break;
178    }
179}
180
181
182void CvMAT::set( uchar* ptr, int type, int i )
183{
184    int cn = CV_MAT_CN(type);
185
186    switch( CV_MAT_DEPTH(type))
187    {
188    case CV_8U:
189        ((uchar*)ptr)[0] = CV_CAST_8U(i);
190        i = cn;
191        while( --i ) ((uchar*)ptr)[i] = 0;
192        break;
193    case CV_8S:
194        ((char*)ptr)[0] = CV_CAST_8S(i);
195        i = cn;
196        while( --i ) ((char*)ptr)[i] = 0;
197        break;
198    case CV_16S:
199        ((short*)ptr)[0] = CV_CAST_16S(i);
200        i = cn;
201        while( --i ) ((short*)ptr)[i] = 0;
202        break;
203    case CV_32S:
204        ((int*)ptr)[0] = i;
205        i = cn;
206        while( --i ) ((int*)ptr)[i] = 0;
207        break;
208    case CV_32F:
209        ((float*)ptr)[0] = (float)i;
210        i = cn;
211        while( --i ) ((float*)ptr)[i] = 0;
212        break;
213    case CV_64F:
214        ((double*)ptr)[0] = (double)i;
215        i = cn;
216        while( --i ) ((double*)ptr)[i] = 0;
217        break;
218    }
219}
220
221
222CvMAT::CvMAT( const _CvMAT_T_& mat_t )
223{
224    data.ptr = 0;
225    type = 0;
226    refcount = 0;
227    *this = mat_t;
228}
229
230
231CvMAT::CvMAT( const _CvMAT_ADD_& mat_add )
232{
233    data.ptr = 0;
234    type = 0;
235    refcount = 0;
236    *this = mat_add;
237}
238
239
240CvMAT::CvMAT( const _CvMAT_ADD_EX_& mat_add )
241{
242    data.ptr = 0;
243    type = 0;
244    refcount = 0;
245    *this = mat_add;
246}
247
248
249CvMAT::CvMAT( const _CvMAT_SCALE_& scale_mat )
250{
251    data.ptr = 0;
252    type = 0;
253    refcount = 0;
254    *this = scale_mat;
255}
256
257
258CvMAT::CvMAT( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
259{
260    data.ptr = 0;
261    type = 0;
262    refcount = 0;
263    *this = scale_shift_mat;
264}
265
266
267CvMAT::CvMAT( const _CvMAT_MUL_& mmul )
268{
269    data.ptr = 0;
270    type = 0;
271    refcount = 0;
272    *this = mmul;
273}
274
275
276CvMAT::CvMAT( const _CvMAT_MUL_ADD_& mmuladd )
277{
278    data.ptr = 0;
279    type = 0;
280    refcount = 0;
281    *this = mmuladd;
282}
283
284
285CvMAT::CvMAT( const _CvMAT_INV_& inv_mat )
286{
287    data.ptr = 0;
288    type = 0;
289    refcount = 0;
290    *this = inv_mat;
291}
292
293
294CvMAT::CvMAT( const _CvMAT_NOT_& not_mat )
295{
296    type = 0;
297    data.ptr = 0;
298    refcount = 0;
299    *this = not_mat;
300}
301
302
303CvMAT::CvMAT( const _CvMAT_UN_LOGIC_& mat_logic )
304{
305    type = 0;
306    data.ptr = 0;
307    refcount = 0;
308    *this = mat_logic;
309}
310
311
312CvMAT::CvMAT( const _CvMAT_LOGIC_& mat_logic )
313{
314    type = 0;
315    data.ptr = 0;
316    refcount = 0;
317    *this = mat_logic;
318}
319
320
321CvMAT::CvMAT( const _CvMAT_COPY_& mat_copy )
322{
323    CvMAT* src = (CvMAT*)mat_copy.a;
324    create( src->height, src->width, src->type );
325    cvCopy( src, this );
326}
327
328
329CvMAT::CvMAT( const _CvMAT_CVT_& mat_cvt )
330{
331    type = 0;
332    data.ptr = 0;
333    refcount = 0;
334    *this = mat_cvt;
335}
336
337
338CvMAT::CvMAT( const _CvMAT_DOT_OP_& dot_op )
339{
340    data.ptr = 0;
341    type = 0;
342    refcount = 0;
343    *this = dot_op;
344}
345
346
347CvMAT::CvMAT( const _CvMAT_SOLVE_& solve_mat )
348{
349    type = 0;
350    data.ptr = 0;
351    refcount = 0;
352    *this = solve_mat;
353}
354
355
356CvMAT::CvMAT( const _CvMAT_CMP_& cmp_mat )
357{
358    type = 0;
359    data.ptr = 0;
360    refcount = 0;
361    *this = cmp_mat;
362}
363
364
365/****************************************************************************************\
366*                                  CvMAT::operator =                                     *
367\****************************************************************************************/
368
369CvMAT& CvMAT::operator = ( const _CvMAT_T_& mat_t )
370{
371    CvMAT* src = (CvMAT*)&mat_t.a;
372    if( !data.ptr )
373    {
374        create( src->width, src->height, src->type );
375    }
376
377    cvTranspose( src, this );
378    return *this;
379}
380
381
382CvMAT& CvMAT::operator = ( const _CvMAT_ADD_& mat_add )
383{
384    CvMAT* a = mat_add.a;
385    CvMAT* b = mat_add.b;
386
387    if( !data.ptr )
388    {
389        create( a->height, a->width, a->type );
390    }
391
392    if( mat_add.beta == 1 )
393    {
394        cvAdd( a, b, this );
395        return *this;
396    }
397
398    if( mat_add.beta == -1 )
399    {
400        cvSub( a, b, this );
401        return *this;
402    }
403
404    if( CV_MAT_DEPTH(a->type) >= CV_32F && CV_MAT_CN(a->type) <= 2 )
405        cvScaleAdd( b, cvScalar(mat_add.beta), a, this );
406    else
407        cvAddWeighted( a, 1, b, mat_add.beta, 0, this );
408    return *this;
409}
410
411
412CvMAT& CvMAT::operator = ( const _CvMAT_ADD_EX_& mat_add )
413{
414    CvMAT* a = mat_add.a;
415    CvMAT* b = mat_add.b;
416
417    if( !data.ptr )
418    {
419        create( a->height, a->width, a->type );
420    }
421
422    cvAddWeighted( a, mat_add.alpha, b, mat_add.beta, mat_add.gamma, this );
423    return *this;
424}
425
426
427CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_& scale_mat )
428{
429    CvMAT* src = scale_mat.a;
430
431    if( !data.ptr )
432    {
433        create( src->height, src->width, src->type );
434    }
435
436    cvConvertScale( src, this, scale_mat.alpha, 0 );
437    return *this;
438}
439
440
441CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
442{
443    CvMAT* src = scale_shift_mat.a;
444
445    if( !data.ptr )
446    {
447        create( src->height, src->width, src->type );
448    }
449
450    cvConvertScale( src, this, scale_shift_mat.alpha, scale_shift_mat.beta );
451    return *this;
452}
453
454
455CvMAT& CvMAT::operator = ( const _CvMAT_MUL_& mmul )
456{
457    CvMAT* a = mmul.a;
458    CvMAT* b = mmul.b;
459    int t_a = mmul.t_ab & 1;
460    int t_b = (mmul.t_ab & 2) != 0;
461    int m = (&(a->rows))[t_a];
462    int n = (&(b->rows))[t_b ^ 1];
463    /* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
464
465    if( !data.ptr )
466    {
467        create( m, n, a->type );
468    }
469
470    if( mmul.alpha == 1 )
471    {
472        if( mmul.t_ab == 0 )
473        {
474            cvMatMulAdd( a, b, 0, this );
475            return *this;
476        }
477
478        if( a->data.ptr == b->data.ptr && mmul.t_ab < 3 &&
479            a->rows == b->rows && a->cols == b->cols &&
480            a->data.ptr != data.ptr )
481        {
482            cvMulTransposed( a, this, mmul.t_ab & 1 );
483            return *this;
484        }
485    }
486
487    cvGEMM( a, b, mmul.alpha, 0, 0, this, mmul.t_ab );
488    return *this;
489}
490
491
492CvMAT& CvMAT::operator = ( const _CvMAT_MUL_ADD_& mmuladd )
493{
494    CvMAT* a = mmuladd.a;
495    CvMAT* b = mmuladd.b;
496    CvMAT* c = mmuladd.c;
497    int t_a = mmuladd.t_abc & 1;
498    int t_b = (mmuladd.t_abc & 2) != 0;
499    int m = (&(a->rows))[t_a];
500    int n = (&(b->rows))[t_b ^ 1];
501    /* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
502
503    if( !data.ptr )
504    {
505        create( m, n, a->type );
506    }
507
508    if( mmuladd.t_abc == 0 && mmuladd.alpha == 1 && mmuladd.beta == 1 )
509        cvMatMulAdd( a, b, c, this );
510    else
511        cvGEMM( a, b, mmuladd.alpha, c, mmuladd.beta, this, mmuladd.t_abc );
512    return *this;
513}
514
515
516CvMAT& CvMAT::operator = ( const _CvMAT_INV_& inv_mat )
517{
518    CvMAT* src = (CvMAT*)&inv_mat.a;
519
520    if( !data.ptr )
521    {
522        create( src->height, src->width, src->type );
523    }
524
525    if( inv_mat.method == 0 )
526        cvInvert( src, this );
527    else
528        cvPseudoInv( src, this );
529    return *this;
530}
531
532
533CvMAT& CvMAT::operator = ( const _CvMAT_NOT_& not_mat )
534{
535    CvMAT* src = not_mat.a;
536
537    if( !data.ptr )
538    {
539        create( src->height, src->width, src->type );
540    }
541
542    cvNot( src, this );
543    return *this;
544}
545
546
547CvMAT& CvMAT::operator = ( const _CvMAT_LOGIC_& mat_logic )
548{
549    CvMAT* a = mat_logic.a;
550    CvMAT* b = mat_logic.b;
551    int flags = mat_logic.flags;
552    _CvMAT_LOGIC_::Op op = mat_logic.op;
553
554    if( !data.ptr )
555    {
556        create( a->height, a->width, a->type );
557    }
558
559    switch( op )
560    {
561    case _CvMAT_LOGIC_::AND:
562
563        if( flags == 0 )
564            cvAnd( a, b, this );
565        else if( flags == 3 )
566        {
567            cvOr( a, b, this );
568            cvNot( this, this );
569        }
570        else if( flags == 1 )
571        {
572            if( data.ptr == b->data.ptr )
573            {
574                cvNot( b, this );
575                cvOr( this, a, this );
576                cvNot( this, this );
577            }
578            else
579            {
580                cvNot( a, this );
581                cvAnd( this, b, this );
582            }
583        }
584        else
585        {
586            if( data.ptr == a->data.ptr )
587            {
588                cvNot( a, this );
589                cvOr( this, b, this );
590                cvNot( this, this );
591            }
592            else
593            {
594                cvNot( b, this );
595                cvAnd( this, a, this );
596            }
597        }
598        break;
599
600    case _CvMAT_LOGIC_::OR:
601
602        if( flags == 0 )
603            cvOr( a, b, this );
604        else if( flags == 3 )
605        {
606            cvAnd( a, b, this );
607            cvNot( this, this );
608        }
609        else if( flags == 1 )
610        {
611            if( data.ptr == b->data.ptr )
612            {
613                cvNot( b, this );
614                cvAnd( this, a, this );
615                cvNot( this, this );
616            }
617            else
618            {
619                cvNot( a, this );
620                cvOr( this, b, this );
621            }
622        }
623        else
624        {
625            if( data.ptr == a->data.ptr )
626            {
627                cvNot( a, this );
628                cvAnd( this, b, this );
629                cvNot( this, this );
630            }
631            else
632            {
633                cvNot( b, this );
634                cvOr( this, a, this );
635            }
636        }
637        break;
638
639    case _CvMAT_LOGIC_::XOR:
640
641        cvXor( a, b, this );
642        if( flags == 1 || flags == 2 )
643            cvNot( this, this );
644        break;
645    }
646
647    return *this;
648}
649
650
651CvMAT& CvMAT::operator = ( const _CvMAT_UN_LOGIC_& mat_logic )
652{
653    CvMAT* a = mat_logic.a;
654    CvScalar scalar = cvScalarAll( mat_logic.alpha );
655    int flags = mat_logic.flags;
656    _CvMAT_LOGIC_::Op op = mat_logic.op;
657
658    if( !data.ptr )
659    {
660        create( a->height, a->width, a->type );
661    }
662
663    switch( op )
664    {
665    case _CvMAT_LOGIC_::AND:
666
667        if( flags == 0 )
668            cvAndS( a, scalar, this );
669        else
670        {
671            cvNot( a, this );
672            cvAndS( this, scalar, this );
673        }
674        break;
675
676    case _CvMAT_LOGIC_::OR:
677
678        if( flags == 0 )
679            cvOrS( a, scalar, this );
680        else
681        {
682            cvNot( a, this );
683            cvOrS( this, scalar, this );
684        }
685        break;
686
687    case _CvMAT_LOGIC_::XOR:
688
689        if( flags == 0 )
690            cvXorS( a, scalar, this );
691        else
692            cvXorS( a, ~scalar, this );
693        break;
694    }
695
696    return *this;
697}
698
699
700CvMAT& CvMAT::operator = ( const _CvMAT_COPY_& mat_copy )
701{
702    CvMAT* src = (CvMAT*)mat_copy.a;
703
704    if( !data.ptr )
705    {
706        create( src->height, src->width, src->type );
707    }
708
709    if( src != this )
710        cvCopy( src, this );
711
712    return *this;
713}
714
715
716CvMAT& CvMAT::operator = ( const _CvMAT_CVT_& mat_cvt )
717{
718    CvMAT* src = (CvMAT*)&mat_cvt.a;
719
720    if( !data.ptr )
721    {
722        int depth = mat_cvt.newdepth;
723        create( src->height, src->width, depth < 0 ? src->type :
724                CV_MAT_CN(src->type)|CV_MAT_DEPTH(depth));
725    }
726
727    cvCvtScale( src, this, mat_cvt.scale, mat_cvt.shift );
728    return *this;
729}
730
731
732CvMAT& CvMAT::operator = ( const _CvMAT_DOT_OP_& dot_op )
733{
734    CvMAT* a = (CvMAT*)&(dot_op.a);
735    CvMAT* b = dot_op.b;
736
737    if( !data.ptr )
738    {
739        create( a->height, a->width, a->type );
740    }
741
742    switch( dot_op.op )
743    {
744    case '*':
745        cvMul( a, b, this, dot_op.alpha );
746        break;
747    case '/':
748        if( b != 0 )
749            cvDiv( a, b, this, dot_op.alpha );
750        else
751            cvDiv( 0, a, this, dot_op.alpha );
752        break;
753    case 'm':
754        if( b != 0 )
755            cvMin( a, b, this );
756        else
757            cvMinS( a, dot_op.alpha, this );
758        break;
759    case 'M':
760        if( b != 0 )
761            cvMax( a, b, this );
762        else
763            cvMaxS( a, dot_op.alpha, this );
764        break;
765    case 'a':
766        if( b != 0 )
767            cvAbsDiff( a, b, this );
768        else
769            cvAbsDiffS( a, this, cvScalar(dot_op.alpha) );
770        break;
771    default:
772        assert(0);
773    }
774
775    return *this;
776}
777
778
779CvMAT& CvMAT::operator = ( const _CvMAT_SOLVE_& solve_mat )
780{
781    CvMAT* a = (CvMAT*)(solve_mat.a);
782    CvMAT* b = (CvMAT*)(solve_mat.b);
783
784    if( !data.ptr )
785    {
786        create( a->height, b->width, a->type );
787    }
788
789    if( solve_mat.method == 0 )
790        cvSolve( a, b, this );
791    else
792    {
793        CvMAT temp;
794        cvInitMatHeader( &temp, a->cols, a->rows, a->type );
795        cvCreateData( &temp );
796
797        cvPseudoInv( a, &temp );
798        cvMatMul( &temp, b, this );
799    }
800
801    return *this;
802}
803
804
805CvMAT& CvMAT::operator = ( const _CvMAT_CMP_& mat_cmp )
806{
807    CvMAT* a = mat_cmp.a;
808    CvMAT* b = mat_cmp.b;
809
810    if( !data.ptr )
811    {
812        create( a->height, a->width, CV_8UC1 );
813    }
814
815    if( b )
816        cvCmp( a, b, this, mat_cmp.cmp_op );
817    else
818        cvCmpS( a, mat_cmp.alpha, this, mat_cmp.cmp_op );
819    return *this;
820}
821
822
823/****************************************************************************************\
824*                                  CvMAT I/O operations                                  *
825\****************************************************************************************/
826
827void  CvMAT::write( const char* name, FILE* f, const char* fmt )
828{
829    int i, j, w = width * CV_MAT_CN(type);
830    FILE* out = f ? f : stdout;
831
832    if( name )
833        fprintf( stdout, "%s(%d x %d) =\n\t", name, rows, cols );
834
835    for( i = 0; i < rows; i++ )
836    {
837        switch( CV_MAT_DEPTH(type))
838        {
839        case CV_8U: if( !fmt )
840                        fmt = "%4d";
841                    for( j = 0; j < w; j++ )
842                        fprintf( out, fmt, ((uchar*)(data.ptr + i*step))[j] );
843                    break;
844        case CV_8S: if( !fmt )
845                        fmt = "%5d";
846                    for( j = 0; j < w; j++ )
847                        fprintf( out, fmt, ((char*)(data.ptr + i*step))[j] );
848                    break;
849        case CV_16S: if( !fmt )
850                        fmt = "%7d";
851                    for( j = 0; j < w; j++ )
852                        fprintf( out, fmt, ((short*)(data.ptr + i*step))[j] );
853                    break;
854        case CV_32S: if( !fmt )
855                        fmt = " %08x";
856                    for( j = 0; j < w; j++ )
857                        fprintf( out, fmt, ((int*)(data.ptr + i*step))[j] );
858                    break;
859        case CV_32F: if( !fmt )
860                        fmt = "%15g";
861                    for( j = 0; j < w; j++ )
862                        fprintf( out, fmt, ((float*)(data.ptr + i*step))[j] );
863                    break;
864        case CV_64F: if( !fmt )
865                        fmt = "%15g";
866                    for( j = 0; j < w; j++ )
867                        fprintf( out, fmt, ((double*)(data.ptr + i*step))[j] );
868                    break;
869        }
870        fprintf( out, "\n%s", i < rows - 1 ? "\t" : "" );
871    }
872    fprintf( out, "\n" );
873}
874
875#endif /* _MSC_VER || __BORLANDC__ */
876
877/* End of file. */
878
879
880