Элементарная графика 1993 г.

Практикум по графике в машинных кодах - компрессия экрана. Декомпрессия экрана. Заключение.


                          3.14. Компрессия экрана.

              Если Ваша программа содержит большое количество  графичес-
         ких изображений, причем они не исполняются самой программой,  а
         подготовлены ранее, например в графическом редакторе, то возни-
         кает вопрос о необходимости каким-либо образом  компрессировать
         изображения, обеспечив возможности хранения максимума экранов в
         ограниченном объеме памяти.

              Все методы  компрессии данных  строятся на  том, что  надо
         выявить повторяющиеся последовательности и заменить их на  код,
         который содержит указание на то, что это за  последовательность
         и каков при этом  коэффициент повторения.  На  сегодняшний день
         известны  самые  разнообразные  приемы,  например основанные на
         том, что  наиболее часто  повторяющиеся символы,  такие как "A"
         кодируются не кодом  ASCII (который равен 65), а своим каким-то
         кодом, например 01, соответственно символ "E" например кодом 02
         и т.п. В результате получается, что битовая конструкция  симво-
         лов содержит много нулей, которые можно "ужать", т.е. на символ
         в среднем расходуется не 8  битов, как обычно, а в  среднем 4-5
         (до 6).  Такой метод  применим при  компрессии текстовых блоков
         общего назначения.

              Если текст имеет специфику, например это текст адвентюрной
         программы,  в  которой  часто  повторяются определенные слова и
         словосочетания, то  компрессия может  основываться на  создании
         резидентного  словаря  на  256  позиций  и замене этих слов или
         словосочетаний  по  тексту  на  их  порядковый  номер.  Излишне
         говорить о том,  что и генерацию  такого словаря и  кодирование
         текста  выполняют  не  вручную,  а  написав для этого служебную
         процедуру.

              В  нашем  случае  речь  идет  о  компрессии графики, а она
         обладает той спецификой,  что здесь особенно  часто встречаются
         повторяющиеся  символы. Так,  например, сплошная горизонтальная
         линия через весь экран представляет из себя 32 следующих подряд
         байта, каждый из  которых равен 255.  Этим обычно и  пользуются
         при  компрессии  графики.  Мы  должны  отметить, что алгоритмов
         компрессии графики может быть бесконечно много и ни один из них
         не является  абсолютным. То  есть для  каждого алгоритма  можно
         подобрать такую раскладку экрана,  при которой он будет  выпол-
         нять максимальное сжатие, но  для каждого же можно  подобрать и
         такие  условия,  при  которых  компрессированный  файл окажется
         больше исходного по величине. В свое время этот вопрос  получил
         некоторое  обсуждение  на  страницах  "ZX-РЕВЮ" (N1, 1991,с. 6,
         N2, 1991,с. 24).

              Процедура компрессии "снимает" изображение с экрана,  ком-
         прессирует его и отправляет на хранение в выделенную для  этого
         область  оперативной  памяти  компьютера,  после  чего готова к
         приему нового экрана. Компрессированные изображения сохраняются
         в оперативной памяти последовательно и могут быть восстановлены
         оттуда с помощью декомпрессирующей программы.

              Назовем процедуру компрессии FN n(h,l), где:
              h - старший байт адреса, с которого начинается область,
         отведенная для компрессированных изображений;
              l - младший байт этого адреса.
              h,l < 255.
              Задание процедуры: DEF FN n(h,l) = USR 56600
              Вызов процедуры :  RANDOMIZE FN n(h,l)

                    10 REM *** Загрузчик машинного кода
                    20 LET adr=56600: LET long=60: LET z=0
                    30 FOR i=0 TO long-1: READ a
                    40 POKE (adr+i),a: LET z=z+a
                    50 NEXT i
                    60 LET z=INT (((z/long)-INT (z/long))*long)
                    70 READ a
                    80 IF a<>z THEN PRINT "??": STOP
                    500 REM ***Данные для машинного кода
                    510 DATA  42,  11,  92,   1,   4
                    520 DATA   0,   9,  86,  14,   8
                    530 DATA   9,  94, 237,  83,  82
                    540 DATA 221,  33,   0,  64,   6
                    550 DATA   1, 126,  44,  32,   8
                    560 DATA  36, 245, 124, 254,  91
                    570 DATA  40,  16, 241,  78, 185
                    580 DATA  32,   4,   4,  32, 238
                    590 DATA   5,  18,  19, 120,  18
                    600 DATA  19,  24, 227, 241,  18
                    610 DATA  19, 120,  18, 237,  83
                    620 DATA  22, 221, 201,   0,   0
                    630 DATA  56,   0,   0,   0,   0

                          Дисассемблер программы:

         56598          NEXT_S DEFW           ;В эту программную пере-
                                              ;менную заносится адрес, с
                                              ;которого может быть нача-
                                              ;то хранение очередного
                                              ;экрана после того, как
                                              ;данная процедура отрабо-
                                              ;тает.
         56600   2A0B5C        LD HL,(5C0BH)  ;См. с. 109...111
         56603   010400        LD BC,0004     ;Сдвиг от DEFADD на 4 бай-
         56606       09        ADD HL,BC      ;та (см. c.109...111).
         56607       56        LD D,(HL)      ;Параметр h.
         56608     0E08        LD C,08        ;Сдвиг на
         56610       09        ADD HL,BC      ;восемь байтов.
         56611       5E        LD E,(HL)      ;Параметр l.
         56612 ED5352DD        LD(ADDR),DE    ;Запомнили h и l в прог-
                                              ;раммной переменной по ад-
                                              ;ресу 56658.
         56616   210040        LD HL,4000     ;Адрес начала дисплейного
                                              ;файла.
         56619     0601 RETURN LD B,01        ;Инициализация счетчика
                                              ;повторяющихся байтов.
         56621       7E        LD A,(HL)      ;Приняли текущий байт.
         56622       2C AGAIN  INC L          ;И перешли к следующему.
         56623     2008        JR NZ,PASS     ;Если регистр L еще не пе-
                                              ;реполнен, то обход.
         56625       24        INC H          ;В противном случае нара-
                                              ;щиваем старший регистр H.
         56626       F5        PUSH AF        ;Проверка
         56627       7C        LD A,H         ;на конец
         56628     FE5B        CP 5B          ;экранной области.
         56630     2810        JR Z,END       ;Переход на завершение ра-
                                              ;боты, если экран исчерпан
         56632       F1        POP AF
         56633       4E PASS   LD C,(HL)      ;Очередной байт приняли в
                                              ;регистр C и сравнили его
         56634       B9        CP C           ;с предыдущим в A.
         56635     2004        JR NZ,PASS_1   ;Если нет повтора, то об-
                                              ;ход на PASS_1.
         56637       04        INC B          ;Если есть повтор, то на-
                                              ;ращиваем счетчик повтора
         56638     20EE        JR NZ,AGAIN    ;и переходим на AGAIN для
                                              ;проверки очередного байта
                                              ;экрана.
         56640       05        DEC B          ;Если счетчик обнулился,
                                              ;т.е. переполнился, умень-
                                              ;шаем его на единицу и пе-
                                              ;рестаем наращивать.
         56641       12 PASS_1 LD (DE),A      ;Перенесли байт из экрана
                                              ;в буфер и указатель в бу-
         56642       13        INC DE         ;фере переставили вверх.
         56643       78        LD A,B         ;Ввели коэффициент повтора
         56644       12        LD (DE),A      ;и заслали его в буфер.
         56645       13        INC DE         ;Переставили указатель в
                                              ;буфере вверх.
         56646     18E3        JR RETURN      ;Возврат для обработки
                                              ;очередного байта.
         56648       F1 END    POP AF         ;Восстановление стека.
         56649       12        LD (DE),A      ;Последний байт выдается
                                              ;в буфер
         56650       13        INC DE         ;Туда же выдается его
         56651       78        LD A,B         ;коэффициент повтора
         56652       12        LD (DE),A      ;из регистра B.
         56653 ED5316DD        LD (NEXT_S),DE ;Адрес конца буфера фикси-
                                              ;руется в переменной.
                                              ;Он может быть использован
                                              ;например для того, чтобы
                                              ;знать где можно начинать
                                              ;сохранение следующего эк-
                                              ;рана.
         56657       C9        RET
         56658          ADDR   DEFW           ;Адрес, с которого начи-
                                              ;нается в ОЗУ область хра-
                                              ;нения нашего скомпресси-
                                              ;рованного экрана.

                          3.15. Декомпрессия экрана.

              Файлы  скомпрессированных  экранов  можно  восстановить из
         ОЗУ и снова поместить на экран. Для этого служит   декомпресси-
         рующая программа FN o(h,l). Здесь:

              h - старший байт адреса, начиная с которого хранится Ваше
         компрессированное изображение;
              l - младший байт этого адреса.
              h,l < 255.
              Задание процедуры: DEF FN o(h,l) = USR 56500
              Вызов процедуры :  RANDOMIZE FN o(h,l)

                    10 REM *** Загрузчик машинного кода
                    20 LET adr=56500: LET long=35: LET z=0
                    30 FOR i=0 TO long-1: READ a
                    40 POKE (adr+i),a: LET z=z+a
                    50 NEXT i
                    60 LET z=INT (((z/long)-INT (z/long))*long)
                    70 READ a
                    80 IF a<>z THEN PRINT "??": STOP
                    500 REM ***Данные для машинного кода
                    510 DATA  42,  11,  92,   1,   4
                    520 DATA   0,   9,  86,  14,   8
                    530 DATA   9,  94,  33,   0,  64
                    540 DATA  26, 245,  19,  26,  19
                    550 DATA  71, 241, 119,  35,  16
                    560 DATA 252, 124, 254,  91,  32
                    570 DATA 240, 201,   0,   0,   0
                    580 DATA  28,   0,   0,   0,   0

              В  результате  работы  компрессирующей  программы   сжатое
         изображение  хранится  в  оперативной  памяти и имеет следующий
         формат:
                ----T---T---T---T----------------T---T---T------¬
                ¦ B1¦ K1¦ B2¦ K2¦    ........... ¦Bi ¦ Ki¦..... ¦
                L---+---+---+---+----------------+---+---+-------

              Здесь Bi - i-ый байт  изображения, а Ki - коэффициент  его
         повтора (от 0 до 255). Процедура декомпрессии предельно проста.
         Байты из памяти берутся парами. Коэффициент повтора  становится
         параметром цикла и в этом цикле байт изображения помещается  на
         экран (на адрес в  экранной области указывает регистровая  пара
         HL). Сигналом к  окончанию работы является  момент выхода H  за
         пределы, отведенные для экранной области.

                          Дисассемблер программы:

         56500   2A0B5C        LD HL,(5C0BH)  ;См. с. 109...111.
         56503   010400        LD BC,0004     ;Сдвиг от DEFADD на 4 бай-
         56506       09        ADD HL,BC      ;та (см. c. 109...111).
         56507       56        LD D,(HL)      ;Параметр h.
         56508     0E08        LD C,08        ;Сдвиг на
         56510       09        ADD HL,BC      ;восемь байтов.
         56511       5E        LD E,(HL)      ;Параметр l.
         56512   210040        LD HL,4000     ;Начало дисплейного файла.
         56515       1A AGAIN  LD A,(DE)      ;Приняли байт из оператив-
                                              ;ной памяти.
         56516       F5        PUSH AF        ;Запомнили его на стеке.
         56517       13        INC DE         ;Переход к новому байту.
         56518       1A        LD A,(DE)      ;Приняли очередной байт
                                              ;(это коэффициент повтора)
         56519       13        INC DE         ;Переход к новому байту.
         56520       47        LD B,A         ;В регистре B организуется
                                              ;счетчик повторов.
         56521       F1        POP AF         ;Восстановили байт экрана.
         56522       77 LOOP   LD (HL),A      ;И поместили его на экран.
         56523       23        INC HL         ;Следующий байт экрана.
         56524     10FC        DJNZ LOOP      ;Повторяем цикл от LOOP
                                              ;столько раз, каков коэф-
                                              ;фициент повтора.
         56526       7C        LD A,H         ;Проверяем на окончание
         56527     FE5B        CP 5BH         ;экранную область памяти.
         56529     20F0        JR NZ,AGAIN    ;Если еще не конец, то
                                              ;продолжаем работу.
         56531       C9        RET            ;Возврат.

                            Уважаемый читатель!

              Скоро  исполнится   десять  лет  со  дня выхода на широкую
         арену  первого  "Спектрума".  По  нашим  данным  первую  партию
         компьютеров  этой  серии  сэр  К.Синклер  продемонстрировал  на
         предновогодней выставке-продаже в декабре 1982 года.

              За  это  время  в  мире  накоплен огромный теоретический и
         практический  опыт  работы  с  этой  самой массовой и доступной
         машиной. Самый большой пласт открытий и достижений находится  в
         тех тысячах высококачественных  программ, которые доступны  Вам
         для работы, отдыхы, развлечения и, самое главное - обучения.

              Компьютерная программа - не книжка с картинками, в которой
         все просто и  понятно, но это,  тем не менее,  все-таки учебник
         для того, кто любит исследовательскую работу. Трудно работать с
         учебником,  в  котором  все  непонятно  и  здесь  мы видим свою
         главную задачу - дать  основные понятия, показать наезженные  и
         освоенные приемы и подходы.  Если теперь разбираясь с  машинным
         кодом  фирменной  программы  Вы  хоть  чуть-чуть   почувствуете
         ощущение, что где-то я это видел и это мне знакомо, значит наша
         цель наполовину достигнута.

              Конечно, мы  затронули только  самый край  всего того, что
         накоплено в области компьютерной  графики. Но, во первых,  мы с
         Вами  не  прощаемся  и  готовим  новые  книги,  а во-вторых, мы
         надеемся, что Вы  начнете самостоятельное планомерное  исследо-
         вание.

              Пройдут  годы,   сменятся  модели   компьютеров  и   языки
         программирования,  но  опыт,  который  Вы сейчас приобретаете с
         маленьким "Спектрумом", останется точно  так же,  как останутся
         основные  алгоритмы  и  приемы,  а  самое главное - останется и
         закрепится  особый  алгоритмический  образ  мышления,   который
         поможет  Вам  легко  освоить   любую  технику  и  любые   языки
         программирования.

                 С уважением.                   "ИНФОРКОМ"



СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Введение - Сегодня Y принес мне кое - какую информацию и я счел кощунством задерживать ее до следующего выпуска.
Demo Party - рассказ о поездке Antares в Казань на CAFe'99
Фантастика - "Звездный Зоопарк" Игoрь Белoгруд и Александр Климoв.
Печатается с продолж. - Кащей бессмертный (глава 6-9).
WANTED - Розыск программ...

В этот день...   21 ноября