Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with this decoder? (in C#) - Help with padding extra bytes

I have a PCX decoder here, written in C#, that is designed to return an IntPtr, which points to an array of uncompressed bytes (PCX files use RLE compression, but my decoder should be able to deal with this). I have already read the width, dimensions and palette from the file and the image will render just file as a bitmaps for most images, but some don't render correctly. The image is there and so are the colours, but the actual bitmap looks like it has been sliced diagonally 4 or 5 times and rearranged. I have checked the number of planes in the image and the bpp is fine too.

I assume it's something wrong with my code, so if anyone can see an error, could you let me know please.


EDIT 2:

As Guffa points out, I am not handling any padding. Could anyone point me in the right direction about this?


The code (sorry, there's quite a bit here, but it's the actual pixel-processor):

IntPtr pBits;
Boolean bRepeat;
Int32 RepeatCount;
Byte ReadByte;
Int32 Row = 0;
Int32 Col = 0;

Byte[] PCXData = new Byte[BytesPerScanline * ScanLines]; //BytesPerScanline * ScanLines);

BinaryReader r = new BinaryReader(file);
r.BaseStream.Seek(128, SeekOrigin.Begin);

while (Row < ScanLines)
{
    ReadByte = r.ReadByte();
    bRepeat = (0xc0 == (ReadByte & 0xC0));
    RepeatCount = (ReadByte & 0x3f);

    if (!(Col >= BytesPerScanline))
    {
        if (bRepeat)
        {
            ReadByte = r.ReadByte();
            while (RepeatCount > 0)
            {
                PCXData[(Row * BytesPerScanline) + Col] = ReadByte;
                RepeatCount -= 1;
                Col += 1;
            }
        }
        else
        {
            PCXData[(Row * BytesPerScanline) + Col] = ReadByte;
            Col += 1;
        }
    }

    if (Col >= BytesPerScanline)
    {
        Col = 0;
        Row += 1;
    }
}

pBits = System.Runtime.InteropServices.Marshal.AllocHGlobal(PCXData.Length);
System.Runtime.InteropServices.Marshal.Copy(PCXData, 0, pBits, PCXData.Length);

return pBits;
like image 670
user646265 Avatar asked Feb 03 '26 21:02

user646265


1 Answers

For one thing, you're not properly disposing of your unmanaged resources (e.g. BinaryReader). Either call r.Dispose() after you're done with it, or wrap it in a using block, like this:

using(BinaryReader r = new BinaryReader(file))
{
  ...
}

And always do this for any object that implements IDisposable.

like image 68
Kon Avatar answered Feb 05 '26 12:02

Kon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!