Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2022-06

Strange issue with TImage and lazarus 2.2.2

28 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luca Olivetti

Before reporting an issue, I wanted to ask.
I have a strange issue with TImage and lazarus 2.2.2: if (at designtime) I load a png or a jpg image in a TImage but at runtime it is blank. Worse, if I copy paste it, I get a streaming read error on Data (either when pasting or when running the program, the latter not always).

Only .ico seems to work with lazarus 2.2.2.

Now, if I open the same project in lazarus 2.0.12, the image is blank, I load a picture and it works.

Then I open the modified project with lazarus 2.2.2, at designtime the image is blank, but when the program is run I can see the image I loaded with lazarus 2.0.12.

I self build lazarus from the git sources, so maybe it is something in my environment.

I tested under both linux(qt5) and windows and the behavior is the same (the only difference is that under windows I use fpc 3.2.0 with lazarus 2.0.12 and 3.2.2 with 2.2.2, while under windows I use fpc 3.2.2 for both). Windows 32 bits and Linux 64 bits.

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti

El 23/6/22 a les 13:29, Luca Olivetti via lazarus ha escrit:

I tested under both linux(qt5) and windows and the behavior is the same (the only difference is that under windows I use fpc 3.2.0 with lazarus 2.0.12 and 3.2.2 with 2.2.2, while under windows I use fpc 3.2.2 for both). Windows 32 bits and Linux 64 bits.

That doesn't make sense: under *linux* I use the same fpc for both lazarus versions.

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti: Before reporting an issue, I wanted to ask. I have a strange issue with TImage and…

El 23/6/22 a les 13:29, Luca Olivetti via lazarus ha escrit:

I self build lazarus from the git sources, so maybe it is something in my environment.

I found the cause: it's the VampyreImaging library.

