Umwandeln in 32 Bit und dann damit arbeiten macht den Code natürlich einfacher. (kein Align und Dergleichen)
Und das Kopieren der Pixel düfte in 32 Bit auch schneller sein. (kopieren ganzer und vor allem ausgerichteter Integer).
Wenn man es am Ende 32 Bit lässt (erstpart das Rückumwandeln), dann müsste man mal sehn, ob das Umwandeln von 24->32 Bit das Zeitplus des optimierten/einfacherem Codes für 32 Bit nicht auffrisst.
Nja, du mußt für die Berechnungen halt immer den richtigen Zeilenanfang benutzen.
* man könnte ein Array mit den Anfängen aufbauen, jeweils aus .Scanline[]
* oder du nimmst die letzte Zeile und mußt aber für die Zeilenbreite den ausgerichteten/aufgerundeten Wert benutzen
Delphi-Quellcode:
//LineWidth := RoundUp(LineWidth / 4) * 4;
//LineWidth := Trunc(/LineWidth + 3) / 4) * 4;
LineWidth := (LineWidth + 3) and not 3;
Das ScanLine[] in der Schleife braucht es auch nicht, denn Quell- und Zielpixel lassen sich gleichermaßen direkt von der letzten Zeile aus berechnen.
Pos = (X * LineWidthInByte) + (Y * PixelSizeInByte)
Ein INC mit den typisierten Zeigern ist nicht so praktisch, wenn man da das Align einbeziehen muß (bei 24 Bit),
aber über einen Cast nach PByte ließe sich das Problem lösen.
Delphi-Quellcode:
Inc(PByte(Sourc), PixelSizeInByte);
Inc(PByte(Dest), LineWidthInByte);
Delphi-Quellcode:
// für 24 Bit
Last := Scanline[Height - 1];
for Y := Height - 1
downto 0
do begin
Src := Last - (Y * (Width * 3) + 3)
and not 3;
// oder Src := Last; vor die Y-Schleife und nach der X-Schleife ein Inc(PByte(Src), Die0bis3AlignBytes); bzw. Src auf den nächsten Integer aufrunden
Dst := Last + Y * 3;
for X := Width - 1
downto 0
do begin
Dst^ := Src^;
Inc(PByte(Src), 3);
Dec(PByte(Dst), Width * 3);
// bzw. die Pointer als Byte-Typ mit Pointerarithmetik und dafür der Cast beim Kopieren -> PRGBTripple(Dst)^ := PRGBTripple(Src)^;
end;
end;
// für 32 Bit (das Auskommentierte für Byte-Typen)
Last := Scanline[Height - 1];
for Y := Height - 1
downto 0
do begin
Src := Last - Y * Width
{* 4};
// oder Src := Last; vor die Y-Schleife ... die Zeilen liegen ja alle sowieso direkt hintereinander
Dst := Last + Y
{* 4};
for X := Width - 1
downto 0
do begin
Dst^ := Src^;
Inc(Src
{, 4});
Dec(Dst, Width
{* 4});
end;
end;
(falls ich mich nicht vertan hab)