diff --git a/modules/core/src/merge.cpp b/modules/core/src/merge.cpp index 40c716ba12..300a718506 100644 --- a/modules/core/src/merge.cpp +++ b/modules/core/src/merge.cpp @@ -42,7 +42,7 @@ vecmerge_( const T** src, T* dst, int len, int cn ) if( r != 0 ) { mode = hal::STORE_UNALIGNED; - if (r % dstElemSize == 0 && len > VECSZ) + if (r % dstElemSize == 0 && len > VECSZ*2) i0 = VECSZ - (r / dstElemSize); } diff --git a/modules/core/src/split.cpp b/modules/core/src/split.cpp index 78d8daadd0..3fab6874b7 100644 --- a/modules/core/src/split.cpp +++ b/modules/core/src/split.cpp @@ -27,8 +27,8 @@ vecsplit_( const T* src, T** dst, int len, int cn ) if( (r0|r1|r2|r3) != 0 ) { mode = hal::STORE_UNALIGNED; - if( r0 == r1 && r0 == r2 && r0 == r3 && r0 % cn == 0 && len > VECSZ ) - i0 = VECSZ - (r0 / cn); + if( r0 == r1 && r0 == r2 && r0 == r3 && r0 % sizeof(T) == 0 && len > VECSZ*2 ) + i0 = VECSZ - (r0 / sizeof(T)); } if( cn == 2 ) diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 7e20f153c8..9622fa47d4 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1824,4 +1824,62 @@ BIGDATA_TEST(Mat, push_back_regression_4158) // memory usage: ~10.6 Gb } } + +TEST(Core_Merge, hang_12171) +{ + Mat src1(4, 24, CV_8UC1, Scalar::all(1)); + Mat src2(4, 24, CV_8UC1, Scalar::all(2)); + Rect src_roi(0, 0, 23, 4); + Mat src_channels[2] = { src1(src_roi), src2(src_roi) }; + Mat dst(4, 24, CV_8UC2, Scalar::all(5)); + Rect dst_roi(1, 0, 23, 4); + cv::merge(src_channels, 2, dst(dst_roi)); + EXPECT_EQ(5, dst.ptr()[0]); + EXPECT_EQ(5, dst.ptr()[1]); + EXPECT_EQ(1, dst.ptr()[2]); + EXPECT_EQ(2, dst.ptr()[3]); + EXPECT_EQ(5, dst.ptr(1)[0]); + EXPECT_EQ(5, dst.ptr(1)[1]); + EXPECT_EQ(1, dst.ptr(1)[2]); + EXPECT_EQ(2, dst.ptr(1)[3]); +} + +TEST(Core_Split, hang_12171) +{ + Mat src(4, 24, CV_8UC2, Scalar(1,2,3,4)); + Rect src_roi(0, 0, 23, 4); + Mat dst1(4, 24, CV_8UC1, Scalar::all(5)); + Mat dst2(4, 24, CV_8UC1, Scalar::all(10)); + Rect dst_roi(0, 0, 23, 4); + Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) }; + cv::split(src(src_roi), dst); + EXPECT_EQ(1, dst1.ptr()[0]); + EXPECT_EQ(1, dst1.ptr()[1]); + EXPECT_EQ(2, dst2.ptr()[0]); + EXPECT_EQ(2, dst2.ptr()[1]); + EXPECT_EQ(1, dst1.ptr(1)[0]); + EXPECT_EQ(1, dst1.ptr(1)[1]); + EXPECT_EQ(2, dst2.ptr(1)[0]); + EXPECT_EQ(2, dst2.ptr(1)[1]); +} + +TEST(Core_Split, crash_12171) +{ + Mat src(4, 40, CV_8UC2, Scalar(1,2,3,4)); + Rect src_roi(0, 0, 39, 4); + Mat dst1(4, 40, CV_8UC1, Scalar::all(5)); + Mat dst2(4, 40, CV_8UC1, Scalar::all(10)); + Rect dst_roi(0, 0, 39, 4); + Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) }; + cv::split(src(src_roi), dst); + EXPECT_EQ(1, dst1.ptr()[0]); + EXPECT_EQ(1, dst1.ptr()[1]); + EXPECT_EQ(2, dst2.ptr()[0]); + EXPECT_EQ(2, dst2.ptr()[1]); + EXPECT_EQ(1, dst1.ptr(1)[0]); + EXPECT_EQ(1, dst1.ptr(1)[1]); + EXPECT_EQ(2, dst2.ptr(1)[0]); + EXPECT_EQ(2, dst2.ptr(1)[1]); +} + }} // namespace