Научная статья на тему 'Об одном нестандартном формате для хранения графических изображений'

Об одном нестандартном формате для хранения графических изображений Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
119
35
i Надоели баннеры? Вы всегда можете отключить рекламу.

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Кольцов Р. В.

The article contains notes about effective format for keeping graphic images, for IBM PC compatible computers, which can be successfully used in shareware. Besides the article contains listings of procedures in assembler of keeping images in a file and displaying them on the screen.

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Кольцов Р. В.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

THE EFFECTIVE FORMAT ON GRAFICAL IMAGE STORAGE

The article contains notes about effective format for keeping graphic images, for IBM PC compatible computers, which can be successfully used in shareware. Besides the article contains listings of procedures in assembler of keeping images in a file and displaying them on the screen.

Текст научной работы на тему «Об одном нестандартном формате для хранения графических изображений»

УДК 519.725

ОБ ОДНОМ НЕСТАНДАРТНОМ ФОРМАТЕ ДЛЯ ХРАНЕНИЯ ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ

© Р.В. Кольцов

Koltsov R.V. The Effective Format of Grafical Images Storage. The article contains notes about effective format for keeping graphic images, for IBM PC compatible computers, which can be successfully used in shareware. Besides the article contains listings of procedures in assembler of keeping images in a file and displaying them on the screen.

Правильный выбор формата для сохранения файлов графики обеспечивает компактное хранение изображений и позволяет экономить дисковое пространство. Иногда выставляются критичные требования к объемам файлов. Такая проблема часто возникает при создании больших проектов, включающих быструю графику, либо при разработке игровых программ и т.п. Свой выбор, конечно, можно остановить на каком-либо стандартном формате, например .PCX, .GIF, .TIF, .PIC [1] и .BMP [2], которые включают в себя помимо собственно кода различную инициализирующую информацию. Но что делать, если Вы пишите приложение для какого-то конкретного графического режима и вся лишняя информация Вам не нужна, да и объем критичен? Возможно, у Вас возникнет желание создать нестандартный файл, который посторонгшй пользователь не сможет просмотреть? Либо же вы желаете программировать один из недо куме г гтиро ванных режимов графики? [3, 4].

Здесь рассматривается нестандартный формат для хранения образа экрана 4-плоскостного графического режима 10h (640x350 точек). Эта статья написана как альтернатива части главы 7 [3], где приводятся листинги сохранеггия и восстановления экранов в режиме 10h без использования сжатия данных, которые весьма неудобны для применения. Здесь Вашему вниманию представлен формат, использующий простой, но достаточно эффективный алгоритм сжатия. В файле образа хранятся подряд байты блоков дашгых. Каждому блоку предшествует свой байт-счетчик Count. Никакая дополнительная информация, типа массивов палитры, в файле не хранится. При желании Вы можете разместить ее непосредственно в своей программе. При записи файла образа каждый блок данных формируется в буфере Buffer вместе с байтом Count, которые по мере заполнения сбрасываются в файл. Байт Count имеет следующую структуру: если его бит 7 равен нулю, то младшие 6 бит показывают число неупако-

ванных байтов в последующем блоке, а если бит 7 равен единице, то биты 0-6 показывают, сколько в последующем байте, являющим собою целый блок, упаковано байтов из видеобуфера. Очевидно, что таких байтов, упаковывающихся в один, не может бьггь больше 127. При записи изображения в файл данные последовательно считываются из четырех битовых плоскостей видеобуфера, причем по столбцам сверху вниз и слева направо для достижения максимального сжатия. Практика показывает, что чаще лучшее сжатие достигается по столбцам, а не по строкам. Это связано с организацией видеобуфера ПЭВМ. Не трудно приведенный алгоритм адаптировать для других видеорежимов, таких как ODh, OEh, OFh, 12h и др. Ключевые места в листингах снабжены комментариями. Поменяв VGA_SEGMENT с OAOOOh на 0A6D6h, Вы сможете читать изображение из файла в невидимую область видеобуфера, с последующим копированием в его видимую часть. Тестируемое графическое изображение в формате .SWE заняло объем 47943 байт, а в формате .PCX 78775 байт.

Листинг 1.1. Данные к процедурам

