Распаковка данных в формате MegaLZ на Ассемблере
Распаковка данных в формате MegaLZ на Ассемблере
Алгоритм MegaLZ был разработан участниками демо-группы MAYhEM для AmigaOS, но из открытых исходников можно собрать упаковщик для Windows. Степень компрессии неплохая, особенно на текстовых данных, на бинарных файлах чуть похуже. И при этом MegaLZ работает очень быстро как на упаковку, так и на распаковку, что тоже является его несомненным плюсом.
Из авторских исходников я скомпилировал консольную утилиту для упаковки и распаковки данных, она есть в прилагаемом к статье архиве. Упакованные данные идут сплошным потоком, в них не содержится никакой информации ни об их размере, ни о размере исходных данных.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Распаковка данных в формате MegaLZ
- ;------------------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; lpOut - указатель на буфер для распакованных данных
- ; На выходе:
- ; EAX = размер распакованных данных
- ;------------------------------------------------------------
- proc megalz_unpack lpCompressed:DWORD,lpOut:DWORD
- pusha
- mov esi,[lpCompressed]
- mov edi,[lpOut]
- mov al,128
- .megalz_literal:
- movsb
- .megalz_main:
- stdcall .get_bit
- jc .megalz_literal
- xor edx,edx
- mov dh,-1
- xor ebx,ebx
- push 2
- pop ecx
- stdcall .get_bit
- jc .case_1x
- stdcall .get_bit
- jc .megalz_short_offset
- dec ecx
- mov dl,63
- .read_3_bits:
- stdcall .get_bit
- adc dl,dl
- jnc .read_3_bits
- .megalz_copy_bytes:
- push esi
- movsx edx,dx
- lea esi,[edi+edx]
- rep movsb
- pop esi
- jmp .megalz_main
- .case_1x:
- stdcall .get_bit
- jnc .case_10
- dec ecx
- .read_log_len:
- stdcall .get_bit
- inc ebx
- jnc .read_log_len
- .megalz_read_len:
- stdcall .get_bit
- adc cl,cl
- jc .megalz_exit
- dec ebx
- jnz .megalz_read_len
- inc ecx
- .case_10:
- inc ecx
- stdcall .get_bit
- jnc .megalz_short_offset
- mov dh,31
- .megalz_long_offset:
- stdcall .get_bit
- adc dh,dh
- jnc .megalz_long_offset
- dec edx
- .megalz_short_offset:
- mov dl,[esi]
- inc esi
- jmp .megalz_copy_bytes
- .megalz_exit:
- sub edi,[lpOut]
- mov [esp+28],edi
- popa
- ret
- .get_bit:
- add al,al
- jnz .exit_get_bit
- lodsb
- adc al,al
- .exit_get_bit:
- retn
- endp
Так как размер исходных данных заранее не определен, перед распаковкой его надо обязательно узнать, чтобы выделить соответствующий объем памяти. Для этого я сделал следующую функцию.
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------------
- ; Получение размера распакованных данных
- ;---------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; На выходе:
- ; EAX = размер распакованных данных
- ;---------------------------------------------------
- proc megalz_size lpCompressed:DWORD
- pusha
- mov esi,[lpCompressed]
- xor edi,edi
- mov al,128
- .megalz_literal:
- inc esi
- inc edi
- .megalz_main:
- stdcall .get_bit
- jc .megalz_literal
- xor edx,edx
- mov dh,-1
- xor ebx,ebx
- push 2
- pop ecx
- stdcall .get_bit
- jc .case_1x
- stdcall .get_bit
- jc .megalz_short_offset
- dec ecx
- mov dl,63
- .read_3_bits:
- stdcall .get_bit
- adc dl,dl
- jnc .read_3_bits
- .megalz_copy_bytes:
- add edi,ecx
- jmp .megalz_main
- .case_1x:
- stdcall .get_bit
- jnc .case_10
- dec ecx
- .read_log_len:
- stdcall .get_bit
- inc ebx
- jnc .read_log_len
- .megalz_read_len:
- stdcall .get_bit
- adc cl,cl
- jc .megalz_exit
- dec ebx
- jnz .megalz_read_len
- inc ecx
- .case_10:
- inc ecx
- stdcall .get_bit
- jnc .megalz_short_offset
- mov dh,31
- .megalz_long_offset:
- stdcall .get_bit
- adc dh,dh
- jnc .megalz_long_offset
- dec edx
- .megalz_short_offset:
- mov dl,[esi]
- inc esi
- jmp .megalz_copy_bytes
- .megalz_exit:
- mov [esp+28],edi
- popa
- ret
- .get_bit:
- add al,al
- jnz .exit_get_bit
- lodsb
- adc al,al
- .exit_get_bit:
- retn
- endp
В приложении пример программы с исходным текстом, которая извлекает из памяти иконку, упакованную по алгоритму MegaLZ, и выводит ее на форму. Там же в архиве утилита для упаковки и распаковки данных от MAYhEM.
Просмотров: 840 | Комментариев: 0
Метки: Assembler, распаковка
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария