diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 6989d61bd3..4f2882df5a 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3234,34 +3234,110 @@ typedef void (*ReduceFunc)( const Mat& src, Mat& dst ); #define reduceMinR32f reduceR_ > #define reduceMinR64f reduceR_ > +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + +static inline void reduceSumC_8u16u16s32f_64f(const cv::Mat& srcmat, cv::Mat& dstmat) +{ + cv::Size size = srcmat.size(); + IppiSize roisize = { size.width, 1 }; + int sstep = (int)srcmat.step, stype = srcmat.type(), + sdepth = CV_MAT_DEPTH(stype), ddepth = dstmat.depth(); + + typedef IppStatus (CV_STDCALL * ippiSum)(const void * pSrc, int srcStep, IppiSize roiSize, Ipp64f* pSum); + typedef IppStatus (CV_STDCALL * ippiSumHint)(const void * pSrc, int srcStep, IppiSize roiSize, Ipp64f* pSum, IppHintAlgorithm hint); + ippiSum ippFunc = 0; + ippiSumHint ippFuncHint = 0; + cv::ReduceFunc func = 0; + + if (ddepth == CV_64F) + { + ippFunc = + stype == CV_8UC1 ? (ippiSum)ippiSum_8u_C1R : + stype == CV_8UC3 ? (ippiSum)ippiSum_8u_C3R : + stype == CV_8UC4 ? (ippiSum)ippiSum_8u_C4R : + stype == CV_16UC1 ? (ippiSum)ippiSum_16u_C1R : + stype == CV_16UC3 ? (ippiSum)ippiSum_16u_C3R : + stype == CV_16UC4 ? (ippiSum)ippiSum_16u_C4R : + stype == CV_16SC1 ? (ippiSum)ippiSum_16s_C1R : + stype == CV_16SC3 ? (ippiSum)ippiSum_16s_C3R : + stype == CV_16SC4 ? (ippiSum)ippiSum_16s_C4R : 0; + ippFuncHint = + stype == CV_32FC1 ? (ippiSumHint)ippiSum_32f_C1R : + stype == CV_32FC3 ? (ippiSumHint)ippiSum_32f_C3R : + stype == CV_32FC4 ? (ippiSumHint)ippiSum_32f_C4R : 0; + func = + sdepth == CV_8U ? (cv::ReduceFunc)cv::reduceC_ > : + sdepth == CV_16U ? (cv::ReduceFunc)cv::reduceC_ > : + sdepth == CV_16S ? (cv::ReduceFunc)cv::reduceC_ > : + sdepth == CV_32F ? (cv::ReduceFunc)cv::reduceC_ > : 0; + } + CV_Assert(!(ippFunc && ippFuncHint) && func); + + if (ippFunc) + { + for (int y = 0; y < size.height; ++y) + if (ippFunc(srcmat.data + sstep * y, sstep, roisize, dstmat.ptr(y)) < 0) + { + setIppErrorStatus(); + cv::Mat dstroi = dstmat.rowRange(y, y + 1); + func(srcmat.rowRange(y, y + 1), dstroi); + } + return; + } + else if (ippFuncHint) + { + for (int y = 0; y < size.height; ++y) + if (ippFuncHint(srcmat.data + sstep * y, sstep, roisize, dstmat.ptr(y), ippAlgHintAccurate) < 0) + { + setIppErrorStatus(); + cv::Mat dstroi = dstmat.rowRange(y, y + 1); + func(srcmat.rowRange(y, y + 1), dstroi); + } + return; + } + + func(srcmat, dstmat); +} + +#endif + #define reduceSumC8u32s reduceC_ > #define reduceSumC8u32f reduceC_ > -#define reduceSumC8u64f reduceC_ > #define reduceSumC16u32f reduceC_ > -#define reduceSumC16u64f reduceC_ > #define reduceSumC16s32f reduceC_ > -#define reduceSumC16s64f reduceC_ > #define reduceSumC32f32f reduceC_ > -#define reduceSumC32f64f reduceC_ > #define reduceSumC64f64f reduceC_ > +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY +#define reduceSumC8u64f reduceSumC_8u16u16s32f_64f +#define reduceSumC16u64f reduceSumC_8u16u16s32f_64f +#define reduceSumC16s64f reduceSumC_8u16u16s32f_64f +#define reduceSumC32f64f reduceSumC_8u16u16s32f_64f +#else +#define reduceSumC8u64f reduceC_ > +#define reduceSumC16u64f reduceC_ > +#define reduceSumC16s64f reduceC_ > +#define reduceSumC32f64f reduceC_ > +#endif + #if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY #define REDUCE_OP(favor, optype, type1, type2) \ static inline void reduce##optype##C##favor(const cv::Mat& srcmat, cv::Mat& dstmat) \ { \ typedef Ipp##favor IppType; \ cv::Size size = srcmat.size(); \ + IppiSize roisize = ippiSize(size.width, 1);\ + int sstep = (int)srcmat.step; \ + \ if (srcmat.channels() == 1) \ { \ for (int y = 0; y < size.height; ++y) \ - { \ - if (ippi##optype##_##favor##_C1R(srcmat.ptr(y), (int)srcmat.step, \ - ippiSize(size.width, 1), dstmat.ptr(y)) < 0) \ + if (ippi##optype##_##favor##_C1R(srcmat.ptr(y), sstep, roisize, dstmat.ptr(y)) < 0) \ { \ + setIppErrorStatus(); \ cv::Mat dstroi = dstmat.rowRange(y, y + 1); \ cv::reduceC_ < type1, type2, cv::Op##optype < type2 > >(srcmat.rowRange(y, y + 1), dstroi); \ } \ - } \ return; \ } \ cv::reduceC_ < type1, type2, cv::Op##optype < type2 > >(srcmat, dstmat); \