Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Загрузка PCX


Автор: Fixin 23.6.2005, 19:02
Вот код загрузки рсх:
Код
k = 0;
    for (y=0 ; y < yy; y++)
    {
        for (x=0; x < xx;)
        {
            dataByte = raw[k++];
            if((dataByte & 0xC0) == 0xC0)
            {
                runLength = dataByte & 0x3F;
                dataByte = raw[k++];
            }
            else
                runLength = 1;
            while(runLength-- > 0)
                pix[y*xx + x++] = dataByte;
        }
    }
"raw" - указатель на облать памяти, где находятся байты данных рсх-а, а "pix" - новообразуемое прямоуголное изображение. Но "прямоугольное" оно только предполагаемо. Строки в рсх-ах выравнены до слова (2 байта), т.е. есть вероятность нахождения в конце каждой строки одного "лишнего" байта, который нужно пропустить.
1) ГДЕ и КОГДА его надо пропускать? ИЛИ
2) Есть свои загрузчики?

Добавлено @ 19:03
Наверное, это надо в "Общие" отправить.

Автор: _hunter 23.6.2005, 19:38
есть у меня подозрение что это код загрузки BMP-шника...
тогда у тебя есть реальная длина картинки и, сответственно, в цикле for (x=0; x < xx;) нужно бежать до нее ( умножив на у ) а в конце цикла прибавляеш к индексу 4 - длина строки % 4
кажись все...

Автор: Earnest 23.6.2005, 19:57
Вот, может сгодится...
Код древний, поэтому что там к чему - уже не помню, но точно работает, потому как взят из работающей программы

Код

void CPCXReader::DecodeLine8 (std::istream& in, LPBYTE pDst) 
{
    int nLineRemainder = m_Pcxh.bplin * m_Pcxh.plans;  //счетчик числа байтов, к-рые нужно записать в строку
    if (m_nCnt && m_Pcxh.plans!=3)    
   {    //заполняем начало строки данными, оставшимися от предыдущей строки
      int nQBts = min ((int)m_nCnt, nLineRemainder);
      memset (pDst, m_nCur, nQBts);
      pDst += nQBts;
      nLineRemainder -= nQBts;
        m_nCnt -= nQBts;
    }

    //цикл декомпрессии строки растра
    while (nLineRemainder > 0)    
   {  ASSERT (m_nCnt == 0);
      //текущий символ и счетчик повторений
        in.read ((char*)&m_nCur, 1);

        //если текущий символ является счетчиком декомпрессии
        if ((m_nCur & 0xc0) == 0xc0)    
      {    //вычисляем его значение
            m_nCnt = max (1, m_nCur & 0x3f);
            //берем новый байт со следующей позиции файла
           in.read ((char*)&m_nCur, 1);

         int nQBts = min ((int)m_nCnt, nLineRemainder);
         memset (pDst, m_nCur, nQBts);
         pDst += nQBts;
         nLineRemainder -= nQBts;
           m_nCnt -= nQBts;
      }
      else
      {  *pDst++ = m_nCur;
         --nLineRemainder;
      }
    }
}

Автор: Fixin 24.6.2005, 19:59
Цитата
что это код загрузки BMP-шника...
Нет, точно рсх.
2 Earnest Посмотрим...

Автор: Fixin 24.6.2005, 20:37
Вот это, я думаю, мне и поможет:
Код
int nLineRemainder = m_Pcxh.bplin * m_Pcxh.plans;

Автор: Fixin 25.6.2005, 15:58
Так там что выравнивается? Строка, после сжатия, или перед?

Автор: _hunter 25.6.2005, 16:10
явно после

Автор: cardinal 25.6.2005, 17:05
Цитата(Fixin @ 23.6.2005, 17:02)
Строки в рсх-ах выравнены до слова (2 байта), т.е. есть вероятность нахождения в конце каждой строки одного "лишнего" байта, который нужно пропустить.

Тогда получается, что кол-во байт в строке четное. Сколько байт на строку считаешь по формуле:
(длина строки в байтах + 1) / 2

Автор: _hunter 25.6.2005, 17:42
кстати... точно до слова? -- обычно ровняют до двух...

Автор: Fixin 26.6.2005, 13:16
Цитата
кстати... точно до слова? -- обычно ровняют до двух...
Так написано в статьях по рсх-ам...
Цитата
Тогда получается, что кол-во байт в строке четное. Сколько байт на строку считаешь по формуле: (длина строки в байтах + 1) / 2
Нет: либо (длина строки в байтах), если уже четное, либо (длина строки в байтах + 1), если длина нечетная.
Цитата
явно после
Попробую...

Автор: cardinal 26.6.2005, 14:53
Цитата(Fixin @ 26.6.2005, 11:16)
Нет: либо (длина строки в байтах), если уже четное, либо (длина строки в байтах + 1), если длина нечетная.

А разница есть? smile Ты с целыми числами работаешь!

А вообще конечно надо сделать так: (длина строки в байтах + 1) / 2 * 2 (целочисленно)
Но это уже ничем не лучше, чем то, что можно сделать с простым if...

Автор: Fixin 28.6.2005, 21:09
Все, загружается. Прямо ни с того, ни с сего... Мистика какая-то smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)