%EUSIPCO 2012
%Imperial College London 
%Andriy Gelman, Jon Onativia and Pier Luigi Dragotti 


function output = inverse_lifting_haar_transform(input, original_label, D, round_param, dwt_uncovered, dwt_intra, motion_Vect)

%label is the original extracted label - needs to be zero padded
%pad label to the same size as the input
[r,c,k] = size(input);
number_of_images = k;

%original_label = padarray(original_label, [0, ceil(number_of_images*max(max(D))), 0], 'both');

%initialize output

m = ceil(log2(k));
%initialize locations

%location = 0:1:(k-1);
location = 1:k;
%initialize low
output = input;
clear input

original_D = D;

for i = m:-1:1
            
    [low_coord, high_coord, new_length, new_location] = derive_coordinates(i, k, location);
    low = output(:,:,low_coord);
    high = output(:,:,high_coord);            
    
    if (i-1) > 0
        [clear_buff_1, dwt_label, dwt_intra, dwt_uncovered, motion_Vect] = lifting_haar_transform(zeros(size(original_label)), double(original_label), D, 'ceil', i-1);
        dwt_label = dwt_label(:,:,1:new_length);        
        clear clear_var;            
        [dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord)] = compute_uncovered_pixels(dwt_label, D, round_param, k, i);    
        %buffer_dwt_label = dwt_label;       
        %dwt_label(:,:,1:2:end) = buffer_dwt_label(:,:,1:new_length);
        %dwt_label(:,:,2:2:end) = buffer_dwt_label(:,:,new_length+1:end); clear dwt_label;       
    else        
        dwt_label = double(original_label);
        [dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord)] = compute_uncovered_pixels(dwt_label, D, round_param, k, 1);
    end
    %Calculate the required label        
    [dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord), dwt_label, clear_var] = move_pixels_into_different_frames(dwt_uncovered(:,:,high_coord), original_D, i, number_of_images, round_param, dwt_label, zeros(size(dwt_label)));
            
    label_buffer = dwt_label(:,:,1:new_length); 
    intra_buffer = dwt_intra(:,:,high_coord);
    motion_Vect_buffer = motion_Vect(high_coord);
    
    %evaluate uncovered pixels      
    %[high] = inverse_forward_prediction(low, high, dwt_uncovered(:,:,high_coord), label_buffer, D*2^(i-1), round_param);
    
    %output(:,:,1:new_length) = inverse_single_temporal_harr(low, high, label, new_location, disparity);    
    [output(:,:,1:new_length)] = inverse_lifting_view_haar_1_decomposition(low, high, label_buffer, D*2^(i-1), round_param, intra_buffer, motion_Vect_buffer);
    clear label_buffer intra_buffer;
    
    %derive the correct label for the data 
    %[dwt_label, dwt_intra, dwt_uncovered] = compute_previous_label(original_label, D, round_param, i-1, high_coord);
       
     
    if (i-1) > 0
        [clear_buff_1, dwt_label, dwt_intra, dwt_uncovered, motion_Vect] = lifting_haar_transform(zeros(size(original_label)), double(original_label), D, 'ceil', i-1);
        dwt_label = dwt_label(:,:,1:new_length);               
        clear clear_var;           
        [dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord)] = compute_uncovered_pixels(dwt_label, original_D, round_param, k, i);      
        %buffer_dwt_label = dwt_label;       
        %dwt_label(:,:,1:2:end) = buffer_dwt_label(:,:,1:new_length);
        %dwt_label(:,:,2:2:end) = buffer_dwt_label(:,:,new_length+1:end); clear dwt_label;       
    else
        dwt_label = double(original_label);           
        [dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord)] = compute_uncovered_pixels(dwt_label, original_D, round_param, k, 1);   
    end
    
    output(:,:,1:new_length) = inverse_move_pixels_into_different_frames(dwt_intra(:,:,high_coord), dwt_uncovered(:,:,high_coord), D, i, k, round_param, dwt_label(:,:,1:new_length), output(:,:,1:new_length));
    
    

        %[dwt_label, dwt_intra, dwt_uncovered] = compute_previous_label(original_label, D, round_param, i-1, high_coord);

    
    %compute intra pixels of the current 
  
    
    %[intra, uncovered, label, in] =
    %move_pixels_into_different_frames(intra, uncovered, D, round_param, label, in);
    %output(:,:,(k/(2^i) + 1): k/(2^(i-1))) = high;

end


end

function [low_coord, high_coord, new_length, location] = derive_coordinates(iteration, original_length, original_location)

low_coord = original_length;
for i = 1:iteration
    low_coord = 1:round(original_length/2);
    high_coord = low_coord(end)+1:original_length;
    original_length = low_coord(end);
end

location = downsample(original_location, 2^(iteration-1));
new_length = length(location);

end
