Fix for SGBM compute() buffer allocation failure on big images

pull/8064/head
Vitaly Tuzov 8 years ago
parent 73b5ef48ef
commit 4950f542d1
  1. 6
      modules/calib3d/src/stereosgbm.cpp
  2. 8
      modules/core/include/opencv2/core/mat.hpp
  3. 26
      modules/core/src/matrix.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));

@ -1416,6 +1416,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

@ -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)
{

Loading…
Cancel
Save