ImageUtility.TargaImage.LoadImageBytes C# (CSharp) Method

LoadImageBytes() private method

Reads the image data bytes from the file. Handles Uncompressed and RLE Compressed image data. Uses FirstPixelDestination to properly align the image.
private LoadImageBytes ( BinaryReader binReader ) : byte[]
binReader System.IO.BinaryReader A BinaryReader that points the loaded file byte stream.
return byte[]
        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

                    }

                    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
                    }

                    // 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;
        }