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.Save ToStream(N ewFile);
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.btnDecompressClic k(Sender: TObject);
var
Count: Integer;
NewFile: TMemoryStream;
begin
InFile := TFileStream.Create('e:\001 .stm', fmOpenRead);
try
NewFile := TMemoryStream.Create;
try
ZStream := TDecompressionStream.Creat e(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.Load FromStream (NewFile);
finally
ZStream.Free;
end;
finally
NewFile.Free;
end;
finally
InFile.Free;
end;
end;
end.
var
frmMain: TfrmMain;
implementation
{$R *.DFM}
procedure TfrmMain.btnCompressClick(
var
NewFile: TMemoryStream;
begin
NewFile := TMemoryStream.Create;
try
image1.Picture.Bitmap.Save
OutFile := TFileStream.Create('e:\001
try
ZStream := TCompressionStream.Create(
try
ZStream.CopyFrom(NewFile, 0);
finally
ZStream.Free;
end;
finally
OutFile.Free;
end;
finally
NewFile.Free;
end;
end;
procedure TfrmMain.btnDecompressClic
var
Count: Integer;
NewFile: TMemoryStream;
begin
InFile := TFileStream.Create('e:\001
try
NewFile := TMemoryStream.Create;
try
ZStream := TDecompressionStream.Creat
try
while True do
begin
Count := ZStream.Read(Buffer, BufferSize);
if Count <> 0 then NewFile.WriteBuffer(Buffer
end;
image1.Picture.Bitmap.Load
finally
ZStream.Free;
end;
finally
NewFile.Free;
end;
finally
InFile.Free;
end;
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.
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.
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.
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;
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;
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.loadf romstream?
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)
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)
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.
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.
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
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
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
ASKER
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