unit TeeFiltersEx;
{$I TeeDefs.inc}

interface

uses
  Windows,
  Classes,
  Graphics,
  TeCanvas;

type
  TSobelFilter=class(TTeeFilter)
  public
    procedure Apply(Bitmap:TBitmap; const R:TRect); override;
    class function Description: String; override;
  end;

implementation

uses
  TeeFilters;

{ TSobelFilter }

procedure TSobelFilter.Apply(Bitmap: TBitmap; const R: TRect);
const
  WX : Array[-1..1,-1..1] of Integer=((1,2, 1),(0,0, 0),(-1,-2,-1));
  WY : Array[-1..1,-1..1] of Integer=((1,0,-1),(2,0,-2),( 1, 0,-1));

var SumX,
    SumY,
    xx,yy,
    tmp,
    x,y : Integer;
    tmpGray : Array of Array of Byte;
begin
  inherited;

  if Length(Lines)=0 then
     Exit;

  // Temp grayscale pixels:
  SetLength(tmpGray,R.Bottom-R.Top+1,R.Right-R.Left+1);

  for y:=R.Top+1 to R.Bottom-1 do
      for x:=R.Left+1 to R.Right-1 do
          with Lines[y,x] do
               tmpGray[y-R.Top,x-R.Left]:=(Blue+Green+Red) div 3;

  // Loop all pixels, calculate Sobel pixel:
  for y:=R.Top+1 to R.Bottom-1 do
      for x:=R.Left+1 to R.Right-1 do
      begin
        SumX:=0;
        SumY:=0;

        for yy:=-1 to 1 do
            for xx:=-1 to 1 do
            begin
              tmp:=tmpGray[y+yy,x+xx];
              Inc(SumX,tmp*WX[xx,yy]);
              Inc(SumY,tmp*WY[xx,yy]);
            end;

        tmp:=Abs(SumX)+Abs(SumY);
        if tmp>255 then tmp:=255;

        with Lines[y,x] do
        begin
          Blue:=tmp;
          Green:=tmp;
          Red:=tmp;
        end;
      end;

  // Release temp grayscale
  tmpGray:=nil;
end;

class function TSobelFilter.Description: String;
begin
  result:='Sobel';
end;

initialization
  TeeRegisterFilters([ TSobelFilter ]);
finalization
  TeeUnRegisterFilters([ TSobelFilter ]);
end.
