Info Guide #12
31 декабря 2017

Дикий ум - Компрессия: Первые компрессоры графики на Speccy (часть 1).

         Компрессия
Alone Coder

   Первые  компрессоры  графики  на Speccy
были, наверно, в  Screen  Machine  by  Joe
Gillespie(5'84) и  в комплекте The Artist 
I(6'85). Возможно, была  ещё более старая 
программа,но от неё не сохранилось ничего,
кроме  названия - Fill-Compressor  by Base
Two Software(1983). 
   Но  в фирменных  играх результат работы
экранных компрессоров мне не попадался.
   Первый  известный  спектрумовский комп─
рессор текста (токенами)- Text Compression
System, опубликованный  в  виде листинга в 
сентябре1984. Такие  системы  использова─
лись в некоторых текстовых адвентюрах.
   В80-х  были  и  программы  непонятного
происхождения (из Восточной Европы?), нап─
ример,какой-то странный древний компрессор
экранов с4 методами - COMPRES+.
   Потом пошли отечественные разработки:
  - компрессор  Балясова  COMPRESS (1990,
Москва)
  - ZX ARC(CoCo, Compressor v1.01 - 1991,
Mike Studio S.Peterburg 1782908)
  - ASC packer Сендецкого(1991, Львов)
   Исторически на Speccy (уже в первой ре─
кламе Screen Machine ) сжатие файлов назы─
ваетсякомпрессией (to compress),а не упа─
ковкой илиархивацией. Но слово "упаковка" 
прижилось на постсоветском пространстве.
   На  C64  известен упаковщик с депакером
1986 года Cruncherhttp://csdb.dk/release/
?id=19112 (возможно, были  и древнее). Тут
видна другая традиция наименования,которая
отразилась и на Амиге.
   Самые популярные отечественные компрес─
соры  разобраны в Inferno Guide #5. Основ─
ное  семейство  использует LZ77 (см. Info
Guide #7) с кодированием параметров чем-то 
типаGamma Code или Elias Delta Code, что─
бы короткие числа занимали меньше бит.Т.к.
хранить  ни деревья, ни таблицы не надо, а
распаковку  обычно ведут прямо поверх упа─
кованного файла, дополнительная память та─
ким  декомпрессорам  не требуется. История
спектрумовских компрессоров почти закончи─
лась  с  появлением  небольшого  семейства
компрессоров  с кодомХаффмана (RIP, mRIP,
ZXRar), дальше обычно просто брали готовые 
разработки с других платформ. Арифметичес─
кое  кодирование (см. пример в  Info Guide
#6) оказалось слишком медленным для Z80. 
   Но спектрумовские  компрессоры  всё ещё
можно  улучшить. Можно начинать с развития
кроссплатформенных компрессоров, тем более
что жадные методики легче реализовать там.
В этом  случае  задача  стоит в основном в
разработке хорошего распаковщика.
   В  этой  статье я перечислю идеи, кото─
рые  всплывали  в  долгих  обсуждениях  на
irc.forestnet.org #mhm  с  lvd, hrumer'ом,
jtn'ом и другими. 

     1. Optimal LZ (см. Info Guide #6)
   Для форматов MegaLZ и Hrum реализовано
в mhmt. Для Хаффмана всё сложнее - поэтому
в  RIP и ZXRar  два пресета - для текста и
кодов, плюс тонкие настройки в ZXRar/mRIP.
   Сделать бы оптимальный mRIP - для одно─
го блока долго не понадобятся новые пакеры
в жанре "медленная распаковка с буфером".

lvd>памяти надо N*размер файла (где N=50 
..100), быстродействие нужно M*ГГц, где M
неизвестно) не зря я обещал ящик кока-колы
тому, кто на спеке получит такой же размер
в мегалзе, как на пц мой пакер.

lvd>как должен выглядеть оптимальный LZH 
для пост-хаффмана?перед кодированием имеем
список всех ссылок на КАЖДЫЙ байт. для LZH
рисуем цены каждой и сзаду наперёд строим
путь,а спереду назад его кодируем в выход.
для Хаффмана - кодируем им выход LZH.
alone> сначала пакуем, чтобы узнать длины 
кодов, потом перепаковываем с учётом этой
статистики. можно много раз. а цены те же.
lvd>то есть строим опт. LZH, кодируем 
Хаффманом,потом перестраиваем LZH с учётом
новых цен? а где гарантия, что такое
сойдётся к оптимуму?
alone> нет гарантии. 
lvd>и ещё, не каждая из всех ссылок может 
в Хаффмана попасть. вот ты составил список
всех ссылок, а потом оптимальный путь. и у
тебя в выход попадают не все ссылки из
всех возможных! потому Хаффман назначит
новую цену токо тем,что на него свалились.
alone> дай не попавшим фальшивую длину 15. 
иначе не сможешь следующий проход пройти.
Это нормальный штраф.на последнем проходе,
естественно, все непопавшие исключаются.
lvd>если они непопавшие,это не значит,что 
за них штраф. вдруг если перетасовать
ссылки с учётом новых цен, вылезут много
повторяющихся других, а ты их штрапом.
alone> ну, 15 даст им шанс. а 255 не даст. 
можно медианный фильтр по длинам ссылок
прогнать. если, например, 5 и 7 юзались, а
6 нет, то ей назначится та же длина кода.
lvd>а может, Хаффмана построить по всем 
вообще ссылкам, которые на каждый байт, и
по резалтам назначить цену.потом опт,потом
перехаффман и коррекция цен. и так далее.

lvd>hrumer: а есть что-то типа Дейкстры 
для LZ+Хаффман? или даже LZ+ексомайзер?
hrumer> Да наверняка есть. Кажется, ещё 
круче есть,в 2014 году zip чуток улучшили, 
подзабыл, как алгоритм называется. Формат 
зипа остаётся. Но времени раз в 10 больше 
надо.Екзомайзер уже внутри имеет LZ.А если 
ты про то, есть ли в нём оптимальное коди─ 
рование  для  вычисленных кодов Хаффмана - 
думаю,что есть. А вот хитро ли подбираются 
коды Хаффмана или нет - я даже не пред─ 
положу. Надо исходники ковырять. 
lvd>а там точно Хаффман? я депакер зырил, 
там что-то типа фикс номер из потока
выбирается,лукап в таблице, из неё ссылка.
кол-во разных ссылок ограничено таблицей.
оптимальное кодирование есть на 100%
только для голого LZ. а в случае Хаффман
овер LZ? неужто надо запоминать все ссылки
для всех позиций, чтоб опт. хф+LZ потом
строить? так никаких гигабайтов не хватит.
hrumer> Насколько помню, там отдельно коды 
Хаффмана для дистанций длины 2 и дистанций 
больше длины 2. Для символов коды Хаффмана 
не используются. И хитро, а скорее всего 
стандартно канонически, упакованы деревья 
типа табличек,по которым эти коды Хаффмана 
декодируют.Там коды Хаффмана для длин ещё. 
lvd>ну, то есть, он эвристику изобрёл 
какую-то или решил проблему подбора
оптимального сжатия в случае хф овер LZ?
hrumer> Как я понял, второе. Но полностью 
оптимальное или нет - не знаю. Видимо, с 
каким-то приближением к оптимальному. А 
может,просто перебор с несколькими 
итерациями. Нашёл:http://dml.compkaluga.
ru/forum/index.php?showtopic=74084

hrumer> а кто такой Роман Петров? автор 
рипа первого? круто же товарищ сделал RIP! 
alx_bw>RIP Packer от Романа Петрова. 
отсюда из Йошки.
alone> mRIP пакует обычно лучше RIP'а, и 
депакер влезает в бейсик. Формат от RIP'а,
но упрощён.Алгоритм из ZXRar.В mRIP'е юза─
ется стратегия упаковки lazy evaluation, а
в RIP'е нет. Это когда не ставится ссылка,
если выгоднее поставить символ и другую
ссылку. Результаты по глюксервису: на трёх
блоках суммой 18К mRIP выиграл 17 байт.
alx_bw>а максимальная длина блока какая? 
#a000 умеет?
alone> #8800,наверно.Там сделано по живому 
из ZXRar'а. Это для версии с оболочкой,а в
версии из автосборщика всё зависит от
всего. Ибо результат поверх пишется.
alx_bw>потому как такие блоки я предвари─ 
тельно жму своей RLE.грубо говоря,оно жмёт
одинаковые байты.таблицу прерываний ту же,
если не инициализится, а уже готовая.

Роман Петров> 
   Я разрабатывал  этот упаковщик в школь─
ные годы,а затем после поступления в ВУЗ у 
меня  не было возможности им заниматься, и 
я передал исходники  Петрову Роману, моему 
тёзке и хорошему знакомому. 
alone> 
   А ходили слухи,что это дипломная работа
8) Если не секрет, как разрабатывался фор─
мат? Почему оказалось так похоже на Rar?
Роман Петров> 
   Да уж, хотя  дипломной работой это и не
было,думаю,на диплом бы там вполне хватило 
- учитывая то, какие  дипломы сейчас пишут 
на специальностях,обучающих программирова─ 
нию :) Формат никак,собственно,не разраба─ 
тывался: учась  в школе и освоив Z80 и ас─ 
семблер, я уж не помню  с чего вдруг решил 
разработать  упаковщик данных - и, конечно 
же,он должен был стать самым эффективным:) 
   В начале  разработки  вообще  ничего не
знал  об алгоритмах сжатия, прочитал уж не 
помню где о Lempel-Ziv,начал разрабатывать 
свой паковщик.О кодах переменной длины то─ 
же ничего не знал, подсмотрел, вроде,как у 
HRUST'а сделано,начал придумывать свои ко─ 
ды. Когда уже  в интернете, которого тогда 
было мало, узнал про коды Хаффмана - заго─ 
релся, конечно, реализовал. 
   Вообще  я буквально жил этим "проектом"
(в школе я,конечно,не знал,что такое прог─ 
раммный проект). Ночами, на уроках,в любое 
свободное время искал новые решения, думал 
над  улучшениями качества/cкорости сжатия. 
Каждое улучшение было настоящей победой :) 
Думаю, таких энтузиастов среди спектрумис─ 
тов было немало. Вообще я искал путь напи─ 
сать  идеальный упаковщик, что, как сейчас 
уже понимаю,вряд ли возможно. Одной из са─ 
мых интересных частей проекта был,конечно, 
распаковщик, его  оптимизация по размеру и 
скорости, битва шла  за каждый байт и такт 
процессора,в основном за байты,т.к.я хотел 
уместить  его  в 256(?) байт (сколько  там 
нужно было для бейсик-блока). Задачу так и 
не решил, но бился над ней много :) 
   Насчёт  похожести  на формат RAR - даже
не знаю, почему  так вышло:) Скорее всего, 
совпадение:) Я,конечно,на последних этапах 
разработки, получив какой-никакой доступ в 
интернет,с жадностью добывал информацию,но 
не помню, чтобы я использовал формат RAR - 
вроде бы,тогда он ещё не был опубликован. 
   Позже  почитал про арифметическое коди─
рование, BWT, было интересно, но до реали─ 
зации  этих алгоритмов руки так и не дошли 
- поступил  в  вуз, пересел на ненавистный 
всем  спектрумистам писи :) Была  ещё пара 
интересных  программ, мною  разработанных, 
но которые так никто и не увидел: 
  - программа  копирования защищённых дис─
кет. в последнее время дискеты стали защи─ 
щать, я поставил себе задачу написать уни─ 
версальный копировщик, который просто счи─ 
тывает  всю  информацию с дискеты, включая 
межсекторную,и копирует. Такую программу я 
написал, всё работало вполне неплохо, даже 
учитывая  глючность  контроллера дисковода 
(ВГ93). Но  нашёлся серьёзный глюк в конт─ 
роллере, 41-ю дорожку он упорно считывал с 
ошибками,  тестировал  на  разных  компах. 
Т.е. копирование  диска полностью станови─ 
лось невозможным, тут я ничего  сделать не 
смог, забросил проект. 
  - загрузчик - не знаю, как они называют─
