Сжатие LZX / LZSS, старые игры от Blizzard |
Добро пожаловать, гость ( Вход | Регистрация )
Сжатие LZX / LZSS, старые игры от Blizzard |
-=CHE@TER=- |
Jun 20 2010, 13:46
Сообщение
#1
|
Walter Sullivan Группа: Root Admin Сообщений: 1,361 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 314 раз(а) |
Тут интересную тему подняли на Extractor.ru:
_ttp://www.extractor.ru/ipb/index.php?showtopic=2111 Нашёл описание Microsoft LZX - он ближе всех походит: _ttp://www.nf-team.org/drmad/zf/zf5/zf5_025.htm Занятный алгоритм. Я практически разобрал формат архивов и сжатия. Там используется какая-то модификация LZX - см. ссылку, которую я дал. Всё бы хорошо, но вот отчего-то у меня после распаковки в 64 байтах файл расходится с тем, что должно быть (там человек выкладывал файл сграбленный из памяти). А расходится из-за того, что окно (window) при распаковке ездит взад и вперёд. В общем, за 2 дня интенсивного mindfuck'а я уже совсем отупел, хотя 90% разобрал как работает... Формат сжатых данных: BYTE - байт-маска, указывающие какие идут данные за ним (обрабатывать нужно задом наперёд!). Если в байте бит зажжён - значит нужно прочитать из входного файла 1 байт и переместить его в выходной поток. Если бит не зажжён, то нужно прочитать из входного файла 2 байта (WORD), которые потом интерпретируются как отсылка к уже распакованным данным (см. ниже). Пусть наш байт будет такой: 10010111 - это значит из файл мы должны прочитать (обрабатывать нужно задом наперёд!): BYTE BYTE BYTE WORD BYTE WORD WORD BYTE Причём, все прочитанные байты мы сразу складываем в выходной файл, а когда читаем WORD, то делаем следующее: Предположим мы прочитали значение типа WORD и оно равно $0FFD - первые 4 бита - количество байт, которые нужно переслать минус 3 (т.е. нужно всегда добавлять 3, чтобы получить количество для пересылки!). Оставшиеся 12 бит (вот тут засада) это адрес в уже распакованном потоке, откуда эти данные нужно читать в выходной. Дело в том, что при распаковке выходной поток используется и как входной тоже. В общем, для $0FFD количество байт для чтения равно 3 (0 + 3), а смещение 0xFFD от начала (?) потока. Но, т.к. поток делится на окна по 4096 ($1000) байт, то тут возникает проблема. Дело в том, что окно смещается вместе с распакованным потоком, но как получить его точное расположение, я не понял. Пока размер распакованного потока менее 4096 - всё ок, как только стал больше, так начинаю брать смещение уже не оттуда. Что самое смешное, так это то что, похоже, экно ездит то вперёд, то назад, потому что я что только не делал и как только его сдвиг не считал - в зависимости от кувырканий, то одни, то другие байты не совпадают. Вот исходные коды распаковщика LZX: lzxfiles.zip (~37 Kb) Что там внутри: 1.zlx - упакованная музыка 1.xmi - дамп распакованной unlzx.c - исходные коды unlzx.exe - программа BTHORNE.EXE - исполняемый файл игры Black Thorne, в исходных кодах я оставил адреса процедуры распаковки z.bat - после его запуска будет произведена попытка распаковать файл и появятся ещё 3 файла: dump - распакованный поток l - сравнение распакованного потока с оригиналом list - это я делал вывод программы для удобства отладки Уф... Кто-нибудь хочет / может помочь? Я просто где-то долблюсь в стенку лбом и не вижу двери. Наставьте, пожалуйста, на путь истинный! (*улыбается*) |
Упрощённая версия | Сейчас: 14th November 2024 - 10:05 |