home *** CD-ROM | disk | FTP | other *** search
- ;***********************************************
- ; 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
-