%% contrib.cal equivalent - diagonal matrix solve
function backlight = brsGetCrosstalk(image)
% Generate Ideal Backlight Luiminance by filtering and sampling.
% Ideal backlight image is genererated by two consecutive
% filtering/downsampling steps, first with an averaging (box) filter,
% then with a gaussian filter
% Adjusts LED drive values to account for crosstalk from neighboring LEDs
    box_filter_size = [7 12];
    intermediate_siz = [90 240]; % First downsampling destination size
    gaussian_radius = 2.1; % disp14enc uses 3, but 2.1 seems to match what disp14enc produces
    backlight_siz = [31 89]; % Size of backlight array if it were filled in to become rectangular
    image = imfilter(image,fspecial('average',box_filter_size),'replicate'); 
    image = imresize(image,intermediate_siz,'bilinear',0);
    image = imfilter(image,fspecial('gaussian',15,gaussian_radius),'replicate'); 
    image = imresize(image,backlight_siz,'bilinear',0);
   
    NEIGH_FRAC = 0.712 / 3.07;    % average neighbor contribution(originally matched for Prototype BrightSide)
    %NEIGH_FRAC = 1.4 / 3.07;
    NEIGH_CONT = 6 * NEIGH_FRAC;  % approximate neighborhood total
    NORM_MULT = 1/(1+NEIGH_CONT); % uniform normalization factor
   
    % Crosstalk matrix for convolution
    conv_kernel = [         0              -NEIGH_FRAC*NORM_MULT            0; ...
                   -NEIGH_FRAC*NORM_MULT            0              -NEIGH_FRAC*NORM_MULT; ...
                            0                       1                       0; ...
                   -NEIGH_FRAC*NORM_MULT            0              -NEIGH_FRAC*NORM_MULT; ...
                            0              -NEIGH_FRAC*NORM_MULT            0];

    % disp14enc assumes image edge values continue to infinity, so pad for the
    % convolution, and make all the negative values zero.
    blval = max(imfilter(image,conv_kernel,'replicate','conv'),0);
    % Only keep values at actual LED positions
    backlight = (brsGetLedPos(image) > 0) .* blval;
        
end

