Reputation: 5163
This should be simple but I'm having trouble changing some C code that uses bitwise operators and shifts into Java.
In C I have:
unsigned short Color(byte r, byte g, byte b)
{
return( ((unsigned short)g & 0x1F )<<10 | ((unsigned short)b & 0x1F)<<5 | (unsigned short)r & 0x1F);
}
This function, Color, returns 16bits where 15 of them represent three 5bit values for red, green, and blue color channels. I'm trying to do something similar in Java except I'm having trouble with data types.
In java I have:
int r=someval, g=anotherval, b=yetanotherval;
And I want to convert these integers to a 2byte data type and use the same bitwise/shift operations as above.
What is the best way to approach this? I was thinking of a 2byte array but that seems unnecessary.
edit
So I gave it a try in Java with shorts but there still seems to be an issue. I started simple with:
short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;
But the compiler complains: "cannot convert from int to short"
Upvotes: 2
Views: 4179
Reputation: 34014
In your example
short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;
Both g and the hex literal get automatically promoted to int
because the logical and operator always works on and returns integers. You can of course cast the result back to short
.
short colorData = (short)(g & 0x001F);
The same should work for the char
datatype, which is in fact the only unsigned integer type on the JVM. I would recommend against using the char type in this way, unless this is an isolated performance/memory sensitive part of your program, since using char
for arithmetic might seem strange and counterintuitive for other maintainers of the source.
Upvotes: 2
Reputation: 399813
You have the short
type in Java as well, but it's always signed, there is no unsigned in Java.
Therefore, it might be better to use an int
, so you don't need to use the sign bit to hold actual color data, which can be a bit (no pun intended!) confusing.
This should work as a starting point, at least:
int Color(int r, int g, int b)
{
return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}
I made the arguments int
as well, for simplicity's sake.
Update: It sounds (and seems) as if you can actually use short
, since you only need 15 bits for the color format. Then let's do that:
short Color(short r, short g, short b)
{
return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}
I haven't tried compiling the above, but it's likely that you'll get conversion errors and will need to add explicit short
casts throughout to make it compile.
Upvotes: 2
Reputation: 29468
In java, all calculation operations, even with only types smaller than int, always result to an int, so you have to explicitly cast it back to short:
short colorData = (short)(g & 0x001F);
Upvotes: 2
Reputation: 11977
Since you are using only 15 bits, the sign bit on the short
data type will be no problem.
Upvotes: 1
Reputation: 1371
char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).
http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
The Java char datatype is 2 bytes by default.
Upvotes: 1