ся, обычно  на  дисках с играми были такие 
для быстрой загрузки игры (курсор + меню). 
Как  это принято, 7 секторов, ну, и макси─ 
мум функционала и быстродействия туда пос─ 
тарался  уместить, в  целом был лучше всех 
распространённых, виденных мной. 
   Вообще для меня это было время, когда я
программировал  с наибольшей  эффективнос─ 
тью, работая  сейчас, эффективность  ниже, 
наверное, раз в 5-10. 
   В настоящее время у меня нет исходников
RIP'a, а мне было бы интересно взгянуть на 
них, поностальгировать и посмотреть, как я 
кодил, будучи в школе :) 
alone> 
   Я пытался  связаться с Megus'ом. Исход─
ники он  не распространял. Himik's ZxZ де─
компилировал программу и выпустил несколь─
ко версий.Вот эти декомпилированные исход─
ники:http://opensourcezx.untergrund.net/
c_soft-packer-rip_src.html
   Я декомпилировал  ZXUnRar, который  за─
бросил  AIG, и  некоторое  время  развивал
программу.Потом у меня сломался PC и стало
неоткуда  брать архивы для тестирования. Я
написал сначала генератор архивов без упа─
ковки, потом  с  упаковкой  (ZXRar). Чтобы
программа занимала как можно меньше (чтобы
пцшники завидовали:)),я её решил упаковать
RIP'ом. Но  у него распаковщик не умещался
в бейсик-блок. Поэтому  я немного упростил
формат и сделал свой RIP (mRIP) из того же
ZXRar, при этом оказалось, что форматы RIP
и Rar мало чем отличаются. Этот mRIP я за─
релизил  в качестве исходника-автосборщика
программ (он есть здесь:http://
alonecoder.nedopc.com/zx/SYS.rar )  -  его
надо  INCLUDE'ить к своим программам, и он
сам их упакует,приклеит бейсик-загрузчик и
запишет на диск.Ещё есть версия mRIP прос─
то для упаковки отдельных файлов. Она тоже
есть на том диске. Её исходники в журнале:
alonecoder.nedopc.com/zx/books/IG10.rar
Роман Петров> 
   Странно, что RIP развивался таким обра─
