⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sui2skinreader.pas

📁 SUIPack是一款为Delphi和C++Builder开发的所见即所得的界面增强VCL组件
💻 PAS
📖 第 1 页 / 共 4 页
字号:

        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 + -