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

📄 sui2skinreader.pas

📁 SUIPack是一款为Delphi和C++Builder开发的所见即所得的界面增强VCL组件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    begin
        CodeLen := CodeLengths[i + StartInx];
        if CodeLen > m_MaxCodeLen then
            m_MaxCodeLen := CodeLen;
        Inc(LengthCount[CodeLen]);
    end;

    DecoderLen := PowerOfTwo[m_MaxCodeLen];
    GetMem(m_Decodes, DecoderLen * sizeof(Integer));
    DecodesEnd := PChar(m_Decodes) + (DecoderLen * sizeof(Integer));
    FillChar(m_Decodes^, DecoderLen * sizeof(Integer), $FF);

    Code := 0;
    LengthCount[0] := 0;
    for i := 1 to m_DefMaxCodeLen do
    begin
        Code := (Code + LengthCount[i-1]) shl 1;
        NextCode[i] := Code;
    end;

    Decodes := m_Decodes;
    TablePtr := @ByteRevTable;

    for Symbol := 0 to Count - 1 do
    begin
        CodeLen := CodeLengths[Symbol + StartInx];

        if CodeLen <> 0 then
        begin
            Code := NextCode[CodeLen];
            asm
                push esi
                mov eax, Code
                mov esi, TablePtr
                xor ecx, ecx
                xor edx, edx
                mov cl, ah
                mov dl, al
                mov al, [esi+ecx]
                mov ah, [esi+edx]
                mov ecx, 16
                pop esi
                sub ecx, CodeLen
                shr eax, cl
                mov Code, eax
            end;

            CodeData := Symbol + (CodeLen shl 16);
            if Symbol >= ExtraOffset then
                CodeData := CodeData + (ExtraBits[Symbol - ExtraOffset] shl 24);

            CodeIncr := PowerOfTwo[CodeLen] * sizeof(Integer);
            asm
                push edi
                mov eax, Decodes
                mov edi, DecodesEnd
                mov edx, Code
                shl edx, 1
                shl edx, 1
                add eax, edx
                mov edx, CodeData
                mov ecx, CodeIncr
            @@1:
                mov [eax], edx
                add eax, ecx
                cmp eax, edi
                jl @@1
                pop edi
            end;
            Inc(NextCode[CodeLen]);
        end;
    end;
end;

constructor THuffmanTree.Create(DefMaxCodeLen: Integer);
begin
    m_DefMaxCodeLen := DefMaxCodeLen;
end;

function THuffmanTree.Decode(LookupBits: Integer): Integer;
begin
    Result := m_Decodes^[LookupBits];
end;

destructor THuffmanTree.Destroy;
begin
    if (m_Decodes <> nil) then
        FreeMem(m_Decodes);
    inherited;
end;

{ Tsk2SkinFileReader }

constructor Tsk2SkinFileReader.Create(FileName, Password : String);
begin
    m_BitmapList := TStringList.Create();
    m_IntegerList := TStringList.Create();
    m_BooleanList := TStringList.Create();
    m_StrList := TStringList.Create();

    Load(FileName, Password);
end;

destructor Tsk2SkinFileReader.Destroy;
var
    i : Integer;
begin
    for i := 0 to m_BitmapList.Count - 1 do
    begin
        m_BitmapList.Objects[i].Free();
        m_BitmapList.Objects[i] := nil;
    end;
    m_StrList.Free();
    m_BooleanList.Free();
    m_IntegerList.Free();
    m_BitmapList.Free();
end;

function Tsk2SkinFileReader.GetBool(Key: String): Boolean;
var
    StrValue : String;
begin
    Result := false;
    StrValue := m_BooleanList.Values[Key];
    if StrValue = '' then
        Exit;
    try
        Result := Boolean(StrToInt(StrValue));
    except end;
end;

function Tsk2SkinFileReader.GetBitmap(Key: String): TBitmap;
var
    nIndex : Integer;
begin
    Result := nil;
    nIndex := m_BitmapList.IndexOf(Key);
    if nIndex = -1 then
        Exit;
    Result := TBitmap(m_BitmapList.Objects[nIndex]);
end;

function Tsk2SkinFileReader.GetInteger(Key: String): Integer;
var
    StrValue : String;
begin
    Result := -1;
    StrValue := m_IntegerList.Values[Key];
    if StrValue = '' then
        Exit;
    try
        Result := StrToInt(StrValue);
    except
        Result := -1;
    end;
end;

function Tsk2SkinFileReader.GetStr(Key: String): String;
begin
    Result := m_StrList.Values[Key];
end;


{$IFDEF VER130}

{ CoFunctions for Delphi 5  --  BEGIN}

function CoCreateGuid(out guid: TGUID): HResult; stdcall; external 'ole32.dll';

function StringFromCLSID(const clsid: TGUID; out psz: PWideChar): HResult; stdcall; external 'ole32.dll' name 'StringFromCLSID';

procedure CoTaskMemFree(pv: Pointer); stdcall; external 'ole32.dll' name 'CoTaskMemFree';

