Ignore:
Timestamp:
Feb 1, 2012, 3:02:33 PM (13 years ago)
Author:
chronos
Message:
  • Modified: Updated BGRABitmap package to version 5.5.
  • Modified: Removed draw method ComboBox and reorganized method list to single listview with using ownerdraw facility.
  • Added: New draw method TBitmap.RawImage.Data Move which use fast Move operation. It requires same pixel format.
  • Added: New draw method Dummy for comparion of empty method and to determine possibily max frame rate limit.
Location:
GraphicTest/BGRABitmap
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/BGRABitmap

    • Property svn:ignore set to
      lib
  • GraphicTest/BGRABitmap/bgracompressablebitmap.pas

    r210 r317  
    1 unit bgracompressablebitmap;
     1unit BGRACompressableBitmap;
    22
    33{$mode objfpc}{$H+}
    44
    55interface
     6
     7{ This unit contains the TBGRACompressableBitmap class, which
     8  can be used to temporarily compress bitmaps in memory.
     9  To use it, create an instance with the bitmap you want
     10  to compress. You can then free the original bitmap because
     11  TBGRACompressableBitmap contains all information necessary
     12  to build it again. To construct again your bitmap, call
     13  the GetBitmap function.
     14
     15  When you have your bitmap in TBGRACompressableBitmap,
     16  you can call Compress function as many times as necessary
     17  until all data is compressed. It does only a part of the
     18  work at each call, so you can put it in a loop or in
     19  a timer. When it's done, Compress returns false to
     20  notify that it did nothing, which means you can
     21  stop calling Compress.
     22
     23  In this implementation, the memory usage grows during
     24  the compression process and is lower only after it is
     25  finished. So it is recommended to compress one bitmap
     26  at a time. }
    627
    728uses
     
    1637     FWidth,FHeight: integer;
    1738     FCaption: String;
     39     FBounds: TRect;
    1840     FCompressedDataArray: array of TMemoryStream;
    1941     FUncompressedData: TMemoryStream;
     
    2547     constructor Create(Source: TBGRABitmap);
    2648     function GetBitmap: TBGRABitmap;
    27      function Compress: boolean;
     49     
     50     //call Compress as many times as necessary
     51     //when it returns false, it means that
     52     //the image compression is finished
     53     function Compress: boolean;
     54     
    2855     function UsedMemory: Int64;
    2956     procedure Assign(Source: TBGRABitmap);
     
    3865uses zstream, BGRABitmapTypes;
    3966
    40 const maxPartSize = 1048576;
     67// size of each chunk treated by Compress function
     68const maxPartSize = 524288;
    4169
    4270{ TBGRACompressedBitmap }
     
    6391end;
    6492
     93{ Constructs the bitmap again, decompressing if necessary.
     94  After this, the image is not compressed anymore so the
     95  memoy usage grows again and the access becomes fast
     96  because there is no need to decompress anymore. }
    6597function TBGRACompressableBitmap.GetBitmap: TBGRABitmap;
     98var UsedPart: TBGRABitmap;
     99    UsedNbPixels: Integer;
    66100begin
    67101  Decompress;
     
    74108  result.Caption := FCaption;
    75109  FUncompressedData.Position := 0;
    76   FUncompressedData.Read(result.Data^,result.NbPixels*Sizeof(TBGRAPixel));
    77 end;
    78 
     110  if (FBounds.Left <> 0) or (FBounds.Top <> 0)
     111    or (FBounds.Right <> FWidth) or (FBounds.Bottom <> FHeight) then
     112  begin
     113    UsedNbPixels := (FBounds.Right-FBounds.Left)*(FBounds.Bottom-FBounds.Top);
     114    if UsedNbPixels > 0 then
     115    begin
     116      UsedPart := TBGRABitmap.Create(FBounds.Right-FBounds.Left,FBounds.Bottom-FBounds.Top);
     117      FUncompressedData.Read(UsedPart.Data^,UsedPart.NbPixels*Sizeof(TBGRAPixel));
     118      result.PutImage(FBounds.Left,FBounds.Top,UsedPart,dmSet);
     119      UsedPart.Free;
     120    end;
     121  end else
     122    FUncompressedData.Read(result.Data^,result.NbPixels*Sizeof(TBGRAPixel));
     123end;
     124
     125{ Returns the total memory used by this object for storing bitmap data }
    79126function TBGRACompressableBitmap.UsedMemory: Int64;
    80127var i: integer;
     
    86133end;
    87134
     135{ Do one compress step or return false }
    88136function TBGRACompressableBitmap.Compress: boolean;
    89137var comp: Tcompressionstream;
     
    91139begin
    92140  if FCompressedDataArray = nil then FCompressionProgress := 0;
    93   if FUncompressedData = nil then
     141  if (FUncompressedData = nil) or (FUncompressedData.Size = 0) then
    94142  begin
    95143    result := false;
     
    104152      partSize := maxPartSize else
    105153        partSize := integer(FUncompressedData.Size - FCompressionProgress);
     154
     155    //use fast compression to avoid slowing down the application
    106156    comp := Tcompressionstream.Create(clfastest,FCompressedDataArray[high(FCompressedDataArray)]);
    107157    comp.write(partSize,sizeof(partSize));
     
    136186end;
    137187
     188{ Free all data }
    138189procedure TBGRACompressableBitmap.FreeData;
    139190var i: integer;
     
    148199end;
    149200
     201{ Copy a bitmap into this object. As it is copied, you need not
     202  keep a copy of the source }
    150203procedure TBGRACompressableBitmap.Assign(Source: TBGRABitmap);
     204var
     205  UsedPart: TBGRABitmap;
     206  NbUsedPixels: integer;
    151207begin
    152208  FreeData;
     
    161217  FHeight := Source.Height;
    162218  FCaption := Source.Caption;
     219  FBounds := Source.GetImageBounds([cRed,cGreen,cBlue,cAlpha]);
     220  NbUsedPixels := (FBounds.Right-FBounds.Left)*(FBounds.Bottom-FBounds.Top);
    163221  FUncompressedData := TMemoryStream.Create;
    164   FUncompressedData.Write(Source.Data^,Source.NbPixels*Sizeof(TBGRAPixel));
     222  if NbUsedPixels = 0 then exit;
     223
     224  if (FBounds.Left <> 0) or (FBounds.Top <> 0)
     225    or (FBounds.Right <> Source.Width) or (FBounds.Bottom <> Source.Height) then
     226  begin
     227    UsedPart := Source.GetPart(FBounds) as TBGRABitmap;
     228    FUncompressedData.Write(UsedPart.Data^,NbUsedPixels*Sizeof(TBGRAPixel));
     229    UsedPart.Free;
     230  end else
     231    FUncompressedData.Write(Source.Data^,Source.NbPixels*Sizeof(TBGRAPixel));
    165232end;
    166233
Note: See TracChangeset for help on using the changeset viewer.