Info Guide
#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 биты столбца справа даст более эффективное дерево. Опыты не дали лучшего качества сжатия, возможно, лишь потому, что атрибуты не были отделены. Это мысль номер три и задел для будущих экспе- риментов. подготовил А. Кодер
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября