How to cram two bytes into a short?
Hi all,
I have some byte[] data that I am receiving, and I need to put two bytes into one short (or int, or whatever), as the byte[] will form a two bytes-per-pixel image. I've been working with 8-bit data (this is 12-bits, NOT packed), which is much easier to manipulate.
I currently have this method to convert a byte[] of 8-bit data into a short (I do this because Java does not support signed types and I need that 8th bit):
privateshort[] convertBytesToShorts(byte[] data){
short[] convertedData =newshort[data.length];
for (int i = 0; i < data.length; i++){
convertedData[i] = (short)((short)data[i] & 0xff);
}
return convertedData;
}
Is there a way to modify this to place two bytes into one short? Is it possible to just AND two bytes with 0xff and add them together to create one short? Surely it cannot be that simple. Also, remember that I must treat the values as unsigned.
Furthermore, the two bytes look like this:
| xxxx xxxx | xxxx 0000 |
So the last four bits in the second byte are 0s.
Any advice is appreciated.
Message was edited by:
Djaunl
[1647 byte] By [
Djaunla] at [2007-11-27 11:36:36]

You need to bit shift one of the bytes by 8 positions, then and the two bytes together.
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
> Is there a way to modify this to place two bytes into
> one short? Is it possible to just AND two bytes with
> 0xff and add them together to create one short?
> Surely it cannot be that simple.
What happened when you wrote and tested code to do just that?
> Also, remember that
> I must treat the values as unsigned.
How is that relevant? Signed or unsigned the bytes are what they are and they'll be the same when you put them into the short.
You cannot "treat" bytes or shorts as unsigned, though, because they are signed. (Well, you can kind of treat them that way--but not if you care about the numerical values.)
> So the last four bits in the second byte are 0s.
Not relevant.
jverda at 2007-7-29 17:09:42 >

Untested:
static short[] packBytesToShorts(byte[] data) {
short[] convertedData = new short[data.length/2];
for(int i = 0; i < convertedData.length; ++i) {
int result = (data[2*i] << 8) | (0xff & data[2*i+1]);
convertedData[i] = (short) result;
}
return convertedData;
}
> I've been working with 8-bit
> data (this is 12-bits, NOT packed),
Obviously that is contradictory.
> I currently have this method to convert a byte[] of
> 8-bit data into a short (I do this because Java does
> not support signed types and I need that 8th bit):
>
Yes it does. The fact that it displays a byte as and integer and the conversion in that process produces a negative display value has nothing at all to do with the bits.
> Is there a way to modify this to place two bytes into
> one short?
short s = (short)(((b1 << 8) & 0x0ff) | (b2 & 0x0ff))
Of course you still have to deal with getting the order correct.
(You can probably get rid of that first mask but you would need to test that.)
#! /usr/bin/groovy
b1 = 0xF0
b2 = 0x0F
s1 = ((b1 << 8) & 0xFF00) | (b2 & 0xFF)
assert s1 == 0xF00F
~
> assert s1 == 0xF00F
I asserted all kinds of things the last time I stepped in ox foof.
jverda at 2007-7-29 17:09:42 >