зом, так-то  я передал исходники Megus'у и 
думал, что он отдаст их всем  на пользова─ 
ние. Странно, кстати,что на Спектруме тема 
Open Source не продвинулось,там ведь очень 
сплочённое  community  было  и практически 
никаких рынков и бизнеса :) 
alone> 
   Для настоящего RIP'а я ковырял распако─
вщик (сократил его на сколько-то байт).
Роман Петров> 
   Это круто! Для меня каждый байт там был
на счету, я чуть голову не сломал, пытаясь 
впихнуть его в 256 байт :) 

        2. Опора на внешние данные
   При упаковке  можно использовать данные
распаковщика - подцеплять его слева к фай─
лу.Юзабельно для 4К интро.Данные ПЗУ лучше
не использовать - бывает разное. Релизовал
lvd в mhmt в2013 году.Пока не релизилось. 
   Эта идея применима и для сжатия текстов
любыми методами, вплоть доPPMd - при упа─
ковке приклеить  слева  типичную  "Войну и
мир",а при распаковке привести распаковщик
в состояние после её распаковки.Может ока─
заться  выгодным просто распаковать её ко─
пию. Евгений Рошал  в курсе :) Просто  для
универсального UnRar в этом мало смысла.

hrumer> словарь в виде депакера. круто:) 
alone> для кодов самое то ) 
hrumer> если сам депакер паковать,то ваще 
все ахнут от степени сжатия. 
alone> рекурсивно? ) 
hrumer> ага. впрочем,там всегда на примере 
RLE - LZ рекурсивен. 

       3. Использовать тонкости ОС
   Для sizecoding можно использовать в ра─
спаковщике  состояние памяти и регистров в
момент запуска файла,учесть адрес запуска,
имя файла и т.п. Можно также  генерировать
бейсик-загрузчик  с кодом  внутри номера и
длины строки,неиспользуемой части чисел...

lvd>я когда 4к на омиге писал,тоже мудрил 
с екзешником. т.е.брал екзешник непакован─
ный и мудрил с секциями амижными. чтобы,
например, выделение всей памяти было
описано в секциях. дата и код были в одной
секции,но указанный размер был дата+код, а
кода в ехе было мало.
crinkler is navigating inside internal
windows process structure in order to
directly get the address of the functions
from the in-memory import table.
ну вот, в виндоз 8 (9,10) не заработает.

           4. Автоподбор метода
hrumer> пока делал оптимизацию 
дехруста, я,на каком то этапе рассматривая 
3 варианта кодирования, всё же один на 
потом оставил и забыл про него.Из-за этого 
у хруста могло быть сжатие лучше. 
lvd>а вообще твои пакеры опирались на 
какие-нибудь теор. исследования?
hrumer> если у тебя есть возможность упра─ 
влять форматом сохраненных данных,то наво─ 
ротить можно кучу. вот и наворотил. взял 
десяток игрушек,которые нравились мне,и на 
них тестил, что лучше работает,а что хуже. 

hrumer> нашёл знатный фейл в хрусте1. там 
много чего неиспользованного, но то, что 
нашёл где-то полгода назад - это айяйяй.:) 
alone> может, в mhmt исправлено? ) 
hrumer> в mhmt это частично исправлено, 
коды наверняка юзаются, но главное - это 
проблема формата, а в оригинальном хрусте1 
в одной из веток коды сохраняются в виде 4 
бит,т.е.1-16,а используются только 9-16.:) 
ну, и в хрусте до кучи неиспользуемых 
кодов...но это-то я знаю,а вот про то, что 
глюканул и не проверил кое-чего, это да... 
т.е. ё-мое, 1 бит экономим. а сколько раз 
встречается такая штука..наверное,много... 
надо хоть версию, где подсчет этой фигни 
ведётся. на сколько байт получился промах. 
alone> надо ещё сделать вторую версию 
пакера и депакера - для распаковки задом
наперёд. и выбирать ту, которая выгоднее.
hrumer> ага, читал извраты металбрайна и 
товарищей на примере exomizer2. 
alone> насчёт оптимизации под пакер - я 
одно время код оптимизировал под пакер.
вместо циклов дупы, а процедур - макросы.
hrumer> + Рощин еще написал статью про то, 
что любят пакеры. 

