Commit 50595239 authored by Alexander Alekhin's avatar Alexander Alekhin

core: fix processing of vector-rows

parent e5d7f446
...@@ -199,6 +199,8 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst, ...@@ -199,6 +199,8 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
func = tab[depth1]; func = tab[depth1];
Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat(); 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 sz = getContinuousSize(src1, src2, dst);
size_t len = sz.width*(size_t)cn; size_t len = sz.width*(size_t)cn;
if( len == (size_t)(int)len ) if( len == (size_t)(int)len )
...@@ -630,6 +632,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, ...@@ -630,6 +632,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
usrdata, oclop, false)) usrdata, oclop, false))
Mat src1 = psrc1->getMat(), src2 = psrc2->getMat(), dst = _dst.getMat(); 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()); 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); tab[depth1](src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, usrdata);
return; return;
...@@ -1279,6 +1283,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op) ...@@ -1279,6 +1283,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
int cn = src1.channels(); int cn = src1.channels();
_dst.create(src1.size(), CV_8UC(cn)); _dst.create(src1.size(), CV_8UC(cn));
Mat dst = _dst.getMat(); 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()); 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); getCmpFunc(src1.depth())(src1.ptr(), src1.step, src2.ptr(), src2.step, dst.ptr(), dst.step, sz.width, sz.height, &op);
return; return;
......
...@@ -443,7 +443,6 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) ...@@ -443,7 +443,6 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
_dst.create( dims, size, _type ); _dst.create( dims, size, _type );
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta}; double scale[] = {alpha, beta};
int cn = channels(); int cn = channels();
...@@ -451,6 +450,8 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) ...@@ -451,6 +450,8 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
if( dims <= 2 ) 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); Size sz = getContinuousSize(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale ); func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
} }
...@@ -512,6 +513,8 @@ void cv::convertFp16( InputArray _src, OutputArray _dst ) ...@@ -512,6 +513,8 @@ void cv::convertFp16( InputArray _src, OutputArray _dst )
if( src.dims <= 2 ) 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); Size sz = getContinuousSize(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, 0); func( src.data, src.step, 0, 0, dst.data, dst.step, sz, 0);
} }
......
...@@ -427,6 +427,8 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl ...@@ -427,6 +427,8 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl
if( src.dims <= 2 ) 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); Size sz = getContinuousSize(src, dst, cn);
func( src.ptr(), src.step, 0, 0, dst.ptr(), dst.step, sz, scale ); func( src.ptr(), src.step, 0, 0, dst.ptr(), dst.step, sz, scale );
} }
......
...@@ -289,7 +289,7 @@ void Mat::copyTo( OutputArray _dst ) const ...@@ -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 // 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 // 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()); dst = dst.reshape(0, (int)dst.total());
const uchar* sptr = data; const uchar* sptr = data;
...@@ -403,6 +403,8 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const ...@@ -403,6 +403,8 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
if( dims <= 2 ) 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); Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return; return;
......
...@@ -168,6 +168,7 @@ inline Size getContinuousSize( const Mat& m1, int widthScale=1 ) ...@@ -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 ) inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
{ {
CV_Assert(m1.size() == m2.size());
return getContinuousSize_(m1.flags & m2.flags, return getContinuousSize_(m1.flags & m2.flags,
m1.cols, m1.rows, widthScale); m1.cols, m1.rows, widthScale);
} }
...@@ -175,26 +176,12 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) ...@@ -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, inline Size getContinuousSize( const Mat& m1, const Mat& m2,
const Mat& m3, int widthScale=1 ) 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, return getContinuousSize_(m1.flags & m2.flags & m3.flags,
m1.cols, m1.rows, widthScale); 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 setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false );
void finalizeHdr(Mat& m); void finalizeHdr(Mat& m);
int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step); int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step);
......
...@@ -1940,5 +1940,36 @@ TEST(Core_InputArray, support_CustomType) ...@@ -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<float> floats(floats_, floats_ + 8);
std::vector<int> 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<float> floats(floats_, floats_ + 8);
std::vector<int> 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 }} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment