Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Zlib implementation

Posted on 2003-01-07
7
Medium Priority
?
1,040 Views
Last Modified: 2010-04-04
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.
0
Comment
Question by:Fled
7 Comments
 
LVL 2

Expert Comment

by:mdspencer
ID: 7680853
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
0
 
LVL 6

Expert Comment

by:bpana
ID: 7680886
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.
0
 
LVL 6

Accepted Solution

by:
bpana earned 400 total points
ID: 7680888
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.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Expert Comment

by:mdspencer
ID: 7682140
There u go, two for the price of one from bpana ;o)
0
 
LVL 1

Expert Comment

by:petervullings
ID: 7682547
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!
0
 

Author Comment

by:Fled
ID: 7685810
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.
0
 
LVL 6

Expert Comment

by:bpana
ID: 7688790
Hi, when I  tested it, I've got good results also, very closed to winzip.

Best regards,
Bogdan Pana
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Loops Section Overview
Suggested Courses

963 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question