lvd>если взять 2 файла разных (например, 
код и графику), то ехомизер по отдельности
их сожмёт лучше, чем если как один жать.
alone> В mRIP'е тоже так будет. 

lvd>софт не обязательно должен быть 
многопоточный. просто его надо запустить
одновременно 10 штук. или 100. распарал─
лелить проще простого - каждый цпу ищет
совпадения в своём куске файла. потом надо
только склеить то, что они напонаходили.

    5. Настройка распаковщика под файл
   Например,в компрессоре PuCrunch эскейп-
коды настраиваются под файл (и могут меня─
ться  на  лету), а коды для заполненияRLE
берутся из таблицы (16(?) отсортированных
по частоте значений) - см.http://www.
ffd2.com/fridge/chacking/c=hacking17.txt
   Этот принцип можно применить и для упа─
ковки кодов команд (сейчас они обычно хра─
нятся как байты).
   Для статистики, самые частые коды в ПЗУ
48K Бейсика (при  его эмуляции):exx (6%), 
call (4.7%),jr z (5.6%),jr nz (3.5%), пре─
фиксed (5.5%), префикс cb (5.4%), префикс
дляiy (4.8%) - в сумме 35%. Можно предус─
мотреть несколько  контекстов 4-битных ко─
манд.Например,где-то надо многоld (hl),n:
inc hl, а где-то многоcall nn:ld (nn),hl. 

alone> Ты ещё не экспериментировал с 
короткими байтами?
hrumer> не. но думаю заняться ночным 
кодингом :) 
alone> Я вот думаю:все пакеры пакуют файл 
подряд. А можно ли выиграть, если паковать
в каком-то сложном порядке? Типа как
картинку рисуют во всяких хоббитах.
hrumer> накладные расходы появятся. но 
должны окупиться. но сложность возрастет. 
была мысль, да впрочем она реализована - 
паковать экран. при распаковке не распако─ 
вывать нули :) 
alone> Ещё чисто для сжатия кода старая 
идея - отделять команды от данных, хоть
грубо. Было несколько идей:
  А) честно смотреть длину команд - это
160 байт кода примерно.
  Б) сделать в пакере правила, по которым
можно будет подгонять код.
  В) ловить данные только в командах ld.
С LZ надо 2 потока каждый со своей адреса─
цией,которые потом склеивать.Но если будут
правила, по которым можно будет подгонять
код, то,может,и с общей адресацией выйдет.
Параметры jr, кстати, сильно отличаются по
распределению от параметров ld. Jp/call -
тоже своё, причём младший байт рандомный,
а старший коррелирует со старшим байтом
адреса и старшим байтом прошлого jp/call.
Младший байт можно сделать, чтобы делился
на 4, например. Руками.
hrumer> вот из-за этого в хрусте появился 
"вставной байт". На PC, как я понял, в бо─ 
льшинстве случаев не заморачиваются,просто 
относительную  адресацию  заменяют на пря─ 
мую, а потом после распаковки,видимо,обра─ 
тно. остальное замудрённо реализовывать. 
из реальных вариантов тока сброс окна при 
смене кода/графики/текста с #4000 до, 
например, #100 с последующим возрастанием. 
alone> Ещё идея - считать на каждом байте 
эвристику (допустим, 4 бита), лезть по ней
в массив и брать оттуда данные коротким
кодом. Можно ещё обновлять на лету.

Leaf5874> По скрипту - есть мысль сделать 
команду callmacro n,где n - номер макроса.
И в макросе одна команда или несколько,
можно читать параметры. Их будет немного.
Так можно и все команды описать, но тогда
надо Хаффманом кодировать - будет жырный
интерпретатор.По уму компилятор должен сам
найти статистику команд и выбрать для них
длины кодов. Как пакер.
Ещё интересное наблюдение - много call
идёт непосредственно после следующего ret.
Вызов непосредственно примыкающей подпрог─
раммы,а остальные сделать с отн. адресом с
расширяемым кодом. Можно все команды скри─
пта сделать через callmacro, тогда n надо
кодировать Хаффманом (код может подобрать
компилятор).По сути упакованная программа,
но при этом исполняемая!
hrumer> Leaf5874: Alone, я тебя уже узнаю 
по почерку! ) 
Leaf5874> Выравнивание на байт надо только 
для целых процедур. Макросы с параметрами
можно через call interpreter_getNbits.
Походу достаточно всего около 20 универса─
льных макросов, как в пи-коде у компилято─
ров.Обращение к переменным в скрипте деше─
вле,чем в машкоде - нужен только их номер,
а не адрес. 7 бит может хватить для прог─
раммы типа ACEdit'а.Их номера,конечно,тоже
можно Хаффманом,но где-то надо таблицу ) А
по поводу упаковки ещё есть идея:разделять
команды и данные. Но чтобы не искать, где
что, самим депакером, можно кодировать их
в самом коде. Например,выравниваем все
команды на 4 байта.
0 0 0 кмд - однобайтная команда
0 0 кмд парам - команда с 1-байтным
               параметром или 2-байтная
