gdal icon indicating copy to clipboard operation
gdal copied to clipboard

Java ReadRaster(): Is there a need for initialization after malloc?

Open tthh7 opened this issue 2 years ago • 1 comments

I use Java to call GDAL for reading raster data, and then initialize a Java array to store the raster data. However, when I pass this array to the C++ interface, the content inside the array is not the initial value. So, during debugging, I found that the data from the Java array is not copied; instead, a temporary data is generated using malloc and passed to the C++ interface for reading the raster dataset. The code is as follows: swig/java/gdal_warp.cpp arg10 = sizeof(char) * jenv->GetArrayLength(jarg9); arg9 = (char*) malloc(arg10); //arg9 = (char*) jenv->GetPrimitiveArrayCritical(jarg9, 0); if (arg9 == NULL) { SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "Unable to allocate temporary buffer."); return 0; } } { /* %typemap(in) (int nList, int* pList) / / check if is List */ if (jarg11) { arg11 = jenv->GetArrayLength(jarg11); if (arg11 == 0) arg12 = NULL; else arg12 = (int *)jenv->GetIntArrayElements(jarg11, NULL); } else { arg11 = 0; arg12 = NULL; } } arg13 = (int)jarg13; arg14 = (int)jarg14; arg15 = (int)jarg15; result = (CPLErr)GDALDatasetShadow_ReadRaster__SWIG_0(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15);

Steps to reproduce the problem.

In the above code, is it necessary to initialize after malloc? Why not directly use the array passed in from Java?

Operating system

centos7

GDAL version and provenance

gdal 2.2.3

tthh7 avatar Dec 13 '23 04:12 tthh7

In the above code, is it necessary to initialize after malloc?

hum.. if you pass a fully contiguous array (that is nPixelSpace, nLineSpace, nBandSpace describe a contiguous array), this should'nt be necessary. But if not, then the issue is more than the SetByteArrayRegion() after GDALDatasetShadow_ReadRaster__SWIG_0() will overwrite elements it shouldn't.

Why not directly use the array passed in from Java?

I believe the issue is that otherwise we need to call a JNI primitive GetPrimitiveArrayCritical() which blocks JNI for other threads.

Rather than using ReadRaster(), I'd suggest ReadRaster_Direct() : https://gdal.org/java/org/gdal/gdal/Dataset.html#ReadRaster_Direct(int,int,int,int,int,int,int,java.nio.ByteBuffer,int%5B%5D)

rouault avatar Dec 13 '23 11:12 rouault