diff --git a/modules/calib3d/src/stereosgbm.cpp b/modules/calib3d/src/stereosgbm.cpp index 27ce62e6f9..d5c160b0fc 100644 --- a/modules/calib3d/src/stereosgbm.cpp +++ b/modules/calib3d/src/stereosgbm.cpp @@ -353,7 +353,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2, if( buffer.empty() || !buffer.isContinuous() || buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize ) - buffer.create(1, (int)totalBufSize, CV_8U); + buffer.reserveBuffer(totalBufSize); // summary cost over different (nDirs) directions CostType* Cbuf = (CostType*)alignPtr(buffer.ptr(), ALIGN); @@ -939,7 +939,7 @@ void getBufferPointers(Mat& buffer, int width, int width1, int D, int num_ch, in 16; //to compensate for the alignPtr shifts if( buffer.empty() || !buffer.isContinuous() || buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize ) - buffer.create(1, (int)totalBufSize, CV_8U); + buffer.reserveBuffer(totalBufSize); // set up all the pointers: curCostVolumeLine = (CostType*)alignPtr(buffer.ptr(), 16); @@ -1615,7 +1615,7 @@ void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDif int width = img.cols, height = img.rows, npixels = width*height; size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar)); if( !_buf.isContinuous() || _buf.empty() || _buf.cols*_buf.rows*_buf.elemSize() < bufSize ) - _buf.create(1, (int)bufSize, CV_8U); + _buf.reserveBuffer(bufSize); uchar* buf = _buf.ptr(); int i, j, dstep = (int)(img.step/sizeof(T)); diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 08ad4dbb0d..0bd0ba53e4 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -1418,6 +1418,14 @@ public: */ void reserve(size_t sz); + /** @brief Reserves space for the certain number of bytes. + + The method reserves space for sz bytes. If the matrix already has enough space to store sz bytes, + nothing happens. If matrix has to be reallocated its previous content could be lost. + @param sz Number of bytes. + */ + void reserveBuffer(size_t sz); + /** @brief Changes the number of matrix rows. The methods change the number of matrix rows. If the matrix is reallocated, the first diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index c542a9ac70..32eed8abaf 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -830,6 +830,32 @@ void Mat::reserve(size_t nelems) dataend = data + step.p[0]*r; } +void Mat::reserveBuffer(size_t nbytes) +{ + size_t esz = 1; + int mtype = CV_8UC1; + if (!empty()) + { + if (!isSubmatrix() && data + nbytes <= dataend)//Should it be datalimit? + return; + esz = elemSize(); + mtype = type(); + } + + size_t nelems = (nbytes - 1) / esz + 1; + +#if SIZE_MAX > UINT_MAX + CV_Assert(nelems <= size_t(INT_MAX)*size_t(INT_MAX)); + int newrows = nelems > size_t(INT_MAX) ? nelems > 0x400*size_t(INT_MAX) ? nelems > 0x100000 * size_t(INT_MAX) ? nelems > 0x40000000 * size_t(INT_MAX) ? + size_t(INT_MAX) : 0x40000000 : 0x100000 : 0x400 : 1; +#else + int newrows = nelems > size_t(INT_MAX) ? 2 : 1; +#endif + int newcols = (int)((nelems - 1) / newrows + 1); + + create(newrows, newcols, mtype); +} + void Mat::resize(size_t nelems) {