Page 1 of 1

Blob field (images) and ZLib

Posted: 25.09.2005, 23:42
by aperger
Hello,

I use the following codes to read and write blob field with ZeOS, but are not working (PostreSQL 8.0.3 with libpq74.dll, FireBird 1.5.x) with the latest CVS version. It was working in 6.1.5 and 6.5.1-alpha (2004-11-14).
I tested it with ADO connection(MS SQL szerver 7), it was working with all version of ZeOS!!! :-(

The problem is: if the image is big (= not a small logo), the content of the image is wrong (mixed pixels), or if I use Zlib compression an error raise when I read it back!

[syntax="delphi"]
// (De-)Compress functions
procedure CompressStream(aSource,aTarget:TStream);
var
compStream:TCompressionStream;
begin
compStream:=TCompressionStream.Create(clFastest,aTarget);
try
aSource.Position:=0;
compStream.CopyFrom(aSource,aSource.Size);
compStream.CompressionRate;
finally
compStream.Free;
end;
end;

procedure DecompressStream(aSorce,aTarget:TStream);
var
decompStream:TDecompressionStream;
nRead:integer;
Buffer:array[0..1023] of Char;
Count:integer;
begin
decompStream:=TDecompressionStream.Create(aSorce);
try
if aSorce.Size > 0 then begin
decompStream.Position:=0;
Count:=1024;
repeat

try
nRead:=decompStream.Read(Buffer,Count);
except
on E:Exception do begin
raise Exception.Create('Decompression error when write it to stream!');
end;
end;

try
aTarget.WriteBuffer(Buffer,nRead);
except
on E:Exception do begin
raise Exception.Create('Decompression error when write it to stream!');
end;
end;

until nRead=0;
end;
finally
decompStream.Free;
end;
end;

(****************************************************)

procedure ReadBlobField(ImageField:TBlobField;Image:TImage;DeCompress:boolean);
var
memoStream:TMemoryStream;
compStream:TMemoryStream;
begin
if ImageField.IsNull then begin
memoStream:=TMemoryStream.Create;
Image.AutoSize:=true;
Image.Picture.Bitmap.LoadFromStream(memoStream);
Image.AutoSize:=false;
exit;
end;

memoStream:=TMemoryStream.Create;
if DeCompress then compStream:=TMemoryStream.Create else compStream:=nil;

try
// blob reading

try
if DeCompress then begin
ImageField.SaveToStream(compStream);
compStream.Position:=0;
DecompressStream(compStream,memoStream);
end else begin
ImageField.SaveToStream(memoStream);
end;
except
on E:Exception do begin
ShowPSError('Blob field reading error: '+#13+E.Message);
memoStream.Size:=0;
if DeCompress then compStream.Size:=0;
end;
end;


try
Image.AutoSize:=true;
memoStream.Position:=0;
Image.Picture.Bitmap.FreeImage;
Image.Picture.Bitmap.Dormant;
if memoStream.Size>0 then begin
memoStream.Position:=0;
Image.Picture.Bitmap.LoadFromStream(memoStream);
end;
Image.AutoSize:=false;
except
on E:Exception do ShowPSError('Image creating error: '+#13+E.Message);
end;
finally
memoStream.Free;
if DeCompress then compStream.Free;
end;
end;

procedure WriteBlobParam(ImageParam:TParam;Image:TImage;Compress:boolean);

var
memoStream:TMemoryStream;
compStream:TMemoryStream;
begin
if not Image.Visible then exit;

memoStream:=TMemoryStream.Create;
if Compress then compStream:=TMemoryStream.Create else compStream:=nil;
try
Image.Picture.Bitmap.SaveToStream(memoStream);
if memoStream.Size=0 then begin
ImageParam.Value:=null;
ImageParam.LoadFromStream(memoStream,ImageParam.DataType);
end else begin
// memoStream.Size;
memoStream.Position:=0;
if Compress then begin
CompressStream(memoStream,compStream);
compStream.Position:=0;
ImageParam.LoadFromStream(compStream,ImageParam.DataType);
end else begin
memoStream.Position:=0;
ImageParam.LoadFromStream(memoStream,ImageParam.DataType);
end;
memoStream.Position:=0;
end;
finally
memoStream.Free;
if Compress then compStream.Free
end;
end;
[/syntax]

Can somebody help? At the moment I am planing to upgarde from D7+ZeOS 6.5.1-alpha-2004-11-14 to D2005-ZeOS-CVS-2005-09-23.


THANX

Attila

Posted: 06.10.2005, 11:49
by skozan
I experienced the same exactly behaviour with Postgres 8.0 / Delphi 7 / Zlib. I used before the 6.1.5 version of Zeos. Now I am testing to retrieve compressed data using the recent 6.5.1, stored in blobs (bytea) with the previous version of ZeosLib (6.1.5), but an exception is raised when I try to read from the Decompression Stream.

I have also some pictures. Most of the pictures stored in bytea are shown properly using the TDBPicture control, some others not.

Here is the procedure that raises the exception:

Code: Select all

procedure DecompressStream(AIn, AOut: TStream; AOnProgress: TNotifyEvent);
var
  x: TDecompressionStream;
  buf: packed array[Word] of Byte;
  read_in: Integer;
begin
  x := nil;
  try
    x := TDecompressionStream.Create(AIn);
    x.OnProgress := AOnProgress;
    repeat
      read_in := x.Read(buf, SizeOf(buf));  //<<<The exception raises here
      if read_in > 0 then
        AOut.Write(buf, read_in);
    until read_in < SizeOf(buf);
  finally
    x.Free;
  end;
end;