Распаковка данных в формате LZE на Ассемблере
Распаковка данных в формате LZE на Ассемблере
Продолжаем тему о распаковке сжатых данных. Сегодня это будет алгоритм LZE. Этот алгоритм разработал в далеком 1989 году Fabrice Bellard, известный как один из разработчиков проекта FFmpeg и упаковщика исполняемых файлов LZEXE, популярного во времена MS-DOS. В этом упаковщике и применялся указанный алгоритм. Fabrice Bellard не стал выкладывать описание LZE в публичный доступ, но в 1995 году японец Hiroaki Goto отреверсил алгоритм и опубликовал его на своем сайте. Я перевел его функцию распаковки с 16-битного Ассемблера на 32-битный, теперь ее, так же как и LZ4, можно использовать в своих проектах.
Для упаковки данных надо использовать утилиту из прилагаемого архива. Чтобы получить размер памяти, необходимой для распаковки, никаких дополнительных танцев с бубном совершать не надо. Размер исходной информации записан в первом DWORD'е упакованных данных, только к нему надо будет применить команду BSWAP, чтобы установить правильный порядок байт. С 4-го байта идут сами упакованные данные. Коэффициент сжатия получается неплохим, на некоторых файлах он превосходит LZ4, на некоторых уступает ему, так что подбирайте инструмент под задачу.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Распаковка данных в формате LZE
- ;------------------------------------------------------------
- ; Оригинальный код: Hiroaki Goto, модификация: ManHunter / PCL
- ;------------------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; lpOut - указатель на буфер для распакованных данных
- ; На выходе:
- ; EAX = размер распакованных данных
- ;------------------------------------------------------------
- proc lze_unpack lpCompressed:DWORD,lpOut:DWORD
- pusha
- mov esi,[lpCompressed]
- lodsd
- mov edi,[lpOut]
- mov ebx,esi
- cld
- mov dh,1
- .decode_lze_1:
- mov al,byte[ebx]
- inc ebx
- stosb
- .decode_lze_2:
- stdcall .decode_bit_test
- jc .decode_lze_1
- xor eax,eax
- dec ax
- stdcall .decode_bit_test
- jc .decode_lze_5
- xor ecx,ecx
- stdcall .decode_bit_test
- adc ecx,ecx
- stdcall .decode_bit_test
- adc ecx,ecx
- mov al,byte[ebx]
- inc ebx
- .decode_lze_3:
- inc ecx
- .decode_lze_4:
- mov esi,edi
- movsx eax,ax
- add esi,eax
- inc ecx
- rep movsb
- jmp .decode_lze_2
- .decode_lze_5:
- mov ah,byte[ebx]
- inc ebx
- mov al,byte[ebx]
- inc ebx
- mov ecx,eax
- shr eax,3
- or ah,0E0h
- and ecx,7
- jnz .decode_lze_3
- mov cl,byte[ebx]
- inc ebx
- or cl,cl
- jnz .decode_lze_4
- sub edi,[lpOut]
- mov [esp+28],edi
- popa
- ret
- .decode_bit_test:
- dec dh
- jnz @f
- mov dl,byte[ebx]
- inc ebx
- mov dh,8
- @@:
- add dl,dl
- retn
- endp
В приложении пример программы с исходным текстом, которая извлекает из памяти иконку, упакованную по алгоритму LZE, и выводит ее на форму. Там же в архиве утилиты для упаковки и распаковки данных от Hiroaki Goto вместе с исходниками.
Просмотров: 962 | Комментариев: 0
Метки: Assembler, распаковка
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария