mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 05:29:54 +08:00
Merge pull request #10489 from SarenT:offset-mat_put
Adding capability to parse subsections of a byte array in Java bindings (#10489) * Adding capability to parse subsections of a byte array in Java bindings. (Because Java lacks pointers. Therefore, reading images within a subsection of a byte array is impossible by Java's nature and limitations. Because of this, many IO functions in Java require additional parameters offset and length to define, which section of an array to be read.) * Corrected according to the review. Previous interfaces were restored, instead internal interfaces were modified to provide subsampling of java byte arrays. * Adding tests and test related files. * Adding missing files for the test. * Simplified the test * Check was corrected according to discussion. An OutOfRangeException will be thrown instead of returning. * java: update MatOfByte implementation checks / tests
This commit is contained in:
parent
9deaddcdff
commit
c6d9ce8fd3
@ -1015,6 +1015,21 @@ public class Mat {
|
|||||||
throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t);
|
throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// javadoc:Mat::put(row,col,data,offset,length)
|
||||||
|
public int put(int row, int col, byte[] data, int offset, int length) {
|
||||||
|
int t = type();
|
||||||
|
if (data == null || length % CvType.channels(t) != 0)
|
||||||
|
throw new java.lang.UnsupportedOperationException(
|
||||||
|
"Provided data element number (" +
|
||||||
|
(data == null ? 0 : data.length) +
|
||||||
|
") should be multiple of the Mat channels count (" +
|
||||||
|
CvType.channels(t) + ")");
|
||||||
|
if (CvType.depth(t) == CvType.CV_8U || CvType.depth(t) == CvType.CV_8S) {
|
||||||
|
return nPutBwOffset(nativeObj, row, col, length, offset, data);
|
||||||
|
}
|
||||||
|
throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t);
|
||||||
|
}
|
||||||
|
|
||||||
// javadoc:Mat::get(row,col,data)
|
// javadoc:Mat::get(row,col,data)
|
||||||
public int get(int row, int col, byte[] data) {
|
public int get(int row, int col, byte[] data) {
|
||||||
int t = type();
|
int t = type();
|
||||||
@ -1318,6 +1333,8 @@ public class Mat {
|
|||||||
|
|
||||||
private static native int nPutB(long self, int row, int col, int count, byte[] data);
|
private static native int nPutB(long self, int row, int col, int count, byte[] data);
|
||||||
|
|
||||||
|
private static native int nPutBwOffset(long self, int row, int col, int count, int offset, byte[] data);
|
||||||
|
|
||||||
private static native int nGetB(long self, int row, int col, int count, byte[] vals);
|
private static native int nGetB(long self, int row, int col, int count, byte[] vals);
|
||||||
|
|
||||||
private static native int nGetS(long self, int row, int col, int count, short[] vals);
|
private static native int nGetS(long self, int row, int col, int count, short[] vals);
|
||||||
|
@ -35,6 +35,11 @@ public class MatOfByte extends Mat {
|
|||||||
fromArray(a);
|
fromArray(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MatOfByte(int offset, int length, byte...a) {
|
||||||
|
super();
|
||||||
|
fromArray(offset, length, a);
|
||||||
|
}
|
||||||
|
|
||||||
public void alloc(int elemNumber) {
|
public void alloc(int elemNumber) {
|
||||||
if(elemNumber>0)
|
if(elemNumber>0)
|
||||||
super.create(elemNumber, 1, CvType.makeType(_depth, _channels));
|
super.create(elemNumber, 1, CvType.makeType(_depth, _channels));
|
||||||
@ -48,6 +53,20 @@ public class MatOfByte extends Mat {
|
|||||||
put(0, 0, a); //TODO: check ret val!
|
put(0, 0, a); //TODO: check ret val!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fromArray(int offset, int length, byte...a) {
|
||||||
|
if (offset < 0)
|
||||||
|
throw new IllegalArgumentException("offset < 0");
|
||||||
|
if (a == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
if (length < 0 || length + offset > a.length)
|
||||||
|
throw new IllegalArgumentException("invalid 'length' parameter: " + Integer.toString(length));
|
||||||
|
if (a.length == 0)
|
||||||
|
return;
|
||||||
|
int num = length / _channels;
|
||||||
|
alloc(num);
|
||||||
|
put(0, 0, a, offset, length); //TODO: check ret val!
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] toArray() {
|
public byte[] toArray() {
|
||||||
int num = checkVector(_channels, _depth);
|
int num = checkVector(_channels, _depth);
|
||||||
if(num < 0)
|
if(num < 0)
|
||||||
|
70
modules/core/misc/java/test/MatOfByteTest.java
Normal file
70
modules/core/misc/java/test/MatOfByteTest.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package org.opencv.test.core;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
import org.opencv.core.CvException;
|
||||||
|
import org.opencv.core.CvType;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.core.MatOfByte;
|
||||||
|
import org.opencv.core.MatOfDouble;
|
||||||
|
import org.opencv.test.OpenCVTestCase;
|
||||||
|
import org.opencv.imgcodecs.Imgcodecs;
|
||||||
|
|
||||||
|
public class MatOfByteTest extends OpenCVTestCase {
|
||||||
|
|
||||||
|
public void testMatOfSubByteArray() {
|
||||||
|
byte[] inputBytes = { 1,2,3,4,5 };
|
||||||
|
|
||||||
|
MatOfByte m0 = new MatOfByte(inputBytes);
|
||||||
|
MatOfByte m1 = new MatOfByte(0, inputBytes.length, inputBytes);
|
||||||
|
MatOfByte m2 = new MatOfByte(1, inputBytes.length - 2, inputBytes);
|
||||||
|
|
||||||
|
assertEquals(5.0, m0.size().height);
|
||||||
|
assertEquals(1.0, m0.size().width);
|
||||||
|
|
||||||
|
assertEquals(m0.get(0, 0)[0], m1.get(0, 0)[0]);
|
||||||
|
assertEquals(m0.get((int) m0.size().height - 1, 0)[0], m1.get((int) m1.size().height - 1, 0)[0]);
|
||||||
|
|
||||||
|
assertEquals(3.0, m2.size().height);
|
||||||
|
assertEquals(1.0, m2.size().width);
|
||||||
|
|
||||||
|
assertEquals(2.0, m2.get(0, 0)[0]);
|
||||||
|
assertEquals(3.0, m2.get(1, 0)[0]);
|
||||||
|
assertEquals(4.0, m2.get(2, 0)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testMatOfSubByteArray_BadArg() {
|
||||||
|
byte[] inputBytes = { 1,2,3,4,5 };
|
||||||
|
|
||||||
|
try {
|
||||||
|
MatOfByte m1 = new MatOfByte(-1, inputBytes.length, inputBytes);
|
||||||
|
fail("Missing check: offset < 0");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MatOfByte m1 = new MatOfByte(0, inputBytes.length, null);
|
||||||
|
fail("Missing check: NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MatOfByte m1 = new MatOfByte(0, -1, inputBytes);
|
||||||
|
fail("Missing check: length < 0");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MatOfByte m1 = new MatOfByte(1, inputBytes.length, inputBytes);
|
||||||
|
fail("Missing check: buffer bounds");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1863,7 +1863,7 @@ namespace {
|
|||||||
#undef JOCvT
|
#undef JOCvT
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count, char* buff)
|
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(! m) return 0;
|
||||||
if(! buff) return 0;
|
if(! buff) return 0;
|
||||||
@ -1875,14 +1875,14 @@ template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count,
|
|||||||
|
|
||||||
if( m->isContinuous() )
|
if( m->isContinuous() )
|
||||||
{
|
{
|
||||||
memcpy(m->ptr(row, col), buff, count);
|
memcpy(m->ptr(row, col), buff + offset, count);
|
||||||
} else {
|
} else {
|
||||||
// row by row
|
// row by row
|
||||||
int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row
|
int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row
|
||||||
if(count<num) num = count;
|
if(count<num) num = count;
|
||||||
uchar* data = m->ptr(row++, col);
|
uchar* data = m->ptr(row++, col);
|
||||||
while(count>0){
|
while(count>0){
|
||||||
memcpy(data, buff, num);
|
memcpy(data, buff + offset, num);
|
||||||
count -= num;
|
count -= num;
|
||||||
buff += num;
|
buff += num;
|
||||||
num = m->cols * (int)m->elemSize();
|
num = m->cols * (int)m->elemSize();
|
||||||
@ -1893,7 +1893,7 @@ template<typename T> static int mat_put(cv::Mat* m, int row, int col, int count,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ARRAY> static jint java_mat_put(JNIEnv* env, jlong self, jint row, jint col, jint count, ARRAY vals)
|
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;
|
static const char *method_name = JavaOpenCVTrait<ARRAY>::put;
|
||||||
try {
|
try {
|
||||||
@ -1904,7 +1904,7 @@ template<class ARRAY> static jint java_mat_put(JNIEnv* env, jlong self, jint row
|
|||||||
if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
|
if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
|
||||||
|
|
||||||
char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0);
|
char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0);
|
||||||
int res = mat_put<typename JavaOpenCVTrait<ARRAY>::value_type>(me, row, col, count, values);
|
int res = mat_put<typename JavaOpenCVTrait<ARRAY>::value_type>(me, row, col, count, offset, values);
|
||||||
env->ReleasePrimitiveArrayCritical(vals, values, JNI_ABORT);
|
env->ReleasePrimitiveArrayCritical(vals, values, JNI_ABORT);
|
||||||
return res;
|
return res;
|
||||||
} catch(const std::exception &e) {
|
} catch(const std::exception &e) {
|
||||||
@ -1924,7 +1924,16 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
|
|||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
|
||||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jbyteArray vals)
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jbyteArray vals)
|
||||||
{
|
{
|
||||||
return java_mat_put(env, self, row, col, count, vals);
|
return java_mat_put(env, self, row, col, count, 0, vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutBwOffset
|
||||||
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jint offset, jbyteArray vals);
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutBwOffset
|
||||||
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jint offset, jbyteArray vals)
|
||||||
|
{
|
||||||
|
return java_mat_put(env, self, row, col, count, offset, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
|
||||||
@ -1933,7 +1942,7 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
|
|||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
|
||||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jshortArray vals)
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jshortArray vals)
|
||||||
{
|
{
|
||||||
return java_mat_put(env, self, row, col, count, vals);
|
return java_mat_put(env, self, row, col, count, 0, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
|
||||||
@ -1942,7 +1951,7 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
|
|||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
|
||||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jintArray vals)
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jintArray vals)
|
||||||
{
|
{
|
||||||
return java_mat_put(env, self, row, col, count, vals);
|
return java_mat_put(env, self, row, col, count, 0, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
||||||
@ -1951,7 +1960,7 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
|||||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
||||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals)
|
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals)
|
||||||
{
|
{
|
||||||
return java_mat_put(env, self, row, col, count, vals);
|
return java_mat_put(env, self, row, col, count, 0, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
Loading…
Reference in New Issue
Block a user