VGA_SEGMENT equ OAOOOh

GC_INDEX equ 3CEh ;Индексный регистр

;GC - графического контроллера DISPLAYED_SCREEN_SIZE equ (640/8)*350

LineBuf db 28000 dup (0)

Filename db 'SCREEN.SWE',0 Handle dw ? ;Дескриптор файла FileLen dw ?

;Count и нижеследующий буфер вместе ;сбрасываются по мере заполнения в файл Count db 0

Buffer db 127 dup (0)

;Флаг = 1, если требуется сброс (update)

UEnableFlag db 0

Листинг 1.2.

/Процедура записи изображения из видеобуфера ;в открытый методом дескриптора файл File SaveTheScreen PROC near push ds es di si cld

mov dx,GC_INDEX

mov ax,0005h ;индекс регистра режима GC out dx,ax mov ax,0304h

mov сх,4 10:push сх out dx,ax push ах mov ах,ОАО0Oh mov es,ах

;В LineBuf считываем по очереди 4 плоскости mov si,offset LineBuf xor di.di mov cx,80 lll:push cx mov cx,350 112:mov bl,es:[di] mov [si],bl add di,80 inc si loop 112

sub di,DISPLAYED_SCREEN_SIZE-1 pop cx loop 111

/Изображение из одной плоскости уже в ;LineBuf.Ниже мы обрабатываем по очереди ;считанные плоскости, сжимая данные, »•заполняем сжатыми данными Buffer и Count, »•которые по мере заполнения сбрасываем на ;диск. push ds pop es

mov si,offset LineBuf mov di,offset LineBuf InitCount:mov Count,0 lodsb mov cl,al push si lodsb cmp al,cl jnz ЫЗ lodsb cmp al,cl jnz ЫЗ mov Count,80h bl3:pop si

;Далее: al - байт, считанный предпоследним

;(LAST), cl - байт, считанный последним (CUR) 13:push сх lodsb mov cl,al

