Рисунки, не использующие палитру. Рисунки, подготовленные в стандарте 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 возврат из подпрограммы