       Использование графических образов в формате PCX в
                    прикладных программах.
                               
                         О.П.Пилипенко

                         Одесса - 1991

        
                          Формат PCX

        Формат PCX, предложенный фирмой ZSoft вместе с
графическим редактором PC Paintbrush, получил широкое
распространение. Возможно, это произошло потому, что фирма
Microsoft поставляет в комплекте со своей мышью именно этот
графический редактор. Изображения в формате PCX умеют создавать
многие сканеры и факсимильные платы. Многие настольные
издательские системы понимают этот формат. Он достаточно простой
и в то же время обеспечивает хорошую степень сжатия не слишком
сложных изображений, а также высокую скорость восстановления
сжатого изображения. К его недостатком относится то, что способ
хранения изображение сильно зависит от аппаратуры, на которой
оно получено.

        
                  Структура файла формата PCX

        Файл в формате PCX состоит из заголовка длиной 128 байт
и графического изображения, сжатого методом RLE.
        
        Заголовок PCX файла можно описать на языке Turbo Pascal
следующим образом:    

    PCXHeader = record
                      PCXId        : byte;
                      VersionNo    : byte;
                      Encoding     : byte;
                      BitsPerPixel : byte;
                      XL, YL       : word;
                      XH, YH       : word;
                      XRes, YRes   : word;
                      Palette      : array[1..48] of byte;
                      Reserved     : byte;
                      NPlanes      : byte;
                      BytesPerLine : word;
                      PaletteInfo  : word;
                      Reserved2    : array[1..58] of byte
                end;

        Поле PCXId всегда содержит значение 0Ah. Отсутствие
этого признака означает, что данный файл не является файлом
формата PCX. Поле VersionNo содержит номер версии PCX формата.
Поле Encoding содержит признак метода сжатия изображения. Во
всех версиях формата, разработанных до сих пор, этот признак
равен единице, что означает, что изображение сжато методом RLE. 

        Поля XL, YL, XH, YH определяют координаты левого
верхнего и правого нижнего углов изображения. XRes и YRes в
случае изображения для видеоэкрана содержат количество пикселов
по горизонтали и вертикали для всего экрана. В случае же
изображения, построенного для принтера они содержат разрешающую
способность принтера в точках на дюйм. Каждая строка изображения
в развернутом виде содержит BytesPerLine байтов. 

        Один пиксел графического изображения может оказаться
разбросанным по разным байтам сжатого образа. Это справедливо,
например, для таких популярных режимов, как 640х350, 16 цветов
для EGA и 640х480, 16 цветов для VGA. Поле BitsPerPixel
сообщает, сколько битов в одном плане соответствует одному
пикселу. Поле NPlanes содержит количество битовых планов
изображения. Упомянутые режимы содержат по четыре плана и по
одному биту на пиксел в каждом плане.

        Поле Palette содержит информацию о палитре, примененной
при создании изображения. Сорока восьми байтов как раз хватает
для описания палитры до шестнадцати цветов включительно. Если
цветов больше, например 256, палитра хранится в файле сразу за
сжатым графическим изображением. Поле PaletteInfo показывает тип
палитры для данного изображения.

        
                       RLE - кодирование

        Для сжатия графического изображения в формате PCX
применяется метод RLE - метод групового кодирования. Цепочка
одинаковых байтов заменяется на два байта - счетчик количества
повторов и повторяемое значение. Два старших бита счетчика
количества повторов всегда установлены в единицу. Это позволяет
отличить его от байтов с видеоданными. Остальные биты содержат
количество повторов - от 1 до 63. Если же требуется закодировать
один байт, у которого два старших бита установлены, приходится
предварять его счетчиком, содержащим количество повторений 1.

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

        
            Восстановление черно-белого изображения

        Теперь, когда мы обогащены знаниями о характере данных,
хранимых в файле PCX, попробуем восстановить изображение из
такого файла.

        Рассмотрим листинг 1. Программа ShowBWPCX осуществляет
восстановление черно-белого изображения из файла в формате PCX.
Программа предназначена для работы с видеоадаптерами EGA и VGA.

        В программе определены два буфера. В буфер DiskBuf по
мере надобности подгружается с диска содержимое файла. Этот
процесс осуществляет процедура NextBlock. По мере заполнения
буфера ScrBuf восстановленным изображением процедура ShowLine
выводит его содержимое на экран. Процедура ExpandBW осуществляет
раскодирование данных, закодированных методом RLE и управляет
процедурами работы с буферами.

        
  Восстановление цветного и черно-белого изображения для CGA
        
        Учитывая распространенность компьютеров класса XT с
видеоадаптерами CGA, я решил включить в свою статью этот раздел.

        Черно-белое изображение для CGA хранится точно так же,
как и для черно-белых режимов EGA/VGA с 640 пикселами в строке.
Отличие в способе вывода восстанавливаемого изображения на экран
объясняется тем, что видеопамять CGA разворачивается на экран
через строку. 

        В случае четырехцветного изображение в режиме 320х200
пикселов для CGA каждый пиксел кодируется двумя битами.
Изображение в этом режиме разворачивается на экран точно также.
Достаточно лишь в зависимости от значения поля BitsPerPixel
заголовка файла установить требуемый режим.

        Программа ShowCGAPCX, представленная в листинге 2,
позволяет визуализировать цветные и черно-белые изображения для
видеоадаптера CGA.
        
        
        Восстановление цветного изображения для EGA/VGA

        Теперь я подробнее остановлюсь на способе хранения
цветных изображений для наиболее популярных режимов
видеоадаптеров EGA и VGA - 16 цветов, 640х350 или 640х480
пикселов. 

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

        В формате PCX для каждой строки изображение
последовательно хранится содержимое четырех плоскостей
видеопамяти. 

        Для того, чтобы восстановленное изображение полностью
соответствовало задуманному, необходимо установить палитру,
сохраненную в файле формата PCX.

        Режимы 640х350 и 640х480 позволяют изображать
одновременно шестнадцать цветов из 64-цветной палитры. Для
установки палитры через функцию BIOS или непосредственно через
порты видеоадаптера необходимо подготовить таблицу из
шестнадцати 6-битовых чисел.

        В заголовке же файла формата PCX палитра хранится иначе.
Каждому значению пиксела соответствуют три числа, задающих
интенсивность красного, синего и зеленого в оттенке,
соответствующем данному значению.

        На листинге 3 приведена программа, позволяющая
восстанавливать шестнадцатицветное изображение. Программа
ShowCoPCX весьма похожа на программу ShowBWPCX. Существенно
изменилась лишь процедура ShowLine. Обратите внимание, что эта
процедура выводит содержимое буфера изображения по четыре раза
на каждую строку. Регистр маски битовой плоскости определяет, в
какую плоскость выводятся данные.

        В программе появилась новая процедура - SetSavedPalette.
Эта процедура перекодирует в приемлемый формат палитру,
хранящуюся в заголовке файла, и устанавливает ее с помощью
функции SetAllPalette языка Turbo Pascal.

        
                          Заключение

        Естественно, что в одной журнальной статье я не смог
осветить все тонкости формата PCX. Я не описал формат PCX файла
для случая 256 цветов и не предложил способа визуализации на
экране дисплея файлов, подготовленных для лазерного принтера.

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