function CreateGUID(out Guid: TGUID): HResult;
begin
    Result := CoCreateGuid(Guid);
end;

function GUIDToString(const GUID: TGUID): string;
var
    P: PWideChar;
begin
    if not Succeeded(StringFromCLSID(GUID, P)) then
        raise Exception.Create('ERROR');
    Result := P;
    CoTaskMemFree(P);
end;

{ CoFunctions for Delphi 5  --  END}

{$ENDIF}

procedure Tsk2SkinFileReader.Load(FileName, Password : String);
var
    FileStream : TStream;
    Stream : TStream;
    Bitmap : TBitmap;
    FileHeader : Tsk2SkinFileHeader;
    NodeHeader : Tsk2SkinFileNodeHeader;
    BaseFileHeader : Tsk2SkinFileBaseHeader;
    StrValue : String;
    IntValue : Integer;
    BoolValue : Boolean;
    TempFileName : String;
    guid : TGUID;
    r : TsuiUnzipResult;
    function GetTempPath() : String;
    var
        TempPath : array [0..MAX_PATH - 1] of Char;
    begin
        windows.GetTempPath(MAX_PATH, TempPath);
        Result := StrPas(TempPath);
        if Result[Length(Result)] <> '\' then
            Result := Result + '\';
    end;
begin
    m_Ready := false;
    CreateGUID(guid);
    TempFileName := GetTempPath() + GUIDToString(guid);
    r := Unzip(FileName, 'SKINDATA.SK2', TempFileName, Password);
    if r = suiURWrongPassword then
    begin
        Exit;
    end
    else if r = suiURFailed then
        raise Exception.Create('Failed to read skin file!');

    // read header
    FileStream := TFileStream.Create(TempFileName, fmOpenRead or fmShareDenyNone);
    FileStream.Read(BaseFileHeader, sizeof(Tsk2SkinFileBaseHeader));
    FileStream.Seek(0, soFromBeginning);
    FileStream.Read(FileHeader, BaseFileHeader.HeaderSize);

    // read nodes
    FileStream.Seek(FileHeader.FirstNode, soFromBeginning);
    FileStream.Read(NodeHeader, sizeof(NodeHeader));

    while NodeHeader.NextNode <> 0 do
    begin
        FileStream.Seek(NodeHeader.NodeStart, soFromBeginning);

        case NodeHeader.NodeType of

        tbntStream :
        begin
            Stream := TMemoryStream.Create();
            Stream.CopyFrom(FileStream, NodeHeader.NodeSize);
            Stream.Seek(0, soFromBeginning);
            Bitmap := TBitmap.Create();
            Bitmap.LoadFromStream(Stream);
            m_BitmapList.AddObject(NodeHeader.NodeKey, Bitmap);
            Stream.Free();
        end;

        tbntStr :
        begin
            SetLength(StrValue, NodeHeader.NodeSize);
            FileStream.Read(StrValue[1], NodeHeader.NodeSize);
            m_StrList.Add(NodeHeader.NodeKey + '=' + StrValue);
        end;

        tbntInt :
        begin
            FileStream.Read(IntValue, NodeHeader.NodeSize);
            m_IntegerList.Add(NodeHeader.NodeKey + '=' + IntToStr(IntValue));
        end;

        tbntBool :
        begin
            FileStream.Read(BoolValue, NodeHeader.NodeSize);
            m_BooleanList.Add(NodeHeader.NodeKey + '=' + IntToStr(Ord(BoolValue)));
        end;

        end; // case

        FileStream.Seek(NodeHeader.NextNode, soFromBeginning);
        FileStream.Read(NodeHeader, sizeof(NodeHeader));
    end;

    FileStream.Free();
    DeleteFile(TempFileName);

    m_Ready := true;
end;

procedure Tsk2SkinFileReader.SetBitmap(Key: String; const Buf: TBitmap);
var
    nIndex : Integer;
    Bitmap : TBitmap;
begin
    nIndex := m_BitmapList.IndexOf(Key);
    if nIndex = -1 then
        Exit;
    Bitmap := TBitmap(m_BitmapList.Objects[nIndex]);
    Bitmap.Assign(Buf);
end;

procedure Tsk2SkinFileReader.SetBool(Key: String; Value: Boolean);
begin
    m_BooleanList.Values[Key] := IntToStr(Ord(Value));
end;

procedure Tsk2SkinFileReader.SetInteger(Key: String; Value: Integer);
begin
    m_IntegerList.Values[Key] := IntToStr(Value);
end;

procedure Tsk2SkinFileReader.ProcessTransparentColor(TransColor: TColor);
var
    i : Integer;
begin
    for i := 0 to m_BitmapList.Count - 1 do
    begin
        if m_BitmapList.Objects[i] <> nil then
        begin
            TBitmap(m_BitmapList.Objects[i]).TransparentMode := tmFixed;
            TBitmap(m_BitmapList.Objects[i]).TransparentColor := TransColor;
        end;
    end;
end;

initialization
    BuildStaticTrees();

finalization
    StaticLiteralTree.Free();
    StaticDistanceTree.Free();
    
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -