📄 urangedecoder.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 + -