unit UBitmap; { Extented TBitmap object for Delphi 1.0 Added methods to load and save a compressed bitmap. Copyright © 1997 by Herbert J.Beemster. Questions, positive remarks, improvements etc. : herbertjb@compuserve.com Credits goes to: - Kurt Haenen for the LZRW1KH unit. - Dan English for the trick with the streams. - Danny Heijl for sample of using LZRW1KH. This piece of source is hereby donated to the public domain. Enjoy! } interface uses WinTypes, WinProcs, SysUtils, Classes, Graphics; type TLZRBitmap = class(TBitmap) public procedure LZRLoadFromFile( const Filename : string ); virtual; procedure LZRSaveToFile( const Filename : string ); virtual; end; {TLZRBitmap} implementation uses LZRW1KH; {Credits : Kurt Haenen} { unit can be in ARCHIVES.SWG !! } const ChunkSize = 32768; IOBufSize = (ChunkSize + 16); LZRWIdentifier : LONGINT = ((((((ORD('L') SHL 8)+ORD('Z')) SHL 8)+ORD('R')) SHL 8)+ORD('W')); var InStream : TMemoryStream; OutStream : TMemoryStream; procedure TLZRBitmap.LZRLoadFromFile( const Filename : string ); var Tmp, Identifier, OrigSize, SrcSize, DstSize : LongInt; SrcBuf, DstBuf : BufferPtr; begin try {Create InStream & OutStream} InStream := TMemoryStream.Create; OutStream := TMemoryStream.Create; {Create buffers for LZWR1KH} Getmem(SrcBuf, IOBufSize); Getmem(DstBuf, IOBufSize); {Load the compressed bitmap} InStream.LoadFromFile( Filename); InStream.Seek(0,0); {Decompress the lot...} {Read compression ID } InStream.Read( Identifier, SizeOf( LongInt)); {Read in uncompressed filesize } InStream.Read( OrigSize, SizeOf( LongInt)); DstSize := ChunkSize; SrcSize := 0; while (DstSize = ChunkSize) do begin {Read size of compressed block } Tmp := InStream.Read( SrcSize, SizeOf( Word)); {Read compressed block } InStream.Read( SrcBuf^, SrcSize); {Decompress block } DstSize := Decompression( SrcBuf, DstBuf, SrcSize); {Write decompressed block out to OutStream } OutStream.Write( DstBuf^, DstSize); end; {TBitmap thinks its loading from a file!} OutStream.Seek(0,0); LoadfromStream( OutStream); finally {Clean Up Memory} InStream.Free; OutStream.Free; Freemem( SrcBuf, IOBufSize); Freemem( DstBuf, IOBufSize); end; {try} end; {LZRLoadFromFile} procedure TLZRBitmap.LZRSaveToFile( const Filename : string ); var Size, CompIdentifier, SrcSize, DstSize : LongInt; SrcBuf, DstBuf : BufferPtr; begin try {Create InStream & OutStream} InStream := TMemoryStream.Create; OutStream := TMemoryStream.Create; {Create buffers for LZWR1KH} Getmem(SrcBuf, IOBufSize); Getmem(DstBuf, IOBufSize); {Save the bitmap to InStream} SaveToStream( InStream); InStream.Seek(0,0); {Compress the lot...} {Write out compression ID } CompIdentifier := LZRWIdentifier; OutStream.Write( CompIdentifier, SizeOf( LongInt)); {Write out uncompressed filesize } Size := InStream.Size; OutStream.Write( Size, SizeOf( LongInt)); SrcSize := ChunkSize; while (SRCSize = ChunkSize) do begin {Read a block of data } SrcSize := InStream.Read( SrcBuf^, ChunkSize); {Compress it } DstSize := Compression( SrcBuf, DstBuf, SrcSize); {Write out compressed size } OutStream.Write( DstSize, SizeOf( Word)); {Write out compressed data } OutStream.Write( DstBuf^, DstSize); end; {while} {Save compressed OutStream to file} OutStream.SaveToFile( Filename); finally {Clean Up Memory} InStream.Free; OutStream.Free; Freemem( SrcBuf, IOBufSize); Freemem( DstBuf, IOBufSize); end; {try} end; {LZRSaveToFile} end.