Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2021-02-27 17:41:57 +00:00
33 changed files with 3656 additions and 314 deletions
+64 -113
View File
@@ -2129,80 +2129,83 @@ namespace {
#undef JOCvT
}
template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count, int offset, char* buff)
{
if(! m) return 0;
if(! buff) return 0;
count *= sizeof(T);
int rest = ((m->rows - row) * m->cols - col) * (int)m->elemSize();
if(count>rest) count = rest;
int res = count;
if( m->isContinuous() )
{
memcpy(m->ptr(row, col), buff + offset, count);
} else {
// row by row
int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row
if(count<num) num = count;
uchar* data = m->ptr(row++, col);
while(count>0){
memcpy(data, buff + offset, num);
count -= num;
buff += num;
num = m->cols * (int)m->elemSize();
if(count<num) num = count;
data = m->ptr(row++, 0);
}
static size_t idx2Offset(cv::Mat* mat, std::vector<int>& indices) {
size_t offset = indices[0];
for (int dim=1; dim < mat->dims; dim++) {
offset = offset*mat->size[dim] + indices[dim];
}
return offset;
}
static void offset2Idx(cv::Mat* mat, size_t offset, std::vector<int>& indices) {
for (int dim=mat->dims-1; dim>=0; dim--) {
indices[dim] = offset % mat->size[dim];
offset = (offset - indices[dim]) / mat->size[dim];
}
return res;
}
// returns true if final index was reached
static bool updateIdx(cv::Mat* m, std::vector<int>& idx, int inc) {
for (int i=m->dims-1; i>=0; i--) {
if (inc == 0) return false;
idx[i] = (idx[i] + 1) % m->size[i];
inc--;
}
return true;
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, size_t inc) {
size_t currentOffset = idx2Offset(mat, indices);
size_t newOffset = currentOffset + inc;
bool reachedEnd = newOffset>=(size_t)mat->total();
offset2Idx(mat, reachedEnd?0:newOffset, indices);
return reachedEnd;
}
template<typename T> static int mat_put_idx(cv::Mat* m, std::vector<int>& idx, int count, int offset, char* buff)
{
template<typename T> static int mat_copy_data(cv::Mat* m, std::vector<int>& idx, int count, char* buff, bool isPut) {
if(! m) return 0;
if(! buff) return 0;
count *= sizeof(T);
int rest = (int)m->elemSize();
for (int i = 0; i < m->dims; i++) {
rest *= (m->size[i] - idx[i]);
}
if(count>rest) count = rest;
int res = count;
size_t countBytes = count * sizeof(T);
size_t remainingBytes = (size_t)(m->total() - idx2Offset(m, idx))*m->elemSize();
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes;
int res = (int)countBytes;
if( m->isContinuous() )
{
memcpy(m->ptr(idx.data()), buff + offset, count);
if (isPut) {
memcpy(m->ptr(idx.data()), buff, countBytes);
} else {
memcpy(buff, m->ptr(idx.data()), countBytes);
}
} else {
// dim by dim
int num = (m->size[m->dims-1] - idx[m->dims-1]) * (int)m->elemSize(); // 1st partial row
if(count<num) num = count;
size_t blockSize = m->size[m->dims-1] * m->elemSize();
size_t firstPartialBlockSize = (m->size[m->dims-1] - idx[m->dims-1]) * m->step[m->dims-1];;
for (int dim=m->dims-2; dim>=0 && blockSize == m->step[dim]; dim--) {
blockSize *= m->size[dim];
firstPartialBlockSize += (m->size[dim] - (idx[dim]+1)) * m->step[dim];
}
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize;
uchar* data = m->ptr(idx.data());
while(count>0){
memcpy(data, buff + offset, num);
updateIdx(m, idx, num / (int)m->elemSize());
count -= num;
buff += num;
num = m->size[m->dims-1] * (int)m->elemSize();
if(count<num) num = count;
while(countBytes>0){
if (isPut) {
memcpy(data, buff, copyCount);
} else {
memcpy(buff, data, copyCount);
}
updateIdx(m, idx, copyCount / m->elemSize());
countBytes -= copyCount;
buff += copyCount;
copyCount = countBytes<blockSize?countBytes:blockSize;
data = m->ptr(idx.data());
}
}
return res;
}
template<typename T> static int mat_put_idx(cv::Mat* m, std::vector<int>& idx, int count, int offset, char* buff)
{
return mat_copy_data<T>(m, idx, count, buff + offset, true);
}
template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count, int offset, char* buff)
{
int indicesArray[] = { row, col };
std::vector<int> indices(indicesArray, indicesArray+2);
return mat_put_idx<T>(m, indices, count, offset, buff);
}
template<class ARRAY> static jint java_mat_put(JNIEnv* env, jlong self, jint row, jint col, jint count, jint offset, ARRAY vals)
{
static const char *method_name = JavaOpenCVTrait<ARRAY>::put;
@@ -2455,68 +2458,16 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutDIdx
} // extern "C"
template<typename T> static int mat_get(cv::Mat* m, int row, int col, int count, char* buff)
{
if(! m) return 0;
if(! buff) return 0;
int bytesToCopy = count * sizeof(T);
int bytesRestInMat = ((m->rows - row) * m->cols - col) * (int)m->elemSize();
if(bytesToCopy > bytesRestInMat) bytesToCopy = bytesRestInMat;
int res = bytesToCopy;
if( m->isContinuous() )
{
memcpy(buff, m->ptr(row, col), bytesToCopy);
} else {
// row by row
int bytesInRow = (m->cols - col) * (int)m->elemSize(); // 1st partial row
while(bytesToCopy > 0)
{
int len = std::min(bytesToCopy, bytesInRow);
memcpy(buff, m->ptr(row, col), len);
bytesToCopy -= len;
buff += len;
row++;
col = 0;
bytesInRow = m->cols * (int)m->elemSize();
}
}
return res;
}
template<typename T> static int mat_get_idx(cv::Mat* m, std::vector<int>& idx, int count, char* buff)
{
if(! m) return 0;
if(! buff) return 0;
return mat_copy_data<T>(m, idx, count, buff, false);
}
count *= sizeof(T);
int rest = (int)m->elemSize();
for (int i = 0; i < m->dims; i++) {
rest *= (m->size[i] - idx[i]);
}
if(count>rest) count = rest;
int res = count;
if( m->isContinuous() )
{
memcpy(buff, m->ptr(idx.data()), count);
} else {
// dim by dim
int num = (m->size[m->dims-1] - idx[m->dims-1]) * (int)m->elemSize(); // 1st partial row
if(count<num) num = count;
uchar* data = m->ptr(idx.data());
while(count>0){
memcpy(buff, data, num);
updateIdx(m, idx, num / (int)m->elemSize());
count -= num;
buff += num;
num = m->size[m->dims-1] * (int)m->elemSize();
if(count<num) num = count;
data = m->ptr(idx.data());
}
}
return res;
template<typename T> static int mat_get(cv::Mat* m, int row, int col, int count, char* buff)
{
int indicesArray[] = { row, col };
std::vector<int> indices(indicesArray, indicesArray+2);
return mat_get_idx<T>(m, indices, count, buff);
}
template<class ARRAY> static jint java_mat_get(JNIEnv* env, jlong self, jint row, jint col, jint count, ARRAY vals) {
@@ -279,19 +279,23 @@ public class OpenCVTestCase extends TestCase {
}
public static <E extends Number> void assertArrayEquals(E[] ar1, E[] ar2, double epsilon) {
if (ar1.length != ar2.length) {
fail("Arrays have different sizes.");
}
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i].doubleValue(), ar2[i].doubleValue(), epsilon);
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
}
public static void assertArrayEquals(short[] ar1, short[] ar2) {
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i], ar2[i]);
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
}
public static void assertArrayEquals(double[] ar1, double[] ar2, double epsilon) {
if (ar1.length != ar2.length) {
fail("Arrays have different sizes.");
}
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i], ar2[i], epsilon);
@@ -305,19 +305,22 @@ public class OpenCVTestCase extends TestCase {
}
public static <E extends Number> void assertArrayEquals(E[] ar1, E[] ar2, double epsilon) {
if (ar1.length != ar2.length) {
fail("Arrays have different sizes.");
}
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i].doubleValue(), ar2[i].doubleValue(), epsilon);
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
}
public static void assertArrayEquals(short[] ar1, short[] ar2) {
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i], ar2[i]);
}
public static void assertArrayEquals(double[] ar1, double[] ar2, double epsilon) {
if (ar1.length != ar2.length) {
fail("Arrays have different sizes.");
}
assertEquals(ar1.length, ar2.length);
for (int i = 0; i < ar1.length; i++)
assertEquals(ar1[i], ar2[i], epsilon);