diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 32eed8abaf..135397aa7d 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -997,8 +997,13 @@ Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright ) Size wholeSize; Point ofs; size_t esz = elemSize(); locateROI( wholeSize, ofs ); - int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height); - int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width); + int row1 = std::min(std::max(ofs.y - dtop, 0), wholeSize.height), row2 = std::max(0, std::min(ofs.y + rows + dbottom, wholeSize.height)); + int col1 = std::min(std::max(ofs.x - dleft, 0), wholeSize.width), col2 = std::max(0, std::min(ofs.x + cols + dright, wholeSize.width)); + if(row1 > row2) + std::swap(row1, row2); + if(col1 > col2) + std::swap(col1, col2); + data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz; rows = row2 - row1; cols = col2 - col1; size.p[0] = rows; size.p[1] = cols; diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index dd5b9a0c2c..6991b40d04 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -599,8 +599,13 @@ UMat& UMat::adjustROI( int dtop, int dbottom, int dleft, int dright ) Size wholeSize; Point ofs; size_t esz = elemSize(); locateROI( wholeSize, ofs ); - int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height); - int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width); + int row1 = std::min(std::max(ofs.y - dtop, 0), wholeSize.height), row2 = std::max(0, std::min(ofs.y + rows + dbottom, wholeSize.height)); + int col1 = std::min(std::max(ofs.x - dleft, 0), wholeSize.width), col2 = std::max(0, std::min(ofs.x + cols + dright, wholeSize.width)); + if(row1 > row2) + std::swap(row1, row2); + if(col1 > col2) + std::swap(col1, col2); + offset += (row1 - ofs.y)*step + (col1 - ofs.x)*esz; rows = row2 - row1; cols = col2 - col1; size.p[0] = rows; size.p[1] = cols; diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index 543fb31ac7..2526ef8a10 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -1240,3 +1240,17 @@ protected: }; TEST(Core_SparseMat, iterations) { CV_SparseMatTest test; test.safe_run(); } + +TEST(MatTestRoi, adjustRoiOverflow) +{ + Mat m(15, 10, CV_32S); + Mat roi(m, cv::Range(2, 10), cv::Range(3,6)); + int rowsInROI = roi.rows; + roi.adjustROI(1, 0, 0, 0); + + ASSERT_EQ(roi.rows, rowsInROI + 1); + + roi.adjustROI(-m.rows, -m.rows, 0, 0); + + ASSERT_EQ(roi.rows, m.rows); +} diff --git a/modules/core/test/test_umat.cpp b/modules/core/test/test_umat.cpp index 9e9835f350..d7a3e6de1f 100644 --- a/modules/core/test/test_umat.cpp +++ b/modules/core/test/test_umat.cpp @@ -496,6 +496,20 @@ TEST_P(UMatTestRoi, adjustRoi) INSTANTIATE_TEST_CASE_P(UMat, UMatTestRoi, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES )); +TEST(UMatTestRoi, adjustRoiOverflow) +{ + UMat m(15, 10, CV_32S); + UMat roi(m, cv::Range(2, 10), cv::Range(3,6)); + int rowsInROI = roi.rows; + roi.adjustROI(1, 0, 0, 0); + + ASSERT_EQ(roi.rows, rowsInROI + 1); + + roi.adjustROI(-m.rows, -m.rows, 0, 0); + + ASSERT_EQ(roi.rows, m.rows); +} + /////////////////////////////////////////////////////////////// Size //////////////////////////////////////////////////////////////////// PARAM_TEST_CASE(UMatTestSizeOperations, int, int, Size, bool)