1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
42 /* ////////////////////////////////////////////////////////////////////
44 // CvMat arithmetic operations: +, - ...
50 /****************************************************************************************\
51 * Arithmetic operations (+, -) without mask *
52 \****************************************************************************************/
54 #define ICV_DEF_BIN_ARI_OP_CASE( __op__, worktype, cast_macro, len )\
58 for( i = 0; i <= (len) - 4; i += 4 ) \
60 worktype t0 = __op__((src1)[i], (src2)[i]); \
61 worktype t1 = __op__((src1)[i+1], (src2)[i+1]); \
63 (dst)[i] = cast_macro( t0 ); \
64 (dst)[i+1] = cast_macro( t1 ); \
66 t0 = __op__((src1)[i+2],(src2)[i+2]); \
67 t1 = __op__((src1)[i+3],(src2)[i+3]); \
69 (dst)[i+2] = cast_macro( t0 ); \
70 (dst)[i+3] = cast_macro( t1 ); \
73 for( ; i < (len); i++ ) \
75 worktype t0 = __op__((src1)[i],(src2)[i]); \
76 (dst)[i] = cast_macro( t0 ); \
80 #define ICV_DEF_BIN_ARI_OP_2D( __op__, name, type, worktype, cast_macro ) \
81 IPCVAPI_IMPL( CvStatus, name, \
82 ( const type* src1, int step1, const type* src2, int step2, \
83 type* dst, int step, CvSize size ), \
84 (src1, step1, src2, step2, dst, step, size) ) \
86 step1/=sizeof(src1[0]); step2/=sizeof(src2[0]); step/=sizeof(dst[0]); \
88 if( size.width == 1 ) \
90 for( ; size.height--; src1 += step1, src2 += step2, dst += step ) \
92 worktype t0 = __op__((src1)[0],(src2)[0]); \
93 (dst)[0] = cast_macro( t0 ); \
98 for( ; size.height--; src1 += step1, src2 += step2, dst += step ) \
100 ICV_DEF_BIN_ARI_OP_CASE( __op__, worktype, \
101 cast_macro, size.width ); \
109 #define ICV_DEF_BIN_ARI_OP_2D_SFS(__op__, name, type, worktype, cast_macro) \
110 IPCVAPI_IMPL( CvStatus, name, \
111 ( const type* src1, int step1, const type* src2, int step2, \
112 type* dst, int step, CvSize size, int /*scalefactor*/ ), \
113 (src1, step1, src2, step2, dst, step, size, 0) ) \
115 step1/=sizeof(src1[0]); step2/=sizeof(src2[0]); step/=sizeof(dst[0]); \
117 if( size.width == 1 ) \
119 for( ; size.height--; src1 += step1, src2 += step2, dst += step ) \
121 worktype t0 = __op__((src1)[0],(src2)[0]); \
122 (dst)[0] = cast_macro( t0 ); \
127 for( ; size.height--; src1 += step1, src2 += step2, dst += step ) \
129 ICV_DEF_BIN_ARI_OP_CASE( __op__, worktype, \
130 cast_macro, size.width ); \
138 #define ICV_DEF_UN_ARI_OP_CASE( __op__, worktype, cast_macro, \
139 src, scalar, dst, len ) \
143 for( ; ((len) -= 12) >= 0; (dst) += 12, (src) += 12 ) \
145 worktype t0 = __op__((scalar)[0], (src)[0]); \
146 worktype t1 = __op__((scalar)[1], (src)[1]); \
148 (dst)[0] = cast_macro( t0 ); \
149 (dst)[1] = cast_macro( t1 ); \
151 t0 = __op__((scalar)[2], (src)[2]); \
152 t1 = __op__((scalar)[3], (src)[3]); \
154 (dst)[2] = cast_macro( t0 ); \
155 (dst)[3] = cast_macro( t1 ); \
157 t0 = __op__((scalar)[4], (src)[4]); \
158 t1 = __op__((scalar)[5], (src)[5]); \
160 (dst)[4] = cast_macro( t0 ); \
161 (dst)[5] = cast_macro( t1 ); \
163 t0 = __op__((scalar)[6], (src)[6]); \
164 t1 = __op__((scalar)[7], (src)[7]); \
166 (dst)[6] = cast_macro( t0 ); \
167 (dst)[7] = cast_macro( t1 ); \
169 t0 = __op__((scalar)[8], (src)[8]); \
170 t1 = __op__((scalar)[9], (src)[9]); \
172 (dst)[8] = cast_macro( t0 ); \
173 (dst)[9] = cast_macro( t1 ); \
175 t0 = __op__((scalar)[10], (src)[10]); \
176 t1 = __op__((scalar)[11], (src)[11]); \
178 (dst)[10] = cast_macro( t0 ); \
179 (dst)[11] = cast_macro( t1 ); \
182 for( (len) += 12, i = 0; i < (len); i++ ) \
184 worktype t0 = __op__((scalar)[i],(src)[i]); \
185 (dst)[i] = cast_macro( t0 ); \
190 #define ICV_DEF_UN_ARI_OP_2D( __op__, name, type, worktype, cast_macro ) \
191 static CvStatus CV_STDCALL name \
192 ( const type* src, int step1, type* dst, int step, \
193 CvSize size, const worktype* scalar ) \
195 step1 /= sizeof(src[0]); step /= sizeof(dst[0]); \
197 if( size.width == 1 ) \
199 for( ; size.height--; src += step1, dst += step ) \
201 worktype t0 = __op__(*(scalar),*(src)); \
202 *(dst) = cast_macro( t0 ); \
207 for( ; size.height--; src += step1, dst += step ) \
209 const type *tsrc = src; \
211 int width = size.width; \
213 ICV_DEF_UN_ARI_OP_CASE( __op__, worktype, cast_macro, \
214 tsrc, scalar, tdst, width ); \
222 #define ICV_DEF_BIN_ARI_ALL( __op__, name, cast_8u ) \
223 ICV_DEF_BIN_ARI_OP_2D_SFS( __op__, icv##name##_8u_C1R, uchar, int, cast_8u ) \
224 ICV_DEF_BIN_ARI_OP_2D_SFS( __op__, icv##name##_16u_C1R, ushort, int, CV_CAST_16U ) \
225 ICV_DEF_BIN_ARI_OP_2D_SFS( __op__, icv##name##_16s_C1R, short, int, CV_CAST_16S ) \
226 ICV_DEF_BIN_ARI_OP_2D( __op__, icv##name##_32s_C1R, int, int, CV_CAST_32S ) \
227 ICV_DEF_BIN_ARI_OP_2D( __op__, icv##name##_32f_C1R, float, float, CV_CAST_32F ) \
228 ICV_DEF_BIN_ARI_OP_2D( __op__, icv##name##_64f_C1R, double, double, CV_CAST_64F )
230 #define ICV_DEF_UN_ARI_ALL( __op__, name ) \
231 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_8u_C1R, uchar, int, CV_CAST_8U ) \
232 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_16u_C1R, ushort, int, CV_CAST_16U ) \
233 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_16s_C1R, short, int, CV_CAST_16S ) \
234 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_32s_C1R, int, int, CV_CAST_32S ) \
235 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_32f_C1R, float, float, CV_CAST_32F ) \
236 ICV_DEF_UN_ARI_OP_2D( __op__, icv##name##_64f_C1R, double, double, CV_CAST_64F )
239 #define CV_SUB_R(a,b) ((b) - (a))
241 ICV_DEF_BIN_ARI_ALL( CV_ADD, Add, CV_FAST_CAST_8U )
242 ICV_DEF_BIN_ARI_ALL( CV_SUB_R, Sub, CV_FAST_CAST_8U )
244 ICV_DEF_UN_ARI_ALL( CV_ADD, AddC )
245 ICV_DEF_UN_ARI_ALL( CV_SUB, SubRC )
247 #define ICV_DEF_INIT_ARITHM_FUNC_TAB( FUNCNAME, FLAG ) \
248 static void icvInit##FUNCNAME##FLAG##Table( CvFuncTable* tab )\
250 tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u_##FLAG; \
251 tab->fn_2d[CV_8S] = 0; \
252 tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u_##FLAG; \
253 tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s_##FLAG; \
254 tab->fn_2d[CV_32S] = (void*)icv##FUNCNAME##_32s_##FLAG; \
255 tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_##FLAG; \
256 tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f_##FLAG; \
259 ICV_DEF_INIT_ARITHM_FUNC_TAB( Sub, C1R )
260 ICV_DEF_INIT_ARITHM_FUNC_TAB( SubRC, C1R )
261 ICV_DEF_INIT_ARITHM_FUNC_TAB( Add, C1R )
262 ICV_DEF_INIT_ARITHM_FUNC_TAB( AddC, C1R )
264 /****************************************************************************************\
265 * External Functions for Arithmetic Operations *
266 \****************************************************************************************/
268 /*************************************** S U B ******************************************/
271 cvSub( const void* srcarr1, const void* srcarr2,
272 void* dstarr, const void* maskarr )
274 static CvFuncTable sub_tab;
275 static int inittab = 0;
279 CV_FUNCNAME( "cvSub" );
284 int y, dy, type, depth, cn, cont_flag = 0;
285 int src1_step, src2_step, dst_step, tdst_step, mask_step;
286 CvMat srcstub1, srcstub2, *src1, *src2;
287 CvMat dststub, *dst = (CvMat*)dstarr;
288 CvMat maskstub, *mask = (CvMat*)maskarr;
291 CvFunc2D_3A1I func_sfs;
292 CvCopyMaskFunc copym_func;
295 CV_SWAP( srcarr1, srcarr2, tmp ); // to comply with IPP
296 src1 = (CvMat*)srcarr1;
297 src2 = (CvMat*)srcarr2;
299 if( !CV_IS_MAT(src1) || !CV_IS_MAT(src2) || !CV_IS_MAT(dst))
301 if( CV_IS_MATND(src1) || CV_IS_MATND(src2) || CV_IS_MATND(dst))
303 CvArr* arrs[] = { src1, src2, dst };
305 CvNArrayIterator iterator;
308 CV_ERROR( CV_StsBadMask,
309 "This operation on multi-dimensional arrays does not support mask" );
311 CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
313 type = iterator.hdr[0]->type;
314 iterator.size.width *= CV_MAT_CN(type);
318 icvInitSubC1RTable( &sub_tab );
322 depth = CV_MAT_DEPTH(type);
323 if( depth <= CV_16S )
325 func_sfs = (CvFunc2D_3A1I)(sub_tab.fn_2d[depth]);
327 CV_ERROR( CV_StsUnsupportedFormat, "" );
331 IPPI_CALL( func_sfs( iterator.ptr[0], CV_STUB_STEP,
332 iterator.ptr[1], CV_STUB_STEP,
333 iterator.ptr[2], CV_STUB_STEP,
336 while( cvNextNArraySlice( &iterator ));
340 func = (CvFunc2D_3A)(sub_tab.fn_2d[depth]);
342 CV_ERROR( CV_StsUnsupportedFormat, "" );
346 IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
347 iterator.ptr[1], CV_STUB_STEP,
348 iterator.ptr[2], CV_STUB_STEP,
351 while( cvNextNArraySlice( &iterator ));
357 int coi1 = 0, coi2 = 0, coi3 = 0;
359 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 ));
360 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 ));
361 CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 ));
362 if( coi1 + coi2 + coi3 != 0 )
363 CV_ERROR( CV_BadCOI, "" );
367 if( !CV_ARE_TYPES_EQ( src1, src2 ) || !CV_ARE_TYPES_EQ( src1, dst ))
368 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
370 if( !CV_ARE_SIZES_EQ( src1, src2 ) || !CV_ARE_SIZES_EQ( src1, dst ))
371 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
373 type = CV_MAT_TYPE(src1->type);
374 size = cvGetMatSize( src1 );
375 depth = CV_MAT_DEPTH(type);
376 cn = CV_MAT_CN(type);
380 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type ))
382 int len = size.width*size.height*cn;
384 if( len <= CV_MAX_INLINE_MAT_OP_SIZE*CV_MAX_INLINE_MAT_OP_SIZE )
386 if( depth == CV_32F )
388 const float* src1data = (const float*)(src1->data.ptr);
389 const float* src2data = (const float*)(src2->data.ptr);
390 float* dstdata = (float*)(dst->data.ptr);
394 dstdata[len-1] = (float)(src2data[len-1] - src1data[len-1]);
401 if( depth == CV_64F )
403 const double* src1data = (const double*)(src1->data.ptr);
404 const double* src2data = (const double*)(src2->data.ptr);
405 double* dstdata = (double*)(dst->data.ptr);
409 dstdata[len-1] = src2data[len-1] - src1data[len-1];
425 int buf_size, elem_size;
427 if( !CV_IS_MAT(mask) )
428 CV_CALL( mask = cvGetMat( mask, &maskstub ));
430 if( !CV_IS_MASK_ARR(mask))
431 CV_ERROR( CV_StsBadMask, "" );
433 if( !CV_ARE_SIZES_EQ( mask, dst ))
434 CV_ERROR( CV_StsUnmatchedSizes, "" );
436 cont_flag = CV_IS_MAT_CONT( src1->type & src2->type & dst->type & mask->type );
437 elem_size = CV_ELEM_SIZE(type);
439 dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
441 dy = MIN(dy,size.height);
442 dstbuf = cvMat( dy, size.width, type );
444 dstbuf.step = cvAlign( dstbuf.step, 8 );
445 buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
446 if( buf_size > CV_MAX_LOCAL_SIZE )
448 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
452 buffer = (uchar*)cvStackAlloc( buf_size );
453 dstbuf.data.ptr = buffer;
456 copym_func = icvGetCopyMaskFunc( elem_size );
461 icvInitSubC1RTable( &sub_tab );
465 if( depth <= CV_16S )
468 func_sfs = (CvFunc2D_3A1I)(sub_tab.fn_2d[depth]);
470 CV_ERROR( CV_StsUnsupportedFormat, "" );
475 func = (CvFunc2D_3A)(sub_tab.fn_2d[depth]);
477 CV_ERROR( CV_StsUnsupportedFormat, "" );
480 src1_step = src1->step;
481 src2_step = src2->step;
482 dst_step = dst->step;
483 tdst_step = tdst->step;
484 mask_step = mask ? mask->step : 0;
486 for( y = 0; y < size.height; y += dy )
488 tsize.width = size.width;
490 if( y + dy > size.height )
491 tsize.height = size.height - y;
492 if( cont_flag || tsize.height == 1 )
494 tsize.width *= tsize.height;
496 src1_step = src2_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
499 IPPI_CALL( depth <= CV_16S ?
500 func_sfs( src1->data.ptr + y*src1->step, src1_step,
501 src2->data.ptr + y*src2->step, src2_step,
502 tdst->data.ptr, tdst_step,
503 cvSize( tsize.width*cn, tsize.height ), 0 ) :
504 func( src1->data.ptr + y*src1->step, src1_step,
505 src2->data.ptr + y*src2->step, src2_step,
506 tdst->data.ptr, tdst_step,
507 cvSize( tsize.width*cn, tsize.height )));
511 IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
512 dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
524 cvSubRS( const void* srcarr, CvScalar scalar, void* dstarr, const void* maskarr )
526 static CvFuncTable subr_tab;
527 static int inittab = 0;
531 CV_FUNCNAME( "cvSubRS" );
535 int sctype, y, dy, type, depth, cn, coi = 0, cont_flag = 0;
536 int src_step, dst_step, tdst_step, mask_step;
537 CvMat srcstub, *src = (CvMat*)srcarr;
538 CvMat dststub, *dst = (CvMat*)dstarr;
539 CvMat maskstub, *mask = (CvMat*)maskarr;
542 CvCopyMaskFunc copym_func;
549 icvInitSubRCC1RTable( &subr_tab );
553 if( !CV_IS_MAT(src) )
555 if( CV_IS_MATND(src) )
559 CV_CALL( src = cvGetMat( src, &srcstub, &coi ));
561 CV_ERROR( CV_BadCOI, "" );
565 if( !CV_IS_MAT(dst) )
567 if( CV_IS_MATND(dst) )
571 CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
573 CV_ERROR( CV_BadCOI, "" );
579 CvArr* arrs[] = { src, dst };
581 CvNArrayIterator iterator;
584 CV_ERROR( CV_StsBadMask,
585 "This operation on multi-dimensional arrays does not support mask" );
587 CV_CALL( cvInitNArrayIterator( 2, arrs, 0, stubs, &iterator ));
589 sctype = type = CV_MAT_TYPE(iterator.hdr[0]->type);
590 if( CV_MAT_DEPTH(sctype) < CV_32S )
591 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;
592 iterator.size.width *= CV_MAT_CN(type);
594 func = (CvFunc2D_2A1P)(subr_tab.fn_2d[CV_MAT_DEPTH(type)]);
596 CV_ERROR( CV_StsUnsupportedFormat, "" );
598 CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 ));
602 IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
603 iterator.ptr[1], CV_STUB_STEP,
604 iterator.size, buf ));
606 while( cvNextNArraySlice( &iterator ));
610 if( !CV_ARE_TYPES_EQ( src, dst ))
611 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
613 if( !CV_ARE_SIZES_EQ( src, dst ))
614 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
616 sctype = type = CV_MAT_TYPE(src->type);
617 depth = CV_MAT_DEPTH(type);
618 cn = CV_MAT_CN(type);
620 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;
622 size = cvGetMatSize( src );
626 if( CV_IS_MAT_CONT( src->type & dst->type ))
628 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE )
630 int len = size.width * size.height;
632 if( type == CV_32FC1 )
634 const float* srcdata = (const float*)(src->data.ptr);
635 float* dstdata = (float*)(dst->data.ptr);
639 dstdata[len-1] = (float)(scalar.val[0] - srcdata[len-1]);
646 if( type == CV_64FC1 )
648 const double* srcdata = (const double*)(src->data.ptr);
649 double* dstdata = (double*)(dst->data.ptr);
653 dstdata[len-1] = scalar.val[0] - srcdata[len-1];
669 int buf_size, elem_size;
671 if( !CV_IS_MAT(mask) )
672 CV_CALL( mask = cvGetMat( mask, &maskstub ));
674 if( !CV_IS_MASK_ARR(mask))
675 CV_ERROR( CV_StsBadMask, "" );
677 if( !CV_ARE_SIZES_EQ( mask, dst ))
678 CV_ERROR( CV_StsUnmatchedSizes, "" );
680 cont_flag = CV_IS_MAT_CONT( src->type & dst->type & mask->type );
681 elem_size = CV_ELEM_SIZE(type);
683 dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
685 dy = MIN(dy,size.height);
686 dstbuf = cvMat( dy, size.width, type );
688 dstbuf.step = cvAlign( dstbuf.step, 8 );
689 buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
690 if( buf_size > CV_MAX_LOCAL_SIZE )
692 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
696 buffer = (uchar*)cvStackAlloc( buf_size );
697 dstbuf.data.ptr = buffer;
700 copym_func = icvGetCopyMaskFunc( elem_size );
703 func = (CvFunc2D_2A1P)(subr_tab.fn_2d[depth]);
705 CV_ERROR( CV_StsUnsupportedFormat, "" );
707 src_step = src->step;
708 dst_step = dst->step;
709 tdst_step = tdst->step;
710 mask_step = mask ? mask->step : 0;
712 CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 ));
714 for( y = 0; y < size.height; y += dy )
716 tsize.width = size.width;
718 if( y + dy > size.height )
719 tsize.height = size.height - y;
720 if( cont_flag || tsize.height == 1 )
722 tsize.width *= tsize.height;
724 src_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
727 IPPI_CALL( func( src->data.ptr + y*src->step, src_step,
728 tdst->data.ptr, tdst_step,
729 cvSize( tsize.width*cn, tsize.height ), buf ));
732 IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
733 dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
744 /******************************* A D D ********************************/
747 cvAdd( const void* srcarr1, const void* srcarr2,
748 void* dstarr, const void* maskarr )
750 static CvFuncTable add_tab;
751 static int inittab = 0;
755 CV_FUNCNAME( "cvAdd" );
759 int y, dy, type, depth, cn, cont_flag = 0;
760 int src1_step, src2_step, dst_step, tdst_step, mask_step;
761 CvMat srcstub1, *src1 = (CvMat*)srcarr1;
762 CvMat srcstub2, *src2 = (CvMat*)srcarr2;
763 CvMat dststub, *dst = (CvMat*)dstarr;
764 CvMat maskstub, *mask = (CvMat*)maskarr;
767 CvFunc2D_3A1I func_sfs;
768 CvCopyMaskFunc copym_func;
771 if( !CV_IS_MAT(src1) || !CV_IS_MAT(src2) || !CV_IS_MAT(dst))
773 if( CV_IS_MATND(src1) || CV_IS_MATND(src2) || CV_IS_MATND(dst))
775 CvArr* arrs[] = { src1, src2, dst };
777 CvNArrayIterator iterator;
780 CV_ERROR( CV_StsBadMask,
781 "This operation on multi-dimensional arrays does not support mask" );
783 CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
785 type = iterator.hdr[0]->type;
786 iterator.size.width *= CV_MAT_CN(type);
790 icvInitAddC1RTable( &add_tab );
794 depth = CV_MAT_DEPTH(type);
795 if( depth <= CV_16S )
797 func_sfs = (CvFunc2D_3A1I)(add_tab.fn_2d[depth]);
799 CV_ERROR( CV_StsUnsupportedFormat, "" );
803 IPPI_CALL( func_sfs( iterator.ptr[0], CV_STUB_STEP,
804 iterator.ptr[1], CV_STUB_STEP,
805 iterator.ptr[2], CV_STUB_STEP,
808 while( cvNextNArraySlice( &iterator ));
812 func = (CvFunc2D_3A)(add_tab.fn_2d[depth]);
814 CV_ERROR( CV_StsUnsupportedFormat, "" );
818 IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
819 iterator.ptr[1], CV_STUB_STEP,
820 iterator.ptr[2], CV_STUB_STEP,
823 while( cvNextNArraySlice( &iterator ));
829 int coi1 = 0, coi2 = 0, coi3 = 0;
831 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 ));
832 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 ));
833 CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 ));
834 if( coi1 + coi2 + coi3 != 0 )
835 CV_ERROR( CV_BadCOI, "" );
839 if( !CV_ARE_TYPES_EQ( src1, src2 ) || !CV_ARE_TYPES_EQ( src1, dst ))
840 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
842 if( !CV_ARE_SIZES_EQ( src1, src2 ) || !CV_ARE_SIZES_EQ( src1, dst ))
843 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
845 type = CV_MAT_TYPE(src1->type);
846 size = cvGetMatSize( src1 );
847 depth = CV_MAT_DEPTH(type);
848 cn = CV_MAT_CN(type);
852 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type ))
854 int len = size.width*size.height*cn;
856 if( len <= CV_MAX_INLINE_MAT_OP_SIZE*CV_MAX_INLINE_MAT_OP_SIZE )
858 if( depth == CV_32F )
860 const float* src1data = (const float*)(src1->data.ptr);
861 const float* src2data = (const float*)(src2->data.ptr);
862 float* dstdata = (float*)(dst->data.ptr);
866 dstdata[len-1] = (float)(src1data[len-1] + src2data[len-1]);
873 if( depth == CV_64F )
875 const double* src1data = (const double*)(src1->data.ptr);
876 const double* src2data = (const double*)(src2->data.ptr);
877 double* dstdata = (double*)(dst->data.ptr);
881 dstdata[len-1] = src1data[len-1] + src2data[len-1];
897 int buf_size, elem_size;
899 if( !CV_IS_MAT(mask) )
900 CV_CALL( mask = cvGetMat( mask, &maskstub ));
902 if( !CV_IS_MASK_ARR(mask))
903 CV_ERROR( CV_StsBadMask, "" );
905 if( !CV_ARE_SIZES_EQ( mask, dst ))
906 CV_ERROR( CV_StsUnmatchedSizes, "" );
908 cont_flag = CV_IS_MAT_CONT( src1->type & src2->type & dst->type & mask->type );
909 elem_size = CV_ELEM_SIZE(type);
911 dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
913 dy = MIN(dy,size.height);
914 dstbuf = cvMat( dy, size.width, type );
916 dstbuf.step = cvAlign( dstbuf.step, 8 );
917 buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
918 if( buf_size > CV_MAX_LOCAL_SIZE )
920 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
924 buffer = (uchar*)cvStackAlloc( buf_size );
925 dstbuf.data.ptr = buffer;
928 copym_func = icvGetCopyMaskFunc( elem_size );
933 icvInitAddC1RTable( &add_tab );
937 if( depth <= CV_16S )
940 func_sfs = (CvFunc2D_3A1I)(add_tab.fn_2d[depth]);
942 CV_ERROR( CV_StsUnsupportedFormat, "" );
947 func = (CvFunc2D_3A)(add_tab.fn_2d[depth]);
949 CV_ERROR( CV_StsUnsupportedFormat, "" );
952 src1_step = src1->step;
953 src2_step = src2->step;
954 dst_step = dst->step;
955 tdst_step = tdst->step;
956 mask_step = mask ? mask->step : 0;
958 for( y = 0; y < size.height; y += dy )
960 tsize.width = size.width;
962 if( y + dy > size.height )
963 tsize.height = size.height - y;
964 if( cont_flag || tsize.height == 1 )
966 tsize.width *= tsize.height;
968 src1_step = src2_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
971 IPPI_CALL( depth <= CV_16S ?
972 func_sfs( src1->data.ptr + y*src1->step, src1_step,
973 src2->data.ptr + y*src2->step, src2_step,
974 tdst->data.ptr, tdst_step,
975 cvSize( tsize.width*cn, tsize.height ), 0 ) :
976 func( src1->data.ptr + y*src1->step, src1_step,
977 src2->data.ptr + y*src2->step, src2_step,
978 tdst->data.ptr, tdst_step,
979 cvSize( tsize.width*cn, tsize.height )));
983 IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
984 dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
996 cvAddS( const void* srcarr, CvScalar scalar, void* dstarr, const void* maskarr )
998 static CvFuncTable add_tab;
999 static int inittab = 0;
1000 int local_alloc = 1;
1003 CV_FUNCNAME( "cvAddS" );
1007 int sctype, y, dy, type, depth, cn, coi = 0, cont_flag = 0;
1008 int src_step, dst_step, tdst_step, mask_step;
1009 CvMat srcstub, *src = (CvMat*)srcarr;
1010 CvMat dststub, *dst = (CvMat*)dstarr;
1011 CvMat maskstub, *mask = (CvMat*)maskarr;
1012 CvMat dstbuf, *tdst;
1014 CvCopyMaskFunc copym_func;
1021 icvInitAddCC1RTable( &add_tab );
1025 if( !CV_IS_MAT(src) )
1027 if( CV_IS_MATND(src) )
1031 CV_CALL( src = cvGetMat( src, &srcstub, &coi ));
1033 CV_ERROR( CV_BadCOI, "" );
1037 if( !CV_IS_MAT(dst) )
1039 if( CV_IS_MATND(dst) )
1043 CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
1045 CV_ERROR( CV_BadCOI, "" );
1051 CvArr* arrs[] = { src, dst };
1053 CvNArrayIterator iterator;
1056 CV_ERROR( CV_StsBadMask,
1057 "This operation on multi-dimensional arrays does not support mask" );
1059 CV_CALL( cvInitNArrayIterator( 2, arrs, 0, stubs, &iterator ));
1061 sctype = type = CV_MAT_TYPE(iterator.hdr[0]->type);
1062 if( CV_MAT_DEPTH(sctype) < CV_32S )
1063 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;
1064 iterator.size.width *= CV_MAT_CN(type);
1066 func = (CvFunc2D_2A1P)(add_tab.fn_2d[CV_MAT_DEPTH(type)]);
1068 CV_ERROR( CV_StsUnsupportedFormat, "" );
1070 CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 ));
1074 IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
1075 iterator.ptr[1], CV_STUB_STEP,
1076 iterator.size, buf ));
1078 while( cvNextNArraySlice( &iterator ));
1082 if( !CV_ARE_TYPES_EQ( src, dst ))
1083 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
1085 if( !CV_ARE_SIZES_EQ( src, dst ))
1086 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
1088 sctype = type = CV_MAT_TYPE(src->type);
1089 depth = CV_MAT_DEPTH(type);
1090 cn = CV_MAT_CN(type);
1091 if( depth < CV_32S )
1092 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;
1094 size = cvGetMatSize( src );
1098 if( CV_IS_MAT_CONT( src->type & dst->type ))
1100 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE )
1102 int len = size.width * size.height;
1104 if( type == CV_32FC1 )
1106 const float* srcdata = (const float*)(src->data.ptr);
1107 float* dstdata = (float*)(dst->data.ptr);
1111 dstdata[len-1] = (float)(scalar.val[0] + srcdata[len-1]);
1118 if( type == CV_64FC1 )
1120 const double* srcdata = (const double*)(src->data.ptr);
1121 double* dstdata = (double*)(dst->data.ptr);
1125 dstdata[len-1] = scalar.val[0] + srcdata[len-1];
1141 int buf_size, elem_size;
1143 if( !CV_IS_MAT(mask) )
1144 CV_CALL( mask = cvGetMat( mask, &maskstub ));
1146 if( !CV_IS_MASK_ARR(mask))
1147 CV_ERROR( CV_StsBadMask, "" );
1149 if( !CV_ARE_SIZES_EQ( mask, dst ))
1150 CV_ERROR( CV_StsUnmatchedSizes, "" );
1152 cont_flag = CV_IS_MAT_CONT( src->type & dst->type & mask->type );
1153 elem_size = CV_ELEM_SIZE(type);
1155 dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
1157 dy = MIN(dy,size.height);
1158 dstbuf = cvMat( dy, size.width, type );
1160 dstbuf.step = cvAlign( dstbuf.step, 8 );
1161 buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
1162 if( buf_size > CV_MAX_LOCAL_SIZE )
1164 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
1168 buffer = (uchar*)cvStackAlloc( buf_size );
1169 dstbuf.data.ptr = buffer;
1172 copym_func = icvGetCopyMaskFunc( elem_size );
1175 func = (CvFunc2D_2A1P)(add_tab.fn_2d[depth]);
1177 CV_ERROR( CV_StsUnsupportedFormat, "" );
1179 src_step = src->step;
1180 dst_step = dst->step;
1181 tdst_step = tdst->step;
1182 mask_step = mask ? mask->step : 0;
1184 CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 ));
1186 for( y = 0; y < size.height; y += dy )
1188 tsize.width = size.width;
1190 if( y + dy > size.height )
1191 tsize.height = size.height - y;
1192 if( cont_flag || tsize.height == 1 )
1194 tsize.width *= tsize.height;
1196 src_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
1199 IPPI_CALL( func( src->data.ptr + y*src->step, src_step,
1200 tdst->data.ptr, tdst_step,
1201 cvSize( tsize.width*cn, tsize.height ), buf ));
1204 IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
1205 dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
1216 /***************************************** M U L ****************************************/
1218 #define ICV_DEF_MUL_OP_CASE( flavor, arrtype, worktype, _cast_macro1_, \
1219 _cast_macro2_, _cvt_macro_ ) \
1220 static CvStatus CV_STDCALL \
1221 icvMul_##flavor##_C1R( const arrtype* src1, int step1, \
1222 const arrtype* src2, int step2, \
1223 arrtype* dst, int step, \
1224 CvSize size, double scale ) \
1226 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); step /= sizeof(dst[0]); \
1228 if( fabs(scale - 1.) < DBL_EPSILON ) \
1230 for( ; size.height--; src1+=step1, src2+=step2, dst+=step ) \
1233 for( i = 0; i <= size.width - 4; i += 4 ) \
1235 worktype t0 = src1[i] * src2[i]; \
1236 worktype t1 = src1[i+1] * src2[i+1]; \
1238 dst[i] = _cast_macro2_(t0); \
1239 dst[i+1] = _cast_macro2_(t1); \
1241 t0 = src1[i+2] * src2[i+2]; \
1242 t1 = src1[i+3] * src2[i+3]; \
1244 dst[i+2] = _cast_macro2_(t0); \
1245 dst[i+3] = _cast_macro2_(t1); \
1248 for( ; i < size.width; i++ ) \
1250 worktype t0 = src1[i] * src2[i]; \
1251 dst[i] = _cast_macro2_(t0); \
1257 for( ; size.height--; src1+=step1, src2+=step2, dst+=step ) \
1260 for( i = 0; i <= size.width - 4; i += 4 ) \
1262 double ft0 = scale*_cvt_macro_(src1[i])*_cvt_macro_(src2[i]); \
1263 double ft1 = scale*_cvt_macro_(src1[i+1])*_cvt_macro_(src2[i+1]); \
1264 worktype t0 = _cast_macro1_(ft0); \
1265 worktype t1 = _cast_macro1_(ft1); \
1267 dst[i] = _cast_macro2_(t0); \
1268 dst[i+1] = _cast_macro2_(t1); \
1270 ft0 = scale*_cvt_macro_(src1[i+2])*_cvt_macro_(src2[i+2]); \
1271 ft1 = scale*_cvt_macro_(src1[i+3])*_cvt_macro_(src2[i+3]); \
1272 t0 = _cast_macro1_(ft0); \
1273 t1 = _cast_macro1_(ft1); \
1275 dst[i+2] = _cast_macro2_(t0); \
1276 dst[i+3] = _cast_macro2_(t1); \
1279 for( ; i < size.width; i++ ) \
1282 t0 = _cast_macro1_(scale*_cvt_macro_(src1[i])*_cvt_macro_(src2[i])); \
1283 dst[i] = _cast_macro2_(t0); \
1292 ICV_DEF_MUL_OP_CASE( 8u, uchar, int, cvRound, CV_CAST_8U, CV_8TO32F )
1293 ICV_DEF_MUL_OP_CASE( 16u, ushort, int, cvRound, CV_CAST_16U, CV_NOP )
1294 ICV_DEF_MUL_OP_CASE( 16s, short, int, cvRound, CV_CAST_16S, CV_NOP )
1295 ICV_DEF_MUL_OP_CASE( 32s, int, int, cvRound, CV_CAST_32S, CV_NOP )
1296 ICV_DEF_MUL_OP_CASE( 32f, float, double, CV_NOP, CV_CAST_32F, CV_NOP )
1297 ICV_DEF_MUL_OP_CASE( 64f, double, double, CV_NOP, CV_CAST_64F, CV_NOP )
1300 ICV_DEF_INIT_ARITHM_FUNC_TAB( Mul, C1R )
1303 typedef CvStatus (CV_STDCALL * CvScaledElWiseFunc)( const void* src1, int step1,
1304 const void* src2, int step2,
1305 void* dst, int step,
1306 CvSize size, double scale );
1309 cvMul( const void* srcarr1, const void* srcarr2, void* dstarr, double scale )
1311 static CvFuncTable mul_tab;
1312 static int inittab = 0;
1314 CV_FUNCNAME( "cvMul" );
1318 int type, depth, coi = 0;
1319 int src1_step, src2_step, dst_step;
1321 CvMat srcstub1, *src1 = (CvMat*)srcarr1;
1322 CvMat srcstub2, *src2 = (CvMat*)srcarr2;
1323 CvMat dststub, *dst = (CvMat*)dstarr;
1325 CvScaledElWiseFunc func;
1329 icvInitMulC1RTable( &mul_tab );
1333 if( !CV_IS_MAT(src1) )
1335 if( CV_IS_MATND(src1) )
1339 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi ));
1341 CV_ERROR( CV_BadCOI, "" );
1345 if( !CV_IS_MAT(src2) )
1347 if( CV_IS_MATND(src2) )
1351 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi ));
1353 CV_ERROR( CV_BadCOI, "" );
1357 if( !CV_IS_MAT(dst) )
1359 if( CV_IS_MATND(dst) )
1363 CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
1365 CV_ERROR( CV_BadCOI, "" );
1371 CvArr* arrs[] = { src1, src2, dst };
1373 CvNArrayIterator iterator;
1375 CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
1377 type = iterator.hdr[0]->type;
1378 iterator.size.width *= CV_MAT_CN(type);
1380 func = (CvScaledElWiseFunc)(mul_tab.fn_2d[CV_MAT_DEPTH(type)]);
1382 CV_ERROR( CV_StsUnsupportedFormat, "" );
1386 IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
1387 iterator.ptr[1], CV_STUB_STEP,
1388 iterator.ptr[2], CV_STUB_STEP,
1389 iterator.size, scale ));
1391 while( cvNextNArraySlice( &iterator ));
1395 if( !CV_ARE_TYPES_EQ( src1, src2 ) || !CV_ARE_TYPES_EQ( src1, dst ))
1396 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
1398 if( !CV_ARE_SIZES_EQ( src1, src2 ) || !CV_ARE_SIZES_EQ( src1, dst ))
1399 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
1401 type = CV_MAT_TYPE(src1->type);
1402 size = cvGetMatSize( src1 );
1404 depth = CV_MAT_DEPTH(type);
1405 size.width *= CV_MAT_CN( type );
1407 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type ))
1409 size.width *= size.height;
1411 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE && scale == 1 )
1413 if( depth == CV_32F )
1415 const float* src1data = (const float*)(src1->data.ptr);
1416 const float* src2data = (const float*)(src2->data.ptr);
1417 float* dstdata = (float*)(dst->data.ptr);
1421 dstdata[size.width-1] = (float)
1422 (src1data[size.width-1] * src2data[size.width-1]);
1424 while( --size.width );
1429 if( depth == CV_64F )
1431 const double* src1data = (const double*)(src1->data.ptr);
1432 const double* src2data = (const double*)(src2->data.ptr);
1433 double* dstdata = (double*)(dst->data.ptr);
1437 dstdata[size.width-1] =
1438 src1data[size.width-1] * src2data[size.width-1];
1440 while( --size.width );
1446 src1_step = src2_step = dst_step = CV_STUB_STEP;
1451 src1_step = src1->step;
1452 src2_step = src2->step;
1453 dst_step = dst->step;
1456 func = (CvScaledElWiseFunc)(mul_tab.fn_2d[CV_MAT_DEPTH(type)]);
1459 CV_ERROR( CV_StsUnsupportedFormat, "" );
1461 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step,
1462 dst->data.ptr, dst_step, size, scale ));
1468 /***************************************** D I V ****************************************/
1470 #define ICV_DEF_DIV_OP_CASE( flavor, arrtype, worktype, checktype, _start_row_macro_, \
1471 _cast_macro1_, _cast_macro2_, _cvt_macro_, _check_macro_, isrc ) \
1473 static CvStatus CV_STDCALL \
1474 icvDiv_##flavor##_C1R( const arrtype* src1, int step1, \
1475 const arrtype* src2, int step2, \
1476 arrtype* dst, int step, \
1477 CvSize size, double scale ) \
1479 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); step /= sizeof(dst[0]); \
1481 for( ; size.height--; src1+=step1, src2+=step2, dst+=step ) \
1483 _start_row_macro_(checktype, src2); \
1484 for( i = 0; i <= size.width - 4; i += 4 ) \
1486 if( _check_macro_(isrc[i]) && _check_macro_(isrc[i+1]) && \
1487 _check_macro_(isrc[i+2]) && _check_macro_(isrc[i+3])) \
1489 double a = (double)_cvt_macro_(src2[i]) * _cvt_macro_(src2[i+1]); \
1490 double b = (double)_cvt_macro_(src2[i+2]) * _cvt_macro_(src2[i+3]); \
1491 double d = scale/(a * b); \
1496 worktype z0 = _cast_macro1_(src2[i+1] * _cvt_macro_(src1[i]) * b); \
1497 worktype z1 = _cast_macro1_(src2[i] * _cvt_macro_(src1[i+1]) * b); \
1498 worktype z2 = _cast_macro1_(src2[i+3] * _cvt_macro_(src1[i+2]) * a); \
1499 worktype z3 = _cast_macro1_(src2[i+2] * _cvt_macro_(src1[i+3]) * a); \
1501 dst[i] = _cast_macro2_(z0); \
1502 dst[i+1] = _cast_macro2_(z1); \
1503 dst[i+2] = _cast_macro2_(z2); \
1504 dst[i+3] = _cast_macro2_(z3); \
1508 worktype z0 = _check_macro_(isrc[i]) ? \
1509 _cast_macro1_(_cvt_macro_(src1[i])*scale/_cvt_macro_(src2[i])) : 0; \
1510 worktype z1 = _check_macro_(isrc[i+1]) ? \
1511 _cast_macro1_(_cvt_macro_(src1[i+1])*scale/_cvt_macro_(src2[i+1])):0;\
1512 worktype z2 = _check_macro_(isrc[i+2]) ? \
1513 _cast_macro1_(_cvt_macro_(src1[i+2])*scale/_cvt_macro_(src2[i+2])):0;\
1514 worktype z3 = _check_macro_(isrc[i+3]) ? \
1515 _cast_macro1_(_cvt_macro_(src1[i+3])*scale/_cvt_macro_(src2[i+3])):0;\
1517 dst[i] = _cast_macro2_(z0); \
1518 dst[i+1] = _cast_macro2_(z1); \
1519 dst[i+2] = _cast_macro2_(z2); \
1520 dst[i+3] = _cast_macro2_(z3); \
1524 for( ; i < size.width; i++ ) \
1526 worktype z0 = _check_macro_(isrc[i]) ? \
1527 _cast_macro1_(_cvt_macro_(src1[i])*scale/_cvt_macro_(src2[i])) : 0; \
1528 dst[i] = _cast_macro2_(z0); \
1536 #define ICV_DEF_RECIP_OP_CASE( flavor, arrtype, worktype, checktype, \
1537 _start_row_macro_, _cast_macro1_, _cast_macro2_, \
1538 _cvt_macro_, _check_macro_, isrc ) \
1540 static CvStatus CV_STDCALL \
1541 icvRecip_##flavor##_C1R( const arrtype* src, int step1, \
1542 arrtype* dst, int step, \
1543 CvSize size, double scale ) \
1545 step1 /= sizeof(src[0]); step /= sizeof(dst[0]); \
1547 for( ; size.height--; src+=step1, dst+=step ) \
1549 _start_row_macro_(checktype, src); \
1550 for( i = 0; i <= size.width - 4; i += 4 ) \
1552 if( _check_macro_(isrc[i]) && _check_macro_(isrc[i+1]) && \
1553 _check_macro_(isrc[i+2]) && _check_macro_(isrc[i+3])) \
1555 double a = (double)_cvt_macro_(src[i]) * _cvt_macro_(src[i+1]); \
1556 double b = (double)_cvt_macro_(src[i+2]) * _cvt_macro_(src[i+3]);\
1557 double d = scale/(a * b); \
1562 worktype z0 = _cast_macro1_(src[i+1] * b); \
1563 worktype z1 = _cast_macro1_(src[i] * b); \
1564 worktype z2 = _cast_macro1_(src[i+3] * a); \
1565 worktype z3 = _cast_macro1_(src[i+2] * a); \
1567 dst[i] = _cast_macro2_(z0); \
1568 dst[i+1] = _cast_macro2_(z1); \
1569 dst[i+2] = _cast_macro2_(z2); \
1570 dst[i+3] = _cast_macro2_(z3); \
1574 worktype z0 = _check_macro_(isrc[i]) ? \
1575 _cast_macro1_(scale/_cvt_macro_(src[i])) : 0; \
1576 worktype z1 = _check_macro_(isrc[i+1]) ? \
1577 _cast_macro1_(scale/_cvt_macro_(src[i+1])):0; \
1578 worktype z2 = _check_macro_(isrc[i+2]) ? \
1579 _cast_macro1_(scale/_cvt_macro_(src[i+2])):0; \
1580 worktype z3 = _check_macro_(isrc[i+3]) ? \
1581 _cast_macro1_(scale/_cvt_macro_(src[i+3])):0; \
1583 dst[i] = _cast_macro2_(z0); \
1584 dst[i+1] = _cast_macro2_(z1); \
1585 dst[i+2] = _cast_macro2_(z2); \
1586 dst[i+3] = _cast_macro2_(z3); \
1590 for( ; i < size.width; i++ ) \
1592 worktype z0 = _check_macro_(isrc[i]) ? \
1593 _cast_macro1_(scale/_cvt_macro_(src[i])) : 0; \
1594 dst[i] = _cast_macro2_(z0); \
1602 #define div_start_row_int(checktype, divisor) \
1605 #define div_start_row_flt(checktype, divisor) \
1606 const checktype* isrc = (const checktype*)divisor; int i
1608 #define div_check_zero_flt(x) (((x) & 0x7fffffff) != 0)
1609 #define div_check_zero_dbl(x) (((x) & CV_BIG_INT(0x7fffffffffffffff)) != 0)
1611 #if defined WIN64 && defined EM64T && defined _MSC_VER && !defined CV_ICC
1612 #pragma optimize("",off)
1615 ICV_DEF_DIV_OP_CASE( 8u, uchar, int, uchar, div_start_row_int,
1616 cvRound, CV_CAST_8U, CV_8TO32F, CV_NONZERO, src2 )
1618 #if defined WIN64 && defined EM64T && defined _MSC_VER && !defined CV_ICC
1619 #pragma optimize("",on)
1623 ICV_DEF_DIV_OP_CASE( 16u, ushort, int, ushort, div_start_row_int,
1624 cvRound, CV_CAST_16U, CV_CAST_64F, CV_NONZERO, src2 )
1625 ICV_DEF_DIV_OP_CASE( 16s, short, int, short, div_start_row_int,
1626 cvRound, CV_CAST_16S, CV_NOP, CV_NONZERO, src2 )
1627 ICV_DEF_DIV_OP_CASE( 32s, int, int, int, div_start_row_int,
1628 cvRound, CV_CAST_32S, CV_CAST_64F, CV_NONZERO, src2 )
1629 ICV_DEF_DIV_OP_CASE( 32f, float, double, int, div_start_row_flt,
1630 CV_NOP, CV_CAST_32F, CV_NOP, div_check_zero_flt, isrc )
1631 ICV_DEF_DIV_OP_CASE( 64f, double, double, int64, div_start_row_flt,
1632 CV_NOP, CV_CAST_64F, CV_NOP, div_check_zero_dbl, isrc )
1634 ICV_DEF_RECIP_OP_CASE( 8u, uchar, int, uchar, div_start_row_int,
1635 cvRound, CV_CAST_8U, CV_8TO32F, CV_NONZERO, src )
1636 ICV_DEF_RECIP_OP_CASE( 16u, ushort, int, ushort, div_start_row_int,
1637 cvRound, CV_CAST_16U, CV_CAST_64F, CV_NONZERO, src )
1638 ICV_DEF_RECIP_OP_CASE( 16s, short, int, short, div_start_row_int,
1639 cvRound, CV_CAST_16S, CV_NOP, CV_NONZERO, src )
1640 ICV_DEF_RECIP_OP_CASE( 32s, int, int, int, div_start_row_int,
1641 cvRound, CV_CAST_32S, CV_CAST_64F, CV_NONZERO, src )
1642 ICV_DEF_RECIP_OP_CASE( 32f, float, double, int, div_start_row_flt,
1643 CV_NOP, CV_CAST_32F, CV_NOP, div_check_zero_flt, isrc )
1644 ICV_DEF_RECIP_OP_CASE( 64f, double, double, int64, div_start_row_flt,
1645 CV_NOP, CV_CAST_64F, CV_NOP, div_check_zero_dbl, isrc )
1647 ICV_DEF_INIT_ARITHM_FUNC_TAB( Div, C1R )
1648 ICV_DEF_INIT_ARITHM_FUNC_TAB( Recip, C1R )
1650 typedef CvStatus (CV_STDCALL * CvRecipFunc)( const void* src, int step1,
1651 void* dst, int step,
1652 CvSize size, double scale );
1655 cvDiv( const void* srcarr1, const void* srcarr2, void* dstarr, double scale )
1657 static CvFuncTable div_tab;
1658 static CvFuncTable recip_tab;
1659 static int inittab = 0;
1661 CV_FUNCNAME( "cvDiv" );
1667 int src1_step, src2_step, dst_step;
1668 int src1_cont_flag = CV_MAT_CONT_FLAG;
1669 CvMat srcstub1, *src1 = (CvMat*)srcarr1;
1670 CvMat srcstub2, *src2 = (CvMat*)srcarr2;
1671 CvMat dststub, *dst = (CvMat*)dstarr;
1676 icvInitDivC1RTable( &div_tab );
1677 icvInitRecipC1RTable( &recip_tab );
1681 if( !CV_IS_MAT(src2) )
1683 if( CV_IS_MATND(src2))
1687 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi ));
1689 CV_ERROR( CV_BadCOI, "" );
1695 if( CV_IS_MATND(src1))
1699 if( !CV_IS_MAT(src1) )
1701 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi ));
1703 CV_ERROR( CV_BadCOI, "" );
1706 if( !CV_ARE_TYPES_EQ( src1, src2 ))
1707 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
1709 if( !CV_ARE_SIZES_EQ( src1, src2 ))
1710 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
1711 src1_cont_flag = src1->type;
1715 if( !CV_IS_MAT(dst) )
1717 if( CV_IS_MATND(dst))
1721 CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
1723 CV_ERROR( CV_BadCOI, "" );
1729 CvArr* arrs[] = { dst, src2, src1 };
1731 CvNArrayIterator iterator;
1733 CV_CALL( cvInitNArrayIterator( 2 + (src1 != 0), arrs, 0, stubs, &iterator ));
1735 type = iterator.hdr[0]->type;
1736 iterator.size.width *= CV_MAT_CN(type);
1740 CvScaledElWiseFunc func =
1741 (CvScaledElWiseFunc)(div_tab.fn_2d[CV_MAT_DEPTH(type)]);
1743 CV_ERROR( CV_StsUnsupportedFormat, "" );
1747 IPPI_CALL( func( iterator.ptr[2], CV_STUB_STEP,
1748 iterator.ptr[1], CV_STUB_STEP,
1749 iterator.ptr[0], CV_STUB_STEP,
1750 iterator.size, scale ));
1752 while( cvNextNArraySlice( &iterator ));
1756 CvRecipFunc func = (CvRecipFunc)(recip_tab.fn_2d[CV_MAT_DEPTH(type)]);
1759 CV_ERROR( CV_StsUnsupportedFormat, "" );
1763 IPPI_CALL( func( iterator.ptr[1], CV_STUB_STEP,
1764 iterator.ptr[0], CV_STUB_STEP,
1765 iterator.size, scale ));
1767 while( cvNextNArraySlice( &iterator ));
1772 if( !CV_ARE_TYPES_EQ( src2, dst ))
1773 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
1775 if( !CV_ARE_SIZES_EQ( src2, dst ))
1776 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
1778 type = CV_MAT_TYPE(src2->type);
1779 size = cvGetMatSize( src2 );
1780 size.width *= CV_MAT_CN( type );
1782 if( CV_IS_MAT_CONT( src1_cont_flag & src2->type & dst->type ))
1784 size.width *= size.height;
1785 src1_step = src2_step = dst_step = CV_STUB_STEP;
1790 src1_step = src1 ? src1->step : 0;
1791 src2_step = src2->step;
1792 dst_step = dst->step;
1797 CvScaledElWiseFunc func = (CvScaledElWiseFunc)(div_tab.fn_2d[CV_MAT_DEPTH(type)]);
1800 CV_ERROR( CV_StsUnsupportedFormat, "" );
1802 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step,
1803 dst->data.ptr, dst_step, size, scale ));
1807 CvRecipFunc func = (CvRecipFunc)(recip_tab.fn_2d[CV_MAT_DEPTH(type)]);
1810 CV_ERROR( CV_StsUnsupportedFormat, "" );
1812 IPPI_CALL( func( src2->data.ptr, src2_step,
1813 dst->data.ptr, dst_step, size, scale ));
1819 /******************************* A D D W E I G T E D ******************************/
1821 #define ICV_DEF_ADD_WEIGHTED_OP(flavor, arrtype, worktype, load_macro, \
1822 cast_macro1, cast_macro2) \
1823 static CvStatus CV_STDCALL \
1824 icvAddWeighted_##flavor##_C1R( const arrtype* src1, int step1, double alpha, \
1825 const arrtype* src2, int step2, double beta, \
1826 double gamma, arrtype* dst, int step, CvSize size )\
1828 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); step /= sizeof(dst[0]); \
1830 for( ; size.height--; src1 += step1, src2 += step2, dst += step ) \
1834 for( i = 0; i <= size.width - 4; i += 4 ) \
1836 worktype t0 = cast_macro1(load_macro((src1)[i])*alpha + \
1837 load_macro((src2)[i])*beta + gamma); \
1838 worktype t1 = cast_macro1(load_macro((src1)[i+1])*alpha + \
1839 load_macro((src2)[i+1])*beta + gamma); \
1841 (dst)[i] = cast_macro2( t0 ); \
1842 (dst)[i+1] = cast_macro2( t1 ); \
1844 t0 = cast_macro1(load_macro((src1)[i+2])*alpha + \
1845 load_macro((src2)[i+2])*beta + gamma); \
1846 t1 = cast_macro1(load_macro((src1)[i+3])*alpha + \
1847 load_macro((src2)[i+3])*beta + gamma); \
1849 (dst)[i+2] = cast_macro2( t0 ); \
1850 (dst)[i+3] = cast_macro2( t1 ); \
1853 for( ; i < size.width; i++ ) \
1855 worktype t0 = cast_macro1(load_macro((src1)[i])*alpha + \
1856 load_macro((src2)[i])*beta + gamma); \
1857 (dst)[i] = cast_macro2( t0 ); \
1868 static CvStatus CV_STDCALL
1869 icvAddWeighted_8u_fast_C1R( const uchar* src1, int step1, double alpha,
1870 const uchar* src2, int step2, double beta,
1871 double gamma, uchar* dst, int step, CvSize size )
1873 int tab1[256], tab2[256];
1875 int j, t0, t1, t2, t3;
1877 alpha *= 1 << shift;
1878 gamma = gamma*(1 << shift) + (1 << (shift - 1));
1881 for( j = 0; j < 256; j++ )
1883 tab1[j] = cvRound(t);
1884 tab2[j] = cvRound(gamma);
1889 t0 = (tab1[0] + tab2[0]) >> shift;
1890 t1 = (tab1[0] + tab2[255]) >> shift;
1891 t2 = (tab1[255] + tab2[0]) >> shift;
1892 t3 = (tab1[255] + tab2[255]) >> shift;
1894 if( (unsigned)(t0+256) < 768 && (unsigned)(t1+256) < 768 &&
1895 (unsigned)(t2+256) < 768 && (unsigned)(t3+256) < 768 )
1897 // use faster table-based convertion back to 8u
1898 for( ; size.height--; src1 += step1, src2 += step2, dst += step )
1902 for( i = 0; i <= size.width - 4; i += 4 )
1904 t0 = CV_FAST_CAST_8U((tab1[src1[i]] + tab2[src2[i]]) >> shift);
1905 t1 = CV_FAST_CAST_8U((tab1[src1[i+1]] + tab2[src2[i+1]]) >> shift);
1908 dst[i+1] = (uchar)t1;
1910 t0 = CV_FAST_CAST_8U((tab1[src1[i+2]] + tab2[src2[i+2]]) >> shift);
1911 t1 = CV_FAST_CAST_8U((tab1[src1[i+3]] + tab2[src2[i+3]]) >> shift);
1913 dst[i+2] = (uchar)t0;
1914 dst[i+3] = (uchar)t1;
1917 for( ; i < size.width; i++ )
1919 t0 = CV_FAST_CAST_8U((tab1[src1[i]] + tab2[src2[i]]) >> shift);
1926 // use universal macro for convertion back to 8u
1927 for( ; size.height--; src1 += step1, src2 += step2, dst += step )
1931 for( i = 0; i <= size.width - 4; i += 4 )
1933 t0 = (tab1[src1[i]] + tab2[src2[i]]) >> shift;
1934 t1 = (tab1[src1[i+1]] + tab2[src2[i+1]]) >> shift;
1936 dst[i] = CV_CAST_8U( t0 );
1937 dst[i+1] = CV_CAST_8U( t1 );
1939 t0 = (tab1[src1[i+2]] + tab2[src2[i+2]]) >> shift;
1940 t1 = (tab1[src1[i+3]] + tab2[src2[i+3]]) >> shift;
1942 dst[i+2] = CV_CAST_8U( t0 );
1943 dst[i+3] = CV_CAST_8U( t1 );
1946 for( ; i < size.width; i++ )
1948 t0 = (tab1[src1[i]] + tab2[src2[i]]) >> shift;
1949 dst[i] = CV_CAST_8U( t0 );
1958 ICV_DEF_ADD_WEIGHTED_OP( 8u, uchar, int, CV_8TO32F, cvRound, CV_CAST_8U )
1959 ICV_DEF_ADD_WEIGHTED_OP( 16u, ushort, int, CV_NOP, cvRound, CV_CAST_16U )
1960 ICV_DEF_ADD_WEIGHTED_OP( 16s, short, int, CV_NOP, cvRound, CV_CAST_16S )
1961 ICV_DEF_ADD_WEIGHTED_OP( 32s, int, int, CV_NOP, cvRound, CV_CAST_32S )
1962 ICV_DEF_ADD_WEIGHTED_OP( 32f, float, double, CV_NOP, CV_NOP, CV_CAST_32F )
1963 ICV_DEF_ADD_WEIGHTED_OP( 64f, double, double, CV_NOP, CV_NOP, CV_CAST_64F )
1966 ICV_DEF_INIT_ARITHM_FUNC_TAB( AddWeighted, C1R )
1968 typedef CvStatus (CV_STDCALL *CvAddWeightedFunc)( const void* src1, int step1, double alpha,
1969 const void* src2, int step2, double beta,
1970 double gamma, void* dst,
1971 int step, CvSize size );
1974 cvAddWeighted( const CvArr* srcAarr, double alpha,
1975 const CvArr* srcBarr, double beta,
1976 double gamma, CvArr* dstarr )
1978 static CvFuncTable addw_tab;
1979 static int inittab = 0;
1981 CV_FUNCNAME( "cvAddWeighted" );
1985 CvMat srcA_stub, *srcA = (CvMat*)srcAarr;
1986 CvMat srcB_stub, *srcB = (CvMat*)srcBarr;
1987 CvMat dst_stub, *dst = (CvMat*)dstarr;
1988 int coi1, coi2, coi;
1989 int srcA_step, srcB_step, dst_step;
1991 CvAddWeightedFunc func;
1996 icvInitAddWeightedC1RTable( &addw_tab );
2000 CV_CALL( srcA = cvGetMat( srcA, &srcA_stub, &coi1 ));
2001 CV_CALL( srcB = cvGetMat( srcB, &srcB_stub, &coi2 ));
2002 CV_CALL( dst = cvGetMat( dst, &dst_stub, &coi ));
2004 if( coi1 || coi2 || coi )
2005 CV_ERROR( CV_BadCOI, "COI must not be set" );
2007 if( !CV_ARE_TYPES_EQ( srcA, srcB ) ||
2008 !CV_ARE_TYPES_EQ( srcA, dst ))
2009 CV_ERROR( CV_StsUnmatchedFormats,
2010 "All input/output arrays should have the same type");
2012 if( !CV_ARE_SIZES_EQ( srcA, srcB ) ||
2013 !CV_ARE_SIZES_EQ( srcA, dst ))
2014 CV_ERROR( CV_StsUnmatchedSizes,
2015 "All input/output arrays should have the same sizes");
2017 size = cvGetMatSize( srcA );
2018 type = CV_MAT_TYPE( srcA->type );
2019 size.width *= CV_MAT_CN( type );
2020 srcA_step = srcA->step;
2021 srcB_step = srcB->step;
2022 dst_step = dst->step;
2024 if( CV_IS_MAT_CONT( type & srcB->type & dst->type ))
2026 size.width *= size.height;
2028 srcA_step = srcB_step = dst_step = CV_AUTOSTEP;
2031 if( type == CV_8UC1 && size.width * size.height >= 1024 &&
2032 fabs(alpha) < 256 && fabs(beta) < 256 && fabs(gamma) < 256*256 )
2034 func = (CvAddWeightedFunc)icvAddWeighted_8u_fast_C1R;
2038 func = (CvAddWeightedFunc)addw_tab.fn_2d[CV_MAT_DEPTH(type)];
2040 CV_ERROR( CV_StsUnsupportedFormat, "This array type is not supported" );
2043 IPPI_CALL( func( srcA->data.ptr, srcA_step, alpha, srcB->data.ptr, srcB_step,
2044 beta, gamma, dst->data.ptr, dst_step, size ));