Распаковка данных в формате BriefLZ на Ассемблере
Распаковка данных в формате BriefLZ на Ассемблере
Программиста Joergen Ibsen вы можете знать, как автора популярной библиотеки aPLib и DOS'овского упаковщика исполняемых файлов aPACK, который на протяжении многих лет неизменно занимал первые строки рейтингов по степени компрессии. Про aPLib поговорим позже, а сегодня будет распаковщик для еще одной разработки Joergen Ibsen - BriefLZ. Это высокоскоростная разновидность Lempel-Ziv алгоритма для сжатия данных, по степени компрессии приближающаяся к zlib.
Заголовок упакованных данных, на мой взгляд, несколько избыточен. Тут контрольные суммы CRC32 упакованных и исходных данных, размер упакованных и исходных данных, формат данных и сигнатура, всего 6 DWORD'ов. Для больших объемов данных это погоды не делает, а на маленьких блоках информации десяток-другой байт можно было бы и сэкономить. Впрочем, автору виднее. Исходники открыты, при необходимости упаковщик можно модифицировать. Из всего заголовка нас интересует 5-й DWORD, в котором содержится размер исходных данных. Для приведения этого DWORD'а в нужный вид к нему придется дополнительно применить команду BSWAP. Эта информация потребуется при определении размера буфера-приемника для распакованных данных.
В официальных исходниках есть пример упаковщика, но вот собирать его мне пришлось самостоятельно. В комментариях к одной из статей меня как-то спросили, зачем я вкладываю в архивы с примерами уже скомпилированные файлы. Вот именно затем и вкладываю. Заставлять пользователя устанавливать среду типа Visual Studio или MinGW, в которой можно собрать авторские исходники, а потом настраивать ее в соответствии с авторским видением окружения, - это неимоверно напрягает. Это же касается и сборки релизов только под x64, если такой вариант не является единственно возможным. Не будем о грустном, переходим к коду распаковщика.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Распаковка данных в формате BriefLZ
- ;------------------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; lpOut - указатель на буфер для распакованных данных
- ; На выходе:
- ; EAX = размер распакованных данных
- ;------------------------------------------------------------
- proc brieflz_unpack lpCompressed:DWORD,lpOut:DWORD
- pusha
- mov esi,[lpCompressed]
- mov edi,[lpOut]
- mov ebx,edi
- lodsd
- lodsd
- lodsd
- lodsd
- lodsd
- bswap eax
- add ebx,eax
- lodsd
- mov ax,8000h
- .brieflz_literal:
- movsb
- .brieflz_main:
- cmp edi,ebx
- jnb .brieflz_exit
- stdcall .brieflz_getbit
- jnc .brieflz_literal
- .brieflz_getgamma:
- pushfd
- cdq
- inc edx
- .brieflz_gamma_loop:
- stdcall .brieflz_getbit
- adc edx,edx
- stdcall .brieflz_getbit
- jc .brieflz_gamma_loop
- popfd
- cmovc ecx,edx
- cmc
- jnc .brieflz_getgamma
- dec edx
- dec edx
- inc ecx
- inc ecx
- shl edx,8
- mov dl,[esi]
- inc esi
- inc edx
- push esi
- mov esi,edi
- sub esi,edx
- rep movsb
- pop esi
- jmp .brieflz_main
- .brieflz_getbit:
- add ax,ax
- jnz .brieflz_exit_getbit
- lodsw
- adc ax,ax
- .brieflz_exit_getbit:
- retn
- .brieflz_exit:
- sub edi,[lpOut]
- mov [esp+28],edi
- popa
- ret
- endp
В приложении пример программы с исходным текстом, которая извлекает из памяти иконку, упакованную по алгоритму BriefLZ, и выводит ее на форму. Там же в архиве утилита для упаковки и распаковки данных от Joergen Ibsen.
Просмотров: 979 | Комментариев: 1
Метки: Assembler, распаковка
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
DRON
(10.02.2021 в 17:58):
Там вроде --optimal надо для максимального сжатия передавать, а не -9, но результаты всё равно хуже чем у aPLib.
Добавить комментарий
Заполните форму для добавления комментария