sysutils, classes;
procedure lhacompress(instr, outstr: tstream);
(* lhacompress starts compressing at instr's current position and continues
to the end of instr, placing the compressed output in outstr starting at
outstr's current position. if you need the entirety of instr compressed
you'll need to set instr.position := 0 before calling.
*)
procedure lhaexpand(instr, outstr: tstream);
(* lhaexpand starts expanding at instr's current position and continues to
the end of instr, placing the expanded output in outstr starting at
outstr's current position. if you need the entirety of instr expanded
you'll need to set instr.position := 0 before calling.
*)
implementation
type
{$ifdef win32}
twobyteint = smallint;
{$else}
twobyteint = integer;
{$endif}
pword=^tword;
tword=array[0..32759]of twobyteint;
pbyte=^tbyte;
tbyte=array[0..65519]of byte;
const
(*
note :
the following constants are set to the values used by lharc.
you can change three of them as follows :
dicbit : lempel-ziv dictionnary size.
lowering this constant can lower the compression efficiency a lot !
but increasing it (on a 32 bit platform only, i.e. delphi 2) will not yield
noticeably better results.
if you set dicbit to 15 or more, set pbit to 5; and if you set dicbit to 19
or more, set npt to np, too.
winbit : sliding window size.
the compression ratio depends a lot of this value.
you can increase it to 15 to get better results on large files.
i recommend doing this if you have enough memory, except if you want that
your compressed data remain compatible with lharc.
on a 32 bit platform, you can increase it to 16. using a larger value will
only waste time and memory.
bufbit : i/o buffer size. you can lower it to save memory, or increase it
to reduce disk access.
*)
bitbufsiz=16;
ucharmax=255;
dicbit=13;
dicsiz=1 shl dicbit;
matchbit=8;
maxmatch=1 shl matchbit;
threshold=3;
percflag=$8000;
nc=(ucharmax+maxmatch+2-threshold);
cbit=9;
codebit=16;
np=dicbit+1;
nt=codebit+3;
pbit=4; {log2(np)}
tbit=5; {log2(nt)}
npt=nt; {greater from np and nt}
nul=0;
maxhashval=(3*dicsiz+(dicsiz shr 9+1)*ucharmax);
winbit=14;
windowsize=1 shl winbit;
bufbit=13;
bufsize=1 shl bufbit;
type
bufferarray = array[0..pred(bufsize)]of byte;
leftrightarray = array[0..2*(nc-1)]of word;
ctablearray = array[0..4095]of word;
clenarray = array[0..pred(nc)]of byte;
heaparray = array[0..nc]of word;
var
origsize,compsize:longint;
infile,outfile:tstream;
bitbuf:word;
n,heapsize:twobyteint;
subbitbuf,bitcount:word;
buffer:^bufferarray;
bufptr:word;
left,right:^leftrightarray;
pttable:array[0..255]of word;
ptlen:array[0..pred(npt)]of byte;
ctable:^ctablearray;
clen:^clenarray;
blocksize:word;
{ the following variables are used by the compression engine only }
heap:^heaparray;
lencnt:array[0..16]of word;
freq,sortptr:pword;
len:pbyte;