update to 0.7.9

This commit is contained in:
Razor12911
2023-09-10 15:03:26 +02:00
parent 30ce6f00fc
commit fde22c2c77
159 changed files with 6345 additions and 49597 deletions

View File

@@ -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;

View File

@@ -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.

View 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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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.

View File

@@ -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;

View File

@@ -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