function [tree, width, height] = bitstream2tree(bitstream, max_vert_deltas)
% -------------------------------------------------------------------------
% MSc Project - MSc in Communications and Signal Processing
% Department of Electrical and Electronic Engineering
% Imperial College London, 2011
%
% Supervisor  : Dr Pier Luigi Dragotti
% Contributor : Andriy Gelman
% Author      : Jon Onativia Bravo
%
% File        : tree2bitstream.m
% -------------------------------------------------------------------------
% 
%
% [bitstream] = tree2bitstream(tree, max_vert_deltas)
%
% INPUT:
%  - 
%
% OUTPUT:
%  - 
%

b_idx = 1;

field_bits = 16;
width      = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
b_idx      = b_idx + field_bits;
height     = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
b_idx      = b_idx + field_bits;

field_bits    = 8;
num_of_layers = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
b_idx         = b_idx + field_bits;

tree = cell(num_of_layers, 1);

max_depth = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
b_idx     = b_idx + field_bits;

for ith_layer = 1 : num_of_layers
    field_bits      = 8;
    num_of_contours = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
    b_idx           = b_idx + field_bits;
    
    % Allocate the contours cells of this specific layer
    tree{ith_layer} = cell(1, num_of_contours);

    for ith_contour = 1 : num_of_contours
        % Allocate the different levels of this contour
        tree{ith_layer}{ith_contour} = cell(max_depth, 1);
        
        field_bits = 8;
        seg_len    = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
        b_idx      = b_idx + field_bits;
        
        % Allocate the firts level's vertices array
        verts = zeros(2, seg_len);
        
        field_bits = 16;
        verts(1,1) = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
        b_idx      = b_idx + field_bits;
        verts(2,1) = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false);
        b_idx      = b_idx + field_bits;
        
        field_bits = log2(max_vert_deltas(1) + 1) + 1;
        for ith_vert = 2 : seg_len
            verts(1,ith_vert) = verts(1,ith_vert-1) + bin2dec(bitstream(b_idx:b_idx+field_bits-1));
            b_idx             = b_idx + field_bits;
            verts(2,ith_vert) = verts(2,ith_vert-1) + bin2dec(bitstream(b_idx:b_idx+field_bits-1));
            b_idx             = b_idx + field_bits;
        end
        
        % Store the first level's verts
        tree{ith_layer}{ith_contour}{1} = verts;
    end
    
end


% Fill the other levels
for depth = 2 : max_depth
    for ith_layer = 1 : num_of_layers
        num_of_contours = length(tree{ith_layer});
            
        for ith_contour = 1 : num_of_contours
            
            prev_verts = tree{ith_layer}{ith_contour}{depth-1};
            if iscell(prev_verts)
                prev_verts    = cell2mat(prev_verts);
            end
            num_of_prev_verts = size(prev_verts, 2);
            
            % The number of the previous levels' vertices it's the number
            % of current's level segments
            tree{ith_layer}{ith_contour}{depth} = cell(1, num_of_prev_verts);
            
            for ith_seg = 1 : num_of_prev_verts
                % Read the current's segment length from the bitstream
                field_bits = 8;
                seg_len    = bin2dec(bitstream(b_idx:b_idx+field_bits-1), false) + 1;
                b_idx      = b_idx + field_bits;
                
                % Allocate segment's vertices array
                verts = zeros(2, seg_len);
                
                % The first vertex correspond to the previous level's
                % vertex
                verts(1,1) = prev_verts(1,ith_seg);
                verts(2,1) = prev_verts(2,ith_seg);
                
                field_bits = log2(max_vert_deltas(depth) + 1) + 1;
                % The following vertices are retrieved from the bitstream
                for ith_vert = 2 : seg_len
                    verts(1,ith_vert) = verts(1,ith_vert-1) + bin2dec(bitstream(b_idx:b_idx+field_bits-1));
                    b_idx             = b_idx + field_bits;
                    verts(2,ith_vert) = verts(2,ith_vert-1) + bin2dec(bitstream(b_idx:b_idx+field_bits-1));
                    b_idx             = b_idx + field_bits;
                end
                
                % Store the vertices array in the tree
                tree{ith_layer}{ith_contour}{depth}{ith_seg} = verts;
            end
        end
        
    end
end


end