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

📄 urangedecoder.pas

📁 Pascal lzma 算法实现,可以直接在delphi中使用,Delphi 2007 是用这个东西发包的
💻 PAS
字号:
unit URangeDecoder;

{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}

interface

uses Classes,ULZMACommon;

type TRangeDecoder=class
       public
         Range,Code:integer;
         Stream:TStream;
         procedure SetStream(const Stream:TStream);
         procedure ReleaseStream;
         procedure Init;
         function DecodeDirectBits(const numTotalBits:integer):integer;
         function DecodeBit(var probs: array of smallint;const index:integer):integer;
       end;

procedure InitBitModels(var probs: array of smallint);

implementation

const kTopMask = not ((1 shl 24) - 1);
      kNumBitModelTotalBits = 11;
      kBitModelTotal = (1 shl kNumBitModelTotalBits);
      kNumMoveBits = 5;

procedure TRangeDecoder.SetStream(const Stream:TStream);
begin
self.Stream:=Stream;
end;

procedure TRangeDecoder.ReleaseStream;
begin
stream:=nil;
end;

procedure TRangeDecoder.Init;
var i:integer;
begin
code:=0;
Range:=-1;
for i:=0 to 4 do begin
    code:=(code shl 8) or byte(ReadByte(stream));
    end;
end;

function TRangeDecoder.DecodeDirectBits(const numTotalBits:integer):integer;
var i,t:integer;
begin
result:=0;
for i := numTotalBits downto 1 do begin
    range:=range shr 1;
    t := ((Code - Range) shr 31);
    Code := Code - Range and (t - 1);
    result := (result shl 1) or (1 - t);
    if ((Range and kTopMask) = 0) then begin
       Code := (Code shl 8) or ReadByte(stream);
       Range := Range shl 8;
       end;
    end;
end;

function TRangeDecoder.DecodeBit(var probs: array of smallint;const index:integer):integer;
var prob,newbound:integer;
begin
prob:=probs[index];
newbound:=(Range shr kNumBitModelTotalBits) * prob;
if (integer((integer(Code) xor integer($80000000))) < integer((integer(newBound) xor integer($80000000)))) then begin
   Range := newBound;
   probs[index] := (prob + ((kBitModelTotal - prob) shr kNumMoveBits));
   if ((Range and kTopMask) = 0) then begin
      Code := (Code shl 8) or ReadByte(stream);
      Range := Range shl 8;
      end;
   result:=0;
   end else begin
       Range := Range - newBound;
       Code := Code - newBound;
       probs[index] := (prob - ((prob) shr kNumMoveBits));
       if ((Range and kTopMask) = 0) then begin
          Code := (Code shl 8) or ReadByte(stream);
          Range := Range shl  8;
          end;
       result:=1;
       end;
end;

procedure InitBitModels(var probs: array of smallint);
var i:integer;
begin
for i:=0 to length(probs)-1 do
    probs[i] := kBitModelTotal shr 1;
end;

end.

⌨️ 快捷键说明

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