pop ax ;LAST:=CUR, CUR:=ds:[sij,si** cmp si, (offset LineBuf+2) \

DISPLAYED_SCREEN_S:ZE jc fw ;LineBuf исчерпан? Переход,если нет ja QuitLoop stosb inc Count

jmp QuitLoop ;исчерпан £w:cmp al.cl ;LAST = CUR ?

jnz m3 ;на “левую ветвь" алгоритма push ах /сохраним LAST lodsb /посмотрим NEXT BYTE з LineBuf dec si ;не меняя там своей позиции cmp al,cl ;равен ли он CUR ? pop ах /восстановим LAST з al jz mecl ;перейти, если NEXT BYTE = CUR :тда1:стр Count, 8Oh ;Count > 30 j b m3 /нет cmp Count,255 j z fwai mm2:inc Count cmp Count,255 jnz fwdO mov al.cl jmp fwdl fwd0:inc Count call Update jmp InitCount m3:cmp Count,127 ;Если Buffer заполнен

jnz m4 ;неповторяющимися байтами,

fwdl:call Update ;то сбросить его а файл mov Count,0 /Инициализируем верно счетчик m4:mov UEnableFlag,1

stosb ;Это операция LAST -> Buffer

inc Count jmp 13

metlrcmp Count,80h /"Правая ветвь" алгоритма j с fwd2 met2:cmp Count,255 jnz met3 fwd2:call Update mov Count,8Oh

met3:mov UEnableFlag,1 stosb inc Count jmp 13

QuitLoop:cmp UEnableFlag,0 jz EOPlane call Update EOPlane:pop ax dec ah pop cx loop jlO pop si di es ds ret j10:jmp 10 SaveTheScreen ENDP

/Процедура, сбрасывающая в файл счетчик чис-/ла байтов Count и Count байтов из Buffer'а Update PROC near push ах bx сх dx mov bx,Handle /дескриптор /ds:dx -> буфер, откуда записываем в файл mov dx,offset Count mov ch,0

mov cl,Count /cx = число записываемых байт

test cl,80h

jz $+*

mov cl,l

inc cx /$-*-4

mov ah,40h/Dos Fn "WriteToFile via Handle" int 21h

mov UEnableFlag,0 mov di,offset Buffer pop dx cx bx ax ret Update ENDP

/Процедура прорисовки битовых плоскостей FillPlane PROC near out dx,ax xor di,di mov ah,Olh mov cx,80 ll:push cx mov cx,3 50 12:dec ah test ah,7Fh jz ml

test ah,80h jnz m2 lodsb jmp m2 ml: lodsb mov ah,al lodsb m2:mov bl,es:[di! stosb add di,79 loop 12

sub di,DISPLAYED_SCREEN_SIZE-1 pop cx loop 11 ret

FillPlane ENDP

/Процедура заполнения зидесбуфера из буфера /Buf.Ha входе ах=сегмент зидесбуфеоа RestoreTheScreen PRCC near

push ds /Для видимой части 0A000h cid /Для невидимой части OAoEGh mov dx,03CEh mov es, ax

call ClearVolumeVisibleScreen /Здесь Buf - это буфер, куда Зы прочитаете свой графический файл. Переименуйте его» если он у Вас имеет другое имя mov ds.Buf xor si,si

mov ax,1003h /Оперция "OR" out dx,ax

mov ax,0701h /пишем в плоскость 3 call FillPlane

mov ax,OBOlh /пишем в плоскость 2 call FillPlane

mov ax,0D01h /пишем в плоскость 1 call FillPlane

mov ax,0E01h /пишем в плоскость 0

call FillPlane

mov ax,0105h

mov dx,03CEh

out ax,ax

pop ds

ret

RestoreTheScreen ENDP /Процедура очистки всего экрана ClearVolumeVisibleScreen PROC near mov ax,0005h out dx.ax

mov ax,0FF08h /Модифицируем все пикселы

out dx,ax

mov ax,0003h

out dx,ax

mov ax,0000h

out dx.ax

mov ax.OFOlh

out dx.ax

xor di.di

mov ex.DISPLAYED_SCREEN_SIZE/2 rep stosw /ax -> es:[di)

ret

ClearVolumeVisibleScreen ENDP /Процедура непосредственно показывающая /графическое изображение на экране и /ожидающая нажатия любой клавиши /На входе ds:dx -> Filename ShowPicture PROC near call FillBufFromFile mov ax,VGA_SEGMENT call RestoreTheScreen mov ah,08h int 21h ret

ShowPicture ENDP

/Процедура заполнения буфера Buf /из файла SCREEN.SWE /На входе ds:dx -> Filename FillBufFromFile PROC near call OpenFile 'mov Handle,ax call ReadFile mov bx,Handle call CloseFile ret

FillBufFromFile

/Процедура открытия файла. В случае успеха /возвращает в ах дескриптор файла OpenFile PROC near mov ah,3Dh mov al,02h int 21h jc Not_open ret

Not_open:mov ax,0003h int lOh

mov dx,offset OpenErrMessage mov ah,09h int 21h

mov ax,4CFFh /Errorlevel = OFFh - Error! int 21h OpenFile ENDP

/Процедура чтения файла целиком в Buf ReadFile PROC near mov ax,4202h xor cx,cx mov dx,cx mov bx,Handle int 21h

mov FileLen,ax mov ah,42 00h xor dx,dx int 21h mov bx,Handle mov cx.FileLen xor dx.dx mov ah,3Fh push ds mov ds,Buf int 21h pop ds ret

ReadFile ENDP /Процедура закрытия файла

/На входе в Ьх дескриптор закрываемого файла CloseFile PROC near mov ah,3Eh int 21h ret

CloseFile ENDP

ЛИТЕРАТУРА

1. Романов В.Ю. Популярные форматы файлов для хранения графических изображений на 1ВМ РС. М.: Унитех, 1992. 160 с.

2. Сван Том. \Vindows. Форматы файлов. М.: Бином, 1995. 288 с.

3. Абраш Майкл. Программирование графики. Таинства. Киев: ЕугоБУВ, 1995. 384 с.

4. Шикин Е.В., Боресков А В. Компьютерная графика. Динамика, реалистические изображения. М.: Диалог-МИФИ, 1995. 228 с.

Поступила в редакцию 5 июня 1996 г.

«

i Надоели баннеры? Вы всегда можете отключить рекламу.