Inferno #05
30 апреля 2004

Sofтинка - экранный компрессор Laser Compact 4.0.

            Laser Compact 4.0
 

   Я не интересовался более старыми верси-
ями, хотя  и  застал их появление. Поэтому 
начну  сразу  с  4-й. Формат у неё простой 
(информация лежит целыми байтами),зато код 
распаковщика очень любопытен. 

   Как  и в описанных ранее экранных комп-
рессорах, LC  рассматривает  6912  экран в
виде  трёх 8-знакоместных линий, состоящих
из столбцов  байт, и лежащих далее линейно
адресуемых атрибутов.
   Файл начинается байтом,который содержит
старший  байт значения разрыва между нача-
лом атрибутов и окончанием экрана.
 

               0=full screen
               1=нижние 2/3
               2=нижняя 1/3
               8=верхние 2/3
               9=средняя 1/3
             16=верхняя 1/3

   Байт  этот  используется в распаковщике
сам по себе,а заодно пересчитывается в ад-
рес начала экрана и его высоту:
 ────────────────────────────────────────── 
                 LD A,(HL)
                 LD LX,A ;разрыв
                 AND 3
                 RLCA
                 RLCA
                 RLCA
                 OR 64
                 LD D,A ;начало экрана
                 LD E,0
                 LD A,(HL)
                 INC HL
                 AND #FC
                 LD C,A
                 LD A,88
                 SUB C
                LD C,A ;конец экрана
────────────────────────────────────────── 
   Распаковщик  отличает от предшественни-
ков тот факт, что адрес на экране пересчи-
тывается  из виртуального на каждом байте:
из регистров HL (виртуальный адрес откуда)
и DE (куда) рассчитывается адрес DE'.
 ────────────────────────────────────────── 
         LD A,H               LD A,D
         CP C ;конец экрана   CP C
         JR NC,──────┐   ┌────JR NC,
         XOR L       │   │    XOR E
         AND #F8    SCF  │    AND #F8
         XOR L      PUSH AF   XOR E
         EXX        ADD A,LX  EXX
         LD D,A     EXX       LD D,A
         EXX        LD D,A    EXX
         XOR L      EXX       XOR E
         XOR H      POP AF    XOR D
         RLCA       LD A,E    RLCA
         RLCA  ┌────JR NC,    RLCA
         EXX───┘    LD A,L ┌──EXX
        LD E,A     JR─────┘  LD E,A
────────────────────────────────────────── 
   Напомню,что LX для полного экрана равен
0. 
   Процедура  перехода к следующему адресу