0 кмд парам парам - понятно
Кмд кмд кмд кмд - 4-байтная
Смещения будут делиться на 4. Два бита
срезаем. Генерить такой код можно любым
макроассемблером. Для 4-байтной может быть
лучше разбирать как кмд кмд парам кмд.
hrumer> Извращенная идея! ) Рабочая. ) 

hrumer> коды для длин не все брать, а, на─ 
пример,исключить нечётные длины 7,9,11,13, 
и тому подобное.сэкономим 1 бит на кодиро─ 
вании длин 6,8,10,12.в 50% случаев без на─ 
кладок,а с учетом оптимального кодирования 
будет не 50% без накладок, а выше, до 80%. 
а оставшиеся 20% или на самотёк пустить, 
или сделать repeat distance для длины в 1. 

hrumer> lvd: я смотрел exomizer. хорошо 
придумано с деревьями, с распаковщиком. 
Автор может ещё выпустить версию 3,возьмёт 
и введёт код, который отвечает за 
обновление деревьев :) 
lvd>я в депакере увидел заполнение 
таблички, из которой потом выбираются
смещения. это и есть те самые деревья?
hrumer> ага, я их деревьями называю. 
таблички и есть. 
alone> какой сам принцип екзомизера? 
hrumer> экзомизер - деревья только для 
длин и смещений. вся хитрость в пакере, 
который пытается вычсчитать оптимальные 
деревья, а потом оптимально закодировать. 
я внутри пакера экзомизера не копался, 
но в депакере все уши торчат :) 
alone> У меня была идея пересчитывать 
литералы по табличке в сортированные по
частоте,а потом битовые длины делать через
код.Можно несколько вариантов такого кода.
Это не Хаффман,но всё равно круто, и всего
256 байт на дерево.
lvd>ну вот ехомизер так и делает, видимо. 
или похоже как-то.

lvd>а zx7? говорят, жмёт круче ехомизера. 
hrumer> zx7, вроде, обычный, особенность в 
том,что смещение длиной до 128 байт короче 
кодируется.+ пакер оптимальные пары ищет. 

hrumer> Alone, crinkler смотрел? :) 
alone> а что там? 
hrumer> а там..а у меня неругательных слов 
нет, что там. 
alone> он вообще хорошо пакует? 
hrumer> Хорошо пакует. на 4к демы 
рассчитан. на уровне линковки, что ли, 
подбирается,где что хранить.при распаковке 
тучу памяти использует. депакер короткий. 
это то,что я помню. пару лет назад смотрел 
подробнее. но там взрыв мозга. будешь 
заглядывать - крепись :) 
alone> использовать память при 4к логично. 
там можно и LZ78 сделать.

alone> кстати, ты не разбирался с LZMA? 
hrumer> LZMA - не, но так, читал слегка. 
Там какой то буржуй в своем блоге офигевал 
от хитростей, которые там есть. там пара 
хитростей,а потом какое то умопомрачитель─ 
ное еще и дожатие... атас... лови ссылку: 
http://cbloomrants.blogspot.ru/
2010/08/08-20-10-deobfuscating-lzma.html

lvd>есть одна задачка. для хруста есть 2 
депукера. один быстрый, но через стек (поп
хл данные выбирает). другой медленный, но
без стека.медленный аж настолько,что выби─
рает из IX.сделан заменой поп хл на загру─
зку hl из ix.ну так вот.вместо pop hl надо
приделать ld a,[hl]:inc hl. намётки были
(в svn есть),но упёрлось в сохранение фла─
гов овер длинных кусков кода.благо МОЙ па─
кер позволяет менять формат таким макаром
:) вместо 16-битных наборов битов делать
8-битные. двойной профит - быстрый и
бесстековый депакер хруста выйдет.

        6. Упаковщик для листалок
   При упаковке текста для использования в
листалке нет смысла загонять буквы в4 би─
та (в5 бит было в листалке ZX Time ). Вы─
годнее  кодировать слоги (или моры соглас─
ная-гласная) одним  числом (это может быть
больше, чем байт) и сжимать Хаффманом.

