CV_IMPL CvScalar cvSum( const CvArr* arr ) { static CvBigFuncTable sum_tab; static CvFuncTable sumcoi_tab; static int inittab = 0; CvScalar sum = {{0,0,0,0}}; CV_FUNCNAME("cvSum"); __BEGIN__; int type, coi = 0; int mat_step; CvSize size; CvMat stub, *mat = (CvMat*)arr; if( !inittab ) { icvInitSumRTable( &sum_tab ); icvInitSumCnCRTable( &sumcoi_tab ); inittab = 1; } if( !CV_IS_MAT(mat) ) { if( CV_IS_MATND(mat) ) { void* matnd = (void*)mat; CvMatND nstub; CvNArrayIterator iterator; int pass_hint; CV_CALL( cvInitNArrayIterator( 1, &matnd, 0, &nstub, &iterator )); type = CV_MAT_TYPE(iterator.hdr[0]->type); if( CV_MAT_CN(type) > 4 ) CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels" ); pass_hint = CV_MAT_DEPTH(type) == CV_32F; if( !pass_hint ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { CvScalar temp = {{0,0,0,0}}; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, temp.val )); sum.val[0] += temp.val[0]; sum.val[1] += temp.val[1]; sum.val[2] += temp.val[2]; sum.val[3] += temp.val[3]; } while( cvNextNArraySlice( &iterator )); } else { CvFunc2D_1A1P1I func = (CvFunc2D_1A1P1I)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { CvScalar temp = {{0,0,0,0}}; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, temp.val, cvAlgHintAccurate )); sum.val[0] += temp.val[0]; sum.val[1] += temp.val[1]; sum.val[2] += temp.val[2]; sum.val[3] += temp.val[3]; } while( cvNextNArraySlice( &iterator )); } EXIT; } else CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_MAT_TYPE(mat->type); size = cvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_MAT_CONT( mat->type )) { size.width *= size.height; if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE ) { if( type == CV_32FC1 ) { float* data = mat->data.fl; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } if( type == CV_64FC1 ) { double* data = mat->data.db; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } } size.height = 1; mat_step = CV_STUB_STEP; } if( CV_MAT_CN(type) == 1 || coi == 0 ) { int pass_hint = CV_MAT_DEPTH(type) == CV_32F; if( CV_MAT_CN(type) > 4 ) CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels" ); if( !pass_hint ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, sum.val )); } else { CvFunc2D_1A1P1I func = (CvFunc2D_1A1P1I)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, sum.val, cvAlgHintAccurate )); } } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(sumcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_MAT_CN(type), coi, sum.val )); } __END__; return sum; }
CV_IMPL CvScalar cvSum( const CvArr* arr ) { static CvBigFuncTable sum_tab; static CvFuncTable sumcoi_tab; static int inittab = 0; CvScalar sum = {{ 0, 0, 0, 0 }}; CV_FUNCNAME("cvSum"); __BEGIN__; int type, coi = 0; int mat_step; CvSize size; CvMat stub, *mat = (CvMat*)arr; if( !inittab ) { icvInitSumRTable( &sum_tab ); icvInitSumCnCRTable( &sumcoi_tab ); inittab = 1; } if( !CV_IS_ARR(mat) ) { CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_ARR_TYPE(mat->type); size = icvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_ARR_CONT( mat->type )) { size.width *= size.height; if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE ) { if( type == CV_32FC1 ) { float* data = mat->data.fl; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } if( type == CV_64FC1 ) { double* data = mat->data.db; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } } size.height = 1; mat_step = CV_STUB_STEP; } if( CV_ARR_CN(type) == 1 || coi == 0 ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, icvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, sum.val )); } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(sumcoi_tab.fn_2d[CV_ARR_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, icvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_ARR_CN(type), coi, sum.val )); } __END__; return sum; }