Hello,
I found a way to improve the performance of my code using scanline, but now I get a warning about missing portability. Are there any information available under which circumstances my code might fail? And is there a way to use my slower code as fallbacks for such platforms like using some {$IfDef <platform>}
Snippet from the slow code (Xorg uses 90% CPU, and my application 20% while executing):
sourcedata := obj.FirstChild.FirstChild.NodeValue;
InputStream := TStringStream.Create(sourcedata);
Decoder := TBase64DecodingStream.Create(InputStream);
readerPicture := TPortableNetworkGraphic.Create;
readerPicture.LoadFromStream(Decoder);
inputmaxX := readerPicture.Width;
inputmaxY := readerPicture.Height;
wptr := 0;
for y := 0 to (py-1) do begin
for x := 0 to (px-1) do begin
if (x < sx) and (y < sy) and (x < inputmaxX) and (y < inputmaxY) then begin
tempdata[wptr] := readerPicture.Canvas.pixels[x, y]; //more than 10x slower
end else begin //source image is smaller than target image -> fill with zeros
tempdata[wptr] := 0;
end;
inc(wptr);
if (wptr >= maxmem) then begin
showmessage('Error, Image' +getnodeident(obj)+ ' too big');
break;
end;
end;
if (wptr >= maxmem) then begin
break;
end;
end;
And ~28x faster (when running multiple instances at the same time):
sourcedata := obj.FirstChild.FirstChild.NodeValue;
InputStream := TStringStream.Create(sourcedata);
Decoder := TBase64DecodingStream.Create(InputStream);
readerPicture := TPortableNetworkGraphic.Create;
readerPicture.LoadFromStream(Decoder);
inputmaxX := readerPicture.Width;
inputmaxY := readerPicture.Height;
wptr := 0;
for y := 0 to (py-1) do begin
if (y < inputmaxY) then begin
ScanData := readerPicture.ScanLine[y];
end;
for x := 0 to (px-1) do begin
if (x < sx) and (y < sy) and (x < inputmaxX) and (y < inputmaxY) then begin
if (scanData <> nil) then begin
r := ScanData^.rgbRed;
g := ScanData^.rgbGreen;
b := ScanData^.rgbBlue;
inc(ScanData);
tempdata[wptr] := (b shl 16) or (g shl 8) or r;
end else begin //fallback
tempdata[wptr] := readerPicture.Canvas.pixels[x, y]; //more than 10x slower
end;
end else begin //source image is smaller than target image -> fill with zeros
tempdata[wptr] := 0;
end;
inc(wptr);
if (wptr >= maxmem) then begin
showmessage('Error, Image' +getnodeident(obj)+ ' too big');
break;
end;
end;
if (wptr >= maxmem) then begin
break;
end;
end;