private byte[] LoadImageBytes(BinaryReader binReader)
{
// read the image data into a byte array
// take into account stride has to be a multiple of 4
// use padding to make sure multiple of 4
byte[] data = null;
if (binReader != null && binReader.BaseStream != null && binReader.BaseStream.Length > 0 && binReader.BaseStream.CanSeek == true) {
if (this.objTargaHeader.ImageDataOffset > 0) {
// padding bytes
byte[] padding = new byte[this.intPadding];
MemoryStream msData = null;
// seek to the beginning of the image data using the ImageDataOffset value
binReader.BaseStream.Seek(this.objTargaHeader.ImageDataOffset, SeekOrigin.Begin);
// get the size in bytes of each row in the image
int intImageRowByteSize = (int)this.objTargaHeader.Width * ((int)this.objTargaHeader.BytesPerPixel);
// get the size in bytes of the whole image
int intImageByteSize = intImageRowByteSize * (int)this.objTargaHeader.Height;
// is this a RLE compressed image type
if (this.objTargaHeader.ImageType == ImageType.RUN_LENGTH_ENCODED_BLACK_AND_WHITE ||
this.objTargaHeader.ImageType == ImageType.RUN_LENGTH_ENCODED_COLOR_MAPPED ||
this.objTargaHeader.ImageType == ImageType.RUN_LENGTH_ENCODED_TRUE_COLOR) {
#region COMPRESSED
// RLE Packet info
byte bRLEPacket = 0;
int intRLEPacketType = -1;
int intRLEPixelCount = 0;
byte[] bRunLengthPixel = null;
// used to keep track of bytes read
int intImageBytesRead = 0;
int intImageRowBytesRead = 0;
// keep reading until we have the all image bytes
while (intImageBytesRead < intImageByteSize) {
// get the RLE packet
bRLEPacket = binReader.ReadByte();
intRLEPacketType = Utilities.GetBits(bRLEPacket, 7, 1);
intRLEPixelCount = Utilities.GetBits(bRLEPacket, 0, 7) + 1;
// check the RLE packet type
if ((RLEPacketType)intRLEPacketType == RLEPacketType.RUN_LENGTH) {
// get the pixel color data
bRunLengthPixel = binReader.ReadBytes((int)this.objTargaHeader.BytesPerPixel);
// add the number of pixels specified using the read pixel color
for (int i = 0; i < intRLEPixelCount; i++) {
foreach (byte b in bRunLengthPixel)
row.Add(b);
// increment the byte counts
intImageRowBytesRead += bRunLengthPixel.Length;
intImageBytesRead += bRunLengthPixel.Length;
// if we have read a full image row
// add the row to the row list and clear it
// restart row byte count
if (intImageRowBytesRead == intImageRowByteSize) {
rows.Add(row);
row = new System.Collections.Generic.List<byte>();
intImageRowBytesRead = 0;
}
}
} else if ((RLEPacketType)intRLEPacketType == RLEPacketType.RAW) {
// get the number of bytes to read based on the read pixel count
int intBytesToRead = intRLEPixelCount * (int)this.objTargaHeader.BytesPerPixel;
// read each byte
for (int i = 0; i < intBytesToRead; i++) {
row.Add(binReader.ReadByte());
// increment the byte counts
intImageBytesRead++;
intImageRowBytesRead++;
// if we have read a full image row
// add the row to the row list and clear it
// restart row byte count
if (intImageRowBytesRead == intImageRowByteSize) {
rows.Add(row);
row = new System.Collections.Generic.List<byte>();
intImageRowBytesRead = 0;
}
}
}
}
#endregion COMPRESSED
} else {
#region NON-COMPRESSED
// loop through each row in the image
for (int i = 0; i < (int)this.objTargaHeader.Height; i++) {
// loop through each byte in the row
for (int j = 0; j < intImageRowByteSize; j++) {
// add the byte to the row
row.Add(binReader.ReadByte());
}
// add row to the list of rows
rows.Add(row);
// create a new row
row = new System.Collections.Generic.List<byte>();
}
#endregion NON-COMPRESSED
}
// flag that states whether or not to reverse the location of all rows.
bool blnRowsReverse = false;
// flag that states whether or not to reverse the bytes in each row.
bool blnEachRowReverse = false;
// use FirstPixelDestination to determine the alignment of the
// image data byte
switch (this.objTargaHeader.FirstPixelDestination) {
case FirstPixelDestination.TOP_LEFT:
blnRowsReverse = false;
blnEachRowReverse = true;
break;
case FirstPixelDestination.TOP_RIGHT:
blnRowsReverse = false;
blnEachRowReverse = false;
break;
case FirstPixelDestination.BOTTOM_LEFT:
blnRowsReverse = true;
blnEachRowReverse = true;
break;
case FirstPixelDestination.BOTTOM_RIGHT:
case FirstPixelDestination.UNKNOWN:
blnRowsReverse = true;
blnEachRowReverse = false;
break;
}
// write the bytes from each row into a memory stream and get the
// resulting byte array
using (msData = new MemoryStream()) {
// do we reverse the rows in the row list.
if (blnRowsReverse == true)
rows.Reverse();
// go through each row
for (int i = 0; i < rows.Count; i++) {
// do we reverse the bytes in the row
if (blnEachRowReverse == true)
rows[i].Reverse();
// get the byte array for the row
byte[] brow = rows[i].ToArray();
// write the row bytes and padding bytes to the memory streem
msData.Write(brow, 0, brow.Length);
msData.Write(padding, 0, padding.Length);
}
// get the image byte array
data = msData.ToArray();
}
} else {
this.ClearAll();
throw new Exception(@"Error loading file, No image data in file.");
}
} else {
this.ClearAll();
throw new Exception(@"Error loading file, could not read file from disk.");
}
// return the image byte array
return data;
}