Заполнение в декодере PCX - PullRequest
2 голосов
/ 04 декабря 2011

У меня есть декодер PCX на C # (см. Ниже), который предназначен для чтения в потоке и вывода растрового изображения. Он работает при работе с изображением, размеры которого кратны 8, и, похоже, работает с большинством изображений, размер которых меньше 8 б.п., независимо от размеров, но изображения с разными размерами искажаются необычным образом (см. эта ссылка ). Пиксели все есть, просто кажется, что они странным образом почти сдвинуты влево. Изображение является действительным PCX и открывается в IrfanView и Paint.net.

Редактировать 1:

Хорошо, вот результат небольшого тестирования: изображения с байтовым значением на строку, которое делится на 8 (например, 316x256), прекрасно декодируют, а изображения с нечетным значением - нет. Это не верно для всех файлов PCX; Казалось бы, некоторые (большинство?) изображения, созданные в IrfanView, работают нормально, а те, что я нашел в других местах, - нет. Я работал над этим некоторое время назад, поэтому я не могу вспомнить, откуда они пришли, я знаю, что изображения, сохраненные с плагином paint.net ( здесь ), также воспроизводят эту проблему. Я думаю, что это, скорее всего, связано с проблемой заполнения, либо с ними, либо с моим декодером, но изображения для декодирования нормально в другом месте, так что, скорее всего, я тот, у кого проблема, я просто не вижу, где: (

Конец редактирования 1.

Мой код для импорта здесь (много, но это весь алгоритм декодирования, за исключением заголовка, который обрабатывается отдельно):

     public IntPtr ReadPixels(Int32 BytesPerScanline, Int32 ScanLines, Stream file)
     {
     //BytesPerScanLine is the taken from the header, ScanLines is the height and file is the filestream
        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;
    }

Мне сообщили, что это может быть проблема с заполнением, но я не вижу, где это может быть в коде, и я изо всех сил пытаюсь понять, как понять, где находится заполнение.

...