Link to home
Start Free TrialLog in
Avatar of Fled
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.
Avatar of Martyn Spencer
Martyn Spencer
Flag of United Kingdom of Great Britain and Northern Ireland image

I haven't the time to drag out any code that uses ZLib for compression that I have written, but if you take a look at IdCompressionIntercept.pas in the indy libraries, it will give you some ideas as to how to implement it. I actually make use of a freeware set of compression components and can email them to you if you wish.

Someone else may have the time to construct an example, so it may be worth waiting for that...

Cheers
Avatar of bpana
bpana

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(SourceFile,
  CompressedFile: string): boolean;
var
  ms1, ms2: TMemoryStream;
begin
  result := False;
  ms1 := TMemoryStream.Create;
  ms2 := TMemoryStream.Create;
  try
    ms1.LoadFromFile(SourceFile);
    if CompressStream(ms1, ms2) then
       result := True;
    ms2.SaveToFile(CompressedFile);
  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(CompressedFile,
  DestFile: string): boolean;
var
  ms1, ms2: TMemoryStream;
begin
  result := False;
  ms1 := TMemoryStream.Create;
  ms2 := TMemoryStream.Create;
  try
    ms1.LoadFromFile(CompressedFile);
    if DecompressStream(ms1, ms2) then
       result := True;
    ms2.SaveToFile(DestFile);
  finally
    ms1.Free;
    ms2.Free;
  end;
end;

function TBPCompress.DeCompressStream(  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.
ASKER CERTIFIED SOLUTION
Avatar of bpana
bpana

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.size);
    // Compress buffer into second buffer
    compressBuf(InpBuf,InpBytes,OutBuf,OutBytes);
    // Clear stream and write second buffer to stream
    self.Clear;
    self.Write(OutBuf^,OutBytes);
  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,OutBytes);
      // Clear stream and copy output buffer to stream
      self.clear;
         self.Write(OutBuf^,OutBytes);
       finally
         if InpBuf <> nil then FreeMem(InpBuf);
         if OutBuf <> nil then FreeMem(OutBuf);
       end;
  end;
end;

Good luck!
Avatar of Fled

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