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

function output = reorganize_partitions(input, input_size, number_of_decompositions, maximum_block_size)

r = input_size(1);
c = input_size(2);

row_subbands = compute_subband_size(r, number_of_decompositions);
col_subbands = compute_subband_size(c, number_of_decompositions);

%re-organize the data in a re-cursive fashion..

%Initialization
block_counter = 1;
%Construct the first subband
 switch ((row_subbands(1)*col_subbands(1))<= (maximum_block_size(1)*maximum_block_size(2)))     
        case 1 %When the subbands have not been partitioned
            block1 = input{block_counter};
            block_counter = block_counter + 1;       
        case 0 %When the subbands have been partitioned, the blocks in the input must be combined to make block 2            
            [block1, block_counter] = extract_subband_blocks(input,...
                [row_subbands(1) col_subbands(1)], maximum_block_size, block_counter);                
 end
    

%Initialization
current_subband = zeros(row_subbands(1), col_subbands(1));
%current_subband(:,:) = input{block_counter};
current_subband(:,:) = block1; clear block1;
%block_counter = block_counter+1;

for l = 1:number_of_decompositions
    
    current_subband_row = sum(row_subbands(1:l));
    current_subband_col = sum(col_subbands(1:l));
    %

    next_subband = zeros(sum(row_subbands(1:l+1)), sum(col_subbands(1:l+1)));

    %extract block2, block3 and block4
    %___________________
    %         |         |
    %    1    |    2    |
    %_________|________ |
    %         |         |
    %    3    |    4    |
    %_________|_________|    
    %

    switch ((current_subband_row*current_subband_col)<= (maximum_block_size(1)*maximum_block_size(2))) 
    
        case 1 %When the subbands have not been partitioned
            block2 = input{block_counter};
            block_counter = block_counter + 1;       
        case 0 %When the subbands have been partitioned, the blocks in the input must be combined to make block 2            
            [block2, block_counter] = extract_subband_blocks(input,...
                [current_subband_row current_subband_col], maximum_block_size, block_counter);                
    end

    switch ((current_subband_row*current_subband_col)<= maximum_block_size(1)*maximum_block_size(2)) 
    
        case 1 %When the subbands have not been partitioned
            block3 = input{block_counter};
            block_counter = block_counter + 1;       
        case 0 %When the subbands have been partitioned, the blocks in the input must be combined to make block 2            
            [block3, block_counter] = extract_subband_blocks(input,...
                [current_subband_row current_subband_col], maximum_block_size, block_counter);                
    end

    switch ((current_subband_row*current_subband_col)<= maximum_block_size(1)*maximum_block_size(2)) 
    
        case 1 %When the subbands have not been partitioned
            block4 = input{block_counter};
            block_counter = block_counter + 1;       
        case 0 %When the subbands have been partitioned, the blocks in the input must be combined to make block 2            
            [block4, block_counter] = extract_subband_blocks(input,...
                [current_subband_row current_subband_col], maximum_block_size, block_counter);                
    end
    
    
    %[current_subband_rows, current_subband_cols] = size(current_subband);
    [next_subband_row, next_subband_col] = size(next_subband);
    
    
    next_subband(1:current_subband_row, 1:current_subband_col) = current_subband;
    
    next_subband(1:current_subband_row, current_subband_col+1:next_subband_col) = block2;
    next_subband(current_subband_row+1: next_subband_row, 1:current_subband_col) = block3;
    next_subband(current_subband_row+1:next_subband_row, current_subband_col+1:next_subband_col) = block4;
    
    current_subband = next_subband;
end
output = current_subband;
end


function output = divide_et_impera(input, iterations)
output = input;
for i = 1:iterations
    
    for ii = 1:length(output)
        buffer((ii-1)*2+1:ii*2) = [ceil(output(ii)/2), floor(output(ii)/2)];
    end
    output = buffer;

end
end


function output = compute_subband_size(input, number_of_decompositions)

output(1) = input;
for l = 1:number_of_decompositions
    
    buffer = output(l);
    output(l) = floor(buffer/2);
    output(l+1) = ceil(buffer/2);
    
end

    output = rot90(rot90(output));

end




function [output, block_counter] = extract_subband_blocks(input, current_dims, maximum_block_size, block_counter)

r = current_dims(1);
c = current_dims(2);
  
r_max = maximum_block_size(1);
c_max = maximum_block_size(2);
        
%calculate the number of partitions applied in the subband         
partitions = floor(log((r*c)/(r_max*c_max))/log(4));

if partitions > 0
    
    number_of_blocks = 4^partitions;

    %extract blocks from input
    output = input(block_counter:block_counter+number_of_blocks-1);

    %reshape the output into the correct form

    output = reshape(output, [sqrt(length(output)), sqrt(length(output))]);

    output = cell2mat(output);

    block_counter = block_counter + number_of_blocks;
else
    output = input{block_counter};
    block_counter = block_counter+1;
    
    
    
end
end









