You can use the SynLZ algorithm within a .zip container within SynZipFiles.
But it is a proprietary extension, not recognized by anything else than this unit!
I highly doubt, but it is better to ask. Is it somehow possible to use FileSynLz() compress multiple files like TZipWrite does?
If not, is it possible to use TZipWrite only as a container? In other words, can I have TZipWrite to create a zip file having several FileSynLz() created files without trying to compress them again.
Thanks.
]]>Thanks.
]]>If you want a zip format, you would have to use SynZip.pas - but it is (much) slower, and compress better.
]]>I have already tried 7zip V15.14 and Winrar V5.30 and failed.
]]>Put whatever you want, some big random 32 bit integer, which would identify your file content, like the file extension does, but here it is internally to the file.
FileUnLz() would check this number, to ensure the file is with the expected format.
function FileSynLZ(const Source, Dest: TFileName; Magic: Cardinal): boolean;
I am not sure what value I should provide for parameter "Magic". Is it possible to have an example code, please?
Thanks.
]]>I want to fast backup some SQLite database files. Sizes mostly smaller than 2GB. Since it is indicated that lzopas_compressfile is faster than copying files, I wanted to give it a try. Unfortunately, I have found below comment in 1.18.2639 version of the framework in SynLZO unit.
{.$define LZOFILE}
{ attempt to use in-place file compression using memory mapping mechanism
-> still not fully functional -> so do not define }
I wonder if the function is not to be used at all.
Thanks.
]]>For AES compression, our latest version in SynCrypto.pas would be even faster on AesNi CPUs.
10 times faster in fact...
InputDataSize := Integer(CurrentBufPtr)-Integer(FBuffer);
if TabArchiver.CompressionLevel=FlexCompress.clNone then begin
CompressedSize := SynLZcompress1(FBuffer, InputDataSize, SynLZBuffer);
ArchMemStream.WriteBuffer(SynLZBuffer^, CompressedSize);
end else
ArchMemStream.WriteBuffer(FBuffer^, InputDataSize);
TabArchiver.ExtractToStream(FileName, LoadStream);
L:=LoadStream.Size;
if TabArchiver.LastCompressionMode=0 then begin
P:=LoadStream.Memory;
aUnCompressedSize:=SynLZdecompressdestlen(P);
SynLZStream.Size := aUnCompressedSize;
if (SynLZdecompress1(P,L,SynLZStream.Memory)<>aUnCompressedSize) then
RaiseMsgError('Invalid SynLZ decompress');
CurrentBufPtr:=SynLZStream.Memory;
L:=SynLZStream.Size;
end else
CurrentBufPtr:=LoadStream.Memory;
Size of backup FlexCompress(PPM+Max) is 2 times smaller than SynLZ.
Size of backup SynLZ is 3 times smaller than without compression
(input buffer is very packed).
SynLZ compression+FlexCompress(Rijndael_256) is 18 times faster than FlexCompress(PPM+Max+Rijndael_256);
decompression time is 10 times faster, Rijndael_256 used in any case.
Compression time(SynLZ+Rijndael_256)=10% of Backup time. 90%=Fetch records
Compression time(PPM+Max+Rijndael_256)=70% of Backup time.
See for instance StreamSynLZ/StreamUnSynLZ in SynCommons.pas unit.
Those functions are adding a hash to check the data integrity before decompression.
a hashing limitation makes SynLZ sometimes unable to pack continuous blocks of same byte -> SynLZ is perfect for xml/text, but SynLZO is prefered for database files
I would like to use the LZ compression to shrink Bitmap images in my application.
Because the bitmaps are screenshots it will have many repeating bytes.
Does the above limitation that I cannot use `SynLZ`, but must use `SynLZO` instead?
I have tried to write / read directly to a filestream giving this magic number but it seems not to work?! It would reduce memory consumption, so it would be nice to use it. As a workaround I use 2 memory streams and store the stream size as a header in the filestream. Is there a way to use a filestream for StreamSynLZ / StreamUnSynLZ directly? (I only need the uncompressed stream internally)
My example app (in short form);
function TestWrite;
var
SL: TStringList;
msIN,msOUT: TMemoryStream;
fs: TFileStream;
sLen: Int64;
begin
SL := TStringList.Create;
msIN := TMemoryStream.Create;
SL.Add('... many lines of blala here');
...
SL.WriteToStream(msIN);
msIN.Position := 0;
SynCommons.StreamSynLZ(msIN,msOUT,4711);
fs := TFileStream.Create('F:\TEST.SYN',fmCreate);
sLen := msOUT.Size;
fs.Write(sLen,SizeOf(sLen));
fs.CopyFrom(msOUT,sLen);
SL.Clear;
msIN.Clear;
msOUT.Clear;
SL.Add('insert new text as second chunk...');
SL.SaveToStream(msIN);
msIN.Position := 0;
SynCommons.StreamSynLZ(msIN,msOUT,0815);
msOUT.Position := 0;
sLen := msOUT.Size;
fs.Write(sLen,SizeOf(sLen));
fs.CopyFrom(msOUT,sLen);
fs.Free;
msIN.Free;
msOUT.Free;
SL.Free;
end;
function TestRead;
var
SL: TStringList;
msIN,msOUT: TMemoryStream;
sLen: Int64;
fs: TFileStream;
begin
SL := TStringList.Create;
msIN := TMemoryStream.Create;
fs := TFileStream.Create('F:\TEST.SYN',fmOpenRead);
fs.Read(sLen,SizeOf(sLen));
msIN.CopyFrom(fs,sLen);
msIN.Position := 0;
msOUT := SynCommons.StreamUnSynLZ(msIN,4711);
msOUT.Position := 0;
SL.ReadFromStream(msOUT); // breakpoint to check data
SL.Clear;
msIN.Clear;
msOUT.Free;
fs.Read(sLen,SizeOf(sLen));
msIN.CopyFrom(fs,sLen);
msIN.Position := 0;
msOUT := SynCommons.StreamUnSynLZ(msIN,0815);
msOUT.Positon := 0;
SL.ReadFromStream(msOUT); // Check data again
SL.Free;
fs.Free;
msIN.Free;
msOUT.Free;
end;
Thx in advance
Moehre
I never used it, personally.
]]>