Ignore:
Timestamp:
Dec 8, 2023, 11:39:45 PM (12 months ago)
Author:
chronos
Message:
  • Added: Range checking for TPixelPointer record type.
Location:
trunk/Packages/DpiControls
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Packages/DpiControls/Dpi.Graphics.pas

    r477 r487  
    270270    procedure ScreenChanged; override;
    271271  public
     272    procedure Assign(Source: TPersistent); override;
    272273    procedure SetSize(AWidth, AHeight: Integer); override;
    273274  end;
     
    293294    constructor Create; override;
    294295    destructor Destroy; override;
    295     procedure Assign(Source: TPersistent); override;
    296296    property ScanLine[Row: Integer]: Pointer read GetScanLine;
    297297  published
     
    418418end;
    419419
     420procedure TCustomBitmap.Assign(Source: TPersistent);
     421begin
     422  if Source is TCustomBitmap then begin
     423    GetNativeCustomBitmap.Assign(TCustomBitmap(Source).GetNativeCustomBitmap);
     424    FWidth := TCustomBitmap(Source).FWidth;
     425    FHeight := TCustomBitmap(Source).FHeight
     426  end else inherited;
     427end;
     428
    420429procedure TCustomBitmap.SetSize(AWidth, AHeight: Integer);
    421430begin
     
    691700  //Exit;
    692701  Dst.BeginUpdate;
    693   SrcPtr := PixelPointer(Src, 0, 0);
    694   DstPtr := PixelPointer(Dst, 0, 0);
     702  SrcPtr := TPixelPointer.Create(Src, 0, 0);
     703  DstPtr := TPixelPointer.Create(Dst, 0, 0);
    695704  {for yy := 0 to Dst.Height - 1 do begin
    696705    for xx := 0 to Dst.Width - 1 do begin
     
    841850end;
    842851
    843 procedure TBitmap.Assign(Source: TPersistent);
    844 begin
    845   if Source is TBitmap then begin
    846     GetNativeBitmap.Assign((Source as TBitmap).GetNativeBitmap);
    847   end else inherited;
    848 end;
    849 
    850852{ TPen }
    851853
  • trunk/Packages/DpiControls/Dpi.PixelPointer.pas

    r468 r487  
    44
    55uses
    6   Classes, SysUtils, Dpi.Graphics;
     6  Classes, SysUtils, Dpi.Graphics, Dpi.Common;
    77
    88type
     
    3535    BytesPerPixel: Integer;
    3636    BytesPerLine: Integer;
     37    Data: PPixel32;
     38    Width: Integer;
     39    Height: Integer;
    3740    procedure NextLine; inline; // Move pointer to start of next line
    3841    procedure PreviousLine; inline; // Move pointer to start of previous line
     
    4144    procedure SetXY(X, Y: Integer); inline; // Set pixel position relative to base
    4245    procedure SetX(X: Integer); inline; // Set horizontal pixel position relative to base
    43     class function Create(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; inline; static;
     46    procedure CheckRange; inline; // Check if current pixel position is not out of range
     47    class function Create(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; static;
    4448  end;
    4549  PPixelPointer = ^TPixelPointer;
     
    6367implementation
    6468
     69resourcestring
     70  SOutOfRange = 'Pixel pointer out of range';
     71  SWrongBitmapSize = 'Wrong bitmap size [width: %d, height: %d]';
     72
    6573{ TPixel32 }
    6674
     
    8391  Line := Pointer(Line) + BytesPerLine;
    8492  Pixel := Line;
     93  CheckRange;
    8594end;
    8695
     
    8998  Line := Pointer(Line) - BytesPerLine;
    9099  Pixel := Line;
     100  CheckRange;
    91101end;
    92102
     
    94104begin
    95105  Pixel := Pointer(Pixel) + BytesPerPixel;
     106  CheckRange;
    96107end;
    97108
     
    99110begin
    100111  Pixel := Pointer(Pixel) - BytesPerPixel;
     112  CheckRange;
    101113end;
    102114
     
    110122begin
    111123  Pixel := Pointer(Line) + X * BytesPerPixel;
     124  CheckRange;
     125end;
     126
     127procedure TPixelPointer.CheckRange;
     128begin
     129  {$IFOPT R+}
     130  if (PByte(Pixel) < PByte(Data)) or
     131    (PByte(Pixel) >= PByte(Data) + (Width + Height * BytesPerLine) * BytesPerPixel) then
     132    raise Exception.Create(SOutOfRange);
     133  {$ENDIF}
    112134end;
    113135
     
    298320  BaseY: Integer): TPixelPointer;
    299321begin
     322  Result.Width := ScaleToNative(Bitmap.Width);
     323  Result.Height := ScaleToNative(Bitmap.Height);
     324  if (Result.Width < 0) or (Result.Height < 0) then
     325    raise Exception.Create(Format(SWrongBitmapSize, [Result.Width, Result.Height]));
    300326  Result.BytesPerLine := Bitmap.RawImage.Description.BytesPerLine;
    301327  Result.BytesPerPixel := Bitmap.RawImage.Description.BitsPerPixel shr 3;
     328  Result.Data := PPixel32(Bitmap.RawImage.Data);
    302329  Result.Base := PPixel32(Bitmap.RawImage.Data + BaseX * Result.BytesPerPixel +
    303330    BaseY * Result.BytesPerLine);
  • trunk/Packages/DpiControls/NativePixelPointer.pas

    r468 r487  
    3232    BytesPerPixel: Integer;
    3333    BytesPerLine: Integer;
     34    Data: PPixel32;
     35    Width: Integer;
     36    Height: Integer;
    3437    procedure NextLine; inline; // Move pointer to start of next line
    3538    procedure PreviousLine; inline; // Move pointer to start of previous line
     
    3841    procedure SetXY(X, Y: Integer); inline; // Set pixel position relative to base
    3942    procedure SetX(X: Integer); inline; // Set horizontal pixel position relative to base
     43    procedure CheckRange; inline; // Check if current pixel position is not out of range
     44    class function Create(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; static;
    4045  end;
    4146  PPixelPointer = ^TPixelPointer;
    4247
    43   function PixelPointer(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; inline;
    4448  function Color32ToColor(Color: TColor32): TColor;
    4549  function ColorToColor32(Color: TColor): TColor32;
     
    4852implementation
    4953
    50 { TPixel32 }
     54resourcestring
     55  SOutOfRange = 'Pixel pointer out of range';
     56  SWrongBitmapSize = 'Wrong bitmap size [width: %d, height: %d]';
     57
     58  { TPixel32 }
    5159
    5260procedure TPixel32.SetRGB(Color: TColor32);
     
    97105end;
    98106
    99 function PixelPointer(Bitmap: TRasterImage; BaseX: Integer;
     107procedure TPixelPointer.CheckRange;
     108begin
     109  {$IFOPT R+}
     110  if (PByte(Pixel) < PByte(Data)) or
     111    (PByte(Pixel) >= PByte(Data) + (Width + Height * BytesPerLine) * BytesPerPixel) then
     112    raise Exception.Create(SOutOfRange);
     113  {$ENDIF}
     114end;
     115
     116class function TPixelPointer.Create(Bitmap: TRasterImage; BaseX: Integer;
    100117  BaseY: Integer): TPixelPointer;
    101118begin
     119  Result.Width := Bitmap.Width;
     120  Result.Height := Bitmap.Height;
     121  if (Result.Width < 0) or (Result.Height < 0) then
     122    raise Exception.Create(Format(SWrongBitmapSize, [Result.Width, Result.Height]));
    102123  Result.BytesPerLine := Bitmap.RawImage.Description.BytesPerLine;
    103124  Result.BytesPerPixel := Bitmap.RawImage.Description.BitsPerPixel shr 3;
     125  Result.Data := PPixel32(Bitmap.RawImage.Data);
    104126  Result.Base := PPixel32(Bitmap.RawImage.Data + BaseX * Result.BytesPerPixel +
    105127    BaseY * Result.BytesPerLine);
Note: See TracChangeset for help on using the changeset viewer.