home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1997 November
/
PCWorld_1997-11_cd.bin
/
software
/
sharware
/
utility
/
PACKERS
/
LZH
/
LHASRC.EXE
/
HUF_.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-03-03
|
14KB
|
849 lines
;***********************************************
; huf_.asm -- new static Huffman
;***********************************************
page 0, 128
include amscls.inc
$_init GEN
NC = (200h - 2)
CBIT = 9
NP = 14
NT = 19
PBIT = 4
TBIT = 5
;NPT = 080h
CGROUP group TEXT
DGROUP group DATA, BSS
TEXT segment public byte 'CODE'
extrn fillbuf_:near
extrn getbits_:near
extrn init_getbits_:near
extrn init_putbits_:near
extrn make_table_:near
extrn make_tree_:near
extrn putbits_:near
extrn putcode_:near
TEXT ends
DATA segment public word 'DATA'
DATA ends
BSS segment public word 'DATA'
buf_ dd 1 dup (?)
buf_limit_ dw 1 dup (?)
blocksize_ dw 1 dup (?)
output_pos_ dd 1 dup (?)
cpos_ dw 1 dup (?)
output_mask_ db 1 dup (?)
BSS ends
extrn c_freq_:word
extrn p_freq_:word
extrn t_freq_:word
extrn left_:word
extrn right_:word
extrn c_table_:word
extrn c_code_:word
extrn pt_table_:word
extrn pt_code_:word
extrn c_len_:byte
extrn pt_len_:byte
public buf_
public buf_limit_
extrn bitbuf_:word
extrn unpackable_:word
assume cs:CGROUP, ds:DGROUP
TEXT segment public byte 'CODE'
;
; static void count_t_freq(void)
;
;public count_t_freq_
count_t_freq_ proc near
push cx
push si
push di
cld
push ds
pop es
mov cx, NT
mov di, offset DGROUP:t_freq_
xor ax, ax
rep stosw
mov cx, NC
mov di, offset DGROUP:c_len_[NC - 1]
std
repe scasb
cld
inc di
mov si, di
mov di, offset DGROUP:c_len_
$_do
mov bl, [di]
inc di
$_if <or bl, bl>, Z
mov cx, -1
repe scasb
dec di
not cx
$_switch
$_case <cmp cx, 2>, BE
add t_freq_[0 * 2], cx
$_break
$_case <cmp cx, 19>, BE
$_if , E
inc t_freq_[0 * 2]
$_endif
inc t_freq_[1 * 2]
$_break
$_default
inc t_freq_[2 * 2]
$_endswitch
$_else
xor bh, bh
shl bx, 1
inc t_freq_[bx + 2 * 2]
$_endif
$_until <cmp di, si>, A
pop di
pop si
pop cx
ret
count_t_freq_ endp
;
; static void write_pt_len(short n, short nbit, short i_special)
;
;public write_pt_len_
write_pt_len_ proc near
push cx
push si
push di
push cx ; i_special
push bx ; nbit
mov si, offset DGROUP:pt_len_
lea di, [si - 1]
add di, ax
mov cx, ax
inc cx
xor al, al
std
repe scasb
cld
mov bx, cx
pop ax ; nbit
call putbits_
inc di
pop cx ; i_special
add cx, si
$_do
xor bh, bh
mov bl, [si]
inc si
$_if <cmp bl, 6>, BE
mov al, 3
$_else
mov ax, bx
sub ax, 3
mov bx, 0fffeh
$_endif
call putbits_
$_if <cmp si, cx>, E
$_while <cmp si, offset DGROUP:pt_len_ + 6>, B, AND
$_c <cmp byte ptr [si], 0>, E
inc si
$_enddo
mov al, 2
mov bx, si
sub bx, offset DGROUP:pt_len_ + 3;
call putbits_
$_endif
$_until <cmp si, di>, A
pop di
pop si
pop cx
ret
write_pt_len_ endp
;
; static void write_c_len(void)
;
;public write_c_len_
write_c_len_ proc near
push cx
push si
push di
mov di, offset DGROUP:c_len_ + NC - 1
mov cx, NC + 1
xor al, al
std
repe scasb
cld
inc di
mov si, di
mov di, offset DGROUP:c_len_
mov bx, cx
mov al, CBIT
call putbits_
$_do
mov bl, [di]
inc di
$_if <or bl, bl>, Z
xor al, al
mov cx, -1
repe scasb
dec di
not cx
$_switch
$_case <cmp cx, 2>, BE
$_do
mov al, pt_len_[0]
mov bx, pt_code_[0 * 2]
call putcode_
$_until <LOOP>
$_break
$_case <cmp cx, 19>, BE
$_if , E
mov al, pt_len_[0]
mov bx, pt_code_[0 * 2]
call putcode_
dec cx
$_endif
mov al, pt_len_[1]
mov bx, pt_code_[1 * 2]
call putcode_
mov al, 4
mov bx, cx
sub bx, 3
call putbits_
$_break
$_default
mov al, pt_len_[2]
mov bx, pt_code_[2 * 2]
call putcode_
mov al, CBIT
mov bx, cx
sub bx, 20
call putbits_
$_endswitch
$_else
xor bh, bh
mov al, pt_len_[bx + 2]
shl bx, 1
mov bx, pt_code_[bx + 4]
call putcode_
$_endif
$_until <cmp di, si>, A
pop di
pop si
pop cx
ret
write_c_len_ endp
;
; static void send_block(void)
;
;public send_block_
send_block_ proc near
push cx
push dx
push si
push di
push bp
mov ax, NC
mov bx, offset DGROUP:c_freq_
mov cx, offset DGROUP:c_len_
mov dx, offset DGROUP:c_code_
call make_tree_
mov bx, ax
mov cx, ax
shl bx, 1
mov bx, c_freq_[bx]
mov al, 16
call putbits_
$_if <cmp cx, NC>, AE
call count_t_freq_
mov ax, NT
mov bx, offset DGROUP:t_freq_
mov cx, offset DGROUP:pt_len_
mov dx, offset DGROUP:pt_code_
call make_tree_
$_if <cmp ax, NT>, AE
mov ax, NT
mov bx, TBIT
mov cx, 3
call write_pt_len_
$_else
if 1
mov bx, ax
mov al, TBIT * 2
call putbits_
else
mov cx, ax
xor bx, bx
mov al, TBIT
call putbits_
mov bx, cx
mov al, TBIT
call putbits_
endif
$_endif
call write_c_len_
$_else
if 1
xor bx, bx
mov al, CBIT + TBIT
call putbits_
mov bx, cx
mov al, CBIT + TBIT
call putbits_
else
xor bx, bx
mov al, TBIT
call putbits_
xor bx, bx
mov al, TBIT
call putbits_
xor bx, bx
mov al, CBIT
call putbits_
mov bx, cx
mov al, CBIT
call putbits_
endif
$_endif
mov ax, NP
mov bx, offset DGROUP:p_freq_
mov cx, offset DGROUP:pt_len_
mov dx, offset DGROUP:pt_code_
call make_tree_
$_if <cmp ax, NP>, AE
mov ax, NP
mov bx, PBIT
mov cx, -1
call write_pt_len_
$_else
if 1
mov bx, ax
mov al, PBIT * 2
call putbits_
else
mov cx, ax
mov al, PBIT
xor bx, bx
call putbits_
mov al, PBIT
mov bx, cx
call putbits_
endif
$_endif
les si, buf_
xor cx, cx
mov bp, word ptr output_pos_
$_do
$_if <and cl, 07h>, Z
lods byte ptr es:[si]
mov ch, al
$_endif
xor bh, bh
lods byte ptr es:[si]
mov bl, al
add ch, 80h
rcl bh, 1
; static void encode_c(short c)
mov al, c_len_[bx]
shl bx, 1
mov bx, c_code_[bx]
call putcode_
;
$_if <shl ch, 1>, NC
lods word ptr es:[si]
; static void encode_p(ushort p)
mov dx, ax
and ax, 0000fh
mov di, ax
mov al, pt_len_[di]
shl di, 1
mov bx, pt_code_[di]
call putcode_
shr di, 1
$_if <dec di>, G
mov ax, di
mov bx, dx
and bl, 0f0h
call putcode_
$_endif
;
$_endif
inc cx
$_until <cmp si, bp>, AE
push ds
pop es
xor ax, ax
mov cx, NC
mov di, offset DGROUP:c_freq_
rep stosw
mov cx, NP
mov di, offset DGROUP:p_freq_
rep stosw
pop bp
pop di
pop si
pop dx
pop cx
ret
send_block_ endp
;
; void output_st1(ushort c, ushort p)
;
public output_st1_
output_st1_ proc near
push di
les di, output_pos_
$_if <ror output_mask_, 1>, C
$_if <cmp di, buf_limit_>, AE
push ax
push bx
push es
call send_block_
pop es
pop bx
pop ax
cmp unpackable_, 0
jne os1_end
xor di, di
$_endif
mov cpos_, di
mov byte ptr es:[di], 0
inc di
$_endif
stosb
xchg bx, ax
shl bx, 1
inc c_freq_[bx]
$_if <shr bh, 1>, NZ
xor bx, bx
shl ax, 1
jz keta1
shl ax, 1
shl ax, 1
mov bx, 13 + 1
keta0:
dec bx
shl ax, 1
jc keta1
dec bx
shl ax, 1
jc keta1
dec bx
shl ax, 1
jc keta1
dec bx
shl ax, 1
jc keta1
dec bx
shl ax, 1
jnc keta0
keta1:
or ax, bx ; ì╢ïlé▀é╠ê╩Æu + îàÉö
stosw
shl bx, 1
inc p_freq_[bx]
mov al, output_mask_
mov bx, cpos_
or es:[bx], al
$_endif
mov word ptr output_pos_, di
os1_end:
pop di
ret
output_st1_ endp
if 0
;
; void far *alloc_buf(void)
;
public alloc_buf_
alloc_buf_ proc near
mov bx, 0ffffh
mov ah, 48h
int 21h
$_if <cmp bx, 256>, AE
mov ax, 1024
$_if <cmp bx, ax>, B
mov ax, bx
$_endif
mov bx, ax
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
sub ax, 24
mov buf_limit_, ax
mov ah, 48h
int 21h
mov bx, ax
$_else
xor bx, bx
$_endif
xor ax, ax
mov word ptr buf_ + 2, bx
mov word ptr buf_, ax
ret
alloc_buf_ endp
endif
;
; void encode_start_st1(void)
;
public encode_start_st1_
encode_start_st1_ proc near
push cx
push di
push ds
pop es
xor ax, ax
mov cx, NC
mov di, offset DGROUP:c_freq_
rep stosw
mov cx, NP
mov di, offset DGROUP:p_freq_
rep stosw
les bx, buf_
mov word ptr output_pos_ + 2, es
mov word ptr output_pos_, bx
mov byte ptr es:[bx], 0
mov output_mask_, 01h
call init_putbits_
pop di
pop cx
ret
encode_start_st1_ endp
;
; void encode_end_st1(void)
;
public encode_end_st1_
encode_end_st1_ proc near
$_if <cmp unpackable_, 0>, E
call send_block_
mov ax, 7
xor bx, bx
call putcode_
$_endif
ret
encode_end_st1_ endp
; /***** decoding *****/
;
; static void read_pt_len(short nn, short nbit, short i_special)
;
;public read_pt_len_
read_pt_len_ proc near
push cx
push dx
push si
push di
push ax
mov si, ax
mov dx, bx
mov ax, bx
call getbits_
cmp ax, si
ja tbl_error_
mov di, offset DGROUP:pt_len_
$_if <or ax, ax>, Z
mov di, offset DGROUP:pt_len_
pop cx
rep stosb
mov ax, dx
call getbits_
mov cx, 256
mov di, offset DGROUP:pt_table_
rep stosw
$_else
mov dx, cx ; dl = i_special
add dx, di
mov si, di
add si, ax ; ax = n
$_do
mov ax, 3
call getbits_
$_if <cmp al, 7>, E
mov bx, bitbuf_
$_while <shl bx, 1>, C
inc ax
$_enddo
push ax
sub ax, 6
call fillbuf_
pop ax
$_endif
stosb
$_if <cmp di, dx>, E
mov ax, 2
call getbits_
mov cx, ax
xor al, al
rep stosb
$_endif
$_until <cmp di, si>, AE
pop cx ; nn
mov si, cx
add cx, offset DGROUP:pt_len_
sub cx, di
jb tbl_error_
xor al, al
rep stosb
mov ax, si
mov bx, offset DGROUP:pt_len_
mov cx, 8
mov dx, offset DGROUP:pt_table_
call make_table_
$_endif
pop di
pop si
pop dx
pop cx
ret
read_pt_len_ endp
extrn error_:near
extrn BROKENARC_:byte
tbl_error_ proc near
mov ax, offset DGROUP:BROKENARC_
xor bx, bx
jmp error_
tbl_error_ endp
;
; static void read_c_len(void)
;
;public read_c_len_
read_c_len_ proc near
push cx
push dx
push di
mov ax, CBIT
call getbits_
cmp ax, NC
ja tbl_error_
mov di, offset DGROUP:c_len_
$_if <or ax, ax>, Z
mov cx, NC
rep stosb
mov ax, CBIT
call getbits_
mov cx, 4096
mov di, offset DGROUP:c_table_
rep stosw
$_else
mov dx, di
add dx, ax ; ax = n
$_do
mov ax, bitbuf_
mov bl, ah
xor bh, bh
shl bx, 1
mov bx, pt_table_[bx]
$_while <cmp bx, NT>, AE
$_if <shl al, 1>, C
mov bx, right_[bx]
$_else
mov bx, left_[bx]
$_endif
$_enddo
push bx
mov al, pt_len_[bx]
call fillbuf_
pop ax
$_if <sub ax, 2>, BE
$_if , Z
mov ax, CBIT
call getbits_
add ax, 20
mov cx, ax
$_else
$_if <inc ax>, Z
mov ax, 4
call getbits_
add ax, 3
mov cx, ax
$_else
mov cx, 1
$_endif
$_endif
xor al, al
rep stosb
$_else
stosb
$_endif
$_until <cmp di, dx>, AE
mov cx, offset DGROUP:c_len_ + NC
sub cx, di
jb tbl_error_
xor al, al
rep stosb
mov ax, NC
mov bx, offset DGROUP:c_len_
mov cx, 12
mov dx, offset DGROUP:c_table_
call make_table_
$_endif
pop di
pop dx
pop cx
ret
read_c_len_ endp
;
; ushort decode_c_st1(void)
;
decode_c proc near
; not entry here
decode_c_st1_2:
push ax
push bx
push cx
mov ax, 16
call getbits_
dec ax
mov blocksize_, ax
mov ax, NT
mov bx, TBIT
mov cx, 3
call read_pt_len_
call read_c_len_
mov ax, NP
mov bx, PBIT
mov cx, -1
call read_pt_len_
pop cx
pop bx
pop ax
jmp decode_c_st1_3
;
; entry here
;
public decode_c_st1_
decode_c_st1_:
push cx
sub blocksize_, 1
jc decode_c_st1_2
decode_c_st1_3:
mov bx, bitbuf_
mov cl, 4
shr bx, cl
shl bx, 1
mov bx, c_table_[bx]
$_if <cmp bx, NC>, B
decode_c_st1_1:
push bx
mov al, c_len_[bx]
call fillbuf_
pop ax
pop cx
ret
$_endif
mov ax, bitbuf_
shl al, cl
$_do
$_if <shl al, 1>, C
mov bx, right_[bx]
$_else
mov bx, left_[bx]
$_endif
$_until <cmp bx, NC>, B
jmp decode_c_st1_1
decode_c endp
;
; ushort decode_p_st1(void)
;
public decode_p_st1_
decode_p_st1_ proc near
push cx
xor bh, bh
mov bl, byte ptr bitbuf_ + 1
shl bx, 1
mov bx, pt_table_[bx]
$_if <cmp bx, NP>, B
decode_p_st1_1:
push bx
mov al, pt_len_[bx]
call fillbuf_
pop ax
$_if <or ax, ax>, NZ
dec ax
mov cx, ax
call getbits_
mov bx, 1
shl bx, cl
or ax, bx
$_endif
pop cx
ret
$_endif
mov al, byte ptr bitbuf_
$_do
$_if <shl al, 1>, C
mov bx, right_[bx]
$_else
mov bx, left_[bx]
$_endif
$_until <cmp bx, NP>, B
jmp decode_p_st1_1
decode_p_st1_ endp
;
; void decode_start_st1(void)
;
public decode_start_st1_
decode_start_st1_ proc near
mov blocksize_, 0
jmp init_getbits_
decode_start_st1_ endp
TEXT ends
end