> I asserted all kinds of things the last time I
> stepped in ox foof.
It felt better than 0xFACE.
~
> > assert s1 == 0xF00F
>
> I asserted all kinds of things the last time I stepped in ox foof.
And that's usually the moment you meet that cafe babe.
> And that's usually the moment you meet that cafe babe.
Or dead beef...
~
d00d,
Why all the Groovy? Part of the current problem is getting the casting right, too.
> Why all the Groovy?
Because it's quick, expressive, and easy to see what's going on. It writes like pseudocode, but actually runs.
> Part of the current problem is
> getting the casting right, too.
I didn't see that as part of the problem, but that's really not that big of a deal, is it? Just cast the overall expression as a short.
~
> I didn't see that as part of the problem, but that's really not that big of a deal, is it? Just cast the overall expression as a short.
No, it's not a big deal, but some people may not realize that (expr1 | expr2) will never have type short.
I havent been following closely but maybe there is a much better
way to do this.
If you have a byte array where every 2 bytes is a short why not
use the NIO (or even regular IO) library?
The NIO has the advantage that you can switich Endian mode (which isnt
applicable here).
Can you grab the byte[] as a ByteArrayInputStream and call
readShort()?
import java.io.*;
public class ShortReader{
public static void main(String[] args){
byte[] data = new byte[]{
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16};
try{
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
Short s = dis.readShort();
System.out.println("Next Short: " + s);
} catch(Exception e){}
}
}
> > import java.io.*;
>
> public class ShortReader{
>
> public static void main(String[] args){
>
> byte[] data = new byte[]{
> 1, 2, 3, 4, 5, 6, 7, 8,
> 9, 10, 11, 12, 13, 14, 15, 16};
>
> try{
>
> ByteArrayInputStream bais = new
> w ByteArrayInputStream(data);
> DataInputStream dis = new DataInputStream(bais);
>
> Short s = dis.readShort();
> System.out.println("Next Short: " + s);
>
> } catch(Exception e){}
>
> }
>
> }
>
I don't see what you're getting at. Could you rephrase that in Groovy?
> > I didn't see that as part of the problem, but
> that's really not that big of a deal, is it? Just
> cast the overall expression as a short.
>
> No, it's not a big deal, but some people may not
> realize that (expr1 | expr2) will never have type
> short.
Then we might also want to cover the fact that with a given byte b, the expression (b & 0xFF) will never have the type byte, either.
> I don't see what you're getting at. Could you rephrase that in Groovy?
Someone's getting bitter... ;o)
~
import java.nio.*;
public class NIOExample {
public static void main(String[] args) {
byte[] bytes = {1,2,3,4,5,6,7,8};
ByteBuffer bb = ByteBuffer.wrap(bytes);
//bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
short[] shorts = new short[sb.remaining()];
sb.get(shorts);
for(short s : shorts)
System.out.format("%04x%n", s);
}
}
Put that in your groovy pipe and smoke it! (Who, me bitter?)
> Put that in your groovy pipe and smoke it!
import java.nio.*
// example...
byte[] data = [ 1, 2, 3, 4, 5, 6, 7, 8 ]
buffer = ByteBuffer.wrap(data).asShortBuffer()
shorts = new short[buffer.remaining()]
buffer.get(shorts)
shorts.each { printf "%04d%n", it }
:o)
~
> yawmark, FTW!
I'm not quite sure what you mean by that. Where I'm from, that's not a polite abbreviation...
~
http://www.urbandictionary.com/define.php?term=ftw
> http://www.urbandictionary.com/define.php?term=ftw
Ah, youth. I'm not hep to the new lingo. See #4 for the connotation with which I'm familiar.
~
> >
> http://www.urbandictionary.com/define.php?term=ftw
>
>
> Ah, youth. I'm not hep to the lingo.
Don't feel too bad. I have to run every second post of Mr Pests through the urban dictionary (and sometimes in desperation Babelfish) to figure out what he is saying.
cotton, wow you gotta love hyperbole.
i never realized my tongue-in-cheek use of internet detritus was
mounting up to every other post. id like to see even one other example...
"ftw" was supposed to be an obvious joke, lol.
it really is the f*cking dumbest phrase ever though.
i saw it used here a while back and its been a source of
amusement since.
Hi guys,
Thank you very much for all the helpful replies. This is my first reply, but I promise I have not forgotten about this thread; at the moment, I'm not retrieving the correct information from the service (in fact, I'm not retrieving any), so it is not possible for me to test any algorithm on the data. If I come up with a solution (or one of the ones provided here works), or if I have any questions, I will post back.
@jverd and jschell: the reason I said I must "treat the bits as unsigned" is because I do not want a negative display value, which is why I'm casting to short and ANDing the bits with 0xff. Ultimately, I will feed this data to MATLAB for processing and display, and I find it easier to cast the data to a larger holder in Java (e.g. in my example code I cast byte[] to short[]). Sorry if that was not clear.
Thanks again, and I'll post back with results.