package org.lateralgm.file.iconio;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.lateralgm.file.StreamDecoder;
import org.lateralgm.file.StreamEncoder;
/**
* <p>
* ARGB bitmap with 8 bits per color (32 bits per sample).
* </p>
*
* @author © Christian Treber, ct@ctreber.com
*/
public class BitmapRGB32BPP extends AbstractBitmapRGB
{
///How far can we read before the next image? If <=0, read as far as necessary.
protected long readStreamLimit;
/**
* @param pDescriptor The image descriptor.
*/
public BitmapRGB32BPP(final BitmapDescriptor pDescriptor)
{
super(pDescriptor);
readStreamLimit = pDescriptor.getOffset() + pDescriptor.getSize();
}
/**
* According to Microsoft, the topmost byte simply is not used, but I found the fourth byte seems
* to be the alpha channel.
*
* @param pDec The decoder.
* @throws IOException
*/
void readBitmap(final StreamDecoder pDec) throws IOException
{
for (int lRowNo = 0; lRowNo < getHeight(); lRowNo++)
{
final byte[] lRow = new byte[getWidth() * 4];
pDec.read(lRow);
int lRowByte = 0;
int lOutputPos = (getHeight() - lRowNo - 1) * getWidth();
for (int lColNo = 0; lColNo < getWidth(); lColNo++)
{
// BGRA -> ARGB, 8 bits per component.
samples[lOutputPos++] = (lRow[lRowByte++] & 0xFF) | ((lRow[lRowByte++] & 0xFF) << 8)
+ ((lRow[lRowByte++] & 0xFF) << 16) | ((lRow[lRowByte++] & 0xFF) << 24);
}
}
}
/**
* 32BPP Bitmaps can optionally have NO mask.
*/
protected void readMask(final StreamDecoder pDec) throws IOException
{
if (readStreamLimit<=0 || pDec.getPos()<readStreamLimit)
{
super.readMask(pDec);
} else {
transparencyMask = new BitmapMask(descriptor);
transparencyMask.fakeRead();
}
}
/**
* @return Create an ARGB image.
*/
public BufferedImage createImageRGB()
{
final BufferedImage lImage = new BufferedImage(getWidth(),getHeight(),
BufferedImage.TYPE_INT_ARGB);
lImage.setRGB(0,0,getWidth(),getHeight(),samples,0,getWidth());
return lImage;
}
void writeBitmap(StreamEncoder out) throws IOException
{
int width = getWidth();
int padding = getPaddingPerScanLine(width,32);
for (int row = getHeight() - 1; row >= 0; row--)
{
int offset = row * width;
for (int x = 0; x < width; x++)
{
int sample = samples[offset + x];
out.write(sample & 0xFF);
out.write((sample >> 8) & 0xFF);
out.write((sample >> 16) & 0xFF);
out.write((sample >> 24) & 0xFF);
}
int i = padding;
while (i-- > 0)
out.write(0);
}
}
}