245 lines
8.0 KiB
ObjectPascal
245 lines
8.0 KiB
ObjectPascal
unit OodleDLL;
|
|
|
|
interface
|
|
|
|
uses
|
|
WinAPI.Windows,
|
|
System.SysUtils, System.Types, System.IOUtils;
|
|
|
|
type
|
|
POodleLZ_CompressOptions = ^TOodleLZ_CompressOptions;
|
|
|
|
TOodleLZ_CompressOptions = record
|
|
verbosity: Integer;
|
|
minMatchLen: Integer;
|
|
seekChunkReset: LongBool;
|
|
seekChunkLen: Integer;
|
|
profile: Cardinal;
|
|
dictionarySize: Integer;
|
|
spaceSpeedTradeoffBytes: Integer;
|
|
maxHuffmansPerChunk: Integer;
|
|
sendQuantumCRCs: LongBool;
|
|
maxLocalDictionarySize: Integer;
|
|
makeLongRangeMatcher: LongBool;
|
|
matchTableSizeLog2: Integer;
|
|
jobify: Integer;
|
|
jobifyUserPtr: Pointer;
|
|
farMatchMinLen: Integer;
|
|
farMatchOffsetLog2: Integer;
|
|
reserved: array [0 .. 3] of Integer;
|
|
end;
|
|
|
|
var
|
|
Oodle_CheckVersion: function(oodle_header_version: Cardinal;
|
|
pOodleLibVersion: PCardinal = nil): LongBool stdcall;
|
|
OodleLZ_Compress_1: function(compressor: Integer; rawBuf: Pointer;
|
|
rawLen: NativeUInt; compBuf: Pointer; compressSelect: Integer = 6;
|
|
pOptions: POodleLZ_CompressOptions = nil; dictionaryBase: Pointer = nil;
|
|
lrm: Pointer = nil): NativeUInt stdcall;
|
|
OodleLZ_Compress_2: function(compressor: Integer; rawBuf: Pointer;
|
|
rawLen: NativeUInt; compBuf: Pointer; compressSelect: Integer = 6;
|
|
pOptions: POodleLZ_CompressOptions = nil; dictionaryBase: Pointer = nil;
|
|
lrm: Pointer = nil; scratchMem: Pointer = nil; scratchSize: NativeUInt = 0)
|
|
: NativeUInt stdcall;
|
|
OodleLZ_Decompress: function(const compBuf: Pointer; compBufSize: NativeUInt;
|
|
rawBuf: Pointer; rawLen: NativeUInt; OodleLZ_FuzzSafe: Integer = 0;
|
|
OodleLZ_CheckCRC: Integer = 0; OodleLZ_Verbosity: Integer = 0;
|
|
decBufBase: Pointer = nil; decBufSize: NativeUInt = 0;
|
|
fpCallback: Pointer = nil; callbackUserData: Pointer = nil;
|
|
decoderMemory: Pointer = nil; decoderMemorySize: NativeUInt = 0;
|
|
threadPhase: Integer = 0): NativeUInt stdcall;
|
|
OodleLZ_CompressOptions_GetDefault_1: function(compressor: Integer;
|
|
lzLevel: Integer): POodleLZ_CompressOptions stdcall;
|
|
OodleLZ_CompressOptions_GetDefault_2: function
|
|
: POodleLZ_CompressOptions stdcall;
|
|
OodleLZ_GetCompressedBufferSizeNeeded_1: function(rawSize: NativeUInt)
|
|
: NativeUInt stdcall;
|
|
OodleLZ_GetCompressedBufferSizeNeeded_2: function(compressor: Integer;
|
|
rawSize: NativeUInt): NativeUInt stdcall;
|
|
|
|
DLLLoaded: Boolean = False;
|
|
|
|
function OodleLZ_Compress(compressor: Integer; rawBuf: Pointer;
|
|
rawLen: NativeUInt; compBuf: Pointer; compressSelect: Integer = 6;
|
|
pOptions: POodleLZ_CompressOptions = nil; dictionaryBase: Pointer = nil;
|
|
lrm: Pointer = nil; scratchMem: Pointer = nil; scratchSize: NativeUInt = 0)
|
|
: NativeUInt;
|
|
function OodleLZ_CompressOptions_GetDefault(compressor: Integer;
|
|
lzLevel: Integer): POodleLZ_CompressOptions;
|
|
function OodleLZ_GetCompressedBufferSizeNeeded(compressor: Byte;
|
|
rawSize: NativeUInt): NativeUInt;
|
|
|
|
implementation
|
|
|
|
var
|
|
DLLHandle: THandle;
|
|
OldCompress, OldCompressOptions_GetDefault,
|
|
OldGetCompressedBufferSizeNeeded: Boolean;
|
|
DLLs: TStringDynArray;
|
|
|
|
procedure Init(Filename: String);
|
|
var
|
|
I: Integer;
|
|
C: Cardinal;
|
|
begin
|
|
if DLLLoaded then
|
|
Exit;
|
|
DLLs := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), 'oo2core*.dll',
|
|
TSearchOption.soTopDirectoryOnly);
|
|
Insert(ExtractFilePath(ParamStr(0)) + Filename, DLLs, 0);
|
|
for I := Low(DLLs) to High(DLLs) do
|
|
begin
|
|
DLLHandle := LoadLibrary(PChar(DLLs[I]));
|
|
if DLLHandle >= 32 then
|
|
break;
|
|
end;
|
|
if DLLHandle < 32 then
|
|
begin
|
|
DLLs := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), 'oo2ext*.dll',
|
|
TSearchOption.soTopDirectoryOnly);
|
|
for I := Low(DLLs) to High(DLLs) do
|
|
begin
|
|
DLLHandle := LoadLibrary(PChar(DLLs[I]));
|
|
if DLLHandle >= 32 then
|
|
break;
|
|
end;
|
|
end;
|
|
if DLLHandle < 32 then
|
|
begin
|
|
DLLs := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), 'oodle2*.dll',
|
|
TSearchOption.soTopDirectoryOnly);
|
|
for I := Low(DLLs) to High(DLLs) do
|
|
begin
|
|
DLLHandle := LoadLibrary(PChar(DLLs[I]));
|
|
if DLLHandle >= 32 then
|
|
break;
|
|
end;
|
|
end;
|
|
if DLLHandle >= 32 then
|
|
begin
|
|
Oodle_CheckVersion := GetProcAddress(DLLHandle, 'Oodle_CheckVersion');
|
|
if not Assigned(Oodle_CheckVersion) then
|
|
for I := 0 to 32 do
|
|
begin
|
|
@Oodle_CheckVersion := GetProcAddress(DLLHandle,
|
|
PChar('_Oodle_CheckVersion@' + (I * 2).ToString));
|
|
if Assigned(Oodle_CheckVersion) then
|
|
break;
|
|
end;
|
|
DLLLoaded := Assigned(Oodle_CheckVersion);
|
|
Oodle_CheckVersion(0, @C);
|
|
OldCompress := LongRec(C).Hi < $2E06;
|
|
OldGetCompressedBufferSizeNeeded := LongRec(C).Hi < $2E08;
|
|
OldCompressOptions_GetDefault := LongRec(C).Hi < $2E08;
|
|
@OodleLZ_Compress_1 := GetProcAddress(DLLHandle, 'OodleLZ_Compress');
|
|
if not Assigned(OodleLZ_Compress_1) then
|
|
for I := 0 to 32 do
|
|
begin
|
|
@OodleLZ_Compress_1 := GetProcAddress(DLLHandle,
|
|
PChar('_OodleLZ_Compress@' + (I * 2).ToString));
|
|
if Assigned(OodleLZ_Compress_1) then
|
|
break;
|
|
end;
|
|
@OodleLZ_Compress_2 := @OodleLZ_Compress_1;
|
|
OodleLZ_Decompress := GetProcAddress(DLLHandle, 'OodleLZ_Decompress');
|
|
if not Assigned(OodleLZ_Decompress) then
|
|
for I := 0 to 32 do
|
|
begin
|
|
@OodleLZ_Decompress := GetProcAddress(DLLHandle,
|
|
PChar('_OodleLZ_Decompress@' + (I * 2).ToString));
|
|
if Assigned(OodleLZ_Decompress) then
|
|
break;
|
|
end;
|
|
OodleLZ_CompressOptions_GetDefault_1 := GetProcAddress(DLLHandle,
|
|
'OodleLZ_CompressOptions_GetDefault');
|
|
if not Assigned(OodleLZ_CompressOptions_GetDefault_1) then
|
|
for I := 0 to 32 do
|
|
begin
|
|
@OodleLZ_CompressOptions_GetDefault_1 :=
|
|
GetProcAddress(DLLHandle, PChar('_OodleLZ_CompressOptions_GetDefault@'
|
|
+ (I * 2).ToString));
|
|
if Assigned(OodleLZ_CompressOptions_GetDefault_1) then
|
|
break;
|
|
end;
|
|
@OodleLZ_CompressOptions_GetDefault_2 :=
|
|
@OodleLZ_CompressOptions_GetDefault_1;
|
|
OodleLZ_GetCompressedBufferSizeNeeded_1 :=
|
|
GetProcAddress(DLLHandle, 'OodleLZ_GetCompressedBufferSizeNeeded');
|
|
if not Assigned(OodleLZ_GetCompressedBufferSizeNeeded_1) then
|
|
for I := 0 to 32 do
|
|
begin
|
|
@OodleLZ_GetCompressedBufferSizeNeeded_1 :=
|
|
GetProcAddress(DLLHandle,
|
|
PChar('_OodleLZ_GetCompressedBufferSizeNeeded@' + (I * 2).ToString));
|
|
if Assigned(OodleLZ_GetCompressedBufferSizeNeeded_1) then
|
|
break;
|
|
end;
|
|
@OodleLZ_GetCompressedBufferSizeNeeded_2 :=
|
|
@OodleLZ_GetCompressedBufferSizeNeeded_1;
|
|
end
|
|
else
|
|
DLLLoaded := False;
|
|
end;
|
|
|
|
procedure Deinit;
|
|
begin
|
|
if not DLLLoaded then
|
|
Exit;
|
|
FreeLibrary(DLLHandle);
|
|
end;
|
|
|
|
function OodleLZ_Compress(compressor: Integer; rawBuf: Pointer;
|
|
rawLen: NativeUInt; compBuf: Pointer; compressSelect: Integer;
|
|
pOptions: POodleLZ_CompressOptions; dictionaryBase: Pointer; lrm: Pointer;
|
|
scratchMem: Pointer; scratchSize: NativeUInt): NativeUInt;
|
|
begin
|
|
if OldCompress then
|
|
Result := OodleLZ_Compress_1(compressor, rawBuf, rawLen, compBuf,
|
|
compressSelect, pOptions, dictionaryBase, lrm)
|
|
else
|
|
Result := OodleLZ_Compress_2(compressor, rawBuf, rawLen, compBuf,
|
|
compressSelect, pOptions, dictionaryBase, lrm, scratchMem, scratchSize);
|
|
end;
|
|
|
|
function OodleLZ_CompressOptions_GetDefault(compressor: Integer;
|
|
lzLevel: Integer): POodleLZ_CompressOptions;
|
|
begin
|
|
if OldCompressOptions_GetDefault then
|
|
Result := OodleLZ_CompressOptions_GetDefault_1(compressor, lzLevel)
|
|
else
|
|
Result := OodleLZ_CompressOptions_GetDefault_2;
|
|
end;
|
|
|
|
function OodleLZ_GetCompressedBufferSizeNeeded(compressor: Byte;
|
|
rawSize: NativeUInt): NativeUInt;
|
|
begin
|
|
if OldGetCompressedBufferSizeNeeded then
|
|
Result := OodleLZ_GetCompressedBufferSizeNeeded_1(rawSize)
|
|
else
|
|
Result := OodleLZ_GetCompressedBufferSizeNeeded_2(compressor, rawSize);
|
|
end;
|
|
|
|
const
|
|
DLLParam = '--oodle=';
|
|
|
|
var
|
|
I: Integer;
|
|
DLLFile: String;
|
|
|
|
initialization
|
|
|
|
DLLFile := 'oodle.dll';
|
|
for I := 1 to ParamCount do
|
|
if ParamStr(I).StartsWith(DLLParam) then
|
|
begin
|
|
DLLFile := ParamStr(I).Substring(DLLParam.Length);
|
|
break;
|
|
end;
|
|
Init(DLLFile);
|
|
|
|
finalization
|
|
|
|
Deinit;
|
|
|
|
end.
|