RosettaCodeData/Task/Image-convolution/Ada/image-convolution-2.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;