Native memory backed BufferedImage with NIO

R

Roland Richter

Dear all,

I work on an application which grabs/creates images in a native DLL
(written in C++, using Intel's IPP) and displays them in a Java
Swing GUI, using a class which displays a given BufferedImage.

This, of course, involves some conversions:

1) On the Java side: Call
((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData()
to obtain a "pointer" to the byte array which backs the BufferedImage.

2) Pass that pointer to the JNI side and copy the contents of the native
image into that arry, something like
env->SetByteArrayRegion( (jbyteArray)target, 0, size, native_data );

I wonder whether copying in step 2) could be avoided.

java.nio is said to provide direct byte buffers for exactly this purpose.
However, I could not figure out the details, so I need some help.

Seems like there are two possibilites:

1) On the JNI side, create a ByteBuffer with NewDirectByteBuffer();
hopefully, this buffer is backed by an array (??!), so that one
can call the array() method on the Java side and use this byte[]
to create a BufferedImage.

2) Create a memory mapped file / MappedByteBuffer on the Java side;
get its address calling GetDirectBufferAddress() on the JNI side,
and use this memory area for the native images.

Both approaches seem error-prone to me; sure I'm missing something???

Any help is highly appreciated.


- Roland
 
G

Gordon Beaton

1) On the JNI side, create a ByteBuffer with NewDirectByteBuffer();
hopefully, this buffer is backed by an array (??!), so that one
can call the array() method on the Java side and use this byte[]
to create a BufferedImage.

Almost right, except that *you* allocate the native array, then
provide its address and size to NewDirectByteBuffer().
2) Create a memory mapped file / MappedByteBuffer on the Java side;
get its address calling GetDirectBufferAddress() on the JNI side,
and use this memory area for the native images.

I've never tried this, but your description sounds about right.

/gordon
 
R

Roland Richter

Gordon Beaton said:
1) On the JNI side, create a ByteBuffer with NewDirectByteBuffer();
hopefully, this buffer is backed by an array (??!), so that one
can call the array() method on the Java side and use this byte[]
to create a BufferedImage.

Almost right, except that *you* allocate the native array, then
provide its address and size to NewDirectByteBuffer().

I'm a little bit confused.

From the allocateDirect(int) documentation:

"Allocates a new direct byte buffer. [...]
Whether or not it has a backing array is unspecified."

The documentation on NewDirectByteBuffer() does not even state
whether the created byte buffer has a backing array or not.

So, if I understand your comment correctly, it always has?
Which buffers won't have a backing array then?

- Roland
 
G

Gordon Beaton

I'm a little bit confused.

From the allocateDirect(int) documentation:

"Allocates a new direct byte buffer. [...]
Whether or not it has a backing array is unspecified."

Since ByteBuffer (which allocateDirect() refers to) is abstract, I
guess the existence of a backing array depends on the particular
subclass implementation.
The documentation on NewDirectByteBuffer() does not even state
whether the created byte buffer has a backing array or not.

The ByteBuffer created by NewDirectByteBuffer() is backed by the array
that you provide. If you provide one, it will have one. I think this
much is clear.

But note too that ByteBuffer.hasArray() returns false if the backing
array is read-only. That could be the case if you create a
MappedByteBuffer from a read-only file, or if the pointer you pass to
NewDirectByteBuffer() refers to read-only memory.

[...]
Which buffers won't have a backing array then?

Except for the read-only comment above, I'm not really sure.

/gordon
 
R

Roland Richter

Gordon said:
The ByteBuffer created by NewDirectByteBuffer() is backed by the array

Just for clarifiction: the array I provide is at the native side ...
that you provide. If you provide one, it will have one. I think this
much is clear.

... and, unfortunately, the created ByteBuffer is NOT backed by
an array at the Java side (i.e. ByteBuffer.hasArray() is false).

I tried that today, and additionaly found this post:
http://forum.java.sun.com/thread.jsp?forum=52&thread=276504

In another post
http://forum.java.sun.com/thread.jsp?forum=4&thread=437539
it is suggested to implement a version of DataBuffer which is
backed by a (Mapped)ByteBuffer *gasp* ...


- Roland
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top