#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 "the FLAC file stream",block_size,order;
OUTPUT "signed residual values";
VAR block_size "block size";
VAR order "predictor order";
VAR coding "coding method";
VAR rice "Rice";
VAR partition_residuals "residual count";
VAR partition_order "partition order";
VAR escape "escape code";
VAR MSB "MSB";
VAR LSB "LSB";
VAR unsigned_ "unsigned";
VAR residual "residual";
FUNC undefined_coding "undefined coding method error";
coding <- read 2 unsigned;
partition_order <- read 4 unsigned;
i <- 0;
;
for p <- 0 to 2 ^ partition_order {
    if coding == 0 {
        rice[p] <- read 4 unsigned;
    } elif coding == 1 {
        rice[p] <- read 5 unsigned;
    } else {
        undefined_coding();
    }
    if p == 0 {
        partition_residuals[0] <-
            floor(block_size / 2 ^ partition_order) - order;
    } else {
        partition_residuals[p] <-
            floor(block_size / 2 ^ partition_order);
    }
    if ((coding == 0) and (rice[p] == 15)) or
       ((coding == 1) and (rice[p] == 31)) {
        escape[p] <- read 5 unsigned;
        for j <- 0 to partition_residuals[p] {
            residual[i] <- read escape[p] signed;
            i <- i + 1;
        }
    } else {
        for j <- 0 to partition_residuals[p] {
            MSB[i] <- read unary 1;
            LSB[i] <- read rice[p] unsigned;
            unsigned_[i] <- MSB[i] * 2 ^ rice[p] + LSB[i];
            if (unsigned_[i] % 2) == 0 /*apply sign bit*/ {
                residual <- unsigned_[i] / 2;
            } else {
                residual[i] <- -floor(unsigned_[i] / 2) - 1;
            }
            i <- i + 1;
        }
    }
}
;
return residual;
