📄 sui2skinreader.pas
字号:
if not FillBuffer(Stream, InBuf, InBufPos, InBufEnd) then
Exit;
BytesInBuffer := InBufEnd - InBufPos;
if Count <= BytesInBuffer then
BytesToRead := Count
else
BytesToRead := BytesInBuffer;
Move(InBufPos^, Buffer^, BytesToRead);
Dec(Count, BytesToRead);
Inc(InBufPos, BytesToRead);
end;
InBitBuf := 0;
InBitsLeft := 0;
end;
function PeekBits(
const Stream : TStream; const Count : Integer; var InBitsLeft : Integer;
var InBitBuf : Integer; var InBufPos : PChar; var InBufEnd : PChar; var InBuf : PChar) : Integer;
var
BitsToGo : Integer;
TempBuffer : Integer;
begin
if Count <= InBitsLeft then
Result := (InBitBuf and ExtractMaskArray[Count])
else
begin
BitsToGo := Count - InBitsLeft;
Result := InBitBuf;
if (InBufEnd - InBufPos) < sizeof(Integer) then
begin
if not FillBuffer(Stream, InBuf, InBufPos, InBufEnd) then
TempBuffer := 0
else
TempBuffer := PInteger(InBufPos)^
end
else
TempBuffer := PInteger(InBufPos)^;
Result := Result + ((TempBuffer and ExtractMaskArray[BitsToGo]) shl InBitsLeft);
end;
end;
procedure DiscardBits(
const Count : integer; var InBitsLeft : Integer;
var InBitBuf : Integer; var InBufPos : PChar);
var
BitsToGo : integer;
begin
if (Count <= InBitsLeft) then
begin
InBitBuf := InBitBuf shr Count;
Dec(InBitsLeft, Count);
end
else
begin
BitsToGo := Count - InBitsLeft;
InBitBuf := PInteger(InBufPos)^;
Inc(InBufPos, sizeof(Integer));
InBitBuf := InBitBuf shr BitsToGo;
InBitsLeft := 32 - BitsToGo;
end;
end;
function ReadBits(
const Count : integer; var InBitsLeft : Integer;
var InBitBuf : Integer; var InBufPos : PChar) : Integer;
var
BitsToGo : integer;
begin
if (Count <= InBitsLeft) then
begin
Result := InBitBuf and ExtractMaskArray[Count];
InBitBuf := InBitBuf shr Count;
Dec(InBitsLeft, Count);
end
else
begin
BitsToGo := Count - InBitsLeft;
Result := InBitBuf;
InBitBuf := PInteger(InBufPos)^;
Inc(InBufPos, sizeof(Integer));
Result := Result + ((InBitBuf and ExtractMaskArray[BitsToGo]) shl InBitsLeft);
InBitBuf := InBitBuf shr BitsToGo;
InBitsLeft := 32 - BitsToGo;
end;
end;
procedure DecodeBuffer(
const Buf; Count : Integer; var M1 : Integer; var M2 : Integer;
var M3: Integer; const M : Integer);
var
i : Integer;
Temp : Integer;
Buffer : PChar;
begin
Buffer := @Buf;
for i := 0 to Count - 1 do
begin
Temp := (M3 and $FFFF) or 2;
Buffer^ := Char(BYTE(Buffer^) xor ((Temp * (Temp xor 1)) shr 8));
M1 := DWORD(CRC32Table[BYTE(M1 xor Integer(Buffer^))] xor ((M1 shr 8) and DWORD($00FFFFFF)));
M2 := M2 + (M1 and $FF);
M2 := (M2 * M) + 1;
M3 := DWORD(CRC32Table[BYTE(M3 xor Integer(M2 shr 24))] xor ((M3 shr 8) and DWORD($00FFFFFF)));
Inc(Buffer);
end;
end;
var
StaticLiteralTree : THuffmanTree = nil;
StaticDistanceTree : THuffmanTree = nil;
procedure BuildStaticTrees;
var
i : integer;
CodeLens : array [0..287] of integer;
begin
for i := 0 to 143 do
CodeLens[i] := 8;
for i := 144 to 255 do
CodeLens[i] := 9;
for i := 256 to 279 do
CodeLens[i] := 7;
for i := 280 to 287 do
CodeLens[i] := 8;
StaticLiteralTree := THuffmanTree.Create(15);
StaticLiteralTree.Build(CodeLens, 0, 288, LitExtraBits, 257);
for i := 0 to 31 do
CodeLens[i] := 5;
StaticDistanceTree := THuffmanTree.Create(15);
StaticDistanceTree.Build(CodeLens, 0, 32, DistExtraBits, 0);
end;
procedure Decode(
const LiteralTree, DistanceTree : THuffmanTree;
const InStream, OutStream : TStream;
var BitCount, InBitsLeft, InBitBuf, BitBuffer, LookupValue, EncodedSymbol : Integer;
var Symbol, SymbolCodeLen, Len, ExtraBitCount, Distance : Integer;
var InBufPos, InBufEnd, InBuf, OutCurrent, OutWritePoint, OutBuf, FromPtr,
FromChar, ToChar : PChar);
var
i : Integer;
begin
BitCount := LiteralTree.MaxCodeLen + 5;
BitBuffer := PeekBits(InStream, BitCount, InBitsLeft, InBitBuf, InBufPos, InBufEnd, InBuf);
LookupValue := BitBuffer and ExtractMaskArray[LiteralTree.MaxCodeLen];
EncodedSymbol := LiteralTree.Decode(LookupValue);
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
while (Symbol <> 256) do
begin
if Symbol < 256 then
begin
OutCurrent^ := Char(Symbol);
Inc(OutCurrent);
if OutCurrent >= OutWritePoint then
begin
OutStream.WriteBuffer(OutBuf^, 32 * 1024);
FromPtr := OutBuf + 32 * 1024;
Move(FromPtr^, OutBuf^, OutCurrent - FromPtr);
OutCurrent := OutCurrent - 32 * 1024;
end;
DiscardBits(SymbolCodeLen, InBitsLeft, InBitBuf, InBufPos);
end
else
begin
if Symbol = 285 then
begin
Len := 258;
DiscardBits(SymbolCodeLen, InBitsLeft, InBitBuf, InBufPos);
end
else
begin
ExtraBitCount := EncodedSymbol shr 24;
if (ExtraBitCount = 0) then
begin
Len := LengthBase[Symbol - 257];
DiscardBits(SymbolCodeLen, InBitsLeft, InBitBuf, InBufPos);
end
else
begin
Len := LengthBase[Symbol - 257] + ((BitBuffer shr SymbolCodeLen) and ExtractMaskArray[ExtraBitCount]);
BitCount := SymbolCodeLen + ExtraBitCount;
DiscardBits(BitCount, InBitsLeft, InBitBuf, InBufPos);
end;
end;
BitCount := DistanceTree.MaxCodeLen + 14;
BitBuffer := PeekBits(InStream, BitCount, InBitsLeft, InBitBuf, InBufPos, InBufEnd, InBuf);
LookupValue := BitBuffer and ExtractMaskArray[DistanceTree.MaxCodeLen];
EncodedSymbol := DistanceTree.Decode(LookupValue);
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
ExtraBitCount := EncodedSymbol shr 24;
if (ExtraBitCount = 0) then
begin
Distance := DistanceBase[Symbol];
DiscardBits(SymbolCodeLen, InBitsLeft, InBitBuf, InBufPos);
end
else
begin
Distance := DistanceBase[Symbol] + ((BitBuffer shr SymbolCodeLen) and ExtractMaskArray[ExtraBitCount]);
BitCount := SymbolCodeLen + ExtraBitCount;
DiscardBits(BitCount, InBitsLeft, InBitBuf, InBufPos);
end;
if (Len <= Distance) then
Move((OutCurrent - Distance)^ , OutCurrent^, Len)
else
begin
FromChar := OutCurrent - Distance;
ToChar := OutCurrent;
for i := 1 to Len do
begin
ToChar^ := FromChar^;
Inc(FromChar);
Inc(ToChar);
end;
end;
Inc(OutCurrent, Len);
if (OutCurrent >= OutWritePoint) then
begin
OutStream.WriteBuffer(OutBuf^, 32 * 1024);
FromPtr := OutBuf + 32 * 1024;
Move(FromPtr^, OutBuf^, OutCurrent - FromPtr);
OutCurrent := OutCurrent - 32 * 1024;
end;
end;
BitCount := LiteralTree.MaxCodeLen + 5;
BitBuffer := PeekBits(InStream, BitCount, InBitsLeft, InBitBuf, InBufPos, InBufEnd, InBuf);
LookupValue := BitBuffer and ExtractMaskArray[LiteralTree.MaxCodeLen];
EncodedSymbol := LiteralTree.Decode(LookupValue);
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
end;
DiscardBits(SymbolCodeLen, InBitsLeft, InBitBuf, InBufPos);
end;
function Unzip(const ZipFileName, ExtractFile, OutputFile, Password : String) : TsuiUnzipResult;
var
ZipStream, OutStream, DecrypedStream, InStream : TStream;
dwFileSignature : DWORD;
TailPos : Integer;
Header : TFileHeader;
DirHeader : TDirFileHeader;
LocalHeader : TLocalFileHeader;
InternalFile : array[0..MAX_PATH - 1] of char;
Found, LastBit : Boolean;
InBuf, OutBuf : PChar;
InBufPos, OutBufPos : PChar;
InBufEnd : PChar;
InBitBuf : Integer;
InBitsLeft : Integer;
OutCurrent : PChar;
OutWritePoint : PChar;
LitCount, DistCount, CodeLenCount : Integer;
CodeLens : array [0..285 + 32] of Integer;
i : Integer;
CodeLenTree, LiteralTree, DistanceTree : THuffmanTree;
BitsToGo : Integer;
SymbolCount, BitCount, BitBuffer, LookupValue, EncodedSymbol, Symbol : Integer;
SymbolCodeLen, RepeatCount, TempBuffer, Len, ExtraBitCount : Integer;
Distance : Integer;
FromPtr, FromChar, ToChar : PChar;
BlockType : Integer;
LenNotLen : TLenNotLen;
BytesToGo, BytesToWrite, BytesToWrite2, Count : Integer;
Buffer : Pointer;
Buffer2 : PChar;
M, M1, M2, M3 : Integer;
H, EncryptedHead : TEncrypetHeader;
Buf : array [0..1023] of Char;
C : Integer;
begin
Result := suiURFailed;
ZipStream := nil;
OutStream := nil;
DecrypedStream := nil;
InBuf := nil;
OutBuf := nil;
if not FileExists(ZipFileName) then
Exit;
try // finally
try //except
ZipStream := TFileStream.Create(ZipFileName, fmOpenRead or fmShareDenyNone);
ZipStream.Position := 0;
ZipStream.Read(dwFileSignature, sizeof(dwFileSignature));
if not ((dwFileSignature and $0000FFFF) = $4B53) then
Exit; // not a zip file
TailPos := FindTail(ZipStream);
if TailPos < 0 then
Exit;
ZipStream.Read(Header.Signature, sizeof(Header.Signature));
ZipStream.Read(Header.DiskNumber, sizeof(Header.DiskNumber));
ZipStream.Read(Header.StartDiskNumber, sizeof(Header.StartDiskNumber));
ZipStream.Read(Header.EntriesOnDisk, sizeof(Header.EntriesOnDisk));
ZipStream.Read(Header.TotalEntries, sizeof(Header.TotalEntries));
ZipStream.Read(Header.DirectorySize, sizeof(Header.DirectorySize));
ZipStream.Read(Header.DirectoryOffset, sizeof(Header.DirectoryOffset));
ZipStream.Read(Header.ZipfileCommentLength, sizeof(Header.ZipfileCommentLength));
if Header.ZipfileCommentLength > 0 then
ZipStream.Seek(Header.ZipfileCommentLength, soFromCurrent);
ZipStream.Seek(Header.DirectoryOffset, soFromBeginning);
Found := false;
while ZipStream.Position < TailPos do
begin
ZipStream.Read(DirHeader.Signature, sizeof(DirHeader.Signature));
ZipStream.Read(DirHeader.VersionMadeBy, sizeof(DirHeader.VersionMadeBy));
ZipStream.Read(DirHeader.VersionNeededToExtract, sizeof(DirHeader.VersionNeededToExtract));
ZipStream.Read(DirHeader.GeneralPurposeBitFlag, sizeof(DirHeader.GeneralPurposeBitFlag));
ZipStream.Read(DirHeader.CompressionMethod, sizeof(DirHeader.CompressionMethod));
ZipStream.Read(DirHeader.LastModFileTime, sizeof(DirHeader.LastModFileTime));
ZipStream.Read(DirHeader.LastModFileDate, sizeof(DirHeader.LastModFileDate));
ZipStream.Read(DirHeader.CRC32, sizeof(DirHeader.CRC32));
ZipStream.Read(DirHeader.CompressedSize, sizeof(DirHeader.CompressedSize));
ZipStream.Read(DirHeader.UncompressedSize, sizeof(DirHeader.UncompressedSize));
ZipStream.Read(DirHeader.FileNameLength, sizeof(DirHeader.FileNameLength));
ZipStream.Read(DirHeader.ExtraFieldLength, sizeof(DirHeader.ExtraFieldLength));
ZipStream.Read(DirHeader.FileCommentLength, sizeof(DirHeader.FileCommentLength));
ZipStream.Read(DirHeader.DiskNumberStart, sizeof(DirHeader.DiskNumberStart));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -