clean
git-svn-id: https://svn.code.sf.net/p/kolmck/code@117 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
This commit is contained in:
@ -1,122 +0,0 @@
|
||||
{
|
||||
Alternative memory manager. To use it, just place a reference to this
|
||||
unit *FIRST* in the uses clause of your project (dpr-file). It is a good idea
|
||||
to use this memory manager with system dcu replacement by Vladimir Kladov.
|
||||
|
||||
Heap API used, which is fast and very effective (allocated block granularity
|
||||
is 16 bytes). One additional benefit is that some proofing tools (MemProof)
|
||||
do not detect API failures, which those can find when standard Delphi memory
|
||||
manager used.
|
||||
=====================================================================
|
||||
Copyright (C) by Vladimir Kladov, 2001
|
||||
---------------------------------------------------------------------
|
||||
http://xcl.cjb.net
|
||||
mailto: bonanzas@xcl.cjb.net
|
||||
}
|
||||
|
||||
unit HeapMM;
|
||||
|
||||
interface
|
||||
|
||||
uses windows;
|
||||
|
||||
const
|
||||
HEAP_NO_SERIALIZE = $00001;
|
||||
HEAP_GROWABLE = $00002;
|
||||
HEAP_GENERATE_EXCEPTIONS = $00004;
|
||||
HEAP_ZERO_MEMORY = $00008;
|
||||
HEAP_REALLOC_IN_PLACE_ONLY = $00010;
|
||||
HEAP_TAIL_CHECKING_ENABLED = $00020;
|
||||
HEAP_FREE_CHECKING_ENABLED = $00040;
|
||||
HEAP_DISABLE_COALESCE_ON_FREE = $00080;
|
||||
HEAP_CREATE_ALIGN_16 = $10000;
|
||||
HEAP_CREATE_ENABLE_TRACING = $20000;
|
||||
HEAP_MAXIMUM_TAG = $00FFF;
|
||||
HEAP_PSEUDO_TAG_FLAG = $08000;
|
||||
HEAP_TAG_SHIFT = 16 ;
|
||||
|
||||
{$DEFINE USE_PROCESS_HEAP}
|
||||
|
||||
var
|
||||
HeapHandle: THandle;
|
||||
{* Global handle to the heap. Do not change it! }
|
||||
|
||||
HeapFlags: DWORD = 0;
|
||||
{* Possible flags are:
|
||||
HEAP_GENERATE_EXCEPTIONS - system will raise an exception to indicate a
|
||||
function failure, such as an out-of-memory
|
||||
condition, instead of returning NULL.
|
||||
HEAP_NO_SERIALIZE - mutual exclusion will not be used while the HeapAlloc
|
||||
function is accessing the heap. Be careful!
|
||||
Not recommended for multi-thread applications.
|
||||
But faster.
|
||||
HEAP_ZERO_MEMORY - obviously. (Slower!)
|
||||
}
|
||||
|
||||
{ Note from MSDN:
|
||||
The granularity of heap allocations in Win32 is 16 bytes. So if you
|
||||
request a global memory allocation of 1 byte, the heap returns a pointer
|
||||
to a chunk of memory, guaranteeing that the 1 byte is available. Chances
|
||||
are, 16 bytes will actually be available because the heap cannot allocate
|
||||
less than 16 bytes at a time.
|
||||
}
|
||||
implementation
|
||||
|
||||
function HeapGetMem(size: Integer): Pointer;
|
||||
// Allocate memory block.
|
||||
begin
|
||||
Result := HeapAlloc( HeapHandle, HeapFlags, size );
|
||||
end;
|
||||
|
||||
function HeapFreeMem(p: Pointer): Integer;
|
||||
// Deallocate memory block.
|
||||
begin
|
||||
Result := Integer( not HeapFree( HeapHandle, HeapFlags and HEAP_NO_SERIALIZE,
|
||||
p ) );
|
||||
end;
|
||||
|
||||
function HeapReallocMem(p: Pointer; size: Integer): Pointer;
|
||||
// Resize memory block.
|
||||
begin
|
||||
Result := HeapRealloc( HeapHandle, HeapFlags and (HEAP_NO_SERIALIZE and
|
||||
HEAP_GENERATE_EXCEPTIONS and HEAP_ZERO_MEMORY),
|
||||
// (Prevent using flag HEAP_REALLOC_IN_PLACE_ONLY here - to allow
|
||||
// system to move the block if necessary).
|
||||
p, size );
|
||||
end;
|
||||
|
||||
{function HeapMemoryManagerSet: Boolean;
|
||||
begin
|
||||
Result := TRUE;
|
||||
end;}
|
||||
|
||||
const
|
||||
HeapMemoryManager: TMemoryManager = (
|
||||
GetMem: HeapGetMem;
|
||||
FreeMem: HeapFreeMem;
|
||||
ReallocMem: HeapReallocMem);
|
||||
|
||||
var OldMM: TMemoryManager;
|
||||
//OldIsMMset: function : Boolean;
|
||||
|
||||
initialization
|
||||
|
||||
{$IFDEF USE_PROCESS_HEAP}
|
||||
HeapHandle := GetProcessHeap;
|
||||
{$ELSE}
|
||||
HeapHandle := HeapCreate( 0, 0, 0 );
|
||||
{$ENDIF}
|
||||
GetMemoryManager( OldMM );
|
||||
//OldIsMMset := IsMemoryManagerSet;
|
||||
//IsMemoryManagerSet := HeapMemoryManagerSet;
|
||||
SetMemoryManager( HeapMemoryManager );
|
||||
|
||||
finalization
|
||||
|
||||
SetMemoryManager( OldMM );
|
||||
//IsMemoryManagerSet := OldIsMMset;
|
||||
{$IFNDEF USE_PROCESS_HEAP}
|
||||
HeapDestroy( HeapHandle );
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
File diff suppressed because it is too large
Load Diff
@ -1,260 +0,0 @@
|
||||
unit objects;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
KOL, Windows, Messages;
|
||||
|
||||
type
|
||||
TWndMethod = procedure(var Message: TMessage) of object;
|
||||
|
||||
function MakeObjectInstance(Method: TWndMethod): Pointer;
|
||||
procedure FreeObjectInstance(ObjectInstance: Pointer);
|
||||
function AllocateHWnd(Method: TWndMethod): HWND;
|
||||
procedure DeallocateHWnd(Wnd: HWND);
|
||||
function IncColor(C: TColor; D: integer): TColor;
|
||||
procedure AjustBitmap(const M: KOL.PBitmap; S, C: TColor);
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
PObjectInstance = ^TObjectInstance;
|
||||
TObjectInstance = packed record
|
||||
Code: Byte;
|
||||
Offset: Integer;
|
||||
case Integer of
|
||||
0: (Next: PObjectInstance);
|
||||
1: (Method: TWndMethod);
|
||||
end;
|
||||
|
||||
type
|
||||
PInstanceBlock = ^TInstanceBlock;
|
||||
TInstanceBlock = packed record
|
||||
Next: PInstanceBlock;
|
||||
Code: array[1..2] of Byte;
|
||||
WndProcPtr: Pointer;
|
||||
Instances: array[0..100] of TObjectInstance;
|
||||
end;
|
||||
|
||||
var
|
||||
InstBlockList: PInstanceBlock;
|
||||
InstBlockCount: integer;
|
||||
InstFreeList: PObjectInstance;
|
||||
|
||||
{ Standard window procedure }
|
||||
{ In ECX = Address of method pointer }
|
||||
{ Out EAX = Result }
|
||||
|
||||
function StdWndProc(Window: HWND; Message, WParam: Longint;
|
||||
LParam: Longint): Longint; stdcall; assembler;
|
||||
asm
|
||||
XOR EAX,EAX
|
||||
PUSH EAX
|
||||
PUSH LParam
|
||||
PUSH WParam
|
||||
PUSH Message
|
||||
MOV EDX,ESP
|
||||
MOV EAX,[ECX].Longint[4]
|
||||
CALL [ECX].Pointer
|
||||
ADD ESP,12
|
||||
POP EAX
|
||||
end;
|
||||
|
||||
{ Allocate an object instance }
|
||||
|
||||
function CalcJmpOffset(Src, Dest: Pointer): Longint;
|
||||
begin
|
||||
Result := Longint(Dest) - (Longint(Src) + 5);
|
||||
end;
|
||||
|
||||
function MakeObjectInstance(Method: TWndMethod): Pointer;
|
||||
const
|
||||
BlockCode: array[1..2] of Byte = (
|
||||
$59, { POP ECX }
|
||||
$E9); { JMP StdWndProc }
|
||||
PageSize = 4096;
|
||||
var
|
||||
Block: PInstanceBlock;
|
||||
Instance: PObjectInstance;
|
||||
begin
|
||||
if InstFreeList = nil then
|
||||
begin
|
||||
Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
Block^.Next := InstBlockList;
|
||||
Move(BlockCode, Block^.Code, SizeOf(BlockCode));
|
||||
Block^.WndProcPtr := Pointer(CalcJmpOffset(@Block^.Code[2], @StdWndProc));
|
||||
Instance := @Block^.Instances;
|
||||
repeat
|
||||
Instance^.Code := $E8; { CALL NEAR PTR Offset }
|
||||
Instance^.Offset := CalcJmpOffset(Instance, @Block^.Code);
|
||||
Instance^.Next := InstFreeList;
|
||||
InstFreeList := Instance;
|
||||
Inc(Longint(Instance), SizeOf(TObjectInstance));
|
||||
until Longint(Instance) - Longint(Block) >= SizeOf(TInstanceBlock);
|
||||
InstBlockList := Block;
|
||||
end;
|
||||
Result := InstFreeList;
|
||||
Instance := InstFreeList;
|
||||
InstFreeList := Instance^.Next;
|
||||
Instance^.Method := Method;
|
||||
inc(InstBlockCount);
|
||||
end;
|
||||
|
||||
{ Free an object instance }
|
||||
|
||||
procedure FreeObjectInstance(ObjectInstance: Pointer);
|
||||
begin
|
||||
if (ObjectInstance <> nil) and (InstBlockCount > 0) then
|
||||
begin
|
||||
PObjectInstance(ObjectInstance)^.Next := InstFreeList;
|
||||
InstFreeList := ObjectInstance;
|
||||
Dec(InstBlockCount);
|
||||
if InstBlockCount = 0 then begin
|
||||
VirtualFree(InstBlockList, 0, MEM_RELEASE);
|
||||
InstBlockList := nil;
|
||||
// ObjectInstance := nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
UtilWindowClass: TWndClass = (
|
||||
style: 0;
|
||||
lpfnWndProc: @DefWindowProc;
|
||||
cbClsExtra: 0;
|
||||
cbWndExtra: 0;
|
||||
hInstance: 0;
|
||||
hIcon: 0;
|
||||
hCursor: 0;
|
||||
hbrBackground: 0;
|
||||
lpszMenuName: nil;
|
||||
lpszClassName: 'KOLFakeUtilWindow');
|
||||
|
||||
function AllocateHWnd(Method: TWndMethod): HWND;
|
||||
var
|
||||
TempClass: TWndClass;
|
||||
ClassRegistered: Boolean;
|
||||
begin
|
||||
UtilWindowClass.hInstance := HInstance;
|
||||
ClassRegistered := GetClassInfo(HInstance, UtilWindowClass.lpszClassName,
|
||||
TempClass);
|
||||
if not ClassRegistered or (TempClass.lpfnWndProc <> @DefWindowProc) then
|
||||
begin
|
||||
if ClassRegistered then
|
||||
Windows.UnregisterClass(UtilWindowClass.lpszClassName, HInstance);
|
||||
Windows.RegisterClass(UtilWindowClass);
|
||||
end;
|
||||
Result := CreateWindowEx(WS_EX_TOOLWINDOW, UtilWindowClass.lpszClassName,
|
||||
'', WS_POPUP {!0}, 0, 0, 0, 0, 0, 0, HInstance, nil);
|
||||
if Assigned(Method) then
|
||||
SetWindowLong(Result, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
|
||||
end;
|
||||
|
||||
procedure DeallocateHWnd(Wnd: HWND);
|
||||
var
|
||||
Instance: Pointer;
|
||||
begin
|
||||
Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC));
|
||||
DestroyWindow(Wnd);
|
||||
if Instance <> @DefWindowProc then FreeObjectInstance(Instance);
|
||||
end;
|
||||
|
||||
procedure SplitColor(C: TColor; var r, g, b: integer);
|
||||
begin
|
||||
b := (c and $FF0000) shr 16;
|
||||
g := (c and $00FF00) shr 08;
|
||||
r := (c and $0000FF) shr 00;
|
||||
end;
|
||||
|
||||
procedure AjustBitmap;
|
||||
var i, j: integer;
|
||||
t: KOL.PBitmap;
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r2,
|
||||
g2,
|
||||
b2: integer;
|
||||
p: PRGBTriple;
|
||||
|
||||
function CalcColor(c1, c2, c3: integer): integer;
|
||||
begin
|
||||
if c1 = c3 then begin
|
||||
Result := c2;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if c1 = 0 then begin
|
||||
Result := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Result := 255 * c1 div c3 - c1 * (255 - c1) * (255 - c2) div c3 div (255 - c3);
|
||||
exit;}
|
||||
|
||||
Result := c1 * c2 div c3;
|
||||
if c2 = 0 then Result := c1 * 150 div 255;
|
||||
if Result > 255 then Result := 255;
|
||||
if Result < 50 then Result := Result + 50;
|
||||
{ exit;
|
||||
a := trunc(x1 * 3);
|
||||
a := c1 * (255 - c1) * c2 * (255 - c2) div c3 div (255 - c3);
|
||||
a := 255 * 255 - 4 * a;
|
||||
try
|
||||
x1 := Trunc((255 - sqrt(a)) / 2);
|
||||
x2 := Trunc((255 + sqrt(a)) / 2);
|
||||
if x1 > x2 then Result := Trunc(x1)
|
||||
else Result := Trunc(x2);
|
||||
except
|
||||
Result := 0;
|
||||
end;}
|
||||
end;
|
||||
|
||||
begin
|
||||
if s = c then exit;
|
||||
if m.Width = 0 then exit;
|
||||
if m.Height = 0 then exit;
|
||||
t := NewBitmap(m.Width, m.Height);
|
||||
m.PixelFormat := pf24bit;
|
||||
t.Assign(m);
|
||||
SplitColor(Color2RGB(s), r, g, b);
|
||||
if r = 0 then r := 1;
|
||||
if g = 0 then g := 1;
|
||||
if b = 0 then b := 1;
|
||||
SplitColor(Color2RGB(c), r2, g2, b2);
|
||||
for j := 0 to t.Height - 1 do begin
|
||||
p := t.scanline[j];
|
||||
for i := 0 to t.Width - 1 do begin
|
||||
p.rgbtRed := CalcColor(p.rgbtRed, r2, r);
|
||||
p.rgbtGreen := CalcColor(p.rgbtGreen, g2, g);
|
||||
p.rgbtBlue := CalcColor(p.rgbtBlue, b2, b);
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
m.Assign(t);
|
||||
t.Free;
|
||||
end;
|
||||
|
||||
function IncColor;
|
||||
var T: TColor;
|
||||
P: PRGBTriple;
|
||||
begin
|
||||
T := Color2RGB(C);
|
||||
p := @T;
|
||||
if D > 0 then begin
|
||||
if p.rgbtBlue < 255 - D then p.rgbtBlue := p.rgbtBlue + D else p.rgbtBlue := 255;
|
||||
if p.rgbtRed < 255 - D then p.rgbtRed := p.rgbtRed + D else p.rgbtRed := 255;
|
||||
if p.rgbtGreen < 255 - D then p.rgbtGreen := p.rgbtGreen + D else p.rgbtGreen := 255;
|
||||
end else begin
|
||||
if p.rgbtBlue > D then p.rgbtBlue := p.rgbtBlue - D else p.rgbtBlue := 000;
|
||||
if p.rgbtRed > D then p.rgbtRed := p.rgbtRed - D else p.rgbtRed := 000;
|
||||
if p.rgbtGreen > D then p.rgbtGreen := p.rgbtGreen - D else p.rgbtGreen := 000;
|
||||
end;
|
||||
Result := T;
|
||||
end;
|
||||
|
||||
begin
|
||||
InstBlockList := nil;
|
||||
InstBlockCount := 0;
|
||||
InstFreeList := nil;
|
||||
end.
|
@ -1,74 +0,0 @@
|
||||
unit UBitTreeDecoder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL, URangeDecoder;
|
||||
|
||||
type PBitTreeDecoder = ^TBitTreeDecoder;
|
||||
TBitTreeDecoder=object(TObj)
|
||||
public
|
||||
Models: array of smallint;
|
||||
NumBitLevels:integer;
|
||||
constructor Create(const AnumBitLevels:integer);
|
||||
procedure _Init;
|
||||
function Decode(const ArangeDecoder:PRangeDecoder):integer;
|
||||
function ReverseDecode(const ArangeDecoder:PRangeDecoder):integer;overload;
|
||||
end;
|
||||
|
||||
function ReverseDecode(var AModels: array of smallint; const AstartIndex:integer;const ArangeDecoder:PRangeDecoder; const ANumBitLevels:integer):integer;overload;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TBitTreeDecoder.Create(const AnumBitLevels:integer);
|
||||
begin
|
||||
self.NumBitLevels := AnumBitLevels;
|
||||
setlength(Models,1 shl AnumBitLevels);
|
||||
end;
|
||||
|
||||
procedure TBitTreeDecoder._Init;
|
||||
begin
|
||||
urangedecoder.InitBitModels(Models);
|
||||
end;
|
||||
|
||||
function TBitTreeDecoder.Decode(const ArangeDecoder:PRangeDecoder):integer;
|
||||
var m,bitIndex:integer;
|
||||
begin
|
||||
m:=1;
|
||||
for bitIndex := NumBitLevels downto 1 do begin
|
||||
m:=m shl 1 + ArangeDecoder.DecodeBit(Models, m);
|
||||
end;
|
||||
result:=m - (1 shl NumBitLevels);
|
||||
end;
|
||||
|
||||
function TBitTreeDecoder.ReverseDecode(const ArangeDecoder:PRangeDecoder):integer;
|
||||
var m,symbol,bitindex,bit:integer;
|
||||
begin
|
||||
m:=1;
|
||||
symbol:=0;
|
||||
for bitindex:=0 to numbitlevels-1 do begin
|
||||
bit:=ArangeDecoder.DecodeBit(Models, m);
|
||||
m:=(m shl 1) + bit;
|
||||
symbol:=symbol or (bit shl bitIndex);
|
||||
end;
|
||||
result:=symbol;
|
||||
end;
|
||||
|
||||
function ReverseDecode(var AModels: array of smallint;const AstartIndex:integer;
|
||||
const ArangeDecoder:PRangeDecoder;const ANumBitLevels:integer):integer;
|
||||
var m,symbol,bitindex,bit:integer;
|
||||
begin
|
||||
m:=1;
|
||||
symbol:=0;
|
||||
for bitindex:=0 to ANumBitLevels -1 do begin
|
||||
bit := ArangeDecoder.DecodeBit(AModels, AstartIndex + m);
|
||||
m := (m shl 1) + bit;
|
||||
symbol := symbol or bit shl bitindex;
|
||||
end;
|
||||
result:=symbol;
|
||||
end;
|
||||
|
||||
end.
|
@ -1,116 +0,0 @@
|
||||
unit UBitTreeEncoder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL, URangeDecoder,URangeEncoder;
|
||||
|
||||
type PBitTreeEncoder =^TBitTreeEncoder;
|
||||
TBitTreeEncoder=object(TObj)
|
||||
public
|
||||
Models: array of smallint;
|
||||
NumBitLevels:integer;
|
||||
constructor Create(const AnumBitLevels:integer);
|
||||
procedure _Init;
|
||||
procedure Encode(const ArangeEncoder:PRangeEncoder;const Asymbol:integer);
|
||||
procedure ReverseEncode(const ArangeEncoder:PRangeEncoder;Asymbol:integer);
|
||||
function GetPrice(const Asymbol:integer):integer;
|
||||
function ReverseGetPrice(Asymbol:integer):integer;overload;
|
||||
end;
|
||||
|
||||
procedure ReverseEncode(var AModels:array of smallint;const AstartIndex:integer;const ArangeEncoder:PRangeEncoder;const ANumBitLevels:integer; Asymbol:integer);
|
||||
function ReverseGetPrice(var AModels:array of smallint;const AstartIndex,ANumBitLevels:integer; Asymbol:integer):integer;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TBitTreeEncoder.Create(const AnumBitLevels:integer);
|
||||
begin
|
||||
self.NumBitLevels:=AnumBitLevels;
|
||||
setlength(Models,1 shl AnumBitLevels);
|
||||
end;
|
||||
|
||||
procedure TBitTreeEncoder._Init;
|
||||
begin
|
||||
URangeDecoder.InitBitModels(Models);
|
||||
end;
|
||||
|
||||
procedure TBitTreeEncoder.Encode(const ArangeEncoder:PRangeEncoder;const Asymbol:integer);
|
||||
var m,bitindex,bit:integer;
|
||||
begin
|
||||
m := 1;
|
||||
for bitIndex := NumBitLevels -1 downto 0 do begin
|
||||
bit := (Asymbol shr bitIndex) and 1;
|
||||
ArangeEncoder.Encode(Models, m, bit);
|
||||
m := (m shl 1) or bit;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBitTreeEncoder.ReverseEncode(const ArangeEncoder:PRangeEncoder;Asymbol:integer);
|
||||
var m,i,bit:integer;
|
||||
begin
|
||||
m:=1;
|
||||
for i:= 0 to NumBitLevels -1 do begin
|
||||
bit := Asymbol and 1;
|
||||
ArangeEncoder.Encode(Models, m, bit);
|
||||
m := (m shl 1) or bit;
|
||||
Asymbol := Asymbol shr 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBitTreeEncoder.GetPrice(const Asymbol:integer):integer;
|
||||
var price,m,bitindex,bit:integer;
|
||||
begin
|
||||
price := 0;
|
||||
m := 1;
|
||||
for bitIndex := NumBitLevels - 1 downto 0 do begin
|
||||
bit := (Asymbol shr bitIndex) and 1;
|
||||
price := price + RangeEncoder.GetPrice(Models[m], bit);
|
||||
m := (m shl 1) + bit;
|
||||
end;
|
||||
result:=price;
|
||||
end;
|
||||
|
||||
function TBitTreeEncoder.ReverseGetPrice(Asymbol:integer):integer;
|
||||
var price,m,i,bit:integer;
|
||||
begin
|
||||
price := 0;
|
||||
m := 1;
|
||||
for i:= NumBitLevels downto 1 do begin
|
||||
bit := Asymbol and 1;
|
||||
Asymbol := Asymbol shr 1;
|
||||
price :=price + RangeEncoder.GetPrice(Models[m], bit);
|
||||
m := (m shl 1) or bit;
|
||||
end;
|
||||
result:=price;
|
||||
end;
|
||||
|
||||
function ReverseGetPrice(var AModels:array of smallint;const AstartIndex,ANumBitLevels:integer;Asymbol:integer):integer;
|
||||
var price,m,i,bit:integer;
|
||||
begin
|
||||
price := 0;
|
||||
m := 1;
|
||||
for i := ANumBitLevels downto 1 do begin
|
||||
bit := Asymbol and 1;
|
||||
Asymbol := Asymbol shr 1;
|
||||
price := price + RangeEncoder.GetPrice(AModels[AstartIndex + m], bit);
|
||||
m := (m shl 1) or bit;
|
||||
end;
|
||||
result:=price;
|
||||
end;
|
||||
|
||||
procedure ReverseEncode(var AModels:array of smallint;const AstartIndex:integer;const ArangeEncoder:PRangeEncoder;const ANumBitLevels:integer;Asymbol:integer);
|
||||
var m,i,bit:integer;
|
||||
begin
|
||||
m:=1;
|
||||
for i := 0 to ANumBitLevels -1 do begin
|
||||
bit := Asymbol and 1;
|
||||
ArangeEncoder.Encode(AModels, AstartIndex + m, bit);
|
||||
m := (m shl 1) or bit;
|
||||
Asymbol := Asymbol shr 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
@ -1,174 +0,0 @@
|
||||
unit UBufferedFS;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL;
|
||||
|
||||
type PBufferedFS = PStream;
|
||||
{
|
||||
const BufferSize=$10000;//64K
|
||||
|
||||
type TBFSMode=(BFMRead,BFMWrite);
|
||||
|
||||
TBufferedFS=class(TFileStream)
|
||||
private
|
||||
membuffer:array [0..BufferSize-1] of byte;
|
||||
bytesinbuffer:integer;
|
||||
bufferpos:integer;
|
||||
bufferdirty:boolean;
|
||||
Mode:TBFSMode;
|
||||
procedure _Init;
|
||||
procedure Flush;
|
||||
procedure ReadBuffer;
|
||||
public
|
||||
constructor Create(const FileName: string; Mode: Word); overload;
|
||||
constructor Create(const FileName: string; Mode: Word; Rights: Cardinal); overload;
|
||||
destructor Destroy; override;
|
||||
function Read(var Buffer; Count: Longint): Longint; override;
|
||||
function Write(const Buffer; Count: Longint): Longint; override;
|
||||
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
|
||||
end;
|
||||
|
||||
type TByteArray = array of byte;
|
||||
PByteArray = ^TByteArray;
|
||||
}
|
||||
implementation
|
||||
{
|
||||
function MovePointer(const P:pointer;const dist:integer):pointer;
|
||||
begin
|
||||
result:=pointer(integer(p)+dist);
|
||||
end;
|
||||
|
||||
procedure TBufferedFS.Init;
|
||||
begin
|
||||
bytesinbuffer:=0;
|
||||
bufferpos:=0;
|
||||
bufferdirty:=false;
|
||||
mode:=BFMWrite;
|
||||
end;
|
||||
|
||||
procedure TBufferedFS.Flush;
|
||||
begin
|
||||
if bufferdirty then
|
||||
inherited Write(membuffer[0],bufferpos);
|
||||
bufferdirty:=false;
|
||||
bytesinbuffer:=0;
|
||||
bufferpos:=0;
|
||||
end;
|
||||
|
||||
constructor TBufferedFS.Create(const FileName: string; Mode: Word);
|
||||
begin
|
||||
inherited;
|
||||
init;
|
||||
end;
|
||||
|
||||
constructor TBufferedFS.Create(const FileName: string; Mode: Word; Rights: Cardinal);
|
||||
begin
|
||||
inherited;
|
||||
init;
|
||||
end;
|
||||
|
||||
destructor TBufferedFS.Destroy;
|
||||
begin
|
||||
flush;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TBufferedFS.ReadBuffer;
|
||||
begin
|
||||
flush;
|
||||
bytesinbuffer:=inherited Read(membuffer,buffersize);
|
||||
bufferpos:=0;
|
||||
end;
|
||||
|
||||
function TBufferedFS.Read(var Buffer; Count: Longint): Longint;
|
||||
var p:PByteArray;
|
||||
bytestoread:integer;
|
||||
b:integer;
|
||||
begin
|
||||
if Mode=BFMWrite then flush;
|
||||
mode:=BFMRead;
|
||||
result:=0;
|
||||
if count<=bytesinbuffer then begin
|
||||
//all data already in buffer
|
||||
move(membuffer[bufferpos],buffer,count);
|
||||
bytesinbuffer:=bytesinbuffer-count;
|
||||
bufferpos:=bufferpos+count;
|
||||
result:=count;
|
||||
end else begin
|
||||
bytestoread:=count;
|
||||
if (bytestoread<>0)and(bytesinbuffer<>0) then begin
|
||||
//read data remaining in buffer and increment data pointer
|
||||
b:=Read(buffer,bytesinbuffer);
|
||||
p:=PByteArray(@(TByteArray(buffer)[b]));
|
||||
bytestoread:=bytestoread-b;
|
||||
result:=b;
|
||||
end else p:=@buffer;
|
||||
if bytestoread>=BufferSize then begin
|
||||
//data to read is larger than the buffer, read it directly
|
||||
result:=result+inherited Read(p^,bytestoread);
|
||||
end else begin
|
||||
//refill buffer
|
||||
ReadBuffer;
|
||||
//recurse
|
||||
result:=result+Read(p^,math.Min(bytestoread,bytesinbuffer));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBufferedFS.Write(const Buffer; Count: Longint): Longint;
|
||||
var p:pointer;
|
||||
bytestowrite:integer;
|
||||
b:integer;
|
||||
begin
|
||||
if mode=BFMRead then begin
|
||||
seek(-BufferSize+bufferpos,soFromCurrent);
|
||||
bytesinbuffer:=0;
|
||||
bufferpos:=0;
|
||||
end;
|
||||
mode:=BFMWrite;
|
||||
result:=0;
|
||||
if count<=BufferSize-bytesinbuffer then begin
|
||||
//all data fits in buffer
|
||||
bufferdirty:=true;
|
||||
move(buffer,membuffer[bufferpos],count);
|
||||
bytesinbuffer:=bytesinbuffer+count;
|
||||
bufferpos:=bufferpos+count;
|
||||
result:=count;
|
||||
end else begin
|
||||
bytestowrite:=count;
|
||||
if (bytestowrite<>0)and(bytesinbuffer<>BufferSize)and(bytesinbuffer<>0) then begin
|
||||
//write data to remaining space in buffer and increment data pointer
|
||||
b:=Write(buffer,BufferSize-bytesinbuffer);
|
||||
p:=MovePointer(@buffer,b);
|
||||
bytestowrite:=bytestowrite-b;
|
||||
result:=b;
|
||||
end else p:=@buffer;
|
||||
if bytestowrite>=BufferSize then begin
|
||||
//empty buffer
|
||||
Flush;
|
||||
//data to write is larger than the buffer, write it directly
|
||||
result:=result+inherited Write(p^,bytestowrite);
|
||||
end else begin
|
||||
//empty buffer
|
||||
Flush;
|
||||
//recurse
|
||||
result:=result+Write(p^,bytestowrite);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBufferedFS.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
|
||||
begin
|
||||
if (Origin=soCurrent)and(Offset=0) then result:=inherited seek(Offset,origin)+bufferpos
|
||||
else begin
|
||||
flush;
|
||||
result:=inherited Seek(offset,origin);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
end.
|
130
Addons/UDig.pas
130
Addons/UDig.pas
@ -1,130 +0,0 @@
|
||||
unit UDig;
|
||||
|
||||
interface
|
||||
|
||||
function stri (n,n1:integer;zero,trim:boolean):string;
|
||||
function strL (n: longint; n1 :integer):string;
|
||||
|
||||
{function strr(n:real;n1,n2:word):string;
|
||||
function strH (w : longint; c : word) : string;}
|
||||
function strhl(w : longint; c : word) : string;
|
||||
function hexi(s:string):word;
|
||||
function hexl(s:string):longint;
|
||||
function inti(s:string):word;
|
||||
{function intl(s:string):longint; }
|
||||
|
||||
implementation
|
||||
|
||||
uses UWrd, UStr;
|
||||
|
||||
function atrim(s : string) : string;
|
||||
var t : string;
|
||||
begin
|
||||
t := s;
|
||||
while (t[1] = ' ') and (length(t) > 0) do t := copy(t, 2, 255);
|
||||
while (t[length(t)] = ' ') and (length(t) > 0) do t := copy(t, 1, length(t) - 1);
|
||||
atrim := t;
|
||||
end;
|
||||
|
||||
{
|
||||
function strh;
|
||||
const a:array[0..15] of cHar =
|
||||
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
|
||||
var r:string;
|
||||
begin
|
||||
if c>0 then r:=strh(w div 16,c-1)+a[w mod 16]
|
||||
else r:='';
|
||||
strH := r;
|
||||
end;
|
||||
}
|
||||
function strhl;
|
||||
const a:array[0..15] of cHar =
|
||||
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
|
||||
var r:string;
|
||||
begin
|
||||
if c > 0 then
|
||||
if w mod 16 >= 0 tHen r := strhl(w sHr 4, c - 1) + a[ w mod 16] else
|
||||
r := strHl(w sHr 4, c - 1) + a[16 + w mod 16]
|
||||
else r := '';
|
||||
strHl := r;
|
||||
end;
|
||||
|
||||
function hexi;
|
||||
const a : string[15] ='123456789ABCDEF';
|
||||
var i : integer;
|
||||
h :word;
|
||||
begin
|
||||
h:=0;
|
||||
for i:=1 to length(s) do begin
|
||||
if S[i]<>' ' then begin
|
||||
h:=h shl 4;
|
||||
h:=h+pos(UpCase(S[i]),a);
|
||||
end;
|
||||
end;
|
||||
hexi:=h;
|
||||
end;
|
||||
|
||||
function hexl;
|
||||
const a : string[15] ='123456789ABCDEF';
|
||||
var i : integer;
|
||||
h :longint;
|
||||
begin
|
||||
h:=0;
|
||||
for i:=1 to length(s) do begin
|
||||
if S[i]<>' ' then begin
|
||||
h:=h shl 4;
|
||||
h:=h+pos(UpCase(S[i]),a);
|
||||
end;
|
||||
end;
|
||||
hexl:=h;
|
||||
end;
|
||||
|
||||
function inti;
|
||||
var
|
||||
rc : integer;
|
||||
ww : longint;
|
||||
begin
|
||||
val(s, ww, rc);
|
||||
inti := ww;
|
||||
end;
|
||||
{
|
||||
function intl;
|
||||
var
|
||||
rc : integer;
|
||||
ww : integer;
|
||||
begin
|
||||
val(s, ww, rc);
|
||||
intl := ww;
|
||||
end;
|
||||
}
|
||||
|
||||
function stri;
|
||||
var s : string;
|
||||
i : integer;
|
||||
begin
|
||||
str(n: n1, s);
|
||||
if zero THen begin
|
||||
for i := 1 to lengtH(s) do
|
||||
if s[i] = ' ' THen s[i] := '0';
|
||||
end;
|
||||
if trim then s := atrim(s);
|
||||
stri := s;
|
||||
end;
|
||||
|
||||
function strl;
|
||||
var s:string;
|
||||
begin
|
||||
str(n:n1,s);
|
||||
strl:=s;
|
||||
end;
|
||||
|
||||
{
|
||||
function strr;
|
||||
var s:string;
|
||||
begin
|
||||
str(n:n1:n2,s);
|
||||
strr:=s;
|
||||
end;
|
||||
}
|
||||
|
||||
end.
|
@ -1,99 +0,0 @@
|
||||
unit UFor;
|
||||
|
||||
interface
|
||||
|
||||
function points(d : boolean; t : string; m : integer): string;
|
||||
function toreal(r : string): real;
|
||||
function rtostr(r : real): string;
|
||||
function plslop(o, c: string; back, buys: boolean): string;
|
||||
function plslom(o, c: string; back, buys: boolean; size, amnt, intr: string): string;
|
||||
function chkprc(o, c, q, b: string): boolean;
|
||||
|
||||
implementation
|
||||
uses SysUtils;
|
||||
|
||||
function points;
|
||||
var s : string;
|
||||
p,
|
||||
i,
|
||||
e : integer;
|
||||
begin
|
||||
s := t;
|
||||
if pos('.', s) = 0 then s := s + '.';
|
||||
while length(s) < 6 do s := s + '0';
|
||||
p := pos('.', s);
|
||||
s := copy(s, 1, p - 1) + copy(s, p + 1, 6 - p);
|
||||
val(s, i, e);
|
||||
if d then inc(i, m) else dec(i, m);
|
||||
s := inttostr(i);
|
||||
while length(s) < 5 do s := '0' + s;
|
||||
s := copy(s, 1, p - 1) + '.' + copy(s, p, 6 - p);
|
||||
points := s;
|
||||
end;
|
||||
|
||||
function toreal(r: string): real;
|
||||
var f : real;
|
||||
i : integer;
|
||||
s : string;
|
||||
begin
|
||||
S := R;
|
||||
val(trim(S), F, I);
|
||||
if (i > 0) and (I < length(S)) then begin
|
||||
if S[I] = '.' then S[I] := ',' else
|
||||
if S[I] = ',' then S[i] := '.';
|
||||
val(trim(S), F, I);
|
||||
end;
|
||||
result := F;
|
||||
end;
|
||||
|
||||
function rtostr;
|
||||
var s : string;
|
||||
begin
|
||||
str(r:5:2, s);
|
||||
rtostr := s;
|
||||
end;
|
||||
|
||||
function plslop;
|
||||
var op,
|
||||
cl : real;
|
||||
j : integer;
|
||||
begin
|
||||
op := toreal(o);
|
||||
cl := toreal(c);
|
||||
repeat
|
||||
op := op * 10;
|
||||
cl := cl * 10;
|
||||
until op > 3000;
|
||||
j := round(cl - op);
|
||||
if back xor buys then j := -j;
|
||||
plslop := inttostr(j);
|
||||
end;
|
||||
|
||||
function plslom;
|
||||
var op, cl: real;
|
||||
dd: real;
|
||||
begin
|
||||
plslom := '0';
|
||||
op := toreal(o);
|
||||
cl := toreal(c);
|
||||
if (op = 0) or (cl = 0) then exit;
|
||||
if back then dd := cl - op
|
||||
else dd := 1/op - 1/cl;
|
||||
dd := dd * toreal(size);
|
||||
if back xor buys then dd := -dd;
|
||||
dd := dd * strtoint(amnt) - toreal(intr);
|
||||
plslom := rtostr(dd);
|
||||
end;
|
||||
|
||||
function chkprc;
|
||||
var op, cl: real;
|
||||
bk, sb: boolean;
|
||||
begin
|
||||
op := toreal(o);
|
||||
cl := toreal(c);
|
||||
bk := (q = 'EUR') or (q = 'GBP');
|
||||
sb := (b = 'Buy');
|
||||
chkprc := (op >= cl) xor (bk xor sb);
|
||||
end;
|
||||
|
||||
end.
|
@ -1,420 +0,0 @@
|
||||
unit ULZBinTree;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses ULZInWindow, KOL;
|
||||
|
||||
type
|
||||
TArrayOfInteger = array [0..0] of Integer;
|
||||
PArrayOfInteger = ^TArrayOfInteger;
|
||||
|
||||
type PLZBinTree = ^TLZBinTree;
|
||||
TLZBinTree = object(TLZInWindow)
|
||||
public
|
||||
cyclicBufferPos:integer;
|
||||
cyclicBufferSize:integer;
|
||||
matchMaxLen:integer;
|
||||
|
||||
son: PArrayOfInteger;//array of integer;
|
||||
hash: array of integer;
|
||||
|
||||
cutValue:integer;
|
||||
hashMask:integer;
|
||||
hashSizeSum:integer;
|
||||
|
||||
HASH_ARRAY:boolean;
|
||||
|
||||
|
||||
kNumHashDirectBytes:integer;
|
||||
kMinMatchCheck:integer;
|
||||
kFixHashSize:integer;
|
||||
constructor Create;
|
||||
procedure SetType(const AnumHashBytes:integer);
|
||||
procedure _Init;virtual;
|
||||
procedure MovePos;virtual;
|
||||
function _Create(const AhistorySize,AkeepAddBufferBefore,AmatchMaxLen,AkeepAddBufferAfter:integer):boolean;
|
||||
function GetMatches(var Adistances:array of integer):integer;
|
||||
procedure Skip(Anum:integer);
|
||||
procedure NormalizeLinks(var Aitems:array of integer;const AnumItems,AsubValue:integer);
|
||||
procedure Normalize;
|
||||
procedure SetCutValue(const AcutValue:integer);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const kHash2Size = 1 shl 10;
|
||||
kHash3Size = 1 shl 16;
|
||||
kBT2HashSize = 1 shl 16;
|
||||
kStartMaxLen = 1;
|
||||
kHash3Offset = kHash2Size;
|
||||
kEmptyHashValue = 0;
|
||||
kMaxValForNormalize = (1 shl 30) - 1;
|
||||
|
||||
var CRCTable: array [0..255] of integer;
|
||||
|
||||
constructor TLZBinTree.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
cyclicBufferSize:=0;
|
||||
cutValue:=$FF;
|
||||
hashSizeSum:=0;
|
||||
HASH_ARRAY:=true;
|
||||
kNumHashDirectBytes:=0;
|
||||
kMinMatchCheck:=4;
|
||||
kFixHashsize:=kHash2Size + kHash3Size;
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.SetType(const AnumHashBytes:integer);
|
||||
begin
|
||||
HASH_ARRAY := (AnumHashBytes > 2);
|
||||
if HASH_ARRAY then begin
|
||||
kNumHashDirectBytes := 0;
|
||||
kMinMatchCheck := 4;
|
||||
kFixHashSize := kHash2Size + kHash3Size;
|
||||
end
|
||||
else begin
|
||||
kNumHashDirectBytes := 2;
|
||||
kMinMatchCheck := 2 + 1;
|
||||
kFixHashSize := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZBinTree._Init;
|
||||
var i:integer;
|
||||
begin
|
||||
inherited _init;
|
||||
for i := 0 to hashSizeSum - 1 do
|
||||
hash[i] := kEmptyHashValue;
|
||||
cyclicBufferPos := 0;
|
||||
ReduceOffsets(-1);
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.MovePos;
|
||||
begin
|
||||
inc(cyclicBufferPos);
|
||||
if cyclicBufferPos >= cyclicBufferSize then
|
||||
cyclicBufferPos := 0;
|
||||
inherited MovePos;
|
||||
if pos = kMaxValForNormalize then
|
||||
Normalize;
|
||||
end;
|
||||
|
||||
function TLZBinTree._Create(const AhistorySize,AkeepAddBufferBefore,AmatchMaxLen,AkeepAddBufferAfter:integer):boolean;
|
||||
var windowReservSize:integer;
|
||||
_cyclicBufferSize:integer;
|
||||
hs:integer;
|
||||
begin
|
||||
if (AhistorySize > kMaxValForNormalize - 256) then begin
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
cutValue := 16 + (AmatchMaxLen shr 1);
|
||||
|
||||
windowReservSize := (AhistorySize + AkeepAddBufferBefore + AmatchMaxLen + AkeepAddBufferAfter) div 2 + 256;
|
||||
|
||||
inherited _Create(AhistorySize + AkeepAddBufferBefore, AmatchMaxLen + AkeepAddBufferAfter, windowReservSize);
|
||||
|
||||
self.matchMaxLen := AmatchMaxLen;
|
||||
|
||||
_cyclicBufferSize := AhistorySize + 1;
|
||||
if self.cyclicBufferSize <> _cyclicBufferSize then begin
|
||||
self.cyclicBufferSize:=_cyclicBufferSize;
|
||||
son:= AllocMem(_cyclicBufferSize * 2);
|
||||
// GetMem(son,_cyclicBufferSize * 2);
|
||||
// setlength(son,_cyclicBufferSize * 2);
|
||||
end;
|
||||
|
||||
hs := kBT2HashSize;
|
||||
|
||||
if HASH_ARRAY then begin
|
||||
hs := AhistorySize - 1;
|
||||
hs := hs or (hs shr 1);
|
||||
hs := hs or (hs shr 2);
|
||||
hs := hs or (hs shr 4);
|
||||
hs := hs or (hs shr 8);
|
||||
hs := hs shr 1;
|
||||
hs := hs or $FFFF;
|
||||
if (hs > (1 shl 24)) then
|
||||
hs := hs shr 1;
|
||||
hashMask := hs;
|
||||
inc(hs);
|
||||
hs := hs + kFixHashSize;
|
||||
end;
|
||||
if (hs <> hashSizeSum) then begin
|
||||
hashSizeSum := hs;
|
||||
setlength(hash,hashSizeSum);
|
||||
end;
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
function TLZBinTree.GetMatches(var Adistances:array of integer):integer;
|
||||
var lenLimit:integer;
|
||||
offset,matchMinPos,cur,maxlen,hashvalue,hash2value,hash3value:integer;
|
||||
temp,curmatch,curmatch2,curmatch3,ptr0,ptr1,len0,len1,count:integer;
|
||||
delta,cyclicpos,pby1,len:integer;
|
||||
begin
|
||||
if pos + matchMaxLen <= streamPos then
|
||||
lenLimit := matchMaxLen
|
||||
else begin
|
||||
lenLimit := streamPos - pos;
|
||||
if lenLimit < kMinMatchCheck then begin
|
||||
MovePos();
|
||||
result:=0;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
offset := 0;
|
||||
if (pos > cyclicBufferSize) then
|
||||
matchMinPos:=(pos - cyclicBufferSize)
|
||||
else matchMinPos:=0;
|
||||
cur := bufferOffset + pos;
|
||||
maxLen := kStartMaxLen; // to avoid items for len < hashSize;
|
||||
hash2Value := 0;
|
||||
hash3Value := 0;
|
||||
|
||||
if HASH_ARRAY then begin
|
||||
temp := CrcTable[bufferBase[cur] and $FF] xor (bufferBase[cur + 1] and $FF);
|
||||
hash2Value := temp and (kHash2Size - 1);
|
||||
temp := temp xor ((bufferBase[cur + 2] and $FF) shl 8);
|
||||
hash3Value := temp and (kHash3Size - 1);
|
||||
hashValue := (temp xor (CrcTable[bufferBase[cur + 3] and $FF] shl 5)) and hashMask;
|
||||
end else
|
||||
hashValue := ((bufferBase[cur] and $FF) xor ((bufferBase[cur + 1] and $FF) shl 8));
|
||||
|
||||
curMatch := hash[kFixHashSize + hashValue];
|
||||
if HASH_ARRAY then begin
|
||||
curMatch2 := hash[hash2Value];
|
||||
curMatch3 := hash[kHash3Offset + hash3Value];
|
||||
hash[hash2Value] := pos;
|
||||
hash[kHash3Offset + hash3Value] := pos;
|
||||
if curMatch2 > matchMinPos then
|
||||
if bufferBase[bufferOffset + curMatch2] = bufferBase[cur] then begin
|
||||
maxLen := 2;
|
||||
Adistances[offset] := maxLen;
|
||||
inc(offset);
|
||||
Adistances[offset] := pos - curMatch2 - 1;
|
||||
inc(offset);
|
||||
end;
|
||||
if curMatch3 > matchMinPos then
|
||||
if bufferBase[bufferOffset + curMatch3] = bufferBase[cur] then begin
|
||||
if curMatch3 = curMatch2 then
|
||||
offset := offset - 2;
|
||||
maxLen := 3;
|
||||
Adistances[offset] := maxlen;
|
||||
inc(offset);
|
||||
Adistances[offset] := pos - curMatch3 - 1;
|
||||
inc(offset);
|
||||
curMatch2 := curMatch3;
|
||||
end;
|
||||
if (offset <> 0) and (curMatch2 = curMatch) then begin
|
||||
offset := offset - 2;
|
||||
maxLen := kStartMaxLen;
|
||||
end;
|
||||
end;
|
||||
|
||||
hash[kFixHashSize + hashValue] := pos;
|
||||
|
||||
ptr0 := (cyclicBufferPos shl 1) + 1;
|
||||
ptr1 := (cyclicBufferPos shl 1);
|
||||
|
||||
len0 := kNumHashDirectBytes;
|
||||
len1 := len0;
|
||||
|
||||
if kNumHashDirectBytes <> 0 then begin
|
||||
if (curMatch > matchMinPos) then begin
|
||||
if (bufferBase[bufferOffset + curMatch + kNumHashDirectBytes] <> bufferBase[cur + kNumHashDirectBytes]) then begin
|
||||
maxLen := kNumHashDirectBytes;
|
||||
Adistances[offset] := maxLen;
|
||||
inc(offset);
|
||||
Adistances[offset] := pos - curMatch - 1;
|
||||
inc(offset);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
count := cutValue;
|
||||
|
||||
while (true) do begin
|
||||
if (curMatch <= matchMinPos) or (count = 0) then begin
|
||||
son[ptr1] := kEmptyHashValue;
|
||||
son[ptr0] := son[ptr1];
|
||||
break;
|
||||
end;
|
||||
dec(count);
|
||||
delta := pos - curMatch;
|
||||
if delta<=cyclicBufferPos then
|
||||
cyclicpos:=(cyclicBufferPos - delta) shl 1
|
||||
else cyclicpos:=(cyclicBufferPos - delta + cyclicBufferSize) shl 1;
|
||||
|
||||
pby1 := bufferOffset + curMatch;
|
||||
len := min(len0, len1);
|
||||
if bufferBase[pby1 + len] = bufferBase[cur + len] then begin
|
||||
inc(len);
|
||||
while (len <> lenLimit) do begin
|
||||
if (bufferBase[pby1 + len] <> bufferBase[cur + len]) then
|
||||
break;
|
||||
inc(len);
|
||||
end;
|
||||
if maxLen < len then begin
|
||||
maxLen := len;
|
||||
Adistances[offset] := maxlen;
|
||||
inc(offset);
|
||||
Adistances[offset] := delta - 1;
|
||||
inc(offset);
|
||||
if (len = lenLimit) then begin
|
||||
son[ptr1] := son[cyclicPos];
|
||||
son[ptr0] := son[cyclicPos + 1];
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (bufferBase[pby1 + len] and $FF) < (bufferBase[cur + len] and $FF) then begin
|
||||
son[ptr1] := curMatch;
|
||||
ptr1 := cyclicPos + 1;
|
||||
curMatch := son[ptr1];
|
||||
len1 := len;
|
||||
end else begin
|
||||
son[ptr0] := curMatch;
|
||||
ptr0 := cyclicPos;
|
||||
curMatch := son[ptr0];
|
||||
len0 := len;
|
||||
end;
|
||||
end;
|
||||
MovePos;
|
||||
result:=offset;
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.Skip(Anum:integer);
|
||||
var lenLimit,matchminpos,cur,hashvalue,temp,hash2value,hash3value,curMatch:integer;
|
||||
ptr0,ptr1,len,len0,len1,count,delta,cyclicpos,pby1:integer;
|
||||
begin
|
||||
repeat
|
||||
if pos + matchMaxLen <= streamPos then
|
||||
lenLimit := matchMaxLen
|
||||
else begin
|
||||
lenLimit := streamPos - pos;
|
||||
if lenLimit < kMinMatchCheck then begin
|
||||
MovePos();
|
||||
dec(Anum);
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
if pos>cyclicBufferSize then
|
||||
matchminpos:=(pos - cyclicBufferSize)
|
||||
else matchminpos:=0;
|
||||
cur := bufferOffset + pos;
|
||||
|
||||
if HASH_ARRAY then begin
|
||||
temp := CrcTable[bufferBase[cur] and $FF] xor (bufferBase[cur + 1] and $FF);
|
||||
hash2Value := temp and (kHash2Size - 1);
|
||||
hash[hash2Value] := pos;
|
||||
temp := temp xor ((bufferBase[cur + 2] and $FF) shl 8);
|
||||
hash3Value := temp and (kHash3Size - 1);
|
||||
hash[kHash3Offset + hash3Value] := pos;
|
||||
hashValue := (temp xor (CrcTable[bufferBase[cur + 3] and $FF] shl 5)) and hashMask;
|
||||
end else
|
||||
hashValue := ((bufferBase[cur] and $FF) xor ((bufferBase[cur + 1] and $FF) shl 8));
|
||||
|
||||
curMatch := hash[kFixHashSize + hashValue];
|
||||
hash[kFixHashSize + hashValue] := pos;
|
||||
|
||||
ptr0 := (cyclicBufferPos shl 1) + 1;
|
||||
ptr1 := (cyclicBufferPos shl 1);
|
||||
|
||||
len0 := kNumHashDirectBytes;
|
||||
len1 := kNumHashDirectBytes;
|
||||
|
||||
count := cutValue;
|
||||
while true do begin
|
||||
if (curMatch <= matchMinPos) or (count = 0) then begin
|
||||
son[ptr1] := kEmptyHashValue;
|
||||
son[ptr0] := son[ptr1];
|
||||
break;
|
||||
end else dec(count);
|
||||
|
||||
delta := pos - curMatch;
|
||||
if (delta <= cyclicBufferPos) then
|
||||
cyclicpos:=(cyclicBufferPos - delta) shl 1
|
||||
else cyclicpos:=(cyclicBufferPos - delta + cyclicBufferSize) shl 1;
|
||||
|
||||
pby1 := bufferOffset + curMatch;
|
||||
len := min(len0, len1);
|
||||
if bufferBase[pby1 + len] = bufferBase[cur + len] then begin
|
||||
inc(len);
|
||||
while (len <> lenLimit) do begin
|
||||
if bufferBase[pby1 + len] <> bufferBase[cur + len] then
|
||||
break;
|
||||
inc(len);
|
||||
end;
|
||||
if len = lenLimit then begin
|
||||
son[ptr1] := son[cyclicPos];
|
||||
son[ptr0] := son[cyclicPos + 1];
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if ((bufferBase[pby1 + len] and $FF) < (bufferBase[cur + len] and $FF)) then begin
|
||||
son[ptr1] := curMatch;
|
||||
ptr1 := cyclicPos + 1;
|
||||
curMatch := son[ptr1];
|
||||
len1 := len;
|
||||
end else begin
|
||||
son[ptr0] := curMatch;
|
||||
ptr0 := cyclicPos;
|
||||
curMatch := son[ptr0];
|
||||
len0 := len;
|
||||
end;
|
||||
end;
|
||||
MovePos;
|
||||
dec(Anum);
|
||||
until Anum=0;
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.NormalizeLinks(var Aitems:array of integer;const AnumItems,AsubValue:integer);
|
||||
var i,value:integer;
|
||||
begin
|
||||
for i:=0 to AnumItems-1 do begin
|
||||
value := Aitems[i];
|
||||
if value <= AsubValue then
|
||||
value := kEmptyHashValue
|
||||
else value := value - AsubValue;
|
||||
Aitems[i] := value;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.Normalize;
|
||||
var subvalue:integer;
|
||||
begin
|
||||
subValue := pos - cyclicBufferSize;
|
||||
NormalizeLinks(son^, cyclicBufferSize * 2, subValue);
|
||||
NormalizeLinks(hash, hashSizeSum, subValue);
|
||||
ReduceOffsets(subValue);
|
||||
end;
|
||||
|
||||
procedure TLZBinTree.SetCutValue(const Acutvalue:integer);
|
||||
begin
|
||||
self.cutValue:=Acutvalue;
|
||||
end;
|
||||
|
||||
procedure InitCRC;
|
||||
var i,r,j:integer;
|
||||
begin
|
||||
for i := 0 to 255 do begin
|
||||
r := i;
|
||||
for j := 0 to 7 do
|
||||
if ((r and 1) <> 0) then
|
||||
r := (r shr 1) xor integer($EDB88320)
|
||||
else
|
||||
r := r shr 1;
|
||||
CrcTable[i] := r;
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
InitCRC;
|
||||
end.
|
@ -1,170 +0,0 @@
|
||||
unit ULZInWindow;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL;
|
||||
|
||||
type TLZInWindow= object(TObj)
|
||||
public
|
||||
bufferBase: array of byte;// pointer to buffer with data
|
||||
stream:PStream;
|
||||
posLimit:integer; // offset (from _buffer) of first byte when new block reading must be done
|
||||
streamEndWasReached:boolean; // if (true) then _streamPos shows real end of stream
|
||||
|
||||
pointerToLastSafePosition:integer;
|
||||
|
||||
bufferOffset:integer;
|
||||
|
||||
blockSize:integer; // Size of Allocated memory block
|
||||
pos:integer; // offset (from _buffer) of curent byte
|
||||
keepSizeBefore:integer; // how many BYTEs must be kept in buffer before _pos
|
||||
keepSizeAfter:integer; // how many BYTEs must be kept buffer after _pos
|
||||
streamPos:integer; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
procedure MoveBlock;
|
||||
procedure ReadBlock;
|
||||
procedure _Free;
|
||||
procedure _Create(const AkeepSizeBefore, AkeepSizeAfter, AkeepSizeReserv:integer);
|
||||
procedure SetStream(const Astream:PStream);
|
||||
procedure ReleaseStream;
|
||||
procedure _Init;virtual;
|
||||
procedure MovePos;virtual;
|
||||
function GetIndexByte(const Aindex:integer):byte;
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
function GetMatchLen(const Aindex:integer;Adistance,Alimit:integer):integer;
|
||||
function GetNumAvailableBytes:integer;
|
||||
procedure ReduceOffsets(const AsubValue:integer);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TLZInWindow.MoveBlock;
|
||||
var offset,numbytes,i:integer;
|
||||
begin
|
||||
offset := bufferOffset + pos - keepSizeBefore;
|
||||
// we need one additional byte, since MovePos moves on 1 byte.
|
||||
if (offset > 0) then
|
||||
dec(offset);
|
||||
|
||||
numBytes := bufferOffset + streamPos - offset;
|
||||
|
||||
// check negative offset ????
|
||||
for i := 0 to numBytes -1 do
|
||||
bufferBase[i] := bufferBase[offset + i];
|
||||
bufferOffset := bufferOffset - offset;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow.ReadBlock;
|
||||
var size,numreadbytes,pointerToPostion:integer;
|
||||
begin
|
||||
if streamEndWasReached then
|
||||
exit;
|
||||
while (true) do begin
|
||||
size := (0 - bufferOffset) + blockSize - streamPos;
|
||||
if size = 0 then
|
||||
exit;
|
||||
numReadBytes := stream.Read(bufferBase[bufferOffset + streamPos], size);
|
||||
if (numReadBytes = 0) then begin
|
||||
posLimit := streamPos;
|
||||
pointerToPostion := bufferOffset + posLimit;
|
||||
if (pointerToPostion > pointerToLastSafePosition) then
|
||||
posLimit := pointerToLastSafePosition - bufferOffset;
|
||||
streamEndWasReached := true;
|
||||
exit;
|
||||
end;
|
||||
streamPos := streamPos + numReadBytes;
|
||||
if (streamPos >= pos + keepSizeAfter) then
|
||||
posLimit := streamPos - keepSizeAfter;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow._Free;
|
||||
begin
|
||||
setlength(bufferBase,0);
|
||||
end;
|
||||
|
||||
procedure TLZInWindow._Create(const AkeepSizeBefore, AkeepSizeAfter, AkeepSizeReserv:integer);
|
||||
var _blocksize:integer;
|
||||
begin
|
||||
self.keepSizeBefore := AkeepSizeBefore;
|
||||
self.keepSizeAfter := AkeepSizeAfter;
|
||||
_blocksize := AkeepSizeBefore + AkeepSizeAfter + AkeepSizeReserv;
|
||||
if (length(bufferBase) = 0) or (self.blockSize <> _blocksize) then begin
|
||||
_Free;
|
||||
self.blockSize := _blocksize;
|
||||
setlength(bufferBase,self.blockSize);
|
||||
end;
|
||||
pointerToLastSafePosition := self.blockSize - AkeepSizeAfter;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow.SetStream(const Astream:PStream);
|
||||
begin
|
||||
self.stream:=Astream;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow.ReleaseStream;
|
||||
begin
|
||||
stream:=nil;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow._Init;
|
||||
begin
|
||||
bufferOffset := 0;
|
||||
pos := 0;
|
||||
streamPos := 0;
|
||||
streamEndWasReached := false;
|
||||
ReadBlock;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow.MovePos;
|
||||
var pointerToPostion:integer;
|
||||
begin
|
||||
inc(pos);
|
||||
if pos > posLimit then begin
|
||||
pointerToPostion := bufferOffset + pos;
|
||||
if pointerToPostion > pointerToLastSafePosition then
|
||||
MoveBlock;
|
||||
ReadBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLZInWindow.GetIndexByte(const Aindex:integer):byte;
|
||||
begin
|
||||
result:=bufferBase[bufferOffset + pos + Aindex];
|
||||
end;
|
||||
|
||||
function TLZInWindow.GetMatchLen(const Aindex:integer;Adistance,Alimit:integer):integer;
|
||||
var pby,i:integer;
|
||||
begin
|
||||
if streamEndWasReached then
|
||||
if (pos + Aindex) + Alimit > streamPos then
|
||||
Alimit := streamPos - (pos + Aindex);
|
||||
inc(Adistance);
|
||||
// Byte *pby = _buffer + (size_t)_pos + Aindex;
|
||||
pby := bufferOffset + pos + Aindex;
|
||||
|
||||
i:=0;
|
||||
while (i<Alimit)and(bufferBase[pby + i] = bufferBase[pby + i - Adistance]) do begin
|
||||
inc(i);
|
||||
end;
|
||||
result:=i;
|
||||
end;
|
||||
|
||||
function TLZInWindow.GetNumAvailableBytes:integer;
|
||||
begin
|
||||
result:=streamPos - pos;
|
||||
end;
|
||||
|
||||
procedure TLZInWindow.ReduceOffsets(const Asubvalue:integer);
|
||||
begin
|
||||
bufferOffset := bufferOffset + Asubvalue;
|
||||
posLimit := posLimit - Asubvalue;
|
||||
pos := pos - Asubvalue;
|
||||
streamPos := streamPos - Asubvalue;
|
||||
end;
|
||||
|
||||
end.
|
@ -1,104 +0,0 @@
|
||||
unit ULZMABase;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
function StateInit:integer;
|
||||
function StateUpdateChar(const index:integer):integer;
|
||||
function StateUpdateMatch(const index:integer):integer;
|
||||
function StateUpdateRep(const index:integer):integer;
|
||||
function StateUpdateShortRep(const index:integer):integer;
|
||||
function StateIsCharState(const index:integer):boolean;
|
||||
function GetLenToPosState(len:integer):integer;
|
||||
|
||||
const kNumRepDistances = 4;
|
||||
kNumStates = 12;
|
||||
kNumPosSlotBits = 6;
|
||||
kDicLogSizeMin = 0;
|
||||
// kDicLogSizeMax = 28;
|
||||
// kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
kNumLenToPosStatesBits = 2; // it's for speed optimization
|
||||
kNumLenToPosStates = 1 shl kNumLenToPosStatesBits;
|
||||
|
||||
kMatchMinLen = 2;
|
||||
|
||||
kNumAlignBits = 4;
|
||||
kAlignTableSize = 1 shl kNumAlignBits;
|
||||
kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
kStartPosModelIndex = 4;
|
||||
kEndPosModelIndex = 14;
|
||||
kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
kNumFullDistances = 1 shl (kEndPosModelIndex div 2);
|
||||
|
||||
kNumLitPosStatesBitsEncodingMax = 4;
|
||||
kNumLitContextBitsMax = 8;
|
||||
|
||||
kNumPosStatesBitsMax = 4;
|
||||
kNumPosStatesMax = (1 shl kNumPosStatesBitsMax);
|
||||
kNumPosStatesBitsEncodingMax = 4;
|
||||
kNumPosStatesEncodingMax = (1 shl kNumPosStatesBitsEncodingMax);
|
||||
|
||||
kNumLowLenBits = 3;
|
||||
kNumMidLenBits = 3;
|
||||
kNumHighLenBits = 8;
|
||||
kNumLowLenSymbols = 1 shl kNumLowLenBits;
|
||||
kNumMidLenSymbols = 1 shl kNumMidLenBits;
|
||||
kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + (1 shl kNumHighLenBits);
|
||||
kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
|
||||
|
||||
implementation
|
||||
|
||||
function StateInit:integer;
|
||||
begin
|
||||
result:=0;
|
||||
end;
|
||||
|
||||
function StateUpdateChar(const index:integer):integer;
|
||||
begin
|
||||
if (index < 4) then
|
||||
result:=0
|
||||
else
|
||||
if (index < 10) then
|
||||
result:=index - 3
|
||||
else
|
||||
result:=index - 6;
|
||||
end;
|
||||
|
||||
function StateUpdateMatch(const index:integer):integer;
|
||||
begin
|
||||
if index<7 then result:=7
|
||||
else result:=10;
|
||||
end;
|
||||
|
||||
function StateUpdateRep(const index:integer):integer;
|
||||
begin
|
||||
if index<7 then result:=8
|
||||
else result:=11;
|
||||
end;
|
||||
|
||||
function StateUpdateShortRep(const index:integer):integer;
|
||||
begin
|
||||
if index<7 then result:=9
|
||||
else result:=11;
|
||||
end;
|
||||
|
||||
function StateIsCharState(const index:integer):boolean;
|
||||
begin
|
||||
result:=index<7;
|
||||
end;
|
||||
|
||||
function GetLenToPosState(len:integer):integer;
|
||||
begin
|
||||
len := len - kMatchMinLen;
|
||||
if (len < kNumLenToPosStates) then
|
||||
result:=len
|
||||
else result:=(kNumLenToPosStates - 1);
|
||||
end;
|
||||
|
||||
end.
|
@ -1,31 +0,0 @@
|
||||
unit ULZMACommon;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL;
|
||||
|
||||
type TLZMAProgressAction=(LPAMax,LPAPos);
|
||||
TLZMAProgress=procedure (const Action:TLZMAProgressAction;const Value:int64) of object;
|
||||
|
||||
function ReadByte(const stream:PStream):byte;
|
||||
procedure WriteByte(const stream:PStream;b:byte);
|
||||
|
||||
const CodeProgressInterval = 50;//approx. number of times an OnProgress event will be fired during coding
|
||||
|
||||
implementation
|
||||
|
||||
function ReadByte(const stream:PStream):byte;
|
||||
begin
|
||||
stream.Read(result,1);
|
||||
end;
|
||||
|
||||
procedure WriteByte(const stream:PStream;b:byte);
|
||||
begin
|
||||
stream.Write(b,1);
|
||||
end;
|
||||
|
||||
end.
|
@ -1,428 +0,0 @@
|
||||
unit ULZMADecoder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses ULZMABase,UBitTreeDecoder,ULZOutWindow,URangeDecoder,KOL,ULZMACommon;
|
||||
|
||||
type PLZMALenDecoder = ^TLZMALenDecoder;
|
||||
PLZMALiteralDecoder = ^TLZMALiteralDecoder;
|
||||
|
||||
PLZMADecoder = ^TLZMADecoder;
|
||||
TLZMADecoder = object(TObj)
|
||||
private
|
||||
FOnProgress:TLZMAProgress;
|
||||
procedure DoProgress(const Action:TLZMAProgressAction;const Value:integer);
|
||||
public
|
||||
m_OutWindow:PLZOutWindow;
|
||||
m_RangeDecoder:PRangeDecoder;
|
||||
|
||||
m_IsMatchDecoders: array [0..ULZMABase.kNumStates shl ULZMABase.kNumPosStatesBitsMax-1] of smallint;
|
||||
m_IsRepDecoders: array [0..ULZMABase.kNumStates-1] of smallint;
|
||||
m_IsRepG0Decoders: array [0..ULZMABase.kNumStates-1] of smallint;
|
||||
m_IsRepG1Decoders: array [0..ULZMABase.kNumStates-1] of smallint;
|
||||
m_IsRepG2Decoders: array [0..ULZMABase.kNumStates-1] of smallint;
|
||||
m_IsRep0LongDecoders: array [0..ULZMABase.kNumStates shl ULZMABase.kNumPosStatesBitsMax-1] of smallint;
|
||||
|
||||
m_PosSlotDecoder: array [0..ULZMABase.kNumLenToPosStates-1] of PBitTreeDecoder;
|
||||
m_PosDecoders: array [0..ULZMABase.kNumFullDistances - ULZMABase.kEndPosModelIndex-1] of smallint;
|
||||
|
||||
m_PosAlignDecoder:PBitTreeDecoder;
|
||||
|
||||
m_LenDecoder:PLZMALenDecoder;
|
||||
m_RepLenDecoder:PLZMALenDecoder;
|
||||
|
||||
m_LiteralDecoder:PLZMALiteralDecoder;
|
||||
|
||||
m_DictionarySize:integer;
|
||||
m_DictionarySizeCheck:integer;
|
||||
|
||||
m_PosStateMask:integer;
|
||||
|
||||
constructor Create;
|
||||
destructor Destroy;virtual;
|
||||
function SetDictionarySize(const dictionarySize:integer):boolean;
|
||||
function SetLcLpPb(const lc,lp,pb:integer):boolean;
|
||||
procedure _Init;
|
||||
function Code(const inStream,outStream:PStream;outSize:int64):boolean;
|
||||
function SetDecoderProperties(const properties:array of byte):boolean;
|
||||
property OnProgress:TLZMAProgress read FOnProgress write FOnProgress;
|
||||
end;
|
||||
|
||||
TLZMALenDecoder = object(TObj)
|
||||
public
|
||||
m_Choice:array [0..1] of smallint;
|
||||
m_LowCoder: array[0..ULZMABase.kNumPosStatesMax-1] of PBitTreeDecoder;
|
||||
m_MidCoder: array[0..ULZMABase.kNumPosStatesMax-1] of PBitTreeDecoder;
|
||||
m_HighCoder: PBitTreeDecoder;
|
||||
m_NumPosStates:integer;
|
||||
constructor Create;
|
||||
destructor Destroy;virtual;
|
||||
procedure _Create(const numPosStates:integer);
|
||||
procedure _Init;
|
||||
function Decode(const rangeDecoder:PRangeDecoder;const posState:integer):integer;
|
||||
end;
|
||||
|
||||
PLZMADecoder2 = ^TLZMADecoder2;
|
||||
TLZMADecoder2 = object(TObj)
|
||||
public
|
||||
m_Decoders: array [0..$300-1] of smallint;
|
||||
procedure _Init;
|
||||
function DecodeNormal(const ArangeDecoder:PRangeDecoder):byte;
|
||||
function DecodeWithMatchByte(const ArangeDecoder:PRangeDecoder;AmatchByte:byte):byte;
|
||||
end;
|
||||
|
||||
TLZMALiteralDecoder = object(TObj)
|
||||
public
|
||||
m_Coders: array of PLZMADecoder2;
|
||||
m_NumPrevBits:integer;
|
||||
m_NumPosBits:integer;
|
||||
m_PosMask:integer;
|
||||
procedure _Create(const AnumPosBits, AnumPrevBits:integer);
|
||||
procedure _Init;
|
||||
function GetDecoder(const Apos:integer;const AprevByte:byte):PLZMADecoder2;
|
||||
destructor Destroy;virtual;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TLZMALenDecoder.Create;
|
||||
begin
|
||||
New(m_HighCoder, Create(ULZMABase.kNumHighLenBits));
|
||||
m_NumPosStates:=0;
|
||||
end;
|
||||
|
||||
destructor TLZMALenDecoder.Destroy;
|
||||
var i:integer;
|
||||
begin
|
||||
m_HighCoder.free;
|
||||
for i:=low(m_LowCoder) to high(m_LowCoder) do begin
|
||||
if m_LowCoder[i]<>nil then m_LowCoder[i].free;
|
||||
if m_MidCoder[i]<>nil then m_MidCoder[i].free;
|
||||
end;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TLZMALenDecoder._Create(const numPosStates:integer);
|
||||
begin
|
||||
while m_NumPosStates < numPosStates do begin
|
||||
New(m_LowCoder[m_NumPosStates], Create(ULZMABase.kNumLowLenBits));
|
||||
New(m_MidCoder[m_NumPosStates], Create(ULZMABase.kNumMidLenBits));
|
||||
inc(m_NumPosStates);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZMALenDecoder._Init;
|
||||
var posState:integer;
|
||||
begin
|
||||
URangeDecoder.InitBitModels(m_Choice);
|
||||
for posState := 0 to m_NumPosStates-1 do begin
|
||||
m_LowCoder[posState]._Init;
|
||||
m_MidCoder[posState]._Init;
|
||||
end;
|
||||
m_HighCoder._Init;
|
||||
end;
|
||||
|
||||
function TLZMALenDecoder.Decode(const rangeDecoder:PRangeDecoder;const posState:integer):integer;
|
||||
var symbol:integer;
|
||||
begin
|
||||
if (rangeDecoder.DecodeBit(m_Choice, 0) = 0) then begin
|
||||
result:=m_LowCoder[posState].Decode(rangeDecoder);
|
||||
exit;
|
||||
end;
|
||||
symbol := ULZMABase.kNumLowLenSymbols;
|
||||
if (rangeDecoder.DecodeBit(m_Choice, 1) = 0) then
|
||||
symbol := symbol + m_MidCoder[posState].Decode(rangeDecoder)
|
||||
else symbol := symbol + ULZMABase.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
|
||||
result:=symbol;
|
||||
end;
|
||||
|
||||
procedure TLZMADecoder2._Init;
|
||||
begin
|
||||
URangeDecoder.InitBitModels(m_Decoders);
|
||||
end;
|
||||
|
||||
function TLZMADecoder2.DecodeNormal(const ArangeDecoder:PRangeDecoder):byte;
|
||||
var symbol:integer;
|
||||
begin
|
||||
symbol := 1;
|
||||
repeat
|
||||
symbol := (symbol shl 1) or ArangeDecoder.DecodeBit(m_Decoders, symbol);
|
||||
until not (symbol < $100);
|
||||
result:=symbol;
|
||||
end;
|
||||
|
||||
function TLZMADecoder2.DecodeWithMatchByte(const ArangeDecoder:PRangeDecoder;AmatchByte:byte):byte;
|
||||
var symbol:integer;
|
||||
matchbit:integer;
|
||||
bit:integer;
|
||||
begin
|
||||
symbol := 1;
|
||||
repeat
|
||||
matchBit := (AmatchByte shr 7) and 1;
|
||||
AmatchByte := AmatchByte shl 1;
|
||||
bit := ArangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) shl 8) + symbol);
|
||||
symbol := (symbol shl 1) or bit;
|
||||
if (matchBit <> bit) then begin
|
||||
while (symbol < $100) do begin
|
||||
symbol := (symbol shl 1) or ArangeDecoder.DecodeBit(m_Decoders, symbol);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
until not (symbol < $100);
|
||||
result:=symbol;
|
||||
end;
|
||||
|
||||
procedure TLZMALiteralDecoder._Create(const AnumPosBits, AnumPrevBits:integer);
|
||||
var numStates,i:integer;
|
||||
begin
|
||||
if (length(m_Coders) <> 0) and (m_NumPrevBits = AnumPrevBits) and (m_NumPosBits = AnumPosBits) then
|
||||
exit;
|
||||
m_NumPosBits := AnumPosBits;
|
||||
m_PosMask := (1 shl AnumPosBits) - 1;
|
||||
m_NumPrevBits := AnumPrevBits;
|
||||
numStates := 1 shl (m_NumPrevBits + m_NumPosBits);
|
||||
setlength(m_Coders,numStates);
|
||||
for i :=0 to numStates-1 do
|
||||
New(m_Coders[i], Create);
|
||||
end;
|
||||
|
||||
destructor TLZMALiteralDecoder.Destroy;
|
||||
var i:integer;
|
||||
begin
|
||||
for i :=low(m_Coders) to high(m_Coders) do
|
||||
if m_Coders[i]<>nil then m_Coders[i].Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TLZMALiteralDecoder._Init;
|
||||
var numStates,i:integer;
|
||||
begin
|
||||
numStates := 1 shl (m_NumPrevBits + m_NumPosBits);
|
||||
for i := 0 to numStates -1 do
|
||||
m_Coders[i]._Init;
|
||||
end;
|
||||
|
||||
function TLZMALiteralDecoder.GetDecoder(const Apos:integer;const AprevByte:byte):PLZMADecoder2;
|
||||
begin
|
||||
result:=m_Coders[((Apos and m_PosMask) shl m_NumPrevBits) + ((AprevByte and $FF) shr (8 - m_NumPrevBits))];
|
||||
end;
|
||||
|
||||
constructor TLZMADecoder.Create;
|
||||
var i:integer;
|
||||
begin
|
||||
FOnProgress:=nil;
|
||||
New(m_OutWindow, Create);
|
||||
New(m_RangeDecoder, Create);
|
||||
New(m_PosAlignDecoder, Create(ULZMABase.kNumAlignBits));
|
||||
New(m_LenDecoder, Create);
|
||||
New(m_RepLenDecoder, Create);
|
||||
New(m_LiteralDecoder, Create);
|
||||
m_DictionarySize:= -1;
|
||||
m_DictionarySizeCheck:= -1;
|
||||
for i := 0 to ULZMABase.kNumLenToPosStates -1 do
|
||||
New(m_PosSlotDecoder[i], Create(ULZMABase.kNumPosSlotBits));
|
||||
end;
|
||||
|
||||
destructor TLZMADecoder.Destroy;
|
||||
var i:integer;
|
||||
begin
|
||||
m_OutWindow.Free;
|
||||
m_RangeDecoder.Free;
|
||||
m_PosAlignDecoder.Free;
|
||||
m_LenDecoder.Free;
|
||||
m_RepLenDecoder.Free;
|
||||
m_LiteralDecoder.Free;
|
||||
for i := 0 to ULZMABase.kNumLenToPosStates -1 do
|
||||
m_PosSlotDecoder[i].Free;
|
||||
end;
|
||||
|
||||
function TLZMADecoder.SetDictionarySize(const dictionarySize:integer):boolean;
|
||||
begin
|
||||
if dictionarySize < 0 then
|
||||
result:=false
|
||||
else begin
|
||||
if m_DictionarySize <> dictionarySize then begin
|
||||
m_DictionarySize := dictionarySize;
|
||||
m_DictionarySizeCheck := max(m_DictionarySize, 1);
|
||||
m_OutWindow._Create(max(m_DictionarySizeCheck, (1 shl 12)));
|
||||
end;
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLZMADecoder.SetLcLpPb(const lc,lp,pb:integer):boolean;
|
||||
var numPosStates:integer;
|
||||
begin
|
||||
if (lc > ULZMABase.kNumLitContextBitsMax) or (lp > 4) or (pb > ULZMABase.kNumPosStatesBitsMax) then begin
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
m_LiteralDecoder._Create(lp, lc);
|
||||
numPosStates := 1 shl pb;
|
||||
m_LenDecoder._Create(numPosStates);
|
||||
m_RepLenDecoder._Create(numPosStates);
|
||||
m_PosStateMask := numPosStates - 1;
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
procedure TLZMADecoder._Init;
|
||||
var i:integer;
|
||||
begin
|
||||
m_OutWindow._Init(false);
|
||||
|
||||
URangeDecoder.InitBitModels(m_IsMatchDecoders);
|
||||
URangeDecoder.InitBitModels(m_IsRep0LongDecoders);
|
||||
URangeDecoder.InitBitModels(m_IsRepDecoders);
|
||||
URangeDecoder.InitBitModels(m_IsRepG0Decoders);
|
||||
URangeDecoder.InitBitModels(m_IsRepG1Decoders);
|
||||
URangeDecoder.InitBitModels(m_IsRepG2Decoders);
|
||||
URangeDecoder.InitBitModels(m_PosDecoders);
|
||||
|
||||
m_LiteralDecoder._Init();
|
||||
for i := 0 to ULZMABase.kNumLenToPosStates -1 do
|
||||
m_PosSlotDecoder[i]._Init;
|
||||
m_LenDecoder._Init;
|
||||
m_RepLenDecoder._Init;
|
||||
m_PosAlignDecoder._Init;
|
||||
m_RangeDecoder._Init;
|
||||
end;
|
||||
|
||||
function TLZMADecoder.Code(const inStream,outStream:PStream;outSize:int64):boolean;
|
||||
var state,rep0,rep1,rep2,rep3:integer;
|
||||
nowPos64:int64;
|
||||
prevByte:byte;
|
||||
posState:integer;
|
||||
decoder2:PLZMADecoder2;
|
||||
len,distance,posSlot,numDirectBits:integer;
|
||||
lpos:int64;
|
||||
progint:int64;
|
||||
begin
|
||||
DoProgress(LPAMax,outSize);
|
||||
m_RangeDecoder.SetStream(inStream);
|
||||
m_OutWindow.SetStream(outStream);
|
||||
_Init;
|
||||
|
||||
state := ULZMABase.StateInit;
|
||||
rep0 := 0; rep1 := 0; rep2 := 0; rep3 := 0;
|
||||
|
||||
nowPos64 := 0;
|
||||
prevByte := 0;
|
||||
progint:=outsize div CodeProgressInterval;
|
||||
lpos:=progint;
|
||||
while (outSize < 0) or (nowPos64 < outSize) do begin
|
||||
if (nowPos64 >=lpos) then begin
|
||||
DoProgress(LPAPos,nowPos64);
|
||||
lpos:=lpos+progint;
|
||||
end;
|
||||
posState := nowPos64 and m_PosStateMask;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state shl ULZMABase.kNumPosStatesBitsMax) + posState) = 0) then begin
|
||||
decoder2 := m_LiteralDecoder.GetDecoder(nowPos64, prevByte);
|
||||
if not ULZMABase.StateIsCharState(state) then
|
||||
prevByte := decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0))
|
||||
else prevByte := decoder2.DecodeNormal(m_RangeDecoder);
|
||||
m_OutWindow.PutByte(prevByte);
|
||||
state := ULZMABase.StateUpdateChar(state);
|
||||
inc(nowPos64);
|
||||
end else begin
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) = 1) then begin
|
||||
len := 0;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) = 0) then begin
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state shl ULZMABase.kNumPosStatesBitsMax) + posState) = 0) then begin
|
||||
state := ULZMABase.StateUpdateShortRep(state);
|
||||
len := 1;
|
||||
end;
|
||||
end else begin
|
||||
if m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) = 0 then
|
||||
distance := rep1
|
||||
else begin
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) = 0) then
|
||||
distance := rep2
|
||||
else begin
|
||||
distance := rep3;
|
||||
rep3 := rep2;
|
||||
end;
|
||||
rep2 := rep1;
|
||||
end;
|
||||
rep1 := rep0;
|
||||
rep0 := distance;
|
||||
end;
|
||||
if len = 0 then begin
|
||||
len := m_RepLenDecoder.Decode(m_RangeDecoder, posState) + ULZMABase.kMatchMinLen;
|
||||
state := ULZMABase.StateUpdateRep(state);
|
||||
end;
|
||||
end else begin
|
||||
rep3 := rep2;
|
||||
rep2 := rep1;
|
||||
rep1 := rep0;
|
||||
len := ULZMABase.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
|
||||
state := ULZMABase.StateUpdateMatch(state);
|
||||
posSlot := m_PosSlotDecoder[ULZMABase.GetLenToPosState(len)].Decode(m_RangeDecoder);
|
||||
if posSlot >= ULZMABase.kStartPosModelIndex then begin
|
||||
numDirectBits := (posSlot shr 1) - 1;
|
||||
rep0 := ((2 or (posSlot and 1)) shl numDirectBits);
|
||||
if posSlot < ULZMABase.kEndPosModelIndex then
|
||||
rep0 := rep0 + UBitTreeDecoder.ReverseDecode(m_PosDecoders,
|
||||
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits)
|
||||
else begin
|
||||
rep0 := rep0 + (m_RangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - ULZMABase.kNumAlignBits) shl ULZMABase.kNumAlignBits);
|
||||
rep0 := rep0 + m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
|
||||
if rep0 < 0 then begin
|
||||
if rep0 = -1 then
|
||||
break;
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end else rep0 := posSlot;
|
||||
end;
|
||||
if (rep0 >= nowPos64) or (rep0 >= m_DictionarySizeCheck) then begin
|
||||
m_OutWindow.Flush();
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
m_OutWindow.CopyBlock(rep0, len);
|
||||
nowPos64 := nowPos64 + len;
|
||||
prevByte := m_OutWindow.GetByte(0);
|
||||
end;
|
||||
end;
|
||||
m_OutWindow.Flush();
|
||||
m_OutWindow.ReleaseStream();
|
||||
m_RangeDecoder.ReleaseStream();
|
||||
DoProgress(LPAPos,nowPos64);
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
function TLZMADecoder.SetDecoderProperties(const properties:array of byte):boolean;
|
||||
var val,lc,remainder,lp,pb,dictionarysize,i:integer;
|
||||
begin
|
||||
if length(properties) < 5 then begin
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
val := properties[0] and $FF;
|
||||
lc := val mod 9;
|
||||
remainder := val div 9;
|
||||
lp := remainder mod 5;
|
||||
pb := remainder div 5;
|
||||
dictionarySize := 0;
|
||||
for i := 0 to 3 do
|
||||
dictionarySize := dictionarysize + ((properties[1 + i]) and $FF) shl (i * 8);
|
||||
if (not SetLcLpPb(lc, lp, pb)) then begin
|
||||
result:=false;
|
||||
exit;
|
||||
end;
|
||||
result:=SetDictionarySize(dictionarySize);
|
||||
end;
|
||||
|
||||
procedure TLZMADecoder.DoProgress(const Action:TLZMAProgressAction;const Value:integer);
|
||||
begin
|
||||
if assigned(fonprogress) then
|
||||
fonprogress(action,value);
|
||||
end;
|
||||
|
||||
end.
|
File diff suppressed because it is too large
Load Diff
@ -1,107 +0,0 @@
|
||||
unit ULZOutWindow;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL;
|
||||
|
||||
type PLZOutWindow = ^TLZOutWindow;
|
||||
TLZOutWindow=object(TObj)
|
||||
public
|
||||
buffer: array of byte;
|
||||
pos:integer;
|
||||
windowSize:integer;
|
||||
streamPos:integer;
|
||||
stream:PStream;
|
||||
procedure _Create(const AwindowSize:integer);
|
||||
procedure SetStream(const Astream:PStream);
|
||||
procedure ReleaseStream;
|
||||
procedure _Init(const Asolid:boolean);
|
||||
procedure Flush;
|
||||
procedure CopyBlock(const Adistance:integer; Alen:integer);
|
||||
procedure PutByte(const Ab:byte);
|
||||
function GetByte(const Adistance:integer):byte;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TLZOutWindow._Create(const AwindowSize:integer);
|
||||
begin
|
||||
if (length(buffer)=0) or (self.windowSize <> AwindowSize) then
|
||||
setlength(buffer,AwindowSize);
|
||||
self.windowSize := AwindowSize;
|
||||
pos := 0;
|
||||
streamPos := 0;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow.SetStream(const Astream:PStream);
|
||||
begin
|
||||
ReleaseStream;
|
||||
self.stream:=Astream;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow.ReleaseStream;
|
||||
begin
|
||||
flush;
|
||||
self.stream:=nil;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow._Init(const Asolid:boolean);
|
||||
begin
|
||||
if not Asolid then begin
|
||||
streamPos:=0;
|
||||
Pos:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow.Flush;
|
||||
var size:integer;
|
||||
begin
|
||||
size := pos - streamPos;
|
||||
if (size = 0) then
|
||||
exit;
|
||||
stream.write(buffer[streamPos], size);
|
||||
if (pos >= windowSize) then
|
||||
pos := 0;
|
||||
streamPos := pos;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow.CopyBlock(const Adistance:integer;Alen:integer);
|
||||
var _pos:integer;
|
||||
begin
|
||||
_pos := self.pos - Adistance - 1;
|
||||
if _pos < 0 then
|
||||
_pos := _pos + windowSize;
|
||||
while Alen<>0 do begin
|
||||
if _pos >= windowSize then
|
||||
_pos := 0;
|
||||
buffer[self.pos] := buffer[_pos];
|
||||
inc(self.pos);
|
||||
inc(_pos);
|
||||
if self.pos >= windowSize then
|
||||
Flush();
|
||||
dec(Alen);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLZOutWindow.PutByte(const Ab:byte);
|
||||
begin
|
||||
buffer[pos] := Ab;
|
||||
inc(pos);
|
||||
if (pos >= windowSize) then
|
||||
Flush();
|
||||
end;
|
||||
|
||||
function TLZOutWindow.GetByte(const Adistance:integer):byte;
|
||||
var _pos:integer;
|
||||
begin
|
||||
_pos := self.pos - Adistance - 1;
|
||||
if (_pos < 0) then
|
||||
_pos := _pos + windowSize;
|
||||
result:=buffer[_pos];
|
||||
end;
|
||||
|
||||
end.
|
@ -1,100 +0,0 @@
|
||||
unit URangeDecoder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL,ULZMACommon;
|
||||
|
||||
type PRangeDecoder = ^TRangeDecoder;
|
||||
TRangeDecoder=object(TObj)
|
||||
public
|
||||
Range,Code:integer;
|
||||
Stream:PStream;
|
||||
procedure SetStream(const AStream:PStream);
|
||||
procedure ReleaseStream;
|
||||
procedure _Init;
|
||||
function DecodeDirectBits(const AnumTotalBits:integer):integer;
|
||||
function DecodeBit(var Aprobs: array of smallint;const Aindex:integer):integer;
|
||||
end;
|
||||
|
||||
procedure InitBitModels(var Aprobs: array of smallint);
|
||||
|
||||
implementation
|
||||
|
||||
const kTopMask = not ((1 shl 24) - 1);
|
||||
kNumBitModelTotalBits = 11;
|
||||
kBitModelTotal = (1 shl kNumBitModelTotalBits);
|
||||
kNumMoveBits = 5;
|
||||
|
||||
procedure TRangeDecoder.SetStream(const AStream:PStream);
|
||||
begin
|
||||
self.Stream:=AStream;
|
||||
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 AnumTotalBits:integer):integer;
|
||||
var i,t:integer;
|
||||
begin
|
||||
result:=0;
|
||||
for i := AnumTotalBits 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 Aprobs: array of smallint;const Aindex:integer):integer;
|
||||
var prob,newbound:integer;
|
||||
begin
|
||||
prob:=Aprobs[Aindex];
|
||||
newbound:=(Range shr kNumBitModelTotalBits) * prob;
|
||||
if (integer((integer(Code) xor integer($80000000))) < integer((integer(newBound) xor integer($80000000)))) then begin
|
||||
Range := newBound;
|
||||
Aprobs[Aindex] := (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;
|
||||
Aprobs[Aindex] := (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 Aprobs: array of smallint);
|
||||
var i:integer;
|
||||
begin
|
||||
for i:=0 to length(Aprobs)-1 do
|
||||
Aprobs[i] := kBitModelTotal shr 1;
|
||||
end;
|
||||
|
||||
end.
|
@ -1,175 +0,0 @@
|
||||
unit URangeEncoder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses KOL,ULZMACommon;
|
||||
|
||||
const kNumBitPriceShiftBits = 6;
|
||||
kTopMask = not ((1 shl 24) - 1);
|
||||
kNumBitModelTotalBits = 11;
|
||||
kBitModelTotal = (1 shl kNumBitModelTotalBits);
|
||||
kNumMoveBits = 5;
|
||||
kNumMoveReducingBits = 2;
|
||||
|
||||
type PRangeEncoder = ^TRangeEncoder;
|
||||
TRangeEncoder=object(TObj)
|
||||
private
|
||||
ProbPrices: array [0..kBitModelTotal shr kNumMoveReducingBits-1] of integer;
|
||||
public
|
||||
Stream:PStream;
|
||||
Low,Position:int64;
|
||||
Range,cacheSize,cache:integer;
|
||||
procedure SetStream(const Astream:PStream);
|
||||
procedure ReleaseStream;
|
||||
procedure _Init;
|
||||
procedure FlushData;
|
||||
procedure FlushStream;
|
||||
procedure ShiftLow;
|
||||
procedure EncodeDirectBits(const v,AnumTotalBits:integer);
|
||||
function GetProcessedSizeAdd:int64;
|
||||
procedure Encode(var Aprobs: array of smallint;const Aindex,Asymbol:integer);
|
||||
constructor Create;
|
||||
function GetPrice(const AProb,Asymbol:integer):integer;
|
||||
function GetPrice0(const AProb:integer):integer;
|
||||
function GetPrice1(const AProb:integer):integer;
|
||||
end;
|
||||
|
||||
var RangeEncoder:PRangeEncoder;
|
||||
|
||||
procedure InitBitModels(var probs:array of smallint);
|
||||
|
||||
implementation
|
||||
|
||||
procedure TRangeEncoder.SetStream(const Astream:PStream);
|
||||
begin
|
||||
self.Stream:=AStream;
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder.ReleaseStream;
|
||||
begin
|
||||
stream:=nil;
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder._Init;
|
||||
begin
|
||||
position := 0;
|
||||
Low := 0;
|
||||
Range := -1;
|
||||
cacheSize := 1;
|
||||
cache := 0;
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder.FlushData;
|
||||
var i:integer;
|
||||
begin
|
||||
for i:=0 to 4 do
|
||||
ShiftLow();
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder.FlushStream;
|
||||
begin
|
||||
//stream.flush;
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder.ShiftLow;
|
||||
var LowHi:integer;
|
||||
temp:integer;
|
||||
begin
|
||||
LowHi := (Low shr 32);
|
||||
if (LowHi <> 0) or (Low < int64($FF000000)) then begin
|
||||
position := position + cacheSize;
|
||||
temp := cache;
|
||||
repeat
|
||||
WriteByte(stream,temp + LowHi);
|
||||
temp := $FF;
|
||||
dec(cacheSize);
|
||||
until(cacheSize = 0);
|
||||
cache := (Low shr 24);
|
||||
end;
|
||||
inc(cacheSize);
|
||||
Low := (Low and integer($FFFFFF)) shl 8;
|
||||
end;
|
||||
|
||||
procedure TRangeEncoder.EncodeDirectBits(const v,AnumTotalBits:integer);
|
||||
var i:integer;
|
||||
begin
|
||||
for i := AnumTotalBits - 1 downto 0 do begin
|
||||
Range := Range shr 1;
|
||||
if (((v shr i) and 1) = 1) then
|
||||
Low := Low + Range;
|
||||
if ((Range and kTopMask) = 0) then begin
|
||||
Range := range shl 8;
|
||||
ShiftLow;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRangeEncoder.GetProcessedSizeAdd:int64;
|
||||
begin
|
||||
result:=cacheSize + position + 4;
|
||||
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;
|
||||
|
||||
procedure TRangeEncoder.Encode(var Aprobs: array of smallint;const Aindex,Asymbol:integer);
|
||||
var prob,newbound:integer;
|
||||
begin
|
||||
prob := Aprobs[Aindex];
|
||||
newBound := (Range shr kNumBitModelTotalBits) * prob;
|
||||
if (Asymbol = 0) then begin
|
||||
Range := newBound;
|
||||
Aprobs[Aindex] := (prob + ((kBitModelTotal - prob) shr kNumMoveBits));
|
||||
end else begin
|
||||
Low := Low + (newBound and int64($FFFFFFFF));
|
||||
Range := Range - newBound;
|
||||
Aprobs[Aindex] := (prob - ((prob) shr kNumMoveBits));
|
||||
end;
|
||||
if ((Range and kTopMask) = 0) then begin
|
||||
Range := Range shl 8;
|
||||
ShiftLow;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TRangeEncoder.Create;
|
||||
var kNumBits:integer;
|
||||
i,j,start,_end:integer;
|
||||
begin
|
||||
kNumBits := (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for i := kNumBits - 1 downto 0 do begin
|
||||
start := 1 shl (kNumBits - i - 1);
|
||||
_end := 1 shl (kNumBits - i);
|
||||
for j := start to _end -1 do
|
||||
ProbPrices[j] := (i shl kNumBitPriceShiftBits) +
|
||||
(((_end - j) shl kNumBitPriceShiftBits) shr (kNumBits - i - 1));
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRangeEncoder.GetPrice(const AProb,Asymbol:integer):integer;
|
||||
begin
|
||||
result:=ProbPrices[(((AProb - Asymbol) xor ((-Asymbol))) and (kBitModelTotal - 1)) shr kNumMoveReducingBits];
|
||||
end;
|
||||
|
||||
function TRangeEncoder.GetPrice0(const AProb:integer):integer;
|
||||
begin
|
||||
result:= ProbPrices[AProb shr kNumMoveReducingBits];
|
||||
end;
|
||||
|
||||
function TRangeEncoder.GetPrice1(const AProb:integer):integer;
|
||||
begin
|
||||
result:= ProbPrices[(kBitModelTotal - AProb) shr kNumMoveReducingBits];
|
||||
end;
|
||||
|
||||
initialization
|
||||
New(RangeEncoder, Create);
|
||||
finalization
|
||||
RangeEncoder.Free;
|
||||
end.
|
301
Addons/USrv.pas
301
Addons/USrv.pas
@ -1,301 +0,0 @@
|
||||
Unit USrv;
|
||||
|
||||
interface
|
||||
uses Windows, Classes, Graphics, Controls, Messages, Dialogs,
|
||||
SysUtils;
|
||||
|
||||
const WM_GETIMAGE = WM_USER + $0429;
|
||||
|
||||
function BitmapToRegion(Bitmap: TBitmap): HRGN;
|
||||
function CopyToBitmap(Control: TControl; Bitmap: TBitmap; Anyway: boolean): boolean;
|
||||
procedure CopyParentImage(Control: TControl; Dest: TCanvas);
|
||||
procedure RestoreImage(DestDC: HDC; SrcBitmap: TBitmap; r: TRect;
|
||||
dwROP: dword); overload;
|
||||
procedure RestoreImage(DestDC: HDC; SrcBitmap: TBitmap; l, t, w, h: integer;
|
||||
dwROP: dword); overload;
|
||||
procedure AjustBitmap(const M: TBitmap; S, C: TColor);
|
||||
procedure FadeBitmap(const M: TBitmap; C: TColor; D: byte);
|
||||
function IncColor(C: TColor; D: integer): TColor;
|
||||
|
||||
implementation
|
||||
|
||||
function BitmapToRegion(Bitmap: TBitmap): HRGN;
|
||||
var
|
||||
X, Y: Integer;
|
||||
XStart: Integer;
|
||||
TransC: TColor;
|
||||
R: HRGN;
|
||||
begin
|
||||
Result := 0;
|
||||
with Bitmap do begin
|
||||
TransC := Canvas.Pixels[0, 0];
|
||||
for Y := 0 to Height - 1 do begin
|
||||
X := 0;
|
||||
while X < Width do begin
|
||||
while (X < Width) and (Canvas.Pixels[X, Y] = TransC) do Inc(X);
|
||||
if X >= Width then Break;
|
||||
XStart := X;
|
||||
while (X < Width) and (Canvas.Pixels[X, Y] <> TransC) do Inc(X);
|
||||
R := CreateRectRgn(XStart, Y, X, Y + 1);
|
||||
if Result = 0 then Result := R
|
||||
else begin
|
||||
CombineRgn(Result, Result, R, RGN_OR);
|
||||
DeleteObject(R);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CopyToBitmap;
|
||||
var x, y: integer;
|
||||
begin
|
||||
Result := False;
|
||||
if Control = nil then exit;
|
||||
x := BitMap.Width - 2;
|
||||
y := BitMap.Height - 2;
|
||||
if (Anyway) or
|
||||
(x + 2 <> Control.Width) or
|
||||
(y + 2 <> Control.Height) or
|
||||
(BitMap.Canvas.Pixels[x, y] = $FFFFFF) or
|
||||
(BitMap.Canvas.Pixels[x, y] = $000000) then begin
|
||||
BitMap.Width := Control.Width;
|
||||
BitMap.Height := Control.Height;
|
||||
CopyParentImage(Control, BitMap.Canvas);
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
TParentControl = class(TWinControl);
|
||||
|
||||
procedure CopyParentImage(Control: TControl; Dest: TCanvas);
|
||||
var
|
||||
I, Count, X, Y, SaveIndex: Integer;
|
||||
DC: HDC;
|
||||
R, SelfR, CtlR: TRect;
|
||||
begin
|
||||
if (Control = nil) or (Control.Parent = nil) then Exit;
|
||||
Count := Control.Parent.ControlCount;
|
||||
DC := Dest.Handle;
|
||||
with Control.Parent do ControlState := ControlState + [csPaintCopy];
|
||||
try
|
||||
with Control do begin
|
||||
SelfR := Bounds(Left, Top, Width, Height);
|
||||
X := -Left; Y := -Top;
|
||||
end;
|
||||
{ Copy parent control image }
|
||||
SaveIndex := SaveDC(DC);
|
||||
try
|
||||
if TParentControl(Control.Parent).Perform(
|
||||
WM_GETIMAGE, DC, integer(@SelfR)) <> $29041961 then begin
|
||||
SetViewportOrgEx(DC, X, Y, nil);
|
||||
IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth,
|
||||
Control.Parent.ClientHeight);
|
||||
with TParentControl(Control.Parent) do begin
|
||||
Perform(WM_ERASEBKGND, DC, 0);
|
||||
PaintWindow(DC);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
RestoreDC(DC, SaveIndex);
|
||||
end;
|
||||
{ Copy images of graphic controls }
|
||||
for I := 0 to Count - 1 do begin
|
||||
if Control.Parent.Controls[I] = Control then continue
|
||||
else if (Control.Parent.Controls[I] <> nil) and
|
||||
(Control.Parent.Controls[I] is TGraphicControl) then
|
||||
begin
|
||||
with TGraphicControl(Control.Parent.Controls[I]) do begin
|
||||
CtlR := Bounds(Left, Top, Width, Height);
|
||||
if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then begin
|
||||
ControlState := ControlState + [csPaintCopy];
|
||||
SaveIndex := SaveDC(DC);
|
||||
try
|
||||
if Perform(
|
||||
WM_GETIMAGE, DC, integer(@SelfR)) <> $29041961 then begin
|
||||
{ SaveIndex := SaveDC(DC);}
|
||||
SetViewportOrgEx(DC, Left + X, Top + Y, nil);
|
||||
IntersectClipRect(DC, 0, 0, Width, Height);
|
||||
Perform(WM_PAINT, DC, 0);
|
||||
end;
|
||||
finally
|
||||
RestoreDC(DC, SaveIndex);
|
||||
ControlState := ControlState - [csPaintCopy];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
with Control.Parent do ControlState := ControlState - [csPaintCopy];
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure RestoreImage(DestDC: HDC; SrcBitmap: TBitmap; r: TRect;
|
||||
dwROP: dword); overload;
|
||||
begin
|
||||
RestoreImage(DestDC, SrcBitmap, r.Left, r.Top,
|
||||
r.Right - r.Left, r.Bottom - r.Top, dwROP);
|
||||
end;
|
||||
|
||||
procedure RestoreImage(DestDC: HDC; SrcBitmap: TBitmap; l, t, w, h: integer;
|
||||
dwROP: dword); overload;
|
||||
var x, y: integer;
|
||||
begin
|
||||
x := l + w div 2;
|
||||
y := t + h div 2;
|
||||
if (SrcBitmap.Canvas.Pixels[x, y] <> $FFFFFF) and
|
||||
(SrcBitMap.Canvas.Pixels[x, y] <> $000000) then begin
|
||||
x := l;
|
||||
y := t;
|
||||
if y + h > SrcBitMap.Height then begin
|
||||
y := SrcBitMap.Height - h;
|
||||
end;
|
||||
bitblt(DestDC, l, t, w, h,
|
||||
SrcBitMap.Canvas.Handle, x, y, dwROP);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SplitColor(C: TColor; var r, g, b: integer);
|
||||
begin
|
||||
b := (c and $FF0000) shr 16;
|
||||
g := (c and $00FF00) shr 08;
|
||||
r := (c and $0000FF) shr 00;
|
||||
end;
|
||||
|
||||
procedure AjustBitmap;
|
||||
var i, j: integer;
|
||||
t: TBitmap;
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r2,
|
||||
g2,
|
||||
b2: integer;
|
||||
p: PRGBTriple;
|
||||
|
||||
function CalcColor(c1, c2, c3: integer): integer;
|
||||
begin
|
||||
if c1 = c3 then begin
|
||||
Result := c2;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if c1 = 0 then begin
|
||||
Result := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Result := 255 * c1 div c3 - c1 * (255 - c1) * (255 - c2) div c3 div (255 - c3);
|
||||
exit;}
|
||||
|
||||
Result := c1 * c2 div c3;
|
||||
if c2 = 0 then Result := c1 * 150 div 255;
|
||||
if Result > 255 then Result := 255;
|
||||
if Result < 50 then Result := Result + 50;
|
||||
{ exit;
|
||||
a := trunc(x1 * 3);
|
||||
a := c1 * (255 - c1) * c2 * (255 - c2) div c3 div (255 - c3);
|
||||
a := 255 * 255 - 4 * a;
|
||||
try
|
||||
x1 := Trunc((255 - sqrt(a)) / 2);
|
||||
x2 := Trunc((255 + sqrt(a)) / 2);
|
||||
if x1 > x2 then Result := Trunc(x1)
|
||||
else Result := Trunc(x2);
|
||||
except
|
||||
Result := 0;
|
||||
end;}
|
||||
end;
|
||||
|
||||
begin
|
||||
if s = c then exit;
|
||||
if m.Width = 0 then exit;
|
||||
if m.Height = 0 then exit;
|
||||
t := TBitmap.Create;
|
||||
m.PixelFormat := pf24bit;
|
||||
t.Assign(m);
|
||||
SplitColor(ColorToRGB(s), r, g, b);
|
||||
if r = 0 then r := 1;
|
||||
if g = 0 then g := 1;
|
||||
if b = 0 then b := 1;
|
||||
SplitColor(ColorToRGB(c), r2, g2, b2);
|
||||
for j := 0 to t.Height - 1 do begin
|
||||
p := t.scanline[j];
|
||||
for i := 0 to t.Width - 1 do begin
|
||||
p.rgbtRed := CalcColor(p.rgbtRed, r2, r);
|
||||
p.rgbtGreen := CalcColor(p.rgbtGreen, g2, g);
|
||||
p.rgbtBlue := CalcColor(p.rgbtBlue, b2, b);
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
m.Assign(t);
|
||||
t.Free;
|
||||
end;
|
||||
|
||||
procedure FadeBitmap;
|
||||
var i, j: integer;
|
||||
t: TBitmap;
|
||||
r,
|
||||
g,
|
||||
b: integer;
|
||||
p: PRGBTriple;
|
||||
|
||||
function CalcColor(o: byte; c: byte; b: byte): byte;
|
||||
var d: byte;
|
||||
begin
|
||||
Result := c;
|
||||
if o > c then begin
|
||||
d := $FF - c;
|
||||
if d > b then d := b;
|
||||
Result := c + c * d div 255;
|
||||
end else
|
||||
if o < c then begin
|
||||
d := c;
|
||||
if d > b then d := b;
|
||||
Result := c - c * d div 255;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
if m.Width = 0 then exit;
|
||||
if m.Height = 0 then exit;
|
||||
t := TBitmap.Create;
|
||||
m.PixelFormat := pf24bit;
|
||||
t.Assign(m);
|
||||
SplitColor(ColorToRGB(c), r, g, b);
|
||||
if r = 0 then r := 1;
|
||||
if g = 0 then g := 1;
|
||||
if b = 0 then b := 1;
|
||||
for j := 0 to t.Height - 1 do begin
|
||||
p := t.scanline[j];
|
||||
for i := 0 to t.Width - 1 do begin
|
||||
p.rgbtRed := CalcColor(p.rgbtRed, r, d);
|
||||
p.rgbtGreen := CalcColor(p.rgbtGreen, g, d);
|
||||
p.rgbtBlue := CalcColor(p.rgbtBlue, b, d);
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
m.Assign(t);
|
||||
t.Free;
|
||||
end;
|
||||
|
||||
function IncColor;
|
||||
var T: TColor;
|
||||
P: PRGBTriple;
|
||||
begin
|
||||
T := ColorToRGB(C);
|
||||
p := @T;
|
||||
if D > 0 then begin
|
||||
if p.rgbtBlue < 255 - D then p.rgbtBlue := p.rgbtBlue + D else p.rgbtBlue := 255;
|
||||
if p.rgbtRed < 255 - D then p.rgbtRed := p.rgbtRed + D else p.rgbtRed := 255;
|
||||
if p.rgbtGreen < 255 - D then p.rgbtGreen := p.rgbtGreen + D else p.rgbtGreen := 255;
|
||||
end else begin
|
||||
if p.rgbtBlue > D then p.rgbtBlue := p.rgbtBlue - D else p.rgbtBlue := 000;
|
||||
if p.rgbtRed > D then p.rgbtRed := p.rgbtRed - D else p.rgbtRed := 000;
|
||||
if p.rgbtGreen > D then p.rgbtGreen := p.rgbtGreen - D else p.rgbtGreen := 000;
|
||||
end;
|
||||
Result := T;
|
||||
end;
|
||||
|
||||
end.
|
258
Addons/UStr.pas
258
Addons/UStr.pas
@ -1,258 +0,0 @@
|
||||
unit UStr;
|
||||
|
||||
interface
|
||||
|
||||
function space ( n:integer):string ;
|
||||
function replicate(ch:char; n:integer):string ;
|
||||
function trim (str:string;c:boolean=false):string ;
|
||||
function alike (a,b:string;var d, p: integer): boolean;
|
||||
function center (str:string;n:integer):string ;
|
||||
function UpSt ( s:string ):string;
|
||||
function LoSt ( s:string ):string;
|
||||
function lpad ( s:string;n:integer;c:char):string;
|
||||
function rpad ( s:string;n:integer;c:char):string;
|
||||
function addbackslash(p : string) : string;
|
||||
function match (sm : string; var st: string) : boolean;
|
||||
function lines (p, l, s : longint) : string;
|
||||
function LoCase (c : char) : char;
|
||||
function JustPathName(PathName : string) : string;
|
||||
function JustFileName(PathName : string) : string;
|
||||
function JustName (PathName : string) : string;
|
||||
function CRC16 (s : string) : system.word;
|
||||
|
||||
implementation
|
||||
|
||||
function space;
|
||||
var i : integer;
|
||||
tempstr : string;
|
||||
begin
|
||||
tempstr:='';
|
||||
for i:=1 to n do tempstr:=tempstr+' ';
|
||||
space:=tempstr;
|
||||
end;
|
||||
|
||||
function replicate;
|
||||
var i : integer;
|
||||
tempstr : string;
|
||||
begin
|
||||
tempstr:='';
|
||||
for i:=1 to n do tempstr:=tempstr+ch;
|
||||
replicate:=tempstr;
|
||||
end;
|
||||
|
||||
function trim;
|
||||
var i,j : integer;
|
||||
s : string;
|
||||
begin
|
||||
trim := '';
|
||||
s := str;
|
||||
if length(str) > 1 then begin
|
||||
i := length(str);
|
||||
j := 1;
|
||||
while (j <= i) and (str[j] = ' ') do inc(j);
|
||||
if j > i then begin
|
||||
result := '';
|
||||
exit;
|
||||
end;
|
||||
while (str[i] = ' ') do dec(i);
|
||||
s := copy(str, j, i - j + 1);
|
||||
end;
|
||||
if c and (length(s) > 3) then begin
|
||||
repeat
|
||||
i := pos(' ', s);
|
||||
if i > 0 then begin
|
||||
s := copy(s, 1, i - 1) + copy(s, i + 1, length(s) - i);
|
||||
end;
|
||||
until i = 0;
|
||||
end;
|
||||
if c then result := LoSt(s)
|
||||
else result := s;
|
||||
end;
|
||||
|
||||
function alike;
|
||||
var e, f: integer;
|
||||
begin
|
||||
result := false;
|
||||
p := 0;
|
||||
e := length(a);
|
||||
f := length(b);
|
||||
if e + f = 0 then begin
|
||||
result := true;
|
||||
d := 100;
|
||||
exit;
|
||||
end;
|
||||
if (e = 0) or (f = 0) then begin
|
||||
d := 0;
|
||||
exit;
|
||||
end;
|
||||
while (p < e) and (p < f) do begin
|
||||
inc(p);
|
||||
if a[p] <> b[p] then begin
|
||||
dec(p);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
d := 200 * p div (e + f);
|
||||
if p * 2 > (e + f) div 2 then begin
|
||||
result := true;
|
||||
end;
|
||||
end;
|
||||
|
||||
function center;
|
||||
var tempstr : string;
|
||||
j : integer;
|
||||
begin
|
||||
j := n - length(trim(str));
|
||||
if j > 0 then tempstr := space(j - j div 2) + trim(str) + space(j div 2)
|
||||
else tempstr := trim(str);
|
||||
center := tempstr;
|
||||
end;
|
||||
|
||||
function UpSt;
|
||||
var t : string;
|
||||
i : integer;
|
||||
begin
|
||||
t := s;
|
||||
for i := 1 to length(s) do t[i] := UpCase(s[i]);
|
||||
UpSt := t;
|
||||
end;
|
||||
|
||||
function LoSt;
|
||||
var t : string;
|
||||
i : integer;
|
||||
begin
|
||||
t := s;
|
||||
for i := 1 to length(s) do t[i] := LoCase(s[i]);
|
||||
LoSt := t;
|
||||
end;
|
||||
|
||||
function lpad;
|
||||
begin
|
||||
lpad := replicate(c, n - length(s)) + s;
|
||||
end;
|
||||
|
||||
function rpad;
|
||||
begin
|
||||
rpad := s + replicate(c, n - length(s));
|
||||
end;
|
||||
|
||||
function addbackslash;
|
||||
begin
|
||||
if length(p) > 0 then
|
||||
if p[length(p)] = '\' then addbackslash := p
|
||||
else addbackslash := p + '\'
|
||||
else addbackslash := p;
|
||||
end;
|
||||
|
||||
function match(sm : string; var st: string) : boolean;
|
||||
var p : integer;
|
||||
_sm,
|
||||
_st : string;
|
||||
begin
|
||||
match := false;
|
||||
if (length(sm) > 0) and (length(st) > 0) then begin
|
||||
_sm := UpSt(sm);
|
||||
_st := UpSt(st);
|
||||
while pos(_sm, _st) > 0 do begin
|
||||
match := true;
|
||||
p := pos(_sm, _st);
|
||||
_st := copy(_st, 1, p - 1) + copy(_st, p + length(_sm), 250);
|
||||
st := copy( st, 1, p - 1) + copy( st, p + length( sm), 250);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function lines;
|
||||
var o : string;
|
||||
i : longint;
|
||||
n : longint;
|
||||
begin
|
||||
if l > 0 then begin
|
||||
i := p * s div l;
|
||||
n := p * s * 2 div l;
|
||||
o := replicate('�', i);
|
||||
if n > i * 2 then o := o + '�';
|
||||
lines := o + space(s - length(o));
|
||||
end else lines := '';
|
||||
end;
|
||||
|
||||
function LoCase;
|
||||
var t : char;
|
||||
begin
|
||||
if (c >= 'A') and (c <= 'Z') then t := chr(ord(c) + 32)
|
||||
else t := c;
|
||||
LoCase := t;
|
||||
end;
|
||||
|
||||
function JustPathname(PathName : string) : string;
|
||||
{-Return just the drive:directory portion of a pathname}
|
||||
var
|
||||
I : Word;
|
||||
begin
|
||||
I := Succ(Word(Length(PathName)));
|
||||
repeat
|
||||
Dec(I);
|
||||
until (PathName[I] in ['\',':',#0]) or (I = 1);
|
||||
|
||||
if I = 1 then
|
||||
{Had no drive or directory name}
|
||||
JustPathname := ''
|
||||
else if I = 1 then
|
||||
{Either the root directory of default drive or invalid pathname}
|
||||
JustPathname := PathName[1]
|
||||
else if (PathName[I] = '\') then begin
|
||||
if PathName[Pred(I)] = ':' then
|
||||
{Root directory of a drive, leave trailing backslash}
|
||||
JustPathname := Copy(PathName, 1, I)
|
||||
else
|
||||
{Subdirectory, remove the trailing backslash}
|
||||
JustPathname := Copy(PathName, 1, Pred(I));
|
||||
end else
|
||||
{Either the default directory of a drive or invalid pathname}
|
||||
JustPathname := Copy(PathName, 1, I);
|
||||
end;
|
||||
|
||||
function JustFilename(PathName : string) : string;
|
||||
{-Return just the filename of a pathname}
|
||||
var
|
||||
I : Word;
|
||||
begin
|
||||
I := Succ(Word(Length(PathName)));
|
||||
repeat
|
||||
Dec(I);
|
||||
until (I = 0) or (PathName[I] in ['\', ':', #0]);
|
||||
JustFilename := Copy(PathName, Succ(I), 64);
|
||||
end;
|
||||
|
||||
function JustName(PathName : string) : string;
|
||||
{-Return just the name (no extension, no path) of a pathname}
|
||||
var
|
||||
DotPos : Byte;
|
||||
begin
|
||||
PathName := JustFileName(PathName);
|
||||
DotPos := Pos('.', PathName);
|
||||
if DotPos > 0 then
|
||||
PathName := Copy(PathName, 1, DotPos-1);
|
||||
JustName := PathName;
|
||||
end;
|
||||
|
||||
|
||||
function CRC16(s : string) : system.word; { By Kevin Cooney }
|
||||
var
|
||||
crc : longint;
|
||||
t,r : byte;
|
||||
begin
|
||||
crc := 0;
|
||||
for t := 1 to length(s) do
|
||||
begin
|
||||
crc := (crc xor (ord(s[t]) shl 8));
|
||||
for r := 1 to 8 do
|
||||
if (crc and $8000)>0 then
|
||||
crc := ((crc shl 1) xor $1021)
|
||||
else
|
||||
crc := (crc shl 1);
|
||||
end;
|
||||
CRC16 := (crc and $FFFF);
|
||||
end;
|
||||
|
||||
end.
|
101
Addons/UWrd.pas
101
Addons/UWrd.pas
@ -1,101 +0,0 @@
|
||||
unit UWrd;
|
||||
|
||||
interface
|
||||
|
||||
function words (str:string;d:char ):integer;
|
||||
function wordn (str:string;d:char;n:integer):string ;
|
||||
function wordd (str:string;d:char;n:integer):string ;
|
||||
function wordp (str:string;d:char;n:integer):integer;
|
||||
function wordi ( wrd,str:string;d:cHar):boolean;
|
||||
function wordf (str:string;d:char;n:integer):string ;
|
||||
|
||||
implementation
|
||||
|
||||
function words;
|
||||
var tempstr : string;
|
||||
ins : boolean;
|
||||
i,j : integer;
|
||||
begin
|
||||
tempstr := d + str + d;
|
||||
ins := false;
|
||||
j := 0;
|
||||
for i := 1 to length(tempstr) do begin
|
||||
if ins then
|
||||
if tempstr[i] =d then ins:=false
|
||||
else begin end
|
||||
else
|
||||
if tempstr[i]<>d then begin
|
||||
inc(j);ins:=true;
|
||||
end;
|
||||
end;
|
||||
words:=j;
|
||||
end;
|
||||
|
||||
function wordn;
|
||||
var i,j:integer;
|
||||
tempstr:string;
|
||||
begin
|
||||
i:=words(str, d);
|
||||
if i<n then begin
|
||||
wordn:='';
|
||||
exit;
|
||||
end;
|
||||
i:=1;
|
||||
while words(copy(str,1,i), d)<n do inc(i);
|
||||
j:=i;
|
||||
tempstr:=str+d;
|
||||
while tempstr[j]<>d do inc(j);
|
||||
wordn:=copy(str,i,j-i);
|
||||
end;
|
||||
|
||||
function wordd;
|
||||
var i,j:integer;
|
||||
sss:string;
|
||||
tempstr:string;
|
||||
begin
|
||||
i:=words(str, d);
|
||||
if i<n then begin
|
||||
wordd:=str;
|
||||
exit;
|
||||
end;
|
||||
i:=1;
|
||||
while words(copy(str,1,i), d)<n do inc(i);
|
||||
j:=i;
|
||||
tempstr:=str+d;
|
||||
while tempstr[j]<>d do inc(j);
|
||||
sss :=copy(str,1,i-1);
|
||||
wordd:=sss+copy(str,j+1,length(tempstr)-j);
|
||||
end;
|
||||
|
||||
function wordp;
|
||||
var i:integer;
|
||||
begin
|
||||
i:=words(str, d);
|
||||
if i < n then begin
|
||||
wordp := 0;
|
||||
exit;
|
||||
end;
|
||||
i:=1;
|
||||
while words(copy(str,1,i), d)<n do inc(i);
|
||||
wordp := i;
|
||||
end;
|
||||
|
||||
function wordi;
|
||||
var i : integer;
|
||||
begin
|
||||
wordi := true;
|
||||
for i := 1 to words(str, d) do
|
||||
if wrd = wordn(str, d, i) tHen exit;
|
||||
wordi := false;
|
||||
end;
|
||||
|
||||
function wordf;
|
||||
var i: integer;
|
||||
begin
|
||||
i := wordp(str, d, n);
|
||||
wordf := '';
|
||||
if (i > 0) and (i < length(str)) then
|
||||
wordf := copy(str, i, length(str) - i + 1);
|
||||
end;
|
||||
|
||||
end.
|
@ -1,255 +0,0 @@
|
||||
unit reader;
|
||||
|
||||
interface
|
||||
|
||||
function compare(_ts, _ms : string) : boolean;
|
||||
procedure setvar ( vn, vv : string);
|
||||
function getvar ( vn : string) : string;
|
||||
function parstr : string;
|
||||
procedure setglo ( vn, vv : string);
|
||||
function getglo ( vn : string) : string;
|
||||
function parse ( vn : string; al : boolean) : string;
|
||||
procedure freeglob;
|
||||
|
||||
implementation
|
||||
|
||||
uses UStr, Serv, UWrd;
|
||||
|
||||
type
|
||||
trec = record
|
||||
name : string[12];
|
||||
valu : string[255];
|
||||
next : pointer;
|
||||
end;
|
||||
|
||||
var
|
||||
fvar,
|
||||
fglo : pointer;
|
||||
vrec,
|
||||
vglo,
|
||||
rrec : ^trec;
|
||||
v,
|
||||
z : string;
|
||||
|
||||
function compare;
|
||||
label fail, succ;
|
||||
var i,
|
||||
j,
|
||||
n : integer;
|
||||
ts,
|
||||
ms : string;
|
||||
|
||||
procedure freelist;
|
||||
begin
|
||||
vrec := fvar;
|
||||
while vrec <> nil do begin
|
||||
rrec := vrec;
|
||||
vrec := vrec^.next;
|
||||
freemem(rrec, sizeof(trec));
|
||||
end;
|
||||
fvar := nil;
|
||||
end;
|
||||
|
||||
begin
|
||||
ts := _ts;
|
||||
ms := _ms;
|
||||
i := 1;
|
||||
j := 1;
|
||||
compare := true;
|
||||
freelist;
|
||||
repeat
|
||||
if (i > length(ts)) and (j > length(ms)) then goto succ;
|
||||
if (i > length(ts)) or (j > length(ms)) then goto fail;
|
||||
if ts[i] = ms[j] then begin
|
||||
inc(i);
|
||||
inc(j);
|
||||
if j > length(ms) then goto succ;
|
||||
end else
|
||||
if ts[i] = '?' then begin
|
||||
inc(i);
|
||||
inc(j);
|
||||
end else
|
||||
if ts[i] = '*' then begin
|
||||
inc(i);
|
||||
if i > length(ts) then goto succ;
|
||||
z := copy(ts, i, 255);
|
||||
if pos('*', z) > 0 then z := copy(z, 1, pos('*', z) - 1);
|
||||
if pos('?', z) > 0 then z := copy(z, 1, pos('?', z) - 1);
|
||||
if pos('%', z) > 0 then z := copy(z, 1, pos('%', z) - 1);
|
||||
while (j <= length(ms)) and (copy(ms, j, length(z)) <> z) do begin
|
||||
while (j < length(ms)) and (ms[j] <> ts[i]) do inc(j);
|
||||
if j > length(ms) then goto fail;
|
||||
if copy(ms, j, length(z)) <> z then inc(j);
|
||||
end;
|
||||
end else
|
||||
if ts[i] = '%' then begin
|
||||
inc(i);
|
||||
n := i;
|
||||
while (i <= length(ts)) and (ts[i] <> '%') do inc(i);
|
||||
if i > length(ts) then goto fail;
|
||||
v := copy(ts, n, i - n);
|
||||
v := upst(v);
|
||||
inc(i);
|
||||
n := j;
|
||||
if i <= length(ts) then begin
|
||||
while (j <= length(ms)) and (ms[j] <> ts[i]) do inc(j);
|
||||
if j > length(ms) then goto fail;
|
||||
end else begin
|
||||
j := length(ms) + 1;
|
||||
end;
|
||||
z := copy(ms, n, j - n);
|
||||
if fvar = nil then begin
|
||||
getmem(fvar, sizeof(trec));
|
||||
vrec := fvar;
|
||||
end else begin
|
||||
getmem(vrec^.next, sizeof(trec));
|
||||
vrec := vrec^.next;
|
||||
end;
|
||||
fillchar(vrec^, sizeof(trec), #0);
|
||||
vrec^.name := v;
|
||||
vrec^.valu := z;
|
||||
if fglo = nil then begin
|
||||
getmem(fglo, sizeof(trec));
|
||||
vglo := fglo;
|
||||
rrec := fglo;
|
||||
fillchar(vglo^, sizeof(trec), #0);
|
||||
end else begin
|
||||
rrec := fglo;
|
||||
while (rrec <> nil) and (rrec^.name <> v) do begin
|
||||
vglo := rrec;
|
||||
rrec := rrec^.next;
|
||||
end;
|
||||
if rrec = nil then begin
|
||||
getmem(vglo^.next, sizeof(trec));
|
||||
vglo := vglo^.next;
|
||||
rrec := vglo;
|
||||
fillchar(vglo^, sizeof(trec), #0);
|
||||
end;
|
||||
end;
|
||||
rrec^.name := v;
|
||||
rrec^.valu := z;
|
||||
end else begin
|
||||
if (i > 1) and (j > i) then
|
||||
if compare(ts, copy(ms, j, length(ms) - j + 1)) then goto succ
|
||||
else goto fail
|
||||
else goto fail;
|
||||
end;
|
||||
until false;
|
||||
fail:
|
||||
compare := false;
|
||||
freelist;
|
||||
exit;
|
||||
succ:
|
||||
exit;
|
||||
end;
|
||||
|
||||
procedure setvar;
|
||||
begin
|
||||
vglo := fvar;
|
||||
while vglo <> Nil do begin
|
||||
if vglo^.name = UpSt(vn) then break;
|
||||
vglo := vglo^.next;
|
||||
end;
|
||||
if vglo = Nil then vglo := NewEList(fvar, sizeof(trec), false);
|
||||
vglo^.name := UpSt(vn);
|
||||
vglo^.valu := vv;
|
||||
end;
|
||||
|
||||
function getvar;
|
||||
var
|
||||
tv : string;
|
||||
begin
|
||||
getvar := '';
|
||||
vrec := fvar;
|
||||
tv := vn;
|
||||
tv := upst(tv);
|
||||
while vrec <> nil do begin
|
||||
if vrec^.name = tv then begin
|
||||
getvar := vrec^.valu;
|
||||
exit;
|
||||
end;
|
||||
vrec := vrec^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure setglo;
|
||||
begin
|
||||
vglo := fglo;
|
||||
while vglo <> Nil do begin
|
||||
if vglo^.name = UpSt(vn) then break;
|
||||
vglo := vglo^.next;
|
||||
end;
|
||||
if vglo = Nil then vglo := NewEList(fglo, sizeof(trec), false);
|
||||
vglo^.name := UpSt(vn);
|
||||
vglo^.valu := vv;
|
||||
end;
|
||||
|
||||
function getglo;
|
||||
var
|
||||
tv : string;
|
||||
begin
|
||||
getglo := '';
|
||||
vglo := fglo;
|
||||
tv := vn;
|
||||
tv := upst(tv);
|
||||
while vglo <> nil do begin
|
||||
if vglo^.name = tv then begin
|
||||
getglo := vglo^.valu;
|
||||
exit;
|
||||
end;
|
||||
vglo := vglo^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure freeglob;
|
||||
begin
|
||||
vglo := fglo;
|
||||
while vglo <> nil do begin
|
||||
rrec := vglo;
|
||||
vglo := vglo^.next;
|
||||
freemem(rrec, sizeof(trec));
|
||||
end;
|
||||
fglo := nil;
|
||||
end;
|
||||
|
||||
function parstr;
|
||||
var
|
||||
tv : string;
|
||||
begin
|
||||
tv := '';
|
||||
vrec := fvar;
|
||||
while vrec <> nil do begin
|
||||
tv := tv + ' ' + vrec^.valu;
|
||||
vrec := vrec^.next;
|
||||
end;
|
||||
parstr := tv;
|
||||
end;
|
||||
|
||||
function parse;
|
||||
var i,
|
||||
p : integer;
|
||||
s : string;
|
||||
rs : string;
|
||||
begin
|
||||
s := '';
|
||||
i := 0;
|
||||
repeat
|
||||
inc(i);
|
||||
rs := wordn(vn, '%', i + 1);
|
||||
rs := getglo(rs);
|
||||
s := s + wordn(vn, '%', i);
|
||||
p := wordp(vn, '%', i + 1);
|
||||
if p > 0 then begin
|
||||
if al then s := copy(s, 1, p - 2);
|
||||
if al then s := s + space(p - 2 - length(s));
|
||||
end;
|
||||
s := s + rs;
|
||||
if rs <> '' then inc(i);
|
||||
until i > words(vn, '%');
|
||||
parse := s;
|
||||
end;
|
||||
|
||||
begin
|
||||
fvar := nil;
|
||||
fglo := nil;
|
||||
end.
|
Reference in New Issue
Block a user