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.