I have followed the TGA specs described here (the info at the end of the page is what this method is based on) and have written a method that takes a TGA file's pixel data section and creates a bitmap out of it.
It works, but the code looks sloppy. Particularly, when I'm actually reading the bytes. You'll notice that I do some sort of odd foreach
loop in order to repeatly add the same bytes to my array.
Here's the method that reads the pixels. It returns an array of bytes representing the pixels.
Is there a way for me to re-write the inner loop in the 128
case to NOT use a foreach in order to set the same sequence of bytes to an array? I imagine I will find myself putting bytes into an array often and it would be nice to know other ways to do it.
private byte[] getImageType10()
{
// header stores total bits per pixel
int bytesPerPixel = header.bpp / 8;
int total = header.width * header.height * bytesPerPixel;
// number of bytes we've read so far
int count = 0;
int repeat;
byte packetHdr;
int packetType;
// temp storage
byte[] bytes;
byte[] pixData = new byte[total];
while (count < total)
{
packetHdr = inFile.ReadByte();
packetType = packetHdr & (1 << 7);
// RLE packet
if (packetType == 128)
{
// packet stores number of times following pixel is repeated
repeat = (packetHdr & ~(1 << 7)) + 1;
bytes = inFile.ReadBytes(bytesPerPixel);
for (int j = 0; j < repeat; j++)
{
foreach (byte b in bytes)
{
pixData[count] = b;
count += 1;
}
}
}
// raw packet
else if (packetType == 0)
{
// packet stores number of pixels that follow
repeat = ((packetHdr & ~(1 << 7)) + 1) * bytesPerPixel;
for (int j = 0; j < repeat; j++)
{
pixData[count] = inFile.ReadByte();
count += 1;
}
}
}
return pixData;
}