Иллюстрированный самоучитель по SVGA

Рисунки, не использующие палитру. Рисунки, подготовленные в стандарте BMP.

Размер порции данных

Рисунки большого размера считываются из файла и строятся по частям. Размер считываемой части файла (порции данных) надо выбрать таким, чтобы в нем укладывалось целое число строк. Это исключает лишние проверки в процессе построения рисунка.

При чтении из файла размер порции данных задается в байтах, а для управления повторами цикла построения рисунка используется количество считанных строк. В примере 3.22 количество строк вычислялось путем деления числа 65 535 на размер строки, а размер порции – путем умножения количества строк на 65 535. В данном случае размер строки в файле может не совпадать с размером строки в рисунке и перед делением его надо вычислить.

Новые переменные

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

iwidth dw 0 количество точек в строке (ширина) рисунка
fwidth dw 0 количество байтов в строке файла
iheight dw 0 количество строк в рисунке (высота рисунка)
rmndr dw 0 добавка к адресу для пропуска "лишних" байтов
part dw 0 количество строк в считываемой порции данных
numbyte dw 0 количество байтов в считываемой порции данных
remline dw 0 количество строк, которые еще не обработаны

Значения переменных iwidth и iheight выбираются из полей заголовка файла, а значения остальных переменных формируются в подпрограмме построения рисунка при выполнении подготовительных действий.

Подпрограмма BigBmp

Текст подпрограммы приведен в примере 7.25. Перед ее вызовом должно быть установлено окно видеопамяти, в котором расположено начало рисунка. Его адрес указывается в регистре di, a es должен содержать код видеосегмента. Предполагается, что задача предварительно открыла файл для чтения и обработала его заголовок так, как это рекомендовано в приложении А, поэтому известны значения переменных iwidth и iheight и файл установлен на начало образа рисунка.

Напомним
Перед построением любого рисунка, тем более большого размера, надо удалить с экрана изображение курсора (call Hidepnt), а после построения рисунка восстановить его на экране (call Showpnt)
.

Пример 7.25. Построение полноцветного рисунка формата BMP.

BigBmp: pusha сохранение "всех" регистров
PushReg <fs,Cur win> сохранение fs и Cur win
mov fs, SwpSeg fs = сегмент буфера обмена
mov SwpOffs, 0 очистка смещения в сегменте
mov dx, iwidth dx = количество точек в строке
neg dx dx = – iwidth
call calloffs bx = (horsize + iwidth) *bytppnt
mov ax, 03 ax = 3
mul iwidth ax = 3*iwidth, утроенный размер строки
mov dx, ax сохраняем его в dx
add ax, 03 с помощью. двух команд округляем
and al, OFCh размер строки до значения, кратного 4
mov f width, ax fwidth = размер строки в файле
sub ax, dx вычисляем добавку к адресу
mov rmndr, ax и сохраняем ее в rmndr
mov ax, – 1 ах = 65535
mov numbyte, ax numbyte = 65535
xor dx, dx очистка старшей части делимого
div fwidth ах = 65535 / fwidth (частное от деления)
mov part, ax part = число строк в порции для чтения
sub numbyte, dx numbyte = numbyte – ах
mov ax, iheight ах = количество строк в рисунке
mov remline, ax remline – счетчик числа строк
dec ax ах = номер последней строки
mul bperline ах = (iheight – l)*bperline
add di, ax di = адрес последней строки рисунка
adc dx, 00 учитываем возможный перенос
mov ax, GrUnit ах = GrUnit (единица измерения окон)
mul dl вычисляем добавку к номеру окна
add Cur win, ax номер окна для последней строки
call Setwin установка окна
NewPart mov ex, numbyte сх = количество считываемых байтов
call Readf чтение порции в буфер обмена
jnc sucread › чтение прошло без ошибок
/ Здесь должны выполнять ся действия в 'случае ошибки при чтении
sue re ad mov ex, part сх = кол-во строк в полной порции
cmp remline, ex считана полная порция данных?
jae @F › да, обходим следующую команду
mov ex, remline нет, сх = оставшееся число строк
@@: sub remline, ex уменьшаем значение счетчика строк
xor si, si si = начало буфера обмена
drwout: push ex сохраняем значение счетчика строк
mov ex, iwidth сх = размер строки – (в точках)
call drawline построение очередной строки
pop ex восстанавливаем счетчик строк
add s i, rmndr корректируем адрес в буфере обмена
sub di, bx di = адрес начала предыдущей строки
jnc @F › адрес в пределах текущего окна
call PrevWin установка предыдущего окна
@@: loop drwout управление циклом построения строк
cir.p remline, 0 остались не обработанные строки?
jne NewPart › да, на чтение следующей порции
PopReg <Cur win, f s> восстановление Cur win и fs
popa восстановление "всех" регистров
call Setwin восстановление исходного окна
ret возврат из подпрограммы
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.