* fixed MemLeak in AssignFromLazIntfImage
authorBergmann89 <bergmann89@muo-game.de>
Sun, 2 Feb 2014 16:10:53 +0000 (17:10 +0100)
committerBergmann89 <bergmann89@muo-game.de>
Sun, 2 Feb 2014 16:10:53 +0000 (17:10 +0100)
glBitmap.pas

index 2bbc6c1..1e95efa 100644 (file)
@@ -4968,6 +4968,42 @@ var
   FormatDesc: TFormatDescriptor;
   ImageData: PByte;
   ImageSize: Integer;
+  CanCopy: Boolean;
+
+  procedure CopyConvert;
+  var
+    bfFormat: TbmpBitfieldFormat;
+    pSourceLine, pDestLine: PByte;
+    pSourceMD, pDestMD: Pointer;
+    x, y: Integer;
+    pixel: TglBitmapPixelData;
+  begin
+    bfFormat  := TbmpBitfieldFormat.Create;
+    with aImage.DataDescription do begin
+      bfFormat.RedMask   := ((1 shl RedPrec)   - 1) shl RedShift;
+      bfFormat.GreenMask := ((1 shl GreenPrec) - 1) shl GreenShift;
+      bfFormat.BlueMask  := ((1 shl BluePrec)  - 1) shl BlueShift;
+      bfFormat.AlphaMask := ((1 shl AlphaPrec) - 1) shl AlphaShift;
+      bfFormat.PixelSize := BitsPerPixel / 8;
+    end;
+    pSourceMD := bfFormat.CreateMappingData;
+    pDestMD   := FormatDesc.CreateMappingData;
+    try
+      for y := 0 to aImage.Height-1 do begin
+        pSourceLine := aImage.PixelData + y * aImage.DataDescription.BytesPerLine;
+        pDestLine   := ImageData        + y * Round(FormatDesc.PixelSize * aImage.Width);
+        for x := 0 to aImage.Width-1 do begin
+          bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
+          FormatDesc.Map(pixel, pDestLine, pDestMD);
+        end;
+      end;
+    finally
+      FormatDesc.FreeMappingData(pDestMD);
+      bfFormat.FreeMappingData(pSourceMD);
+      bfFormat.Free;
+    end;
+  end;
+
 begin
   result := false;
   if not Assigned(aImage) then
@@ -4986,10 +5022,17 @@ begin
   if (f = tfEmpty) then
     exit;
 
+  CanCopy :=
+    (Round(FormatDesc.PixelSize * 8)     = aImage.DataDescription.Depth) and
+    (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
+
   ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
   ImageData := GetMem(ImageSize);
   try
-    Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
+    if CanCopy then
+      Move(aImage.PixelData^, ImageData^, ImageSize)
+    else
+      CopyConvert;
     SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
   except
     if Assigned(ImageData) then