From 899463e5066c0e0e141bbc7aa93296c9318b8bc0 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sun, 2 Feb 2014 17:10:53 +0100 Subject: [PATCH] * fixed MemLeak in AssignFromLazIntfImage --- glBitmap.pas | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/glBitmap.pas b/glBitmap.pas index 2bbc6c1..1e95efa 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -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 -- 2.1.4