function output=averagefilter(image, varargin)
%**************************************************************************
% This is a function to execute average filtering in each block.
% 1. Input 'image 'is the image.
% 2. Input 'varargin' includes other parameter, such as the window size.
%
% Created By: Kaichang CHENG, Jul 10,2019
%**************************************************************************
num = length(varargin);
if num > 2
    error('myfuns:somefun2Alt:TooManyInputs', 'requires at most 2 optional inputs');
end
opt = {[3 3] 0};       
opt(1:num) = varargin;
[windowSize, padding] = opt{:}; 
s1 = windowSize(1);
s2 = windowSize(2);
if ~mod(s1,2) 
    s1 = s1-1; 
end       
if ~mod(s2,2) 
    s2 = s2-1; 
end
[rows, cols,ndim] = size(image);  
if (ndim==3)           
    disp('The input image must be a two dimensional array.')
    disp('Consider using rgb2gray or similar function.')
    return
end
% Pad the image.
imageP  = padarray(image, [(s1+1)/2 (s2+1)/2], padding, 'pre');
imageP2 = padarray(imageP, [(s1-1)/2 (s2-1)/2], padding, 'post');
% Always use double because uint8 would be too small.
imageD = double(imageP2);
t = cumsum(cumsum(imageD),2);
imageAve = t(1+s1:rows+s1, 1+s2:cols+s2) + t(1:rows, 1:cols)...
    - t(1+s1:rows+s1, 1:cols) - t(1:rows, 1+s2:cols+s2);
imageAve = imageAve/(s1*s2);
% Return matrix in the original type class.
output = cast(imageAve, class(image));