diff --git a/hal/ipp/CMakeLists.txt b/hal/ipp/CMakeLists.txt index c80e76bfed..bf57db6f8e 100644 --- a/hal/ipp/CMakeLists.txt +++ b/hal/ipp/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(ipphal STATIC "${CMAKE_CURRENT_SOURCE_DIR}/src/norm_ipp.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/cart_polar_ipp.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/transforms_ipp.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/src/sum_ipp.cpp" ) #TODO: HAVE_IPP_ICV and HAVE_IPP_IW added as private macro till OpenCV itself is diff --git a/hal/ipp/include/ipp_hal_core.hpp b/hal/ipp/include/ipp_hal_core.hpp index 6707db7290..10c2477413 100644 --- a/hal/ipp/include/ipp_hal_core.hpp +++ b/hal/ipp/include/ipp_hal_core.hpp @@ -32,6 +32,11 @@ int ipp_hal_normDiff(const uchar* src1, size_t src1_step, const uchar* src2, siz #undef cv_hal_normDiff #define cv_hal_normDiff ipp_hal_normDiff +int ipp_hal_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result); + +#undef cv_hal_sum +#define cv_hal_sum ipp_hal_sum + #endif int ipp_hal_polarToCart32f(const float* mag, const float* angle, float* x, float* y, int len, bool angleInDegrees); @@ -56,4 +61,6 @@ int ipp_hal_transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data, #undef cv_hal_transpose2d #define cv_hal_transpose2d ipp_hal_transpose2d +//! @endcond + #endif diff --git a/hal/ipp/src/sum_ipp.cpp b/hal/ipp/src/sum_ipp.cpp new file mode 100644 index 0000000000..8603347986 --- /dev/null +++ b/hal/ipp/src/sum_ipp.cpp @@ -0,0 +1,55 @@ +#include "ipp_hal_core.hpp" + +#include +#include + +#if IPP_VERSION_X100 >= 700 + +int ipp_hal_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result) +{ + int cn = CV_MAT_CN(src_type); + if (cn > 4) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + IppiSize sz = { width, height }; + + typedef IppStatus (CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm); + typedef IppStatus (CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *); + ippiSumFuncHint ippiSumHint = + src_type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R : + src_type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R : + src_type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R : + 0; + ippiSumFuncNoHint ippiSum = + src_type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R : + src_type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R : + src_type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R : + src_type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R : + src_type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R : + src_type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R : + src_type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R : + src_type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R : + src_type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R : + 0; + + if( ippiSumHint || ippiSum ) + { + IppStatus ret = ippiSumHint ? + CV_INSTRUMENT_FUN_IPP(ippiSumHint, src_data, (int)src_step, sz, result, ippAlgHintAccurate) : + CV_INSTRUMENT_FUN_IPP(ippiSum, src_data, (int)src_step, sz, result); + if( ret >= 0 ) + { + return CV_HAL_ERROR_OK; + } + else + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + } + + return CV_HAL_ERROR_NOT_IMPLEMENTED; +} + +#endif diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp index 8e566174f8..c48f1163bb 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -1123,8 +1123,22 @@ inline int hal_ni_copyToMasked(const uchar* src_data, size_t src_step, uchar* ds #define cv_hal_copyToMasked hal_ni_copyToMasked //! @endcond -//! @} +/** + @ brief sum + @param src_data Source image data + @param src_step Source image step + @param src_type Source image type + @param width, height Source image dimensions + @param result Pointer to save the sum result to. + */ +inline int hal_ni_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result) +{ return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @cond IGNORED +#define cv_hal_sum hal_ni_sum +//! @endcond + +//! @} #if defined(__clang__) #pragma clang diagnostic pop diff --git a/modules/core/src/sum.dispatch.cpp b/modules/core/src/sum.dispatch.cpp index fade948336..2d1c23b9b1 100644 --- a/modules/core/src/sum.dispatch.cpp +++ b/modules/core/src/sum.dispatch.cpp @@ -10,14 +10,6 @@ #include "sum.simd.hpp" #include "sum.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content -#ifndef OPENCV_IPP_SUM -#undef HAVE_IPP -#undef CV_IPP_RUN_FAST -#define CV_IPP_RUN_FAST(f, ...) -#undef CV_IPP_RUN -#define CV_IPP_RUN(c, f, ...) -#endif // OPENCV_IPP_SUM - namespace cv { @@ -126,90 +118,42 @@ bool ocl_sum( InputArray _src, Scalar & res, int sum_op, InputArray _mask, #endif -#ifdef HAVE_IPP -static bool ipp_sum(Mat &src, Scalar &_res) -{ - CV_INSTRUMENT_REGION_IPP(); - -#if IPP_VERSION_X100 >= 700 - int cn = src.channels(); - if (cn > 4) - return false; - size_t total_size = src.total(); - int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( src.dims == 2 || (src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) ) - { - IppiSize sz = { cols, rows }; - int type = src.type(); - typedef IppStatus (CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm); - typedef IppStatus (CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *); - ippiSumFuncHint ippiSumHint = - type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R : - type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R : - type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R : - 0; - ippiSumFuncNoHint ippiSum = - type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R : - type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R : - type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R : - type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R : - type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R : - type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R : - type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R : - type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R : - type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R : - 0; - CV_Assert(!ippiSumHint || !ippiSum); - if( ippiSumHint || ippiSum ) - { - Ipp64f res[4]; - IppStatus ret = ippiSumHint ? - CV_INSTRUMENT_FUN_IPP(ippiSumHint, src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) : - CV_INSTRUMENT_FUN_IPP(ippiSum, src.ptr(), (int)src.step[0], sz, res); - if( ret >= 0 ) - { - for( int i = 0; i < cn; i++ ) - _res[i] = res[i]; - return true; - } - } - } -#else - CV_UNUSED(src); CV_UNUSED(_res); -#endif - return false; -} -#endif - Scalar sum(InputArray _src) { CV_INSTRUMENT_REGION(); -#if defined HAVE_OPENCL || defined HAVE_IPP - Scalar _res; -#endif + Scalar _res = Scalar::all(0.0); #ifdef HAVE_OPENCL CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, ocl_sum(_src, _res, OCL_OP_SUM), - _res) + _res); #endif Mat src = _src.getMat(); - CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_sum(src, _res), _res); + int cn = src.channels(); + CV_CheckLE( cn, 4, "cv::sum does not support more than 4 channels" ); - int k, cn = src.channels(), depth = src.depth(); + if (_src.dims() <= 2) + { + CALL_HAL_RET2(sum, cv_hal_sum, _res, src.data, src.step, src.type(), src.cols, src.rows, &_res[0]); + } + else if (_src.isContinuous()) + { + CALL_HAL_RET2(sum, cv_hal_sum, _res, src.data, 0, src.type(), (int)src.total(), 1, &_res[0]); + } + + int k, depth = src.depth(); SumFunc func = getSumFunc(depth); - CV_Assert( cn <= 4 && func != 0 ); + CV_Assert( func != nullptr ); const Mat* arrays[] = {&src, 0}; uchar* ptrs[1] = {}; NAryMatIterator it(arrays, ptrs); - Scalar s; int total = (int)it.size, blockSize = total, intSumBlockSize = 0; int j, count = 0; AutoBuffer _buf; - int* buf = (int*)&s[0]; + int* buf = (int*)&_res[0]; size_t esz = 0; bool blockSum = depth < CV_32S; @@ -236,7 +180,7 @@ Scalar sum(InputArray _src) { for( k = 0; k < cn; k++ ) { - s[k] += buf[k]; + _res[k] += buf[k]; buf[k] = 0; } count = 0; @@ -244,7 +188,7 @@ Scalar sum(InputArray _src) ptrs[0] += bsz*esz; } } - return s; + return _res; } } // namespace