Skip to content

Commit 67b6ef4

Browse files
committed
Merge pull request opencv#19503 from komakai:fix-android-putget
2 parents 7ffc4b5 + 5cf08b0 commit 67b6ef4

File tree

4 files changed

+102
-123
lines changed

4 files changed

+102
-123
lines changed

modules/core/misc/java/test/MatTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,27 @@ public void testGetIntIntShortArray() {
455455
bytesNum = sm.get(1, 1, buff11);
456456
assertEquals(4, bytesNum);
457457
assertTrue(Arrays.equals(new short[] {340, 341, 0, 0}, buff11));
458+
459+
Mat m2 = new Mat(new int[]{ 5, 6, 8 }, CvType.CV_16S);
460+
short[] data = new short[(int)m2.total()];
461+
for (int i = 0; i < data.length; i++ ) {
462+
data[i] = (short)i;
463+
}
464+
m2.put(new int[] {0, 0, 0}, data);
465+
Mat matNonContinuous = m2.submat(new Range[]{new Range(1,4), new Range(2,5), new Range(3,6)});
466+
Mat matContinuous = matNonContinuous.clone();
467+
short[] outNonContinuous = new short[(int)matNonContinuous.total()];
468+
matNonContinuous.get(new int[] { 0, 0, 0 }, outNonContinuous);
469+
short[] outContinuous = new short[(int)matNonContinuous.total()];
470+
matContinuous.get(new int[] { 0, 0, 0 }, outContinuous);
471+
assertArrayEquals(outNonContinuous, outContinuous);
472+
Mat subMat2 = m2.submat(new Range[]{new Range(1,4), new Range(1,5), new Range(0,8)});
473+
Mat subMatClone2 = subMat2.clone();
474+
short[] outNonContinuous2 = new short[(int)subMat2.total()];
475+
subMat2.get(new int[] { 0, 1, 1 }, outNonContinuous2);
476+
short[] outContinuous2 = new short[(int)subMat2.total()];
477+
subMatClone2.get(new int[] { 0, 1, 1 }, outContinuous2);
478+
assertArrayEquals(outNonContinuous2, outContinuous2);
458479
}
459480

