|
@@ -53,14 +53,14 @@ uses
|
|
|
uses
|
|
uses
|
|
|
Classes, SysUtils;
|
|
Classes, SysUtils;
|
|
|
{$ENDIF FPC_DOTTEDUNITS}
|
|
{$ENDIF FPC_DOTTEDUNITS}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const
|
|
const
|
|
|
DECR_OK = 0;
|
|
DECR_OK = 0;
|
|
|
DECR_DATAFORMAT = 1;
|
|
DECR_DATAFORMAT = 1;
|
|
|
DECR_ILLEGALDATA = 2;
|
|
DECR_ILLEGALDATA = 2;
|
|
|
DECR_NOMEMORY = 3;
|
|
DECR_NOMEMORY = 3;
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// some constants defined by the LZX specification
|
|
// some constants defined by the LZX specification
|
|
|
LZX_MIN_MATCH = 2;
|
|
LZX_MIN_MATCH = 2;
|
|
|
LZX_MAX_MATCH = 257;
|
|
LZX_MAX_MATCH = 257;
|
|
@@ -73,7 +73,7 @@ const
|
|
|
LZX_ALIGNED_NUM_ELEMENTS = 8; // aligned offset tree #elements
|
|
LZX_ALIGNED_NUM_ELEMENTS = 8; // aligned offset tree #elements
|
|
|
LZX_NUM_PRIMARY_LENGTHS = 7; // this one missing from spec!
|
|
LZX_NUM_PRIMARY_LENGTHS = 7; // this one missing from spec!
|
|
|
LZX_NUM_SECONDARY_LENGTHS = 249;// length tree #elements
|
|
LZX_NUM_SECONDARY_LENGTHS = 249;// length tree #elements
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// LZX huffman defines: tweak tablebits as desired
|
|
// LZX huffman defines: tweak tablebits as desired
|
|
|
LZX_PRETREE_MAXSYMBOLS = LZX_PRETREE_NUM_ELEMENTS;
|
|
LZX_PRETREE_MAXSYMBOLS = LZX_PRETREE_NUM_ELEMENTS;
|
|
|
LZX_PRETREE_TABLEBITS = 6;
|
|
LZX_PRETREE_TABLEBITS = 6;
|
|
@@ -85,14 +85,14 @@ const
|
|
|
LZX_ALIGNED_TABLEBITS = 7;
|
|
LZX_ALIGNED_TABLEBITS = 7;
|
|
|
|
|
|
|
|
LZX_LENTABLE_SAFETY = 64; // we allow length table decoding overruns
|
|
LZX_LENTABLE_SAFETY = 64; // we allow length table decoding overruns
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
extra_bits: array [0..50] of Byte = (
|
|
extra_bits: array [0..50] of Byte = (
|
|
|
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
|
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
|
|
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
|
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
|
|
15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
|
15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
|
|
17, 17, 17
|
|
17, 17, 17
|
|
|
);
|
|
);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
position_base: array [0..50] of dword = (
|
|
position_base: array [0..50] of dword = (
|
|
|
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
|
|
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
|
|
|
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
|
|
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
|
|
@@ -156,23 +156,23 @@ type
|
|
|
LengthTable: TLZX_LENGTH_TABLE;
|
|
LengthTable: TLZX_LENGTH_TABLE;
|
|
|
AlignedTAble: TLZX_ALIGNED_TABLE;
|
|
AlignedTAble: TLZX_ALIGNED_TABLE;
|
|
|
end;
|
|
end;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// create an lzx state object
|
|
// create an lzx state object
|
|
|
function LZXinit(window: LongInt): PLZXState;
|
|
function LZXinit(window: LongInt): PLZXState;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// destroy an lzx state object
|
|
// destroy an lzx state object
|
|
|
procedure LZXteardown(pState: PLZXState);
|
|
procedure LZXteardown(pState: PLZXState);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// reset an lzx stream
|
|
// reset an lzx stream
|
|
|
function LZXreset(pState: PLZXState): LongInt;
|
|
function LZXreset(pState: PLZXState): LongInt;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
function LZXdecompress(pState: PLZXstate; inpos, outpos: PByte; inlen, outlen: LongInt): LongInt;
|
|
function LZXdecompress(pState: PLZXstate; inpos, outpos: PByte; inlen, outlen: LongInt): LongInt;
|
|
|
|
|
|
|
|
implementation
|
|
implementation
|
|
|
|
|
|
|
|
const
|
|
const
|
|
|
ULONG_BITS = sizeof(LongInt)shl 3;
|
|
ULONG_BITS = sizeof(LongInt)shl 3;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
function make_decode_table(nsyms: dword; nbits: dword; length: PByte; table: PWord): LongInt;
|
|
function make_decode_table(nsyms: dword; nbits: dword; length: PByte; table: PWord): LongInt;
|
|
|
var
|
|
var
|
|
|
Sym: Word;
|
|
Sym: Word;
|
|
@@ -318,7 +318,7 @@ begin
|
|
|
bits := TBufBits.Create;
|
|
bits := TBufBits.Create;
|
|
|
bits.bitbuf := lb^.bb;
|
|
bits.bitbuf := lb^.bb;
|
|
|
bits.bitsleft := lb^.bl;
|
|
bits.bitsleft := lb^.bl;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
inpos := lb^.ip;
|
|
inpos := lb^.ip;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -356,7 +356,7 @@ begin
|
|
|
else if (z = 18) then begin
|
|
else if (z = 18) then begin
|
|
|
y := bits.read(5, inpos);
|
|
y := bits.read(5, inpos);
|
|
|
Inc(y, 20);
|
|
Inc(y, 20);
|
|
|
- while y > 0 do begin
|
|
|
|
|
|
|
+ while y > 0 do begin
|
|
|
dec(y);
|
|
dec(y);
|
|
|
lens[x] := 0;
|
|
lens[x] := 0;
|
|
|
inc(x);
|
|
inc(x);
|
|
@@ -394,8 +394,8 @@ begin
|
|
|
Result := 0;
|
|
Result := 0;
|
|
|
bits.Free;
|
|
bits.Free;
|
|
|
end;
|
|
end;
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
function LZXinit(window: LongInt): PLZXState;
|
|
function LZXinit(window: LongInt): PLZXState;
|
|
@@ -438,7 +438,7 @@ begin
|
|
|
pState^.R0 := 1;
|
|
pState^.R0 := 1;
|
|
|
pState^.R1 := 1;
|
|
pState^.R1 := 1;
|
|
|
pState^.R2 := 1;
|
|
pState^.R2 := 1;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
pState^.main_elements := LZX_NUM_CHARS + (posn_slots shl 3);
|
|
pState^.main_elements := LZX_NUM_CHARS + (posn_slots shl 3);
|
|
|
pState^.header_read := 0;
|
|
pState^.header_read := 0;
|
|
|
pState^.frames_read := 0;
|
|
pState^.frames_read := 0;
|
|
@@ -577,7 +577,7 @@ var
|
|
|
Exit;
|
|
Exit;
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
begin
|
|
begin
|
|
|
endinp := inpos + inlen;
|
|
endinp := inpos + inlen;
|
|
|
window := pState^.window;
|
|
window := pState^.window;
|
|
@@ -587,7 +587,7 @@ begin
|
|
|
R0 := pState^.R0;
|
|
R0 := pState^.R0;
|
|
|
R1 := pState^.R1;
|
|
R1 := pState^.R1;
|
|
|
R2 := pState^.R2;
|
|
R2 := pState^.R2;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
togo := outlen;//, this_run, main_element, aligned_bits;
|
|
togo := outlen;//, this_run, main_element, aligned_bits;
|
|
|
bits := TBufBits.Create;
|
|
bits := TBufBits.Create;
|
|
|
bits.Init;
|
|
bits.Init;
|
|
@@ -616,7 +616,7 @@ begin
|
|
|
pState^.block_type := Word(bits.read(3, inpos));
|
|
pState^.block_type := Word(bits.read(3, inpos));
|
|
|
i := bits.read(16, inpos);
|
|
i := bits.read(16, inpos);
|
|
|
j := bits.read(8, inpos);
|
|
j := bits.read(8, inpos);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
pState^.block_length := (i shl 8) or j;
|
|
pState^.block_length := (i shl 8) or j;
|
|
|
pState^.block_remaining := pState^.block_length;
|
|
pState^.block_remaining := pState^.block_length;
|
|
|
|
|
|