You are not logged in.
Pages: 1
Unit: mormot.ui.gdiplus
For Delphi 10.2 and higher the function CanLoadFromStream() must be defined, otherwise the following source code will not work:
Image.Picture.LoadFromStream(Stream);
PNG documentation is here. Required changes:
TPngImage = class(TSynPicture)
public
{$ifdef ISDELPHI102}
class function CanLoadFromStream(pmStream: TStream): Boolean; override;
{$endif}
end;
{ TPngImage }
{$ifdef ISDELPHI102}
class function TPngImage.CanLoadFromStream(pmStream: TStream): Boolean;
type
TPngSignature = array[0..7] of AnsiChar;
const
PNG_SIGNATURE: TPngSignature = (#137, #80, #78, #71, #13, #10, #26, #10);
var
pos: Int64;
sig: TPngSignature;
begin
pos := pmStream.Position;
try
Result := (pmStream.Read(sig, SizeOf(TPngSignature)) = SizeOf(TPngSignature));
if Result then
Result := CompareMemSmall(@sig[0], @PNG_SIGNATURE[0], SizeOf(TPngSignature));
finally
pmStream.Position := pos;
end;
end;
{$endif}
With best regards
Thomas
Offline
I didn't know about this new method.
Why can't we just let CanLoadFromStream() always return true, and let the regular behavior be used?
For instance, a TSynPicture is not limited to PNG or any single format.
Please try https://github.com/synopse/mORMot2/commit/0d874d18
Offline
Why can't we just let CanLoadFromStream() always return true, and let the regular behavior be used?
I think the change can't work because it's defined that way:
procedure TPicture.LoadFromStream(Stream: TStream);
...
GraphicClass := FileFormats.FindFormat(Stream);
...
end;
function TFileFormatsList.FindFormat(Stream: TStream): TGraphicClass;
var
I: Integer;
begin
for I := Count - 1 downto 0 do
with TFileFormatType(Items[I]) do
if GraphicClass.CanLoadFromStream(Stream) then
begin
Result := GraphicClass;
Exit;
end;
Result := nil;
end;
With best regards
Thomas
Last edited by tbo (2022-06-13 17:40:43)
Offline
Make sense!
Please try https://github.com/synopse/mORMot2/commit/2c1829af
Offline
Thank you very much. But shouldn't the name of the function CanLoadFromMemory() rather be:
class function CheckFileSignature(pmFirst4Bytes: Cardinal): Boolean; virtual;
Following this Wikipedia article: List of file signatures. Ok, English is not my language, but with the name CanLoadFromMemory() I didn't know what to expect. Of course, I could be completely wrong.
With best regards
Thomas
Offline
I followed the Delphi method logic.
Otherwise, the Delphi method should be renamed CheckStreamSignature().
The name of the function CanLoadFromStream(pmStream: TStream) is correct, because a stream is passed as parameter. You can use any part of the stream for your check and there may be other reasons for not loading. The function CanLoadFromMemory(first4: cardinal) is a class function and only the first four bytes are passed. For me, the functionality of this function is not necessarily apparent from the name.
But that is only theory. Much more interesting is: If you better use the mormot.ui.gdiplus unit instead of the Vcl.Imaging.pngimage, saving a 2MB PNG image takes 9 ms vs. 900 ms with the Delphi unit. Loading is done in 10 ms instead of 80 ms. I should probably mention that the images are AES encrypted (TAesPkcs7Reader/TAesPkcs7Writer) and stored in a zip file. These are the facts why I like mORMot so much. Many thanks for that.
With best regards
Thomas
Offline
Pages: 1