%%
% ___________________________________________
% VSIM: View Synthesis with Inverse Mapping
% ===========================================
% The VSIM demo
% See readme.txt for details.

close all;
clear all;
start = tic;
%% Setup
% Define the dimensions and set paths of the input sequences 

numFrames = 5; % Number of frames to process

expName = 'Dancer_v_2_1920x1088';
camFileNameLeft = 'C:\3DV\SEQUENCES\Dancer\Dancer_c_1_1920x1088.yuv';
camFileNameRight = 'C:\3DV\SEQUENCES\Dancer\Dancer_c_3_1920x1088.yuv';

depFileNameLeft = 'C:\3DV\SEQUENCES\Dancer\Dancer_d_1_1920x1088.yuv';
depFileNameRight = 'C:\3DV\SEQUENCES\Dancer\Dancer_d_3_1920x1088.yuv';

camFileNameMiddle = 'C:\3DV\SEQUENCES\Dancer\Dancer_c_2_1920x1088.yuv';
camFileNameVirtual = 'Dancer_v_2_1920x1088.yuv';
depFileNameVirtual = 'Dancer_d_2_1920x1088.yuv';

width = 1920;
height = 1088;
zNear = 2289;
zFar = 213500;

% Define the camera parameters
% Left Camera Parameters
fL = [2302.852541609168 0.0                 960.0
    0.0               2302.852541609168   540.0
    0.0               0.0                 1.0 ];

% Left camera position on x-axis
pL = -80;

% Right Camera Parameters
fR = [2302.852541609168     0.0                 960.0
    0.0                   2302.852541609168   540.0
    0.0                   0.0                 1.0 ];

% Right camera position on x-axis
pR = -40;

% Baseline spacing
b = (pR - pL)/2;

zN = 1/zNear;
zF = 1/zFar;

% Open the file to save the virtual view
fid=fopen(camFileNameVirtual,'w');
if (fid < 0)
    error('Could not open the file!');
end;

%%
% Here goes the main 
for fNo=0:numFrames-1
    loopS = tic;
    %% Read the two images, left and right
    [Yl, Ul, Vl] = yuv_import(camFileNameLeft, [width height], 1, fNo);
    [Yr, Ur, Vr] = yuv_import(camFileNameRight, [width height], 1, fNo);
      
    %% Read the two depths, left and right
    [DYl, ~, ~] = yuv_import(depFileNameLeft,[width height], 1, fNo);
    [DYr, ~, ~] = yuv_import(depFileNameRight,[width height], 1, fNo);
    
    %% Compute the actual depths of left and right views
    %  Compute inverse of depth
    zInvL = DYl{1}(:,:,1)/255*(zN - zF) + zF;
    zInvR = DYr{1}(:,:,1)/255*(zN - zF) + zF;
        
    %% Compute the virtual view left
    [ vLY, vLU, vLV, holesL, nShiftL ] = computeVVLeft(Yl{1}, Ul{1}, Vl{1}, zInvL, height, width, fL(2,2), b );
       
    % and virtual right view
    [ vRY, vRU, vRV, holesR, nShiftR ] = computeVVRight(Yr{1}, Ur{1}, Vr{1}, zInvR, height, width, fR(2,2), b );
  
    %% Combining the two views
    bfL = 0.5;
    [ vMY, vMU, vMV, holesV ] = combineViewsPro( vLY, vLU, vLV, vRY, vRU, vRV, holesL, holesR, width, height, bfL );

    % Fill the holes with inverse warping
    sf = 1;
    [ vMY, vMU, vMV, ~ ] = computeVVInv2F(Yl{1}, Ul{1}, Vl{1}, vMY, vMU, vMV, Yr{1}, Ur{1}, Vr{1}, holesV, nShiftL, nShiftR, width, zInvL, fL(2,2), b, zInvR, sf );
   
    
    %% Save the frame
     
    fwrite(fid,vMY','uint8');
    fwrite(fid,vMU','uint8');
    fwrite(fid,vMV','uint8');
    
    clear DUl im vLU  DUr vLV DVl vLY DVr nShiftL vMU DYl nShiftR vMV DYr edgelist newPos vMY  err vRU oldPos vRV vRY var pixByDepthL fU pixByDepthR xx Ul fV yy Ur fY  sList Vl fholesL seglist Vr shiftd zInvL Yl shiftdL zInvR  Ym  holesL shiftdR Yr holesR holesV updatedOrignalEList
    display(sprintf('Frame %d: %4.2f sec.', fNo, toc(loopS)));
    
end
display(sprintf('Total Time: %4.2f', toc(start)));

fclose('all');

display(sprintf('\nComputing PSNR...'));
computePSNR( camFileNameVirtual, camFileNameMiddle, numFrames, height, width, expName )

display('DONE');
