/// <summary>
        /// Read a RecordRle record.
        /// </summary>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <returns>True if succeeded, otherwise false.</returns>
        private bool ReadRle(int record, int frame)
        {
            // Create buffer to hold extracted image
            records[record].Frames[frame].Width  = records[record].Width;
            records[record].Frames[frame].Height = records[record].Height;
            records[record].Frames[frame].Stride = records[record].Width;
            records[record].Frames[frame].Format = DFBitmap.Formats.Indexed;
            records[record].Frames[frame].Data   = new byte[records[record].Width * records[record].Height];

            // Find offset to special row headers for this frame
            long position = records[record].Position + records[record].DataOffset;

            position += (records[record].Height * frame) * 4;
            BinaryReader Reader = managedFile.GetReader(position);

            // Read special row headers for this frame
            SpecialRowHeader[] SpecialRowHeaders = new SpecialRowHeader[records[record].Height];
            for (int i = 0; i < records[record].Height; i++)
            {
                SpecialRowHeaders[i].RowOffset   = Reader.ReadInt16();
                SpecialRowHeaders[i].RowEncoding = (RowEncoding)Reader.ReadUInt16();
            }

            // Create row memory writer
            BinaryWriter writer = new BinaryWriter(new MemoryStream(records[record].Frames[frame].Data));

            // Extract all rows of image
            foreach (SpecialRowHeader header in SpecialRowHeaders)
            {
                // Get offset to row relative to record data offset
                position = records[record].Position + header.RowOffset;
                Reader.BaseStream.Position = position;

                // Handle row data based on compression
                if (RowEncoding.IsRleEncoded == header.RowEncoding)
                {
                    // Extract RLE row
                    byte pixel    = 0;
                    int  probe    = 0;
                    int  rowPos   = 0;
                    int  rowWidth = Reader.ReadUInt16();
                    do
                    {
                        probe = Reader.ReadInt16();
                        if (probe < 0)
                        {
                            probe = -probe;
                            pixel = Reader.ReadByte();
                            for (int i = 0; i < probe; i++)
                            {
                                writer.Write(pixel);
                                rowPos++;
                            }
                        }
                        else if (0 < probe)
                        {
                            writer.Write(Reader.ReadBytes(probe));
                            rowPos += probe;
                        }
                    } while (rowPos < rowWidth);
                }
                else
                {
                    // Just copy bytes
                    writer.Write(Reader.ReadBytes(records[record].Width));
                }
            }

            return(true);
        }
        /// <summary>
        /// Read a RecordRle record.
        /// </summary>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <returns>True if succeeded, otherwise false.</returns>
        private bool ReadRle(int record, int frame)
        {
            // Create buffer to hold extracted image
            byte[] data = new byte[records[record].Width * records[record].Height];
            records[record].Frames[frame].Width = records[record].Width;
            records[record].Frames[frame].Height = records[record].Height;

            // Find offset to special row headers for this frame
            long position = records[record].Position + records[record].DataOffset;
            position += (records[record].Height * frame) * 4;
            BinaryReader reader = managedFile.GetReader(position);

            // Read special row headers for this frame
            SpecialRowHeader[] SpecialRowHeaders = new SpecialRowHeader[records[record].Height];
            for (int i = 0; i < records[record].Height; i++)
            {
                SpecialRowHeaders[i].RowOffset = reader.ReadInt16();
                SpecialRowHeaders[i].RowEncoding = (RowEncoding)reader.ReadUInt16();
            }

            // Extract all rows of image
            int dstPos = 0;
            foreach(SpecialRowHeader header in SpecialRowHeaders)
            {
                // Get offset to row relative to record data offset
                position = records[record].Position + header.RowOffset;
                reader.BaseStream.Position = position;

                // Handle row data based on compression
                if (RowEncoding.IsRleEncoded == header.RowEncoding)
                {
                    // Extract RLE row
                    byte pixel = 0;
                    int probe = 0;
                    int rowPos = 0;
                    int rowWidth = reader.ReadUInt16();
                    do
                    {
                        probe = reader.ReadInt16();
                        if (probe < 0)
                        {
                            probe = -probe;
                            pixel = reader.ReadByte();
                            for (int i = 0; i < probe; i++)
                            {
                                data[dstPos++] = pixel;
                                rowPos++;
                            }
                        }
                        else if (0 < probe)
                        {
                            byte[] nextBytes = reader.ReadBytes(probe);
                            Array.Copy(nextBytes, 0, data, dstPos, nextBytes.Length);
                            dstPos += nextBytes.Length;
                            rowPos += probe;
                        }
                    } while (rowPos < rowWidth);
                }
                else
                {
                    // Just copy bytes
                    byte[] nextBytes = reader.ReadBytes(records[record].Width);
                    Array.Copy(nextBytes, 0, data, dstPos, nextBytes.Length);
                    dstPos += nextBytes.Length;
                }
            }

            // Assign complete data to image
            records[record].Frames[frame].Data = data;

            return true;
        }
        /// <summary>
        /// Read a RecordRle record.
        /// </summary>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <returns>True if succeeded, otherwise false.</returns>
        private bool ReadRle(int record, int frame)
        {
            // Create buffer to hold extracted image
            byte[] data = new byte[records[record].Width * records[record].Height];
            records[record].Frames[frame]         = new DFBitmap();
            records[record].Frames[frame].Width   = records[record].Width;
            records[record].Frames[frame].Height  = records[record].Height;
            records[record].Frames[frame].Palette = Palette;

            // Find offset to special row headers for this frame
            long position = records[record].Position + records[record].DataOffset;

            position += (records[record].Height * frame) * 4;
            BinaryReader reader = managedFile.GetReader(position);

            // Read special row headers for this frame
            SpecialRowHeader[] SpecialRowHeaders = new SpecialRowHeader[records[record].Height];
            for (int i = 0; i < records[record].Height; i++)
            {
                SpecialRowHeaders[i].RowOffset   = reader.ReadInt16();
                SpecialRowHeaders[i].RowEncoding = (RowEncoding)reader.ReadUInt16();
            }

            // Extract all rows of image
            int dstPos = 0;

            foreach (SpecialRowHeader SRHeader in SpecialRowHeaders)
            {
                // Get offset to row relative to record data offset
                position = records[record].Position + SRHeader.RowOffset;
                reader.BaseStream.Position = position;

                // Handle row data based on compression
                if (RowEncoding.IsRleEncoded == SRHeader.RowEncoding)
                {
                    // Extract RLE row
                    byte pixel    = 0;
                    int  probe    = 0;
                    int  rowPos   = 0;
                    int  rowWidth = reader.ReadUInt16();
                    do
                    {
                        probe = reader.ReadInt16();
                        if (probe < 0)
                        {
                            probe = -probe;
                            pixel = reader.ReadByte();
                            for (int i = 0; i < probe; i++)
                            {
                                data[dstPos++] = pixel;
                                rowPos++;
                            }
                        }
                        else if (0 < probe)
                        {
                            byte[] nextBytes = reader.ReadBytes(probe);
                            Array.Copy(nextBytes, 0, data, dstPos, nextBytes.Length);
                            dstPos += nextBytes.Length;
                            rowPos += probe;
                        }
                    } while (rowPos < rowWidth);
                }
                else
                {
                    // Just copy bytes
                    byte[] nextBytes = reader.ReadBytes(records[record].Width);
                    Array.Copy(nextBytes, 0, data, dstPos, nextBytes.Length);
                    dstPos += nextBytes.Length;
                }
            }

            // Assign complete data to image
            records[record].Frames[frame].Data = data;

            return(true);
        }
        /// <summary>
        /// Read a RecordRle record.
        /// </summary>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <returns>True if succeeded, otherwise false.</returns>
        private bool ReadRle(int record, int frame)
        {
            // Create buffer to hold extracted image
            records[record].Frames[frame].Width = records[record].Width;
            records[record].Frames[frame].Height = records[record].Height;
            records[record].Frames[frame].Stride = records[record].Width;
            records[record].Frames[frame].Format = DFBitmap.Formats.Indexed;
            records[record].Frames[frame].Data = new byte[records[record].Width * records[record].Height];

            // Find offset to special row headers for this frame
            long position = records[record].Position + records[record].DataOffset;
            position += (records[record].Height * frame) * 4;
            BinaryReader Reader = managedFile.GetReader(position);

            // Read special row headers for this frame
            SpecialRowHeader[] SpecialRowHeaders = new SpecialRowHeader[records[record].Height];
            for (int i = 0; i < records[record].Height; i++)
            {
                SpecialRowHeaders[i].RowOffset = Reader.ReadInt16();
                SpecialRowHeaders[i].RowEncoding = (RowEncoding)Reader.ReadUInt16();
            }

            // Create row memory writer
            BinaryWriter writer = new BinaryWriter(new MemoryStream(records[record].Frames[frame].Data));

            // Extract all rows of image
            foreach(SpecialRowHeader header in SpecialRowHeaders)
            {
                // Get offset to row relative to record data offset
                position = records[record].Position + header.RowOffset;
                Reader.BaseStream.Position = position;

                // Handle row data based on compression
                if (RowEncoding.IsRleEncoded == header.RowEncoding)
                {
                    // Extract RLE row
                    byte pixel = 0;
                    int probe = 0;
                    int rowPos = 0;
                    int rowWidth = Reader.ReadUInt16();
                    do
                    {
                        probe = Reader.ReadInt16();
                        if (probe < 0)
                        {
                            probe = -probe;
                            pixel = Reader.ReadByte();
                            for (int i = 0; i < probe; i++)
                            {
                                writer.Write(pixel);
                                rowPos++;
                            }
                        }
                        else if (0 < probe)
                        {
                            writer.Write(Reader.ReadBytes(probe));
                            rowPos += probe;
                        }
                    } while (rowPos < rowWidth);
                }
                else
                {
                    // Just copy bytes
                    writer.Write(Reader.ReadBytes(records[record].Width));
                }
            }

            return true;
        }