Changeset 72 for trunk/ScreenTools.pas


Ignore:
Timestamp:
Jan 15, 2017, 11:47:01 AM (7 years ago)
Author:
chronos
Message:
  • Modified: Unified direct pixel access using TPixelPointer.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ScreenTools.pas

    r68 r72  
    3535    Pixel: PPixel32;
    3636    Line: PPixel32;
     37    RelLine: PPixel32;
    3738    BytesPerPixel: Integer;
    3839    BytesPerLine: Integer;
    39     procedure NextLine; inline;
    40     procedure NextPixel; inline;
    41     procedure SetXY(X, Y: Integer); inline;
    42     procedure SetX(X: Integer); inline;
    43     procedure Init(Bitmap: TBitmap; X: Integer = 0; Y: Integer = 0); inline;
     40    procedure NextLine; inline; // Move pointer to start of new base line
     41    procedure NextPixel; inline; // Move pointer to next pixel
     42    procedure SetXY(X, Y: Integer); inline; // Set pixel position relative to base
     43    procedure SetX(X: Integer); inline; // Set horizontal pixel position relative to base
     44    procedure Init(Bitmap: TBitmap; BaseX: Integer = 0; BaseY: Integer = 0); inline;
    4445  end;
    4546  PPixelPointer = ^TPixelPointer;
     
    4849function ChangeResolution(x, y, bpp, freq: integer): boolean;
    4950{$ENDIF}
    50 function GetBitmapPixelPtr(Bitmap: TBitmap; X, Y: Integer): PPixel32;
    5151procedure RestoreResolution;
    5252function Play(Item: string; Index: integer = -1): boolean;
     
    298298end;
    299299
    300 function GetBitmapPixelPtr(Bitmap: TBitmap; X, Y: Integer): PPixel32;
    301 begin
    302   Result := Pointer(Bitmap.RawImage.Data) + X * (Bitmap.RawImage.Description.BitsPerPixel shr 3) + Y * Bitmap.RawImage.Description.BytesPerLine;
    303 end;
    304 
    305300procedure EmptyMenu(MenuItems: TMenuItem; Keep: integer = 0);
    306301var
     
    464459  begin
    465460    Bmp.BeginUpdate;
    466     PixelPtr.Init(bmp, 0, 0);
     461    PixelPtr.Init(bmp);
    467462    for Y := 0 to Bmp.Height - 1 do begin
    468463      for X := 0 to Bmp.Width - 1 do begin
     
    483478  FileName: string;
    484479  Source: TBitmap;
    485   DataPixel, MaskPixel: PPixel32;
     480  DataPixel, MaskPixel: TPixelPointer;
    486481begin
    487482  i := 0;
     
    517512    GrExt[nGrExt].Data.BeginUpdate;
    518513    GrExt[nGrExt].Mask.BeginUpdate;
    519     for y := 0 to Source.Height - 1 do
    520     begin
    521       for x := 0 to xmax - 1 do
    522       begin
    523         DataPixel := GetBitmapPixelPtr(GrExt[nGrExt].Data, x, y);
    524         MaskPixel := GetBitmapPixelPtr(GrExt[nGrExt].Mask, x, Y);
    525 
    526         OriginalColor := DataPixel^.ARGB and $FFFFFF;
    527         if (OriginalColor = $FF00FF) or (OriginalColor = $7F007F) then
    528         begin // transparent
    529           MaskPixel^.ARGB := $FFFFFF;
    530           DataPixel^.ARGB := DataPixel^.ARGB and $FF000000
    531         end
    532         else
    533         begin
    534           MaskPixel^.ARGB := $000000; // non-transparent
    535           if Gamma <> 100 then
    536           begin
    537             DataPixel^.B := GammaLUT[DataPixel^.B];
    538             DataPixel^.G := GammaLUT[DataPixel^.G];
    539             DataPixel^.R := GammaLUT[DataPixel^.R];
    540           end
    541         end
    542       end
     514    DataPixel.Init(GrExt[nGrExt].Data);
     515    MaskPixel.Init(GrExt[nGrExt].Mask);
     516    for y := 0 to Source.Height - 1 do begin
     517      for x := 0 to xmax - 1 do begin
     518        OriginalColor := DataPixel.Pixel^.ARGB and $FFFFFF;
     519        if (OriginalColor = $FF00FF) or (OriginalColor = $7F007F) then begin // transparent
     520          MaskPixel.Pixel^.ARGB := $FFFFFF;
     521          DataPixel.Pixel^.ARGB := DataPixel.Pixel^.ARGB and $FF000000
     522        end else begin
     523          MaskPixel.Pixel^.ARGB := $000000; // non-transparent
     524          if Gamma <> 100 then begin
     525            DataPixel.Pixel^.B := GammaLUT[DataPixel.Pixel^.B];
     526            DataPixel.Pixel^.G := GammaLUT[DataPixel.Pixel^.G];
     527            DataPixel.Pixel^.R := GammaLUT[DataPixel.Pixel^.R];
     528          end;
     529        end;
     530        DataPixel.NextPixel;
     531        MaskPixel.NextPixel;
     532      end;
     533      DataPixel.NextLine;
     534      MaskPixel.NextLine;
    543535    end;
    544536    GrExt[nGrExt].Data.EndUpdate;
     
    562554begin
    563555  Dst.BeginUpdate;
    564   PixelPtr.Init(Dst, 0, 0);
     556  PixelPtr.Init(Dst);
    565557  for yy := 0 to h - 1 do begin
    566558    for xx := 0 to w - 1 do begin
     
    580572var
    581573  X, Y: Integer;
    582   Brightness, test: integer;
    583   PixelSrc: ^Byte;
    584   PixelDst: PPixel32;
    585 begin
    586   //TODO Assert(Src.PixelFormat = pf8bit);
     574  Brightness, Test: Integer;
     575  PixelSrc: TPixelPointer;
     576  PixelDst: TPixelPointer;
     577  pf: TPixelFormat;
     578begin
     579  pf := src.PixelFormat;
     580  //Assert(Src.PixelFormat = pf8bit);
    587581  Assert(dst.PixelFormat = pf24bit);
    588582  if xDst < 0 then
     
    607601  dst.BeginUpdate;
    608602  Src.BeginUpdate;
     603  PixelDst.Init(Dst, xDst, yDst);
     604  PixelSrc.Init(Src, xSrc, ySrc);
    609605  for Y := 0 to h - 1 do begin
    610     PixelDst := GetBitmapPixelPtr(dst, xDst, yDst + Y);
    611     PixelSrc := Pointer(GetBitmapPixelPtr(Src, xSrc, ySrc + Y));
    612606    for X := 0 to w - 1 do begin
    613       Brightness := PixelSrc^;
    614       test := (PixelDst^.R * Brightness) shr 7;
    615       if test >= 256 then PixelDst^.R := 255
    616         else PixelDst^.R := test; // Red
    617       test := (PixelDst^.G * Brightness) shr 7;
    618       if test >= 256 then PixelDst^.G := 255
    619         else PixelDst^.G := test; // Green
    620       test := (PixelDst^.B * Brightness) shr 7;
    621       if test >= 256 then
    622         PixelDst^.R := 255
    623       else
    624         PixelDst^.B := test; // Blue
    625       PixelDst := Pointer(PixelDst) + (Dst.RawImage.Description.BitsPerPixel shr 3);
    626       PixelSrc := Pointer(PixelSrc) + (Src.RawImage.Description.BitsPerPixel shr 3);
    627     end;
     607      Brightness := PixelSrc.Pixel^.B; // One byte for 8-bit color
     608      test := (PixelDst.Pixel^.R * Brightness) shr 7;
     609      if test >= 256 then PixelDst.Pixel^.R := 255
     610        else PixelDst.Pixel^.R := test; // Red
     611      test := (PixelDst.Pixel^.G * Brightness) shr 7;
     612      if test >= 256 then PixelDst.Pixel^.G := 255
     613        else PixelDst.Pixel^.G := test; // Green
     614      test := (PixelDst.Pixel^.B * Brightness) shr 7;
     615      if test >= 256 then PixelDst.Pixel^.R := 255
     616        else PixelDst.Pixel^.B := Test; // Blue
     617      PixelDst.NextPixel;
     618      PixelSrc.NextPixel;
     619    end;
     620    PixelDst.NextLine;
     621    PixelSrc.NextLine;
    628622  end;
    629623  src.EndUpdate;
     
    639633var
    640634  ix, iy, amp1, amp2, trans, Value: integer;
    641   SrcPixel, DstPixel: PPixel32;
     635  SrcPixel, DstPixel: TPixelPointer;
    642636begin
    643637  if xDst < 0 then begin
     
    660654  Src.BeginUpdate;
    661655  dst.BeginUpdate;
    662   for iy := 0 to h - 1 do
    663   begin
    664     for ix := 0 to w - 1 do
    665     begin
    666       SrcPixel := GetBitmapPixelPtr(Src, xSrc + ix, ySrc + iy);
    667       DstPixel := GetBitmapPixelPtr(Dst, xDst + ix, yDst + iy);
    668       trans := SrcPixel^.B * 2; // green channel = transparency
    669       amp1 := SrcPixel^.G * 2;
    670       amp2 := SrcPixel^.R * 2;
    671       if trans <> $FF then
    672       begin
    673         Value := (DstPixel^.B * trans + ((Color2 shr 16) and $FF) * amp2
     656  SrcPixel.Init(Src, xSrc, ySrc);
     657  DstPixel.Init(Dst, xDst, yDst);
     658  for iy := 0 to h - 1 do begin
     659    for ix := 0 to w - 1 do begin
     660      trans := SrcPixel.Pixel^.B * 2; // green channel = transparency
     661      amp1 := SrcPixel.Pixel^.G * 2;
     662      amp2 := SrcPixel.Pixel^.R * 2;
     663      if trans <> $FF then begin
     664        Value := (DstPixel.Pixel^.B * trans + ((Color2 shr 16) and $FF) * amp2
    674665          + ((Color1 shr 16) and $FF) * amp1) div $FF;
    675         if Value < 256 then DstPixel^.B := Value
    676         else DstPixel^.B := 255;
    677         Value := (DstPixel^.G * trans + ((Color2 shr 8) and $FF) * amp2
     666        if Value < 256 then DstPixel.Pixel^.B := Value
     667          else DstPixel.Pixel^.B := 255;
     668        Value := (DstPixel.Pixel^.G * trans + ((Color2 shr 8) and $FF) * amp2
    678669          + ((Color1 shr 8) and $FF) * amp1) div $FF;
    679         if Value < 256 then DstPixel^.G := Value
    680           else DstPixel^.G := 255;
    681         Value := (DstPixel^.R * trans + (Color2 and $FF) * amp2 +
     670        if Value < 256 then DstPixel.Pixel^.G := Value
     671          else DstPixel.Pixel^.G := 255;
     672        Value := (DstPixel.Pixel^.R * trans + (Color2 and $FF) * amp2 +
    682673          (Color1 and $FF) * amp1) div $FF;
    683         if Value < 256 then DstPixel^.R := Value
    684           else DstPixel^.R := 255;
     674        if Value < 256 then DstPixel.Pixel^.R := Value
     675          else DstPixel.Pixel^.R := 255;
    685676      end;
    686     end;
     677      SrcPixel.NextPixel;
     678      DstPixel.NextPixel;
     679    end;
     680    SrcPixel.NextLine;
     681    DstPixel.NextLine;
    687682  end;
    688683  Src.EndUpdate;
     
    698693var
    699694  i, Red, Green: integer;
    700   Pixel: PPixel32;
     695  PixelPtr: TPixelPointer;
    701696begin
    702697  bmp.BeginUpdate;
    703698  assert(bmp.PixelFormat = pf24bit);
    704699  h := y + h;
    705   while y < h do
    706   begin
    707     Pixel := GetBitmapPixelPtr(Bmp, x, y);
    708     for i := 0 to w - 1 do
    709     begin
    710       Red := ((Pixel^.B * (Color0 and $0000FF) + Pixel^.G * (Color1 and $0000FF)
    711         + Pixel^.R * (Color2 and $0000FF)) shr 8) and $ff;
    712       Green := ((Pixel^.B * ((Color0 shr 8) and $0000FF) + Pixel^.G *
    713         ((Color1 shr 8) and $0000FF) + Pixel^.R * ((Color2 shr 8) and
     700  PixelPtr.Init(Bmp, x, y);
     701  while y < h do begin
     702    for i := 0 to w - 1 do  begin
     703      Red := ((PixelPtr.Pixel^.B * (Color0 and $0000FF) + PixelPtr.Pixel^.G * (Color1 and $0000FF)
     704        + PixelPtr.Pixel^.R * (Color2 and $0000FF)) shr 8) and $ff;
     705      Green := ((PixelPtr.Pixel^.B * ((Color0 shr 8) and $0000FF) + PixelPtr.Pixel^.G *
     706        ((Color1 shr 8) and $0000FF) + PixelPtr.Pixel^.R * ((Color2 shr 8) and
    714707        $0000FF)) shr 8) and $ff;
    715       Pixel^.B := ((Pixel^.B * ((Color0 shr 16) and $0000FF) + Pixel^.G *
    716         ((Color1 shr 16) and $0000FF) + Pixel^.R * ((Color2 shr 16) and $0000FF))
     708      PixelPtr.Pixel^.B := ((PixelPtr.Pixel^.B * ((Color0 shr 16) and $0000FF) + PixelPtr.Pixel^.G *
     709        ((Color1 shr 16) and $0000FF) + PixelPtr.Pixel^.R * ((Color2 shr 16) and $0000FF))
    717710        shr 8) and $ff; // Blue
    718       Pixel^.G := Green;
    719       Pixel^.R := Red;
    720       Pixel := pointer(Pixel) + (Bmp.RawImage.Description.BitsPerPixel shr 3);
     711      PixelPtr.Pixel^.G := Green;
     712      PixelPtr.Pixel^.R := Red;
     713      PixelPtr.NextPixel;
    721714    end;
    722715    inc(y);
     716    PixelPtr.NextLine;
    723717  end;
    724718  bmp.EndUpdate;
     
    749743  DestCanvas.CopyRect(Rect(X, Y, X + Width, Y + Height), SrcCanvas,
    750744    Rect(XSrc, YSrc, XSrc + Width, YSrc + Height));
     745  Result := True;
    751746end;
    752747
     
    14471442end;
    14481443
    1449 procedure TPixelPointer.Init(Bitmap: TBitmap; X: Integer = 0; Y: Integer = 0); inline;
    1450 begin
    1451   Base := PPixel32(Bitmap.RawImage.Data);
     1444procedure TPixelPointer.Init(Bitmap: TBitmap; BaseX: Integer = 0; BaseY: Integer = 0); inline;
     1445begin
    14521446  BytesPerLine := Bitmap.RawImage.Description.BytesPerLine;
    14531447  BytesPerPixel := Bitmap.RawImage.Description.BitsPerPixel shr 3;
    1454   SetXY(X, Y);
     1448  Base := PPixel32(Bitmap.RawImage.Data + BaseX * BytesPerPixel + BaseY * BytesPerLine);
     1449  SetXY(0, 0);
    14551450end;
    14561451
Note: See TracChangeset for help on using the changeset viewer.