3 messages in net.java.dev.jna.usersRe: [jna-users] IndexOutOfBoundsExcep...
FromSent OnAttachments
Mark FortnerJul 8, 2008 12:50 pm 
Michael Brewer-DavisJul 8, 2008 1:02 pm 
Mark FortnerJul 9, 2008 9:16 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] IndexOutOfBoundsException when getting byte arrayActions...
From:Mark Fortner (phid@gmail.com)
Date:Jul 9, 2008 9:16:26 am
List:net.java.dev.jna.users

Thanks Michael. That did the trick!

Mark

On Tue, Jul 8, 2008 at 1:03 PM, Michael Brewer-Davis < mich@tech4learning.com> wrote:

Use PointerByReference.getValue() to get the referenced value.

(PointerByReference.getPointer() gets the pointer to the memory in which that value is stored.)

Mark Fortner wrote:

I'm trying to use JNA to call the J2KCodec (a JPEG2000 library). The C function that I'm calling has this signature:

J2K_CODEC_API(void*) J2K_EasyDecode(char *filename, unsigned char **buffer, int *width, int *height, int *components, char *options);

Basically the function returns a pointer to a buffer containing the image data, as well as the height, width, and number of components of the image.

I used the PointerByReference class to access the buffer as shown in the example on the JNA site:

PointerByReference bufferPointer = new PointerByReference(); IntByReference size = new IntByReference(); IntByReference pitch = new IntByReference(); IntByReference width = new IntByReference(); IntByReference height = new IntByReference(); IntByReference components = new IntByReference();

String options = "bpp=4,co=RGB,rl=1";

int decode = J2KCodecLibrary.INSTANCE.easyDecode(srcFile.getAbsolutePath(), bufferPointer, width, height, components, options);

this.width = width.getValue(); this.height = height.getValue(); int comp = components.getValue(); int arraySize = this.width * this.height * comp * 4;

Pointer bufp = bufferPointer.getPointer(); byte[] imageArray = bufp.getByteArray(0, arraySize);

And I get this message:

java.lang.IndexOutOfBoundsException: Bounds exceeds available space : size=4, offset=299520 at com.sun.jna.Memory.boundsCheck(Memory.java:149) at com.sun.jna.Memory.read(Memory.java:166) at com.sun.jna.Pointer.getByteArray(Pointer.java:566) at

com.l3com.imageio.j2kcodec.J2KCodecImageReader.read(J2KCodecImageReader.java:216) at javax.imageio.ImageReader.read(Unknown Source) at com.l3com.imageio.gui.J2KViewer.renderImage(J2KViewer.java:146) at com.l3com.imageio.gui.J2KViewerTest.testViewImage(J2KViewerTest.java:303)

As I understand it, the native code is responsible for allocating the memory for the byte array, and JNA is merely accessing that memory. So, why does the bounds check compare the size of the pointer against the size of the array? The pointer is pointing to the beginning of the array, why do I care how big the pointer is? More importantly, why does JNA care how big the pointer is?

Secondly, how do I fix this? Is there some other approach I should be taking to calling the C-function?

My library declaration looks like this

public interface J2KCodecLibrary extends StdCallLibrary { J2KCodecLibrary INSTANCE = (J2KCodecLibrary) Native.loadLibrary("j2k-codec", J2KCodecLibrary.class, FUNCTION_MAP);

public interface J2K_CODEC_API extends Callback { void callback(int signal); }

int startLogging(int level, int append); void stopLogging();

int openMemory(Pointer imagePointer, int src_size); J2K_CODEC_API openFile(String filename); int decode(Pointer imagePointer, PointerByReference bufp , IntByReference size, String options, IntByReference pitch);

int getInfo(Pointer imagePointer, IntByReference width, IntByReference height, IntByReference components); int easyDecode(String filename, PointerByReference bufp, IntByReference width, IntByReference height, IntByReference components, String options); String getErrorString(int errCode); }

blog: http://feeds.feedburner.com/jroller/ideafactory