I am trying to create an image from a binary file. The file contains a 32x32 icon and its corresponding 16 colors palette.
Specification
The icon is 512 bytes long. The icon is separated in 4x4 tiles. Each tile is 4x8 bytes.
Here's the 4x8 arrangement of bytes for a single tile:
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
Here's the bits expanded from the above bytes:
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
Breaking each byte into four pixels each gives the following tile:
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
Each 4 bit is the index of the color in the palette.
The color palette is 32 bytes long and contains 16 colors. Each color is 16bits (5 for each component while the last is unused).
Problem - Step 1
I have managed to parse the image data into an array of 512 bytes and the color palette into an array of 32 bytes. But I am not really sure how to continue from hereon.
I read all the image data bytes into a BitSet, but I am not sure if this is even useful.
Also, I don't know how to construct a color from two bytes.
Any help/suggestions/comments?
Thank you.
Problem - Step 2
So with your help I've created an IndexColorModel out of the the color palette as follows:
int[] colors = new int[16*3];
for (int i = 0; i < 16; i++) {
byte b1 = this.palette[i]; // byte 1: 5 bits of R and 3 bits of G
byte b2 = this.palette[i+1]; // byte 2: 2 bits of G and 5 bits of B and 0.
// colors are encoded in inverse order
colors[i+2] = (b2 & 0x3E) >>> // red
colors[i+1] = ((b1 & 0x07) << 2) | ((b2 & 0xC0) >> 6); // green
colors[i] = (b1 & 0xF8) >>> 3; // blue
}
IndexColorModel cm = new IndexColorModel(5, 16*3, colors, 0, false, 0, DataBuffer.TYPE_BYTE);
Now I need to create a BufferedImage from the array of bytes I have read from the binary file using the above IndexColorModel.
So far I have this:
DataBuffer buffer = new DataBufferByte(this.titleData, 32*32);
int pixelStride = 4; //assuming r, g, b, skip, r, g, b, skip...
int scanlineStride = 4*32; //no extra padding
int[] bandOffsets = {0, 1, 2}; //r, g, b
WritableRaster raster = Raster.createInterleavedRaster(buffer, 32, 32, scanlineStride, pixelStride, bandOffsets, null);
boolean isAlphaPremultiplied = false;
BufferedImage bim = new BufferedImage(cm, raster, isAlphaPremultiplied, null);
Taken from here.
this.titleData is an array of 512 bytes that where read from the binary file.
The above code throws the following exception:
Caused by: java.awt.image.RasterFormatException: Data array too small (should be 4094 )
Any help? Once again, thank you very much.