jtn> я в з80-6 делал токены двухбуквенные. 
считал все и сортировал. 
alone> у тебя депакинг в реалтайме? 
jtn> да. там рле+токены в реалтайме. 
alone> и сильно жмёт? 
jtn> процентов 30, если не вру. 
alone> у мну Хаффман реалтаймовый сжал 
146К в 97К. ZX-Guide #3 "Понедельник-2".
jtn> так там скролл почти фреймовый. 
alone> у меня совсем фреймовый. 23 строки. 
jtn> как ты Хаффман в рилтайме разожмёшь? 
alone> там у меня длина Хаффмана 
ограничена 8 битами.
jtn> ну,значит,зачот.у мну без подзагрузок 
+ 2 фонта. 4х8 и пропорциональный 
(сдвинутый 8 раз). и всё в 128к. текста 
вроде чистого около 70к. 
alone> нефреймово можно и 200К, я 
когда-то считал. но это всё 128-е времена.

   Ещё   вариант: Fast  Recursive  Coding
Based on Grouping of Symbolshttp://arxiv.
org/ftp/arxiv/papers/0708/0708.2893.pdf

        7. Расширяемые коды ссылок
   Можно сужать  и  расширять  коды ссылок
в разных  местах  файла. Один пример был в
Hrust1, но варианты неисчислимы. 

hrumer> у меня была идея делать коды для 
смещений и длин разной длины, но с ограни─ 
чением на то,что их длины возрастают,и ак─ 
куратно использовать в депакере(+обновлять 
по мере продвижения по файлу).но я не смог 
написать компактной реализации на z80 :( 

alone> я писал упаковку звука по методу 
DAKX, сжимает иногда раза в два.
но для кода неизвестно что будет.
hrumer> я вот чёт не до конца въехал 
насчёт DAKX. это типа просто кодируем 
число,и чем больше число,тем больше битов? 
1 - %1. 2 - %10, 3 - 110. и т.д. 
а последнее число все единицы. так? 
alone> нет,там хранится текущая ширина ко─ 
да,она обновляется в зависимости от числа.
если идут маленькие числа - сужаем код,ес─
ли большие - расширяем:http://alonecoder.
nedopc.com/zx/books/zxg4html/dakx.htm
это можно применить и для ссылок в LZ!
hrumer> скинул себе, буду осмысливать. 
я, кстати, параллельно над лазекомпактом 
голову ломаю. есть ли короткое исполнение 
на z80 таких кодов: 0,1x0,1x1x0,1x1x1xx 
(как в LC5) но! при урезании длины кода до 
1,2,3,4,5,6,7 бит. 
alone> такого не видел. 
hrumer> в LC можно отлично выиграть на 
этом. но короткая реализация такого - это 
надо голову ломать. 

alone> Можно ли выиграть, если все метки и 
переходы будут по чётным адресам?
hrumer> не, ковыряю и собираю статистику 
по Бурнашевскому сишному hrum3.5. смотрел, 
длины как распределяются. на некоторых 
файлах при только чётных длинах от 6 можно 
выиграть. но сколько - пока не посчитал. 
с длинами = 1 тоже всё зависит от файла. 
на некоторых можно выиграть, если длину 
брать макисимум = 4, а не 8. 
alone> А можно выиграть, если не юзать 
длины 1,2 и кодировать 3 и т.д. как старые
1 и т.д.?
hrumer> весь предполагаемый выигрыш сожрут 
"непакуемые" байты, кодируемые 9 битами. 
кстати, нашел более выигрышное (по 
скорости распаковки) кодирование длин. 
биты просто по-другому записывать. 
;альтернативный вариант:
    LD B,256-16
DPC4 LD A,%01000000
DPC2
    SLA C
    JR NZ,$+6
    LD C,(HL)
    INC HL
    RL C
    RLA
    JR NC,DPC2
;--
    JR NZ,LENXX;12/7 закончили с длинами
    INC B      ;4
    INC B      ;4
    INC B      ;4
    JR NZ,DPC4 ;12/7 если не 16, то ещё
                 ;берем. тут 16, но А = 0,
               ;и далее в В результат уже.
    DEC B      ;4 тут ещё можно сделать
               ;DJNZ на этот адрес. но это
               ;длиннее на 1 байт, но,
               ;возможно, быстрее
LENXX
    ADD A,B    ;4
    DEC A      ;4 ;или это убрать и выше
              ;загрузить B,15 с переходом.
    CP 256-16+4;7 extended number.
    JR Z,DPC5;B<>1;B=4  ;12/7
    ADC A,256-16-1;корректировка. ;7
alone> И какие коды получаются? 
hrumer> да по длинам те же самые. 
alone> А если b в цикле не инкрементить, а 
декрементить, выигрыша нет? В цикле только
djnz,а на выходе 3 раза add a,b(или sub b)
hrumer> декрементить думал, но там после 
этого править длину надо через вычитание. 

hrumer> ещё из реальных, но не реализован─ 
ных - непакуемые байты: если "А" не упако─ 
вался,а за ним "BCDEFG..." не упаковались, 
то не должно быть такого, что А идёт отде─ 
льно,а BCDEF...отдельно.Значит,код,который 
показывает непакованный блок, не должен 
идти за непакованным байтом. Значит, этот 
код что-то другое может кодировать. но это 
копейки... ещё из реальных,но копеечных - 
вставной символ. если вставной символ 
совпадает с символом, который был D байт 
назад,то это что-то могло бы значить... 
alone> В этой ситуации можно сдвинуть 
все коды длин ссылок на 1.
hrumer> кстати, для текста, видимо, после 
паковки байтов 100-300 можно длину не с 1 
брать,а с 2. и для графики надо потестить. 
т.е. min len сначала = 1, потом =2. 
alone> А если вообще без длины 1? Сколько 
проигрыш? В RIP длины вообще от 3
начинаются. Но там Хаффман.
hrumer> без длины = 1 - на текстах даже 
выигрыш, причем без дожатия Хаффаном. на 
графике тоже. 
alone> тогда надо менять формат хруста ) 
hrumer> корректировать minlen прямо в 
потоке, ага. 



