|
@@ -0,0 +1,141 @@
|
|
|
|
+{ ***************************************************************************
|
|
|
|
+
|
|
|
|
+ Copyright (c) 2016-2019 Kike Pérez
|
|
|
|
+
|
|
|
|
+ Unit : Quick.Compression.LZO
|
|
|
|
+ Description : LZO Compressor
|
|
|
|
+ Author : Kike Pérez
|
|
|
|
+ Version : 1.8
|
|
|
|
+ Created : 15/09/2019
|
|
|
|
+ Modified : 22/09/2019
|
|
|
|
+
|
|
|
|
+ This file is part of QuickLib: https://github.com/exilon/QuickLib
|
|
|
|
+
|
|
|
|
+ ***************************************************************************
|
|
|
|
+
|
|
|
|
+ Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
+ you may not use this file except in compliance with the License.
|
|
|
|
+ You may obtain a copy of the License at
|
|
|
|
+
|
|
|
|
+ http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
+
|
|
|
|
+ Unless required by applicable law or agreed to in writing, software
|
|
|
|
+ distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
+ See the License for the specific language governing permissions and
|
|
|
|
+ limitations under the License.
|
|
|
|
+
|
|
|
|
+ *************************************************************************** }
|
|
|
|
+
|
|
|
|
+unit Quick.Compression.LZO;
|
|
|
|
+
|
|
|
|
+{$i QuickLib.inc}
|
|
|
|
+
|
|
|
|
+interface
|
|
|
|
+
|
|
|
|
+uses
|
|
|
|
+ SysUtils;
|
|
|
|
+
|
|
|
|
+const
|
|
|
|
+
|
|
|
|
+ {$IFDEF MSWINDOWS}
|
|
|
|
+ LIBPATH = '.\lzo.dll';
|
|
|
|
+ {$ELSE}
|
|
|
|
+ LIBPATH = './lzo.so';
|
|
|
|
+ {$ENDIF}
|
|
|
|
+
|
|
|
|
+type
|
|
|
|
+
|
|
|
|
+ TLZOCompressor = class
|
|
|
|
+ private
|
|
|
|
+ fWorkMemory : Pointer;
|
|
|
|
+ public
|
|
|
|
+ constructor Create;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+ function Version : string;
|
|
|
|
+ function VersionDate : string;
|
|
|
|
+ function Compress(const aUncompressed : string) : string;
|
|
|
|
+ function Decompress(const aCompressed : string) : string;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ ELZOCompressor = class(Exception);
|
|
|
|
+
|
|
|
|
+implementation
|
|
|
|
+
|
|
|
|
+function __lzo_init3 : Integer; stdcall; external LIBPATH;
|
|
|
|
+function lzo_version_string : PChar; stdcall; external LIBPATH;
|
|
|
|
+function lzo_version_date : PChar; stdcall; external LIBPATH;
|
|
|
|
+function lzo1x_1_compress(src : Pointer; src_len : LongWord; dest : Pointer; var dest_len : LongWord; wrkmem : Pointer) : Integer; stdcall; external LIBPATH;
|
|
|
|
+function lzo1x_decompress(src : Pointer; src_len : LongWord; dest : Pointer; var dest_len : LongWord; wrkmem : Pointer) : Integer; stdcall; external LIBPATH;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+{ TLZOCompressor }
|
|
|
|
+
|
|
|
|
+function TLZOCompressor.Compress(const aUncompressed: string): string;
|
|
|
|
+var
|
|
|
|
+ srclen : Integer;
|
|
|
|
+ outlen : LongWord;
|
|
|
|
+ uncompressed : TBytes;
|
|
|
|
+ compressed : TBytes;
|
|
|
|
+ byteslen : array[1.. sizeof(integer)] of byte;
|
|
|
|
+begin
|
|
|
|
+ outlen := 0;
|
|
|
|
+ try
|
|
|
|
+ SetLength(compressed, Round(aUncompressed.Length + aUncompressed.Length / 64 + 16 + 3 + 4));
|
|
|
|
+ uncompressed := TEncoding.UTF8.GetBytes(aUncompressed);
|
|
|
|
+ lzo1x_1_compress(uncompressed, High(uncompressed)+1, compressed, outlen, fWorkMemory);
|
|
|
|
+ Finalize(uncompressed);
|
|
|
|
+ srclen := aUncompressed.Length;
|
|
|
|
+ Move(srclen,byteslen[1], SizeOf(Integer));
|
|
|
|
+ SetLength(compressed,outlen + 4);
|
|
|
|
+ Move(byteslen,compressed[outlen],4);
|
|
|
|
+ Result := TEncoding.ANSI.GetString(compressed,0,outlen + 4);
|
|
|
|
+ except
|
|
|
|
+ on E : Exception do raise ELZOCompressor.CreateFmt('LZO Compression error: %s',[e.Message]);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+constructor TLZOCompressor.Create;
|
|
|
|
+begin
|
|
|
|
+ if __lzo_init3 <> 0 then raise Exception.Create('Initialization LZO-Compressor failed');
|
|
|
|
+ GetMem(fWorkMemory,16384 * 4);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TLZOCompressor.Decompress(const aCompressed: string): string;
|
|
|
|
+var
|
|
|
|
+ srclen : LongWord;
|
|
|
|
+ dstlen : LongWord;
|
|
|
|
+ uncompressed : TBytes;
|
|
|
|
+ compressed : TBytes;
|
|
|
|
+ i : Integer;
|
|
|
|
+begin
|
|
|
|
+ try
|
|
|
|
+ compressed := TEncoding.ANSI.GetBytes(aCompressed);
|
|
|
|
+ //get src length
|
|
|
|
+ srclen := PLongInt(@compressed[High(compressed)-3])^;
|
|
|
|
+ SetLength(uncompressed,srclen);
|
|
|
|
+ dstlen := 0;
|
|
|
|
+ lzo1x_decompress(compressed, High(compressed) - 4, uncompressed, dstlen, fWorkMemory);
|
|
|
|
+ Result := TEncoding.UTF8.GetString(uncompressed,0,dstlen);
|
|
|
|
+ except
|
|
|
|
+ on E : Exception do raise ELZOCompressor.CreateFmt('LZO Descompression error: %s',[e.Message]);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TLZOCompressor.Destroy;
|
|
|
|
+begin
|
|
|
|
+ FreeMem(fWorkMemory);
|
|
|
|
+ inherited;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TLZOCompressor.Version: string;
|
|
|
|
+begin
|
|
|
|
+ Result := string(lzo_version_string);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TLZOCompressor.VersionDate: string;
|
|
|
|
+begin
|
|
|
|
+ Result := string(lzo_version_date^);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+end.
|