Что не так с этим декодером? (в C #) - Помощь с заполнением дополнительных байтов - PullRequest
3 голосов
/ 15 апреля 2011

У меня здесь есть декодер PCX, написанный на C #, который предназначен для возврата IntPtr, который указывает на массив несжатых байтов (файлы PCX используют сжатие RLE, но мой декодер должен быть в состоянии справиться с этим). Я уже прочитал ширину, размеры и палитру из файла, и изображение будет отображать только файл в виде растровых изображений для большинства изображений, но некоторые из них отображаются неправильно. Изображение есть, как и цвета, но фактическое растровое изображение выглядит так, как будто оно было разрезано по диагонали 4 или 5 раз и переставлено. Я проверил количество плоскостей на изображении, и с bpp тоже все в порядке.

Я предполагаю, что с моим кодом что-то не так, поэтому, если кто-то увидит ошибку, не могли бы вы сообщить мне, пожалуйста.


РЕДАКТИРОВАТЬ 2:

Как указывает Гуффа, я не занимаюсь заполнением. Может ли кто-нибудь указать мне правильное направление по этому поводу?


Код (извините, здесь совсем немного, но это фактический пиксельный процессор):

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;

1 Ответ

1 голос
/ 15 апреля 2011

Во-первых, вы неправильно распределяете неуправляемые ресурсы (например, BinaryReader). Либо позвоните r.Dispose() после того, как закончите, либо оберните его в блок использования, например:

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

И всегда делайте это для любого объекта, который реализует IDisposable .

...