Skip to content

Commit

Permalink
Some micro optimizations for BlendMaskLine and ReduceOpacity
Browse files Browse the repository at this point in the history
  • Loading branch information
ahausladen committed Sep 7, 2024
1 parent 1a22510 commit 6dc31a1
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions source/Img32.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,8 @@ function BlendMask(bgColor, alphaMask: TColor32): TColor32;
{$RANGECHECKS OFF} // negative array index is used

procedure BlendMaskLine(bgColor, alphaMask: PColor32; width: nativeint);
label
SkipNone32;
var
a: byte;
begin
Expand All @@ -1283,13 +1285,22 @@ procedure BlendMaskLine(bgColor, alphaMask: PColor32; width: nativeint);
// common values.
while width < 0 do
begin
// MulTable[0, fgA] -> 0, if bgColor is already 0 => skip
while PStaticARGBArray(bgColor)[width].Color = 0 do
begin
SkipNone32:
inc(width);
if width = 0 then exit;
end;
a := PStaticARGBArray(bgColor)[width].A;
// MulTable[0, fgA] -> 0 => replace color with 0
while a = 0 do
begin
PStaticColor32Array(bgColor)[width] := 0;
inc(width);
if width = 0 then exit;
if PStaticARGBArray(bgColor)[width].Color = 0 then
goto SkipNone32;
a := PStaticARGBArray(bgColor)[width].A;
end;
// MulTable[255, fgA] -> fgA => replace alpha with fgA
Expand Down Expand Up @@ -3707,12 +3718,15 @@ procedure TImage32.ReduceOpacity(opacity: Byte);
var
i: Integer;
c: PARGB;
a: Byte;
begin
if opacity = 255 then Exit;
c := PARGB(PixelBase);
for i := 0 to Width * Height -1 do
begin
c.A := MulTable[c.A, opacity];
a := c.A;
if a <> 0 then
c.A := MulTable[a, opacity];
inc(c);
end;
Changed;
Expand All @@ -3723,19 +3737,24 @@ procedure TImage32.ReduceOpacity(opacity: Byte; rec: TRect);
var
i,j, rw: Integer;
c: PARGB;
a: Byte;
lineOffsetInBytes: integer;
begin
Types.IntersectRect(rec, rec, bounds);
if IsEmptyRect(rec) then Exit;
rw := RectWidth(rec);
c := @Pixels[rec.Top * Width + rec.Left];
for i := rec.Top to rec.Bottom -1 do
lineOffsetInBytes := (Width - rw) * SizeOf(TARGB);
for i := rec.Top to rec.Bottom - 1 do
begin
for j := 1 to rw do
begin
c.A := MulTable[c.A, opacity];
a := c.A;
if a <> 0 then
c.A := MulTable[a, opacity];
inc(c);
end;
inc(c, Width - rw);
inc(PByte(c), lineOffsetInBytes);
end;
Changed;
end;
Expand Down

0 comments on commit 6dc31a1

Please sign in to comment.