47 lines
1.8 KiB
Ada
47 lines
1.8 KiB
Ada
type Kernel_3x3 is array (-1..1, -1..1) of Float_Luminance;
|
|
|
|
procedure Filter (Picture : in out Image; K : Kernel_3x3) is
|
|
function Get (I, J : Integer) return Float_Pixel is
|
|
pragma Inline (Get);
|
|
begin
|
|
if I in Picture'Range (1) and then J in Picture'Range (2) then
|
|
declare
|
|
Color : Pixel := Picture (I, J);
|
|
begin
|
|
return (Float_Luminance (Color.R), Float_Luminance (Color.G), Float_Luminance (Color.B));
|
|
end;
|
|
else
|
|
return (others => 0.0);
|
|
end if;
|
|
end Get;
|
|
W11, W12, W13 : Float_Pixel; -- The image window
|
|
W21, W22, W23 : Float_Pixel;
|
|
W31, W32, W33 : Float_Pixel;
|
|
Above : array (Picture'First (2) - 1..Picture'Last (2) + 1) of Float_Pixel;
|
|
This : Float_Pixel;
|
|
begin
|
|
for I in Picture'Range (1) loop
|
|
W11 := Above (Picture'First (2) - 1); -- The upper row is taken from the cache
|
|
W12 := Above (Picture'First (2) );
|
|
W13 := Above (Picture'First (2) + 1);
|
|
W21 := (others => 0.0); -- The middle row
|
|
W22 := Get (I, Picture'First (2) );
|
|
W23 := Get (I, Picture'First (2) + 1);
|
|
W31 := (others => 0.0); -- The bottom row
|
|
W32 := Get (I+1, Picture'First (2) );
|
|
W33 := Get (I+1, Picture'First (2) + 1);
|
|
for J in Picture'Range (2) loop
|
|
This :=
|
|
W11 * K (-1, -1) + W12 * K (-1, 0) + W13 * K (-1, 1) +
|
|
W21 * K ( 0, -1) + W22 * K ( 0, 0) + W23 * K ( 0, 1) +
|
|
W31 * K ( 1, -1) + W32 * K ( 1, 0) + W33 * K ( 1, 1);
|
|
Above (J-1) := W21;
|
|
W11 := W12; W12 := W13; W13 := Above (J+1); -- Shift the window
|
|
W21 := W22; W22 := W23; W23 := Get (I, J+1);
|
|
W31 := W32; W32 := W23; W33 := Get (I+1, J+1);
|
|
Picture (I, J) := To_Pixel (This);
|
|
end loop;
|
|
Above (Picture'Last (2)) := W21;
|
|
end loop;
|
|
end Filter;
|