-
-
Save CynicRus/56dd08e6d536bea1bd95d07136efa281 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
procedure SnappyDecompress(Input: TByteArray; Offset, | |
Length: integer; var Output: TByteArray); | |
var | |
i, l, o, c,targetIndex,SourceIndex,targetLength: integer; | |
function incPP(var AVal: integer): integer; | |
begin | |
result := AVal; | |
inc(AVal); | |
end; | |
begin | |
sourceIndex:=offset; | |
targetIndex:=0; | |
targetLength:=0; | |
i:=0; | |
repeat | |
targetLength := targetLength + (input[sourceIndex] and $7f) shl (incPP(i) * 7); | |
until ((input[incPP(sourceIndex)] and $80) <> $80); | |
SetLength(Output,targetLength); | |
while (sourceIndex < offset + length) do | |
begin | |
if(targetIndex >= targetLength) then | |
raise Exception.Create('Superfluous input data encountered on offset '+IntToStr(sourceIndex)); | |
case (input[sourceIndex] and 3) of | |
0: begin | |
l := (input[incPP(sourceIndex)] shr 2) and $3f; | |
case l of | |
60: begin | |
l := input[incPP(sourceIndex)] and $ff; | |
inc(l); | |
end; | |
61: | |
begin | |
l := input[incPP(sourceIndex)] and $ff; | |
l := l or ((input[incPP(sourceIndex)]) and $ff); | |
inc(l); | |
end; | |
62: | |
begin | |
l := input[incPP(sourceIndex)] and $ff; | |
l :=l or ((input[IncPP(sourceIndex)] and $ff) shl 8); | |
l :=l or ((input[IncPP(sourceIndex)] and $ff) shl 16); | |
inc(l); | |
end; | |
63: | |
begin | |
l := input[IncPP(sourceIndex)] and $ff; | |
l := l or ((input[IncPP(sourceIndex)] and $ff) shl 8); | |
l := l or ((input[IncPP(sourceIndex)] and $ff) shl 16); | |
l := l or ((input[IncPP(sourceIndex)] and $ff) shl 24); | |
inc(l); | |
end | |
else | |
inc(l); | |
end; | |
Move(Input[sourceIndex],Output[targetIndex],l); | |
sourceIndex := sourceIndex + l; | |
targetIndex :=targetIndex + l; | |
end; | |
1: | |
begin | |
l := 4 + ((input[sourceIndex] shr 2) and 7); | |
o := (input[IncPP(sourceIndex)] and $e0) shl 3; | |
o := o or (input[incPP(sourceIndex)] and $ff); | |
if (l < o) then | |
begin | |
move(output[targetIndex - o],output[targetIndex],l); | |
targetIndex:=targetIndex + l; | |
end | |
else | |
begin | |
if (o = 1) then | |
begin | |
FillChar(Output[targetIndex],l,output[targetIndex-l]); | |
targetIndex:= targetIndex + l; | |
end | |
else | |
begin | |
while (l > 0) do | |
begin | |
c:= ifthen( L > o, o, l); | |
Move(output[targetIndex-o],output[targetIndex],c); | |
targetIndex:= targetIndex + c; | |
l:= l - c; | |
end; | |
end; | |
end; | |
end; | |
2: | |
begin | |
l := ((input[IncPP(sourceIndex)] shr 2) and $3f) + 1; | |
o := input[IncPP(sourceIndex)] and $ff; | |
o := o or ((input[IncPP(sourceIndex)] and $ff) shl 8); | |
if (l < o) then | |
begin | |
move(output[abs(targetIndex - o)],output[targetIndex],l); | |
targetIndex:=targetIndex + l; | |
end | |
else | |
begin | |
if (o = 1) then | |
begin | |
FillChar(Output[targetIndex],l,output[targetIndex-l]); | |
targetIndex:= targetIndex + l; | |
end | |
else | |
begin | |
while (l > 0) do | |
begin | |
c:= ifthen( L > o, o, l); | |
Move(output[targetIndex-o],output[targetIndex],c); | |
targetIndex:= targetIndex + c; | |
l:= l - c; | |
end; | |
end; | |
end; | |
end; | |
3: | |
begin | |
l := ((input[IncPP(sourceIndex)] shr 2) and $3f) + 1; | |
o := input[IncPP(sourceIndex)] and $ff; | |
o := o or ((input[IncPP(sourceIndex)] and $ff) shl 8); | |
o := o or ((input[IncPP(sourceIndex)] and $ff) shl 16); | |
o := o or ((input[IncPP(sourceIndex)] and $ff) shl 24); | |
if (l < o) then | |
begin | |
move(output[targetIndex - o],output[targetIndex],l); | |
targetIndex:=targetIndex + l; | |
end | |
else | |
begin | |
if (o = 1) then | |
begin | |
FillChar(Output[targetIndex],l,output[targetIndex-l]); | |
targetIndex:= targetIndex + l; | |
end | |
else | |
begin | |
while (l > 0) do | |
begin | |
c:= ifthen( L > o, o, l); | |
Move(output[targetIndex-o],output[targetIndex],c); | |
targetIndex:= targetIndex + c; | |
l:= l - c; | |
end; | |
end; | |
end; | |
end; | |
end; | |
end; | |
end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment