Fled
asked on
Zlib implementation
Hello everybody.
Does anybody know how to imprement compression unit Zlib?
I know that Delphi is delivered witht Zlib.dcu but again, no documentation is provided...
Some sample code would be appreciated.
Francois Leduc
Laval, Qc, Can.
Does anybody know how to imprement compression unit Zlib?
I know that Delphi is delivered witht Zlib.dcu but again, no documentation is provided...
Some sample code would be appreciated.
Francois Leduc
Laval, Qc, Can.
Hi,
I worked with ZLIB and I got good results for compression.
I'll put a unit in which you have the functions you need.
unit BPCompress;
interface
uses
Windows, SysUtils, Classes, ZLib;
type
TBPCompress = class
public
function CompressFile( SourceFile : string;
CompressedFile : string ) : boolean;
function CompressStream( inpStream : TMemoryStream;
outStream : TMemoryStream ) : boolean;
function DeCompressFile( CompressedFile : string;
DestFile : string ) : boolean;
function DeCompressStream( inpStream : TMemoryStream;
outStream : TMemoryStream ) : boolean;
end;
implementation
function TBPCompress.CompressFile(S ourceFile,
CompressedFile: string): boolean;
var
ms1, ms2: TMemoryStream;
begin
result := False;
ms1 := TMemoryStream.Create;
ms2 := TMemoryStream.Create;
try
ms1.LoadFromFile(SourceFil e);
if CompressStream(ms1, ms2) then
result := True;
ms2.SaveToFile(CompressedF ile);
finally
ms1.Free;
ms2.Free;
end;
end;
function TBPCompress.CompressStream ( inpStream : TMemoryStream;
outStream : TMemoryStream
) : boolean;
var
InpBuf, OutBuf: Pointer;
InpBytes, OutBytes: Integer;
begin
result := False;
InpBuf := nil;
OutBuf := nil;
try
GetMem(InpBuf, inpStream.Size);
inpStream.Position := 0;
InpBytes := inpStream.Read(InpBuf^, inpStream.Size);
CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes);
outStream.Write(OutBuf^, OutBytes);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then begin
FreeMem(OutBuf);
result := True;
end;
end;
end;
function TBPCompress.DeCompressFile (Compresse dFile,
DestFile: string): boolean;
var
ms1, ms2: TMemoryStream;
begin
result := False;
ms1 := TMemoryStream.Create;
ms2 := TMemoryStream.Create;
try
ms1.LoadFromFile(Compresse dFile);
if DecompressStream(ms1, ms2) then
result := True;
ms2.SaveToFile(DestFile);
finally
ms1.Free;
ms2.Free;
end;
end;
function TBPCompress.DeCompressStre am( inpStream : TMemoryStream;
outStream : TMemoryStream
) : boolean;
var
InpBuf, OutBuf: Pointer;
InpBytes, OutBytes: Integer;
begin
result := False;
InpBuf := nil;
OutBuf := nil;
inpStream.Position := 0;
InpBytes := inpStream.Size - inpStream.Position;
if InpBytes > 0 then
try
GetMem(InpBuf, InpBytes);
inpStream.Read(InpBuf^, InpBytes);
DecompressBuf(InpBuf, InpBytes, 0, OutBuf, OutBytes);
outStream.Write(OutBuf^, OutBytes);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then begin
FreeMem(OutBuf);
result := True;
end;
end;
outStream.Position := 0;
end;
end.
I worked with ZLIB and I got good results for compression.
I'll put a unit in which you have the functions you need.
unit BPCompress;
interface
uses
Windows, SysUtils, Classes, ZLib;
type
TBPCompress = class
public
function CompressFile( SourceFile : string;
CompressedFile : string ) : boolean;
function CompressStream( inpStream : TMemoryStream;
outStream : TMemoryStream ) : boolean;
function DeCompressFile( CompressedFile : string;
DestFile : string ) : boolean;
function DeCompressStream( inpStream : TMemoryStream;
outStream : TMemoryStream ) : boolean;
end;
implementation
function TBPCompress.CompressFile(S
CompressedFile: string): boolean;
var
ms1, ms2: TMemoryStream;
begin
result := False;
ms1 := TMemoryStream.Create;
ms2 := TMemoryStream.Create;
try
ms1.LoadFromFile(SourceFil
if CompressStream(ms1, ms2) then
result := True;
ms2.SaveToFile(CompressedF
finally
ms1.Free;
ms2.Free;
end;
end;
function TBPCompress.CompressStream
outStream : TMemoryStream
) : boolean;
var
InpBuf, OutBuf: Pointer;
InpBytes, OutBytes: Integer;
begin
result := False;
InpBuf := nil;
OutBuf := nil;
try
GetMem(InpBuf, inpStream.Size);
inpStream.Position := 0;
InpBytes := inpStream.Read(InpBuf^, inpStream.Size);
CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes);
outStream.Write(OutBuf^, OutBytes);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then begin
FreeMem(OutBuf);
result := True;
end;
end;
end;
function TBPCompress.DeCompressFile
DestFile: string): boolean;
var
ms1, ms2: TMemoryStream;
begin
result := False;
ms1 := TMemoryStream.Create;
ms2 := TMemoryStream.Create;
try
ms1.LoadFromFile(Compresse
if DecompressStream(ms1, ms2) then
result := True;
ms2.SaveToFile(DestFile);
finally
ms1.Free;
ms2.Free;
end;
end;
function TBPCompress.DeCompressStre
outStream : TMemoryStream
) : boolean;
var
InpBuf, OutBuf: Pointer;
InpBytes, OutBytes: Integer;
begin
result := False;
InpBuf := nil;
OutBuf := nil;
inpStream.Position := 0;
InpBytes := inpStream.Size - inpStream.Position;
if InpBytes > 0 then
try
GetMem(InpBuf, InpBytes);
inpStream.Read(InpBuf^, InpBytes);
DecompressBuf(InpBuf, InpBytes, 0, OutBuf, OutBytes);
outStream.Write(OutBuf^, OutBytes);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then begin
FreeMem(OutBuf);
result := True;
end;
end;
outStream.Position := 0;
end;
end.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
There u go, two for the price of one from bpana ;o)
bpana has the solution, but also for your interest, here is a TStream derivative with a stream.compress and stream.decompress property (dont foget to add 'zlib' to the 'uses' clause):
type
TfcMemoryStream = class (TMemoryStream)
public
procedure compress;
procedure decompress;
end;
// COMPRESS
procedure TfcMemoryStream.compress;
var
InpBuf,OutBuf : Pointer;
InpBytes,OutBytes : integer;
begin
InpBuf := nil;
OutBuf := nil;
try
// Read whole stream into buffer
self.position := 0;
GetMem(InpBuf,self.size);
InpBytes := self.Read(InpBuf^,self.siz e);
// Compress buffer into second buffer
compressBuf(InpBuf,InpByte s,OutBuf,O utBytes);
// Clear stream and write second buffer to stream
self.Clear;
self.Write(OutBuf^,OutByte s);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then FreeMem(OutBuf);
end;
end;
// DECOMPRESS
procedure TfcMemoryStream.decompress ;
var
InpBuf,OutBuf : Pointer;
OutBytes,sz : integer;
begin
InpBuf := nil;
OutBuf := nil;
sz := self.size-self.Position;
if sz > 0 then begin
try
// Read part of stream into buffer (from 'position' to end)
GetMem(InpBuf,sz);
self.Read(InpBuf^,sz);
// Decompress buffer into output buffer
decompressBuf(InpBuf,sz,0, OutBuf,Out Bytes);
// Clear stream and copy output buffer to stream
self.clear;
self.Write(OutBuf^,OutByte s);
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then FreeMem(OutBuf);
end;
end;
end;
Good luck!
type
TfcMemoryStream = class (TMemoryStream)
public
procedure compress;
procedure decompress;
end;
// COMPRESS
procedure TfcMemoryStream.compress;
var
InpBuf,OutBuf : Pointer;
InpBytes,OutBytes : integer;
begin
InpBuf := nil;
OutBuf := nil;
try
// Read whole stream into buffer
self.position := 0;
GetMem(InpBuf,self.size);
InpBytes := self.Read(InpBuf^,self.siz
// Compress buffer into second buffer
compressBuf(InpBuf,InpByte
// Clear stream and write second buffer to stream
self.Clear;
self.Write(OutBuf^,OutByte
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then FreeMem(OutBuf);
end;
end;
// DECOMPRESS
procedure TfcMemoryStream.decompress
var
InpBuf,OutBuf : Pointer;
OutBytes,sz : integer;
begin
InpBuf := nil;
OutBuf := nil;
sz := self.size-self.Position;
if sz > 0 then begin
try
// Read part of stream into buffer (from 'position' to end)
GetMem(InpBuf,sz);
self.Read(InpBuf^,sz);
// Decompress buffer into output buffer
decompressBuf(InpBuf,sz,0,
// Clear stream and copy output buffer to stream
self.clear;
self.Write(OutBuf^,OutByte
finally
if InpBuf <> nil then FreeMem(InpBuf);
if OutBuf <> nil then FreeMem(OutBuf);
end;
end;
end;
Good luck!
ASKER
Thank you Bpana it is functionning perfectly. I was using an huffman algo but it was not efficient with encrypted files (some times the compressed files where bigger than the origials). Now I can reach a 48% compresssion factor with ZLib.
Hi, when I tested it, I've got good results also, very closed to winzip.
Best regards,
Bogdan Pana
Best regards,
Bogdan Pana
Someone else may have the time to construct an example, so it may be worth waiting for that...
Cheers