Copy Mat to bytearray: Wrong JNI-Wrapper

672 views
Skip to first unread message

Zohob

unread,
Apr 20, 2012, 5:10:20 AM4/20/12
to
Hey,
I'm currently trying to copy a matrix in native code via memcpy.
Because my code crashes, I searched the web and found this:

https://code.ros.org/trac/opencv/browser/branches/android-experimental/opencv/android/android-opencv/jni/image_pool.cpp?rev=4700
In line 118 it says:
void copyMatToBuffer(char* buffer, const cv::Mat& mat)
{
    memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
}

But seems wrong to me! The memory length of one mat is mat.rows*mat.step().
Since the method does not seem to be used anywhere, this is not a big deal but if it's really wrong it should probably be changed.
Have I found a bug and if yes could you forward it to the developers?

P.S.: How do I copy the content of one mat into a char* buffer?
both
1) memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
2) memcpy(buffer, mat.data, mat.rows*mat.step());
are not working and I get a memory access error

Rui Marques

unread,
Apr 20, 2012, 6:20:54 AM4/20/12
to android...@googlegroups.com
That link that you posted i think it is quite old code.
The current opencv code repository is here:
http://code.opencv.org/projects/opencv/repository

And the bug submitting can also be done after registering yourself in http://code.opencv.org

dschaudel

unread,
Apr 20, 2012, 6:56:08 AM4/20/12
to android...@googlegroups.com
want do you want to do? pass an java mat object to native code?
keep it simple. use the getNativeObjAddr() method.

java side:

NativeMethod(long NativeMatAddress);

native code:

JNIEXPORT void ... (JNIENV* env, jobject thiz, jlong addrNativeMat) { ...
... Mat* mat = (Mat*) addrNativeMat; ...



dont forget to dereference the pointer for further processing ...


On Friday, April 20, 2012 11:08:39 AM UTC+2, Zohob wrote:
Hey,
I'm currently trying to copy a matrix in native code via memcpy.
Because my code crashes, I searched the web and found this:

https://code.ros.org/trac/opencv/browser/branches/android-experimental/opencv/android/android-opencv/jni/image_pool.cpp?rev=4700
In line 118 it says:
void copyMatToBuffer(char* buffer, const cv::Mat& mat)
{
    memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
}

But seems wrong to me! The memory length of one mat is mat.rows*mat.step().
Since the method does not seem to be used anywhere, this is not a big deal but if it's really wrong it should probably be changed.
Have I found a bug and if yes could you forward it to the developers?

P.S.: How do I copy the content of one mat into a char* buffer?
both
1) memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
2) memcpy(buffer, mat.data, mat.rows*mat.step());
are not working and I get a memory access error

On Friday, April 20, 2012 11:08:39 AM UTC+2, Zohob wrote:
Hey,
I'm currently trying to copy a matrix in native code via memcpy.
Because my code crashes, I searched the web and found this:

https://code.ros.org/trac/opencv/browser/branches/android-experimental/opencv/android/android-opencv/jni/image_pool.cpp?rev=4700
In line 118 it says:
void copyMatToBuffer(char* buffer, const cv::Mat& mat)
{
    memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
}

But seems wrong to me! The memory length of one mat is mat.rows*mat.step().
Since the method does not seem to be used anywhere, this is not a big deal but if it's really wrong it should probably be changed.
Have I found a bug and if yes could you forward it to the developers?

P.S.: How do I copy the content of one mat into a char* buffer?
both
1) memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
2) memcpy(buffer, mat.data, mat.rows*mat.step());
are not working and I get a memory access error

On Friday, April 20, 2012 11:08:39 AM UTC+2, Zohob wrote:
Hey,
I'm currently trying to copy a matrix in native code via memcpy.
Because my code crashes, I searched the web and found this:

https://code.ros.org/trac/opencv/browser/branches/android-experimental/opencv/android/android-opencv/jni/image_pool.cpp?rev=4700
In line 118 it says:
void copyMatToBuffer(char* buffer, const cv::Mat& mat)
{
    memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
}

But seems wrong to me! The memory length of one mat is mat.rows*mat.step().
Since the method does not seem to be used anywhere, this is not a big deal but if it's really wrong it should probably be changed.
Have I found a bug and if yes could you forward it to the developers?

P.S.: How do I copy the content of one mat into a char* buffer?
both
1) memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
2) memcpy(buffer, mat.data, mat.rows*mat.step());
are not working and I get a memory access error

On Friday, April 20, 2012 11:08:39 AM UTC+2, Zohob wrote:
Hey,
I'm currently trying to copy a matrix in native code via memcpy.
Because my code crashes, I searched the web and found this:

https://code.ros.org/trac/opencv/browser/branches/android-experimental/opencv/android/android-opencv/jni/image_pool.cpp?rev=4700
In line 118 it says:
void copyMatToBuffer(char* buffer, const cv::Mat& mat)
{
    memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
}

But seems wrong to me! The memory length of one mat is mat.rows*mat.step().
Since the method does not seem to be used anywhere, this is not a big deal but if it's really wrong it should probably be changed.
Have I found a bug and if yes could you forward it to the developers?

P.S.: How do I copy the content of one mat into a char* buffer?
both
1) memcpy(buffer, mat.data, mat.rows * mat.cols * mat.step1());
2) memcpy(buffer, mat.data, mat.rows*mat.step());
are not working and I get a memory access error

Zohob

unread,
Apr 20, 2012, 7:25:33 AM4/20/12
to
What I am trying to do is not exactly android specific - I posted this message here because the mistake I found was in (as Rui said: old) android code.
Anyhow: If I had used

Mat* mat = (Mat*) addrNativeMat;
then I would want to write the data into a buffer.
int size = mat.rows*mat.step();
unsigned char datagram[10+size];

//... leaving out code

unsigned char *ptr = &datagram[10];
memcpy
(&ptr, mat.data, size); //This line fails and I don't know why

dschaudel

unread,
Apr 20, 2012, 7:33:12 AM4/20/12
to android...@googlegroups.com
dereference the pointer!

in size = mat->rows * mat->step() ...

or

int size = (*mat).rows * (*mat).step() ...



...


On Friday, April 20, 2012 1:24:45 PM UTC+2, Zohob wrote:
What I am trying to do is not exactly android specific - I posted this message here because the mistake I found was in (as Rui said: old) android code.
Anyhow: If I had used
Mat* mat = (Mat*) addrNativeMat;

Zohob

unread,
Apr 20, 2012, 8:19:00 AM4/20/12
to android...@googlegroups.com
I'm deeply sorry to cause confusion but in my original code I dereferenced mat like your first suggestion.
The improved code (I added the fuction declaration to make clear, where mat comes from) is:
void aMethod(cv::Mat *mat) {
int size = mat->rows*mat->step;
unsigned char datagram[10+size];

//... leaving out code

unsigned char *ptr = &datagram[10];
memcpy(&ptr, mat->data, size); //This line fails and I don't know why
}

But it does not work :-(

Andrey Pavlenko

unread,
Apr 20, 2012, 9:30:27 AM4/20/12
to android...@googlegroups.com
memcpy(ptr, mat->data, size);

be aware that it works for  continuous Mat-s only!

mat->isContinuous() == true


Zohob

unread,
Apr 24, 2012, 8:48:04 AM4/24/12
to
I corrected the pointers and checked for continuity. Although the matrix was continuous, it did not work.

But then I found the underlying error: The buffer was located at the stack and was too large for it (around 1 MB). Since the bug did not occur after the allocation but not until the memcpy, it was hard to find for me.
I moved the datagram to the heap using malloc and everything works fine.

Thank all of you!
Reply all
Reply to author
Forward
0 new messages