FStart : PAnsiChar;{Π½Π°ΡΠ°Π»ΠΎ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°}
FStartOffset : longint;{ΡΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠ° Π΄Π»Ρ FStart}
FStream : TStream;{Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ}
protected
procedure swAdvanceAfterAdd(aCount : integer);
procedure swReadFromStream;
procedure swSetCapacity(aValue : longint);
procedure swWriteToStream(aFinalBlock : boolean);
public
constructor Create(aStream : TStream;
aCompressing : boolean);
destructor Destroy; override;
{ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΠΊΠ°ΠΊ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠΆΠ°ΡΠΈΡ, ΡΠ°ΠΊ ΠΈ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ}
procedure Clear;
{ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠΆΠ°ΡΠΈΡ}
procedure Advance(aCount : integer);
function Compare(aOffset : longint;
var aDistance : integer): integer;
procedure GetNextSignature(var aMS : TtdLZSignature;
varaOffset : longint);
{ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ}
procedure AddChar(aCh : AnsiChar);
procedureAddCode(aDistance : integer;
aLength : integer);
property Name : TtdNameString read FName write FName;
end;
constructor TtdLZSlidingWindow.Create(aStream : TStream;
aCompressing : boolean);
begin
inherited Create;
{ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ}
FCompressing := aCompressing;
FStream := aStream;
{ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°: ΡΠΎΠ³Π»Π°ΡΠ½ΠΎ ΠΏΡΠΈΠ½ΡΡΠΎΠ³ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π° ΡΠ°Π²Π΅Π½ 8192 Π±Π°ΠΉΡΠ°ΠΌ ΠΏΠ»ΡΡ 10 Π±Π°ΠΉΡΠΎΠ² Π΄Π»Ρ ΡΠΏΡΠ΅ΠΆΠ΄Π°ΡΡΠ΅Π³ΠΎ ΠΏΡΠΎΡΠΌΠΎΡΡΠ°}
swSetCapacity(tdcLZSlidingWindowSize + tdcLZLookAheadSize);
{ΡΠ±ΡΠΎΡΠΈΡΡ Π±ΡΡΠ΅Ρ ΠΈ, Π΅ΡΠ»ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠΆΠ°ΡΠΈΠ΅, ΡΡΠΈΡΠ°ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· ΡΠΆΠΈΠΌΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°}
Clear;
if aCompressing then
swReadFromStream;
end;
destructor TtdLZSlidingWindow.Destroy;
begin
if Assigned(FBuffer) then begin
{Π·Π°Π²Π΅ΡΡΠΈΡΡ Π·Π°ΠΏΠΈΡΡ Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ, Π΅ΡΠ»ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠΆΠ°ΡΠΈΠ΅}
if not FCompressing then
swWriteToStream(true);
{ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ Π±ΡΡΠ΅Ρ}
FreeMem(FBuffer, FBufferEnd - FBuffer);
end;
inherited Destroy;
end;
procedure TtdLZSlidingWindow.AddChar(aCh : AnsiChar);
begin
{Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠΈΠΌΠ²ΠΎΠ» Π² Π±ΡΡΠ΅Ρ}
FCurrent^ :=aCh;
{ΡΠΌΠ΅ΡΡΠΈΡΡ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ Π½Π° ΠΎΠ΄ΠΈΠ½ ΡΠΈΠΌΠ²ΠΎΠ»}
swAdvanceAfterAdd(1);
end;
procedure TtdLZSlidingWindow.AddCode(aDistance : integer;
aLength : integer);
var
FromChar : PAnsiChar;
ToChar : PAnsiChar;
i : integer;
begin
{ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ ; ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½Π΅Π»ΡΠ·Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ Move, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ°ΡΡΡ ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌΡΡ Π΄Π°Π½Π½ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° ΡΠ΅Π°Π»ΡΠ½ΡΠΌ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π΄Π°Π½Π½ΡΡ }
FromChar := FCurrent - aDistance;
ToChar := FCurrent;
for i := 1 to aLength do
begin
ToChar^ := FromChar^;
inc(FromChar);
inc(ToChar);
end;
{ΡΠΌΠ΅ΡΡΠΈΡΡ Π½Π°ΡΠ°Π»ΠΎ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°}
swAdvanceAfterAdd(aLength);
end;
procedure TtdLZSlidingWindow.swAdvanceAfterAdd(aCount : integer);
begin
{ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠΌΠ΅ΡΡΠΈΡΡ Π½Π°ΡΠ°Π»ΠΎ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°}
if ( (FCurrent - FStart) >= tdcLZSlidingWindowSize) then begin
inc(FStart, aCount);
inc(FStartOffset, aCount);
end;
{ΡΠΌΠ΅ΡΡΠΈΡΡ ΡΠ΅ΠΊΡΡΠΈΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ}
inc(FCurrent, aCount);
{ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ Π² Π·ΠΎΠ½Ρ ΠΏΠ΅ΡΠ΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ}
if (FStart >= FMidPoint) then begin
{Π·Π°ΠΏΠΈΡΠ°ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π² ΠΏΠΎΡΠΎΠΊ (ΠΎΡ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ FBuffer Π΄ΠΎ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ FStart)}
swWriteToStream(false);
{ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΡΠΈΡΡ ΡΠ΅ΠΊΡΡΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² Π½Π°ΡΠ°Π»ΠΎ Π±ΡΡΠ΅ΡΠ°}
Move(FStart^, FBuffer^, FCurrent - FStart );
{ΡΠ±ΡΠΎΡΠΈΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ}
dec(FCurrent, FStart - FBuffer);
FStart := FBuffer;
end;
end;
procedure TtdLZSlidingWindow.swSetCapacity(aValue : longint);
var
NewQueue : PAnsiChar;
begin
{ΠΎΠΊΡΡΠ³Π»ΠΈΡΡ Π·Π°ΠΏΡΠΎΡΠ΅Π½Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΌ Π΄ΠΎ Π±Π»ΠΈΠΆΠ°ΠΉΡΠ΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΊΡΠ°ΡΠ½ΠΎΠ³ΠΎ 64 Π±Π°ΠΉΡΠ°ΠΌ}
aValue := (aValue + 63) and $7FFFFFC0;
{ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π½ΠΎΠ²ΡΠΉ Π±ΡΡΠ΅Ρ}
GetMem(NewQueue, aValue * 2);
{ΡΠ½ΠΈΡΡΠΎΠΆΠΈΡΡ ΡΡΠ°ΡΡΠΉ Π±ΡΡΠ΅Ρ}
if ( FBuffer <> nil ) then
FreeMem(FBuffer, FBufferEnd - FBuffer);
{ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π½Π°ΡΠ°Π»ΡΠ½ΡΠΉ/ΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ}
FBuffer := NewQueue;
FStart := NewQueue;
FCurrent := NewQueue;
FLookAheadEnd := NewQueue;
FBufferEnd := NewQueue + (aValue * 2);
FMidPoint := NewQueue + aValue;
end;
procedure TtdLZSlidingWindow.swWriteToStream(aFinalBlock : boolean);
var
BytesToWrite : longint;
begin
{Π·Π°ΠΏΠΈΡΠ°ΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΊΡΡΠΈΠΌ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠΈΠΌ ΠΎΠΊΠ½ΠΎΠΌ}
if aFinalBlock then
BytesToWrite := FCurrent - Fbuffer else
BytesToWrite := FStart - FBuffer;
FStream.WriteBuffer(FBuffer^, BytesToWrite);
end;
ΠΠ΅ΡΠΎΠ΄ AddChar Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΎΠ΄ΠΈΠ½ΠΎΡΠ½ΡΠΉ Π»ΠΈΡΠ΅ΡΠ°Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ» Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ ΠΈ ΡΠ΄Π²ΠΈΠ³Π°Π΅Ρ ΡΡΠΎ ΠΎΠΊΠ½ΠΎ Π²ΠΏΠ΅ΡΠ΅Π΄ Π½Π° ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ. ΠΠ½ΡΡΡΠ΅Π½Π½ΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ swAdvanceAfterAdd Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΠ΅Π°Π»ΡΠ½ΡΠΉ ΡΠ΄Π²ΠΈΠ³ ΠΈ ΠΏΠΎΡΠ»Π΅ ΡΠ΄Π²ΠΈΠ³Π° ΠΎΠΊΠ½Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, ΠΌΠΎΠΆΠ΅Ρ Π»ΠΈ Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ Π±Π»ΠΎΠΊ Π±ΡΡΡ Π·Π°ΠΏΠΈΡΠ°Π½ Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ. ΠΠ΅ΡΠΎΠ΄ AddCode Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΏΠ°ΡΡ ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΠ΅/Π΄Π»ΠΈΠ½Π° Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ ΠΊΠΎΠΏΠΈΡΡΡ ΡΠΈΠΌΠ²ΠΎΠ»Ρ ΠΈΠ· ΡΠΆΠ΅ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΠ°ΡΡΠΈ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π° Π² ΡΠ΅ΠΊΡΡΡΡ ΠΏΠΎΠ·ΠΈΡΠΈΡ. ΠΠ°ΡΠ΅ΠΌ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ ΡΠ΄Π²ΠΈΠ³Π°Π΅ΡΡΡ Π²ΠΏΠ΅ΡΠ΅Π΄.
Π’Π΅ΠΏΠ΅ΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠΎΠ΄ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ. (Π‘ΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΊΠΎΠ΄ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΡΠ°Π½ΡΡΠ΅ ΠΊΠΎΠ΄Π° ΡΠΆΠ°ΡΠΈΡ ΠΊΠ°ΠΆΠ΅ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π½Π΅Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ, Π½ΠΎ Π² Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΡΠΎΡΠΌΠ°Ρ ΡΠΆΠ°ΡΡΡ Π΄Π°Π½Π½ΡΡ Π½Π°ΡΡΠΎΠ»ΡΠΊΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½, ΡΡΠΎ ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΏΡΠΎΡΠ΅!) ΠΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠΊΠ» Π² Π²ΠΈΠ΄Π΅ ΠΌΠ°ΡΠΈΠ½Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ Ρ ΡΡΠ΅ΠΌΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡΠΌΠΈ: ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π±Π°ΠΉΡΠ° ΡΠ»Π°Π³Π°, ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΈΠΌΠ²ΠΎΠ»Π° ΠΈ, Π½Π°ΠΊΠΎΠ½Π΅Ρ, ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΊΠΎΠ΄Π° ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΡ/Π΄Π»ΠΈΠ½Ρ. ΠΠΎΠ΄ ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 11.24. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Ρ Π±Π°ΠΉΡΠΎΠ² Π² Π½Π΅ΡΠΆΠ°ΡΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅, Π·Π°ΠΏΠΈΡΠ°Π½Π½ΠΎΠΌΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΎΠΉ ΡΠΆΠ°ΡΠΈΡ Π² Π½Π°ΡΠ°Π»ΠΎ ΡΠΆΠ°ΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°.
ΠΠΎΡΠ»Π΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π²Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ ΡΠ²Π»ΡΠ΅ΡΡΡ Π·Π°ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌ Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ° LZ77, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π½Π΅ΡΠΆΠ°ΡΡΡ Π΄Π°Π½Π½ΡΡ . ΠΠ°ΡΠ΅ΠΌ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ Π²Ρ ΠΎΠ΄ Π² ΠΏΡΠΎΡΡΡΡ ΠΌΠ°ΡΠΈΠ½Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ, ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡΡΡ Π±Π°ΠΉΡΠΎΠΌ ΡΠ»Π°Π³Π°, ΡΡΠΈΡΡΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°. ΠΡΠ»ΠΈ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ -dsGetFlagByte, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π±Π°ΠΉΡ ΡΠ»Π°Π³Π°. ΠΡΠ»ΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ - dsGetChar, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π»ΠΈΡΠ΅ΡΠ°Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ» ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ Π΅Π³ΠΎ Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ. Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ Π±ΡΠ΄Π΅Ρ dsGetDistLen, ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΠ°ΡΡ ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΠ΅/ Π΄Π»ΠΈΠ½Π° ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ Π΅Π΅ Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ. ΠΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Ρ Π²ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°.
ΠΠΈΡΡΠΈΠ½Π³ 11.24. ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΠΆΠ°ΡΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅ΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ LZ77
procedure TDLZDecompress(aInStream, aOutStream : TStream);
type
TDecodeState = (dsGetFlagByte, dsGetChar, dsGetDistLen);
var
SlideWin : TtdLZSlidingWindow;
BytesUnpacked : longint;
TotalSize : longint;
LongValue : longint;
DecodeState : TDecodeState;
FlagByte : byte;
FlagMask : byte;
NextChar : AnsiChar;
NextDistLen : longint;
CodeCount : integer;
Len : integer;
begin
SlideWin := TtdLZSlidingWindow.Create(aOutStream, false);
try
SlideWin.Name := 'LZ77 Decompress sliding window';
{ΡΡΠΈΡΠ°ΡΡ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠ° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ: ΡΠΈΠΌΠ²ΠΎΠ»Ρ 'TDLZ', Π·Π° ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΡΠ°Π·ΠΌΠ΅Ρ Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°}
aInStream.ReadBuffer(LongValue, sizeof(LongValue));
if (LongValue <> TDLZHeader) then
RaiseError(tdeLZBadEncodedStream, 'TDLZDecompress');
aInStream.ReadBuffer(TotalSize, sizeof(TotalSize));
{ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΡΡΡ ΠΊ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ}
BytesUnpacked := 0;
NextDistLen := 0;
DecodeState := dsGetFlagByte;
CodeCount := 0;
FlagMask := 1;
{Π΄ΠΎ ΡΠ΅Ρ nop, ΠΏΠΎΠΊΠ° ΠΎΡΡΠ°ΡΡΡΡ Π±Π°ΠΉΡΡ Π΄Π»Ρ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ...}
while (BytesUnpacked < TotalSize) do
begin
{ΡΡΠΈΡΡΠ²Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ}
case DecodeState of
dsGetFlagByte : begin
aInStream.ReadBuffer(FlagByte, 1);
CodeCount := 0;
FlagMask := 1;
end;
dsGetChar : begin
aInStream.ReadBuffer(NextChar, 1);
SlideWin.AddChar(NextChar);
inc(BytesUnpacked);
end;
dsGetDistLen : begin
aInStream.ReadBuffer(NextDistLen, 2);
Len := (NextDistLen and tdcLZLengthMask) + 3;
SlideWin.AddCode( (NextDistLen shr tdcLZDistanceShift) + 1, Len);
inc(BytesUnpacked, Len);
end;
end;
{Π²ΡΡΠΈΡΠ»ΠΈΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ}
inc(CodeCount);
if (CodeCount > 8) then
DecodeState := dsGetFlagByte else begin
if ((FlagByte and FlagMask) = 0) then
DecodeState := dsGetChar
else
DecodeState := dsGetDistLen;
FlagMask := FlagMask shl 1;
end;
end;
finally
SlideWin.Free;
end;
{try.. finally}
end;
Π‘ΠΆΠ°ΡΠΈΠ΅ LZ77
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΡΠ° ΡΠ°ΡΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠΆΠ°ΡΠΈΡ. ΠΡΠΈ ΡΡΠΎΠΌ ΠΎΡΠ΅Π½Ρ Π±ΡΡΡΡΠΎ ΠΌΡ ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π΅ΠΌΡΡ ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ: ΠΏΠΎΠΈΡΠΊΠΎΠΌ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½ΠΎΠ³ΠΎ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΡΠΎΠΊΠΎΠΉ Π² ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈ ΠΏΡΠ΅Π΄ΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΌΠΈ 8192 Π±Π°ΠΉΡΠ°ΠΌΠΈ. ΠΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° - ΠΏΠΎΠΈΡΠΊΠ° Π²ΠΎ Π²ΡΠ΅ΠΌ Π±ΡΡΠ΅ΡΠ΅ - ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΎΡΠΊΠ°Π·Π°ΡΡΡΡ ΠΈΠ·-Π·Π° Π΅Π³ΠΎ ΡΠ»ΠΈΡΠΊΠΎΠΌ Π½ΠΈΠ·ΠΊΠΎΠΉ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ.
Π ΡΠ²ΠΎΠ΅ΠΉ ΠΏΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΠ°Π±ΠΎΡΠ΅ ΠΠΈΠ² ΠΈ ΠΠ΅ΠΌΠΏΠ΅Π»Ρ Π½Π΅ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΠ»ΠΈ ΠΏΠΎΡΡΠΈ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΡΠ΅ΡΠ΅Π½ΠΈΠΉ. ΠΠΎΠ΅-ΠΊΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π΄Π΅ΡΠ΅Π²ΠΎ Π±ΠΈΠ½Π°ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠΈΡΠΊΠ°, ΠΏΠΎΡΡΡΠΎΠ΅Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅ΡΡ ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°, Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΡ Π²ΡΡΡΠ΅ΡΠ°Π²ΡΠΈΡ ΡΡ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠΈΡ ΡΡΡΠΎΠΊ (ΠΏΡΠΈΠΌΠ΅ΡΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ ΡΠ»ΡΠΆΠΈΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, ΡΠΎΠ·Π΄Π°Π½Π½Π°Ρ ΠΠ°ΡΠΊΠΎΠΌ ΠΠ΅Π»ΡΡΠΎΠ½ΠΎΠΌ (Mark Nelson) [15]). ΠΠ΄Π½Π°ΠΊΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, ΡΠ²ΡΠ·Π°Π½Π½ΡΡ Ρ ΡΠ΅ΠΌ, ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡΡΡΡ ΠΎ Π±Π°Π»Π°Π½ΡΠΈΡΠΎΠ²ΠΊΠ΅ Π΄Π΅ΡΠ΅Π²Π° ΠΈ ΠΎΠ± ΠΈΠ·Π±Π°Π²Π»Π΅Π½ΠΈΠΈ ΠΎΡ ΡΡΡΠΎΠΊ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΡΠ΄Π°Π»Π΅Π½Ρ ΠΈΠ· ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π³ΠΎ ΠΎΠΊΠ½Π°. ΠΠΎΡΡΠΎΠΌΡ ΠΌΡ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΠΎΠ²Π΅ΡΠΎΠΌ, ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΌ Π² ΠΎΠ½Π»Π°ΠΉΠ½ΠΎΠ²ΠΎΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ΅ Deflate Compressed
Data Format Specification (Π‘ΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΡΠΎΡΠΌΠ°ΡΠ° Π΄Π°Π½Π½ΡΡ , ΡΠΆΠ°ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ Deflate) (RFC 1951) ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΠΌ Ρ Π΅Ρ-ΡΠ°Π±Π»ΠΈΡΡ.
ΠΠ»Π³ΠΎΡΠΈΡΠΌ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ: ΠΌΡ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ ΡΡΠΈ ΡΠΈΠΌΠ²ΠΎΠ»Π° Π² ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ - Π±ΡΠ΄Π΅ΠΌ Π½Π°Π·ΡΠ²Π°ΡΡ ΠΈΡ ΡΠΈΠ³Π½Π°ΡΡΡΠΎΠΉ (signature). Π‘ΠΈΠ³Π½Π°ΡΡΡΠ° Ρ Π΅ΡΠΈΡΡΠ΅ΡΡΡ Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ², Π° Π·Π°ΡΠ΅ΠΌ Ρ Π΅Ρ-Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π² Ρ Π΅Ρ-ΡΠ°Π±Π»ΠΈΡΠ΅, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅ΠΌΡ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅. Π¦Π΅ΠΏΠΎΡΠΊΠΈ ΠΈΠ»ΠΈ ΡΠ²ΡΠ·Π½ΡΠ΅ ΡΠΏΠΈΡΠΊΠΈ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ΅ Ρ Π΅Ρ-ΡΠ°Π±Π»ΠΈΡΡ Π±ΡΠ΄ΡΡ ΡΠΎΡΡΠΎΡΡΡ ΠΈΠ· ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠ΅ΠΉ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ², ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΡΡΠ΅Ρ ΡΠΈΠΌΠ²ΠΎΠ»ΡΠ½ΡΡ ΡΠΈΠ³Π½Π°ΡΡΡ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΈΠ³Π½Π°ΡΡΡΡ Π²ΠΎ Π²Ρ ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅.
ΠΡΠ°ΠΊ, ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈ Ρ Π΅ΡΠΈΡΡΠ΅ΠΌ Π΅Π΅ Π² ΡΠ²ΡΠ·Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠΈΠΉ ΡΠΎΠ±ΠΎΠΉ - ΠΎΠ΄Π½Ρ ΠΈΠ· ΡΠ΅ΠΏΠΎΡΠ΅ΠΊ Π² Ρ Π΅Ρ-ΡΠ°Π±Π»ΠΈΡΠ΅. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ ΡΠ²ΡΠ·Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΈ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌ Ρ ΡΠ°Π½ΡΡΡΡΡΡ Π² Π½Π΅ΠΌ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° Ρ ΠΈΠΌΠ΅ΡΡΠΈΠΌΠΈΡΡ ΡΠΈΠ³Π½Π°ΡΡΡΠ°ΠΌΠΈ. ΠΡΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠΈ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠ΅ΠΉ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΠΌΡ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΠΌ Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, Π° Π·Π°ΡΠ΅ΠΌ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌ ΡΠΈΠΌΠ²ΠΎΠ»Ρ Π² ΡΠΊΠΎΠ»ΡΠ·ΡΡΠ΅ΠΌ ΠΎΠΊΠ½Π΅ Ρ ΡΠΈΠΌΠ²ΠΎΠ»Π°ΠΌΠΈ Π² ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ. ΠΡ ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌ ΡΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° Π² ΡΠ²ΡΠ·Π½ΠΎΠΌ ΡΠΏΠΈΡΠΊΠ΅, ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠ΅Π³ΠΎ Ρ Π΄Π°Π½Π½ΠΎΠΉ ΡΠΈΠ³Π½Π°ΡΡΡΠΎΠΉ, ΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½ΠΎΠ΅ Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅.