Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get short[] from a ByteBuffer

I am using JNI code in an Android project in which the JNI native function requires a short[] argument. However, the original data is stored as a ByteBuffer. I'm trying the convert the data format as follows.

ByteBuffer rgbBuf = ByteBuffer.allocate(size);
...    
short[] shortArray = (short[]) rgbBuf.asShortBuffer().array().clone();

But I encounter the following problem when running the second line of code shown above:

E/AndroidRuntime(23923): Caused by: java.lang.UnsupportedOperationException
E/AndroidRuntime(23923): at Java.nio.ShortToByteBufferAdapter.protectedArray(ShortToByteBufferAdapter.java:169)

Could anyone suggest a means to implement the conversion?

like image 227
bei Avatar asked Aug 13 '12 08:08

bei


People also ask

How do I get data from ByteBuffer?

The get() method of java. nio. ByteBuffer class is used to read the byte at the buffer's current position, and then increments the position. Return Value: This method returns the byte at the buffer's current position.

How do I get strings from ByteBuffer?

The toString() method of ByteBuffer class is the inbuilt method used to returns a string representing the data contained by ByteBuffer Object. A new String object is created and initialized to get the character sequence from this ByteBuffer object and then String is returned by toString().

How do I get ByteBuffer length?

After you've written to the ByteBuffer, the number of bytes you've written can be found with the position() method. If you then flip() the buffer, the number of bytes in the buffer can be found with the limit() or remaining() methods.

What is the byte order of ByteBuffer?

By default, the order of a ByteBuffer object is BIG_ENDIAN. If a byte order is passed as a parameter to the order method, it modifies the byte order of the buffer and returns the buffer itself. The new byte order may be either LITTLE_ENDIAN or BIG_ENDIAN.


2 Answers

The method do this is a bit odd, actually. You can do it as below; ordering it is important to convert it to a short array.

short[] shortArray = new short[size/2];
rgbBuf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortArray);

Additionally, you may have to use allocateDirect instead of allocate.

like image 188
Cat Avatar answered Oct 13 '22 01:10

Cat


I had the same error with anything that used asShortBuffer(). Here's a way around it (adapted from 2 bytes to short java):

short[] shortArray = new short[rgbBuf.capacity() / 2]);
for (int i=0; i<shortArray.length; i++)
{   
    ByteBuffer bb = ByteBuffer.allocate(2);
    bb.order(ByteOrder.LITTLE_ENDIAN);
    bb.put(rgbBuf[2*i]);
    bb.put(rgbBuf[2*i + 1]);
    shortArray[i] = bb.getShort(0);
}
like image 39
Hari Honor Avatar answered Oct 12 '22 23:10

Hari Honor