%     This code implements the recoloring method described in the paper:
%     Musialski, P., Cui, M., Ye, J., Razdan, A., & Wonka, P. (2012). 
%     A Framework for Interactive Image Color Editing. 
%     The Visual Computer, 29(11), 1173–1186. doi:10.1007/s00371-012-0761-5

%     Copyright (C) 2011-2013, Przemyslaw Musialski, pm@cg.tuwien.ac.at
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% -------------------------------------------------------------------------


function [resimg] = RunOptimization(handles)
% this function actually solves for the new image using the previously
% computed weights and the

tarLab              = handles.tarLab;
landmarks           = handles.landmarks;
targetsample        = handles.targetsample;
lambda              = handles.lambda;
cformOut            = handles.cformOut;
tar                 = tarLab(targetsample,:);
W                   = handles.W;

t1  = tic;
if(handles.channels==2)
    temptar         = tar(:,2:3)';
    [result]        = SolveLLE_Embedding(W,temptar,lambda); %result = result';
    result          = [landmarks(:,1) result];
else
    temptar         = tar';
    [result]        = SolveLLE_Embedding(W,temptar,lambda); %result = result';
end
fprintf(1,['...took ' num2str(toc(t1)) 's.\n'] );

t2 = tic;
fprintf(1,'Reconstructing image from landmarks \n');
% reconstruction of the original points from DT
BC   = handles.BC;
BA   = handles.BA;
BI   = handles.BI;
resvec     = reconstructImageBI(result, BI, BC, BA);
fprintf(1,['...took ' num2str(toc(t2)) 's.\n'] );

clear nnidx;
clear dist;

resvec              = applycform(resvec,cformOut);
resimg              = WrapVector2Image(resvec,handles.imH,handles.imW);
srcRGB              = handles.srcRGB;
rms                 = sqrt( sum( (srcRGB(:)-resvec(:)).^2) / numel(resvec) )

fprintf(1,'------------------\n');



function [Y] = SolveLLE_Embedding(W,C,beta)
% solves for new image
% see Equation (7) in the paper

[n,~] = size(W);
[d,m] = size(C);
B = beta*sparse(1:m,1:m,1);

fprintf(1,'Computing LLE Embedding on %d points in %d dimensions\n',n,d);
if(m==n)
    
    A =  W+B;
    b = C';
    
    Y = beta*(A\b);
else
    W11 = W(1:m, 1:m) + B;
    W12 = W(1:m, m+1:n);
    W22 = W(m+1:n, m+1:n);
    A   = [W11 W12; W12' W22];
    
    b = zeros(n,d);
    b(1:m,:) = C';
    
    %----------------
    % solve A*x = b
    Y = A\b;
    Y = beta*Y;
end
return;



function [resvec] = reconstructImageBI(colors,bi,bc,ba)
    % interpolate the remaining values from landmarks
    points = [colors; ba];
    tind = bi;
    resvec = GetPointsFromBarycentric3D(bc', points', tind')';
return;


