Преобразование палитры в форматы Hi-Color
Для того чтобы с палитрой можно было работать, ее надо прочитать из файла, содержащего образ рисунка, в оперативную память. Расположение палитры в файле и ее размеры зависят от стандарта хранения графических данных, которому соответствует выбранный вами файл. Никакого единообразия тут нет, но всегда остается возможность преобразовать файл в тот стандарт, с которым вы предпочитаете работать. Большинство графических редакторов позволяют сделать такое преобразование.
Способы чтения палитры файлов стандартов BMP и PCX описаны, соответственно, в Приложении А. В обоих случаях мы советовали размешать прочитанную палитру в буфере обмена, сегмент которого хранится в переменной swpseg, расположенной в разделе данных задачи.
Независимо от стандарта, для определения размера и местонахождения палитры в файле надо, прежде всего, прочитать и проанализировать его заголовок. При чтении заголовок помещается в буфер обмена, поэтому к моменту начала обработки палитры в регистре fs находится код сегмента (копия переменной Swpseg), а в si – адрес начала палитры в памяти.
При анализе заголовка файла определяются две важные величины – количество строк (цветов) в палитре и ее размер. Напомним, что он в три или в четыре раза больше количества строк. Размер нужен при чтении палитры, а количество строк – при ее преобразовании в таблицу цветов. Перед вызовом описываемых ниже подпрограмм количество строк указывается в регистре сх.
После чтения палитры вызываются описываемые ниже подпрограммы. Они формируют таблицу (одномерный массив), содержащую коды цветов, формат которых соответствует установленному видеорежиму. Для хранения таблицы надо выделить пространство оперативной памяти. Учитывая, что количество цветов в исходной палитре не больше 256-ти, в режимах Hi-Color размер указанного пространства памяти составляет 256 слов (512 байтов).
Расположение таблицы цветов
Таблица цветов нужна только при первом построении рисунка, поэтому отводить для ее хранения постоянное место в памяти не целесообразно. В подобных случаях, обычно, рекомендуется выделять память только на время ее использования. В предыдущем разделе мы специально создавали буфер общего назначения, пространство которого доступно различным подпрограммам. Например, начало этого буфера использовалось для сохранения исходного фона на месте расположения информационной строки. Этот буфер и можно применять для временного размещения таблицы цветов.
Напомним, смещение и сегмент буфера общего назначения хранятся в следующих переменных, которые должны быть описаны в разделе данных:
GenOffs dw 0; адрес (смещение) в буфере общего назначения GenSeg dw 0; сегмент, содержащий буфер общего назначения
Способы выделения пространства для размещения буфера описаны в Приложении Б данной книги. После его выделения становится известным значение сегмента, которое задача должна сохранить в GenSeg. Исходное значение Genoffs равно нулю, а текущее значение зависит от того, какая часть буфера используется в данный момент времени.
Все приведенные ниже подпрограммы используют следующие входные параметры:
- адрес начала преобразуемой палитры указан в регистрах fs:si;
- размер палитры (в виде количества строк) в регистре сх;
- адрес начала формируемой таблицы цветов указывают переменные Genseg и GenOffs;
- результат преобразований помещается в таблицу цветов.
Теперь о преобразованиях. Формируемый код цвета зависит от установленного видеорежима Hi-Color. Существует две разновидности этих режимов. В одном случае код цвета занимает 15, а в другом 16 разрядов, расположение базовых цветов для обоих случаев показано в табл. 7.1. Мы рассмотрим два варианта подпрограмм, формирующих 15-разрядный код цвета, и обсудим, как сформировать 16-разрядный код цвета.
Палитра формата rgb
В этом случае базовые цвета в строке палитры и в формируемом коде расположены в одинаковой последовательности. Поэтому коды базовых цветов, считанные из строки палитры, надо сокращать до пяти разрядов и помещать в формируемый код цвета. Для того чтобы они оказались в нужном месте, перед добавлением кода очередного цвета формируемый код сдвигается на 5 разрядов влево. В примере 7.17 показан способ выполнения этих действий.
Пример 7.17. Преобразование палитры rgb в 15-разрядный код.
cnvpal: PushReg <ax,bx,cx,di,si,es>; сохранение содержимого регистров les di, dword ptr GenOffs; es:di = адрес таблицы цветов modcol: mov al, fs:[si]; читаем код красного цвета в al shr al, 03; сокращаем его до 5-ти разрядов mov bh, fs:[si+1]; читаем код зеленого цвета в bh shld ax, fax, 05;!! или shld ax, bx, 06 mov bh, fs: [si-t-2] читаем код синего цвета в bh shld ax, bx, 05 сдвигаем и дополняем код в ах add si, 03 адрес следующей строки палитры stosw записываем новый код цвета loop modcol управление повторами цикла PopReg <es,si,di,cx,bx,ax>; восстановление регистров ret возврат из подпрограммы