Другие статьи номера:

Помощь - об оболочке: произошли некоторые изменения в кнопках.

Предисловие - от авторов: Прошедшие два года были очень насыщенными.

Комьюнити - ZX Spectrum: Как это было в Рязани (1980-е).

Комьюнити - ZX Spectrum: Как это было в Рязани (1991-1993).

Комьюнити - ZX Spectrum: Как это было в Рязани (1993-1995).

Комьюнити - ZX Spectrum: Как это было в Рязани (1995-1997).

Комьюнити - сценеры шутят.

Код - этюды: вызов процедур по списку адресов.

Код - 3D демы на ZX Spectrum: история развития 3д движков.

Код - 3D движок: оптимизация на прообразе 3D Construction Kit.

Код - 3D движок: фрагменты.

Код - Посекторный движок для 3D-шутера от Destr.

Код - 3D скролл на ZX Spectrum (часть 1).

Код - 3D скролл на ZX Spectrum: реализация (часть 2).

Графика - графические редакторы: Старый софт от Alone Coder'а.

Графика - палитра: Палитровые эффекты в играх.

Музыка - биперные движки: Двоичная модуляция (часть 1).

Музыка - биперные движки: Двоичная модуляция (часть 1).

Системки - история операционной системы CP/M для Спектрума (часть 1).

Системки - история операционной системы CP/M для Спектрума: ограничения (часть 2).

Системки - NedoLang: Начало - самый простой процедурный язык (часть 1).

Системки - NedoLang: Путь к самокомпиляции (часть 2).

Системки - NedoLang: Проклятие языка Си (часть 3).

Системки - NedoLang: Памяти под самокомпиляцию не хватало (часть 4).

Системки - NedoLang: ускорение (часть 5).

Системки - NedoLang: Куда плыть дальше (часть 6).

Металлолом - Знакомьтесь, ATM-turbo 3! ATM-turbo 3 (v8.0) - что это такое и с чем его едят.

Металлолом - Из истории Betadisk'а: Дисковый интерфейс от Technology Research был.

Дикий ум - Компрессия: Первые компрессоры графики на Speccy (часть 1).

Дикий ум - Компрессия: Фичи с эвристикой, Потоковая декомпрессия, Сжатие музыки (часть 2).

Игрушки - От редакции: 2017-й год вышел очень богатым на события.

Игрушки - интервью с автором игры Mickey the Basic game (Sergio).

Игрушки - квест "Неожиданное Путешествие" - взгляд изнутри.

Игрушки - Nomad: интервью с автором скролл-шутера Nomad (Hippiman).

Игрушки - Скроллинг в Evo SDK.

Игрушки - Hints & Tips: Mickey, Nomad.

Мыльница - Errata: ошибки в Info Guide #11, ACNews #65.

Письма - отзывы о журнале от: raver, destr, sirx, survivor, Ellvis, Utz и Николая Амосова.

Об авторах - Авторы журнала.


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

Похожие статьи:
Экзамен - вопросы по игре "They Stoley a million" и ответы на прошлые.
От редактора - мы cнова c вами.
Улыбки - расшифровка смайликов на все случаи жизни.

В этот день...   21 июля