Ich habe einige sehr einfache Änderungen vorgenommen. Bei mir benötigt der Algorithmus dann nur noch die halbe Zeit. Das Ergebnis ist nicht identisch mit dem alten Algorithmus. Die Ursache liegt meiner Meinung nach im Floatingpoint-Rundungsalgorithmus begründet. Das Bild sieht aber nicht offensichtlich falsch aus.
Delphi-Quellcode:
procedure Draw32BitToBitmapSamso(const BitOben: TBitmap; BitUnten: TBitmap);
var
h, w, i: Integer;
RGBA_Unten, RGBA_Oben: PRGBQuad;
begin
for h := 0 to BitUnten.Height-1 do begin
RGBA_Unten := BitUnten.ScanLine[h];
RGBA_Oben := BitOben.ScanLine[h];
For w:= 0 to BitUnten.Width-1 do begin
if RGBA_Oben^.rgbReserved = 0 then begin
// unten bleibt
end else begin
i := RGBA_Unten^.rgbBlue - (RGBA_Unten^.rgbBlue - RGBA_Oben^.rgbBlue) * RGBA_Oben^.rgbReserved div 256;
if i < 0 then RGBA_Unten^.rgbBlue := 0 else RGBA_Unten^.rgbBlue := i;
i := RGBA_Unten^.rgbGreen - (RGBA_Unten^.rgbGreen - RGBA_Oben^.rgbGreen) * RGBA_Oben^.rgbReserved div 256;
if i < 0 then RGBA_Unten^.rgbGreen := 0 else RGBA_Unten^.rgbGreen := i;
i := RGBA_Unten^.rgbRed - (RGBA_Unten^.rgbRed - RGBA_Oben^.rgbRed) * RGBA_Oben^.rgbReserved div 256;
if i < 0 then RGBA_Unten^.rgbRed := 0 else RGBA_Unten^.rgbRed := i;
RGBA_Unten^.rgbReserved := 255;
end;
inc(RGBA_Unten); inc(RGBA_Oben);
end;
end;
end;