.
   Subject: Re: Bug in TBitmap for RLE-encoded bmp's
      Date: Fri, 3 Jul 1998 11:29:30 +0100
      From: "David Willis" <david.willis@intellexis.com>
Newsgroups: borland.public.delphi.graphics
 

There is a leak of a Bitmap handle in TBitmap.ReadDIB for RLE bitmaps in
graphics.pas. It is still there in Delphi 4 for which I have a fix below.
Same fix lines apply to Delphi 3 code although there have been some other
code adjustments to the function.

I have a {$DEFINE FIXES} at the top of my replacement graphics.pas. Look out
for the {$IFDEF FIXES} conditional defines in the code below for fixed
lines.

Hope this helps, it took me a long time to pinpoint this.

David


procedure TBitmap.ReadDIB(Stream: TStream; ImageSize: LongWord);
const
  DIBPalSizes: array [Boolean] of Byte = (sizeof(TRGBQuad),
sizeof(TRGBTriple));
var

  ..... Lines chopped ....

  {$IFDEF FIXES}
    ABmHandle: HBITMAP;  //David Willis
  {$ENDIF}
begin

  ..... Lines chopped ....
 

    DC := GDICheck(GetDC(0));
    try
      if (bmiHeader.biCompression = BI_RLE8)
        or (bmiHeader.biCompression = BI_RLE4) or DDBsOnly then
      begin
        MemDC := 0;

        {$IFDEF FIXES}
          ABmHandle := 0;    //David Willis
        {$ENDIF}

        GetMem(BitsMem, ImageSize);
        try
          Stream.ReadBuffer(BitsMem^, ImageSize);
          MemDC := GDICheck(CreateCompatibleDC(DC));

          {$IFDEF FIXES}
            ABmHandle := CreateCompatibleBitmap(DC, 1, 1); //David Willis
            DeleteObject(SelectObject(MemDC, ABmHandle)); //David Willis
          {$ELSE}
            DeleteObject(SelectObject(MemDC, CreateCompatibleBitmap(DC, 1,1)));  //Original line
          {$ENDIF}

          OldPal := 0;
          if bmiHeader.biClrUsed > 0 then
          begin
            Pal := PaletteFromDIBColorTable(0, ColorTable,bmiHeader.biClrUsed);
            OldPal := SelectPalette(MemDC, Pal, False);
            RealizePalette(MemDC);
          end;

          try
            BMHandle := CreateDIBitmap(MemDC, BitmapInfo^.bmiHeader,
                                       CBM_INIT, BitsMem,
                                       BitmapInfo^, DIB_RGB_COLORS);
            if (BMHandle = 0) then
              if GetLastError = 0 then
                InvalidBitmap
              else
                RaiseLastWin32Error;
          finally
            if OldPal <> 0 then
              SelectPalette(MemDC, OldPal, True);
          end;
        finally
          if MemDC <> 0 then DeleteDC(MemDC);

          {$IFDEF FIXES}
            if ABmHandle <> 0 then DeleteObject(ABmHandle); //David Willis
          {$ENDIF}

          FreeMem(BitsMem);
        end;
      end

....  Rest of function unchanged ...



guy wrote in message <359CA1C9.64A316BD@arbed-rech-isdn1.restena.lu>...
>Hi,
>
>I've found a bug in TBitmap for RLE-encoded bmp's. When I load such a
>bmp in an TImage I can make the IDE crash silently. (and if you've saved
>the project code it will crash upon startup).
>
>Here is what I do
>
>1. Create a new project.
>2. Put a TImage on the form.
>3. Load a RLE-encoded bitmap.
>4. Right click on the form -> View as text
>5. Right click on the editor window - > View as form
>
>at this point there is an error in the first scanlines of the picture or
>the IDE crashes.
>To make the IDE crash for sure repeat steps 4-5.
>
>What I figured out for the moment is, that there is an error in the
>streaming procedures for DIB's. At some point the image size may get
>negative, (because the stored image data is smaller than the unpacked
>image) and this error is not detected by the VCL. But this cannot be the
>whole story because the bug appears regardless of the image size. I'm
>not sure if the error appears with EVERY bitmap but I have found it for
>all the bitmaps I tested.
>
>Someone has an idea???
>
>Best regards
>Guy Fink
TP-links