function [approx_layers, total_segmentation_cost] = lossy_progressive_segmentation_encoding(layer_stack, target_segmentation_rate)
% -------------------------------------------------------------------------
% 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        : lossy_progressive_segmentation_encoding_msc.m
% -------------------------------------------------------------------------
% This function receives a stack of binary shape images and a bit budget
% and returns that approximated shapes and the actual required amount of 
% bits. The contours are encoded encodes the contour of the 
%
% [layer_stack, total_segmentation_cost] = 
%      lossy_progressive_segmentation_encoding(layer_stack, target_segmentation_rate)
%
% INPUT:
%  - layer_stack              : Set of binary images.
%  - target_segmentation_rate : Bit budget for the contour encoding.
%
% OUTPUT:
%  - approx_layers            : Approximated shapes.
%  - total_segmentation_cost  : Actual cost.
%

% Tree parameters
max_error_vec = 10:-0.5:1;
max_delta     = 31;

% Labels parameters
[height, width, num_layers] = size(layer_stack);

% Output variable
approx_layers = zeros(height, width, num_layers);

tree            = cell(num_layers-1, 1);
first_iteration = true;
for max_error = max_error_vec

    % Store the results of the previous iteration in case the current
    % iteration exceeds the bit budget
    if ~first_iteration
        prev_tree          = tree;
        prev_required_bits = required_bits;
    end
    
    % Compute the contour trees for each layer 
    %do this for each layer
    for l = 1 : num_layers
        tree{l} = estimate_contours_tree(layer_stack(:,:,l), max_error, max_delta);
    end % end of l = 1 : num_layers

    % Obtain the bitstreams
    [bitstream, layer_limits] = tree2bitstream_v3(tree, max_delta, width, height);

    % Compress the bitstream
    field_bits    = log2(max_delta + 1) + 1;
    [substream]   = arithm_enc_stream(bitstream, layer_limits, field_bits);
    required_bits = length(substream{1}) * 8;
    
    % Check that the bit budget is not exceeded
    if required_bits > target_segmentation_rate
        if ~first_iteration
            tree          = prev_tree;
            required_bits = prev_required_bits;
        end
        break;
    end
    
    first_iteration = false;
end

% Reconstruct the layers for this given bitrate
for l = 1 : num_layers
    %if l < num_layers
        verts                = tree2contour(tree{l});
        approx_layers(:,:,l) = contour2shape(verts, width, height);
    %else
    %    approx_layers(:,:,l) = zeros(height, width);
    %    for ith_layer = 1 : num_layers-1
    %        approx_layers(:,:,l) = xor(approx_layers(:,:,l), approx_layers(:,:,ith_layer));
    %    end
    %    approx_layers(:,:,l) = ~approx_layers(:,:,l);    
    %end
end

% Output variable
total_segmentation_cost = required_bits;
