#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 block_size[s],min_channel[s],max_channel[s],
huffman_lsbs[s],quant_step_size[s],huffman_offset[s];
OUTPUT bypassed_lsbs[s],residual[s];
VAR block_size "block size";
VAR min_channel "min channel";
VAR max_channel "max channel";
VAR bypassed_lsbs "bypassed LSBs";
VAR residual "residual";
VAR lsb_bits "LSB bits";
VAR huffman_lsbs "Huffman LSBs";
VAR quant_step_size "quant step size";
VAR codebook "codebook";
VAR sign_shift "sign shift";
VAR huffman_offset "Huffman offset";
VAR signed_huffman_offset "signed Huffman offset";
VAR matrix_count "matrix count";
VAR lsb_bypass "LSB bypass";
VAR MSB "MSB";
VAR LSB "LSB";
FUNC read_huffman "read Huffman code";
for c <- min_channel[s] to (max_channel[s] + 1)
/*calculate signed Huffman offset*/ {
    lsb_bits[s][c] <- huffman_lsbs[s][c] - quant_step_size[s][c];
    if codebook[s][c] > 0 {
        sign_shift <- lsb_bits[s][c] + 2 - codebook[s][c];
        if sign_shift >= 0 {
            signed_huffman_offset[s][c] <-
                huffman_offset[s][c] - 7 * 2 ^ lsb_bits[s][c] - 2 ^ sign_shift;
        } else {
            signed_huffman_offset[s][c] <-
                huffman_offset[s][c] - 7 * 2 ^ lsb_bits[s][c];
        }
    } else {
        sign_shift <- lsb_bits[s][c] - 1;
        if sign_shift >= 0 {
            signed_huffman_offset[s][c] <-
                huffman_offset[s][c] - 2 ^ sign_shift;
        } else {
            signed_huffman_offset[s][c] <- huffman_offset[s][c];
        }
    }
}
for i <- 0 to block_size {
    for m <- 0 to matrix_count[s] {
        bypassed_lsbs[s][m][i] <-
            (read 1 unsigned) if (lsb_bypass[s][m] == 1) else 0;
    }
    for c <- min_channel[s] to (max_channel[s] + 1) {
        if codebook[s][c] == 0 {
            MSB <- 0;
        } else {
            MSB <- read_huffman(codebook[s][c]);
            assert MSB >= 0;
        }
        LSB <- read (lsb_bits[s][c]) unsigned;
        residual[s][c][i] <-
           ((MSB * 2 ^ lsb_bits[s][c]) + LSB + signed_huffman_offset[s][c]) *
           2 ^ quant_step_size[s][c];
    }
}
return bypassed_lsbs[s],residual[s];
