function SynLZcompress1pas(src: PAnsiChar; size: integer; dst: PAnsiChar): integer;
var
dstbeg, // initial dst value
srcend, // real last byte available in src
srcendmatch, // last byte to try for hashing
o: PAnsiChar;
cwbit: byte;
cwpoint: PCardinal;
v, h, cached, t, tmax: PtrUInt;
offset: TOffsets;
cache: array[0..4095] of cardinal; // 16KB+16KB=32KB on stack (48KB for cpu64)
begin
dstbeg := dst;
// 1. store in_len
if size >= $8000 then
begin
// size in 32KB..2GB -> stored as integer
PWord(dst)^ := $8000 or (size and $7fff);
PWord(dst + 2)^ := size shr 15;
inc(dst, 4);
end
else
begin
PWord(dst)^ := size; // size<32768 -> stored as word
if size = 0 then
begin
result := 2;
exit;
end;
inc(dst, 2);
end;
// 2. compress
srcend := src + size;
srcendmatch := srcend - (6 + 5);
cwbit := 0;
cwpoint := pointer(dst);
PCardinal(dst)^ := 0;
inc(dst, SizeOf(cwpoint^));
FillCharFast(offset, SizeOf(offset), 0); // fast 16KB reset to 0
// 1. main loop to search using hash[]
if src <= srcendmatch then
repeat
v := PCardinal(src)^;
h := ((v shr 12) xor v) and 4095;
o := offset[h];
offset[h] := src;
cached := v xor {%H-}cache[h]; // o=nil if cache[h] is uninitialized
cache[h] := v;
if (cached and $00ffffff = 0) and
(o <> nil) and
(src - o > 2) then
begin
cwpoint^ := cwpoint^ or (cardinal(1) shl cwbit);
inc(src, 2);
inc(o, 2);
t := 1;
tmax := srcend - src - 1;
if tmax >= (255 + 16) then
tmax := (255 + 16);
while (o[t] = src[t]) and
(t < tmax) do
inc(t);
inc(src, t);
h := h shl 4;
// here we have always t>0
if t <= 15 then
begin
// mark 2 to 17 bytes -> size=1..15
PWord(dst)^ := integer(t or h);
inc(dst, 2);
end
else
begin
// mark 18 to (255+16) bytes -> size=0, next byte=t
dec(t, 16);
PWord(dst)^ := h; // size=0
dst[2] := ansichar(t);
inc(dst, 3);
end;
end
else
begin
dst^ := src^;
inc(src);
inc(dst);
end;
if cwbit < 31 then
begin
inc(cwbit);
if src <= srcendmatch then
continue
else
break;
end
else
begin
cwpoint := pointer(dst);
PCardinal(dst)^ := 0;
inc(dst, SizeOf(cwpoint^));
cwbit := 0;
if src <= srcendmatch then
continue
else
break;
end;
until false;
// 2. store remaining bytes
if src < srcend then
repeat
dst^ := src^;
inc(src);
inc(dst);
if cwbit < 31 then
begin
inc(cwbit);
if src < srcend then
continue
else
break;
end
else
begin
PCardinal(dst)^ := 0;
inc(dst, 4);
cwbit := 0;
if src < srcend then
continue
else
break;
end;
until false;
result := dst - dstbeg;
end;