If I install it in the ide, it will stream png as "TImagingPNG" instead of "TPortableNetworkGraphic" but then it cannot read that format back (the method TPicture.ReadData doesn't find the corresponding class). I suppose it does the same for all other image type that the VampyreImaging library supports.

I just uninstalled it from the ide and left it as a dependency for the projects where I need it (that's what I did with the previous version of lazarus, maybe I encountered the same problem and forgot about it).

I don't understand why the ide prefers one class over the other, I guess they are all treated the same and the one registered last wins?

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Mattias Gaertner

El 23/6/22 a les 21:40, Mattias Gaertner via lazarus ha escrit:

Show quoted text 8 lines
On Thu, 23 Jun 2022 20:38:59 +0200 Luca Olivetti via lazarus wrote: > [...] > I don't understand why the ide prefers one class over the other, I > guess they are all treated the same and the one registered last wins? Correct. See TPicture.RegisterFileFormat

Not that it's going to matter now that I uninstalled the package, but why did it find the class for writing and not for reading it back? Also, once solved that, if it streams it using a class provided by a package, shouldn't the project have a dependency automatically added on that package?

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Mattias Gaertner
to Luca Olivetti
Show quoted text 16 lines
El 23/6/22 a les 21:40, Mattias Gaertner via lazarus ha escrit: > On Thu, 23 Jun 2022 20:38:59 +0200 > Luca Olivetti via lazarus wrote: > >> [...] >> I don't understand why the ide prefers one class over the other, I >> guess they are all treated the same and the one registered last >> wins? > > Correct. See TPicture.RegisterFileFormat Not that it's going to matter now that I uninstalled the package, but why did it find the class for writing and not for reading it back? Also, once solved that, if it streams it using a class provided by a package, shouldn't the project have a dependency automatically added on that package?

Both should read+write valid png files, otherwise there is a bug.

Are you sure, that the VampyreImaging lib is supposed to be installed in the IDE and to replace the default png TPicture?

Mattias

Reply by email

Luca Olivetti
to Mattias Gaertner

El 24/6/22 a les 0:19, Mattias Gaertner via lazarus ha escrit:

Show quoted text 6 lines
> but why did it find the class for writing and not for reading it back? > Also, once solved that, if it streams it using a class provided by a > package, shouldn't the project have a dependency automatically added > on that package? Both should read+write valid png files, otherwise there is a bug.

I was stepping though the method TPicture.ReadData(Stream: TStream) and I saw that GraphicClassName was "TImagingPNG" but the line

GraphicClass := GetPicFileFormats.FindClassName(GraphicClassName)

returned nil

Are you sure, that the VampyreImaging lib is supposed to be installed in the IDE and to replace the default png TPicture?

Actually I'm not, since it works fine for what I need without installing it, but in its options IDE Integration is marked as "Designtime and runtime".

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Werner Pamler
to Luca Olivetti

Vampyre has its own file format registration system. There is a class TImageFileFormat, and there is a list ImageFileFormats which stores the parameters for all known file formats. Each file format has a reader/writer unit, and these units add the file format to the ImageFileFormatsList if such a unit exists in a uses clause.

FPC has a similar registration system, it registeres its own reader/writers in a similar list, ImageHandlers.

Vampyre does not take care of the FPC image type registration. But that's not the problem...

To make things worse, LCL has another registration system for the image types known to TPicture. There is a list TPicFileFormatsList which stores pointers to TPicFileFormat records. The instance of this list, PicFileFormats, is accessible only via a factory function GetPicFileformats which is not accessible from the outside. The formats known to the TPicture are added in the constructor of TPicFileFormatsList, again fully hidden inside the picture.inc. It is my impression there is no way to register a new format in any way without modifying the sources of TPicture.

This is bad... In my opinion, the TPicture file format registration should be moved into the interface part of the graphics unit so that the user can add his own image formats. Then Vampyre could call GetPicFileFormats.Add and provide the information for its own readers/writers; if there are duplicate formats the old ones should be removed in the Add call.

Werner

Reply by email

Mattias Gaertner
to Werner Pamler
[...] It is my impression there is no way to register a new format in any way without modifying the sources of TPicture.
TPicture:
    class function SupportsClipboardFormat(FormatID: TClipboardFormat): Boolean;
    class procedure RegisterFileFormat(const AnExtension, ADescription: string;
      AGraphicClass: TGraphicClass);
    class procedure RegisterClipboardFormat(FormatID: TClipboardFormat;
      AGraphicClass: TGraphicClass);
    class procedure UnregisterGraphicClass(AClass: TGraphicClass);
    class function FindGraphicClassWithFileExt(const Ext: string;
      ExceptionOnNotFound: boolean = true): TGraphicClass;

Mattias

Reply by email

Luca Olivetti
to Werner Pamler: Vampyre has its own file format registration system. There is a class TImageFileFormat,…

[sorry for the top post, I'm answering from my phone]

I think it does, otherwise the TPicture in the TImage wouldn't be streamed as TImagingPNG. OTOH, if I read the TPicture code correctly, there's only one registration so I don't understand how it is possible that it finds the class for writing but not for reading.

24 jun. 2022 11:09:36 Werner Pamler via lazarus :

Vampyre does not take care of the FPC image type registration. But that's not the problem..

Reply by email

Werner Pamler
to Mattias Gaertner: On Fri, 24 Jun 2022 11:09:17 +0200 TPicture: class function…
Mattias Gaertner wrote 15 lines
On Fri, 24 Jun 2022 11:09:17 +0200 Werner Pamler via lazarus wrote: > [...] It is > my impression there is no way to register a new format in any way > without modifying the sources of TPicture. TPicture: class function SupportsClipboardFormat(FormatID: TClipboardFormat): Boolean; class procedure RegisterFileFormat(const AnExtension, ADescription: string; AGraphicClass: TGraphicClass); class procedure RegisterClipboardFormat(FormatID: TClipboardFormat; AGraphicClass: TGraphicClass); class procedure UnregisterGraphicClass(AClass: TGraphicClass); class function FindGraphicClassWithFileExt(const Ext: string; ExceptionOnNotFound: boolean = true): TGraphicClass;

Ah, of course. (I thought I had searched for "Register" in unit graphics...). Now I saw that Vampyre also uses these TPicture class methods to finally register their formats for TPicture. Thus, everything should be fine.

But still the situation is not very satisfying.

First observation after installing VampyreImagingPackageExt (the other package, VampyreImagingPackage, has no registration unit): I add TImage to a form and load the Lazarus "paw" to it. Works fine at designtime, but at runtime the image is empty. As the OP already noted Vampyre's TImagingPNG class is not found. This is because the Vampyre formats are registered only at designtime, but not at runtime of a project. But this can be fixed easily: After adding unit *ImagingComponents *to the uses clause, the "paw" is displayed at runtime, too.

Next complication comes into play if the user decides to uninstall Vampyre. The problem is that every graphic type writes its class name to the lfm file in front of the image data (Picture.Data). So, when a picture was loaded into TImage while Vampyre was installed all the images are brand-marked by the Vampyre classes, e.g. TImagingPNG rather than TPortableNetworkGraphic:

This is the part of the lfm written when Vampyre is installed (I am adding spaces to the hex data to see the digits:

? object Image1: TImage
??? Left = 8
??? Height = 344
??? Top = 8
??? Width = 456
??? Picture.Data = {
????? 0B 54 49 6D 61 67 69 6E 67 50 4E 47 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 01 C6
????? 11 T? I? m? a? g? i? n? g? P? N? G??????????????? // 11 is the length byte

An image written by the LCL without Vampyre contains this:

object Image1: TImage
??? Left = 24
??? Height = 284
??? Top = 20
??? Width = 376
??? Picture.Data = {
????? 17 54 50 6F 72 74 61 62 6C 65 4E 65 74 77 6F 72 6B 47 72 61 70 68 69 63 9A 3D 00 00 89 50 4E 47
????? 23 T? P? o? r? t? a? b? l? e? N? e? t? w? o? r? k? G? r a? p? h? i? c

When such a project is loaded into a Lazarus without Vampyre at first the VampyreImagingPackage and/or VampyreImagingPackageExt requirements must be removed from the project. But, of course, the Vampyre image class signatures are still in the lfm file, and the IDE refuses to load the form with this error:

??? Unable to find the component class "TForm1".
??? It is not registered via RegisterClass and no lfm was found. ??? It is needed by unit:
D:\Prog_Lazarus\tests\_images\vampyre\format_registration\vampyre_stripped\unit1.lfm

I think this is the most confusing part of that issue. If it would say "Unable to find class "TImagingPNG"" it would be much clearer.

However, I don't think that much can be done against that. There is always a risk when using third-party components that irreversible changes could occur. Hmm, well, somebody could write a tool the fix the image classname header in the lfm's Picture.Data.

Werner

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220624/4e75f1c0/attachment.htm>

Reply by email

Luca Olivetti
to Werner Pamler

El 24/6/22 a les 17:27, Werner Pamler via lazarus ha escrit:

Ah, of course. (I thought I had searched for "Register" in unit graphics...). Now I saw that Vampyre also uses these TPicture class methods to finally register their formats for TPicture. Thus, everything should be fine.

No, it isn't: it doesn't find the class when reading. When you copy and paste a TImage you'll have a stream read error, as well as when reopening the project.

But still the situation is not very satisfying.

Yes, I find it suboptimal that the picture format can be hijacked without adding a dependency on the needed package to correctly read it back. Of course it's my fault since I installed it in the ide without a real need, but I still think there's something wrong.

Show quoted text 6 lines
First observation after installing VampyreImagingPackageExt (the other package, VampyreImagingPackage, has no registration unit): I add TImage to a form and load the Lazarus "paw" to it. Works fine at designtime, but at runtime the image is empty. As the OP already noted Vampyre's TImagingPNG class is not found. This is because the Vampyre formats are registered only at designtime, but not at runtime of a project.

It doesn't even work at designtime (see above).

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Werner Pamler
to Luca Olivetti
Luca Olivetti wrote 9 lines
> First observation after installing VampyreImagingPackageExt (the > other package, VampyreImagingPackage, has no registration unit): I > add TImage to a form and load the Lazarus "paw" to it. Works fine at > designtime, but at runtime the image is empty. As the OP already > noted Vampyre's TImagingPNG class is not found. This is because the > Vampyre formats are registered only at designtime, but not at runtime > of a project. It doesn't even work at designtime (see above).

Try attached demo project. The "paw" image was inserted into a TImage after installation of Vampyre. All I had to do to get it working is to add Vampyre to the project requirements and to add ImagingComponents to the uses clause (or check the? box "Add package unit to uses section" in the package options, then the formats will be registered for runtime automatically).

Please note: I am not talking about the clipboard here, in fact I did not even investigate this because this is a different issue. -------------- next part --------------
A non-text attachment was scrubbed...
Name: vampyre_paw.zip
Type: application/x-zip-compressed
Size: 14543 bytes
Desc: not available
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220626/6a722bb8/attachment-0001.bin>

Reply by email

Luca Olivetti
to Werner Pamler

El 26/6/22 a les 1:08, Werner Pamler via lazarus ha escrit:

Show quoted text 8 lines
> It doesn't even work at designtime (see above). Try attached demo project. The "paw" image was inserted into a TImage after installation of Vampyre. All I had to do to get it working is to add Vampyre to the project requirements and to add ImagingComponents to the uses clause (or check the? box "Add package unit to uses section" in the package options, then the formats will be registered for runtime automatically).

With the VampyreImaginPackage 0.80 not installed in the ide, I can open the project, see a blank image and when I try to run it:

"Project project1 raised exception class 'EReadError' with message: Stream read error"

With the package installed I get the error as soon as I try to open the project (as well as when I try to run it).

I cannot install the VampyreImagingPackageExt

Warning: linker: /usr/bin/ld:
/home/luca/Datos/laz_2_2/onlinepackagemanager/packages/VampyreImaging/Packages/lib/VampyreImagingPackageExt/3.2.2/x86_64-linux/default/ZLibDelphi.o: undefined reference to symbol 'deflateInit_'

(in fact, I never installed it, yet it streamed the pictures as TImagingPMG)

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Werner Pamler

El 26/6/22 a les 11:36, Werner Pamler via lazarus ha escrit:

Show quoted text 5 lines
Am 26.06.2022 um 10:54 schrieb Luca Olivetti via lazarus: > VampyreImaginPackage 0.80 Mine is v0.82 which is the current version in OPM. According to their release notes there are changes related to PNG saving.

My online package manager only has 0.80, the repository is http://packages.lazarus-ide.org

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Werner Pamler
to Luca Olivetti
Luca Olivetti wrote 9 lines
El 26/6/22 a les 11:36, Werner Pamler via lazarus ha escrit: > Am 26.06.2022 um 10:54 schrieb Luca Olivetti via lazarus: >> VampyreImaginPackage 0.80 > > Mine is v0.82 which is the current version in OPM. According to their > release notes there are changes related to PNG saving. My online package manager only has 0.80, the repository is http://packages.lazarus-ide.org

Ah, I had installed the git version, and then OPM displays the installed version number...

You can find the author's github version (v0.82) at https://github.com/galfar/imaginglib (if you don't use git, you can download also a zip from there).

Reply by email

Luca Olivetti
to Werner Pamler

El 26/6/22 a les 13:44, Werner Pamler via lazarus ha escrit:

Show quoted text 18 lines
Am 26.06.2022 um 13:20 schrieb Luca Olivetti via lazarus: > El 26/6/22 a les 11:36, Werner Pamler via lazarus ha escrit: >> Am 26.06.2022 um 10:54 schrieb Luca Olivetti via lazarus: >>> VampyreImaginPackage 0.80 >> >> Mine is v0.82 which is the current version in OPM. According to their >> release notes there are changes related to PNG saving. > > My online package manager only has 0.80, the repository is > http://packages.lazarus-ide.org Ah, I had installed the git version, and then OPM displays the installed version number... You can find the author's github version (v0.82) at https://github.com/galfar/imaginglib (if you don't use git, you can download also a zip from there).

Even if version 0.82 solves the stream read error, the underlying problem is still there: it hijacks the format used for streaming TPicture but there is no dependency added to the projects when you add a TPicture.
I don't know if that's even possible, but it is a problem nevertheless.

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti: El 24/6/22 a les 0:19, Mattias Gaertner via lazarus ha escrit: I was stepping though the…

El 24/6/22 a les 9:48, Luca Olivetti via lazarus ha escrit:

Show quoted text 15 lines
El 24/6/22 a les 0:19, Mattias Gaertner via lazarus ha escrit: >> but why did it find the class for writing and not for reading it back? >> Also, once solved that, if it streams it using a class provided by a >> package, shouldn't the project have a dependency automatically added >> on that package? > > Both should read+write valid png files, otherwise there is a bug. I was stepping though the method TPicture.ReadData(Stream: TStream) and I saw that GraphicClassName was "TImagingPNG" but the line GraphicClass := GetPicFileFormats.FindClassName(GraphicClassName) returned nil

I'm puzzled: now I removed the vampyre lib from the ide, in a form I need ImagingComponent and ImagingClassed.
I drop a TPicture with a png image and it is time it is streamed as TPortableNetworkGraphic *but* FindClassName cannot find it.
How is that possible?

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti

El 30/6/22 a les 13:45, Luca Olivetti via lazarus ha escrit:

Show quoted text 6 lines
I'm puzzled: now I removed the vampyre lib from the ide, in a form I need ImagingComponent and ImagingClassed. I drop a TPicture with a png image and it is blank at runtime. This time it is streamed as TPortableNetworkGraphic *but* FindClassName cannot find it. How is that possible?

AAAAAAAGH Because the Vampyre library explicitly deletes it

   {$IFDEF COMPONENT_SET_LCL}
     // Unregister Lazarus? default PNG loader which crashes on some PNG
files
     TPicture.UnregisterGraphicClass(TPortableNetworkGraphic);
   {$ENDIF}

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Ondrej Pokorny
to Mattias Gaertner
Mattias Gaertner wrote 8 lines
On Fri, 24 Jun 2022 17:27:13 +0200 Werner Pamler via lazarus wrote: > [...] > But still the situation is not very satisfying. Maybe instead of the GraphicClass.ClassName the first extension can be written. That means, that an old IDE cannot read the graphic.

I did this already before: the next stable release should write the ClassName but support reading the extension and then the second stable release should write the extension.

With it we make sure that always the last 2 released version can read the LFM. That is enough.

Ondrej

Reply by email

Werner Pamler
to Mattias Gaertner: On Fri, 24 Jun 2022 17:27:13 +0200 Maybe instead of the GraphicClass.ClassName the first…
Mattias Gaertner wrote
Maybe instead of the GraphicClass.ClassName the first extension can be written. That means, that an old IDE cannot read the graphic.

This will break Delphi compatibility, i.e. forms with an image in which the Picture has been loaded by Delphi will not be readable by Lazarus any more, and vice versa. Just checked again the signature that Delphi writes to the begin of the Picture.Data: it's the class name, not the extension.

Show quoted text 6 lines
Or the vampyrlib defines type TPortableNetworkGraphic = class(TImagingPNG); and registers that in TPicture.

Yes, that might be a solution at first sight. But I don't know what happens when a project requires Vampyre (i.e. registers this new TPortableNetworkgraphic), but a unit has only the ordinary graphics unit in its uses clause, i.e. accesses the old TPortableNetworkGraphic.

Reply by email

Ondrej Pokorny
to Werner Pamler
Werner Pamler wrote 9 lines
Am 30.06.2022 um 15:11 schrieb Mattias Gaertner via lazarus: > Maybe instead of the GraphicClass.ClassName the first extension can be > written. > That means, that an old IDE cannot read the graphic. This will break Delphi compatibility, i.e. forms with an image in which the Picture has been loaded by Delphi will not be readable by Lazarus any more, and vice versa. Just checked again the signature that Delphi writes to the begin of the Picture.Data: it's the class name, not the extension.

And what about writing the extension to the data end?

??? Picture.Data = {
????? 0B 54 49 6D 61 67 69 6E 67 50 4E 47 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 01 C6
????? 11 T? I? m? a? g? i? n? g? P? N? G??????????????? // 11 is the length byte
????? 03 p? n? g

That should be both Delphi and legacy Lazarus compatible if the reader reads only the defined count of bytes for the classname?

Newer Lazarus versions would first search the extension and if not found they search for the classname.

Ondrej

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220630/3c1f32ac/attachment.htm>

Reply by email

Werner Pamler
to Ondrej Pokorny
Ondrej Pokorny wrote 23 lines
On 30.06.2022 16:54, Werner Pamler via lazarus wrote: > Am 30.06.2022 um 15:11 schrieb Mattias Gaertner via lazarus: >> Maybe instead of the GraphicClass.ClassName the first extension can be >> written. >> That means, that an old IDE cannot read the graphic. > This will break Delphi compatibility, i.e. forms with an image in > which the Picture has been loaded by Delphi will not be readable by > Lazarus any more, and vice versa. Just checked again the signature > that Delphi writes to the begin of the Picture.Data: it's the class > name, not the extension. And what about writing the extension to the data end? ??? Picture.Data = { ????? 0B 54 49 6D 61 67 69 6E 67 50 4E 47 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 01 C6 ????? 11 T? I? m? a? g? i? n? g? P? N? G??????????????? // 11 is the length byte ????? 03 p? n? g That should be both Delphi and legacy Lazarus compatible if the reader reads only the defined count of bytes for the classname?

But isn't this the same problem? When Vampyre is not installed, and the streamer sees the TImageingPNG classname there is no way how to find the end of the Picture.Data block.

Newer Lazarus versions would first search the extension and if not found they search for the classname.

Where's that? AFAICS, TPicture only looks for the classname. From Laz/main:

procedure TPicture.ReadData(Stream: TStream);
var
 ? GraphicClassName: Shortstring;
 ? NewGraphic: TGraphic;
 ? GraphicClass: TGraphicClass;
 ? ok: boolean;
begin
*? Stream.Read(GraphicClassName[0], 1);**
**? Stream.Read(GraphicClassName[1], length(GraphicClassName));*
 ? GraphicClass := GetPicFileFormats.FindClassName(GraphicClassName);
 ? NewGraphic := nil;
 ? if GraphicClass  nil then begin
 ??? NewGraphic := GraphicClass.Create;
 ??? ok:=false;
 ??? try
 ????? NewGraphic.ReadData(Stream);
 ????? ok:=true;
 ??? finally
 ????? if not ok then NewGraphic.Free;
 ??? end;
 ? end;
 ? FGraphic.Free;
 ? FGraphic := NewGraphic;
 ? if NewGraphic  nil then begin
 ??? NewGraphic.OnChange := @Changed;
 ??? NewGraphic.OnProgress := @Progress;
 ? end;
 ? Changed(Self);
end;
procedure TPicture.WriteData(Stream: TStream);
var
 ? GraphicClassName: ShortString;
begin
 ? with Stream do
 ? begin
 ??? if Graphic  nil then
 ????? GraphicClassName := Graphic.ClassName
 ??? else
 ????? GraphicClassName := '';
*??? Write(GraphicClassName, Length(GraphicClassName) + 1);*
 ??? if Graphic  nil then
 ????? Graphic.WriteData(Stream);
 ? end;
end;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220630/7fd78273/attachment-0001.htm>

Reply by email

Luca Olivetti
to Werner Pamler

El 30/6/22 a les 18:20, Werner Pamler via lazarus ha escrit:

But isn't this the same problem? When Vampyre is not installed, and the streamer sees the TImageingPNG classname there is no way how to find the end of the Picture.Data block.

Wouldn't it be better (if at all possible) to add a dependency on the unit that registered the class for streaming?

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email

Ondrej Pokorny
to Werner Pamler: But isn't this the same problem? When Vampyre is not installed, and the streamer sees the…
Werner Pamler wrote 28 lines
Am 30.06.2022 um 17:03 schrieb Ondrej Pokorny via lazarus: > On 30.06.2022 16:54, Werner Pamler via lazarus wrote: >> Am 30.06.2022 um 15:11 schrieb Mattias Gaertner via lazarus: >>> Maybe instead of the GraphicClass.ClassName the first extension can be >>> written. >>> That means, that an old IDE cannot read the graphic. >> This will break Delphi compatibility, i.e. forms with an image in >> which the Picture has been loaded by Delphi will not be readable by >> Lazarus any more, and vice versa. Just checked again the signature >> that Delphi writes to the begin of the Picture.Data: it's the class >> name, not the extension. > > And what about writing the extension to the data end? > > ??? Picture.Data = { > ????? 0B 54 49 6D 61 67 69 6E 67 50 4E 47 89 50 4E 47 0D 0A 1A 0A 00 > 00 00 0D 49 48 44 52 00 00 01 C6 > ????? 11 T? I? m? a? g? i? n? g? P? N? G??????????????? // 11 is the > length byte > ????? 03 p? n? g > > That should be both Delphi and legacy Lazarus compatible if the > reader reads only the defined count of bytes for the classname? > But isn't this the same problem? When Vampyre is not installed, and the streamer sees the TImageingPNG classname there is no way how to find the end of the Picture.Data block.

Oh yes, you are right. The ClassName is written in the beginning of the stream. From the sample I assumed it is written in the end but that doesn't make sense. My bad.

---

Well there is an easier solution. I just remembered that I added an image handler resolver TFPCustomImage.FindHandlerFromStream() to FPC three years ago: https://gitlab.com/freepascal.org/fpc/source/-/issues/33955

So if the ClassName is not found, the FP image handler can be found from the actual image stream. Every image format can be detected directly from the stream, so the ClassName is actually redundant. When we have the TIHData for the stream, then we have everything - the extension and the FP reader/writer. From this information we can find the LCL image handler from the registered list - of course only if at least /some/ handler is registered for the extension.

Of course, we are limited to the FPC version - I don't know if the feature is already in a released version. But we can add the support for the FPC versions with this feature.

Ondrej

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220630/39277e07/attachment.htm>

Reply by email

Luca Olivetti
to Luca Olivetti: El 30/6/22 a les 13:45, Luca Olivetti via lazarus ha escrit: AAAAAAAGH Because the…

El 30/6/22 a les 14:47, Luca Olivetti via lazarus ha escrit:

Show quoted text 17 lines
El 30/6/22 a les 13:45, Luca Olivetti via lazarus ha escrit: > I'm puzzled: now I removed the vampyre lib from the ide, in a form I > need ImagingComponent and ImagingClassed. > I drop a TPicture with a png image and it is blank at runtime. > This time it is streamed as TPortableNetworkGraphic *but* > FindClassName cannot find it. > How is that possible? AAAAAAAGH Because the Vampyre library explicitly deletes it ? {$IFDEF COMPONENT_SET_LCL} ??? // Unregister Lazarus? default PNG loader which crashes on some PNG files ??? TPicture.UnregisterGraphicClass(TPortableNetworkGraphic); ? {$ENDIF}

Two years later I forgot about this issue and I found it again with lazarus 3.2 and a freshly downloade vampyre imaging library (which is still at version 0.80 in the online package manager, though I see that the line is still there in the github repository).

Probably my fault for not reporting the issue to Vampyre, I just hope my memory serves me better next time.

Bye

Luca Olivetti Wetron Automation Technology https://wetron.es/ Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007

Reply by email