update to 0.7.9
This commit is contained in:
@@ -43,17 +43,17 @@ begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, CryptoCodecs[XOR_CODEC]) = 0) then
|
||||
begin
|
||||
SetBits(Option^, 0, 0, 5);
|
||||
SetBits(Option^, 0, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, CryptoCodecs[AES_CODEC]) = 0) then
|
||||
begin
|
||||
SetBits(Option^, 1, 0, 5);
|
||||
SetBits(Option^, 1, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, CryptoCodecs[RC4_CODEC]) = 0) then
|
||||
begin
|
||||
SetBits(Option^, 2, 0, 5);
|
||||
SetBits(Option^, 2, 0, 3);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -63,37 +63,8 @@ end;
|
||||
procedure CryptoScan1(Instance, Depth: Integer; Input: PByte;
|
||||
Size, SizeEx: NativeInt; Output: _PrecompOutput; Add: _PrecompAdd;
|
||||
Funcs: PPrecompFuncs);
|
||||
var
|
||||
X: Integer;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], CryptoCodecs);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
Output(Instance, Input, DI1.OldSize);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := DI1.OldSize;
|
||||
SI.NewSize := DI1.NewSize;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(CryptoCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, -1);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function CryptoScan2(Instance, Depth: Integer; Input: Pointer; Size: NativeInt;
|
||||
@@ -110,7 +81,7 @@ begin
|
||||
begin
|
||||
Output(Instance, Input, StreamInfo^.OldSize);
|
||||
StreamInfo^.NewSize := StreamInfo^.OldSize;
|
||||
Funcs^.LogScan2(CryptoCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(CryptoCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, -1);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -124,7 +95,7 @@ var
|
||||
Res: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
Res := 0;
|
||||
if not Funcs^.GetResource(StreamInfo^.Resource, nil, @Res) then
|
||||
exit;
|
||||
@@ -142,7 +113,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
Result := True;
|
||||
Funcs^.LogProcess(CryptoCodecs[GetBits(StreamInfo^.Option, 0, 5)], nil,
|
||||
Funcs^.LogProcess(CryptoCodecs[GetBits(StreamInfo^.Option, 0, 3)], nil,
|
||||
StreamInfo^.OldSize, -1, -1, Result);
|
||||
end;
|
||||
end;
|
||||
@@ -155,7 +126,7 @@ var
|
||||
Res: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
Res := 0;
|
||||
if not Funcs^.GetResource(StreamInfo.Resource, nil, @Res) then
|
||||
exit;
|
||||
@@ -174,7 +145,7 @@ begin
|
||||
end;
|
||||
Output(Instance, Input, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
Funcs^.LogRestore(CryptoCodecs[GetBits(StreamInfo.Option, 0, 5)], nil,
|
||||
Funcs^.LogRestore(CryptoCodecs[GetBits(StreamInfo.Option, 0, 3)], nil,
|
||||
StreamInfo.OldSize, -1, -1, Result);
|
||||
end;
|
||||
end;
|
||||
|
@@ -4,8 +4,7 @@ interface
|
||||
|
||||
uses
|
||||
InitCode,
|
||||
Utils,
|
||||
UIMain,
|
||||
Utils, LibImport,
|
||||
PrecompUtils,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.StrUtils,
|
||||
@@ -52,7 +51,7 @@ type
|
||||
TPrecompOutput = procedure(Instance: Integer; const Buffer: Pointer;
|
||||
Size: Integer)cdecl;
|
||||
TPrecompAdd = procedure(Instance: Integer; Info: LStrInfo1; Codec: PChar;
|
||||
DepthInfo: PDepthInfo)cdecl;
|
||||
Reserved: Pointer)cdecl;
|
||||
|
||||
TPrecompInit = function(Command: PChar; Count: Integer; Funcs: LPrecompFuncs)
|
||||
: Boolean cdecl;
|
||||
@@ -75,6 +74,7 @@ type
|
||||
PDLLStruct = ^TDLLStruct;
|
||||
|
||||
TDLLStruct = record
|
||||
Lib: TLibImport;
|
||||
Names: TArray<String>;
|
||||
Init: TPrecompInit;
|
||||
Free: TPrecompFree;
|
||||
@@ -88,11 +88,11 @@ type
|
||||
var
|
||||
CodecIndex: TArray<Integer>;
|
||||
CodecAdd: TArray<_PrecompAdd>;
|
||||
DLLList: TStringDynArray;
|
||||
|
||||
CodecDLL: TArray<TDLLStruct>;
|
||||
|
||||
procedure AddStream(Instance: Integer; Info: LStrInfo1; Codec: PChar;
|
||||
DepthInfo: PDepthInfo)cdecl;
|
||||
Reserved: Pointer)cdecl;
|
||||
var
|
||||
SI: _StrInfo1;
|
||||
begin
|
||||
@@ -106,7 +106,7 @@ begin
|
||||
SI.Status := TStreamStatus.None;
|
||||
LongRec(SI.Option).Lo := Info^.Option;
|
||||
LongRec(SI.Option).Hi := CodecIndex[Instance];
|
||||
CodecAdd[Instance](Instance, @SI, Codec, DepthInfo)
|
||||
CodecAdd[Instance](Instance, @SI, Codec, nil)
|
||||
end;
|
||||
|
||||
function DLLInit(Command: PChar; Count: Integer; Funcs: PPrecompFuncs): Boolean;
|
||||
@@ -258,7 +258,7 @@ function ImageRvaToVa(NtHeaders: Pointer; Base: Pointer; Rva: ULONG;
|
||||
LastRvaSection: Pointer): Pointer; stdcall; external 'dbghelp.dll';
|
||||
|
||||
procedure ImageExportedFunctionNames(const ImageName: string;
|
||||
NamesList: TStrings);
|
||||
NamesList: TStrings)overload;
|
||||
var
|
||||
I: Integer;
|
||||
FileHandle: THandle;
|
||||
@@ -270,65 +270,41 @@ var
|
||||
Names: PAnsiChar;
|
||||
NamesDataLeft: Integer;
|
||||
begin
|
||||
// NOTE: our policy in this procedure is to exit upon any failure and return an empty list
|
||||
|
||||
NamesList.Clear;
|
||||
|
||||
FileHandle := CreateFile(PChar(ImageName), GENERIC_READ, FILE_SHARE_READ, nil,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if FileHandle = INVALID_HANDLE_VALUE then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
try
|
||||
ImageHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
|
||||
if ImageHandle = 0 then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
try
|
||||
ImagePointer := MapViewOfFile(ImageHandle, FILE_MAP_READ, 0, 0, 0);
|
||||
if not Assigned(ImagePointer) then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
try
|
||||
Header := ImageNtHeader(ImagePointer);
|
||||
if not Assigned(Header) then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
if Header.Signature <> $00004550 then
|
||||
begin // "PE\0\0" as a DWORD.
|
||||
exit;
|
||||
end;
|
||||
|
||||
ExportTable := ImageRvaToVa(Header, ImagePointer,
|
||||
Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
|
||||
if not Assigned(ExportTable) then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
NamesPointer := ImageRvaToVa(Header, ImagePointer,
|
||||
Cardinal(ExportTable.AddressOfNames), nil);
|
||||
if not Assigned(NamesPointer) then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
Names := ImageRvaToVa(Header, ImagePointer,
|
||||
Cardinal(NamesPointer^), nil);
|
||||
if not Assigned(Names) then
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
NamesDataLeft := Header.OptionalHeader.DataDirectory[0].Size;
|
||||
for I := 0 to ExportTable.NumberOfNames - 1 do
|
||||
begin
|
||||
NamesList.Add(Names);
|
||||
// Locate the next name
|
||||
while (Names^ <> chr(0)) and (NamesDataLeft > 0) do
|
||||
begin
|
||||
Inc(Names);
|
||||
@@ -338,7 +314,6 @@ begin
|
||||
end;
|
||||
finally
|
||||
UnmapViewOfFile(ImagePointer);
|
||||
// Ignore error as there is not much we could do.
|
||||
end;
|
||||
finally
|
||||
CloseHandle(ImageHandle);
|
||||
@@ -348,61 +323,111 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ImageExportedFunctionNames(const ImageName: TCustomMemoryStream;
|
||||
NamesList: TStrings)overload;
|
||||
var
|
||||
I, J: Integer;
|
||||
I: Integer;
|
||||
Header: PIMAGE_NT_HEADERS;
|
||||
ExportTable: PIMAGE_EXPORT_DIRECTORY;
|
||||
NamesPointer: Pointer;
|
||||
Names: PAnsiChar;
|
||||
NamesDataLeft: Integer;
|
||||
begin
|
||||
NamesList.Clear;
|
||||
Header := ImageNtHeader(ImageName.Memory);
|
||||
if not Assigned(Header) then
|
||||
exit;
|
||||
if Header.Signature <> $00004550 then
|
||||
exit;
|
||||
ExportTable := ImageRvaToVa(Header, ImageName.Memory,
|
||||
Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
|
||||
if not Assigned(ExportTable) then
|
||||
exit;
|
||||
NamesPointer := ImageRvaToVa(Header, ImageName.Memory,
|
||||
Cardinal(ExportTable.AddressOfNames), nil);
|
||||
if not Assigned(NamesPointer) then
|
||||
exit;
|
||||
Names := ImageRvaToVa(Header, ImageName.Memory, Cardinal(NamesPointer^), nil);
|
||||
if not Assigned(Names) then
|
||||
exit;
|
||||
NamesDataLeft := Header.OptionalHeader.DataDirectory[0].Size;
|
||||
for I := 0 to ExportTable.NumberOfNames - 1 do
|
||||
begin
|
||||
NamesList.Add(Names);
|
||||
while (Names^ <> chr(0)) and (NamesDataLeft > 0) do
|
||||
begin
|
||||
Inc(Names);
|
||||
dec(NamesDataLeft);
|
||||
end;
|
||||
Inc(Names);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
I, J, X: Integer;
|
||||
S: String;
|
||||
DLLList: TStringDynArray;
|
||||
FuncList: TStringList;
|
||||
DLLStruct: PDLLStruct;
|
||||
DLLHandle: THandle;
|
||||
RStream: TResourceStream;
|
||||
|
||||
initialization
|
||||
|
||||
FuncList := TStringList.Create;
|
||||
FuncList.Clear;
|
||||
DLLList := TDirectory.GetFiles(ExpandPath(PluginsPath, True), '*.dll',
|
||||
TSearchOption.soTopDirectoryOnly);
|
||||
FuncList := TStringList.Create;
|
||||
for I := Low(DLLList) to High(DLLList) do
|
||||
begin
|
||||
ImageExportedFunctionNames(DLLList[I], FuncList);
|
||||
if (FuncList.IndexOf('PrecompInit') >= 0) and
|
||||
(FuncList.IndexOf('PrecompCodec') >= 0) then
|
||||
begin
|
||||
New(DLLStruct);
|
||||
DLLHandle := LoadLibrary(PChar(DLLList[I]));
|
||||
if DLLHandle >= 32 then
|
||||
X := Length(CodecDLL);
|
||||
SetLength(CodecDLL, Succ(X));
|
||||
CodecDLL[X].Lib := TLibImport.Create;
|
||||
CodecDLL[X].Lib.LoadLib(PChar(DLLList[I]));
|
||||
if CodecDLL[X].Lib.Loaded then
|
||||
begin
|
||||
@DLLStruct^.Init := GetProcAddress(DLLHandle, 'PrecompInit');
|
||||
Assert(@DLLStruct^.Init <> nil);
|
||||
@DLLStruct^.Free := GetProcAddress(DLLHandle, 'PrecompFree');
|
||||
@DLLStruct^.Codec := GetProcAddress(DLLHandle, 'PrecompCodec');
|
||||
@DLLStruct^.Scan1 := GetProcAddress(DLLHandle, 'PrecompScan1');
|
||||
@DLLStruct^.Scan2 := GetProcAddress(DLLHandle, 'PrecompScan2');
|
||||
@DLLStruct^.Process := GetProcAddress(DLLHandle, 'PrecompProcess');
|
||||
@DLLStruct^.Restore := GetProcAddress(DLLHandle, 'PrecompRestore');
|
||||
CodecDLL[X].Init := CodecDLL[X].Lib.GetProcAddr('PrecompInit');
|
||||
Assert(@CodecDLL[X].Init <> nil);
|
||||
@CodecDLL[X].Free := CodecDLL[X].Lib.GetProcAddr('PrecompFree');
|
||||
@CodecDLL[X].Codec := CodecDLL[X].Lib.GetProcAddr('PrecompCodec');
|
||||
@CodecDLL[X].Scan1 := CodecDLL[X].Lib.GetProcAddr('PrecompScan1');
|
||||
@CodecDLL[X].Scan2 := CodecDLL[X].Lib.GetProcAddr('PrecompScan2');
|
||||
@CodecDLL[X].Process := CodecDLL[X].Lib.GetProcAddr('PrecompProcess');
|
||||
@CodecDLL[X].Restore := CodecDLL[X].Lib.GetProcAddr('PrecompRestore');
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(ChangeFileExt(ExtractFileName(DLLList[I]), ''),
|
||||
PLUGIN_LIBRARY);
|
||||
Insert(DLLStruct^, CodecDLL, Length(CodecDLL));
|
||||
J := 0;
|
||||
while Assigned(CodecDLL[Pred(Length(CodecDLL))].Codec(J)) do
|
||||
while Assigned(CodecDLL[X].Codec(J)) do
|
||||
begin
|
||||
S := String(CodecDLL[Pred(Length(CodecDLL))].Codec(J));
|
||||
Insert(S, CodecDLL[Pred(Length(CodecDLL))].Names,
|
||||
Length(CodecDLL[Pred(Length(CodecDLL))].Names));
|
||||
S := String(CodecDLL[X].Codec(J));
|
||||
if SameText(ChangeFileExt(ExtractFileName(S), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
FORCEDMETHOD := True;
|
||||
Insert(S, CodecDLL[X].Names, Length(CodecDLL[X].Names));
|
||||
Insert(S, Codec.Names, Length(Codec.Names));
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddCodec(S);
|
||||
if not SameText(ChangeFileExt(ExtractFileName(S), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddCodec(S);
|
||||
Inc(J);
|
||||
end;
|
||||
if J = 0 then
|
||||
begin
|
||||
Insert(ChangeFileExt(ExtractFileName(DLLList[I]), ''),
|
||||
CodecDLL[Pred(Length(CodecDLL))].Names,
|
||||
Length(CodecDLL[Pred(Length(CodecDLL))].Names));
|
||||
CodecDLL[X].Names, Length(CodecDLL[X].Names));
|
||||
Insert(ChangeFileExt(ExtractFileName(DLLList[I]), ''), Codec.Names,
|
||||
Length(Codec.Names));
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddCodec(ChangeFileExt(ExtractFileName(DLLList[I]), ''));
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
CodecDLL[X].Lib.Free;
|
||||
SetLength(CodecDLL, X);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@@ -416,4 +441,9 @@ Codec.Scan2 := @DLLScan2;
|
||||
Codec.Process := @DLLProcess;
|
||||
Codec.Restore := @DLLRestore;
|
||||
|
||||
finalization
|
||||
|
||||
for I := High(CodecDLL) downto Low(CodecDLL) do
|
||||
CodecDLL[I].Lib.Free;
|
||||
|
||||
end.
|
||||
|
432
precompressor/PrecompDStorage.pas
Normal file
432
precompressor/PrecompDStorage.pas
Normal file
@@ -0,0 +1,432 @@
|
||||
unit PrecompDStorage;
|
||||
|
||||
{$POINTERMATH ON}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
DStorage,
|
||||
Utils,
|
||||
PrecompUtils,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.Math;
|
||||
|
||||
var
|
||||
Codec: TPrecompressor;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
DStorageCodecs: array of PChar = ['gdeflate'];
|
||||
CODEC_COUNT = 1;
|
||||
GDEFLATE_CODEC = 0;
|
||||
|
||||
const
|
||||
D_MAXSIZE = 16 * 1024 * 1024;
|
||||
|
||||
var
|
||||
SOList: array of array [0 .. CODEC_COUNT - 1] of TSOList;
|
||||
ctx: array of IDStorageCompressionCodec;
|
||||
DMaxSize: Integer = D_MAXSIZE;
|
||||
CodecAvailable, CodecEnabled: TArray<Boolean>;
|
||||
|
||||
const
|
||||
GDefSig = $FB04;
|
||||
|
||||
type
|
||||
PGDefSI = ^TGDefSI;
|
||||
|
||||
TGDefSI = record
|
||||
CSize, DSize: Integer;
|
||||
end;
|
||||
|
||||
function GetGDefSI(Buff: PByte; Size: Integer; StreamInfo: PGDefSI): Boolean;
|
||||
type
|
||||
PHdr = ^THdr;
|
||||
|
||||
THdr = packed record
|
||||
Signature, BlkCount: Word;
|
||||
Unk1, LastBlkSize: Cardinal;
|
||||
end;
|
||||
const
|
||||
MinSize = 64;
|
||||
BlkSize = 65536;
|
||||
FailSize = 884;
|
||||
var
|
||||
I, J: Integer;
|
||||
DefHdr: THdr;
|
||||
StartPos1, StartPos2, LastPos: NativeInt;
|
||||
begin
|
||||
Result := False;
|
||||
if Size < 12 then
|
||||
exit;
|
||||
if PHdr(Buff)^.Signature = GDefSig then
|
||||
begin
|
||||
DefHdr := PHdr(Buff)^;
|
||||
if DefHdr.BlkCount = 0 then
|
||||
exit;
|
||||
StreamInfo^.CSize := 0;
|
||||
StreamInfo^.DSize := 0;
|
||||
StartPos1 := sizeof(THdr);
|
||||
StartPos2 := sizeof(THdr) + Pred(DefHdr.BlkCount) * Integer.Size;
|
||||
LastPos := StartPos2;
|
||||
for I := 0 to DefHdr.BlkCount - 1 do
|
||||
begin
|
||||
if (LastPos + Integer.Size > Size) or (PInteger(Buff + LastPos)^ = 0) then
|
||||
exit;
|
||||
if I = DefHdr.BlkCount - 1 then
|
||||
J := DefHdr.LastBlkSize
|
||||
else
|
||||
J := (PInteger(Buff + StartPos1) + I)^ - (LastPos - StartPos2);
|
||||
Inc(LastPos, J);
|
||||
if (InRange(J, MinSize, BlkSize + FailSize) = False) or (LastPos > Size)
|
||||
or (PInteger(Buff + LastPos - Integer.Size)^ <> 0) then
|
||||
exit;
|
||||
Inc(StreamInfo^.CSize, J);
|
||||
Inc(StreamInfo^.DSize, BlkSize);
|
||||
end;
|
||||
Inc(StreamInfo^.CSize, StartPos2);
|
||||
Result := StreamInfo^.CSize >= MinSize;
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetGDefUS(Instance: Integer; Input: PByte; Pos: NativeInt;
|
||||
StreamInfo: PGDefSI; Output: _PrecompOutput; Add: _PrecompAdd;
|
||||
Funcs: PPrecompFuncs): size_t;
|
||||
const
|
||||
MinSize = 64;
|
||||
var
|
||||
Buffer: PByte;
|
||||
SI: _StrInfo1;
|
||||
begin
|
||||
Result := 0;
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo^.DSize);
|
||||
if not Assigned(ctx[Instance]) then
|
||||
DStorageCreateCompressionCodec(DSTORAGE_COMPRESSION_FORMAT_GDEFLATE, 1,
|
||||
IID_IDStorageCompressionCodec, ctx[Instance]);
|
||||
if not Failed(ctx[Instance].DecompressBuffer(Input + Pos, StreamInfo^.CSize,
|
||||
Buffer, StreamInfo^.DSize, @Result)) then
|
||||
if (Result > MinSize) and (Result > StreamInfo^.CSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Result);
|
||||
SI.Position := Pos;
|
||||
SI.OldSize := StreamInfo^.CSize;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, GDEFLATE_CODEC, 0, 3);
|
||||
SI.Status := TStreamStatus.None;
|
||||
SI.NewSize := Result;
|
||||
Funcs^.LogScan1(DStorageCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetDefLevel(Index: Integer): DSTORAGE_COMPRESSION;
|
||||
begin
|
||||
case Index of
|
||||
1:
|
||||
Result := DSTORAGE_COMPRESSION_DEFAULT;
|
||||
2:
|
||||
Result := DSTORAGE_COMPRESSION_FASTEST;
|
||||
3:
|
||||
Result := DSTORAGE_COMPRESSION_BEST_RATIO;
|
||||
else
|
||||
Result := DSTORAGE_COMPRESSION_DEFAULT;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DStorageInit(Command: PChar; Count: Integer;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
Options: TArray<Integer>;
|
||||
S: String;
|
||||
X, Y: Integer;
|
||||
begin
|
||||
Result := True;
|
||||
SetLength(SOList, Count);
|
||||
for X := Low(SOList) to High(SOList) do
|
||||
for Y := Low(SOList[X]) to High(SOList[X]) do
|
||||
SOList[X, Y] := TSOList.Create([], TSOMethod.MTF);
|
||||
for X := Low(CodecAvailable) to High(CodecAvailable) do
|
||||
begin
|
||||
CodecAvailable[X] := False;
|
||||
CodecEnabled[X] := False;
|
||||
end;
|
||||
for X := Low(CodecAvailable) to High(CodecAvailable) do
|
||||
CodecAvailable[X] := DStorage.DLLLoaded;
|
||||
X := 0;
|
||||
while Funcs^.GetCodec(Command, X, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, X, False);
|
||||
if (CompareText(S, DStorageCodecs[GDEFLATE_CODEC]) = 0) and DStorage.DLLLoaded
|
||||
then
|
||||
begin
|
||||
CodecEnabled[GDEFLATE_CODEC] := True;
|
||||
if Funcs^.GetParam(Command, X, 'l') <> '' then
|
||||
for I := Low(SOList) to High(SOList) do
|
||||
SOList[I][GDEFLATE_CODEC].Update
|
||||
([StrToInt(Funcs^.GetParam(Command, X, 'l'))], True);
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
if CodecAvailable[GDEFLATE_CODEC] then
|
||||
begin
|
||||
SetLength(ctx, Count);
|
||||
for X := Low(ctx) to High(ctx) do
|
||||
ctx[X] := nil;
|
||||
end;
|
||||
SetLength(Options, 0);
|
||||
for I := 1 to 3 do
|
||||
Insert(I, Options, Length(Options));
|
||||
for X := Low(SOList) to High(SOList) do
|
||||
for Y := Low(SOList[X]) to High(SOList[X]) do
|
||||
if SOList[X, Y].Count = 0 then
|
||||
SOList[X, Y].Update(Options);
|
||||
end;
|
||||
|
||||
procedure DStorageFree(Funcs: PPrecompFuncs);
|
||||
var
|
||||
X, Y: Integer;
|
||||
begin
|
||||
for X := Low(SOList) to High(SOList) do
|
||||
for Y := Low(SOList[X]) to High(SOList[X]) do
|
||||
SOList[X, Y].Free;
|
||||
end;
|
||||
|
||||
function DStorageParse(Command: PChar; Option: PInteger;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
S: String;
|
||||
I: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, DStorageCodecs[GDEFLATE_CODEC]) = 0) and DStorage.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, GDEFLATE_CODEC, 0, 3);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 2);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DStorageScan1(Instance, Depth: Integer; Input: PByte;
|
||||
Size, SizeEx: NativeInt; Output: _PrecompOutput; Add: _PrecompAdd;
|
||||
Funcs: PPrecompFuncs);
|
||||
var
|
||||
Buffer: PByte;
|
||||
Pos: NativeInt;
|
||||
X, Y, Z: Integer;
|
||||
SI: _StrInfo1;
|
||||
GDefSI: TGDefSI;
|
||||
begin
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Pos := 0;
|
||||
while Pos < Size do
|
||||
begin
|
||||
if PWord(Input + Pos)^ = GDefSig then
|
||||
if GetGDefSI(Input + Pos, SizeEx - Pos, @GDefSI) then
|
||||
begin
|
||||
try
|
||||
if GetGDefUS(Instance, Input, Pos, @GDefSI, Output, Add, Funcs) > 0
|
||||
then
|
||||
begin
|
||||
Inc(Pos, GDefSI.CSize);
|
||||
continue;
|
||||
end;
|
||||
except
|
||||
end;
|
||||
end;
|
||||
Inc(Pos);
|
||||
end;
|
||||
end;
|
||||
|
||||
function DStorageScan2(Instance, Depth: Integer; Input: Pointer;
|
||||
Size: NativeInt; StreamInfo: PStrInfo2; Offset: PInteger;
|
||||
Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
Buffer: PByte;
|
||||
B: Boolean;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
Res: size_t;
|
||||
GDefSI: TGDefSI;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if (StreamInfo^.OldSize > 0) and REPROCESSED then
|
||||
if (Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^)
|
||||
.Lo = StreamInfo^.OldSize) and
|
||||
(Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Lo <
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi)
|
||||
then
|
||||
StreamInfo^.OldSize :=
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi;
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
begin
|
||||
if not GetGDefSI(Input, Size, @GDefSI) then
|
||||
exit;
|
||||
StreamInfo^.OldSize := GDefSI.CSize;
|
||||
end;
|
||||
if StreamInfo^.NewSize > 0 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo^.NewSize);
|
||||
if not Assigned(ctx[Instance]) then
|
||||
DStorageCreateCompressionCodec(DSTORAGE_COMPRESSION_FORMAT_GDEFLATE, 1,
|
||||
IID_IDStorageCompressionCodec, ctx[Instance]);
|
||||
if (Failed(ctx[Instance].DecompressBuffer(Input, StreamInfo^.OldSize,
|
||||
Buffer, StreamInfo^.NewSize, @Res)) = False) and
|
||||
(Res = StreamInfo^.NewSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
Result := True;
|
||||
end;
|
||||
end
|
||||
else if (StreamInfo^.NewSize <= 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, GDefSI.DSize);
|
||||
if not Assigned(ctx[Instance]) then
|
||||
DStorageCreateCompressionCodec(DSTORAGE_COMPRESSION_FORMAT_GDEFLATE, 1,
|
||||
IID_IDStorageCompressionCodec, ctx[Instance]);
|
||||
if not Failed(ctx[Instance].DecompressBuffer(Input, StreamInfo^.OldSize,
|
||||
Buffer, GDefSI.DSize, @Res)) then
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
StreamInfo^.NewSize := Res;
|
||||
Funcs^.LogScan2(DStorageCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DStorageProcess(Instance, Depth: Integer; OldInput, NewInput: Pointer;
|
||||
StreamInfo: PStrInfo2; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
Buffer: PByte;
|
||||
Params: String;
|
||||
A, B: Integer;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
Res1: size_t;
|
||||
Res2: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
if not Assigned(ctx[Instance]) then
|
||||
DStorageCreateCompressionCodec(DSTORAGE_COMPRESSION_FORMAT_GDEFLATE, 1,
|
||||
IID_IDStorageCompressionCodec, ctx[Instance]);
|
||||
A := ctx[Instance].CompressBufferBound(StreamInfo^.NewSize);
|
||||
Buffer := Funcs^.Allocator(Instance, A);
|
||||
SOList[Instance][X].Index := 0;
|
||||
while SOList[Instance][X].Get(I) >= 0 do
|
||||
begin
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 3, 2) <> I then
|
||||
continue;
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) then
|
||||
begin
|
||||
Res1 := StreamInfo^.OldSize;
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
Params := '';
|
||||
case X of
|
||||
GDEFLATE_CODEC:
|
||||
begin
|
||||
Params := 'l' + I.ToString;
|
||||
if not Result then
|
||||
if Failed(ctx[Instance].CompressBuffer(NewInput,
|
||||
StreamInfo^.NewSize, GetDefLevel(I), Buffer, A, @Res1)) then
|
||||
Res1 := 0;
|
||||
end;
|
||||
end;
|
||||
if not Result then
|
||||
Result := (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(DStorageCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, Res1, Result);
|
||||
if Result or (StreamInfo^.Status >= TStreamStatus.Predicted) then
|
||||
break;
|
||||
end;
|
||||
if Result then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 3, 5);
|
||||
SOList[Instance][X].Add(I);
|
||||
end;
|
||||
end;
|
||||
|
||||
function DStorageRestore(Instance, Depth: Integer; Input, InputExt: Pointer;
|
||||
StreamInfo: _StrInfo3; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
Buffer: PByte;
|
||||
Params: String;
|
||||
A: Integer;
|
||||
X: Integer;
|
||||
Res1: size_t;
|
||||
Res2: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
if not Assigned(ctx[Instance]) then
|
||||
DStorageCreateCompressionCodec(DSTORAGE_COMPRESSION_FORMAT_GDEFLATE, 1,
|
||||
IID_IDStorageCompressionCodec, ctx[Instance]);
|
||||
A := ctx[Instance].CompressBufferBound(StreamInfo.NewSize);
|
||||
Buffer := Funcs^.Allocator(Instance, A);
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 2).ToString;
|
||||
case X of
|
||||
GDEFLATE_CODEC:
|
||||
begin
|
||||
if not Result then
|
||||
if Failed(ctx[Instance].CompressBuffer(Input, StreamInfo.NewSize,
|
||||
GetDefLevel(GetBits(StreamInfo.Option, 3, 5)), Buffer, A, @Res1))
|
||||
then
|
||||
Res1 := 0;
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogRestore(DStorageCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize, Res1, True);
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
begin
|
||||
Output(Instance, Buffer, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
I: Integer;
|
||||
|
||||
initialization
|
||||
|
||||
Codec.Names := [];
|
||||
for I := Low(DStorageCodecs) to High(DStorageCodecs) do
|
||||
begin
|
||||
Codec.Names := Codec.Names + [DStorageCodecs[I]];
|
||||
StockMethods.Add(DStorageCodecs[I]);
|
||||
end;
|
||||
Codec.Initialised := False;
|
||||
Codec.Init := @DStorageInit;
|
||||
Codec.Free := @DStorageFree;
|
||||
Codec.Parse := @DStorageParse;
|
||||
Codec.Scan1 := @DStorageScan1;
|
||||
Codec.Scan2 := @DStorageScan2;
|
||||
Codec.Process := @DStorageProcess;
|
||||
Codec.Restore := @DStorageRestore;
|
||||
SetLength(CodecAvailable, Length(Codec.Names));
|
||||
SetLength(CodecEnabled, Length(Codec.Names));
|
||||
|
||||
end.
|
@@ -255,6 +255,13 @@ begin
|
||||
Inc(CodecSize[Instance], Size);
|
||||
end;
|
||||
|
||||
procedure ExecOutput3(Instance: Integer; const Buffer: Pointer;
|
||||
Size: Integer)cdecl;
|
||||
begin
|
||||
CodecOutput[Instance](Instance, Buffer, Size);
|
||||
Inc(CodecSize[Instance], Size);
|
||||
end;
|
||||
|
||||
function ExeEncode(Index, Instance: Integer; Input: Pointer;
|
||||
StreamInfo: PStrInfo2; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
@@ -346,17 +353,23 @@ begin
|
||||
end;
|
||||
|
||||
function ExeDecode(Index, Instance: Integer; Input: Pointer;
|
||||
StreamInfo: PStrInfo2; Funcs: PPrecompFuncs): Boolean;
|
||||
StreamInfo: PStrInfo2; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
Buffer: PByte;
|
||||
X: Integer;
|
||||
Executed: Boolean;
|
||||
S, T: String;
|
||||
Res: Integer;
|
||||
LOutput: _ExecOutput;
|
||||
begin
|
||||
Result := False;
|
||||
CodecSize[Instance] := 0;
|
||||
CodecAllocator[Instance] := Funcs^.Allocator;
|
||||
CodecOutput[Instance] := Output;
|
||||
if Assigned(Output) then
|
||||
LOutput := ExecOutput3
|
||||
else
|
||||
LOutput := ExecOutput2;
|
||||
with CodecExe[Index] do
|
||||
begin
|
||||
if not DirectoryExists(WorkDir[Instance, 1]) then
|
||||
@@ -398,7 +411,7 @@ begin
|
||||
PChar(WorkDir[Instance, 1]))
|
||||
else
|
||||
Executed := PrecompExecStdout(Instance, PChar(Exec[1]), PChar(S),
|
||||
PChar(WorkDir[Instance, 1]), ExecOutput2);
|
||||
PChar(WorkDir[Instance, 1]), LOutput);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
@@ -407,7 +420,7 @@ begin
|
||||
PChar(WorkDir[Instance, 1]), Input, StreamInfo^.NewSize)
|
||||
else
|
||||
Executed := ExecStdioProcess(Ctx[Instance, 1], Input,
|
||||
StreamInfo^.NewSize, StreamInfo^.OldSize, ExecOutput2);
|
||||
StreamInfo^.NewSize, StreamInfo^.OldSize, LOutput);
|
||||
end;
|
||||
end;
|
||||
if Executed then
|
||||
@@ -421,7 +434,7 @@ begin
|
||||
X := Read(WrkMem[Instance, 0], E_WORKMEM);
|
||||
while X > 0 do
|
||||
begin
|
||||
ExecOutput2(Instance, @WrkMem[Instance, 0], X);
|
||||
LOutput(Instance, @WrkMem[Instance, 0], X);
|
||||
X := Read(WrkMem[Instance, 0], E_WORKMEM);
|
||||
end;
|
||||
finally
|
||||
@@ -453,8 +466,8 @@ begin
|
||||
begin
|
||||
repeat
|
||||
CodecExe[X].WorkDir[Y, Z] := IncludeTrailingPathDelimiter
|
||||
(IncludeTrailingPathDelimiter(GetCurrentDir) + CodecExe[X].Name + '_' +
|
||||
IntToHex(Random($10000), 4));
|
||||
(IncludeTrailingPathDelimiter(GetCurrentDir) + CodecExe[X].Name +
|
||||
'_' + IntToHex(Random($1000000), 4));
|
||||
until DirectoryExists(CodecExe[X].WorkDir[Y, Z]) = False;
|
||||
IncludeTrailingPathDelimiter(CodecExe[X].WorkDir[Y, Z]);
|
||||
if CodecExe[X].Mode[Z] = STDIO_MODE then
|
||||
@@ -462,7 +475,6 @@ begin
|
||||
PChar(CodecExe[X].Param[Z]), PChar(CodecExe[X].WorkDir[Y, Z]),
|
||||
CodecExe[X].IsLib[Z]);
|
||||
end;
|
||||
AddMethod(CodecExe[X].Name);
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -502,43 +514,8 @@ end;
|
||||
procedure ExeScan1(Instance, Depth: Integer; Input: PByte;
|
||||
Size, SizeEx: NativeInt; Output: _PrecompOutput; Add: _PrecompAdd;
|
||||
Funcs: PPrecompFuncs);
|
||||
var
|
||||
Buffer: PByte;
|
||||
X: Integer;
|
||||
SI1: _StrInfo1;
|
||||
SI2: _StrInfo2;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexText(DS, Codec.Names);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
SI2.OldSize := DI1.OldSize;
|
||||
SI2.NewSize := DI1.NewSize;
|
||||
if ExeEncode(X, Instance, Input, @SI2, Output, Funcs) then
|
||||
begin
|
||||
SI1.Position := 0;
|
||||
SI1.OldSize := SI2.OldSize;
|
||||
SI1.NewSize := CodecSize[Instance];
|
||||
SetBits(SI1.Option, CodecExe[X].ID, 0, 31);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI1.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI1.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI1.NewSize;
|
||||
DI2.NewSize := 0;
|
||||
Funcs^.LogScan1(PChar(Codec.Names[X]), SI1.Position, SI1.OldSize,
|
||||
SI1.NewSize);
|
||||
Add(Instance, @SI1, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function ExeScan2(Instance, Depth: Integer; Input: Pointer; Size: NativeInt;
|
||||
@@ -570,7 +547,7 @@ var
|
||||
Buffer: PByte;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
@@ -583,7 +560,7 @@ begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if ExeDecode(X, Instance, NewInput, StreamInfo, Funcs) then
|
||||
if ExeDecode(X, Instance, NewInput, StreamInfo, nil, Funcs) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, CodecSize[Instance]);
|
||||
Res1 := CodecSize[Instance];
|
||||
@@ -593,15 +570,12 @@ begin
|
||||
StreamInfo^.NewSize, Res1, Result);
|
||||
if (Result = False) and (DIFF_TOLERANCE > 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance,
|
||||
Res1 + Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatch(OldInput, StreamInfo^.OldSize, Buffer, Res1,
|
||||
Buffer + Res1, Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatchEx(Instance, OldInput, StreamInfo^.OldSize,
|
||||
Buffer, Res1, Output);
|
||||
Funcs^.LogPatch1(StreamInfo^.OldSize, Res1, Res2,
|
||||
Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2));
|
||||
if Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2) then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, Res2);
|
||||
SetBits(StreamInfo^.Option, 1, 31, 1);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -615,13 +589,18 @@ end;
|
||||
function ExeRestore(Instance, Depth: Integer; Input, InputExt: Pointer;
|
||||
StreamInfo: _StrInfo3; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
LOutput: _PrecompOutput;
|
||||
Buffer: PByte;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
SI: _StrInfo2;
|
||||
begin
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
LOutput := nil
|
||||
else
|
||||
LOutput := Output;
|
||||
Result := False;
|
||||
X := -1;
|
||||
for I := Low(CodecExe) to High(CodecExe) do
|
||||
@@ -636,7 +615,7 @@ begin
|
||||
SI.NewSize := StreamInfo.NewSize;
|
||||
SI.Resource := StreamInfo.Resource;
|
||||
SI.Option := StreamInfo.Option;
|
||||
if ExeDecode(X, Instance, Input, @SI, Funcs) then
|
||||
if ExeDecode(X, Instance, Input, @SI, LOutput, Funcs) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, CodecSize[Instance]);
|
||||
Res1 := CodecSize[Instance];
|
||||
@@ -644,22 +623,15 @@ begin
|
||||
StreamInfo.NewSize, Res1, True);
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatch(InputExt, StreamInfo.ExtSize, Buffer, Res1,
|
||||
Buffer + Res1, StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatchEx(Instance, InputExt, StreamInfo.ExtSize,
|
||||
Buffer, Res1, Output);
|
||||
Funcs^.LogPatch2(StreamInfo.OldSize, Res1, StreamInfo.ExtSize, Res2 > 0);
|
||||
if Res2 > 0 then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, StreamInfo.OldSize);
|
||||
if Res2 = StreamInfo.OldSize then
|
||||
Result := True;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
begin
|
||||
Output(Instance, Buffer, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
end
|
||||
else
|
||||
Funcs^.LogRestore(PChar(Codec.Names[X]), nil, StreamInfo.OldSize,
|
||||
@@ -677,7 +649,7 @@ begin
|
||||
end;
|
||||
|
||||
var
|
||||
I, J, K, X: Integer;
|
||||
A, I, J, K, X: Integer;
|
||||
S1, S2, S3: String;
|
||||
Bytes: TBytes;
|
||||
Ini: TMemIniFile;
|
||||
|
@@ -5,7 +5,6 @@ interface
|
||||
uses
|
||||
InitCode,
|
||||
Utils, ParseExpr,
|
||||
UIMain,
|
||||
PrecompUtils,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.StrUtils,
|
||||
@@ -64,10 +63,10 @@ var
|
||||
I, J: Integer;
|
||||
X, Y, Z: Integer;
|
||||
S: String;
|
||||
SList: TStringDynArray;
|
||||
ParamsSet: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
ParamsSet := False;
|
||||
for X := Low(CodecAvailable) to High(CodecAvailable) do
|
||||
for Y := Low(CodecAvailable[X]) to High(CodecAvailable[X]) do
|
||||
begin
|
||||
@@ -135,24 +134,31 @@ begin
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, X, False);
|
||||
for Y := Low(Codec.Names) to High(Codec.Names) do
|
||||
begin
|
||||
ParamsSet := False;
|
||||
if CompareText(S, Codec.Names[Y]) = 0 then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := True;
|
||||
for Z := Low(CodecCfg[0, Y]) to High(CodecCfg[0, Y]) do
|
||||
if Funcs^.GetParam(Command, X, PChar(CodecCfg[0, Y, Z].Name)) <> ''
|
||||
then
|
||||
begin
|
||||
if not ParamsSet then
|
||||
begin
|
||||
SList := DecodeStr(CodecCfg[0, Y, Z].Name, ',');
|
||||
for J := Low(SList) to High(SList) do
|
||||
if Funcs^.GetParam(Command, X, PChar(SList[J])) <> '' then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := False;
|
||||
ParamsSet := True;
|
||||
if not ParamsSet then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := False;
|
||||
ParamsSet := True;
|
||||
end;
|
||||
CodecEnabled[Y, Z] := True;
|
||||
break;
|
||||
end;
|
||||
CodecEnabled[Y, Z] := True;
|
||||
end;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
for X := Low(CodecEnabled) to High(CodecEnabled) do
|
||||
@@ -195,13 +201,12 @@ var
|
||||
A, B: Integer;
|
||||
I, J: Integer;
|
||||
X, Y: Integer;
|
||||
Pos: NativeInt;
|
||||
Pos, Pos2: NativeInt;
|
||||
NI: NativeInt;
|
||||
I64: Int64;
|
||||
StreamPosInt, StreamOffsetInt, OldSizeInt, NewSizeInt,
|
||||
DepthSizeInt: NativeInt;
|
||||
SI: _StrInfo1;
|
||||
DI: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
if Depth > 0 then
|
||||
@@ -221,7 +226,9 @@ begin
|
||||
StreamPosInt := Pos;
|
||||
for Y := Low(Structure) to High(Structure) do
|
||||
begin
|
||||
if (X <> Y) and (Structure[Y].BeforeStream = True) then
|
||||
if (Structure[Y].BeforeStream = True) and
|
||||
(IndexText(Structure[Y].Name, ['Signature', 'Footer']) < 0)
|
||||
then
|
||||
begin
|
||||
NI := Structure[Y].Position - Structure[X].Position;
|
||||
if Structure[Y].Name = 'Stream' then
|
||||
@@ -263,13 +270,31 @@ begin
|
||||
except
|
||||
end;
|
||||
end;
|
||||
for Y := Low(Structure) to High(Structure) do
|
||||
begin
|
||||
if (Structure[Y].BeforeStream = False) and
|
||||
(Structure[Y].Name = 'Footer') then
|
||||
begin
|
||||
Structure[Y].Value := 0;
|
||||
Pos2 := StreamPosInt;
|
||||
if BinarySearch(Input, Pos2, SizeEx, Structure[Y].Data,
|
||||
Structure[Y].Size, Pos2) then
|
||||
begin
|
||||
I64 := Pos2 - StreamPosInt;
|
||||
Structure[Y].Value := I64.ToDouble;
|
||||
end;
|
||||
end;
|
||||
if Status = TScanStatus.Fail then
|
||||
break;
|
||||
end;
|
||||
StreamOffsetInt := Round(Parser.Evaluate(StreamOffset));
|
||||
OldSizeInt := Round(Parser.Evaluate(OldSize));
|
||||
NewSizeInt := Round(Parser.Evaluate(NewSize));
|
||||
DepthSizeInt := Round(Parser.Evaluate(DepthSize));
|
||||
for Y := Low(Structure) to High(Structure) do
|
||||
begin
|
||||
if (X <> Y) and (Structure[Y].BeforeStream = False) then
|
||||
if (Structure[Y].BeforeStream = False) and
|
||||
(IndexText(Structure[Y].Name, ['Footer']) < 0) then
|
||||
begin
|
||||
NI := Structure[Y].Position - Structure[X].Position +
|
||||
StreamOffsetInt + OldSizeInt;
|
||||
@@ -313,13 +338,12 @@ begin
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
Add(Instance, @SI, PChar(Codec), nil);
|
||||
DS := Funcs^.GetDepthCodec(PChar(Codec));
|
||||
Move(DS[0], DI.Codec, SizeOf(DI.Codec));
|
||||
DI.OldSize := NewSizeInt;
|
||||
DI.NewSize := DepthSizeInt;
|
||||
Add(Instance, @SI, PChar(Codec), @DI);
|
||||
if DS <> '' then
|
||||
Funcs^.AddDepthStream(Instance, 0, NewSizeInt, DepthSizeInt,
|
||||
DS, 0, 0);
|
||||
Inc(Pos, Max(OldSizeInt, 1));
|
||||
// fix this
|
||||
Status := TScanStatus.Success;
|
||||
end;
|
||||
if Status <> TScanStatus.Success then
|
||||
@@ -366,8 +390,9 @@ begin
|
||||
end;
|
||||
|
||||
var
|
||||
I, J, K, X, Y: Integer;
|
||||
I, J, K, X, Y, Z: Integer;
|
||||
SL: TStringList;
|
||||
Ini: TMemIniFile;
|
||||
Bytes: TBytes;
|
||||
S1, S2: String;
|
||||
Pos: Integer;
|
||||
@@ -377,23 +402,30 @@ var
|
||||
CfgRecArray: PCfgRecDynArray;
|
||||
CfgStruct: PCfgStruct;
|
||||
SList: TStringDynArray;
|
||||
RStream: TResourceStream;
|
||||
|
||||
initialization
|
||||
|
||||
CfgList := TDirectory.GetFiles(ExpandPath(PluginsPath, True), '*.ini',
|
||||
TSearchOption.soTopDirectoryOnly);
|
||||
SL := TStringList.Create;
|
||||
SetLength(CodecCfg, 1);
|
||||
CfgList := TDirectory.GetFiles(ExpandPath(PluginsPath, True), '*.ini',
|
||||
TSearchOption.soTopDirectoryOnly);
|
||||
for I := Low(CfgList) to High(CfgList) do
|
||||
begin
|
||||
with TIniFile.Create(CfgList[I]) do
|
||||
Ini := TMemIniFile.Create(CfgList[I]);
|
||||
with Ini do
|
||||
try
|
||||
if ReadString('Stream1', 'Name', '') <> '' then
|
||||
begin
|
||||
if SameText(ChangeFileExt(ExtractFileName(CfgList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
FORCEDMETHOD := True;
|
||||
S1 := ChangeFileExt(ExtractFileName(CfgList[I]), '');
|
||||
Insert(S1, Codec.Names, Length(Codec.Names));
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S1, PLUGIN_CONFIG);
|
||||
if not SameText(ChangeFileExt(ExtractFileName(CfgList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S1, PLUGIN_CONFIG);
|
||||
SetLength(CodecCfg[0], Succ(Length(CodecCfg[0])));
|
||||
CfgRecArray := @CodecCfg[0, Pred(Length(CodecCfg[0]))];
|
||||
X := 1;
|
||||
@@ -405,7 +437,11 @@ begin
|
||||
CfgRec^.Parser := TExpressionParser.Create;
|
||||
CfgRec^.Name := ReadString('Stream' + X.ToString, 'Name', '');
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddCodec(CfgRec^.Name);
|
||||
begin
|
||||
SList := DecodeStr(CfgRec^.Name, ',');
|
||||
for Y := Low(SList) to High(SList) do
|
||||
XTLAddCodec(SList[Y]);
|
||||
end;
|
||||
CfgRec^.Codec := ReadString('Stream' + X.ToString, 'Codec', '');
|
||||
CfgRec^.BigEndian := ReadBool('Stream' + X.ToString,
|
||||
'BigEndian', False);
|
||||
@@ -426,10 +462,11 @@ begin
|
||||
CfgStruct^.Size :=
|
||||
Round(IfThen(S2 <> '', CfgRec^.Parser.Evaluate(S2), 0));
|
||||
GetMem(CfgStruct^.Data, CfgStruct^.Size);
|
||||
if CfgStruct^.Name = 'Signature' then
|
||||
Z := IndexText(CfgStruct^.Name, ['Signature', 'Footer']);
|
||||
if Z >= 0 then
|
||||
begin
|
||||
S1 := ReplaceStr(ReadString('Stream' + X.ToString, 'Signature',
|
||||
'0'), ' ', '');
|
||||
S1 := ReplaceStr(ReadString('Stream' + X.ToString,
|
||||
CaseStr(Z, ['Signature', 'Footer']), '0'), ' ', '');
|
||||
ConvertHexChr(S1);
|
||||
HexValue := S1[1] = '$';
|
||||
if HexValue then
|
||||
@@ -487,7 +524,8 @@ begin
|
||||
S1 := SL[J].Substring(0, SL[J].IndexOf('=')).TrimRight;
|
||||
S2 := SL[J].Substring(Succ(SL[J].IndexOf('='))).TrimLeft;
|
||||
if (IndexText(S1, ['Name', 'Codec', 'BigEndian', 'Signature',
|
||||
'Structure']) >= 0) or S1.StartsWith('Condition', True) then
|
||||
'Footer', 'Structure']) >= 0) or S1.StartsWith('Condition', True)
|
||||
then
|
||||
SL.Delete(J);
|
||||
end;
|
||||
SetLength(CfgRec^.Names, SL.Count);
|
||||
@@ -495,8 +533,8 @@ begin
|
||||
SetLength(CfgRec^.Values, SL.Count);
|
||||
for J := 0 to SL.Count - 1 do
|
||||
begin
|
||||
S1 := SL[J].Substring(0, SL[J].IndexOf('=')).TrimRight;
|
||||
S2 := SL[J].Substring(Succ(SL[J].IndexOf('='))).TrimLeft;
|
||||
S1 := SL[J].Substring(0, SL[J].IndexOf('=')).Trim;
|
||||
S2 := SL[J].Substring(Succ(SL[J].IndexOf('='))).Trim;
|
||||
CfgRec^.Names[J] := S1;
|
||||
CfgRec^.Exprs[J] := S2;
|
||||
CfgRec^.Values[J] := 0;
|
||||
|
@@ -5,7 +5,6 @@ interface
|
||||
uses
|
||||
InitCode,
|
||||
Utils, ParseExpr,
|
||||
UIMain,
|
||||
PrecompUtils,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.StrUtils,
|
||||
@@ -73,10 +72,10 @@ var
|
||||
I, J: Integer;
|
||||
X, Y, Z: Integer;
|
||||
S: String;
|
||||
SList: TStringDynArray;
|
||||
ParamsSet: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
ParamsSet := False;
|
||||
for X := Low(CodecAvailable) to High(CodecAvailable) do
|
||||
for Y := Low(CodecAvailable[X]) to High(CodecAvailable[X]) do
|
||||
begin
|
||||
@@ -177,24 +176,31 @@ begin
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, X, False);
|
||||
for Y := Low(Codec.Names) to High(Codec.Names) do
|
||||
begin
|
||||
ParamsSet := False;
|
||||
if CompareText(S, Codec.Names[Y]) = 0 then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := True;
|
||||
for Z := Low(CodecCfg[0, Y]) to High(CodecCfg[0, Y]) do
|
||||
if Funcs^.GetParam(Command, X, PChar(CodecCfg[0, Y, Z].Name)) <> ''
|
||||
then
|
||||
begin
|
||||
if not ParamsSet then
|
||||
begin
|
||||
SList := DecodeStr(CodecCfg[0, Y, Z].Name, ',');
|
||||
for J := Low(SList) to High(SList) do
|
||||
if Funcs^.GetParam(Command, X, PChar(SList[J])) <> '' then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := False;
|
||||
ParamsSet := True;
|
||||
if not ParamsSet then
|
||||
begin
|
||||
for I := Low(CodecEnabled[Y]) to High(CodecEnabled[Y]) do
|
||||
CodecEnabled[Y, I] := False;
|
||||
ParamsSet := True;
|
||||
end;
|
||||
CodecEnabled[Y, Z] := True;
|
||||
break;
|
||||
end;
|
||||
CodecEnabled[Y, Z] := True;
|
||||
end;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
for X := Low(CodecEnabled) to High(CodecEnabled) do
|
||||
@@ -243,9 +249,7 @@ var
|
||||
I64: Int64;
|
||||
LoopPosInt, StreamPosInt1, StreamPosInt2, StreamOffsetInt, OldSizeInt,
|
||||
NewSizeInt, DepthSizeInt: NativeInt;
|
||||
LoopContinue: Boolean;
|
||||
SI: _StrInfo1;
|
||||
DI: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
|
||||
procedure UpdateCounters(var C: TConfigRec);
|
||||
@@ -288,11 +292,10 @@ var
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
Add(Instance, @SI, PChar(Codec), nil);
|
||||
DS := Funcs^.GetDepthCodec(PChar(Codec));
|
||||
Move(DS[0], DI.Codec, SizeOf(DI.Codec));
|
||||
DI.OldSize := NewSizeInt;
|
||||
DI.NewSize := DepthSizeInt;
|
||||
Add(Instance, @SI, PChar(Codec), @DI);
|
||||
if DS <> '' then
|
||||
Funcs^.AddDepthStream(Instance, 0, NewSizeInt, DepthSizeInt, DS, 0, 0);
|
||||
Status := TScanStatus.Success;
|
||||
end;
|
||||
end;
|
||||
@@ -504,6 +507,7 @@ end;
|
||||
var
|
||||
I, J, K, X, Y, Z: Integer;
|
||||
SL: TStringList;
|
||||
Ini: TMemIniFile;
|
||||
Bytes: TBytes;
|
||||
S1, S2, S3: String;
|
||||
Pos: Integer;
|
||||
@@ -514,23 +518,30 @@ var
|
||||
CfgStruct: PCfgStruct;
|
||||
CfgCounter: PCfgCounter;
|
||||
SList: TStringDynArray;
|
||||
RStream: TResourceStream;
|
||||
|
||||
initialization
|
||||
|
||||
CfgList := TDirectory.GetFiles(ExpandPath(PluginsPath, True), '*.ini',
|
||||
TSearchOption.soTopDirectoryOnly);
|
||||
SL := TStringList.Create;
|
||||
SetLength(CodecCfg, 1);
|
||||
CfgList := TDirectory.GetFiles(ExpandPath(PluginsPath, True), '*.ini',
|
||||
TSearchOption.soTopDirectoryOnly);
|
||||
for I := Low(CfgList) to High(CfgList) do
|
||||
begin
|
||||
with TIniFile.Create(CfgList[I]) do
|
||||
Ini := TMemIniFile.Create(CfgList[I]);
|
||||
with Ini do
|
||||
try
|
||||
if ReadString('StreamList1', 'Name', '') <> '' then
|
||||
begin
|
||||
if SameText(ChangeFileExt(ExtractFileName(CfgList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
FORCEDMETHOD := True;
|
||||
S1 := ChangeFileExt(ExtractFileName(CfgList[I]), '');
|
||||
Insert(S1, Codec.Names, Length(Codec.Names));
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S1, PLUGIN_CONFIG);
|
||||
if not SameText(ChangeFileExt(ExtractFileName(CfgList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S1, PLUGIN_CONFIG);
|
||||
SetLength(CodecCfg[0], Succ(Length(CodecCfg[0])));
|
||||
CfgRecArray := @CodecCfg[0, Pred(Length(CodecCfg[0]))];
|
||||
X := 1;
|
||||
@@ -542,7 +553,11 @@ begin
|
||||
CfgRec^.Parser := TExpressionParser.Create;
|
||||
CfgRec^.Name := ReadString('StreamList' + X.ToString, 'Name', '');
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddCodec(CfgRec^.Name);
|
||||
begin
|
||||
SList := DecodeStr(CfgRec^.Name, ',');
|
||||
for Y := Low(SList) to High(SList) do
|
||||
XTLAddCodec(SList[Y]);
|
||||
end;
|
||||
CfgRec^.Codec := ReadString('StreamList' + X.ToString, 'Codec', '');
|
||||
CfgRec^.BigEndian := ReadBool('StreamList' + X.ToString,
|
||||
'BigEndian', False);
|
||||
|
@@ -24,17 +24,20 @@ const
|
||||
|
||||
const
|
||||
L_MAXSIZE = 16 * 1024 * 1024;
|
||||
L_BLOCKSIZE = 0;
|
||||
L_BLOCKDEPENDENCY = 0;
|
||||
L_ACCELERATION = 1;
|
||||
L_BLOCKDEPENDENCY = 0;
|
||||
L_BLOCKSIZE1 = 0;
|
||||
L_BLOCKSIZE2 = 0;
|
||||
|
||||
var
|
||||
SOList: array of array [0 .. CODEC_COUNT - 1] of TSOList;
|
||||
cctx1, cctx2: array of Pointer;
|
||||
CodecAvailable, CodecEnabled: TArray<Boolean>;
|
||||
LMaxSize: Integer = L_MAXSIZE;
|
||||
LBlockSize: Integer = L_BLOCKSIZE;
|
||||
LBlockDependency: Integer = L_BLOCKDEPENDENCY;
|
||||
LAcceleration: Integer = L_ACCELERATION;
|
||||
LBlockDependency: Integer = L_BLOCKDEPENDENCY;
|
||||
LBlockSize1: Integer = L_BLOCKSIZE1;
|
||||
LBlockSize2: Integer = L_BLOCKSIZE2;
|
||||
|
||||
function LZ4Init(Command: PChar; Count: Integer; Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
@@ -66,6 +69,8 @@ begin
|
||||
LMaxSize := ConvertToBytes(Funcs^.GetParam(Command, X, 's'));
|
||||
if Funcs^.GetParam(Command, X, 'a') <> '' then
|
||||
LAcceleration := StrToInt(Funcs^.GetParam(Command, X, 'a'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
LBlockSize1 := StrToInt(Funcs^.GetParam(Command, X, 'b'));
|
||||
end
|
||||
else if (CompareText(S, LZ4Codecs[LZ4HC_CODEC]) = 0) and LZ4DLL.DLLLoaded
|
||||
then
|
||||
@@ -77,6 +82,8 @@ begin
|
||||
([StrToInt(Funcs^.GetParam(Command, X, 'l'))], True);
|
||||
if Funcs^.GetParam(Command, X, 's') <> '' then
|
||||
LMaxSize := ConvertToBytes(Funcs^.GetParam(Command, X, 's'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
LBlockSize1 := StrToInt(Funcs^.GetParam(Command, X, 'b'));
|
||||
end
|
||||
else if (CompareText(S, LZ4Codecs[LZ4F_CODEC]) = 0) and LZ4DLL.DLLLoaded
|
||||
then
|
||||
@@ -88,16 +95,28 @@ begin
|
||||
([StrToInt(Funcs^.GetParam(Command, X, 'l'))], True);
|
||||
if Funcs^.GetParam(Command, X, 's') <> '' then
|
||||
LMaxSize := ConvertToBytes(Funcs^.GetParam(Command, X, 's'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
LBlockSize := StrToInt(Funcs^.GetParam(Command, X, 'b')) - 4;
|
||||
if Funcs^.GetParam(Command, X, 'd') <> '' then
|
||||
LBlockDependency := StrToInt(Funcs^.GetParam(Command, X, 'd'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
LBlockSize2 := StrToInt(Funcs^.GetParam(Command, X, 'b')) - 4;
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
for X := Low(SOList) to High(SOList) do
|
||||
if SOList[X, LZ4_CODEC].Count = 0 then
|
||||
SOList[X, LZ4_CODEC].Update([1]);
|
||||
if CodecAvailable[LZ4_CODEC] then
|
||||
begin
|
||||
SetLength(cctx1, Count);
|
||||
for X := Low(cctx1) to High(cctx1) do
|
||||
cctx1[X] := nil;
|
||||
end;
|
||||
if CodecAvailable[LZ4HC_CODEC] then
|
||||
begin
|
||||
SetLength(cctx2, Count);
|
||||
for X := Low(cctx2) to High(cctx2) do
|
||||
cctx2[X] := nil;
|
||||
end;
|
||||
SetLength(Options, 0);
|
||||
for I := 2 to 12 do
|
||||
Insert(I, Options, Length(Options));
|
||||
@@ -119,6 +138,14 @@ begin
|
||||
for X := Low(SOList) to High(SOList) do
|
||||
for Y := Low(SOList[X]) to High(SOList[X]) do
|
||||
SOList[X, Y].Free;
|
||||
if CodecAvailable[LZ4_CODEC] then
|
||||
for X := Low(cctx1) to High(cctx1) do
|
||||
if Assigned(cctx1[X]) then
|
||||
LZ4_freeStream(cctx1[X]);
|
||||
if CodecAvailable[LZ4HC_CODEC] then
|
||||
for X := Low(cctx2) to High(cctx2) do
|
||||
if Assigned(cctx2[X]) then
|
||||
LZ4_freeStreamHC(cctx2[X]);
|
||||
end;
|
||||
|
||||
function LZ4Parse(Command: PChar; Option: PInteger;
|
||||
@@ -129,36 +156,41 @@ var
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
SetBits(Option^, LBlockSize, 12, 2);
|
||||
SetBits(Option^, LBlockDependency, 14, 1);
|
||||
SetBits(Option^, LAcceleration, 15, 7);
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, LZ4Codecs[LZ4_CODEC]) = 0) and LZ4DLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, LZ4_CODEC, 0, 5);
|
||||
SetBits(Option^, LZ4_CODEC, 0, 3);
|
||||
SetBits(Option^, LAcceleration, 7, 7);
|
||||
SetBits(Option^, LBlockSize1, 15, 13);
|
||||
if Funcs^.GetParam(Command, I, 'a') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'a')), 15, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'a')), 7, 7);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, LZ4Codecs[LZ4HC_CODEC]) = 0) and LZ4DLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, LZ4HC_CODEC, 0, 5);
|
||||
SetBits(Option^, LZ4HC_CODEC, 0, 3);
|
||||
SetBits(Option^, LBlockSize1, 15, 13);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 4);
|
||||
if Funcs^.GetParam(Command, I, 'b') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'b')), 15, 13);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, LZ4Codecs[LZ4F_CODEC]) = 0) and LZ4DLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, LZ4F_CODEC, 0, 5);
|
||||
SetBits(Option^, LZ4F_CODEC, 0, 3);
|
||||
SetBits(Option^, LBlockDependency, 14, 1);
|
||||
SetBits(Option^, LBlockSize2, 15, 13);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 4);
|
||||
if Funcs^.GetParam(Command, I, 'b') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'b')) - 4, 12, 2);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'b')) -
|
||||
4, 15, 13);
|
||||
if Funcs^.GetParam(Command, I, 'd') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'd')), 14, 1);
|
||||
Result := True;
|
||||
@@ -175,71 +207,26 @@ var
|
||||
Pos: NativeInt;
|
||||
X, Y, Z: Integer;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], LZ4Codecs);
|
||||
if X < 0 then
|
||||
exit;
|
||||
if DI1.OldSize = 0 then
|
||||
DI1.OldSize := SizeEx;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
Y := Max(DI1.NewSize, LMaxSize);
|
||||
Buffer := Funcs^.Allocator(Instance, Y);
|
||||
case X of
|
||||
LZ4_CODEC, LZ4HC_CODEC:
|
||||
Y := LZ4_decompress_safe(Input, Buffer, DI1.OldSize, Y);
|
||||
LZ4F_CODEC:
|
||||
Y := LZ4F_decompress_safe(Input, Buffer, DI1.OldSize, Y);
|
||||
end;
|
||||
if (Y > DI1.OldSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Y);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := DI1.OldSize;
|
||||
SI.NewSize := Y;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
SetBits(SI.Option, LBlockSize, 12, 2);
|
||||
SetBits(SI.Option, LBlockDependency, 14, 1);
|
||||
SetBits(SI.Option, LAcceleration, 15, 7);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(LZ4Codecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Buffer := Funcs^.Allocator(Instance, LMaxSize);
|
||||
Pos := 0;
|
||||
while Pos < Size do
|
||||
begin
|
||||
if CodecEnabled[LZ4_CODEC] or
|
||||
(CodecEnabled[LZ4HC_CODEC] and (SOList[Instance][LZ4HC_CODEC].Count = 1))
|
||||
then
|
||||
if CodecEnabled[LZ4_CODEC] or (CodecEnabled[LZ4HC_CODEC]) then
|
||||
begin
|
||||
if (Input + Pos)^ in [$F0 .. $F3] then
|
||||
if (Input + Pos)^ in [$F0 .. $F4] then
|
||||
begin
|
||||
X := LZ4_decompress_generic(Input + Pos, Buffer, SizeEx - Pos, LMaxSize,
|
||||
Integer(endOnOutputSize));
|
||||
if X > 256 then
|
||||
Y := LZ4_decompress_safe(Input + Pos, Buffer, X, LMaxSize)
|
||||
else
|
||||
Y := 0;
|
||||
try
|
||||
X := LZ4_decompress_generic(Input + Pos, Buffer, SizeEx - Pos,
|
||||
LMaxSize, Integer(endOnOutputSize));
|
||||
if X > 256 then
|
||||
Y := LZ4_decompress_safe(Input + Pos, Buffer, X, LMaxSize)
|
||||
else
|
||||
Y := 0;
|
||||
except
|
||||
end;
|
||||
if Y > 256 then
|
||||
begin
|
||||
if (X < Y) and (X > 256) then
|
||||
@@ -250,11 +237,13 @@ begin
|
||||
SI.NewSize := Y;
|
||||
SI.Option := 0;
|
||||
if CodecEnabled[LZ4_CODEC] then
|
||||
SetBits(SI.Option, LZ4_CODEC, 0, 5)
|
||||
SetBits(SI.Option, LZ4_CODEC, 0, 3)
|
||||
else
|
||||
SetBits(SI.Option, LZ4HC_CODEC, 0, 5);
|
||||
SetBits(SI.Option, LZ4HC_CODEC, 0, 3);
|
||||
SetBits(SI.Option, LAcceleration, 7, 7);
|
||||
SetBits(SI.Option, LBlockSize1, 15, 13);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(LZ4Codecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(LZ4Codecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, 256);
|
||||
@@ -275,12 +264,11 @@ begin
|
||||
SI.OldSize := X;
|
||||
SI.NewSize := Y;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, LZ4F_CODEC, 0, 5);
|
||||
SetBits(SI.Option, Z - 4, 12, 2);
|
||||
SetBits(SI.Option, 0, 14, 1);
|
||||
SetBits(SI.Option, LAcceleration, 15, 7);
|
||||
SetBits(SI.Option, LZ4F_CODEC, 0, 3);
|
||||
SetBits(SI.Option, LBlockDependency, 14, 1);
|
||||
SetBits(SI.Option, Z - 4, 15, 13);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(LZ4Codecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(LZ4Codecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, SI.OldSize);
|
||||
@@ -300,7 +288,15 @@ var
|
||||
Res: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if (StreamInfo^.OldSize > 0) and REPROCESSED then
|
||||
if (Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^)
|
||||
.Lo = StreamInfo^.OldSize) and
|
||||
(Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Lo <
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi)
|
||||
then
|
||||
StreamInfo^.OldSize :=
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi;
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
exit;
|
||||
StreamInfo^.NewSize := Max(StreamInfo^.NewSize, LMaxSize);
|
||||
@@ -317,7 +313,7 @@ begin
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
StreamInfo^.NewSize := Res;
|
||||
Funcs^.LogScan2(LZ4Codecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(LZ4Codecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -330,12 +326,14 @@ var
|
||||
Params: String;
|
||||
I: Integer;
|
||||
X, Y: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
Progress: NativeInt;
|
||||
A, B: Integer;
|
||||
LZ4FT: LZ4F_preferences_t;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Y := LZ4F_compressFrameBound(StreamInfo^.NewSize, nil);
|
||||
@@ -345,7 +343,7 @@ begin
|
||||
begin
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 5, 7) <> I then
|
||||
if GetBits(StreamInfo^.Option, 3, 4) <> I then
|
||||
continue;
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) and
|
||||
(GetBits(StreamInfo^.Option, 31, 1) = 0) then
|
||||
@@ -358,30 +356,81 @@ begin
|
||||
case X of
|
||||
LZ4_CODEC:
|
||||
begin
|
||||
Params := 'a' + GetBits(StreamInfo^.Option, 15, 7).ToString;
|
||||
Params := 'a' + GetBits(StreamInfo^.Option, 7, 7).ToString + ':' + 'b'
|
||||
+ GetBits(StreamInfo^.Option, 15, 13).ToString;
|
||||
if not Result then
|
||||
{ Res1 := LZ4_compress_block(NewInput, Buffer,
|
||||
StreamInfo^.NewSize, Y); }
|
||||
Res1 := LZ4_compress_fast(NewInput, Buffer, StreamInfo^.NewSize, Y,
|
||||
GetBits(StreamInfo^.Option, 15, 7));
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 15, 13) = 0 then
|
||||
Res1 := LZ4_compress_fast(NewInput, Buffer, StreamInfo^.NewSize,
|
||||
Y, GetBits(StreamInfo^.Option, 7, 7))
|
||||
else
|
||||
begin
|
||||
if cctx1[Instance] = nil then
|
||||
cctx1[Instance] := LZ4_createStream;
|
||||
LZ4_resetStream(cctx1[Instance]);
|
||||
B := 0;
|
||||
Res1 := 0;
|
||||
while B < StreamInfo^.NewSize do
|
||||
begin
|
||||
A := LZ4_compress_fast_continue(cctx1[Instance],
|
||||
PByte(NewInput) + B, Buffer + Res1,
|
||||
Min(GetBits(StreamInfo^.Option, 15, 13) * 1024,
|
||||
StreamInfo^.NewSize - B), StreamInfo^.NewSize - Res1,
|
||||
GetBits(StreamInfo^.Option, 7, 7));
|
||||
if A > 0 then
|
||||
begin
|
||||
Inc(Res1, A);
|
||||
Inc(B, GetBits(StreamInfo^.Option, 15, 13) * 1024);
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
LZ4HC_CODEC:
|
||||
begin
|
||||
Params := 'l' + I.ToString;
|
||||
Params := 'l' + I.ToString + ':' + 'b' + GetBits(StreamInfo^.Option,
|
||||
15, 13).ToString;
|
||||
if not Result then
|
||||
Res1 := LZ4_compress_HC(NewInput, Buffer,
|
||||
StreamInfo^.NewSize, Y, I);
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 15, 13) = 0 then
|
||||
Res1 := LZ4_compress_HC(NewInput, Buffer,
|
||||
StreamInfo^.NewSize, Y, I)
|
||||
else
|
||||
begin
|
||||
if cctx2[Instance] = nil then
|
||||
cctx2[Instance] := LZ4_createStreamHC;
|
||||
LZ4_resetStreamHC(cctx2[Instance], I);
|
||||
B := 0;
|
||||
Res1 := 0;
|
||||
while B < StreamInfo^.NewSize do
|
||||
begin
|
||||
A := LZ4_compress_HC_continue(cctx2[Instance],
|
||||
PByte(NewInput) + B, Buffer + Res1,
|
||||
Min(GetBits(StreamInfo^.Option, 15, 13) * 1024,
|
||||
StreamInfo^.NewSize - B), StreamInfo^.NewSize - Res1);
|
||||
if A > 0 then
|
||||
begin
|
||||
Inc(Res1, A);
|
||||
Inc(B, GetBits(StreamInfo^.Option, 15, 13) * 1024);
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
LZ4F_CODEC:
|
||||
begin
|
||||
FillChar(LZ4FT, SizeOf(LZ4F_preferences_t), 0);
|
||||
LZ4FT.compressionLevel := I;
|
||||
LZ4FT.frameInfo.blockSizeID :=
|
||||
LZ4F_blockSizeID_t(GetBits(StreamInfo^.Option, 12, 2) + 4);
|
||||
LZ4F_blockSizeID_t(GetBits(StreamInfo^.Option, 15, 13) + 4);
|
||||
LZ4FT.frameInfo.blockMode :=
|
||||
LZ4F_blockMode_t(GetBits(StreamInfo^.Option, 14, 1));
|
||||
Params := 'l' + I.ToString + ':' + 'b' +
|
||||
(GetBits(StreamInfo^.Option, 12, 2) + 4).ToString + ':' + 'd' +
|
||||
(GetBits(StreamInfo^.Option, 15, 13) + 4).ToString + ':' + 'd' +
|
||||
GetBits(StreamInfo^.Option, 14, 1).ToString;
|
||||
if not Result then
|
||||
Res1 := LZ4F_compressFrame(Buffer, Y, NewInput,
|
||||
@@ -391,7 +440,7 @@ begin
|
||||
if not Result then
|
||||
Result := (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(LZ4Codecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(LZ4Codecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, Res1, Result);
|
||||
if Result or (StreamInfo^.Status >= TStreamStatus.Predicted) then
|
||||
break;
|
||||
@@ -399,14 +448,12 @@ begin
|
||||
if (Result = False) and ((StreamInfo^.Status >= TStreamStatus.Predicted) or
|
||||
(SOList[Instance][X].Count = 1)) and (DIFF_TOLERANCE > 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatch(OldInput, StreamInfo^.OldSize, Buffer, Res1,
|
||||
Buffer + Res1, Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatchEx(Instance, OldInput, StreamInfo^.OldSize,
|
||||
Buffer, Res1, Output);
|
||||
Funcs^.LogPatch1(StreamInfo^.OldSize, Res1, Res2,
|
||||
Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2));
|
||||
if Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2) then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, Res2);
|
||||
SetBits(StreamInfo^.Option, 1, 31, 1);
|
||||
SOList[Instance][X].Add(I);
|
||||
Result := True;
|
||||
@@ -414,7 +461,7 @@ begin
|
||||
end;
|
||||
if Result then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 5, 7);
|
||||
SetBits(StreamInfo^.Option, I, 3, 4);
|
||||
SOList[Instance][X].Add(I);
|
||||
end;
|
||||
end;
|
||||
@@ -425,12 +472,13 @@ var
|
||||
Buffer: PByte;
|
||||
Params: String;
|
||||
X: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
A, B: Integer;
|
||||
LZ4FT: LZ4F_preferences_t;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Params := '';
|
||||
@@ -439,47 +487,90 @@ begin
|
||||
case X of
|
||||
LZ4_CODEC:
|
||||
begin
|
||||
Params := 'a' + GetBits(StreamInfo.Option, 15, 7).ToString;
|
||||
Res1 := LZ4_compress_fast(Input, Buffer, StreamInfo.NewSize,
|
||||
LZ4F_compressFrameBound(StreamInfo.NewSize, nil),
|
||||
GetBits(StreamInfo.Option, 15, 7));
|
||||
Params := 'a' + GetBits(StreamInfo.Option, 7, 7).ToString + ':' + 'b' +
|
||||
GetBits(StreamInfo.Option, 15, 13).ToString;
|
||||
if GetBits(StreamInfo.Option, 15, 13) = 0 then
|
||||
Res1 := LZ4_compress_fast(Input, Buffer, StreamInfo.NewSize,
|
||||
LZ4F_compressFrameBound(StreamInfo.NewSize, nil),
|
||||
GetBits(StreamInfo.Option, 7, 7))
|
||||
else
|
||||
begin
|
||||
if cctx1[Instance] = nil then
|
||||
cctx1[Instance] := LZ4_createStream;
|
||||
LZ4_resetStream(cctx1[Instance]);
|
||||
B := 0;
|
||||
Res1 := 0;
|
||||
while B < StreamInfo.NewSize do
|
||||
begin
|
||||
A := LZ4_compress_fast_continue(cctx1[Instance], PByte(Input) + B,
|
||||
Buffer + Res1, Min(GetBits(StreamInfo.Option, 15, 13) * 1024,
|
||||
StreamInfo.NewSize - B), StreamInfo.NewSize - Res1,
|
||||
GetBits(StreamInfo.Option, 7, 7));
|
||||
if A > 0 then
|
||||
begin
|
||||
Inc(B, GetBits(StreamInfo.Option, 15, 13) * 1024);
|
||||
Inc(Res1, A);
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
LZ4HC_CODEC:
|
||||
begin
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString;
|
||||
Res1 := LZ4_compress_HC(Input, Buffer, StreamInfo.NewSize,
|
||||
LZ4F_compressFrameBound(StreamInfo.NewSize, nil),
|
||||
GetBits(StreamInfo.Option, 5, 7));
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 4).ToString + ':' + 'b' +
|
||||
GetBits(StreamInfo.Option, 15, 13).ToString;
|
||||
if GetBits(StreamInfo.Option, 15, 13) = 0 then
|
||||
Res1 := LZ4_compress_HC(Input, Buffer, StreamInfo.NewSize,
|
||||
LZ4F_compressFrameBound(StreamInfo.NewSize, nil),
|
||||
GetBits(StreamInfo.Option, 3, 4))
|
||||
else
|
||||
begin
|
||||
if cctx2[Instance] = nil then
|
||||
cctx2[Instance] := LZ4_createStreamHC;
|
||||
LZ4_resetStreamHC(cctx2[Instance], GetBits(StreamInfo.Option, 3, 4));
|
||||
B := 0;
|
||||
Res1 := 0;
|
||||
while B < StreamInfo.NewSize do
|
||||
begin
|
||||
A := LZ4_compress_HC_continue(cctx2[Instance], PByte(Input) + B,
|
||||
Buffer + Res1, Min(GetBits(StreamInfo.Option, 15, 13) * 1024,
|
||||
StreamInfo.NewSize - B), StreamInfo.NewSize - Res1);
|
||||
if A > 0 then
|
||||
begin
|
||||
Inc(B, GetBits(StreamInfo.Option, 15, 13) * 1024);
|
||||
Inc(Res1, A);
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
LZ4F_CODEC:
|
||||
begin
|
||||
FillChar(LZ4FT, SizeOf(LZ4F_preferences_t), 0);
|
||||
LZ4FT.compressionLevel := GetBits(StreamInfo.Option, 5, 7);
|
||||
LZ4FT.compressionLevel := GetBits(StreamInfo.Option, 3, 4);
|
||||
LZ4FT.frameInfo.blockSizeID :=
|
||||
LZ4F_blockSizeID_t(GetBits(StreamInfo.Option, 12, 2) + 4);
|
||||
LZ4F_blockSizeID_t(GetBits(StreamInfo.Option, 15, 13) + 4);
|
||||
LZ4FT.frameInfo.blockMode :=
|
||||
LZ4F_blockMode_t(GetBits(StreamInfo.Option, 14, 1));
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString + ':' + 'b' +
|
||||
(GetBits(StreamInfo.Option, 12, 2) + 4).ToString + ':' + 'd' +
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 4).ToString + ':' + 'b' +
|
||||
(GetBits(StreamInfo.Option, 15, 13) + 4).ToString + ':' + 'd' +
|
||||
GetBits(StreamInfo.Option, 14, 1).ToString;
|
||||
Res1 := LZ4F_compressFrame(Buffer,
|
||||
LZ4F_compressFrameBound(StreamInfo.NewSize, nil), Input,
|
||||
StreamInfo.NewSize, @LZ4FT);
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogRestore(LZ4Codecs[GetBits(StreamInfo.Option, 0, 5)], PChar(Params),
|
||||
Funcs^.LogRestore(LZ4Codecs[GetBits(StreamInfo.Option, 0, 3)], PChar(Params),
|
||||
StreamInfo.OldSize, StreamInfo.NewSize, Res1, True);
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatch(InputExt, StreamInfo.ExtSize, Buffer, Res1,
|
||||
Buffer + Res1, StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatchEx(Instance, InputExt, StreamInfo.ExtSize, Buffer,
|
||||
Res1, Output);
|
||||
Funcs^.LogPatch2(StreamInfo.OldSize, Res1, StreamInfo.ExtSize, Res2 > 0);
|
||||
if Res2 > 0 then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, StreamInfo.OldSize);
|
||||
if Res2 = StreamInfo.OldSize then
|
||||
Result := True;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
|
@@ -87,15 +87,6 @@ begin
|
||||
else
|
||||
break;
|
||||
end;
|
||||
{ -5:
|
||||
begin
|
||||
// increase output buffer size and try again
|
||||
break;
|
||||
end; }
|
||||
{ -8:
|
||||
begin
|
||||
// reduce input buffer size and try again
|
||||
end; }
|
||||
else
|
||||
break;
|
||||
end;
|
||||
@@ -206,30 +197,30 @@ begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, LZOCodecs[LZO1X_CODEC]) = 0) and LZODLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, LZO1X_CODEC, 0, 5);
|
||||
SetBits(Option^, LZO1XVariant, 12, 12);
|
||||
SetBits(Option^, LZO1X_CODEC, 0, 3);
|
||||
SetBits(Option^, LZO1XVariant, 7, 12);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 4);
|
||||
if Funcs^.GetParam(Command, I, 'v') = '999' then
|
||||
SetBits(Option^, 999, 12, 12);
|
||||
SetBits(Option^, 999, 7, 12);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, LZOCodecs[LZO2A_CODEC]) = 0) and LZODLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, LZO2A_CODEC, 0, 5);
|
||||
SetBits(Option^, LZO2AVariant, 12, 12);
|
||||
SetBits(Option^, LZO2A_CODEC, 0, 3);
|
||||
SetBits(Option^, LZO2AVariant, 7, 12);
|
||||
if Funcs^.GetParam(Command, I, 'v') = '999' then
|
||||
SetBits(Option^, 999, 12, 12);
|
||||
SetBits(Option^, 999, 7, 12);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, LZOCodecs[LZO1C_CODEC]) = 0) and LZODLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, LZO1C_CODEC, 0, 5);
|
||||
SetBits(Option^, LZO1CVariant, 12, 12);
|
||||
SetBits(Option^, LZO1C_CODEC, 0, 3);
|
||||
SetBits(Option^, LZO1CVariant, 7, 12);
|
||||
if Funcs^.GetParam(Command, I, 'v') = '999' then
|
||||
SetBits(Option^, 999, 12, 12);
|
||||
SetBits(Option^, 999, 7, 12);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -246,61 +237,7 @@ var
|
||||
Pos: NativeInt;
|
||||
LZOSI: TLZOSI;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], LZOCodecs);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
Res := Max(DI1.NewSize, LMaxSize);
|
||||
Buffer := Funcs^.Allocator(Instance, Res);
|
||||
case X of
|
||||
LZO1X_CODEC:
|
||||
if not lzo1x_decompress_safe(Input, DI1.OldSize, Buffer, @Res) = 0 then
|
||||
Res := 0;
|
||||
LZO2A_CODEC:
|
||||
if not lzo2a_decompress_safe(Input, DI1.OldSize, Buffer, @Res) = 0 then
|
||||
Res := 0;
|
||||
LZO1C_CODEC:
|
||||
if not lzo1c_decompress_safe(Input, DI1.OldSize, Buffer, @Res) = 0 then
|
||||
Res := 0;
|
||||
end;
|
||||
if (Res > DI1.OldSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := DI1.OldSize;
|
||||
SI.NewSize := Res;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
case X of
|
||||
LZO1X_CODEC:
|
||||
SetBits(SI.Option, LZO1XVariant, 12, 12);
|
||||
LZO2A_CODEC:
|
||||
SetBits(SI.Option, LZO2AVariant, 12, 12);
|
||||
LZO1C_CODEC:
|
||||
SetBits(SI.Option, LZO1CVariant, 12, 12);
|
||||
end;
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(LZOCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Buffer := Funcs^.Allocator(Instance, LMaxSize);
|
||||
@@ -314,10 +251,10 @@ begin
|
||||
SI.OldSize := LZOSI.CSize;
|
||||
SI.NewSize := LZOSI.DSize;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, LZO1X_CODEC, 0, 5);
|
||||
SetBits(SI.Option, LZO1XVariant, 12, 12);
|
||||
SetBits(SI.Option, LZO1X_CODEC, 0, 3);
|
||||
SetBits(SI.Option, LZO1XVariant, 7, 12);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(LZOCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(LZOCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, LZOSI.CSize);
|
||||
@@ -336,7 +273,15 @@ var
|
||||
Res: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if (StreamInfo^.OldSize > 0) and REPROCESSED then
|
||||
if (Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^)
|
||||
.Lo = StreamInfo^.OldSize) and
|
||||
(Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Lo <
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi)
|
||||
then
|
||||
StreamInfo^.OldSize :=
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi;
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
exit;
|
||||
Res := Max(StreamInfo^.NewSize, LMaxSize);
|
||||
@@ -359,7 +304,7 @@ begin
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
StreamInfo^.NewSize := Res;
|
||||
Funcs^.LogScan2(LZOCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(LZOCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -376,7 +321,7 @@ var
|
||||
Res2: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo^.NewSize);
|
||||
@@ -385,7 +330,7 @@ begin
|
||||
begin
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 5, 7) <> I then
|
||||
if GetBits(StreamInfo^.Option, 3, 4) <> I then
|
||||
continue;
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) and
|
||||
(GetBits(StreamInfo^.Option, 31, 1) = 0) then
|
||||
@@ -400,11 +345,11 @@ begin
|
||||
Res1 := StreamInfo^.NewSize;
|
||||
case X of
|
||||
LZO1X_CODEC:
|
||||
case GetBits(StreamInfo^.Option, 12, 12) of
|
||||
case GetBits(StreamInfo^.Option, 7, 12) of
|
||||
LZO1X_999:
|
||||
begin
|
||||
Params := 'l' + I.ToString + ':' + 'v' +
|
||||
GetBits(StreamInfo^.Option, 12, 12).ToString;
|
||||
GetBits(StreamInfo^.Option, 7, 12).ToString;
|
||||
if not Result then
|
||||
if not lzo1x_999_compress_level(NewInput, StreamInfo^.NewSize,
|
||||
Buffer, @Res1, WrkMem[Instance], nil, 0, nil, I) = 0 then
|
||||
@@ -412,10 +357,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
LZO2A_CODEC:
|
||||
case GetBits(StreamInfo^.Option, 12, 12) of
|
||||
case GetBits(StreamInfo^.Option, 7, 12) of
|
||||
LZO2A_999:
|
||||
begin
|
||||
Params := 'v' + GetBits(StreamInfo^.Option, 12, 12).ToString;
|
||||
Params := 'v' + GetBits(StreamInfo^.Option, 7, 12).ToString;
|
||||
if not Result then
|
||||
if not lzo2a_999_compress(NewInput, StreamInfo^.NewSize, Buffer,
|
||||
@Res1, WrkMem[Instance]) = 0 then
|
||||
@@ -423,10 +368,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
LZO1C_CODEC:
|
||||
case GetBits(StreamInfo^.Option, 12, 12) of
|
||||
case GetBits(StreamInfo^.Option, 7, 12) of
|
||||
LZO1C_999:
|
||||
begin
|
||||
Params := 'v' + GetBits(StreamInfo^.Option, 12, 12).ToString;
|
||||
Params := 'v' + GetBits(StreamInfo^.Option, 7, 12).ToString;
|
||||
if not Result then
|
||||
if not lzo1c_999_compress(NewInput, StreamInfo^.NewSize, Buffer,
|
||||
@Res1, WrkMem[Instance]) = 0 then
|
||||
@@ -437,30 +382,14 @@ begin
|
||||
if not Result then
|
||||
Result := (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(LZOCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(LZOCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, Res1, Result);
|
||||
if Result or (StreamInfo^.Status >= TStreamStatus.Predicted) then
|
||||
break;
|
||||
end;
|
||||
{ if (Result = False) and ((StreamInfo^.Status >= TStreamStatus.Predicted) or
|
||||
(SOList[Instance][X].Count = 1)) and (DIFF_TOLERANCE > 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatch(OldInput, StreamInfo^.OldSize, Buffer, Res1,
|
||||
Buffer + Res1, Max(StreamInfo^.OldSize, Res1));
|
||||
Funcs^.LogPatch1(StreamInfo^.OldSize, Res1, Res2,
|
||||
Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2));
|
||||
if Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2) then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, Res2);
|
||||
SetBits(StreamInfo^.Option, 1, 31, 1);
|
||||
SOList[Instance][X].Add(I);
|
||||
Result := True;
|
||||
end;
|
||||
end; }
|
||||
if Result then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 5, 7);
|
||||
SetBits(StreamInfo^.Option, I, 3, 4);
|
||||
SOList[Instance][X].Add(I);
|
||||
end;
|
||||
end;
|
||||
@@ -475,7 +404,7 @@ var
|
||||
Res2: NativeUInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Params := '';
|
||||
@@ -485,53 +414,40 @@ begin
|
||||
Res1 := StreamInfo.NewSize;
|
||||
case X of
|
||||
LZO1X_CODEC:
|
||||
case GetBits(StreamInfo.Option, 12, 12) of
|
||||
case GetBits(StreamInfo.Option, 7, 12) of
|
||||
LZO1X_999:
|
||||
begin
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString + ':' +
|
||||
'v' + GetBits(StreamInfo.Option, 12, 12).ToString;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 4).ToString + ':' +
|
||||
'v' + GetBits(StreamInfo.Option, 7, 12).ToString;
|
||||
if not lzo1x_999_compress_level(Input, StreamInfo.NewSize, Buffer,
|
||||
@Res1, WrkMem[Instance], nil, 0, nil, GetBits(StreamInfo.Option,
|
||||
5, 7)) = 0 then
|
||||
3, 4)) = 0 then
|
||||
Res1 := 0;
|
||||
end;
|
||||
end;
|
||||
LZO2A_CODEC:
|
||||
case GetBits(StreamInfo.Option, 12, 12) of
|
||||
case GetBits(StreamInfo.Option, 7, 12) of
|
||||
LZO2A_999:
|
||||
begin
|
||||
Params := 'v' + GetBits(StreamInfo.Option, 12, 12).ToString;
|
||||
Params := 'v' + GetBits(StreamInfo.Option, 7, 12).ToString;
|
||||
if not lzo2a_999_compress(Input, StreamInfo.NewSize, Buffer, @Res1,
|
||||
WrkMem[Instance]) = 0 then
|
||||
Res1 := 0;
|
||||
end;
|
||||
end;
|
||||
LZO1C_CODEC:
|
||||
case GetBits(StreamInfo.Option, 12, 12) of
|
||||
case GetBits(StreamInfo.Option, 7, 12) of
|
||||
LZO1C_999:
|
||||
begin
|
||||
Params := 'v' + GetBits(StreamInfo.Option, 12, 12).ToString;
|
||||
Params := 'v' + GetBits(StreamInfo.Option, 7, 12).ToString;
|
||||
if not lzo2a_999_compress(Input, StreamInfo.NewSize, Buffer, @Res1,
|
||||
WrkMem[Instance]) = 0 then
|
||||
Res1 := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogRestore(LZOCodecs[GetBits(StreamInfo.Option, 0, 5)], PChar(Params),
|
||||
Funcs^.LogRestore(LZOCodecs[GetBits(StreamInfo.Option, 0, 3)], PChar(Params),
|
||||
StreamInfo.OldSize, StreamInfo.NewSize, Res1, True);
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatch(InputExt, StreamInfo.ExtSize, Buffer, Res1,
|
||||
Buffer + Res1, StreamInfo.OldSize);
|
||||
Funcs^.LogPatch2(StreamInfo.OldSize, Res1, StreamInfo.ExtSize, Res2 > 0);
|
||||
if Res2 > 0 then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
begin
|
||||
Output(Instance, Buffer, StreamInfo.OldSize);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -483,25 +483,25 @@ begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, MediaCodecs[FLAC_CODEC]) = 0) and FLACDLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, FLAC_CODEC, 0, 5);
|
||||
SetBits(Option^, FLAC_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, MediaCodecs[PACKJPG_CODEC]) = 0) and PackJPGDLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, PACKJPG_CODEC, 0, 5);
|
||||
SetBits(Option^, PACKJPG_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, MediaCodecs[BRUNSLI_CODEC]) = 0) and BrunsliDLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, BRUNSLI_CODEC, 0, 5);
|
||||
SetBits(Option^, BRUNSLI_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, MediaCodecs[JOJPEG_CODEC]) = 0) and JoJpegDLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, JOJPEG_CODEC, 0, 5);
|
||||
SetBits(Option^, JOJPEG_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -516,75 +516,10 @@ var
|
||||
Pos: NativeInt;
|
||||
X, Y, Z: Integer;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
wave_hdr: TWAVE_hdr;
|
||||
data_size, hdr_size: Cardinal;
|
||||
progressive: Boolean;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], MediaCodecs);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
Y := DI1.OldSize;
|
||||
case X of
|
||||
FLAC_CODEC:
|
||||
begin
|
||||
if GetWAVEInfo(Input, Y, @wave_hdr, @data_size, @hdr_size) then
|
||||
Y := data_size + hdr_size
|
||||
else
|
||||
Y := 0;
|
||||
end;
|
||||
PACKJPG_CODEC, BRUNSLI_CODEC, JOJPEG_CODEC:
|
||||
begin
|
||||
if GetJPEGInfo(Input, Y, @data_size, @progressive) then
|
||||
Y := data_size
|
||||
else
|
||||
Y := 0;
|
||||
end;
|
||||
else
|
||||
Y := 0;
|
||||
end;
|
||||
if Y > 0 then
|
||||
begin
|
||||
Z := data_size;
|
||||
if X = FLAC_CODEC then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, hdr_size);
|
||||
Move(Input^, Buffer^, hdr_size);
|
||||
Inc(PInteger(Buffer)^);
|
||||
Output(Instance, @hdr_size, hdr_size.Size);
|
||||
Output(Instance, Buffer, hdr_size);
|
||||
Output(Instance, Input + hdr_size, Z);
|
||||
Inc(Z, hdr_size.Size);
|
||||
Inc(Z, hdr_size);
|
||||
end
|
||||
else
|
||||
Output(Instance, Input, Z);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := Y;
|
||||
SI.NewSize := Z;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(MediaCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, -1);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Pos := 0;
|
||||
@@ -612,9 +547,9 @@ begin
|
||||
SI.OldSize := Y;
|
||||
SI.NewSize := Z;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, FLAC_CODEC, 0, 5);
|
||||
SetBits(SI.Option, FLAC_CODEC, 0, 3);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(MediaCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(MediaCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, -1);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, SI.OldSize);
|
||||
@@ -638,13 +573,13 @@ begin
|
||||
SI.NewSize := Z;
|
||||
SI.Option := 0;
|
||||
if CodecEnabled[BRUNSLI_CODEC] then
|
||||
SetBits(SI.Option, BRUNSLI_CODEC, 0, 5)
|
||||
SetBits(SI.Option, BRUNSLI_CODEC, 0, 3)
|
||||
else if CodecEnabled[JOJPEG_CODEC] then
|
||||
SetBits(SI.Option, JOJPEG_CODEC, 0, 5)
|
||||
SetBits(SI.Option, JOJPEG_CODEC, 0, 3)
|
||||
else if CodecEnabled[PACKJPG_CODEC] then
|
||||
SetBits(SI.Option, PACKJPG_CODEC, 0, 5);
|
||||
SetBits(SI.Option, PACKJPG_CODEC, 0, 3);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(MediaCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(MediaCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, -1);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, SI.OldSize);
|
||||
@@ -666,7 +601,7 @@ var
|
||||
progressive: Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
exit;
|
||||
Y := StreamInfo^.OldSize;
|
||||
@@ -705,7 +640,7 @@ begin
|
||||
else
|
||||
Output(Instance, Input, Z);
|
||||
StreamInfo^.NewSize := Z;
|
||||
Funcs^.LogScan2(MediaCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(MediaCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, -1);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -723,7 +658,7 @@ var
|
||||
Res1, Res2: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Params := '';
|
||||
@@ -833,7 +768,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogProcess(MediaCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(MediaCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, -1, Result);
|
||||
end;
|
||||
|
||||
@@ -849,7 +784,7 @@ var
|
||||
Res1, Res2: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Params := '';
|
||||
@@ -948,40 +883,6 @@ begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
{ while True do
|
||||
begin
|
||||
Res1 := jojpeg_Loop(ctx, jojpeg_Decompress);
|
||||
if Res1 = 0 then
|
||||
break;
|
||||
if (Res1 = jojpeg_dec_Input1) then
|
||||
begin
|
||||
Res2 := Min(StreamInfo.NewSize - I, J_WORKMEM);
|
||||
jojpeg_Addbuf(ctx, jojpeg_Decompress, PByte(Input) + I, Res2,
|
||||
jojpeg_dec_Input1);
|
||||
Inc(I, Res2);
|
||||
end;
|
||||
if (Res1 = jojpeg_dec_Input2) then
|
||||
begin
|
||||
Res2 := Min(StreamInfo.ExtSize - J, J_WORKMEM);
|
||||
jojpeg_Addbuf(ctx, jojpeg_Decompress, PByte(InputExt) + J, Res2,
|
||||
jojpeg_dec_Input2);
|
||||
Inc(J, Res2);
|
||||
end;
|
||||
if (Res1 = jojpeg_dec_Output) then
|
||||
begin
|
||||
Output(Instance, Buffer, J_WORKMEM);
|
||||
Inc(Y, J_WORKMEM);
|
||||
jojpeg_Addbuf(ctx, jojpeg_Decompress, Buffer, J_WORKMEM,
|
||||
jojpeg_dec_Output);
|
||||
end;
|
||||
end;
|
||||
if (Y <> StreamInfo.OldSize) and (StreamInfo.OldSize - Y < J_WORKMEM)
|
||||
then
|
||||
begin
|
||||
Res2 := StreamInfo.OldSize - Y;
|
||||
Output(Instance, Buffer, Res2);
|
||||
Inc(Y, Res2);
|
||||
end; }
|
||||
Res := Y;
|
||||
Result := Y = StreamInfo.OldSize;
|
||||
finally
|
||||
@@ -989,7 +890,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogRestore(MediaCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
Funcs^.LogRestore(MediaCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.NewSize, Res, -1, Result);
|
||||
end;
|
||||
|
||||
|
@@ -29,14 +29,15 @@ const
|
||||
O_WORKMEM = 64 * 1024 * 1024;
|
||||
O_LENGTH = 32;
|
||||
O_TRADEOFF = 256;
|
||||
O_DICTIONARY = 0;
|
||||
O_BLOCKSIZE = 0;
|
||||
|
||||
var
|
||||
SOList: array of array [0 .. CODEC_COUNT - 1] of TSOList;
|
||||
OMaxSize: Integer = O_MAXSIZE;
|
||||
OWorkMem: Integer = O_WORKMEM;
|
||||
OLength: Integer = O_LENGTH;
|
||||
OTradeOff: Integer = O_TRADEOFF;
|
||||
ODictionary: Integer = O_DICTIONARY;
|
||||
OBlockSize: Integer = O_BLOCKSIZE;
|
||||
CodecAvailable, CodecEnabled: TArray<Boolean>;
|
||||
|
||||
type
|
||||
@@ -211,7 +212,7 @@ procedure OodleDecompressCB(userdata: Pointer; rawBuf: PByte;
|
||||
rawLen: NativeUInt; compBuf: PByte; compBufferSize, rawDone,
|
||||
compUsed: NativeUInt);
|
||||
begin
|
||||
WriteLn(ErrOutput, rawDone);
|
||||
|
||||
end;
|
||||
|
||||
function LocalLZ_Decompress(asrc, adst: PByte; asrcSize, adstCapacity: Integer;
|
||||
@@ -240,14 +241,29 @@ function CustomLZ_Decompress(src, dst: PByte; srcSize, dstCapacity: Integer;
|
||||
var Res: Integer): Boolean;
|
||||
const
|
||||
BlkSize = 262144;
|
||||
ScnSize = 4096;
|
||||
Sc2Size = 16384;
|
||||
var
|
||||
W, X, Y, Z: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
Y := 0;
|
||||
X := dstCapacity;
|
||||
X := Min(Max(LocalLZ_Decompress(src, dst, srcSize, X, 0, Y),
|
||||
LocalLZ_Decompress(src, dst, srcSize, X, 1, Z)), Pred(X));
|
||||
W := dstCapacity;
|
||||
X := 0;
|
||||
while (X < srcSize) and (W > srcSize) and
|
||||
(W > Max(0, dstCapacity - BlkSize)) do
|
||||
begin
|
||||
X := Min(Max(LocalLZ_Decompress(src, dst, srcSize, W, 0, Y),
|
||||
LocalLZ_Decompress(src, dst, srcSize, W, 1, Z)), W);
|
||||
Dec(W, ScnSize);
|
||||
end;
|
||||
if X < srcSize then
|
||||
exit;
|
||||
if X mod Sc2Size <> 0 then
|
||||
begin
|
||||
X := X + Sc2Size - (X mod Sc2Size);
|
||||
X := Min(Max(LocalLZ_Decompress(src, dst, srcSize, X, 0, Y),
|
||||
LocalLZ_Decompress(src, dst, srcSize, X, 1, Z)), X);
|
||||
end;
|
||||
W := X;
|
||||
while (Y = 0) and (X > dstCapacity - BlkSize) and (W - X < OLength) do
|
||||
begin
|
||||
@@ -306,26 +322,27 @@ begin
|
||||
SI.Position := Pos;
|
||||
SI.OldSize := StreamInfo^.CSize;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, OTradeOff, 13, 11);
|
||||
SetBits(SI.Option, OTradeOff, 8, 11);
|
||||
SetBits(SI.Option, OBlockSize, 19, 13);
|
||||
case StreamInfo^.Codec of
|
||||
1:
|
||||
if CodecEnabled[KRAKEN_CODEC] then
|
||||
SetBits(SI.Option, KRAKEN_CODEC, 0, 5);
|
||||
SetBits(SI.Option, KRAKEN_CODEC, 0, 3);
|
||||
2:
|
||||
if CodecEnabled[MERMAID_CODEC] then
|
||||
SetBits(SI.Option, MERMAID_CODEC, 0, 5)
|
||||
SetBits(SI.Option, MERMAID_CODEC, 0, 3)
|
||||
else if CodecEnabled[SELKIE_CODEC] then
|
||||
SetBits(SI.Option, SELKIE_CODEC, 0, 5);
|
||||
SetBits(SI.Option, SELKIE_CODEC, 0, 3);
|
||||
3:
|
||||
if CodecEnabled[LEVIATHAN_CODEC] then
|
||||
SetBits(SI.Option, LEVIATHAN_CODEC, 0, 5);
|
||||
SetBits(SI.Option, LEVIATHAN_CODEC, 0, 3);
|
||||
end;
|
||||
if CodecEnabled[HYDRA_CODEC] then
|
||||
SetBits(SI.Option, HYDRA_CODEC, 0, 5);
|
||||
SetBits(SI.Option, Integer(StreamInfo^.HasCRC), 12, 1);
|
||||
SetBits(SI.Option, HYDRA_CODEC, 0, 3);
|
||||
SetBits(SI.Option, Integer(StreamInfo^.HasCRC), 7, 1);
|
||||
SI.Status := TStreamStatus.None;
|
||||
SI.NewSize := Result;
|
||||
Funcs^.LogScan1(OodleCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(OodleCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
end;
|
||||
@@ -385,12 +402,14 @@ begin
|
||||
([StrToInt(Funcs^.GetParam(Command, X, 'l'))], True);
|
||||
if Funcs^.GetParam(Command, X, 's') <> '' then
|
||||
OMaxSize := ConvertToBytes(Funcs^.GetParam(Command, X, 's'));
|
||||
if Funcs^.GetParam(Command, X, 'w') <> '' then
|
||||
OWorkMem := StrToInt(Funcs^.GetParam(Command, X, 'w'));
|
||||
if Funcs^.GetParam(Command, X, 'n') <> '' then
|
||||
OLength := StrToInt(Funcs^.GetParam(Command, X, 'n'));
|
||||
if Funcs^.GetParam(Command, X, 't') <> '' then
|
||||
OTradeOff := StrToInt(Funcs^.GetParam(Command, X, 't'));
|
||||
if Funcs^.GetParam(Command, X, 'd') <> '' then
|
||||
ODictionary := StrToInt(Funcs^.GetParam(Command, X, 'd'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
OBlockSize := StrToInt(Funcs^.GetParam(Command, X, 'b'));
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
@@ -420,7 +439,8 @@ var
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
SetBits(Option^, OTradeOff, 13, 11);
|
||||
SetBits(Option^, OTradeOff, 8, 11);
|
||||
SetBits(Option^, OBlockSize, 19, 13);
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
@@ -428,15 +448,15 @@ begin
|
||||
for J := Low(OodleCodecs) to High(OodleCodecs) do
|
||||
if (CompareText(S, OodleCodecs[J]) = 0) and OodleDLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, J, 0, 5);
|
||||
SetBits(Option^, J, 0, 3);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 4);
|
||||
if String(Funcs^.GetParam(Command, I, 'c')) = '1' then
|
||||
SetBits(Option^, 1, 12, 1);
|
||||
SetBits(Option^, 1, 7, 1);
|
||||
if Funcs^.GetParam(Command, I, 't') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 't')), 13, 11);
|
||||
if Funcs^.GetParam(Command, I, 'd') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'd')), 24, 5);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 't')), 8, 11);
|
||||
if Funcs^.GetParam(Command, I, 'b') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'b')), 19, 13);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -453,71 +473,7 @@ var
|
||||
Res: Integer;
|
||||
SI: _StrInfo1;
|
||||
OodleSI: TOodleSI;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], OodleCodecs);
|
||||
if X < 0 then
|
||||
exit;
|
||||
if DI1.OldSize = 0 then
|
||||
DI1.OldSize := SizeEx;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
if (X in [LZNA_CODEC, LEVIATHAN_CODEC]) and (DI1.NewSize <= 0) then
|
||||
exit;
|
||||
if DI1.NewSize <= 0 then
|
||||
Res := OMaxSize
|
||||
else
|
||||
Res := DI1.NewSize;
|
||||
Buffer := Funcs^.Allocator(Instance, Res);
|
||||
case X of
|
||||
KRAKEN_CODEC, MERMAID_CODEC, SELKIE_CODEC, HYDRA_CODEC:
|
||||
begin
|
||||
if DI1.NewSize <= 0 then
|
||||
begin
|
||||
if not CustomLZ_Decompress(Input, Buffer, DI1.OldSize, Res, Res)
|
||||
then
|
||||
Res := 0;
|
||||
end
|
||||
else
|
||||
Res := OodleLZ_Decompress(Input, DI1.OldSize, Buffer, Res);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
if DI1.NewSize > 0 then
|
||||
Res := OodleLZ_Decompress(Input, DI1.OldSize, Buffer, Res)
|
||||
else
|
||||
Res := 0;
|
||||
end;
|
||||
end;
|
||||
if (Res > DI1.OldSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := DI1.OldSize;
|
||||
SI.NewSize := Res;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(OodleCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Pos := 0;
|
||||
@@ -554,13 +510,20 @@ var
|
||||
Buffer: PByte;
|
||||
B: Boolean;
|
||||
I: Integer;
|
||||
ResultN: TIntegerDynArray;
|
||||
X: Integer;
|
||||
Res: Integer;
|
||||
OodleSI: TOodleSI;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if (StreamInfo^.OldSize > 0) and REPROCESSED then
|
||||
if (Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^)
|
||||
.Lo = StreamInfo^.OldSize) and
|
||||
(Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Lo <
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi)
|
||||
then
|
||||
StreamInfo^.OldSize :=
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi;
|
||||
if (X <> LZNA_CODEC) and (StreamInfo^.OldSize <= 0) then
|
||||
begin
|
||||
GetOodleSI(Input, Size, @OodleSI);
|
||||
@@ -586,7 +549,7 @@ begin
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
StreamInfo^.NewSize := Res;
|
||||
Funcs^.LogScan2(OodleCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(OodleCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -602,17 +565,17 @@ var
|
||||
I: Integer;
|
||||
W: Integer;
|
||||
X, Y: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
COptions: TOodleLZ_CompressOptions;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Y := GetOodleCodec(X);
|
||||
Buffer := Funcs^.Allocator(Instance, OodleLZ_GetCompressedBufferSizeNeeded(Y,
|
||||
StreamInfo^.NewSize) + IfThen(OldCompress, 0, O_WORKMEM));
|
||||
StreamInfo^.NewSize) + IfThen(OldCompress, 0, OWorkMem));
|
||||
if OldCompress then
|
||||
begin
|
||||
Work := nil;
|
||||
@@ -622,17 +585,16 @@ begin
|
||||
begin
|
||||
Work := Buffer + OodleLZ_GetCompressedBufferSizeNeeded(Y,
|
||||
StreamInfo^.NewSize);
|
||||
W := O_WORKMEM;
|
||||
W := OWorkMem;
|
||||
end;
|
||||
SOList[Instance][X].Index := 0;
|
||||
while SOList[Instance][X].Get(I) >= 0 do
|
||||
begin
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 5, 7) <> I then
|
||||
if GetBits(StreamInfo^.Option, 3, 4) <> I then
|
||||
continue;
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) and
|
||||
(GetBits(StreamInfo^.Option, 31, 1) = 0) then
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) then
|
||||
begin
|
||||
Res1 := StreamInfo^.OldSize;
|
||||
Result := True;
|
||||
@@ -640,20 +602,19 @@ begin
|
||||
end;
|
||||
Move(OodleLZ_CompressOptions_GetDefault(Y, I)^, COptions,
|
||||
SizeOf(TOodleLZ_CompressOptions));
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo^.Option, 12, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo^.Option, 13, 11);
|
||||
COptions.dictionarySize := IfThen(GetBits(StreamInfo^.Option, 24, 5) = 0, 0,
|
||||
Round(Power(2, GetBits(StreamInfo^.Option, 24, 5))));
|
||||
Params := 'l' + I.ToString + ':' + 'c' + GetBits(StreamInfo^.Option, 12, 1)
|
||||
.ToString + ':' + 't' + GetBits(StreamInfo^.Option, 13, 11).ToString + ':'
|
||||
+ 'd' + GetBits(StreamInfo^.Option, 24, 5).ToString;
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo^.Option, 7, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo^.Option, 8, 11);
|
||||
COptions.dictionarySize := GetBits(StreamInfo^.Option, 19, 13) * 1024;
|
||||
Params := 'l' + I.ToString + ':' + 'c' + GetBits(StreamInfo^.Option, 7, 1)
|
||||
.ToString + ':' + 't' + GetBits(StreamInfo^.Option, 8, 11).ToString + ':'
|
||||
+ 'b' + GetBits(StreamInfo^.Option, 19, 13).ToString;
|
||||
if not Result then
|
||||
Res1 := OodleLZ_Compress(Y, NewInput, StreamInfo^.NewSize, Buffer, I,
|
||||
@COptions, nil, nil, Work, W);
|
||||
if not Result then
|
||||
Result := (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(OodleCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(OodleCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, Res1, Result);
|
||||
if Result or (StreamInfo^.Status = TStreamStatus.Predicted) then
|
||||
break;
|
||||
@@ -666,10 +627,9 @@ begin
|
||||
begin
|
||||
Move(OodleLZ_CompressOptions_GetDefault(Y, B)^, COptions,
|
||||
SizeOf(TOodleLZ_CompressOptions));
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo^.Option, 12, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo^.Option, 13, 11);
|
||||
COptions.dictionarySize := IfThen(GetBits(StreamInfo^.Option, 24, 5) = 0,
|
||||
0, Round(Power(2, GetBits(StreamInfo^.Option, 24, 5))));
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo^.Option, 7, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo^.Option, 8, 11);
|
||||
COptions.dictionarySize := GetBits(StreamInfo^.Option, 19, 13) * 1024;
|
||||
Res1 := OodleLZ_Compress(Y, NewInput, StreamInfo^.NewSize, Buffer, B,
|
||||
@COptions, nil, nil, Work, W);
|
||||
if (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
@@ -679,25 +639,9 @@ begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
{ if (Result = False) and ((StreamInfo^.Status >= TStreamStatus.Predicted) or
|
||||
(SOList[Instance][X].Count = 1)) and (DIFF_TOLERANCE > 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatch(OldInput, StreamInfo^.OldSize, Buffer, Res1,
|
||||
Buffer + Res1, Max(StreamInfo^.OldSize, Res1));
|
||||
Funcs^.LogPatch1(StreamInfo^.OldSize, Res1, Res2,
|
||||
Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2));
|
||||
if Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2) then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, Res2);
|
||||
SetBits(StreamInfo^.Option, 1, 31, 1);
|
||||
SOList[Instance][X].Add(I);
|
||||
Result := True;
|
||||
end;
|
||||
end; }
|
||||
if Result then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 5, 7);
|
||||
SetBits(StreamInfo^.Option, I, 3, 4);
|
||||
SOList[Instance][X].Add(I);
|
||||
end;
|
||||
end;
|
||||
@@ -709,17 +653,17 @@ var
|
||||
Params: String;
|
||||
W: Integer;
|
||||
X, Y: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
COptions: TOodleLZ_CompressOptions;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if CodecAvailable[X] = False then
|
||||
exit;
|
||||
Y := GetOodleCodec(X);
|
||||
Buffer := Funcs^.Allocator(Instance, OodleLZ_GetCompressedBufferSizeNeeded(Y,
|
||||
StreamInfo.NewSize) + IfThen(OldCompress, 0, O_WORKMEM));
|
||||
StreamInfo.NewSize) + IfThen(OldCompress, 0, OWorkMem));
|
||||
if OldCompress then
|
||||
begin
|
||||
Work := nil;
|
||||
@@ -729,35 +673,21 @@ begin
|
||||
begin
|
||||
Work := Buffer + OodleLZ_GetCompressedBufferSizeNeeded(Y,
|
||||
StreamInfo.NewSize);
|
||||
W := O_WORKMEM;
|
||||
W := OWorkMem;
|
||||
end;
|
||||
Move(OodleLZ_CompressOptions_GetDefault(Y, GetBits(StreamInfo.Option, 5, 7))^,
|
||||
Move(OodleLZ_CompressOptions_GetDefault(Y, GetBits(StreamInfo.Option, 3, 4))^,
|
||||
COptions, SizeOf(TOodleLZ_CompressOptions));
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo.Option, 12, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo.Option, 13, 11);
|
||||
COptions.dictionarySize := IfThen(GetBits(StreamInfo.Option, 24, 5) = 0, 0,
|
||||
Round(Power(2, GetBits(StreamInfo.Option, 24, 5))));
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString + ':' + 'c' +
|
||||
GetBits(StreamInfo.Option, 12, 1).ToString + ':' + 't' +
|
||||
GetBits(StreamInfo.Option, 13, 11).ToString + ':' + 'd' +
|
||||
GetBits(StreamInfo.Option, 24, 5).ToString;
|
||||
COptions.sendQuantumCRCs := GetBits(StreamInfo.Option, 7, 1) = 1;
|
||||
COptions.spaceSpeedTradeoffBytes := GetBits(StreamInfo.Option, 8, 11);
|
||||
COptions.dictionarySize := GetBits(StreamInfo.Option, 19, 13) * 1024;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 4).ToString + ':' + 'c' +
|
||||
GetBits(StreamInfo.Option, 7, 1).ToString + ':' + 't' +
|
||||
GetBits(StreamInfo.Option, 8, 11).ToString + ':' + 'b' +
|
||||
GetBits(StreamInfo.Option, 19, 13).ToString;
|
||||
Res1 := OodleLZ_Compress(Y, Input, StreamInfo.NewSize, Buffer,
|
||||
GetBits(StreamInfo.Option, 5, 7), @COptions, nil, nil, Work, W);
|
||||
Funcs^.LogRestore(OodleCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
GetBits(StreamInfo.Option, 3, 4), @COptions, nil, nil, Work, W);
|
||||
Funcs^.LogRestore(OodleCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize, Res1, True);
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatch(InputExt, StreamInfo.ExtSize, Buffer, Res1,
|
||||
Buffer + Res1, StreamInfo.OldSize);
|
||||
Funcs^.LogPatch2(StreamInfo.OldSize, Res1, StreamInfo.ExtSize, Res2 > 0);
|
||||
if Res2 > 0 then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
begin
|
||||
Output(Instance, Buffer, StreamInfo.OldSize);
|
||||
|
@@ -5,7 +5,6 @@ interface
|
||||
uses
|
||||
InitCode,
|
||||
Utils, SynCommons, SynCrypto,
|
||||
UIMain,
|
||||
PrecompUtils,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.StrUtils,
|
||||
@@ -56,7 +55,7 @@ var
|
||||
CodecSearch: TArray<TArray<TSearchStruct>>;
|
||||
CodecAvailable, CodecEnabled: TArray<Boolean>;
|
||||
|
||||
function CheckHashList(Instance: Integer; Position: NativeInt;
|
||||
function CheckHashList(Instance: Integer; Position, SizeEx: NativeInt;
|
||||
HashList: TArray<THashStruct>; Funcs: PPrecompFuncs): Boolean;
|
||||
const
|
||||
BufferSize = 65536;
|
||||
@@ -83,8 +82,8 @@ begin
|
||||
end;
|
||||
if (X > 0) or (CRC <> HashList[I].Hash) then
|
||||
break;
|
||||
if I = High(HashList) then
|
||||
Result := True;
|
||||
if (I = High(HashList)) or ((FULLSCAN = False) and (LPos > SizeEx)) then
|
||||
exit(True)
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -174,7 +173,6 @@ var
|
||||
X, Y: Integer;
|
||||
Pos, LSize: NativeInt;
|
||||
SI: _StrInfo1;
|
||||
DI: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
SS: PSearchStruct;
|
||||
CRC: Cardinal;
|
||||
@@ -205,8 +203,8 @@ begin
|
||||
Checked := True;
|
||||
end;
|
||||
if (CodecSearch[I, SearchInfo[I, J, X]].Hash = CRC) and
|
||||
CheckHashList(Instance, Pos, CodecSearch[I, SearchInfo[I, J, X]]
|
||||
.HashList, Funcs) then
|
||||
CheckHashList(Instance, Pos, SizeEx,
|
||||
CodecSearch[I, SearchInfo[I, J, X]].HashList, Funcs) then
|
||||
begin
|
||||
SS := @CodecSearch[I, SearchInfo[I, J, X]];
|
||||
Output(Instance, nil, 0);
|
||||
@@ -221,11 +219,11 @@ begin
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
Add(Instance, @SI, PChar(SS^.Codec), nil);
|
||||
DS := Funcs^.GetDepthCodec(PChar(SS^.Codec));
|
||||
Move(DS[0], DI.Codec, SizeOf(DI.Codec));
|
||||
DI.OldSize := SS^.EntryList[Y].NewSize;
|
||||
DI.NewSize := SS^.EntryList[Y].DepthSize;
|
||||
Add(Instance, @SI, PChar(SS^.Codec), @DI);
|
||||
if DS <> '' then
|
||||
Funcs^.AddDepthStream(Instance, 0, SS^.EntryList[Y].NewSize,
|
||||
SS^.EntryList[Y].DepthSize, DS, 0, 0);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@@ -279,12 +277,17 @@ begin
|
||||
begin
|
||||
if FStream.Position < FStream.Size then
|
||||
begin
|
||||
if SameText(ChangeFileExt(ExtractFileName(SearchList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
FORCEDMETHOD := True;
|
||||
J := Length(CodecSearch);
|
||||
SetLength(CodecSearch, Succ(J));
|
||||
S := ChangeFileExt(ExtractFileName(SearchList[I]), '');
|
||||
Insert(S, Codec.Names, Length(Codec.Names));
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S, PLUGIN_DATABASE);
|
||||
if not SameText(ChangeFileExt(ExtractFileName(SearchList[I]), ''),
|
||||
ChangeFileExt(ExtractFileName(Utils.GetModuleName), '')) then
|
||||
if InitCode.UIDLLLoaded then
|
||||
XTLAddplugin(S, PLUGIN_DATABASE);
|
||||
end;
|
||||
while FStream.Position < FStream.Size do
|
||||
begin
|
||||
|
@@ -4,7 +4,7 @@ interface
|
||||
|
||||
uses
|
||||
InitCode,
|
||||
Utils, Threading, XXHASHLIB,
|
||||
Utils, Threading, XXHASHLIB, ZSTDLib,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math,
|
||||
System.Generics.Defaults, System.Generics.Collections;
|
||||
@@ -36,12 +36,14 @@ type
|
||||
|
||||
TStreamStatus = (None, Invalid, Predicted, Database);
|
||||
|
||||
PDepthInfo = ^TDepthInfo;
|
||||
PDepthStream = ^TDepthStream;
|
||||
|
||||
TDepthInfo = packed record
|
||||
Codec: array [0 .. 31] of Char;
|
||||
OldSize: Integer;
|
||||
NewSize: Integer;
|
||||
TDepthStream = record
|
||||
Position: Int64;
|
||||
OldSize, NewSize: Integer;
|
||||
Resource: Integer;
|
||||
Codec: Byte;
|
||||
Option: Integer;
|
||||
end;
|
||||
|
||||
PEncodeSI = ^TEncodeSI;
|
||||
@@ -58,7 +60,7 @@ type
|
||||
Option: Integer;
|
||||
Checksum: XXH128_hash_t;
|
||||
Status: TStreamStatus;
|
||||
DepthInfo: TDepthInfo;
|
||||
DepthStreams: TArray<TDepthStream>;
|
||||
end;
|
||||
|
||||
PFutureSI = ^TFutureSI;
|
||||
@@ -71,7 +73,7 @@ type
|
||||
Scan2: Boolean;
|
||||
Option: Integer;
|
||||
Status: TStreamStatus;
|
||||
DepthInfo: TDepthInfo;
|
||||
DepthStreams: TArray<TDepthStream>;
|
||||
end;
|
||||
|
||||
PStreamHeader = ^TStreamHeader;
|
||||
@@ -124,7 +126,8 @@ type
|
||||
: TPrecompStr cdecl;
|
||||
GetParam: function(Cmd: PChar; Index: Integer; Param: PChar)
|
||||
: TPrecompStr cdecl;
|
||||
GetDepthInfo: function(Index: Integer): TDepthInfo cdecl;
|
||||
AddDepthStream: procedure(Instance: Integer; Position: Int64;
|
||||
OldSize, NewSize: Integer; Codec: PChar; Option, Resource: Integer)cdecl;
|
||||
Compress: function(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
OutBuff: Pointer; OutSize: Integer; DictBuff: Pointer; DictSize: Integer)
|
||||
: Integer cdecl; // 5
|
||||
@@ -203,7 +206,7 @@ type
|
||||
_PrecompOutput = procedure(Instance: Integer; const Buffer: Pointer;
|
||||
Size: Integer)cdecl;
|
||||
_PrecompAdd = procedure(Instance: Integer; Info: PStrInfo1; Codec: PChar;
|
||||
DepthInfo: PDepthInfo)cdecl;
|
||||
Reserved: Pointer)cdecl;
|
||||
|
||||
_PrecompInit = function(Command: PChar; Count: Integer;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
@@ -260,7 +263,7 @@ type
|
||||
TDuplicate1 = packed record
|
||||
Size: Integer;
|
||||
Checksum: XXH128_hash_t;
|
||||
Index: Integer;
|
||||
Index1, Index2: Integer;
|
||||
Count: Integer;
|
||||
end;
|
||||
|
||||
@@ -271,10 +274,17 @@ type
|
||||
Count: Integer;
|
||||
end;
|
||||
|
||||
PDuplicate3 = ^TDuplicate3;
|
||||
|
||||
TDuplicate3 = packed record
|
||||
Size: Integer;
|
||||
Index: Integer;
|
||||
Count: Integer;
|
||||
end;
|
||||
|
||||
TPrecompVMStream = class(TStream)
|
||||
private const
|
||||
FSuffix1 = '-vm.tmp';
|
||||
FSuffix2 = '_mapped.io';
|
||||
FSuffix = '-vm.tmp';
|
||||
protected
|
||||
procedure SetSize(const NewSize: Int64); override;
|
||||
procedure SetSize(NewSize: Longint); override;
|
||||
@@ -301,6 +311,9 @@ type
|
||||
Size: Integer;
|
||||
end;
|
||||
|
||||
procedure _Init(Count: Integer);
|
||||
procedure _Free;
|
||||
|
||||
procedure AddMethod(Method: String);
|
||||
procedure ClearMethods;
|
||||
|
||||
@@ -327,9 +340,15 @@ function PrecompHash(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
function PrecompEncodePatch(OldBuff: Pointer; OldSize: Integer;
|
||||
NewBuff: Pointer; NewSize: Integer; PatchBuff: Pointer; PatchSize: Integer)
|
||||
: Integer cdecl;
|
||||
function PrecompEncodePatchEx(Instance: Integer; OldBuff: Pointer;
|
||||
OldSize: Integer; NewBuff: Pointer; NewSize: Integer; Output: _PrecompOutput)
|
||||
: Integer cdecl;
|
||||
function PrecompDecodePatch(PatchBuff: Pointer; PatchSize: Integer;
|
||||
OldBuff: Pointer; OldSize: Integer; NewBuff: Pointer; NewSize: Integer)
|
||||
: Integer cdecl;
|
||||
function PrecompDecodePatchEx(Instance: Integer; PatchBuff: Pointer;
|
||||
PatchSize: Integer; OldBuff: Pointer; OldSize: Integer;
|
||||
Output: _PrecompOutput): Integer cdecl;
|
||||
function PrecompAddResource(FileName: PChar): Integer cdecl;
|
||||
function PrecompGetResource(Index: Integer; Data: Pointer; Size: PInteger)
|
||||
: Boolean cdecl;
|
||||
@@ -367,9 +386,14 @@ function PrecompAcceptPatch(OldSize, NewSize, PatchSize: Integer)
|
||||
: Boolean cdecl;
|
||||
|
||||
var
|
||||
Codec: TPrecompressor;
|
||||
PrecompFunctions: _PrecompFuncs;
|
||||
DIFF_TOLERANCE: Single = 0.05;
|
||||
DIFF_CLEVEL: Integer = 1;
|
||||
OPTIMISE_DEC: Boolean = False;
|
||||
FULLSCAN: Boolean = False;
|
||||
REPROCESSED: Boolean = False;
|
||||
FORCEDMETHOD: Boolean = False;
|
||||
EncodeSICmp: TEncodeSIComparer;
|
||||
FutureSICmp: TFutureSIComparer;
|
||||
StockMethods, ExternalMethods: TStringList;
|
||||
@@ -378,9 +402,46 @@ var
|
||||
implementation
|
||||
|
||||
uses
|
||||
ZLibDLL, LZ4DLL, LZODLL, ZSTDDLL, OodleDLL, XDeltaDLL,
|
||||
ZLibDLL, LZ4DLL, LZODLL, ZSTDDLL, OodleDLL,
|
||||
SynCommons, SynCrypto;
|
||||
|
||||
const
|
||||
DummyCodecs: array of PChar = ['none'];
|
||||
CODEC_COUNT = 1;
|
||||
NONE_CODEC = 0;
|
||||
|
||||
type
|
||||
TPrecompVar = record
|
||||
ZSTDCtx1: ZSTD_CCtx;
|
||||
ZSTDCtx2: ZSTD_DCtx;
|
||||
end;
|
||||
|
||||
var
|
||||
_PrecompVar: TArray<TPrecompVar>;
|
||||
|
||||
procedure _Init(Count: Integer);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
SetLength(_PrecompVar, Count);
|
||||
for I := Low(_PrecompVar) to High(_PrecompVar) do
|
||||
begin
|
||||
_PrecompVar[I].ZSTDCtx1 := ZSTDLib.ZSTD_createCCtx;
|
||||
_PrecompVar[I].ZSTDCtx2 := ZSTDLib.ZSTD_createDCtx;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _Free;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
for I := Low(_PrecompVar) to High(_PrecompVar) do
|
||||
begin
|
||||
ZSTDLib.ZSTD_freeCCtx(_PrecompVar[I].ZSTDCtx1);
|
||||
ZSTDLib.ZSTD_freeDCtx(_PrecompVar[I].ZSTDCtx2);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TEncodeSIComparer.Compare(const Left, Right: TEncodeSI): Integer;
|
||||
begin
|
||||
Result := Integer(CompareValue(Left.ActualPosition, Right.ActualPosition));
|
||||
@@ -431,7 +492,7 @@ begin
|
||||
List2 := DecodeStr(List1[I], SPrecompSep2);
|
||||
for J := Succ(Low(List2)) to High(List2) do
|
||||
begin
|
||||
if FileExists(PluginsPath + List2[J]) then
|
||||
if FileExists(ExpandPath(PluginsPath + List2[J], True)) then
|
||||
begin
|
||||
Result := PrecompAddResource(PChar(List2[J]));
|
||||
break;
|
||||
@@ -473,16 +534,10 @@ begin
|
||||
if FInitialised then
|
||||
exit;
|
||||
FFilename := LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName),
|
||||
FSuffix1));
|
||||
FSuffix));
|
||||
if FileExists(FFilename) then
|
||||
DeleteFile(FFilename);
|
||||
{$IFDEF CPU32BITS}
|
||||
FStream := TFileStream.Create(FFilename, fmCreate);
|
||||
{$ELSE}
|
||||
FStream := TSharedMemoryStream.Create
|
||||
(LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName),
|
||||
'_' + Random($7FFFFFFF).ToHexString + FSuffix2)), FFilename);
|
||||
{$ENDIF}
|
||||
FStream := TFileStreamEx.Create(FFilename, $4000000);
|
||||
FInitialised := True;
|
||||
end;
|
||||
|
||||
@@ -594,7 +649,7 @@ begin
|
||||
else
|
||||
begin
|
||||
for I := Succ(Low(List2)) to High(List2) do
|
||||
if List2[I].StartsWith(Param, False) and
|
||||
if List2[I].StartsWith(Param, True) and
|
||||
(ResourceExists(List2[I]) = False) then
|
||||
begin
|
||||
S := List2[I].Substring(Length(Param));
|
||||
@@ -631,12 +686,15 @@ function PrecompCompress(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
DictSize: Integer): Integer;
|
||||
var
|
||||
ZStream: z_stream;
|
||||
LZ4FT: LZ4F_preferences_t;
|
||||
I, X: Integer;
|
||||
S: String;
|
||||
dst: NativeUInt;
|
||||
WrkMem: array [0 .. $7FFFF] of Byte;
|
||||
begin
|
||||
Result := 0;
|
||||
X := IndexText(PrecompGetCodec(Codec, 0, False),
|
||||
['zlib', 'lz4', 'lz4hc', 'lzo1c', 'lzo1x', 'lzo2a', 'zstd', 'lzna',
|
||||
['zlib', 'lz4', 'lz4hc', 'lz4f', 'lzo1c', 'lzo1x', 'lzo2a', 'zstd', 'lzna',
|
||||
'kraken', 'mermaid', 'selkie', 'hydra', 'leviathan']);
|
||||
case X of
|
||||
0:
|
||||
@@ -677,7 +735,52 @@ begin
|
||||
Result := LZ4_compress_HC(InBuff, OutBuff, InSize, OutSize,
|
||||
StrToInt(S));
|
||||
end;
|
||||
3:
|
||||
if LZ4DLL.DLLLoaded then
|
||||
begin
|
||||
FillChar(LZ4FT, SizeOf(LZ4F_preferences_t), 0);
|
||||
S := PrecompGetParam(Codec, 0, 'l');
|
||||
if S = '' then
|
||||
S := '9';
|
||||
LZ4FT.compressionLevel := S.ToInteger;
|
||||
S := PrecompGetParam(Codec, 0, 'b');
|
||||
if S = '' then
|
||||
S := '4';
|
||||
LZ4FT.frameInfo.blockSizeID := LZ4F_blockSizeID_t(S.ToInteger);
|
||||
S := PrecompGetParam(Codec, 0, 'd');
|
||||
if S = '' then
|
||||
S := '0';
|
||||
LZ4FT.frameInfo.blockMode := LZ4F_blockMode_t(S.ToInteger);
|
||||
Result := LZ4F_compressFrame(OutBuff, OutSize, InBuff, InSize, @LZ4FT);
|
||||
end;
|
||||
4:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
dst := OutSize;
|
||||
if lzo1c_999_compress(InBuff, InSize, OutBuff, @dst, @WrkMem[0]) = 0
|
||||
then
|
||||
Result := dst;
|
||||
end;
|
||||
5:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
S := PrecompGetParam(Codec, 0, 'l');
|
||||
if S = '' then
|
||||
S := '8';
|
||||
dst := OutSize;
|
||||
if lzo1x_999_compress_level(InBuff, InSize, OutBuff, @dst, @WrkMem[0],
|
||||
nil, 0, nil, StrToInt(S)) = 0 then
|
||||
Result := dst;
|
||||
end;
|
||||
6:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
dst := OutSize;
|
||||
if lzo2a_999_compress(InBuff, InSize, OutBuff, @dst, @WrkMem[0]) = 0
|
||||
then
|
||||
Result := dst;
|
||||
end;
|
||||
7:
|
||||
if ZSTDDLL.DLLLoaded then
|
||||
begin
|
||||
S := PrecompGetParam(Codec, 0, 'l');
|
||||
@@ -685,21 +788,21 @@ begin
|
||||
S := '19';
|
||||
Result := ZSTD_compress(OutBuff, OutSize, InBuff, InSize, StrToInt(S));
|
||||
end;
|
||||
7 .. 12:
|
||||
8 .. 13:
|
||||
if OodleDLL.DLLLoaded then
|
||||
begin
|
||||
case X of
|
||||
7:
|
||||
I := 6;
|
||||
8:
|
||||
I := 8;
|
||||
I := 7;
|
||||
9:
|
||||
I := 9;
|
||||
I := 8;
|
||||
10:
|
||||
I := 11;
|
||||
I := 9;
|
||||
11:
|
||||
I := 12;
|
||||
I := 11;
|
||||
12:
|
||||
I := 12;
|
||||
13:
|
||||
I := 13;
|
||||
else
|
||||
I := 8;
|
||||
@@ -718,11 +821,12 @@ function PrecompDecompress(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
var
|
||||
ZStream: z_stream;
|
||||
S: String;
|
||||
dst: NativeUInt;
|
||||
begin
|
||||
Result := 0;
|
||||
case IndexText(Codec, ['zlib', 'lz4', 'lz4hc', 'lz4f', 'lzo1c', 'lzo1x',
|
||||
'lzo2a', 'zstd', 'lzna', 'kraken', 'mermaid', 'selkie', 'hydra',
|
||||
'leviathan']) of
|
||||
case IndexText(PrecompGetCodec(Codec, 0, False),
|
||||
['zlib', 'lz4', 'lz4hc', 'lz4f', 'lzo1c', 'lzo1x', 'lzo2a', 'zstd', 'lzna',
|
||||
'kraken', 'mermaid', 'selkie', 'hydra', 'leviathan']) of
|
||||
0:
|
||||
if ZLibDLL.DLLLoaded then
|
||||
begin
|
||||
@@ -748,6 +852,27 @@ begin
|
||||
3:
|
||||
if LZ4DLL.DLLLoaded then
|
||||
Result := LZ4F_decompress_safe(InBuff, OutBuff, InSize, OutSize);
|
||||
4:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
dst := OutSize;
|
||||
if lzo1c_decompress_safe(InBuff, InSize, OutBuff, @dst) = 0 then
|
||||
Result := dst;
|
||||
end;
|
||||
5:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
dst := OutSize;
|
||||
if lzo1x_decompress_safe(InBuff, InSize, OutBuff, @dst) = 0 then
|
||||
Result := dst;
|
||||
end;
|
||||
6:
|
||||
if LZODLL.DLLLoaded then
|
||||
begin
|
||||
dst := OutSize;
|
||||
if lzo2a_decompress_safe(InBuff, InSize, OutBuff, @dst) = 0 then
|
||||
Result := dst;
|
||||
end;
|
||||
7:
|
||||
if ZSTDDLL.DLLLoaded then
|
||||
Result := ZSTD_decompress(OutBuff, OutSize, InBuff, InSize);
|
||||
@@ -760,7 +885,7 @@ end;
|
||||
function PrecompEncrypt(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
KeyBuff: Pointer; KeySize: Integer): Boolean;
|
||||
var
|
||||
AES: TAESECB;
|
||||
AES: TAESAbstract;
|
||||
RC4: TRC4;
|
||||
begin
|
||||
Result := False;
|
||||
@@ -792,7 +917,7 @@ end;
|
||||
function PrecompDecrypt(Codec: PChar; InBuff: Pointer; InSize: Integer;
|
||||
KeyBuff: Pointer; KeySize: Integer): Boolean;
|
||||
var
|
||||
AES: TAESECB;
|
||||
AES: TAESAbstract;
|
||||
RC4: TRC4;
|
||||
begin
|
||||
Result := False;
|
||||
@@ -906,31 +1031,148 @@ end;
|
||||
function PrecompEncodePatch(OldBuff: Pointer; OldSize: Integer;
|
||||
NewBuff: Pointer; NewSize: Integer; PatchBuff: Pointer;
|
||||
PatchSize: Integer): Integer;
|
||||
begin
|
||||
Result := EncodePatch(OldBuff, OldSize, NewBuff, NewSize, PatchBuff,
|
||||
PatchSize);
|
||||
end;
|
||||
|
||||
function PrecompEncodePatchEx(Instance: Integer; OldBuff: Pointer;
|
||||
OldSize: Integer; NewBuff: Pointer; NewSize: Integer;
|
||||
Output: _PrecompOutput): Integer;
|
||||
|
||||
function highbit64(V: UInt64): Cardinal;
|
||||
var
|
||||
Count: Cardinal;
|
||||
begin
|
||||
Count := 0;
|
||||
Assert(V <> 0);
|
||||
V := V shr 1;
|
||||
while V <> 0 do
|
||||
begin
|
||||
V := V shr 1;
|
||||
Inc(Count);
|
||||
end;
|
||||
Result := Count;
|
||||
end;
|
||||
|
||||
var
|
||||
Res: NativeUInt;
|
||||
Buffer: array [0 .. $40000 - 1] of Byte;
|
||||
BufferSize: Integer;
|
||||
Ctx: ZSTD_CCtx;
|
||||
Inp: ZSTDLib.ZSTD_inBuffer;
|
||||
Oup: ZSTDLib.ZSTD_outBuffer;
|
||||
Res: NativeInt;
|
||||
|
||||
procedure DoWrite;
|
||||
begin
|
||||
Output(Instance, @Buffer[0], Oup.Pos);
|
||||
Inc(Result, Oup.Pos);
|
||||
Oup.dst := @Buffer[0];
|
||||
Oup.Size := BufferSize;
|
||||
Oup.Pos := 0;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := 0;
|
||||
if not XDeltaDLL.DLLLoaded then
|
||||
exit;
|
||||
if xd3_encode(OldBuff, OldSize, NewBuff, NewSize, PatchBuff, @Res, PatchSize,
|
||||
Integer(XD3_NOCOMPRESS)) = 0 then
|
||||
Result := Res;
|
||||
// MakeDiff(OldBuff, NewBuff, PatchBuff, OldSize, NewSize, Result);
|
||||
BufferSize := Min(ZSTDLib.ZSTD_CStreamOutSize, Length(Buffer));
|
||||
Ctx := _PrecompVar[Instance].ZSTDCtx1;
|
||||
Oup.dst := @Buffer[0];
|
||||
Oup.Size := BufferSize;
|
||||
Oup.Pos := 0;
|
||||
Inp.src := OldBuff;
|
||||
Inp.Size := OldSize;
|
||||
Inp.Pos := 0;
|
||||
ZSTDLib.ZSTD_initCStream(Ctx, DIFF_CLEVEL);
|
||||
ZSTDLib.ZSTD_CCtx_setParameter(Ctx, ZSTDLib.ZSTD_cParameter.ZSTD_c_windowLog,
|
||||
highbit64(NewSize) + 1);
|
||||
ZSTDLib.ZSTD_CCtx_setParameter(Ctx,
|
||||
ZSTDLib.ZSTD_cParameter.ZSTD_c_enableLongDistanceMatching, 1);
|
||||
ZSTDLib.ZSTD_CCtx_refPrefix(Ctx, NewBuff, NewSize);
|
||||
while Inp.Pos < Inp.Size do
|
||||
begin
|
||||
Res := ZSTDLib.ZSTD_compressStream(Ctx, Oup, Inp);
|
||||
if Res < 0 then
|
||||
exit(0)
|
||||
else if Res > 0 then
|
||||
DoWrite
|
||||
else
|
||||
break;
|
||||
end;
|
||||
ZSTDLib.ZSTD_flushStream(Ctx, Oup);
|
||||
DoWrite;
|
||||
ZSTDLib.ZSTD_endStream(Ctx, Oup);
|
||||
DoWrite;
|
||||
end;
|
||||
|
||||
function PrecompDecodePatch(PatchBuff: Pointer; PatchSize: Integer;
|
||||
OldBuff: Pointer; OldSize: Integer; NewBuff: Pointer;
|
||||
NewSize: Integer): Integer;
|
||||
begin
|
||||
Result := DecodePatch(PatchBuff, PatchSize, OldBuff, OldSize,
|
||||
NewBuff, NewSize);
|
||||
end;
|
||||
|
||||
function PrecompDecodePatchEx(Instance: Integer; PatchBuff: Pointer;
|
||||
PatchSize: Integer; OldBuff: Pointer; OldSize: Integer;
|
||||
Output: _PrecompOutput): Integer;
|
||||
|
||||
function highbit64(V: UInt64): Cardinal;
|
||||
var
|
||||
Count: Cardinal;
|
||||
begin
|
||||
Count := 0;
|
||||
Assert(V <> 0);
|
||||
V := V shr 1;
|
||||
while V <> 0 do
|
||||
begin
|
||||
V := V shr 1;
|
||||
Inc(Count);
|
||||
end;
|
||||
Result := Count;
|
||||
end;
|
||||
|
||||
var
|
||||
Res: NativeUInt;
|
||||
Buffer: array [0 .. $40000 - 1] of Byte;
|
||||
BufferSize: Integer;
|
||||
Ctx: ZSTD_DCtx;
|
||||
Inp: ZSTDLib.ZSTD_inBuffer;
|
||||
Oup: ZSTDLib.ZSTD_outBuffer;
|
||||
Res: NativeInt;
|
||||
|
||||
procedure DoWrite;
|
||||
begin
|
||||
Output(Instance, @Buffer[0], Oup.Pos);
|
||||
Inc(Result, Oup.Pos);
|
||||
Oup.dst := @Buffer[0];
|
||||
Oup.Size := BufferSize;
|
||||
Oup.Pos := 0;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := 0;
|
||||
if not XDeltaDLL.DLLLoaded then
|
||||
exit;
|
||||
if xd3_decode(PatchBuff, PatchSize, OldBuff, OldSize, NewBuff, @Res, NewSize,
|
||||
Integer(XD3_NOCOMPRESS)) = 0 then
|
||||
Result := Res;
|
||||
// MakePatch(OldBuff, PatchBuff, NewBuff, OldSize, PatchSize, Result);
|
||||
BufferSize := Min(ZSTDLib.ZSTD_DStreamOutSize, Length(Buffer));
|
||||
Ctx := _PrecompVar[Instance].ZSTDCtx2;
|
||||
Oup.dst := @Buffer[0];
|
||||
Oup.Size := BufferSize;
|
||||
Oup.Pos := 0;
|
||||
Inp.src := PatchBuff;
|
||||
Inp.Size := PatchSize;
|
||||
Inp.Pos := 0;
|
||||
ZSTDLib.ZSTD_DCtx_setParameter(Ctx,
|
||||
ZSTDLib.ZSTD_dParameter.ZSTD_d_windowLogMax, highbit64(OldSize) + 1);
|
||||
ZSTDLib.ZSTD_DCtx_refPrefix(Ctx, OldBuff, OldSize);
|
||||
while Inp.Pos < Inp.Size do
|
||||
begin
|
||||
Res := ZSTDLib.ZSTD_decompressStream(Ctx, Oup, Inp);
|
||||
if Res < 0 then
|
||||
exit(0)
|
||||
else if Res >= 0 then
|
||||
begin
|
||||
DoWrite;
|
||||
if Res = 0 then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function PrecompAddResource(FileName: PChar): Integer;
|
||||
@@ -951,8 +1193,8 @@ begin
|
||||
end;
|
||||
if not Exists then
|
||||
begin
|
||||
with TFileStream.Create(PluginsPath + FileName, fmOpenRead or
|
||||
fmShareDenyNone) do
|
||||
with TFileStream.Create(ExpandPath(PluginsPath + FileName, True),
|
||||
fmOpenRead or fmShareDenyNone) do
|
||||
try
|
||||
I := Length(Resources);
|
||||
SetLength(Resources, Succ(I));
|
||||
@@ -1287,13 +1529,93 @@ begin
|
||||
Result := PatchSize <= DIFF_TOLERANCE;
|
||||
end;
|
||||
|
||||
function DummyInit(Command: PChar; Count: Integer;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure DummyFree(Funcs: PPrecompFuncs);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function DummyParse(Command: PChar; Option: PInteger;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
var
|
||||
S: String;
|
||||
I: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, DummyCodecs[NONE_CODEC]) = 0) then
|
||||
begin
|
||||
SetBits(Option^, NONE_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DummyScan1(Instance, Depth: Integer; Input: PByte;
|
||||
Size, SizeEx: NativeInt; Output: _PrecompOutput; Add: _PrecompAdd;
|
||||
Funcs: PPrecompFuncs);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function DummyScan2(Instance, Depth: Integer; Input: Pointer; Size: Cardinal;
|
||||
StreamInfo: PStrInfo2; Offset: PInteger; Output: _PrecompOutput;
|
||||
Funcs: PPrecompFuncs): Boolean;
|
||||
begin
|
||||
Result := StreamInfo^.OldSize > 0;
|
||||
StreamInfo^.NewSize := StreamInfo^.OldSize;
|
||||
if Result then
|
||||
Output(Instance, Input, StreamInfo^.OldSize);
|
||||
Funcs^.LogScan2(DummyCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, -1);
|
||||
end;
|
||||
|
||||
function DummyProcess(Instance, Depth: Integer; OldInput, NewInput: Pointer;
|
||||
StreamInfo: PStrInfo2; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
begin
|
||||
Result := StreamInfo.OldSize > 0;
|
||||
end;
|
||||
|
||||
function DummyRestore(Instance, Depth: Integer; Input, InputExt: Pointer;
|
||||
StreamInfo: _StrInfo3; Output: _PrecompOutput; Funcs: PPrecompFuncs): Boolean;
|
||||
begin
|
||||
Output(Instance, Input, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
var
|
||||
I: Integer;
|
||||
|
||||
initialization
|
||||
|
||||
EncodeSICmp := TEncodeSIComparer.Create;
|
||||
FutureSICmp := TFutureSIComparer.Create;
|
||||
StockMethods := TStringList.Create;
|
||||
ExternalMethods := TStringList.Create;
|
||||
if not XDeltaDLL.DLLLoaded then
|
||||
DIFF_TOLERANCE := 0;
|
||||
|
||||
Codec.Names := [];
|
||||
for I := Low(DummyCodecs) to High(DummyCodecs) do
|
||||
begin
|
||||
Codec.Names := Codec.Names + [DummyCodecs[I]];
|
||||
StockMethods.Add(DummyCodecs[I]);
|
||||
end;
|
||||
Codec.Initialised := False;
|
||||
Codec.Init := @DummyInit;
|
||||
Codec.Free := @DummyFree;
|
||||
Codec.Parse := @DummyParse;
|
||||
Codec.Scan1 := @DummyScan1;
|
||||
Codec.Scan2 := @DummyScan2;
|
||||
Codec.Process := @DummyProcess;
|
||||
Codec.Restore := @DummyRestore;
|
||||
|
||||
end.
|
||||
|
@@ -62,11 +62,7 @@ var
|
||||
LStr: TPNGStruct;
|
||||
CRC: Cardinal;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
Result := 0;
|
||||
if Pos + 16 < Size then
|
||||
begin
|
||||
@@ -124,16 +120,12 @@ begin
|
||||
SI.NewSize := CurPos;
|
||||
SI.Status := TStreamStatus.None;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, PNG_CODEC, 0, 5);
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
SetBits(SI.Option, PNG_CODEC, 0, 3);
|
||||
if Assigned(Add) then
|
||||
begin
|
||||
Funcs^.LogScan1(ZlibCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(ZlibCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -322,7 +314,19 @@ begin
|
||||
Insert(I, Options, Length(Options));
|
||||
end;
|
||||
if SOList[X, Y].Count = 0 then
|
||||
begin
|
||||
SOList[X, Y].Update(Options);
|
||||
case Y of
|
||||
ZLIB_CODEC:
|
||||
begin
|
||||
SOList[X, Y].Add(99);
|
||||
SOList[X, Y].Add(18);
|
||||
SOList[X, Y].Add(58);
|
||||
SOList[X, Y].Add(68);
|
||||
SOList[X, Y].Add(98);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
@@ -372,38 +376,38 @@ var
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
SetBits(Option^, ZWinBits, 12, 3);
|
||||
SetBits(Option^, ZWinBits, 10, 3);
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, ZlibCodecs[ZLIB_CODEC]) = 0) and ZLibDLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, ZLIB_CODEC, 0, 5);
|
||||
SetBits(Option^, ZLIB_CODEC, 0, 3);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 7);
|
||||
if Funcs^.GetParam(Command, I, 'w') <> '' then
|
||||
SetBits(Option^, EnsureRange(StrToInt(Funcs^.GetParam(Command, I, 'w'))
|
||||
- 8, 1, 7), 12, 3);
|
||||
- 8, 1, 7), 10, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, ZlibCodecs[REFLATE_CODEC]) = 0) and ReflateDLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, REFLATE_CODEC, 0, 5);
|
||||
SetBits(Option^, REFLATE_CODEC, 0, 3);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 7);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, ZlibCodecs[PREFLATE_CODEC]) = 0) and PreflateDLL.DLLLoaded
|
||||
then
|
||||
begin
|
||||
SetBits(Option^, PREFLATE_CODEC, 0, 5);
|
||||
SetBits(Option^, PREFLATE_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end
|
||||
else if (CompareText(S, ZlibCodecs[PNG_CODEC]) = 0) then
|
||||
begin
|
||||
SetBits(Option^, PNG_CODEC, 0, 5);
|
||||
SetBits(Option^, PNG_CODEC, 0, 3);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -418,29 +422,16 @@ var
|
||||
Pos: NativeInt;
|
||||
Res: Integer;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
|
||||
ZStream: z_streamp;
|
||||
IsZlib: Boolean;
|
||||
Level: Integer;
|
||||
WinBits: Byte;
|
||||
ScanBytes: Integer;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
LastIn, LastOut: Cardinal;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
X := -1;
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], ZlibCodecs);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
end
|
||||
else if BoolArray(CodecEnabled, False) then
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
if Assigned(Add) then
|
||||
exit;
|
||||
for I := Low(ZStream2[Instance]) to High(ZStream2[Instance]) do
|
||||
@@ -553,38 +544,34 @@ begin
|
||||
begin
|
||||
case Level of
|
||||
0:
|
||||
SetBits(SI.Option, 1, 5, 7);
|
||||
SetBits(SI.Option, 1, 3, 7);
|
||||
1:
|
||||
SetBits(SI.Option, 5, 5, 7);
|
||||
SetBits(SI.Option, 5, 3, 7);
|
||||
2:
|
||||
SetBits(SI.Option, 6, 5, 7);
|
||||
SetBits(SI.Option, 6, 3, 7);
|
||||
3:
|
||||
SetBits(SI.Option, 9, 5, 7);
|
||||
SetBits(SI.Option, 9, 3, 7);
|
||||
end;
|
||||
SI.Status := TStreamStatus.Predicted;
|
||||
end
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
SetBits(SI.Option, WinBits, 12, 3);
|
||||
SetBits(SI.Option, WinBits, 10, 3);
|
||||
if not((Input + Pos)^ and 7 in [$4, $5]) then
|
||||
SetBits(SI.Option, 1, 15, 1);
|
||||
SetBits(SI.Option, 1, 13, 1);
|
||||
for I := Low(CodecEnabled) to High(CodecEnabled) do
|
||||
begin
|
||||
if (I = ZLIB_CODEC) and (WinBits = 0) then
|
||||
SetBits(SI.Option, 1, 12, 3);
|
||||
SetBits(SI.Option, I, 0, 5);
|
||||
if CodecEnabled[I] or (I = X) or
|
||||
SetBits(SI.Option, 1, 10, 3);
|
||||
SetBits(SI.Option, I, 0, 3);
|
||||
if CodecEnabled[I] or
|
||||
(CodecAvailable[I] and not Assigned(Add)) then
|
||||
begin
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
if Assigned(Add) then
|
||||
begin
|
||||
Funcs^.LogScan1(ZlibCodecs[GetBits(SI.Option, 0, 5)],
|
||||
Funcs^.LogScan1(ZlibCodecs[GetBits(SI.Option, 0, 3)],
|
||||
SI.Position, SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -629,7 +616,7 @@ begin
|
||||
if Result then
|
||||
begin
|
||||
Offset^ := Scan2Pos[Instance];
|
||||
Funcs^.LogScan2(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
end;
|
||||
end;
|
||||
@@ -663,7 +650,7 @@ var
|
||||
CRC: Cardinal;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if not X in [PNG_CODEC] then
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
@@ -679,26 +666,26 @@ begin
|
||||
M := I mod 10;
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if InRange(GetBits(StreamInfo^.Option, 5, 7), 1, 9) then
|
||||
if InRange(GetBits(StreamInfo^.Option, 3, 7), 1, 9) then
|
||||
begin
|
||||
if not IsValidLevel(L, GetBits(StreamInfo^.Option, 5, 7)) then
|
||||
if not IsValidLevel(L, GetBits(StreamInfo^.Option, 3, 7)) then
|
||||
continue;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 5, 7) <> I then
|
||||
if GetBits(StreamInfo^.Option, 3, 7) <> I then
|
||||
continue;
|
||||
if StreamInfo^.Status = TStreamStatus.Database then
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
Params := 'l' + I.ToString + ':' + 'w' +
|
||||
(GetBits(StreamInfo^.Option, 12, 3) + 8).ToString;
|
||||
(GetBits(StreamInfo^.Option, 10, 3) + 8).ToString;
|
||||
ZStream := @ZStream1[Instance, L, M,
|
||||
GetBits(StreamInfo^.Option, 12, 3)];
|
||||
GetBits(StreamInfo^.Option, 10, 3)];
|
||||
if not Assigned(ZStream^.zalloc) then
|
||||
deflateInit2(ZStream^, L, Z_DEFLATED,
|
||||
-(GetBits(StreamInfo^.Option, 12, 3) + 8), M, Z_DEFAULT_STRATEGY);
|
||||
-(GetBits(StreamInfo^.Option, 10, 3) + 8), M, Z_DEFAULT_STRATEGY);
|
||||
if not Result then
|
||||
begin
|
||||
ZStream^.next_in := NewInput;
|
||||
@@ -720,13 +707,13 @@ begin
|
||||
end
|
||||
else
|
||||
ZStream.total_out := StreamInfo^.OldSize;
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize,
|
||||
ZStream^.total_out, (Result = True) or
|
||||
(Verified and (Res1 = Z_STREAM_END)));
|
||||
if (Result = True) or (Verified and (Res1 = Z_STREAM_END)) then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 5, 7);
|
||||
SetBits(StreamInfo^.Option, I, 3, 7);
|
||||
SOList[Instance][ZLIB_CODEC].Add(I);
|
||||
Result := True;
|
||||
break;
|
||||
@@ -737,9 +724,9 @@ begin
|
||||
if CodecEnabled[REFLATE_CODEC] or CodecEnabled[PREFLATE_CODEC] then
|
||||
begin
|
||||
if CodecEnabled[REFLATE_CODEC] then
|
||||
SetBits(StreamInfo^.Option, REFLATE_CODEC, 0, 5)
|
||||
SetBits(StreamInfo^.Option, REFLATE_CODEC, 0, 3)
|
||||
else if CodecEnabled[PREFLATE_CODEC] then
|
||||
SetBits(StreamInfo^.Option, PREFLATE_CODEC, 0, 5);
|
||||
SetBits(StreamInfo^.Option, PREFLATE_CODEC, 0, 3);
|
||||
Result := ZlibProcess(Instance, Depth, OldInput, NewInput,
|
||||
StreamInfo, Output, Funcs);
|
||||
end;
|
||||
@@ -753,7 +740,7 @@ begin
|
||||
RefInst1[Instance] := raw2hif_Alloc;
|
||||
HR := RefInst1[Instance];
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
L := GetBits(StreamInfo^.Option, 5, 7)
|
||||
L := GetBits(StreamInfo^.Option, 3, 7)
|
||||
else
|
||||
L := RLevel;
|
||||
if L > 9 then
|
||||
@@ -788,12 +775,12 @@ begin
|
||||
Inc(I, Res2);
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize + J,
|
||||
StreamInfo^.OldSize, M = StreamInfo^.NewSize);
|
||||
if M = StreamInfo^.NewSize then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 15, 1) = 1 then
|
||||
if GetBits(StreamInfo^.Option, 13, 1) = 1 then
|
||||
begin
|
||||
if not Assigned(RefInst2[Instance]) then
|
||||
RefInst2[Instance] := hif2raw_Alloc;
|
||||
@@ -830,10 +817,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (GetBits(StreamInfo^.Option, 15, 1) = 0) or
|
||||
if (GetBits(StreamInfo^.Option, 13, 1) = 0) or
|
||||
(CRC = Hash32(0, OldInput, StreamInfo^.OldSize)) then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, L, 5, 7);
|
||||
SetBits(StreamInfo^.Option, L, 3, 7);
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
@@ -850,7 +837,7 @@ begin
|
||||
Output(Instance, Buffer, Res2);
|
||||
Result := True;
|
||||
end;
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize + Res2,
|
||||
StreamInfo^.OldSize, Result);
|
||||
end;
|
||||
@@ -859,7 +846,7 @@ begin
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo^.OldSize);
|
||||
if DecodePNG(NewInput, Buffer, StreamInfo^.OldSize) then
|
||||
Result := CompareMem(OldInput, Buffer, StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(ZlibCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize,
|
||||
StreamInfo^.OldSize, Result);
|
||||
end;
|
||||
@@ -879,7 +866,7 @@ var
|
||||
HR: Pointer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if not X in [PNG_CODEC] then
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
@@ -888,14 +875,14 @@ begin
|
||||
ZLIB_CODEC:
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Z_WORKMEM);
|
||||
L := GetBits(StreamInfo.Option, 5, 7) div 10;
|
||||
M := GetBits(StreamInfo.Option, 5, 7) mod 10;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString + ':' + 'w' +
|
||||
(GetBits(StreamInfo.Option, 12, 3) + 8).ToString;
|
||||
ZStream := @ZStream1[Instance, L, M, GetBits(StreamInfo.Option, 12, 3)];
|
||||
L := GetBits(StreamInfo.Option, 3, 7) div 10;
|
||||
M := GetBits(StreamInfo.Option, 3, 7) mod 10;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 7).ToString + ':' + 'w' +
|
||||
(GetBits(StreamInfo.Option, 10, 3) + 8).ToString;
|
||||
ZStream := @ZStream1[Instance, L, M, GetBits(StreamInfo.Option, 10, 3)];
|
||||
if not Assigned(ZStream^.zalloc) then
|
||||
deflateInit2(ZStream^, L, Z_DEFLATED,
|
||||
-(GetBits(StreamInfo.Option, 12, 3) + 8), M, Z_DEFAULT_STRATEGY);
|
||||
-(GetBits(StreamInfo.Option, 10, 3) + 8), M, Z_DEFAULT_STRATEGY);
|
||||
ZStream^.next_in := Input;
|
||||
ZStream^.avail_in := StreamInfo.NewSize;
|
||||
deflateReset(ZStream^);
|
||||
@@ -909,7 +896,7 @@ begin
|
||||
Res2 := Z_WORKMEM - ZStream^.avail_out;
|
||||
Output(Instance, Buffer, Res2);
|
||||
until (ZStream^.avail_in = 0) and (ZStream^.avail_out > 0);
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize,
|
||||
ZStream^.total_out, True);
|
||||
Result := True;
|
||||
@@ -923,8 +910,8 @@ begin
|
||||
I := 0;
|
||||
J := 0;
|
||||
M := 0;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString;
|
||||
hif2raw_Init(HR, GetBits(StreamInfo.Option, 5, 7));
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 7).ToString;
|
||||
hif2raw_Init(HR, GetBits(StreamInfo.Option, 3, 7));
|
||||
while True do
|
||||
begin
|
||||
Res1 := hif2raw_Loop(HR);
|
||||
@@ -951,7 +938,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
Result := StreamInfo.OldSize = M;
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize + J, M, Result);
|
||||
end;
|
||||
PREFLATE_CODEC:
|
||||
@@ -965,7 +952,7 @@ begin
|
||||
Output(Instance, Buffer, Res1);
|
||||
Result := True;
|
||||
end;
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize +
|
||||
StreamInfo.ExtSize, Res1, Result);
|
||||
end;
|
||||
@@ -977,7 +964,7 @@ begin
|
||||
Output(Instance, Buffer, StreamInfo.OldSize);
|
||||
Result := True;
|
||||
end;
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 5)],
|
||||
Funcs^.LogRestore(ZlibCodecs[GetBits(StreamInfo.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo.OldSize, StreamInfo.NewSize,
|
||||
StreamInfo.OldSize, Result);
|
||||
end;
|
||||
|
@@ -20,14 +20,19 @@ const
|
||||
|
||||
const
|
||||
Z_MAXSIZE = 16 * 1024 * 1024;
|
||||
Z_FASTMODE = 0;
|
||||
Z_WINDOWLOG = 0;
|
||||
Z_BLOCKSIZE = 0;
|
||||
|
||||
var
|
||||
SOList: array of array [0 .. CODEC_COUNT - 1] of TSOList;
|
||||
cctx, dctx: array of Pointer;
|
||||
// cdict, ddict: Pointer;
|
||||
DStream: TMemoryStream;
|
||||
CodecAvailable, CodecEnabled: TArray<Boolean>;
|
||||
ZMaxSize: Integer = Z_MAXSIZE;
|
||||
ZFastMode: Integer = Z_FASTMODE;
|
||||
ZWindowLog: Integer = Z_WINDOWLOG;
|
||||
ZBlockSize: Integer = Z_BLOCKSIZE;
|
||||
|
||||
function ZSTDInit(Command: PChar; Count: Integer; Funcs: PPrecompFuncs)
|
||||
: Boolean;
|
||||
@@ -62,6 +67,12 @@ begin
|
||||
([StrToInt(Funcs^.GetParam(Command, X, 'l'))], True);
|
||||
if Funcs^.GetParam(Command, X, 's') <> '' then
|
||||
ZMaxSize := ConvertToBytes(Funcs^.GetParam(Command, X, 's'));
|
||||
if Funcs^.GetParam(Command, X, 'f') <> '' then
|
||||
ZFastMode := ConvertToBytes(Funcs^.GetParam(Command, X, 'f'));
|
||||
if Funcs^.GetParam(Command, X, 'w') <> '' then
|
||||
ZWindowLog := ConvertToBytes(Funcs^.GetParam(Command, X, 'w'));
|
||||
if Funcs^.GetParam(Command, X, 'b') <> '' then
|
||||
ZBlockSize := StrToInt(Funcs^.GetParam(Command, X, 'b'));
|
||||
end;
|
||||
Inc(X);
|
||||
end;
|
||||
@@ -111,15 +122,24 @@ var
|
||||
begin
|
||||
Result := False;
|
||||
Option^ := 0;
|
||||
SetBits(Option^, ZFastMode, 8, 1);
|
||||
SetBits(Option^, ZWindowLog, 9, 5);
|
||||
SetBits(Option^, ZBlockSize, 14, 13);
|
||||
I := 0;
|
||||
while Funcs^.GetCodec(Command, I, False) <> '' do
|
||||
begin
|
||||
S := Funcs^.GetCodec(Command, I, False);
|
||||
if (CompareText(S, ZSTDCodecs[ZSTD_CODEC]) = 0) and ZSTDDLL.DLLLoaded then
|
||||
begin
|
||||
SetBits(Option^, ZSTD_CODEC, 0, 5);
|
||||
SetBits(Option^, ZSTD_CODEC, 0, 3);
|
||||
if Funcs^.GetParam(Command, I, 'l') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 5, 7);
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'l')), 3, 5);
|
||||
if String(Funcs^.GetParam(Command, I, 'f')) = '1' then
|
||||
SetBits(Option^, 1, 8, 1);
|
||||
if Funcs^.GetParam(Command, I, 'w') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'w')), 9, 5);
|
||||
if Funcs^.GetParam(Command, I, 'b') <> '' then
|
||||
SetBits(Option^, StrToInt(Funcs^.GetParam(Command, I, 'b')), 14, 13);
|
||||
Result := True;
|
||||
end;
|
||||
Inc(I);
|
||||
@@ -134,52 +154,7 @@ var
|
||||
Pos: NativeInt;
|
||||
X, Y, Z: Integer;
|
||||
SI: _StrInfo1;
|
||||
DI1, DI2: TDepthInfo;
|
||||
DS: TPrecompStr;
|
||||
begin
|
||||
DI1 := Funcs^.GetDepthInfo(Instance);
|
||||
DS := Funcs^.GetCodec(DI1.Codec, 0, False);
|
||||
if DS <> '' then
|
||||
begin
|
||||
X := IndexTextW(@DS[0], ZSTDCodecs);
|
||||
if (X < 0) or (DI1.OldSize <> SizeEx) then
|
||||
exit;
|
||||
if not CodecAvailable[X] then
|
||||
exit;
|
||||
Y := ZSTD_findDecompressedSize(Input, SizeEx);
|
||||
if Y <= 0 then
|
||||
Y := ZMaxSize;
|
||||
Buffer := Funcs^.Allocator(Instance, Y);
|
||||
case X of
|
||||
ZSTD_CODEC:
|
||||
begin
|
||||
if not Assigned(dctx[Instance]) then
|
||||
dctx[Instance] := ZSTD_createDCtx;
|
||||
Y := ZSTD_decompressDCtx(dctx[Instance], Buffer, Y, Input, X);
|
||||
end;
|
||||
end;
|
||||
if (Y > DI1.OldSize) then
|
||||
begin
|
||||
Output(Instance, Buffer, Y);
|
||||
SI.Position := 0;
|
||||
SI.OldSize := DI1.OldSize;
|
||||
SI.NewSize := Y;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, X, 0, 5);
|
||||
if System.Pos(SPrecompSep2, DI1.Codec) > 0 then
|
||||
SI.Status := TStreamStatus.Predicted
|
||||
else
|
||||
SI.Status := TStreamStatus.None;
|
||||
DS := Funcs^.GetDepthCodec(DI1.Codec);
|
||||
Move(DS[0], DI2.Codec, SizeOf(DI2.Codec));
|
||||
DI2.OldSize := SI.NewSize;
|
||||
DI2.NewSize := SI.NewSize;
|
||||
Funcs^.LogScan1(ZSTDCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, DI1.Codec, @DI2);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if BoolArray(CodecEnabled, False) then
|
||||
exit;
|
||||
Pos := 0;
|
||||
@@ -205,8 +180,11 @@ begin
|
||||
SI.OldSize := X;
|
||||
SI.NewSize := Y;
|
||||
SI.Option := 0;
|
||||
SetBits(SI.Option, ZFastMode, 8, 1);
|
||||
SetBits(SI.Option, ZWindowLog, 9, 5);
|
||||
SetBits(SI.Option, ZBlockSize, 14, 13);
|
||||
SI.Status := TStreamStatus.None;
|
||||
Funcs^.LogScan1(ZSTDCodecs[GetBits(SI.Option, 0, 5)], SI.Position,
|
||||
Funcs^.LogScan1(ZSTDCodecs[GetBits(SI.Option, 0, 3)], SI.Position,
|
||||
SI.OldSize, SI.NewSize);
|
||||
Add(Instance, @SI, nil, nil);
|
||||
Inc(Pos, SI.OldSize);
|
||||
@@ -227,7 +205,15 @@ var
|
||||
Res: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if (StreamInfo^.OldSize > 0) and REPROCESSED then
|
||||
if (Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^)
|
||||
.Lo = StreamInfo^.OldSize) and
|
||||
(Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Lo <
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi)
|
||||
then
|
||||
StreamInfo^.OldSize :=
|
||||
Int64Rec(PInt64(PByte(Input) + StreamInfo^.OldSize - Int64.Size)^).Hi;
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
StreamInfo^.OldSize := ZSTD_findFrameCompressedSize(Input, Size);
|
||||
if StreamInfo^.OldSize <= 0 then
|
||||
@@ -250,7 +236,7 @@ begin
|
||||
begin
|
||||
Output(Instance, Buffer, Res);
|
||||
StreamInfo^.NewSize := Res;
|
||||
Funcs^.LogScan2(ZSTDCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogScan2(ZSTDCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
StreamInfo^.OldSize, StreamInfo^.NewSize);
|
||||
Result := True;
|
||||
end;
|
||||
@@ -264,14 +250,14 @@ var
|
||||
A, B: Integer;
|
||||
I: Integer;
|
||||
X: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
Inp: ZSTD_inBuffer;
|
||||
Oup: ZSTD_outBuffer;
|
||||
Progress: NativeInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo^.Option, 0, 5);
|
||||
X := GetBits(StreamInfo^.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo^.NewSize);
|
||||
@@ -280,7 +266,7 @@ begin
|
||||
begin
|
||||
if StreamInfo^.Status >= TStreamStatus.Predicted then
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 5, 7) <> I then
|
||||
if GetBits(StreamInfo^.Option, 3, 5) <> I then
|
||||
continue;
|
||||
if (StreamInfo^.Status = TStreamStatus.Database) and
|
||||
(GetBits(StreamInfo^.Option, 31, 1) = 0) then
|
||||
@@ -293,53 +279,79 @@ begin
|
||||
case X of
|
||||
ZSTD_CODEC:
|
||||
begin
|
||||
Params := 'l' + I.ToString;
|
||||
{ ZSTD_CCtx_reset(cctx[Instance], ZSTD_reset_session_and_parameters);
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_strategy, 5);
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_compressionLevel, I); }
|
||||
Params := 'l' + I.ToString + ':' + 'f' + GetBits(StreamInfo^.Option,
|
||||
8, 1).ToString + ':' + 'w' + GetBits(StreamInfo^.Option, 9, 5)
|
||||
.ToString + ':' + 'b' + GetBits(StreamInfo^.Option, 14, 13)
|
||||
.ToString;
|
||||
if not Assigned(cctx[Instance]) then
|
||||
cctx[Instance] := ZSTD_createCCtx;
|
||||
if not Result then
|
||||
Res1 := ZSTD_compressCCtx(cctx[Instance], Buffer,
|
||||
StreamInfo^.NewSize, NewInput, StreamInfo^.NewSize, I);
|
||||
begin
|
||||
if GetBits(StreamInfo^.Option, 14, 13) = 0 then
|
||||
begin
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_compressionLevel,
|
||||
IfThen(GetBits(StreamInfo^.Option, 8, 1) = 0, I, -I));
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_windowLog,
|
||||
GetBits(StreamInfo^.Option, 9, 5));
|
||||
if Assigned(ZSTD_compress2) then
|
||||
Res1 := ZSTD_compress2(cctx[Instance], Buffer,
|
||||
StreamInfo^.NewSize, NewInput, StreamInfo^.NewSize)
|
||||
else if Assigned(ZSTD_compress_generic) then
|
||||
begin
|
||||
Oup.dst := Buffer;
|
||||
Oup.Size := StreamInfo^.NewSize;
|
||||
Oup.Pos := 0;
|
||||
Inp.src := PByte(NewInput);
|
||||
Inp.Size := StreamInfo^.NewSize;
|
||||
Inp.Pos := 0;
|
||||
ZSTD_compress_generic(cctx[Instance], @Oup, @Inp, ZSTD_e_end);
|
||||
Res1 := Oup.Pos;
|
||||
end
|
||||
else
|
||||
Res1 := ZSTD_compressCCtx(cctx[Instance], Buffer,
|
||||
StreamInfo^.NewSize, NewInput, StreamInfo^.NewSize,
|
||||
IfThen(GetBits(StreamInfo^.Option, 8, 1) = 0, I, -I))
|
||||
end
|
||||
else
|
||||
begin
|
||||
Progress := 0;
|
||||
Oup.dst := Buffer;
|
||||
Oup.Size := StreamInfo^.NewSize;
|
||||
Oup.Pos := 0;
|
||||
ZSTD_initCStream(cctx[Instance],
|
||||
IfThen(GetBits(StreamInfo^.Option, 8, 1) = 0, I, -I));
|
||||
while Progress < StreamInfo^.NewSize do
|
||||
begin
|
||||
Inp.src := PByte(NewInput) + Progress;
|
||||
Inp.Size := Min(StreamInfo^.NewSize - Progress,
|
||||
GetBits(StreamInfo^.Option, 14, 13) * 1024);
|
||||
Inp.Pos := 0;
|
||||
if ZSTD_compressStream(cctx[Instance], @Oup, @Inp) > 0 then
|
||||
begin
|
||||
ZSTD_flushStream(cctx[Instance], @Oup);
|
||||
Inc(Progress, Inp.Size)
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
ZSTD_endStream(cctx[Instance], @Oup);
|
||||
Res1 := Oup.Pos;
|
||||
end;
|
||||
{ Res1 := ZSTD_compress_usingCDict(cctx[Instance], Buffer,
|
||||
StreamInfo^.NewSize, NewInput, StreamInfo^.NewSize, cdict); }
|
||||
end;
|
||||
end;
|
||||
{ Res1 := ZSTD_compress_usingCDict(cctx[Instance], Buffer,
|
||||
StreamInfo^.NewSize, NewInput, StreamInfo^.NewSize, cdict); }
|
||||
{ begin
|
||||
Params := 'l' + I.ToString;
|
||||
Progress := 0;
|
||||
Oup.dst := Buffer;
|
||||
Oup.Size := StreamInfo^.NewSize;
|
||||
Oup.Pos := 0;
|
||||
ZSTD_initCStream(cctx[Instance], I);
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_strategy, 9);
|
||||
while Progress < StreamInfo^.NewSize do
|
||||
begin
|
||||
Inp.src := PByte(NewInput) + Progress;
|
||||
Inp.Size := Min(StreamInfo^.NewSize - Progress, 64 * 1024);
|
||||
Inp.Pos := 0;
|
||||
if ZSTD_compressStream(cctx[Instance], @Oup, @Inp) > 0 then
|
||||
begin
|
||||
ZSTD_flushStream(cctx[Instance], @Oup);
|
||||
Inc(Progress, Inp.Size)
|
||||
end
|
||||
else
|
||||
exit;
|
||||
end;
|
||||
ZSTD_endStream(cctx[Instance], @Oup);
|
||||
Res1 := Oup.Pos;
|
||||
end; }
|
||||
end;
|
||||
if not Result then
|
||||
Result := (Res1 = StreamInfo^.OldSize) and CompareMem(OldInput, Buffer,
|
||||
StreamInfo^.OldSize);
|
||||
Funcs^.LogProcess(ZSTDCodecs[GetBits(StreamInfo^.Option, 0, 5)],
|
||||
Funcs^.LogProcess(ZSTDCodecs[GetBits(StreamInfo^.Option, 0, 3)],
|
||||
PChar(Params), StreamInfo^.OldSize, StreamInfo^.NewSize, Res1, Result);
|
||||
if Result or (StreamInfo^.Status >= TStreamStatus.Predicted) then
|
||||
break;
|
||||
end;
|
||||
if Result and OPTIMISE_DEC and (StreamInfo^.Status <> TStreamStatus.Database)
|
||||
then
|
||||
and (GetBits(StreamInfo^.Option, 8, 1) = 0) then
|
||||
begin
|
||||
A := Pred(I);
|
||||
for B := A downto 1 do
|
||||
@@ -358,14 +370,12 @@ begin
|
||||
else if (Result = False) and ((StreamInfo^.Status >= TStreamStatus.Predicted)
|
||||
or (SOList[Instance][X].Count = 1)) and (DIFF_TOLERANCE > 0) then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatch(OldInput, StreamInfo^.OldSize, Buffer, Res1,
|
||||
Buffer + Res1, Max(StreamInfo^.OldSize, Res1));
|
||||
Res2 := PrecompEncodePatchEx(Instance, OldInput, StreamInfo^.OldSize,
|
||||
Buffer, Res1, Output);
|
||||
Funcs^.LogPatch1(StreamInfo^.OldSize, Res1, Res2,
|
||||
Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2));
|
||||
if Funcs^.AcceptPatch(StreamInfo^.OldSize, Res1, Res2) then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, Res2);
|
||||
SetBits(StreamInfo^.Option, 1, 31, 1);
|
||||
SOList[Instance][X].Add(I);
|
||||
Result := True;
|
||||
@@ -373,7 +383,7 @@ begin
|
||||
end;
|
||||
if Result then
|
||||
begin
|
||||
SetBits(StreamInfo^.Option, I, 5, 7);
|
||||
SetBits(StreamInfo^.Option, I, 3, 5);
|
||||
SOList[Instance][X].Add(I);
|
||||
end;
|
||||
end;
|
||||
@@ -384,39 +394,94 @@ var
|
||||
Buffer: PByte;
|
||||
Params: String;
|
||||
X: Integer;
|
||||
Res1: Integer;
|
||||
Res1: NativeInt;
|
||||
Res2: NativeUInt;
|
||||
Inp: ZSTD_inBuffer;
|
||||
Oup: ZSTD_outBuffer;
|
||||
Progress: NativeInt;
|
||||
begin
|
||||
Result := False;
|
||||
X := GetBits(StreamInfo.Option, 0, 5);
|
||||
X := GetBits(StreamInfo.Option, 0, 3);
|
||||
if BoolArray(CodecAvailable, False) or (CodecAvailable[X] = False) then
|
||||
exit;
|
||||
Buffer := Funcs^.Allocator(Instance, StreamInfo.NewSize);
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 5, 7).ToString;
|
||||
Params := 'l' + GetBits(StreamInfo.Option, 3, 5).ToString + ':' + 'f' +
|
||||
GetBits(StreamInfo.Option, 8, 1).ToString + ':' + 'b' +
|
||||
GetBits(StreamInfo.Option, 14, 13).ToString;
|
||||
case X of
|
||||
ZSTD_CODEC:
|
||||
begin
|
||||
if not Assigned(cctx[Instance]) then
|
||||
cctx[Instance] := ZSTD_createCCtx;
|
||||
Res1 := ZSTD_compressCCtx(cctx[Instance], Buffer, StreamInfo.NewSize,
|
||||
Input, StreamInfo.NewSize, GetBits(StreamInfo.Option, 5, 7));
|
||||
if GetBits(StreamInfo.Option, 14, 13) = 0 then
|
||||
begin
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_compressionLevel,
|
||||
IfThen(GetBits(StreamInfo.Option, 8, 1) = 0,
|
||||
GetBits(StreamInfo.Option, 3, 5),
|
||||
-GetBits(StreamInfo.Option, 3, 5)));
|
||||
ZSTD_CCtx_setParameter(cctx[Instance], ZSTD_c_windowLog,
|
||||
GetBits(StreamInfo.Option, 9, 5));
|
||||
if Assigned(ZSTD_compress2) then
|
||||
Res1 := ZSTD_compress2(cctx[Instance], Buffer, StreamInfo.NewSize,
|
||||
Input, StreamInfo.NewSize)
|
||||
else if Assigned(ZSTD_compress_generic) then
|
||||
begin
|
||||
Oup.dst := Buffer;
|
||||
Oup.Size := StreamInfo.NewSize;
|
||||
Oup.Pos := 0;
|
||||
Inp.src := PByte(Input);
|
||||
Inp.Size := StreamInfo.NewSize;
|
||||
Inp.Pos := 0;
|
||||
ZSTD_compress_generic(cctx[Instance], @Oup, @Inp, ZSTD_e_end);
|
||||
Res1 := Oup.Pos;
|
||||
end
|
||||
else
|
||||
Res1 := ZSTD_compressCCtx(cctx[Instance], Buffer,
|
||||
StreamInfo.NewSize, Input, StreamInfo.NewSize,
|
||||
IfThen(GetBits(StreamInfo.Option, 8, 1) = 0,
|
||||
GetBits(StreamInfo.Option, 3, 5),
|
||||
-GetBits(StreamInfo.Option, 3, 5)));
|
||||
end
|
||||
else
|
||||
begin
|
||||
Progress := 0;
|
||||
Oup.dst := Buffer;
|
||||
Oup.Size := StreamInfo.NewSize;
|
||||
Oup.Pos := 0;
|
||||
ZSTD_initCStream(cctx[Instance],
|
||||
IfThen(GetBits(StreamInfo.Option, 8, 1) = 0,
|
||||
GetBits(StreamInfo.Option, 3, 5),
|
||||
-GetBits(StreamInfo.Option, 3, 5)));
|
||||
while Progress < StreamInfo.NewSize do
|
||||
begin
|
||||
Inp.src := PByte(Input) + Progress;
|
||||
Inp.Size := Min(StreamInfo.NewSize - Progress,
|
||||
GetBits(StreamInfo.Option, 14, 13) * 1024);
|
||||
Inp.Pos := 0;
|
||||
if ZSTD_compressStream(cctx[Instance], @Oup, @Inp) > 0 then
|
||||
begin
|
||||
ZSTD_flushStream(cctx[Instance], @Oup);
|
||||
Inc(Progress, Inp.Size)
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
ZSTD_endStream(cctx[Instance], @Oup);
|
||||
Res1 := Oup.Pos;
|
||||
end;
|
||||
{ Res1 := ZSTD_compress_usingCDict(cctx[Instance], Buffer,
|
||||
StreamInfo.NewSize, Input, StreamInfo.NewSize, cdict); }
|
||||
end;
|
||||
end;
|
||||
Funcs^.LogRestore(ZSTDCodecs[GetBits(StreamInfo.Option, 0, 5)], PChar(Params),
|
||||
Funcs^.LogRestore(ZSTDCodecs[GetBits(StreamInfo.Option, 0, 3)], PChar(Params),
|
||||
StreamInfo.OldSize, StreamInfo.NewSize, Res1, True);
|
||||
if GetBits(StreamInfo.Option, 31, 1) = 1 then
|
||||
begin
|
||||
Buffer := Funcs^.Allocator(Instance, Res1 + StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatch(InputExt, StreamInfo.ExtSize, Buffer, Res1,
|
||||
Buffer + Res1, StreamInfo.OldSize);
|
||||
Res2 := PrecompDecodePatchEx(Instance, InputExt, StreamInfo.ExtSize, Buffer,
|
||||
Res1, Output);
|
||||
Funcs^.LogPatch2(StreamInfo.OldSize, Res1, StreamInfo.ExtSize, Res2 > 0);
|
||||
if Res2 > 0 then
|
||||
begin
|
||||
Output(Instance, Buffer + Res1, StreamInfo.OldSize);
|
||||
if Res2 = StreamInfo.OldSize then
|
||||
Result := True;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if Res1 = StreamInfo.OldSize then
|
||||
@@ -431,11 +496,6 @@ var
|
||||
|
||||
initialization
|
||||
|
||||
{ DStream := TMemoryStream.Create;
|
||||
DStream.LoadFromFile(ExtractFilePath(Utils.GetModuleName) + 'frostbite3_dict.dat');
|
||||
cdict := ZSTD_createCDict(DStream.Memory, DStream.Size, 19);
|
||||
ddict := ZSTD_createDDict(DStream.Memory, DStream.Size); }
|
||||
|
||||
Codec.Names := [];
|
||||
for I := Low(ZSTDCodecs) to High(ZSTDCodecs) do
|
||||
begin
|
||||
|
Reference in New Issue
Block a user