mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-28 10:02:14 +00:00
115 lines
3.1 KiB
ObjectPascal
115 lines
3.1 KiB
ObjectPascal
unit UBitTreeEncoder;
|
|
|
|
{$IFDEF FPC}
|
|
{$MODE Delphi}
|
|
{$ENDIF}
|
|
|
|
interface
|
|
|
|
uses URangeDecoder,URangeEncoder;
|
|
|
|
type TBitTreeEncoder=class
|
|
public
|
|
Models: array of smallint;
|
|
NumBitLevels:integer;
|
|
constructor Create(const numBitLevels:integer);
|
|
procedure Init;
|
|
procedure Encode(const rangeEncoder:TRangeEncoder;const symbol:integer);
|
|
procedure ReverseEncode(const rangeEncoder:TRangeEncoder;symbol:integer);
|
|
function GetPrice(const symbol:integer):integer;
|
|
function ReverseGetPrice(symbol:integer):integer;overload;
|
|
end;
|
|
|
|
procedure ReverseEncode(var Models:array of smallint;const startIndex:integer;const rangeEncoder:TRangeEncoder;const NumBitLevels:integer; symbol:integer);
|
|
function ReverseGetPrice(var Models:array of smallint;const startIndex,NumBitLevels:integer; symbol:integer):integer;
|
|
|
|
implementation
|
|
|
|
constructor TBitTreeEncoder.Create(const numBitLevels:integer);
|
|
begin
|
|
self.NumBitLevels:=numBitLevels;
|
|
setlength(Models,1 shl numBitLevels);
|
|
end;
|
|
|
|
procedure TBitTreeEncoder.Init;
|
|
begin
|
|
URangeDecoder.InitBitModels(Models);
|
|
end;
|
|
|
|
procedure TBitTreeEncoder.Encode(const rangeEncoder:TRangeEncoder;const symbol:integer);
|
|
var m,bitindex,bit:integer;
|
|
begin
|
|
m := 1;
|
|
for bitIndex := NumBitLevels -1 downto 0 do begin
|
|
bit := (symbol shr bitIndex) and 1;
|
|
rangeEncoder.Encode(Models, m, bit);
|
|
m := (m shl 1) or bit;
|
|
end;
|
|
end;
|
|
|
|
procedure TBitTreeEncoder.ReverseEncode(const rangeEncoder:TRangeEncoder;symbol:integer);
|
|
var m,i,bit:integer;
|
|
begin
|
|
m:=1;
|
|
for i:= 0 to NumBitLevels -1 do begin
|
|
bit := symbol and 1;
|
|
rangeEncoder.Encode(Models, m, bit);
|
|
m := (m shl 1) or bit;
|
|
symbol := symbol shr 1;
|
|
end;
|
|
end;
|
|
|
|
function TBitTreeEncoder.GetPrice(const symbol:integer):integer;
|
|
var price,m,bitindex,bit:integer;
|
|
begin
|
|
price := 0;
|
|
m := 1;
|
|
for bitIndex := NumBitLevels - 1 downto 0 do begin
|
|
bit := (symbol shr bitIndex) and 1;
|
|
price := price + RangeEncoder.GetPrice(Models[m], bit);
|
|
m := (m shl 1) + bit;
|
|
end;
|
|
result:=price;
|
|
end;
|
|
|
|
function TBitTreeEncoder.ReverseGetPrice(symbol:integer):integer;
|
|
var price,m,i,bit:integer;
|
|
begin
|
|
price := 0;
|
|
m := 1;
|
|
for i:= NumBitLevels downto 1 do begin
|
|
bit := symbol and 1;
|
|
symbol := symbol shr 1;
|
|
price :=price + RangeEncoder.GetPrice(Models[m], bit);
|
|
m := (m shl 1) or bit;
|
|
end;
|
|
result:=price;
|
|
end;
|
|
|
|
function ReverseGetPrice(var Models:array of smallint;const startIndex,NumBitLevels:integer;symbol:integer):integer;
|
|
var price,m,i,bit:integer;
|
|
begin
|
|
price := 0;
|
|
m := 1;
|
|
for i := NumBitLevels downto 1 do begin
|
|
bit := symbol and 1;
|
|
symbol := symbol shr 1;
|
|
price := price + RangeEncoder.GetPrice(Models[startIndex + m], bit);
|
|
m := (m shl 1) or bit;
|
|
end;
|
|
result:=price;
|
|
end;
|
|
|
|
procedure ReverseEncode(var Models:array of smallint;const startIndex:integer;const rangeEncoder:TRangeEncoder;const NumBitLevels:integer;symbol:integer);
|
|
var m,i,bit:integer;
|
|
begin
|
|
m:=1;
|
|
for i := 0 to NumBitLevels -1 do begin
|
|
bit := symbol and 1;
|
|
rangeEncoder.Encode(Models, startIndex + m, bit);
|
|
m := (m shl 1) or bit;
|
|
symbol := symbol shr 1;
|
|
end;
|
|
end;
|
|
|
|
end.
|