Манипуляции с палитройДля окончания обработки заголовка надо извлечь из него величины, необходимые для установки или преобразования палитры цветов.Палитра применяется в тех случаях, когда цвет не указан в коде точки (biBitcnt = 1, 4 или 8), она содержит описание используемых в рисунке цветов и состоит из строк, количество которых изменяется от 2 до 256. Строка содержит полный код цвета и занимает 3 (формат OS/2) или 4 (формат Windows) байта. Базовые цвета расположены в строке в следующем порядке: синий, зеленый, красный, в формате Windows к ним добавлен пустой байт, т. е. строки хранятся в форматах bgr или bgr0. Характеристики палитрыДля работы с палитрой надо вычислить значения трех величин, которые мы обозначим как paddr — адрес начала палитры в буфере обмена, pniine — количество строк (цветов) в палитре и pbpi — количество байтов в строке палитры. Они определяются так: Шаг 8. Вычисляем адрес начала
палитры (paddr) как сумму значения поля isize и смещения этого поля (оно
равно о Eh). Размер палитры в байтах вычисляется как разность содержимого
поля bfOffBits (его смещение одь) и paddr. В зависимости от формата заголовка
(Windows или OS/2) присваиваем переменной pbpi значение 4 или 3. Для определения
формата заголовка проверяем значение paddr, если оно равно 36h, то это
формат Windows, в противном случае — OS/2. Вычисляем pniine = paddr/pbpl. Пример А.6. Определение характеристик палитры mov di, fs: [si+OEh] di = размер Bitmap info Вычисленные величины сохраняются только в том случае, если работа с па-литрой будет производиться в другой подпрограмме. При этом переменные рaddr, pnline и pbpl надо описать в разделе данных задачи. Если же работа с палитрой выполняется в продолжении описываемой подпрограммы, то пе-речисленные переменные не нужны, мы их вводили только для удобства описания. После выполнения примера А.6 из заголовка получена информация, необходимая для построения рисунка и работы с палитрой. Если вы не планируете включить установку или преобразование палитры в описываемую десь подпрограмму, то в конец текста примера А.б добавьте команду ret. Дальнейшие манипуляции с палитрой зависят от установленного задачей видеорежима. Если это один их режимов PPG, то ее надо установить, а если это один из режимов direct color, то преобразовать в таблицу цветов, кото-рая нужна для построения рисунка. Установка палитры заключается в записи перечисленных в ней цветов в регистры цвета видеокарты (DAC-регистры). Эти регистры доступны только При работе в видеорежимах PPG. При простой установке в регистры записываются коды всех цветов без их предварительного анализа. Недостаток та-кого способа в том, что в результате установки палитры добавляемого рисунка небольшого размера могут измениться цвета точек основного изобра-жения, находящегося на экране. Для более рационального использования регистров видеокарты перед установкой палитры могут выполняться анализ и преобразование добавляемых цветов. Эти вопросы подробно обсуждались в разделе, разделе и разделе основной части книги. Здесь мы ограничимся простым примером. В разделе описан способ простой установки палитры, хранящейся в файлах формата PCX. Рассмотрим аналогичные действия для вмр-файлов. Напомним, что для записи кодов базовых цветов в регистры цвета видеокарты используется одна из функций прерывания int 10h. Существуют две ее разновидности — для записи кода в один регистр и для записи кодов в группу регистров. Нас будет интересовать последняя, поскольку она позволяет установить всю палитру за одно обращение к BIOS. Подробное описание функций BIOS приведено в разделе. Нужная нам функция имеет код 12h. Перед ее вызовом надо подготовить палитру так, чтобы в каждой ее строке было записано по 3 байта, содержащих базовые цвета, расположенные в порядке rgb, причем коды цветов должны быть сокращены до шести разрядов (два старших разряда кода BIOS игнорирует). Программная реализация преобразования и простой установки палитры показана в примере А.7, который является продолжением примера А.6. Пример А.7. Преобразование и установка палитры convert : mov ex, ax ex = количество строк в палитре Напомним, что после выполнения примера А.6 в регистрах находятся следующие величины: ах — количество строк в палитре, bх — размер строки в байтах, di — адрес начала палитры. Выполнение примера А.7 начинается с формирования содержимого регистров, используемых при преобразовании палитры. Для этого в сх копируется содержимое ах, а в si — содержимое di. Исходное содержимое es сохраняется и в него записывается код сегмента буфера обмена. Адрес и количество строк будут нужны при установке палитры, поэтому содержимое регистров сх и di сохраняется в стеке. Цикл преобразования имеет метку s_ip. В нем производятся перестановка красного и синего и сокращение кодов базовых цветов до 6-ти разрядов. Первая команда цикла считывает код синего базового цвета в регистр ai, a вторая команда переставляет содержимое регистра ai и байта со смещением 2. В результате в ai оказывается код красного цвета, а в байте со смещением 2 — код синего цвета. Содержимое регистра ai сдвигается на 2 разряда вправо (сокращается до 6-ти разрядов) и записывается в буфер обмена. Зеленый и синий цвета обрабатываются совместно. Их коды считываются в регистр ах, его содержимое сдвигается на 2 разряда вправо, и очищаются два старших разряда ai. Результат записывается в буфер обмена. Описанные действия повторяются для каждой строки палитры. Преобразованная палитра помещается на место исходной. Если заголовок файла соответствует формату Windows, то она окажется короче исходной за счет исключения пустых байтов. После цикла преобразования, начиная с команды, имеющей метку setpai, выполняется установка палитры. Размер палитры вйталкивается из стека в регистр сх, а адрес ее начала в dx. Для записи, начиная с нулевого DAc-регистра, bx очищается. В регистр ах помещается код запроса и происходит обращение к BIOS для установки палитры. После возврата из BIOS из стека восстанавливается исходное значение es и подпрограмма BitMap завершается, поскольку она выполнила все предусмотренные действия. Построение таблицы цветов Если задача работает в одном из режимов direct color, то регистры цвета видеокарты не используются. В таких случаях исходная палитра преобразуется в таблицу, содержащую коды базовых цветов точек в формате, соответствующем установленному видеорежиму. Другими словами, надо преобразовать строки исходной палитры, упаковав базовые цвета в 16-разрядное слово для режимов Hi-Color или в 32-разрядное слово для режимов True color. Таблица цветов используется для преобразования кодов точек при построении рисунка. Способы построения таблицы цветов описаны в разделe (для режимов Hi-color) и разделe (для режимов True color). Здесь мы ограничимся примерами ДЛЯ реЖИМОВ True Color. В указанных разделах предполагалось, что таблица цветов размещается в буфере общего назначения. Код сегмента, содержащего этот буфер, хранится в переменной GenSeg, а адрес свободного пространства в нем находится в переменной Genoffs. Таким образом, пара переменных GenSeg и GenOffs задает полный адрес начала таблицы цветов в оперативной памяти. Если заголовок файла соответствует формату Windows, то исходная палитра просто копируется в буфер общего назначения. А если заголовок файла соответствует формату OS/2, то при копировании палитры к базовым цветам каждой строки надо добавить пустой байт. Программная реализация построения таблицы цветов показана в примере А.8, который является продолжением примера А.6. Предполагается, что в регистрах находятся следующие данные: ах — количество строк в палитре, bx — размер строки в байтах, di — адрес начала палитры. Пример А.8. Построение таблицы цветов для режимов True Color TabCol: mov si, di si = адрес начала палитры Пример А.8 является несколько измененным вариантом примера 7.19. При выполнении подготовительных действий добавлено формирование содержимого регистров bx, сх и si, а в цикл построения таблицы включена команда add si, bx для пропуска пустого байта, если заголовок соответствует формату Windows. Если ваша задача устанавливает один из режимов Hi-color, то возьмите за основу пример 7.18 и внесите в него аналогичные изменения. Заключение. |
Назад | Содержание | Вперед |