From 50595239371def45aafd35540ed747caad5006e9 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 8 Nov 2018 18:42:53 +0300 Subject: [PATCH] core: fix processing of vector-rows --- modules/core/src/arithm.cpp | 6 ++++++ modules/core/src/convert.cpp | 5 ++++- modules/core/src/convert_scale.cpp | 2 ++ modules/core/src/copy.cpp | 4 +++- modules/core/src/precomp.hpp | 19 +++--------------- modules/core/test/test_mat.cpp | 31 ++++++++++++++++++++++++++++++ 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index 0626607e2f..b0778d244c 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -199,6 +199,8 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst, func = tab[depth1]; Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat(); + if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src1, src2, dst); size_t len = sz.width*(size_t)cn; if( len == (size_t)(int)len ) @@ -630,6 +632,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, usrdata, oclop, false)) Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat(); + if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src1, src2, dst, src1.channels()); tab[depth1](src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, usrdata); return; @@ -1279,6 +1283,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op) int cn = src1.channels(); _dst.create(src1.size(), CV_8UC(cn)); Mat dst = _dst.getMat(); + if (_dst.isVector() && dst.size() != src1.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src1, src2, dst, src1.channels()); getCmpFunc(src1.depth())(src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, &op); return; diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index fe63fa6c3b..43b878acf0 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -443,7 +443,6 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) _dst.create( dims, size, _type ); Mat dst = _dst.getMat(); - BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); double scale[] = {alpha, beta}; int cn = channels(); @@ -451,6 +450,8 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) if( dims <= 2 ) { + if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src, dst, cn); func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale ); } @@ -512,6 +513,8 @@ void cv::convertFp16( InputArray _src, OutputArray _dst ) if( src.dims <= 2 ) { + if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src, dst, cn); func( src.data, src.step, 0, 0, dst.data, dst.step, sz, 0); } diff --git a/modules/core/src/convert_scale.cpp b/modules/core/src/convert_scale.cpp index a63ea5be72..51d25f7aa2 100644 --- a/modules/core/src/convert_scale.cpp +++ b/modules/core/src/convert_scale.cpp @@ -427,6 +427,8 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl if( src.dims <= 2 ) { + if (_dst.isVector() && dst.size() != src.size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(src, dst, cn); func( src.ptr(), src.step, 0, 0, dst.ptr(), dst.step, sz, scale ); } diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index fc4f363c7b..edc333d837 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -289,7 +289,7 @@ void Mat::copyTo( OutputArray _dst ) const { // For some cases (with vector) dst.size != src.size, so force to column-based form // It prevents memory corruption in case of column-based src - if (_dst.isVector()) + if (_dst.isVector() && dst.size() != size()) // https://github.com/opencv/opencv/pull/4159 dst = dst.reshape(0, (int)dst.total()); const uchar* sptr = data; @@ -403,6 +403,8 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const if( dims <= 2 ) { + if (_dst.isVector() && dst.size() != size()) // https://github.com/opencv/opencv/pull/4159 + dst = dst.reshape(0, (int)dst.total()); Size sz = getContinuousSize(*this, dst, mask, mcn); copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); return; diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index 6b3b23cddb..ac4077d952 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -168,6 +168,7 @@ inline Size getContinuousSize( const Mat& m1, int widthScale=1 ) inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) { + CV_Assert(m1.size() == m2.size()); return getContinuousSize_(m1.flags & m2.flags, m1.cols, m1.rows, widthScale); } @@ -175,26 +176,12 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) inline Size getContinuousSize( const Mat& m1, const Mat& m2, const Mat& m3, int widthScale=1 ) { + CV_Assert(m1.size() == m2.size()); + CV_Assert(m1.size() == m3.size()); return getContinuousSize_(m1.flags & m2.flags & m3.flags, m1.cols, m1.rows, widthScale); } -inline Size getContinuousSize( const Mat& m1, const Mat& m2, - const Mat& m3, const Mat& m4, - int widthScale=1 ) -{ - return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags, - m1.cols, m1.rows, widthScale); -} - -inline Size getContinuousSize( const Mat& m1, const Mat& m2, - const Mat& m3, const Mat& m4, - const Mat& m5, int widthScale=1 ) -{ - return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags & m5.flags, - m1.cols, m1.rows, widthScale); -} - void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false ); void finalizeHdr(Mat& m); int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step); diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 48cb35d7bf..91a93539fc 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1940,5 +1940,36 @@ TEST(Core_InputArray, support_CustomType) } } +TEST(Core_Vectors, issue_13078) +{ + float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + std::vector floats(floats_, floats_ + 8); + std::vector ints(4); + + Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2); + + m.convertTo(ints, CV_32S); + + ASSERT_EQ(1, ints[0]); + ASSERT_EQ(3, ints[1]); + ASSERT_EQ(5, ints[2]); + ASSERT_EQ(7, ints[3]); +} + +TEST(Core_Vectors, issue_13078_workaround) +{ + float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + std::vector floats(floats_, floats_ + 8); + std::vector ints(4); + + Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2); + + m.convertTo(Mat(ints), CV_32S); + + ASSERT_EQ(1, ints[0]); + ASSERT_EQ(3, ints[1]); + ASSERT_EQ(5, ints[2]); + ASSERT_EQ(7, ints[3]); +} }} // namespace -- GitLab