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 "_cv.h"
43
44#define  ICV_DEF_ACC_FUNC( name, srctype, dsttype, cvtmacro )           \
45IPCVAPI_IMPL( CvStatus,                                                 \
46name,( const srctype *src, int srcstep, dsttype *dst,                   \
47       int dststep, CvSize size ), (src, srcstep, dst, dststep, size )) \
48                                                                        \
49{                                                                       \
50    srcstep /= sizeof(src[0]);                                          \
51    dststep /= sizeof(dst[0]);                                          \
52                                                                        \
53    for( ; size.height--; src += srcstep, dst += dststep )              \
54    {                                                                   \
55        int x;                                                          \
56        for( x = 0; x <= size.width - 4; x += 4 )                       \
57        {                                                               \
58            dsttype t0 = dst[x] + cvtmacro(src[x]);                     \
59            dsttype t1 = dst[x + 1] + cvtmacro(src[x + 1]);             \
60            dst[x] = t0;  dst[x + 1] = t1;                              \
61                                                                        \
62            t0 = dst[x + 2] + cvtmacro(src[x + 2]);                     \
63            t1 = dst[x + 3] + cvtmacro(src[x + 3]);                     \
64            dst[x + 2] = t0;  dst[x + 3] = t1;                          \
65        }                                                               \
66                                                                        \
67        for( ; x < size.width; x++ )                                    \
68            dst[x] += cvtmacro(src[x]);                                 \
69    }                                                                   \
70                                                                        \
71    return CV_OK;                                                       \
72}
73
74
75ICV_DEF_ACC_FUNC( icvAdd_8u32f_C1IR, uchar, float, CV_8TO32F )
76ICV_DEF_ACC_FUNC( icvAdd_32f_C1IR, float, float, CV_NOP )
77ICV_DEF_ACC_FUNC( icvAddSquare_8u32f_C1IR, uchar, float, CV_8TO32F_SQR )
78ICV_DEF_ACC_FUNC( icvAddSquare_32f_C1IR, float, float, CV_SQR )
79
80
81#define  ICV_DEF_ACCPROD_FUNC( flavor, srctype, dsttype, cvtmacro )         \
82IPCVAPI_IMPL( CvStatus, icvAddProduct_##flavor##_C1IR,                      \
83( const srctype *src1, int step1, const srctype *src2, int step2,           \
84  dsttype *dst, int dststep, CvSize size ),                                 \
85 (src1, step1, src2, step2, dst, dststep, size) )                           \
86{                                                                           \
87    step1 /= sizeof(src1[0]);                                               \
88    step2 /= sizeof(src2[0]);                                               \
89    dststep /= sizeof(dst[0]);                                              \
90                                                                            \
91    for( ; size.height--; src1 += step1, src2 += step2, dst += dststep )    \
92    {                                                                       \
93        int x;                                                              \
94        for( x = 0; x <= size.width - 4; x += 4 )                           \
95        {                                                                   \
96            dsttype t0 = dst[x] + cvtmacro(src1[x])*cvtmacro(src2[x]);      \
97            dsttype t1 = dst[x+1] + cvtmacro(src1[x+1])*cvtmacro(src2[x+1]);\
98            dst[x] = t0;  dst[x + 1] = t1;                                  \
99                                                                            \
100            t0 = dst[x + 2] + cvtmacro(src1[x + 2])*cvtmacro(src2[x + 2]);  \
101            t1 = dst[x + 3] + cvtmacro(src1[x + 3])*cvtmacro(src2[x + 3]);  \
102            dst[x + 2] = t0;  dst[x + 3] = t1;                              \
103        }                                                                   \
104                                                                            \
105        for( ; x < size.width; x++ )                                        \
106            dst[x] += cvtmacro(src1[x])*cvtmacro(src2[x]);                  \
107    }                                                                       \
108                                                                            \
109    return CV_OK;                                                           \
110}
111
112
113ICV_DEF_ACCPROD_FUNC( 8u32f, uchar, float, CV_8TO32F )
114ICV_DEF_ACCPROD_FUNC( 32f, float, float, CV_NOP )
115
116
117#define  ICV_DEF_ACCWEIGHT_FUNC( flavor, srctype, dsttype, cvtmacro )   \
118IPCVAPI_IMPL( CvStatus, icvAddWeighted_##flavor##_C1IR,                 \
119( const srctype *src, int srcstep, dsttype *dst, int dststep,           \
120  CvSize size, dsttype alpha ), (src, srcstep, dst, dststep, size, alpha) )\
121{                                                                       \
122    dsttype beta = (dsttype)(1 - alpha);                                \
123    srcstep /= sizeof(src[0]);                                          \
124    dststep /= sizeof(dst[0]);                                          \
125                                                                        \
126    for( ; size.height--; src += srcstep, dst += dststep )              \
127    {                                                                   \
128        int x;                                                          \
129        for( x = 0; x <= size.width - 4; x += 4 )                       \
130        {                                                               \
131            dsttype t0 = dst[x]*beta + cvtmacro(src[x])*alpha;          \
132            dsttype t1 = dst[x+1]*beta + cvtmacro(src[x+1])*alpha;      \
133            dst[x] = t0; dst[x + 1] = t1;                               \
134                                                                        \
135            t0 = dst[x + 2]*beta + cvtmacro(src[x + 2])*alpha;          \
136            t1 = dst[x + 3]*beta + cvtmacro(src[x + 3])*alpha;          \
137            dst[x + 2] = t0; dst[x + 3] = t1;                           \
138        }                                                               \
139                                                                        \
140        for( ; x < size.width; x++ )                                    \
141            dst[x] = dst[x]*beta + cvtmacro(src[x])*alpha;              \
142    }                                                                   \
143                                                                        \
144    return CV_OK;                                                       \
145}
146
147
148ICV_DEF_ACCWEIGHT_FUNC( 8u32f, uchar, float, CV_8TO32F )
149ICV_DEF_ACCWEIGHT_FUNC( 32f, float, float, CV_NOP )
150
151
152#define  ICV_DEF_ACCMASK_FUNC_C1( name, srctype, dsttype, cvtmacro )    \
153IPCVAPI_IMPL( CvStatus,                                                 \
154name,( const srctype *src, int srcstep, const uchar* mask, int maskstep,\
155       dsttype *dst, int dststep, CvSize size ),                        \
156       (src, srcstep, mask, maskstep, dst, dststep, size ))             \
157{                                                                       \
158    srcstep /= sizeof(src[0]);                                          \
159    dststep /= sizeof(dst[0]);                                          \
160                                                                        \
161    for( ; size.height--; src += srcstep,                               \
162                          dst += dststep, mask += maskstep )            \
163    {                                                                   \
164        int x;                                                          \
165        for( x = 0; x <= size.width - 2; x += 2 )                       \
166        {                                                               \
167            if( mask[x] )                                               \
168                dst[x] += cvtmacro(src[x]);                             \
169            if( mask[x+1] )                                             \
170                dst[x+1] += cvtmacro(src[x+1]);                         \
171        }                                                               \
172                                                                        \
173        for( ; x < size.width; x++ )                                    \
174            if( mask[x] )                                               \
175                dst[x] += cvtmacro(src[x]);                             \
176    }                                                                   \
177                                                                        \
178    return CV_OK;                                                       \
179}
180
181
182ICV_DEF_ACCMASK_FUNC_C1( icvAdd_8u32f_C1IMR, uchar, float, CV_8TO32F )
183ICV_DEF_ACCMASK_FUNC_C1( icvAdd_32f_C1IMR, float, float, CV_NOP )
184ICV_DEF_ACCMASK_FUNC_C1( icvAddSquare_8u32f_C1IMR, uchar, float, CV_8TO32F_SQR )
185ICV_DEF_ACCMASK_FUNC_C1( icvAddSquare_32f_C1IMR, float, float, CV_SQR )
186
187
188#define  ICV_DEF_ACCPRODUCTMASK_FUNC_C1( flavor, srctype, dsttype, cvtmacro )  \
189IPCVAPI_IMPL( CvStatus, icvAddProduct_##flavor##_C1IMR,                 \
190( const srctype *src1, int step1, const srctype* src2, int step2,       \
191  const uchar* mask, int maskstep, dsttype *dst, int dststep, CvSize size ),\
192  (src1, step1, src2, step2, mask, maskstep, dst, dststep, size ))      \
193{                                                                       \
194    step1 /= sizeof(src1[0]);                                           \
195    step2 /= sizeof(src2[0]);                                           \
196    dststep /= sizeof(dst[0]);                                          \
197                                                                        \
198    for( ; size.height--; src1 += step1, src2 += step2,                 \
199                          dst += dststep, mask += maskstep )            \
200    {                                                                   \
201        int x;                                                          \
202        for( x = 0; x <= size.width - 2; x += 2 )                       \
203        {                                                               \
204            if( mask[x] )                                               \
205                dst[x] += cvtmacro(src1[x])*cvtmacro(src2[x]);          \
206            if( mask[x+1] )                                             \
207                dst[x+1] += cvtmacro(src1[x+1])*cvtmacro(src2[x+1]);    \
208        }                                                               \
209                                                                        \
210        for( ; x < size.width; x++ )                                    \
211            if( mask[x] )                                               \
212                dst[x] += cvtmacro(src1[x])*cvtmacro(src2[x]);          \
213    }                                                                   \
214                                                                        \
215    return CV_OK;                                                       \
216}
217
218
219ICV_DEF_ACCPRODUCTMASK_FUNC_C1( 8u32f, uchar, float, CV_8TO32F )
220ICV_DEF_ACCPRODUCTMASK_FUNC_C1( 32f, float, float, CV_NOP )
221
222#define  ICV_DEF_ACCWEIGHTMASK_FUNC_C1( flavor, srctype, dsttype, cvtmacro ) \
223IPCVAPI_IMPL( CvStatus, icvAddWeighted_##flavor##_C1IMR,                \
224( const srctype *src, int srcstep, const uchar* mask, int maskstep,     \
225  dsttype *dst, int dststep, CvSize size, dsttype alpha ),              \
226  (src, srcstep, mask, maskstep, dst, dststep, size, alpha ))           \
227{                                                                       \
228    dsttype beta = (dsttype)(1 - alpha);                                \
229    srcstep /= sizeof(src[0]);                                          \
230    dststep /= sizeof(dst[0]);                                          \
231                                                                        \
232    for( ; size.height--; src += srcstep,                               \
233                          dst += dststep, mask += maskstep )            \
234    {                                                                   \
235        int x;                                                          \
236        for( x = 0; x <= size.width - 2; x += 2 )                       \
237        {                                                               \
238            if( mask[x] )                                               \
239                dst[x] = dst[x]*beta + cvtmacro(src[x])*alpha;          \
240            if( mask[x+1] )                                             \
241                dst[x+1] = dst[x+1]*beta + cvtmacro(src[x+1])*alpha;    \
242        }                                                               \
243                                                                        \
244        for( ; x < size.width; x++ )                                    \
245            if( mask[x] )                                               \
246                dst[x] = dst[x]*beta + cvtmacro(src[x])*alpha;          \
247    }                                                                   \
248                                                                        \
249    return CV_OK;                                                       \
250}
251
252ICV_DEF_ACCWEIGHTMASK_FUNC_C1( 8u32f, uchar, float, CV_8TO32F )
253ICV_DEF_ACCWEIGHTMASK_FUNC_C1( 32f, float, float, CV_NOP )
254
255
256#define  ICV_DEF_ACCMASK_FUNC_C3( name, srctype, dsttype, cvtmacro )    \
257IPCVAPI_IMPL( CvStatus,                                                 \
258name,( const srctype *src, int srcstep, const uchar* mask, int maskstep,\
259       dsttype *dst, int dststep, CvSize size ),                        \
260       (src, srcstep, mask, maskstep, dst, dststep, size ))             \
261{                                                                       \
262    srcstep /= sizeof(src[0]);                                          \
263    dststep /= sizeof(dst[0]);                                          \
264                                                                        \
265    for( ; size.height--; src += srcstep,                               \
266                          dst += dststep, mask += maskstep )            \
267    {                                                                   \
268        int x;                                                          \
269        for( x = 0; x < size.width; x++ )                               \
270            if( mask[x] )                                               \
271            {                                                           \
272                dsttype t0, t1, t2;                                     \
273                t0 = dst[x*3] + cvtmacro(src[x*3]);                     \
274                t1 = dst[x*3+1] + cvtmacro(src[x*3+1]);                 \
275                t2 = dst[x*3+2] + cvtmacro(src[x*3+2]);                 \
276                dst[x*3] = t0;                                          \
277                dst[x*3+1] = t1;                                        \
278                dst[x*3+2] = t2;                                        \
279            }                                                           \
280    }                                                                   \
281                                                                        \
282    return CV_OK;                                                       \
283}
284
285
286ICV_DEF_ACCMASK_FUNC_C3( icvAdd_8u32f_C3IMR, uchar, float, CV_8TO32F )
287ICV_DEF_ACCMASK_FUNC_C3( icvAdd_32f_C3IMR, float, float, CV_NOP )
288ICV_DEF_ACCMASK_FUNC_C3( icvAddSquare_8u32f_C3IMR, uchar, float, CV_8TO32F_SQR )
289ICV_DEF_ACCMASK_FUNC_C3( icvAddSquare_32f_C3IMR, float, float, CV_SQR )
290
291
292#define  ICV_DEF_ACCPRODUCTMASK_FUNC_C3( flavor, srctype, dsttype, cvtmacro )  \
293IPCVAPI_IMPL( CvStatus, icvAddProduct_##flavor##_C3IMR,                 \
294( const srctype *src1, int step1, const srctype* src2, int step2,       \
295  const uchar* mask, int maskstep, dsttype *dst, int dststep, CvSize size ),\
296  (src1, step1, src2, step2, mask, maskstep, dst, dststep, size ))      \
297{                                                                       \
298    step1 /= sizeof(src1[0]);                                           \
299    step2 /= sizeof(src2[0]);                                           \
300    dststep /= sizeof(dst[0]);                                          \
301                                                                        \
302    for( ; size.height--; src1 += step1, src2 += step2,                 \
303                          dst += dststep, mask += maskstep )            \
304    {                                                                   \
305        int x;                                                          \
306        for( x = 0; x < size.width; x++ )                               \
307            if( mask[x] )                                               \
308            {                                                           \
309                dsttype t0, t1, t2;                                     \
310                t0 = dst[x*3]+cvtmacro(src1[x*3])*cvtmacro(src2[x*3]);  \
311                t1 = dst[x*3+1]+cvtmacro(src1[x*3+1])*cvtmacro(src2[x*3+1]);\
312                t2 = dst[x*3+2]+cvtmacro(src1[x*3+2])*cvtmacro(src2[x*3+2]);\
313                dst[x*3] = t0;                                          \
314                dst[x*3+1] = t1;                                        \
315                dst[x*3+2] = t2;                                        \
316            }                                                           \
317    }                                                                   \
318                                                                        \
319    return CV_OK;                                                       \
320}
321
322
323ICV_DEF_ACCPRODUCTMASK_FUNC_C3( 8u32f, uchar, float, CV_8TO32F )
324ICV_DEF_ACCPRODUCTMASK_FUNC_C3( 32f, float, float, CV_NOP )
325
326
327#define  ICV_DEF_ACCWEIGHTMASK_FUNC_C3( flavor, srctype, dsttype, cvtmacro ) \
328IPCVAPI_IMPL( CvStatus, icvAddWeighted_##flavor##_C3IMR,                \
329( const srctype *src, int srcstep, const uchar* mask, int maskstep,     \
330  dsttype *dst, int dststep, CvSize size, dsttype alpha ),              \
331  (src, srcstep, mask, maskstep, dst, dststep, size, alpha ))           \
332{                                                                       \
333    dsttype beta = (dsttype)(1 - alpha);                                \
334    srcstep /= sizeof(src[0]);                                          \
335    dststep /= sizeof(dst[0]);                                          \
336                                                                        \
337    for( ; size.height--; src += srcstep,                               \
338                          dst += dststep, mask += maskstep )            \
339    {                                                                   \
340        int x;                                                          \
341        for( x = 0; x < size.width; x++ )                               \
342            if( mask[x] )                                               \
343            {                                                           \
344                dsttype t0, t1, t2;                                     \
345                t0 = dst[x*3]*beta + cvtmacro(src[x*3])*alpha;          \
346                t1 = dst[x*3+1]*beta + cvtmacro(src[x*3+1])*alpha;      \
347                t2 = dst[x*3+2]*beta + cvtmacro(src[x*3+2])*alpha;      \
348                dst[x*3] = t0;                                          \
349                dst[x*3+1] = t1;                                        \
350                dst[x*3+2] = t2;                                        \
351            }                                                           \
352    }                                                                   \
353                                                                        \
354    return CV_OK;                                                       \
355}
356
357ICV_DEF_ACCWEIGHTMASK_FUNC_C3( 8u32f, uchar, float, CV_8TO32F )
358ICV_DEF_ACCWEIGHTMASK_FUNC_C3( 32f, float, float, CV_NOP )
359
360
361#define  ICV_DEF_INIT_ACC_TAB( FUNCNAME )                                           \
362static  void  icvInit##FUNCNAME##Table( CvFuncTable* tab, CvBigFuncTable* masktab ) \
363{                                                                                   \
364    tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u32f_C1IR;                          \
365    tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_C1IR;                           \
366                                                                                    \
367    masktab->fn_2d[CV_8UC1] = (void*)icv##FUNCNAME##_8u32f_C1IMR;                   \
368    masktab->fn_2d[CV_32FC1] = (void*)icv##FUNCNAME##_32f_C1IMR;                    \
369                                                                                    \
370    masktab->fn_2d[CV_8UC3] = (void*)icv##FUNCNAME##_8u32f_C3IMR;                   \
371    masktab->fn_2d[CV_32FC3] = (void*)icv##FUNCNAME##_32f_C3IMR;                    \
372}
373
374
375ICV_DEF_INIT_ACC_TAB( Add )
376ICV_DEF_INIT_ACC_TAB( AddSquare )
377ICV_DEF_INIT_ACC_TAB( AddProduct )
378ICV_DEF_INIT_ACC_TAB( AddWeighted )
379
380
381CV_IMPL void
382cvAcc( const void* arr, void* sumarr, const void* maskarr )
383{
384    static CvFuncTable acc_tab;
385    static CvBigFuncTable accmask_tab;
386    static int inittab = 0;
387
388    CV_FUNCNAME( "cvAcc" );
389
390    __BEGIN__;
391
392    int type, sumdepth;
393    int mat_step, sum_step, mask_step = 0;
394    CvSize size;
395    CvMat stub, *mat = (CvMat*)arr;
396    CvMat sumstub, *sum = (CvMat*)sumarr;
397    CvMat maskstub, *mask = (CvMat*)maskarr;
398
399    if( !inittab )
400    {
401        icvInitAddTable( &acc_tab, &accmask_tab );
402        inittab = 1;
403    }
404
405    if( !CV_IS_MAT( mat ) || !CV_IS_MAT( sum ))
406    {
407        int coi1 = 0, coi2 = 0;
408        CV_CALL( mat = cvGetMat( mat, &stub, &coi1 ));
409        CV_CALL( sum = cvGetMat( sum, &sumstub, &coi2 ));
410        if( coi1 + coi2 != 0 )
411            CV_ERROR( CV_BadCOI, "" );
412    }
413
414    if( CV_MAT_DEPTH( sum->type ) != CV_32F )
415        CV_ERROR( CV_BadDepth, "" );
416
417    if( !CV_ARE_CNS_EQ( mat, sum ))
418        CV_ERROR( CV_StsUnmatchedFormats, "" );
419
420    sumdepth = CV_MAT_DEPTH( sum->type );
421    if( sumdepth != CV_32F && (maskarr != 0 || sumdepth != CV_64F))
422        CV_ERROR( CV_BadDepth, "Bad accumulator type" );
423
424    if( !CV_ARE_SIZES_EQ( mat, sum ))
425        CV_ERROR( CV_StsUnmatchedSizes, "" );
426
427    size = cvGetMatSize( mat );
428    type = CV_MAT_TYPE( mat->type );
429
430    mat_step = mat->step;
431    sum_step = sum->step;
432
433    if( !mask )
434    {
435        CvFunc2D_2A func=(CvFunc2D_2A)acc_tab.fn_2d[CV_MAT_DEPTH(type)];
436
437        if( !func )
438            CV_ERROR( CV_StsUnsupportedFormat, "Unsupported type combination" );
439
440        size.width *= CV_MAT_CN(type);
441        if( CV_IS_MAT_CONT( mat->type & sum->type ))
442        {
443            size.width *= size.height;
444            mat_step = sum_step = CV_STUB_STEP;
445            size.height = 1;
446        }
447
448        IPPI_CALL( func( mat->data.ptr, mat_step, sum->data.ptr, sum_step, size ));
449    }
450    else
451    {
452        CvFunc2D_3A func = (CvFunc2D_3A)accmask_tab.fn_2d[type];
453
454        if( !func )
455            CV_ERROR( CV_StsUnsupportedFormat, "" );
456
457        CV_CALL( mask = cvGetMat( mask, &maskstub ));
458
459        if( !CV_IS_MASK_ARR( mask ))
460            CV_ERROR( CV_StsBadMask, "" );
461
462        if( !CV_ARE_SIZES_EQ( mat, mask ))
463            CV_ERROR( CV_StsUnmatchedSizes, "" );
464
465        mask_step = mask->step;
466
467        if( CV_IS_MAT_CONT( mat->type & sum->type & mask->type ))
468        {
469            size.width *= size.height;
470            mat_step = sum_step = mask_step = CV_STUB_STEP;
471            size.height = 1;
472        }
473
474        IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step,
475                         sum->data.ptr, sum_step, size ));
476    }
477
478    __END__;
479}
480
481
482CV_IMPL void
483cvSquareAcc( const void* arr, void* sq_sum, const void* maskarr )
484{
485    static CvFuncTable acc_tab;
486    static CvBigFuncTable accmask_tab;
487    static int inittab = 0;
488
489    CV_FUNCNAME( "cvSquareAcc" );
490
491    __BEGIN__;
492
493    int coi1, coi2;
494    int type;
495    int mat_step, sum_step, mask_step = 0;
496    CvSize size;
497    CvMat stub, *mat = (CvMat*)arr;
498    CvMat sumstub, *sum = (CvMat*)sq_sum;
499    CvMat maskstub, *mask = (CvMat*)maskarr;
500
501    if( !inittab )
502    {
503        icvInitAddSquareTable( &acc_tab, &accmask_tab );
504        inittab = 1;
505    }
506
507    CV_CALL( mat = cvGetMat( mat, &stub, &coi1 ));
508    CV_CALL( sum = cvGetMat( sum, &sumstub, &coi2 ));
509
510    if( coi1 != 0 || coi2 != 0 )
511        CV_ERROR( CV_BadCOI, "" );
512
513    if( !CV_ARE_CNS_EQ( mat, sum ))
514        CV_ERROR( CV_StsUnmatchedFormats, "" );
515
516    if( CV_MAT_DEPTH( sum->type ) != CV_32F )
517        CV_ERROR( CV_BadDepth, "" );
518
519    if( !CV_ARE_SIZES_EQ( mat, sum ))
520        CV_ERROR( CV_StsUnmatchedSizes, "" );
521
522    size = cvGetMatSize( mat );
523    type = CV_MAT_TYPE( mat->type );
524
525    mat_step = mat->step;
526    sum_step = sum->step;
527
528    if( !mask )
529    {
530        CvFunc2D_2A func = (CvFunc2D_2A)acc_tab.fn_2d[CV_MAT_DEPTH(type)];
531
532        if( !func )
533            CV_ERROR( CV_StsUnsupportedFormat, "" );
534
535        size.width *= CV_MAT_CN(type);
536
537        if( CV_IS_MAT_CONT( mat->type & sum->type ))
538        {
539            size.width *= size.height;
540            mat_step = sum_step = CV_STUB_STEP;;
541            size.height = 1;
542        }
543
544        IPPI_CALL( func( mat->data.ptr, mat_step, sum->data.ptr, sum_step, size ));
545    }
546    else
547    {
548        CvFunc2D_3A func = (CvFunc2D_3A)accmask_tab.fn_2d[type];
549
550        if( !func )
551            CV_ERROR( CV_StsUnsupportedFormat, "" );
552
553        CV_CALL( mask = cvGetMat( mask, &maskstub ));
554
555        if( !CV_IS_MASK_ARR( mask ))
556            CV_ERROR( CV_StsBadMask, "" );
557
558        if( !CV_ARE_SIZES_EQ( mat, mask ))
559            CV_ERROR( CV_StsUnmatchedSizes, "" );
560
561        mask_step = mask->step;
562
563        if( CV_IS_MAT_CONT( mat->type & sum->type & mask->type ))
564        {
565            size.width *= size.height;
566            mat_step = sum_step = mask_step = CV_STUB_STEP;
567            size.height = 1;
568        }
569
570        IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step,
571                         sum->data.ptr, sum_step, size ));
572    }
573
574    __END__;
575}
576
577
578CV_IMPL void
579cvMultiplyAcc( const void* arrA, const void* arrB,
580               void* acc, const void* maskarr )
581{
582    static CvFuncTable acc_tab;
583    static CvBigFuncTable accmask_tab;
584    static int inittab = 0;
585
586    CV_FUNCNAME( "cvMultiplyAcc" );
587
588    __BEGIN__;
589
590    int coi1, coi2, coi3;
591    int type;
592    int mat1_step, mat2_step, sum_step, mask_step = 0;
593    CvSize size;
594    CvMat stub1, *mat1 = (CvMat*)arrA;
595    CvMat stub2, *mat2 = (CvMat*)arrB;
596    CvMat sumstub, *sum = (CvMat*)acc;
597    CvMat maskstub, *mask = (CvMat*)maskarr;
598
599    if( !inittab )
600    {
601        icvInitAddProductTable( &acc_tab, &accmask_tab );
602        inittab = 1;
603    }
604
605    CV_CALL( mat1 = cvGetMat( mat1, &stub1, &coi1 ));
606    CV_CALL( mat2 = cvGetMat( mat2, &stub2, &coi2 ));
607    CV_CALL( sum = cvGetMat( sum, &sumstub, &coi3 ));
608
609    if( coi1 != 0 || coi2 != 0 || coi3 != 0 )
610        CV_ERROR( CV_BadCOI, "" );
611
612    if( !CV_ARE_CNS_EQ( mat1, mat2 ) || !CV_ARE_CNS_EQ( mat1, sum ))
613        CV_ERROR( CV_StsUnmatchedFormats, "" );
614
615    if( CV_MAT_DEPTH( sum->type ) != CV_32F )
616        CV_ERROR( CV_BadDepth, "" );
617
618    if( !CV_ARE_SIZES_EQ( mat1, sum ) || !CV_ARE_SIZES_EQ( mat2, sum ))
619        CV_ERROR( CV_StsUnmatchedSizes, "" );
620
621    size = cvGetMatSize( mat1 );
622    type = CV_MAT_TYPE( mat1->type );
623
624    mat1_step = mat1->step;
625    mat2_step = mat2->step;
626    sum_step = sum->step;
627
628    if( !mask )
629    {
630        CvFunc2D_3A func = (CvFunc2D_3A)acc_tab.fn_2d[CV_MAT_DEPTH(type)];
631
632        if( !func )
633            CV_ERROR( CV_StsUnsupportedFormat, "" );
634
635        size.width *= CV_MAT_CN(type);
636
637        if( CV_IS_MAT_CONT( mat1->type & mat2->type & sum->type ))
638        {
639            size.width *= size.height;
640            mat1_step = mat2_step = sum_step = CV_STUB_STEP;
641            size.height = 1;
642        }
643
644        IPPI_CALL( func( mat1->data.ptr, mat1_step, mat2->data.ptr, mat2_step,
645                         sum->data.ptr, sum_step, size ));
646    }
647    else
648    {
649        CvFunc2D_4A func = (CvFunc2D_4A)accmask_tab.fn_2d[type];
650
651        if( !func )
652            CV_ERROR( CV_StsUnsupportedFormat, "" );
653
654        CV_CALL( mask = cvGetMat( mask, &maskstub ));
655
656        if( !CV_IS_MASK_ARR( mask ))
657            CV_ERROR( CV_StsBadMask, "" );
658
659        if( !CV_ARE_SIZES_EQ( mat1, mask ))
660            CV_ERROR( CV_StsUnmatchedSizes, "" );
661
662        mask_step = mask->step;
663
664        if( CV_IS_MAT_CONT( mat1->type & mat2->type & sum->type & mask->type ))
665        {
666            size.width *= size.height;
667            mat1_step = mat2_step = sum_step = mask_step = CV_STUB_STEP;
668            size.height = 1;
669        }
670
671        IPPI_CALL( func( mat1->data.ptr, mat1_step, mat2->data.ptr, mat2_step,
672                         mask->data.ptr, mask_step,
673                         sum->data.ptr, sum_step, size ));
674    }
675
676    __END__;
677}
678
679
680typedef CvStatus (CV_STDCALL *CvAddWeightedFunc)( const void* src, int srcstep,
681                                                  void* dst, int dststep,
682                                                  CvSize size, float alpha );
683
684typedef CvStatus (CV_STDCALL *CvAddWeightedMaskFunc)( const void* src, int srcstep,
685                                                      void* dst, int dststep,
686                                                      const void* mask, int maskstep,
687                                                      CvSize size, float alpha );
688
689CV_IMPL void
690cvRunningAvg( const void* arrY, void* arrU,
691              double alpha, const void* maskarr )
692{
693    static CvFuncTable acc_tab;
694    static CvBigFuncTable accmask_tab;
695    static int inittab = 0;
696
697    CV_FUNCNAME( "cvRunningAvg" );
698
699    __BEGIN__;
700
701    int coi1, coi2;
702    int type;
703    int mat_step, sum_step, mask_step = 0;
704    CvSize size;
705    CvMat stub, *mat = (CvMat*)arrY;
706    CvMat sumstub, *sum = (CvMat*)arrU;
707    CvMat maskstub, *mask = (CvMat*)maskarr;
708
709    if( !inittab )
710    {
711        icvInitAddWeightedTable( &acc_tab, &accmask_tab );
712        inittab = 1;
713    }
714
715    CV_CALL( mat = cvGetMat( mat, &stub, &coi1 ));
716    CV_CALL( sum = cvGetMat( sum, &sumstub, &coi2 ));
717
718    if( coi1 != 0 || coi2 != 0 )
719        CV_ERROR( CV_BadCOI, "" );
720
721    if( !CV_ARE_CNS_EQ( mat, sum ))
722        CV_ERROR( CV_StsUnmatchedFormats, "" );
723
724    if( CV_MAT_DEPTH( sum->type ) != CV_32F )
725        CV_ERROR( CV_BadDepth, "" );
726
727    if( !CV_ARE_SIZES_EQ( mat, sum ))
728        CV_ERROR( CV_StsUnmatchedSizes, "" );
729
730    size = cvGetMatSize( mat );
731    type = CV_MAT_TYPE( mat->type );
732
733    mat_step = mat->step;
734    sum_step = sum->step;
735
736    if( !mask )
737    {
738        CvAddWeightedFunc func = (CvAddWeightedFunc)acc_tab.fn_2d[CV_MAT_DEPTH(type)];
739
740        if( !func )
741            CV_ERROR( CV_StsUnsupportedFormat, "" );
742
743        size.width *= CV_MAT_CN(type);
744        if( CV_IS_MAT_CONT( mat->type & sum->type ))
745        {
746            size.width *= size.height;
747            mat_step = sum_step = CV_STUB_STEP;
748            size.height = 1;
749        }
750
751        IPPI_CALL( func( mat->data.ptr, mat_step,
752                         sum->data.ptr, sum_step, size, (float)alpha ));
753    }
754    else
755    {
756        CvAddWeightedMaskFunc func = (CvAddWeightedMaskFunc)accmask_tab.fn_2d[type];
757
758        if( !func )
759            CV_ERROR( CV_StsUnsupportedFormat, "" );
760
761        CV_CALL( mask = cvGetMat( mask, &maskstub ));
762
763        if( !CV_IS_MASK_ARR( mask ))
764            CV_ERROR( CV_StsBadMask, "" );
765
766        if( !CV_ARE_SIZES_EQ( mat, mask ))
767            CV_ERROR( CV_StsUnmatchedSizes, "" );
768
769        mask_step = mask->step;
770
771        if( CV_IS_MAT_CONT( mat->type & sum->type & mask->type ))
772        {
773            size.width *= size.height;
774            mat_step = sum_step = mask_step = CV_STUB_STEP;
775            size.height = 1;
776        }
777
778        IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step,
779                         sum->data.ptr, sum_step, size, (float)alpha ));
780    }
781
782    __END__;
783}
784
785
786/* End of file. */
787