отсутствует.Это дало возможность,не сильно
раздувая распаковщик, реализовать ссылку с
копированием байтов задом наперед. Что ещё
более интересно,код режима работы основно-
го цикла  распаковщика  всё время хранится
 во флагах:
    Z, NC - повтор одного байта A
    Z, C - копирование HL-- в DE++
   NZ, NC - брать байты непосредственно из
 потока (HL')
   NZ, C - копирование HL++ в DE++
   Число проходов цикла в любом случае ле-
жит в B.

   После первого байта, который описан вы-
ше, в потоке лежит упакованный экран,зако-
дированный следующим образом:

%11000000 - конец экрана; 
 %11xxxxx0,байты (NZ, NC) - просто байты из 
 потока. Число байтов %xxxxx=1..31;
 %11xxxx01,байт (Z, NC) - %xxxx=1..15  оди- 
 наковых байт;
 %11000001,длина,байт (NZ,NC) - до 256 оди- 
 наковых байт (0=256);
%11xxxx11 (Z, NC) - %xxxx=1..15 нулей; 
%11000011,длина (Z, NC) - 16..256 нулей; 
 %0pppphhh,%llllllll (NZ,C) - короткая ссы- 
  лка: -disp=%11111hhhllllllll, puts=%pppp+
 +1=2..16;
 %10ppphhh,%llllllll (Z, C) - короткая ссы- 
  лка к копированием в обратном порядке:
 -disp=%11111hhhllllllll, puts=%ppp+1;
 %00000HHH, %ppppppph, %llllllll  (NZ, C) - 
  длинная  ссылка: -disp=%1111HHHhllllllll,
 len=%ppppppp+1,
 %10000HHH,%ppppppph,%llllllll(Z,C) - длин- 
  ная  ссылка с копированием в обратном по-
 рядке, аналогично.
 

   Недостаток формата в большом количестве
способов записать одно и то же.Кроме того, 
хотя 0 кодируется просто,специальных кодов 
для #ff не предусмотрено. Идея не доведена 
до конца... 


            Laser Compact 5.2
 

   В данной версии исключены коды обращён-
ного  копирования, но  добавлена  упаковка 
ссылок по Хаффману.В связи с этим,в сорев- 
новании между LC4.0 и LC5.2 может выиграть 
 как тот, так и другой. 
   С появлением  Burial Laser Compact фор-
мат LC5.2 стал  почти  стандартом. "Почти" 
потому, что так и не было согласовано рас- 
ширение (у Hrumer'а .PLC, у Sinn'а .plc ), 
а универсальный  просмотрщик  BV  так и не 
научился раскрывать этот формат. 

   Как  и раньше, LC рассматривает экран в
виде 3 (впрочем, зависит от того,экран это
или часть) линий ломаных столбцов плюс ат-
рибуты.
   Преобразование адресов для этого выгля-
дит следующим образом (почти полностью со-
впадает с LC4.0 ):
 ────────────────────────────────────────── 
             LD A,D
             CP HX
             JR NC,───────┐
             XOR E        │
             AND #F8      │
             XOR E        │
             LD B,A      EXX
             XOR E       ADD A,E
             XOR D       EXX
             RLCA        LD B,A
             RLCA        LD C,E
             LD C,A       │
               └────┬─────┘
                   │
────────────────────────────────────────── 
   Внутри экрана, если представить его ли-
нейным по ломаным  столбцам (т.е. так, как
его проходит распаковщик), опять действует
сжатие  из  семейства  LZ. Размер  словаря
#1700 байт, максимальная  строка - 255/256 
байт. (При смещении >768 длина  строки ко-
дируется как на единицу меньшая.)
   Битовый  и  байтовый потоки реализованы
аналогично формату Hrust2.x, за исключени-
ем того,что в одной из ветвей чтения бита:
 

                 SLA D
                 JR NZ,$+6
                 LD D,(HL)
                 INC HL
                RL D

вместо RL используется SLI (т.к. начальное
значение D равно  0, а не 128 ). Программа
ZX_Emul 0.33 не всегда эмулирует этот фра- 
гмент правильно. Это происходит,по-видимо-
му, из-за неправильного выставления флагов
после команды  SLI D. Заменой SLI на RL (с
предварительным  занесением  128 в регистр
D) эту проблему удаётся решить. В приложе- 
нии вы сможете найти патчи к ZX Guide##3,4
в виде секторов, которые нужно записать на
указанное место диска.
   Внутри распаковщика действует не только
отрицательное  смещение, как  это обычно у
Hrumer'а, но и отрицательная длина  ссылки 
(цикл INC LX:JR NZ ).Это связано с тем,что
старший  байт смещения и длина ссылки изв-
лекаются одним и тем же участком кода. Ко-
 дируются же они по следующей таблице:
   (см. цикл DLC5, который проходится рас-
паковщиком  2  раза подряд, один  раз  для 
-puts=LX, второй раз для -dispH=A' ) 
 ────────────────────────────────────────── 
             код    -disp   puts
           1         FFxx     2
           011       FExx     3
           001       FDxx     4
           01011     FCxx     5
           01001     FBxx     6
           00011     FAxx     7
           00001     F9xx   байт*
           0101011   F8xx     8
           0101010   F7xx     9
           0101001   F6xx    10
           0101000   F5xx    11
           0100011   F4xx    12
           0100010   F3xx    13
           0100001   F2xx    14
           0100000   F1xx    15
           0001011   F0xx    16
           0001010   EFxx    17
           0001001   EExx    18
           0001000   EDxx    19
           0000011   ECxx    20
           0000010   EBxx    21
           0000001   EAxx    22
          0000000   E9xx    23
────────────────────────────────────────── 
(*) чтение байта из байтового потока; если 
он равен нулю,распаковка прерывается,иначе 
после декрементирования взять его за АНТИ- 
длину  ссылки. Т.е. тот  самый LX, который 
увеличивается до достижения нуля. 

   После получения -dispH из байтового по-
тока  извлекается -dispL. Как уже было от-
мечено, при disp>768 увеличивается puts.
 

   С учётом всего сказанного формат читае-
тся следующим образом: 

   Заголовок:
+0 "LCMP5" 
 +5 длина файла,начиная с поля "код размера 
 экрана"
 +6 длина дополнительной области заголовка, 
  которая может начинаться после этого бай-
  та.(На практике [+6]=0, и доп.область от-
  сутствует.) Фрагмент распаковщика, учиты-
  вающий эту деталь формата,несколько избы-
  точен: LD A,(HL):INC HL:LD E,A... В неко-
  торых  случаях выгодно отрезать как заго-
 ловок,так и начало самого распаковщика.
 +7+[+6] код размера экрана. Благодаря ост- 
  роумному  решению  равен  старшему  байту
  расстояния  от окончания пиксельной части
  экрана до атрибутов.6 возможных значений:
               0=full screen
               1=нижние 2/3
               2=нижняя 1/3
               8=верхние 2/3
               9=средняя 1/3
              16=верхняя 1/3
  Декодируется так: x&3=0/1/2 - номер нача-
  льной  трети; x&#FC=0/8/16 - работать  до
 строки 24/16/8 соответственно.
+8+[+6] 1-й байт экрана в несжатом виде. 
+9+[+6] первый байт битового потока и т.д. 

   Битовый поток:
%1 - взять байт из байтового потока; 
 %0,-puts,-dispH (-dispL из байтового пото- 
  ка) - ссылка  назад  с копированием. Коды
  для disp и puts приведены в таблице выше.
  При disp=1, очевидно, происходит повторе-
 ние предыдущего байта и т.п.


   Несколько слов о самих идеях сжатия...
 

   Поскольку относительный процент атрибу-
тов  в картинке  невелик, создание особого 
способа сжатия не было для них целесообра- 
зно. Между  тем, если  использовать сжатие 
байтового  потока по Хаффману, специфичес- 
кие атрибутные байты в состоянии испортить 
 всё дерево. Это мысль номер раз. 
   Установленный  факт, что не обязательно
пользоваться  упаковщиком LC ради достиже- 
ния  близких к предельным (хотя кто знает, 
каковы они?) степеней сжатия. Разложив не- 
сколько экранов по столбцам и наXORив друг 
на друга соседние байты, мы обычно получа- 
ли  массив, сжимаемый  программой ZXRar 
режиме Rar ) до  объёмов  менее полученных 
Laser Compact'ом. Но некоторым экранам XOR 
оказался  противопоказан. Конечно, выигрыш 
надо было бы считать по сравнению с файла- 
ми LC5.2, упакованными с помощью lazy eva- 
luation  или другого "умного" метода опти- 
мизации ссылок,но пока такого LC нет (рав- 
но как и такого Hrust1.x ).Это мысль номер 
 два. 
   В связи с предыдущим высказывалось пре-
дположение, что наXORивание 0,1 битов сто- 
лбца слева на 6,7 биты столбца справа даст 
более  эффективное  дерево. Опыты  не дали 
лучшего  качества  сжатия,  возможно, лишь 
потому, что атрибуты не были отделены. Это 
мысль номер три и задел для будущих экспе- 
риментов. 

                       подготовил А. Кодер




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

Похожие статьи:
Реклама - Реклама и объявления...
wArЫz! - свежий wArЫz: ZX-Light #1-#0c,Black Crow #6,Pussy,Hrip 1.o5,KoSMe #oo,Virtual Worlds #1,WTE 4.0 demo,Psycho Xor demo,Zx-Format Free,3axват 0 demo,Welcome to the hell 0.1.
Бук - Похождения Штирлица и другие приключения Бормана.

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