148 lines
2.2 KiB
NASM
148 lines
2.2 KiB
NASM
;; File: lzp.asm
|
|
|
|
; Lempel-Ziv + Prediction (a fast, efficient, and memory-use
|
|
; conservative compression algorithm)
|
|
; (paper: https://ieeexplore.ieee.org/document/488353)
|
|
format COFF
|
|
use32
|
|
|
|
;; https://hugi.scene.org/online/coding/hugi%2012%20-%20colzp.htm
|
|
|
|
LZP_HASH_ORDER = 16
|
|
LZP_HASH_SIZE = (1 shl LZP_HASH_ORDER)
|
|
|
|
public lzp_compress
|
|
public lzp_decompress
|
|
|
|
; hash(h, x) (h = (h << 4) ^ x)
|
|
|
|
section '.code' code
|
|
|
|
; xor hash, hash
|
|
; xor mask, mask
|
|
; j = 1
|
|
; while (insz > 0)
|
|
; {
|
|
; if (ecx == 8)
|
|
; {
|
|
; mov [out], mask
|
|
; xor ecx, ecx
|
|
; xor mask, mask
|
|
; j = 1;
|
|
; }
|
|
; c = in[inpos++]
|
|
; if (c == table[hash])
|
|
; {
|
|
; mask |= 1 << ecx
|
|
; }
|
|
; else
|
|
; {
|
|
; table[hash] = c
|
|
; out[j] = c;
|
|
; }
|
|
; HASH(hash, c)
|
|
; ecx++;
|
|
; }
|
|
|
|
;; Function: lzp_compress
|
|
;;
|
|
;; Parameters:
|
|
;;
|
|
;; [esp+8] - output buffer (can be NULL)
|
|
;; [esp+12] - input buffer
|
|
;; [esp+16] - size of the input buffer
|
|
;;
|
|
;; Returns:
|
|
;;
|
|
;; eax - size of compressed data
|
|
;;
|
|
param_out equ [ebp+8]
|
|
param_in equ [ebp+12]
|
|
param_insz equ [ebp+16]
|
|
local_buff equ [ebp-10]
|
|
local_inpos equ [ebp-14]
|
|
lzp_compress:
|
|
push ebp
|
|
mov ebp, esp
|
|
sub esp, 14
|
|
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
mov edi, param_insz
|
|
test edi, edi
|
|
je .exit
|
|
|
|
mov ebx, 0
|
|
mov esi, 0
|
|
mov edi, 0
|
|
.loop:
|
|
xor ecx, ecx
|
|
|
|
cmp esi, param_insz
|
|
je .end
|
|
|
|
|
|
xor ecx, ecx
|
|
;; fetch data
|
|
mov eax, param_in
|
|
movzx eax, byte [eax+esi]
|
|
inc esi
|
|
|
|
cmp al, byte [table + ebx]
|
|
jne .not_in_table
|
|
mov edx, 1
|
|
sal edx, cl
|
|
or ebx, edx
|
|
|
|
.not_in_table:
|
|
mov byte [table + ebx], al
|
|
|
|
inc ecx
|
|
.check:
|
|
cmp esi, param_insz
|
|
jb .loop
|
|
.end:
|
|
.exit:
|
|
mov eax, edi ; return compressed data size
|
|
;; restore esi, edi
|
|
pop edi
|
|
pop esi
|
|
|
|
leave
|
|
ret
|
|
|
|
;; Function: lzp_decompress
|
|
;;
|
|
;; Parameters:
|
|
;;
|
|
;; [esp+8] - output buffer (can be null)
|
|
;; [esp+12] - input buffer
|
|
;; [esp+16] - size of the input buffer
|
|
;;
|
|
;; Returns:
|
|
;;
|
|
;; eax - size of uncompressed data
|
|
;;
|
|
lzp_decompress:
|
|
push ebp
|
|
mov ebp, esp
|
|
mov eax, [esp+8] ; in
|
|
mov edx, [esp+12] ; size
|
|
xor ecx, ecx
|
|
.loop:
|
|
cmp ecx, edx
|
|
je .end
|
|
|
|
inc ecx
|
|
jmp .loop
|
|
.end:
|
|
mov eax, ecx
|
|
leave
|
|
ret
|
|
|
|
section '.data' data
|
|
|
|
table db LZP_HASH_SIZE dup(0)
|