#This work is licensed under the
#Creative Commons Attribution-Share Alike 3.0 United States License.
#To view a copy of this license, visit
#http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
#Creative Commons,
#171 Second Street, Suite 300,
#San Francisco, California, 94105, USA.

INPUT "MLP block data",restart_header[s],decoding_parameters[s];
OUTPUT filtered[s],bypassed_lsbs[s],restart_header[s],decoding_parameters[s];
VAR restart_header_present "restart header present";
VAR restart_header "restart header";
VAR max_channel "max channel";
VAR min_channel "min channel";
VAR decoding_parameters "decoding parameters";
VAR block_size "block size";
VAR quant_step_size "quant step size";
VAR channel_params "channel parameters";
VAR huffman_offset "Huffman offset";
VAR huffman_lsbs "Huffman LSBs";
VAR fir_order "FIR order";
VAR fir_shift "FIR shift";
VAR fir_coeff "FIR coefficient";
VAR fir_state "FIR state";
VAR iir_order "IIR order";
VAR iir_shift "IIR shift";
VAR iir_coeff "IIR coefficient";
VAR iir_state "IIR state";
VAR filtered "filtered";
VAR residual "residual";
VAR bypassed_lsbs "bypassed LSBs";
FUNC read_restart_header "read restart header" "mlp:readrestartheader";
FUNC read_decoding_parameters "read decoding parameters"
"mlp:readdecodingparams";
FUNC read_residual "read residual" "mlp:read_residuals";
FUNC filter_channel "filter channel" "mlp:channel_filtering";
if (read 1 unsigned) == 1 /*decoding parameters present*/ {
    restart_header_present <- read 1 unsigned;
    if restart_header_present == 1 {
        restart_header[s] <- read_restart_header();
    }
    min_channel[s],max_channel[s] <- restart_header[s];
    decoding_parameters[s] <- read_decoding_parameters(
        restart_header_present[s],
        min_channel[s],max_channel[s],
        decoding_parameters[s]);
} else {
    min_channel[s],max_channel[s] <- restart_header[s];
}

block_size[s],
quant_step_size[s],
channel_params[s] <- decoding_parameters[s];
huffman_offset[s],huffman_lsbs[s] <- channel_params[s];
bypassed_lsbs[s],residual[s] <- read_residual(block_size[s],
                                              min_channel[s],
                                              max_channel[s],
                                              huffman_lsbs[s],
                                              quant_step_size[s],
                                              huffman_offset[s]);
for c <- min_channel[s] to (max_channel[s] + 1) {
    fir_order[s][c],
    fir_shift[s][c],
    fir_coeff[s][c],
    fir_state[s][c],
    iir_order[s][c],
    iir_shift[s][c],
    iir_coeff[s][c],
    iir_state[s][c] <- channel_params[s][c];
    filtered[s][c],fir_state[s][c],iir_state[s][c] <-
    filter_channel(block_size[s],
                   quant_step_size[s][c],
                   residual[s][c],
                   fir_order[s][c],
                   fir_shift[s][c],
                   fir_coeff[s][c],
                   fir_state[s][c],
                   iir_order[s][c],
                   iir_shift[s][c],
                   iir_coeff[s][c],
                   iir_state[s][c]);
    channel_params[s][c] <- fir_state[s][c],iir_state[s][c];
}
decoding_parameters[s] <- channel_params[s][c];
return filtered[s],bypassed_lsbs[s],restart_header[s],decoding_parameters[s];
