Преобразование палитры в форматы Hi-Color
В примере 7.17 основную роль играет команда shld, напомним ее особенности. При выполнении команды содержимое первых двух операндов, в данном случае это регистры ах и bx, сдвигается как одно 32-разрядное слово, но записывается только старшая часть результата в первый операнд, а содержимое второго операнда не изменяется. Таким образом, в примере 7.17 команда shld сдвигает содержимое регистра ах на пять разрядов влево и записывает в освободившееся место пять старших разрядов регистра bх.
В зависимости от установленного видеорежима код зеленого цвета может занимать 5 или 6 разрядов. В комментарии показано, как изменится одна из команд shld в случае формирования 16-разрядного кода цвета.
Устаревший формат палитры PCX.
В разделе 4.4 говорилось о том, что существует устаревший формат 256-цветной палитры, поддерживаемый версией стандарта PCX, разработанной фирмой Genius. Если вам надо работать с файлом, соответствующим этому стандарту, то проще всего преобразовать его в основной стандарт фирмы ZSoft. Это можно сделать, например, с помощью графического редактора Photofinish фирмы ZSoft.
Палитры формата bgr и bgr0
В этом случае базовые цвета в строке палитры и в формируемом коде расположены в противоположном порядке, коды красного и синего цветов переставлены местами. Есть два способа учесть эту особенность. Байты палитры можно считывать по порядку, а перед добавлением очередного цвета сдвигать формируемый код вправо, а не влево, как это делалось раньше. Другой способ заключается в том, чтобы считывать байты строки палитры в обратном порядке, а формируемый код по-прежнему сдвигать влево. В примере 7.18 реализован второй способ формирования кода цвета.
Пример 7.18. Преобразование палитры bgr в 15-разрядный код.
cnvpal: PushReg < ax,b x, ex, di, si,es>; сохранение содержимого регистров les di, dwo:d ptr (5enOffs; es:di = адрес таблицы цветов modcol: mov al, fs: [si+2] читаем код красного цвета в al shr al, 03 сокращаем его до 5-ти разрядов mov bh, fs: [si+1] читаем код зеленого цвета в bh shld ax, bx, 05!! или shld ax, bx, 06 mov bh, fs: [si] читаем код синего цвета в bh shld ax, bx, 05 сдвигаем и дополняем код в ах add si, 03!! для формата "bgrO" – add si, 04 stosw записываем новый код цвета loop modcol управление повторами цикла PopReg <es,si,di, ex, зх,ах>; восстановление регистров ret возврат из подпрограммы
Если вы сравните тексты примеров 7.17 и 7.18, то обнаружите, что в них различаются только индексные выражения у первой и третьей команд пересылки. За счет такого трюка мы считывает базовые цвета в том порядке, в котором они должны располагаться в формируемом коде.
В примере 7.18 появилась вторая переменная команда, выполняющая переадресацию строк палитры. При работе с форматом bgr значение адреса увеличивается на 3, а с форматом bgr0 – на 4. На практике нет никакой необходимости работать с переменной командой, ее второй операнд просто не должен зависеть от размера строки палитры.
Палитры форматов bgr и bgr0 используются в двух разных версиях стандарта BMP.
Заголовки файлов обрабатываются по единой схеме, не зависящей от версии (см. приложение А данной книги). При обработке заголовка обязательно определяется размер строки палитры т. к. он нужен при всех манипуляциях с палитрой. Поэтому вторым операндом команды add si, оз должно быть не значение константы, а имя регистра или переменной, в котором (в которой) хранится размер строки палитры.
Универсальный вариант подпрограммы
В обоих приведенных примерах от установленного режима Hi-Color зависит третий операнд одной из команд shid. От переменной команды можно избавиться следующим способом.
При выполнении задачей подготовительных действий обязательно считывается массив info, содержащий наиболее важные характеристики установленного видеорежима. В частности, в байте этого массива со смещением 2in указан размер кода зеленого цвета. В режимах Hi-color там находится число 5 или 6. Это число надо сохранить в специально выделенном байте, присвоив ему удобное для вас имя, например gcoisize, и использовать в подпрограммах примеров 7.17 и 7.18 при обработке зеленого цвета.
Причем величина сдвига может быть либо явно указана в записи команды, либо помещена в регистр el, который применяется в качестве первого операнда команды. В примерах 7.17 и 7.18 регистр сх используется в качестве счетчика, поэтому понадобятся две дополнительные команды для сохранения и восстановления его содержимого. Таким образом", одна переменная команда shid может быть заменена следующей группой команд:
push сх; сохраняем счетчик повторов цикла mov cl, gcoisize; cl = величина сдвига (5 или 6) shid ах, bx, cl; сдвиг на величину, указанную в cl pop сх; восстанавливаем счетчик повтором цикла
Учитывая, что цикл преобразований повторяется не более 256-ти раз, дополнительные потери времени будут не столь велики, зато подпрограмма окажется применимой во всех видеорежимах Hi-Color.