Link to home
Start Free TrialLog in
Avatar of perkley
perkley

asked on

zLib and Stream?

I have most of the code, I just need a little help if possible.  This code does not seem to work.  If I create a TFileStream, then I can save a bitmap picture and LoadFromStream and it brings it back.  However, I am trying to compress the File, and when you use the file, then it decompresses it into memory and uses it, instead of extracting a file somewhere.  Anybody have any ideas why this does not work.  I am using the zLib component that comes with Delphi.

var
  frmMain: TfrmMain;

implementation

{$R *.DFM}

procedure TfrmMain.btnCompressClick(Sender: TObject);
var
    NewFile: TMemoryStream;
begin
  NewFile := TMemoryStream.Create;
  try
    image1.Picture.Bitmap.SaveToStream(NewFile);
    OutFile := TFileStream.Create('e:\001.stm', fmCreate);
    try
      ZStream := TCompressionStream.Create(clFastest, OutFile);
      try
        ZStream.CopyFrom(NewFile, 0);
      finally
        ZStream.Free;
      end;

    finally
      OutFile.Free;
    end;
  finally
    NewFile.Free;
  end;
end;

procedure TfrmMain.btnDecompressClick(Sender: TObject);
var
  Count: Integer;
  NewFile: TMemoryStream;
begin
  InFile := TFileStream.Create('e:\001.stm', fmOpenRead);
  try
    NewFile := TMemoryStream.Create;
    try

      ZStream := TDecompressionStream.Create(InFile);
      try
        while True do
          begin
            Count := ZStream.Read(Buffer, BufferSize);
            if Count <> 0 then NewFile.WriteBuffer(Buffer, Count) else Break;
          end;
        image1.Picture.Bitmap.LoadFromStream(NewFile);
      finally
        ZStream.Free;
      end;
    finally
      NewFile.Free;
    end;
  finally
    InFile.Free;
  end;

end;

end.
ASKER CERTIFIED SOLUTION
Avatar of inthe
inthe

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
Avatar of perkley
perkley

ASKER

I am getting an error on this line of your code:

CompressBuf(Strm.Memory, Strm.Size, PStrm, i);

ERROR: Incompatible Types "Integer" and "Pointer".
The error is on the PStrm, which you defined as Pointer.

I am using Delphi 5 Professional
mm..i only use d4.03 so cant test what to do .
i have other code for this but the only difference in it is setting

begin
PStrm := nil

you could try CompressBuf(Strm.Memory, Strm.Size,nil,i) ..
i cant really say for sure ,i though it would be same in d4 & d5 for this stuff.

Avatar of perkley

ASKER

Your code is okay, except, that they added a new variable to send, and that was what the problem was.  I need to send an integer for CmpMode.  Do you have any idea what I should send.  Here is the code that it runs on my computer.

procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; CmpMode : Integer;
                      var OutBuf: Pointer; var OutBytes: Integer);
var
  strm: TZStreamRec;
  P: Pointer;
begin
  FillChar(strm, sizeof(strm), 0);
  strm.zalloc := zlibAllocMem;
  strm.zfree := zlibFreeMem;
  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
  GetMem(OutBuf, OutBytes);
  try
    strm.next_in := InBuf;
    strm.avail_in := InBytes;
    strm.next_out := OutBuf;
    strm.avail_out := OutBytes;
    CCheck(deflateInit_(strm, cmpMode, zlib_version, sizeof(strm)));
    try
      while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
      begin
        P := OutBuf;
        Inc(OutBytes, 256);
        ReallocMem(OutBuf, OutBytes);
        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
        strm.avail_out := 256;
      end;
    finally
      CCheck(deflateEnd(strm));
    end;
    ReallocMem(OutBuf, strm.total_out);
    OutBytes := strm.total_out;
  except
    FreeMem(OutBuf);
    raise
  end;
end;
Avatar of perkley

ASKER

k, cmpmode is the compression level, so it seems to put it to the stream fine.  The problem is that when it comes to the decompression section, it gives an error.  Have you tested it with a bitmap going into an image.picture.bitmap.loadfromstream?
i only used it once on d3 only changing a few lines in the d3 exmaple that was provided ,im going to fire up delphi and take a look see what happens.
is the declaration for decompressbuf still the same?

(as a note if you have d4 or d3 you can try using that version of zlib see if get same errors)
Avatar of perkley

ASKER

Yes, the decompressbuf seems to be the same, but it is the decompressbuf that it has the error with when trying to decompress the picture.
hi,
i tried my example and worked fine using d4 ,so i am assuming it is a problem with this new CmpMode parameter.so i replace my compressbuf procedure in zlib.pas to your new one and used thus in my unit:

CompressBuf(Strm.Memory, Strm.Size,0,PStrm, i);

it worked fine again,no error on decompress.



if you like i could send you my zlib unit and my test unit.
Avatar of perkley

ASKER

Hmm, k, I took the Zlib off of the Delphi 5 CD again, because I noticed that it was coming from a backup program I was using. They had modified the Zlib component a little.

I took the path off for their modified one, and put the original back.  It still gave the same error though, but it did not ask for the Compression Level.

Anyway, let me see your example program, because maybe I typed something wrong somewhere.

Send to Douglas@rexburg.com
Avatar of perkley

ASKER

Thanks, I did have one small problem - called the filename I was reading from.  I changed the example you gave me to fit my program, and I typed the file to read from wrong, and so it was giving me an error.  Sorry to put you through the research, when it was on my end.  Your code does work well.
:o) no probs