An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180421/3b15536b/attachment.html>
Mailing lists / lazarus / 2018-04
A bitmap strange issue
11 messages · 6 people · –
- GGiuliano Colla 5
- OOndrej Pokorny 2
- LLuca Olivetti 1
- MMattias Gaertner 1
- MMichael Van Canneyt 1
- VVojtěch Čihák 1
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
El 21/04/18 a les 17:18, Giuliano Colla via Lazarus ha escrit:
Show quoted text 6 lines
If you follow the implementation of Image1.Picture.LoadFromFile you'll see that it frees the current bitmap, that's the cause of the sigsev. If you want to save the bitmap for later use, you should probably make a copy instead.
Show quoted text 10 lines
And this assignment makes a copy of MyBitmap
> //MyBitmap.FreeImage; Useless FreeAndNil(MyBitmap); end;
Bye
Hi,
@ MyBitmap := Image1.Picture.Bitmap;
This line only copies pointer, but Image1.Picture.Bitmap belongs to Image1 and it should care itself. If you need copy of the bitmap you shoud use:
MyBitmap.Assign(Image1.Picture.Bitmap);
V.
Il 21/04/2018 18:07, Vojtěch Čihák via Lazarus ha scritto:
Show quoted text 5 lines
That's what I had guessed, but this means that there's a patent inconsistency, as shown in the Button2Click part of my test:
Image1.Picture.Bitmap := MyBitmap; FreeAndNil(MyBitmap);
doesn't generate any error. If I don't free MyBitmap I see a memory leakage in heaptrc.
IOW
Image1.Picture.Bitmap := MyBitmap;performs an implicit assign, creating a new Bitmap Object for Image1.
The apparently symmetrical
MyBitmap := Image1.Picture.Bitmap;just copies the pointer. Timage.Picture.GetBitmap and TImage.Picture.SetBitmap do not follow the same logic.
All of this is maybe somewhat Delphi compatible. Actually Delphi (Rad Studio 10.1) doesn't generate a SIGSEV with the same code, but rather just an "Illegal Pointer Operation" warning. However IMO it still remains quite inconsistent.
Giuliano
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180422/b1c265e3/attachment.html>
Giuliano Colla wrote 25 lines
This is how all properties that are TPersistent descendents work, so this behaviour should not come as a surprise.
Michael.
Il 21/04/2018 18:07, Vojtěch Čihák via Lazarus ha scritto: That's what I had guessed,…
Giuliano Colla wrote 23 lines
Do you really mean that
Image1.Picture.Bitmap.SomeProperty := SomeValue;
should apply SomeProperty := SomeValue on a copied object of Bitmap and
produce a memory leak?And the same, that
Image1.Picture.Bitmap := Image2.Picture.Bitmap;
should produce a memory leak because of the temporary bitmap object?
...and taking it into detail because Picture is a property of TImage as well:
Image1.Picture.Bitmap := Image2.Picture.Bitmap;
would actually produce 3 memory leaks: 2x TPicture and 1x TBitmap.
Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180422/030e0b46/attachment.html>
Il 22/04/2018 13:49, Ondrej Pokorny via Lazarus ha scritto:
Do you really mean that Image1.Picture.Bitmap.SomeProperty := SomeValue; should apply SomeProperty := SomeValue on a copied object of Bitmap and produce a memory leak?
No, I mean that like
Image1.Picture.Bitmap := SomeBitmap;actually executes a
Image1.Picture.Bitmap.assign(SomeBitmap);(see TPicture.SetGraphic called by TPicture.SetBitmap in picture.inc), so
SomeBitmap := Image1.Picture.BItmap;should execute (with proper checks)
SomeBitmap.assign(Image1.Picture.Bitmap);I speak about manipulating the Tpicture.Bitmap property itself, not the TBitmap properties, which would not be affected.
Giuliano
This is how all properties that are TPersistent descendents work, so this behaviour…
Il 22/04/2018 13:22, Michael Van Canneyt via Lazarus ha scritto:
This is how all properties that are TPersistent descendents work, so this behaviour should not come as a surprise.
I wouldn't say so.
E.g. TCanvas is a TPersistent descendent, but the Canvas property of a TCustomControl is declared like that:
property Canvas: TCanvas read FCanvas write FCanvas;
This means that after a
SomeControl.Canvas := MyCanvas;or
MyCanvas := SomeControl.Canvas;SomeControl.Canvas and MyCanvas will be the same object. Only a pointer is copied.
On the contrary, the property Bitmap of a TPicture is declare like that:
property Bitmap: TBitmap read GetBitmap write SetBitmap;
where GetBitmap actually returns the TPicture.Bitmap Object, while SetBitmap creates a different Bitmap Object, and assigns it the content of the supplied bitmap (see TPicture.SetGraphic, called by TPicture.SetBitmap).
This means that after a
MyBitmap := SomePicture.Bitmap;MyBitmap and SomePicture.Bitmap will represent the same Object, while after a
SomePicture.Bitmap := MyBitmap;MyBitmap and SomePicture.Bitmap will represent different Objects.
This is IMHO a TPicture specific inconsistency.
Giuliano
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180422/3ce63141/attachment.html>
Il 22/04/2018 13:49, Ondrej Pokorny via Lazarus ha scritto: No, I mean that like…
Show quoted text 9 lines
And what to do with
W := Image1.Picture.BItmap.Width?Mattias
Il 22/04/2018 17:39, Mattias Gaertner via Lazarus ha scritto:
And what to do with W := Image1.Picture.BItmap.Width?
You're right, there's no easy way out.
The original sin has been maybe to call Bitmap a TPicture property which isn't really a TBitmap, as the GetBitmap and SetBitmap methods show. This makes it easy to put any image into a picture, but creates unavoidable inconsistencies.
Giuliano
Il 22/04/2018 13:49, Ondrej Pokorny via Lazarus ha scritto: No, I mean that like…
Giuliano Colla wrote 22 lines
You can definitely do this - but not on on the Image1.Picture side and on the other side - SomeBitmap:
property SomeBitmap: TBitmap read GetSomeBitmap write SetSomeBitmap;-> implement SetSomeBitmap to execute .Assign() and you are good.
Ondrej
