📄 lzss16.pas
字号:
ADD SI,DI
MOV AX,[ES:SI+OFFSET TBinaryTree.Left]
{ mov ax, word ptr [Offset Left + di]} { ; the subtree }
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV [ES:SI+BX+OFFSET TBinaryTree.Right],AX
{ mov word ptr [Offset Right + bx], ax}
xchg ax, bx
MOV [ES:SI+BX+OFFSET TBinaryTree.Mom],AX
{ mov word ptr [Offset Mom + bx], ax}
ADD SI,CX
MOV BX,[ES:SI+OFFSET TBinaryTree.Left]
{ mov bx, word ptr [Offset Left + si]}
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,DI
MOV [ES:SI+OFFSET TBinaryTree.Left],BX
{ mov word ptr [Offset Left + di], bx}
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV [ES:SI+BX+OFFSET TBinaryTree.Mom],DI
{ mov word ptr [Offset Mom + bx], di}
MOV SI,CX
POP CX
@del2:
PUSH CX
MOV CX,SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,CX
MOV BX,[ES:SI+OFFSET TBinaryTree.Right]
{ mov bx, word ptr [Offset Right + si]}
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,DI
MOV [ES:SI+OFFSET TBinaryTree.Right],BX
{ mov word ptr [Offset Right + di], bx}
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV [ES:SI+BX+OFFSET TBinaryTree.Mom],DI
MOV SI,CX
POP CX
{ mov word ptr [Offset Mom + bx], di}
@del3:
PUSH CX
MOV CX,DI
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
ADD DI,SI
MOV BX,[ES:DI+OFFSET TBinaryTree.Mom]
{ mov bx, word ptr [Offset Mom + si]}
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
ADD DI,CX
MOV [ES:DI+OFFSET TBinaryTree.Mom],BX
{ mov word ptr [Offset Mom + di], bx}
MOV DI,CX
POP CX
PUSH DI
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
CMP SI,[ES:DI+BX+OFFSET TBinaryTree.Right]
POP DI
{ cmp si, word ptr [Offset Right + bx]}
jne @del4
PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV [ES:SI+BX+OFFSET TBinaryTree.Right],DI
POP SI
{ mov word ptr [Offset Right + bx], di}
jmp @del5
@del4:
PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV [ES:SI+BX+OFFSET TBinaryTree.Left],DI
POP SI
{ mov word ptr [Offset Left + bx], di}
@del5:
PUSH DI
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
ADD DI,SI
MOV WORD PTR [ES:DI+OFFSET TBinaryTree.Mom],Nul
POP DI
{ mov word ptr [Offset Mom + si], NUL}
@del7: pop bx
pop di
shr si, Log2TLZSSWord
@end:
End; { DeleteNode }
Procedure LZEncode; assembler;
Asm
{ }
{ Load ES with segment of Binary Tree structure ... }
{ }
MOV ES, PtrRec[OFFSET BinaryTree].&Seg
{ }
{ Now encode ... }
{ }
call initTree
xor bx, bx
mov [Offset CodeBuf], bl
mov dx, 1
mov ch, dl
xor si, si
mov di, N - F
@Encode2: call getc
jnc @ReadOK
or bx, bx
je @Encode19
jmp @Encode4
@ReadOK: PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,DI
MOV [ES:SI+BX],AL
POP SI
{ mov byte ptr [Offset TextBuf +di + bx], al}
inc bx
cmp bx, F
jb @Encode2
@Encode4: mov cl, bl
xor bx, bx
push di
dec di
@Encode5: call InsertNode
inc bx
dec di
cmp bx, F
jb @Encode5
pop di
call InsertNode
@Encode6: mov ax, matchLen
cmp al, cl
jbe @Encode7
mov al, cl
mov matchLen, ax
@Encode7: cmp al, THRESHOLD
ja @Encode8
mov matchLen, 1
or byte ptr codeBuf, ch
mov bx, dx
PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,DI
MOV AL,[ES:SI]
POP SI
{ mov al, byte ptr [Offset TextBuf + di]}
mov byte ptr [Offset CodeBuf + bx], al
inc dx
jmp @Encode9
@Encode8: mov bx, dx
mov ax, MatchPos
mov byte ptr [Offset Codebuf + bx], al
inc bx
push cx
mov cl, 4
shl ah, cl
pop cx
mov al, byte ptr MatchLen
sub al, THRESHOLD + 1
add ah, al
mov byte ptr [Offset Codebuf + bx], ah
inc bx
mov dx, bx
@Encode9: shl ch, 1
jnz @Encode11
xor bx, bx
@Encode10: mov al, byte ptr [Offset CodeBuf + bx]
call putc
inc bx
cmp bx, dx
jb @Encode10
mov dx, 1
mov ch, dl
mov byte ptr codeBuf, dh
@Encode11: mov bx, matchLen
mov lastLen, bx
xor bx, bx
@Encode12: call getc
{ jc @Encode14}
jc @EncodeY
push ax
call deleteNode
pop ax
PUSH DI
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
ADD DI,SI
STOSB
POP DI
{ mov byte ptr [Offset TextBuf + si], al}
cmp si, F - 1
jae @Encode13
PUSH DI
MOV DI,PtrRec[OFFSET BinaryTree].Ofs
ADD DI,SI
MOV [ES:DI+N],AL
POP DI
{ mov byte ptr [Offset TextBuf + si + N], al}
@Encode13: inc si
and si, N - 1
inc di
and di, N - 1
call insertNode
inc bx
cmp bx, lastLen
jb @Encode12
jmp @Encode16
(* @Encode14: sub printCount, bx
jnc @EncodeY
mov ax, printPeriod
mov printCount, ax
push dx { Print out a period as a sign. }
mov dl, DBLARROW
mov ah, 2
int 21h
pop dx *)
@EncodeX: inc bx
call deleteNode
inc si
and si, N - 1
inc di
and di, N - 1
dec cl
jz @EncodeY
call insertNode
@EncodeY: cmp bx, LastLen
jb @EncodeX
@Encode16: test cl, cl
jnz @Encode6
@Encode17: test dx, dx
jz @Encode19
xor bx, bx
@Encode18: mov al, byte ptr [Offset Codebuf + bx]
call putc
inc bx
cmp bx, dx
jb @Encode18
@Encode19:
call LZSS_Write
End; { Encode }
Procedure LZDecode; assembler;
Asm
{ }
{ Load ES with segment of Binary Tree structure ... }
{ }
MOV ES, PtrRec[OFFSET BinaryTree].&Seg
{ }
{ Now decode ... }
{ }
xor dx, dx
mov di, N - F
@Decode2: shr dx, 1
or dh, dh
jnz @Decode3
call getc
jc @Decode9
mov dh, 0ffh
mov dl, al
@Decode3: call getc
jc @Decode9
test dl, 1
jz @Decode4
PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
ADD SI,DI
MOV [ES:SI],AL
POP SI
{ mov byte ptr [Offset TextBuf + di], al}
inc di
and di, N - 1
call putc
jmp @Decode2
@Decode4: mov bl, al
call getc
jc @Decode9
mov bh, al
{$IFOPT G+}
shr bh, 4
{$ELSE}
mov cl, 4
shr bh, cl
{$ENDIF}
mov cl, al
and cl, 0fh
add cl, THRESHOLD
inc cl
@Decode5: and bx, N - 1
PUSH SI
MOV SI,PtrRec[OFFSET BinaryTree].Ofs
MOV AL,[ES:SI+BX]
ADD SI,DI
MOV [ES:SI],AL
POP SI
{ mov al, byte ptr [Offset TextBuf + bx]
mov byte ptr [Offset TextBuf + di], al}
inc di
and di, N - 1
call putc
inc bx
dec cl
jnz @Decode5
jmp @Decode2
@Decode9:
call LZSS_Write
End; { Decode }
Function LZInit : boolean;
label
LZAbort;
Begin
{
*Non-interruptable* test for whether LZ unit is busy ...
}
asm
MOV AL, True { if IsLZInitialized then goto LZAbort; }
XCHG IsLZInitialized, AL { IsLZInitialized := True; }
TEST AL, AL
JNZ LZAbort
end;
{
Unit WASN'T busy, but it is now ...
}
New(InBufP);
New(OutBufP);
New(BinaryTree);
if (InBufP = nil) or (OutBufP = nil) or (BinaryTree = nil) then
LZDone;
LZAbort:
LZInit := IsLZInitialized
End; { LZInit }
Procedure LZDone;
Begin
if InBufP <> nil then
Dispose(InBufP);
if OutBufP <> nil then
Dispose(OutBufP);
if BinaryTree <> nil then
Dispose(BinaryTree);
IsLZInitialized := False
End; { LZDone }
Procedure LZSquash;
Begin
if IsLZInitialized then
begin
InBufPtr := LZRWBufSize;
InBufSize := LZRWBufSize;
OutBufPtr := 0;
Height := 0;
MatchPos := 0;
MatchLen := 0;
LastLen := 0;
FillChar(BinaryTree^, SizeOf(TBinaryTree), 0);
FillChar(CodeBuf, SizeOf(CodeBuf), 0);
LZReadProc := ReadProc;
LZWriteProc := WriteProc;
LZEncode
end
End; { LZSquash }
Procedure LZUnSquash;
Begin
if IsLZInitialized then
begin
InBufPtr := LZRWBufSize;
InBufSize := LZRWBufSize;
OutBufPtr := 0;
FillChar(BinaryTree^.TextBuf, SizeOf(TLZTextBuf), 0);
LZReadProc := ReadProc;
LZWriteProc := WriteProc;
LZDecode;
end
End; { LZUnSquash }
{$IFDEF Windows}
Function HeapFunc(Size : word) : integer; far; assembler;
Asm
MOV AX,1
End; { HeapFunc }
{$ENDIF}
{$IFDEF Windows}
Begin
HeapError := @HeapFunc;
{$ENDIF}
End. { LZSSUNIT }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -