diff --git a/modules/core/src/norm.cpp b/modules/core/src/norm.cpp index a8d19cb21c..09cd677799 100644 --- a/modules/core/src/norm.cpp +++ b/modules/core/src/norm.cpp @@ -1005,6 +1005,11 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR : 0) : 0; + if (cv::ipp::getIppTopFeatures() & ippCPUID_AVX2) // IPP_DISABLE_NORM_16UC3_mask_small (#11399) + { + if (normType == NORM_L1 && type == CV_16UC3 && sz.width < 16) + return false; + } if( ippiNormDiff_C3CMR ) { Ipp64f norm1, norm2, norm3; diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index 5e80a55c65..6c90c1c857 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -2084,4 +2084,22 @@ TEST(Core_Set, regression_11044) EXPECT_EQ(std::numeric_limits::infinity(), testDouble.at(0, 0)); } +TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small) +{ + int cn = 3; + Size sz(9, 4); // width < 16 + Mat a(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(1)); + Mat b(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(2)); + uchar mask_[9*4] = { + 255, 255, 255, 0, 255, 255, 0, 255, 0, + 0, 255, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 0, 255, 0, 255, 255, + 0, 0, 255, 0, 255, 255, 255, 0, 255 +}; + Mat mask(sz, CV_8UC1, mask_); + + EXPECT_EQ((double)9*4*cn, cv::norm(a, b, NORM_L1)); // without mask, IPP works well + EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask)); +} + }} // namespace