460481
public void testGetNativeObjAddr() {

modules/java/generator/src/cpp/Mat.cpp

Lines changed: 62 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,80 +2129,83 @@ namespace {
21292129
#undef JOCvT
21302130
}
21312131

2132-
template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count, int offset, char* buff)
2133-
{
2134-
if(! m) return 0;
2135-
if(! buff) return 0;
2136-
2137-
count *= sizeof(T);
2138-
int rest = ((m->rows - row) * m->cols - col) * (int)m->elemSize();
2139-
if(count>rest) count = rest;
2140-
int res = count;
2132+
static size_t idx2Offset(cv::Mat* mat, std::vector<int>& indices) {
2133+
size_t offset = indices[0];
2134+
for (int dim=1; dim < mat->dims; dim++) {
2135+
offset = offset*mat->size[dim] + indices[dim];
2136+
}
2137+
return offset;
2138+
}
21412139

2142-
if( m->isContinuous() )
2143-
{
2144-
memcpy(m->ptr(row, col), buff + offset, count);
2145-
} else {
2146-
// row by row
2147-
int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row
2148-
if(count<num) num = count;
2149-
uchar* data = m->ptr(row++, col);
2150-
while(count>0){
2151-
memcpy(data, buff + offset, num);
2152-
count -= num;
2153-
buff += num;
2154-
num = m->cols * (int)m->elemSize();
2155-
if(count<num) num = count;
2156-
data = m->ptr(row++, 0);
2157-
}
2140+
static void offset2Idx(cv::Mat* mat, size_t offset, std::vector<int>& indices) {
2141+
for (int dim=mat->dims-1; dim>=0; dim--) {
2142+
indices[dim] = offset % mat->size[dim];
2143+
offset = (offset - indices[dim]) / mat->size[dim];
21582144
}
2159-
return res;
21602145
}
21612146

21622147
// returns true if final index was reached
2163-
static bool updateIdx(cv::Mat* m, std::vector<int>& idx, int inc) {
2164-
for (int i=m->dims-1; i>=0; i--) {
2165-
if (inc == 0) return false;
2166-
idx[i] = (idx[i] + 1) % m->size[i];
2167-
inc--;
2168-
}
2169-
return true;
2148+
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, size_t inc) {
2149+
size_t currentOffset = idx2Offset(mat, indices);
2150+
size_t newOffset = currentOffset + inc;
2151+
bool reachedEnd = newOffset>=(size_t)mat->total();
2152+
offset2Idx(mat, reachedEnd?0:newOffset, indices);
2153+
return reachedEnd;
21702154
}
21712155

2172-
template<typename T> static int mat_put_idx(cv::Mat* m, std::vector<int>& idx, int count, int offset, char* buff)
2173-
{
2156+
template<typename T> static int mat_copy_data(cv::Mat* m, std::vector<int>& idx, int count, char* buff, bool isPut) {
21742157
if(! m) return 0;
21752158
if(! buff) return 0;
21762159

2177-
count *= sizeof(T);
2178-
int rest = (int)m->elemSize();
2179-
for (int i = 0; i < m->dims; i++) {
2180-
rest *= (m->size[i] - idx[i]);
2181-
}
2182-
if(count>rest) count = rest;
2183-
int res = count;
2160+
size_t countBytes = count * sizeof(T);
2161+
size_t remainingBytes = (size_t)(m->total() - idx2Offset(m, idx))*m->elemSize();
2162+
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes;
2163+
int res = (int)countBytes;
21842164

21852165
if( m->isContinuous() )
21862166
{
2187-
memcpy(m->ptr(idx.data()), buff + offset, count);
2167+
if (isPut) {
2168+
memcpy(m->ptr(idx.data()), buff, countBytes);
2169+
} else {
2170+
memcpy(buff, m->ptr(idx.data()), countBytes);
2171+
}
21882172
} else {
2189-
// dim by dim
2190-
int num = (m->size[m->dims-1] - idx[m->dims-1]) * (int)m->elemSize(); // 1st partial row
2191-
if(count<num) num = count;
2173+
size_t blockSize = m->size[m->dims-1] * m->elemSize();
2174+
size_t firstPartialBlockSize = (m->size[m->dims-1] - idx[m->dims-1]) * m->step[m->dims-1];;
2175+
for (int dim=m->dims-2; dim>=0 && blockSize == m->step[dim]; dim--) {
2176+
blockSize *= m->size[dim];
2177+
firstPartialBlockSize += (m->size[dim] - (idx[dim]+1)) * m->step[dim];
2178+
}
2179+
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize;
21922180
uchar* data = m->ptr(idx.data());
2193-
while(count>0){
2194-
memcpy(data, buff + offset, num);
2195-
updateIdx(m, idx, num / (int)m->elemSize());
2196-
count -= num;
2197-
buff += num;
2198-
num = m->size[m->dims-1] * (int)m->elemSize();
2199-
if(count<num) num = count;
2181+
while(countBytes>0){
2182+
if (isPut) {
2183+
memcpy(data, buff, copyCount);
2184+
} else {
2185+
memcpy(buff, data, copyCount);
2186+
}
2187+
updateIdx(m, idx, copyCount / m->elemSize());
2188+
countBytes -= copyCount;
2189+
buff += copyCount;
2190+
copyCount = countBytes<blockSize?countBytes:blockSize;
22002191
data = m->ptr(idx.data());
22012192
}
22022193
}
22032194
return res;
22042195
}
22052196

2197+
template<typename T> static int mat_put_idx(cv::Mat* m, std::vector<int>& idx, int count, int offset, char* buff)
2198+
{
2199+
return mat_copy_data<T>(m, idx, count, buff + offset, true);
2200+
}
2201+
2202+
template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count, int offset, char* buff)
2203+
{
2204+
int indicesArray[] = { row, col };
2205+
std::vector<int> indices(indicesArray, indicesArray+2);
2206+
return mat_put_idx<T>(m, indices, count, offset, buff);
2207+
}
2208+
22062209
template<class ARRAY> static jint java_mat_put(JNIEnv* env, jlong self, jint row, jint col, jint count, jint offset, ARRAY vals)
22072210
{
22082211
static const char *method_name = JavaOpenCVTrait<ARRAY>::put;
@@ -2455,68 +2458,16 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutDIdx
24552458

24562459
} // extern "C"
24572460

2458-
template<typename T> static int mat_get(cv::Mat* m, int row, int col, int count, char* buff)
2461+
template<typename T> static int mat_get_idx(cv::Mat* m, std::vector<int>& idx, int count, char* buff)
24592462
{
2460-
if(! m) return 0;
2461-
if(! buff) return 0;
2462-
2463-
int bytesToCopy = count * sizeof(T);
2464-
int bytesRestInMat = ((m->rows - row) * m->cols - col) * (int)m->elemSize();
2465-
if(bytesToCopy > bytesRestInMat) bytesToCopy = bytesRestInMat;
2466-
int res = bytesToCopy;
2467-
2468-
if( m->isContinuous() )
2469-
{
2470-
memcpy(buff, m->ptr(row, col), bytesToCopy);
2471-
} else {
2472-
// row by row
2473-
int bytesInRow = (m->cols - col) * (int)m->elemSize(); // 1st partial row
2474-
while(bytesToCopy > 0)
2475-
{
2476-
int len = std::min(bytesToCopy, bytesInRow);
2477-
memcpy(buff, m->ptr(row, col), len);
2478-
bytesToCopy -= len;
2479-
buff += len;
2480-
row++;
2481-
col = 0;
2482-
bytesInRow = m->cols * (int)m->elemSize();
2483-
}
2484-
}
2485-
return res;
2463+
return mat_copy_data<T>(m, idx, count, buff, false);
24862464
}
24872465

2488-
template<typename T> static int mat_get_idx(cv::Mat* m, std::vector<int>& idx, int count, char* buff)
2466+
template<typename T> static int mat_get(cv::Mat* m, int row, int col, int count, char* buff)
24892467
{
2490-
if(! m) return 0;
2491-
if(! buff) return 0;
2492-
2493-
count *= sizeof(T);
2494-
int rest = (int)m->elemSize();
2495-
for (int i = 0; i < m->dims; i++) {
2496-
rest *= (m->size[i] - idx[i]);
2497-
}
2498-
if(count>rest) count = rest;
2499-
int res = count;
2500-
2501-
if( m->isContinuous() )
2502-
{
2503-
memcpy(buff, m->ptr(idx.data()), count);
2504-
} else {
2505-
// dim by dim
2506-
int num = (m->size[m->dims-1] - idx[m->dims-1]) * (int)m->elemSize(); // 1st partial row
2507-
if(count<num) num = count;
2508-
uchar* data = m->ptr(idx.data());
2509-
while(count>0){
2510-
memcpy(buff, data, num);
2511-
updateIdx(m, idx, num / (int)m->elemSize());
2512-
count -= num;
2513-
buff += num;
2514-
num = m->size[m->dims-1] * (int)m->elemSize();
2515-
if(count<num) num = count;
2516-
data = m->ptr(idx.data());
2517-
}
2518-
}
2519-
return res;
2468+
int indicesArray[] = { row, col };
2469+
std::vector<int> indices(indicesArray, indicesArray+2);
2470+
return mat_get_idx<T>(m, indices, count, buff);
25202471
}
25212472

25222473
template<class ARRAY> static jint java_mat_get(JNIEnv* env, jlong self, jint row, jint col, jint count, ARRAY vals) {

modules/java/test/android_test/src/org/opencv/test/OpenCVTestCase.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,19 +279,23 @@ public static <E extends Number> void assertListEquals(List<E> list1, List<E> li
279279
}
280280

281281
public static <E extends Number> void assertArrayEquals(E[] ar1, E[] ar2, double epsilon) {
282-
if (ar1.length != ar2.length) {
283-
fail("Arrays have different sizes.");
284-
}
282+
assertEquals(ar1.length, ar2.length);
285283

286284
for (int i = 0; i < ar1.length; i++)
287285
assertEquals(ar1[i].doubleValue(), ar2[i].doubleValue(), epsilon);
288286
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
289287
}
290288

289+
public static void assertArrayEquals(short[] ar1, short[] ar2) {
290+
assertEquals(ar1.length, ar2.length);
291+
292+
for (int i = 0; i < ar1.length; i++)
293+
assertEquals(ar1[i], ar2[i]);
294+
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
295+
}
296+
291297
public static void assertArrayEquals(double[] ar1, double[] ar2, double epsilon) {
292-
if (ar1.length != ar2.length) {
293-
fail("Arrays have different sizes.");
294-
}
298+
assertEquals(ar1.length, ar2.length);
295299

296300
for (int i = 0; i < ar1.length; i++)
297301
assertEquals(ar1[i], ar2[i], epsilon);

modules/java/test/pure_test/src/org/opencv/test/OpenCVTestCase.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,22 @@ public static <E extends Number> void assertListEquals(List<E> list1, List<E> li
305305
}
306306

307307
public static <E extends Number> void assertArrayEquals(E[] ar1, E[] ar2, double epsilon) {
308-
if (ar1.length != ar2.length) {
309-
fail("Arrays have different sizes.");
310-
}
308+
assertEquals(ar1.length, ar2.length);
311309

312310
for (int i = 0; i < ar1.length; i++)
313311
assertEquals(ar1[i].doubleValue(), ar2[i].doubleValue(), epsilon);
314312
//assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
315313
}
316314

315+
public static void assertArrayEquals(short[] ar1, short[] ar2) {
316+
assertEquals(ar1.length, ar2.length);
317+
318+
for (int i = 0; i < ar1.length; i++)
319+
assertEquals(ar1[i], ar2[i]);
320+
}
321+
317322
public static void assertArrayEquals(double[] ar1, double[] ar2, double epsilon) {
318-
if (ar1.length != ar2.length) {
319-
fail("Arrays have different sizes.");
320-
}
323+
assertEquals(ar1.length, ar2.length);
321324

322325
for (int i = 0; i < ar1.length; i++)
323326
assertEquals(ar1[i], ar2[i], epsilon);

0 commit comments

Comments
 (0)