displaying BMP 16 bit R5 G6 B5 image

I am trying to display BMP 16 bit R5 G6 B5 image modifing BMPlib (http://www.osbald.co.uk) with no success

This is the code I have:

Image unpack16_565(byte[] rawData, int scanlineSize) {

int b = 0, k = 0, x = 0, y = 0;
byte red,green,blue;
int[] data = new int[bmp_infoheader.biWidth * bmp_infoheader.biHeight];

try {
for (y = 0; y < bmp_infoheader.biHeight; y++) {
b = (bmp_infoheader.biHeight - 1 - y) * bmp_infoheader.biWidth;
k = y * scanlineSize;

for (x = 0; x < bmp_infoheader.biWidth; x++) {

red = (byte) (rawData[k]>>3);

green = (byte) ((byte) (((rawData[k++]&0x7))<<3)|(rawData[k]>>5));

blue = (byte) ((byte) rawData[k++]&0x1f);

data[x + b] = 0xFF000000 | (((int)(red)) & 0xFF) | (((int)green) & 0xFF) << 8
| (((int)blue) & 0xFF) << 16;

}
}
} catch (Exception e) {
}
;
return Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(bmp_infoheader.biWidth, bmp_infoheader.biHeight, ColorModel.getRGBdefault(),
data, 0, bmp_infoheader.biWidth));

}

As far as I understand I have a byte[] of BMP. So I have to use bit operations to get from two bytes, 3 colors of the pixel

8 bit 8bit
[RRRRR GGG] [GGG BBBBB]
1 byte 1 byte

The result it the image with BROKEN colors.

If anybody could point what is wrong with the code, hints, links to examples, I would appreciate it…

Thanks!

Some random idees:
-bytes are signed. Be completely sure that your handeling the signed bit correctly. The easiest would be to convert it to and int. Debug it so you make to conversion correctly and you don’t end up with a negative int.
-You sould use >>> instead of >> so that the signed bit is shifted.
-red is bits 0x00ff0000 and blue is 0x000000ff. Switch the red and blue shifting when you store the final color in the int array.

thanks for your reply. I checked your homepage and your game, great project. how many lines of code it has ?

I am really not experienced with graphics.

I checked the bytes read in byte array and than every RGB for a pixel (two bytes for a pixel), they seems to be OK.

I am not really familiar with displaying images in Java.

Could you explain me an algorithm for reading 16 bit BMP and R5G6B5 ?

It that true, that

I have to read two bytes from the file, 5 first bits are Red color of the pixel, 6 next Green, 5 next Blue

How are they stored in the file ?

file
byte1 byte2 byte3 byte4

R = first 5 bits of byte1
G = last 3 bits of byte1 and first 3 bits of byte2
B = last 5 bits of byte2

Than if I read all those values I create an INT ORing R | G | B and ANDing 0xFFFF since I have two bytes pixels, and INT in java are 4 bytes ?

I was looking for an algorithm for displaying BMP 16 bit with enc. R5G6B5 but couldnt find it.

Thanks

ImageIO can read bmps. I’m not sure if 16bit also works, but it’s worth a try.

I don’t know how the bmp format works. But you can probably find the spec on The Programmer’s File Format Collection.

Each pixel is probably stored in 2 bytes in the way as you said. This is how I would do it (off the top of my head, so thre are bugs):


int highbyte = rawData[k++];
int lowbyte = rawData[k++];

// rgb16 has the color propably stored as R5G6B5
int rgb16 = ((highbyte & 0xff) << 8) | (lowbyte & 0xff);

// 16 is the number of bits that needs to shift a 8 bit red to the location in a 24 bit packed
// 11 is its position in rgb16
// 3 is because it is stored as 5 bits instead of 8 in rgb16
int red24 = (rgb16 << (16 - 11 + 3)) & 0xff0000;

int green24 = (rgb16 << (8-5+2)) & 0x00ff00
int blue24 = (rgb16 << (0-0+3)) & 0x0000ff
int rgb24 = 0xff000000 | red24 | green24 | blue24;

data[x + b] = rgb24;

THANKS!!! ;D WORKS PERFECTLY

small correction though

As I read BMP are written as little endians, so reading value 0x1234, i first read 0x34 and than 0x12

int highbyte = rawData[k++];
int lowbyte = rawData[k++];

//rgb16 has the color propably stored as R5G6B5
int rgb16 = (highbyte & 0xff) | (lowbyte & 0xff)<<8 ;