/*
  Copyright (c) 2005-2009, The Musepack Development Team
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

  * Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  * Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the following
  disclaimer in the documentation and/or other materials provided
  with the distribution.

  * Neither the name of the The Musepack Development Team nor the
  names of its contributors may be used to endorse or promote
  products derived from this software without specific prior
  written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file mpc_decoder.c
/// Core decoding routines and logic.

#include <string.h>
#include "mpcdec.h"
#include "minimax.h"
#include "decoder.h"
#include "huffman.h"
#include "internal.h"
#include "mpcdec_math.h"
#include "requant.h"
#include "mpc_bits_reader.h"

//SV7 tables
extern const mpc_lut_data   mpc_HuffQ [7] [2];
extern const mpc_lut_data   mpc_HuffHdr;
extern const mpc_huffman    mpc_table_HuffSCFI [ 4];
extern const mpc_lut_data   mpc_HuffDSCF;

//SV8 tables
extern const mpc_can_data mpc_can_Bands;
extern const mpc_can_data mpc_can_SCFI[2];
extern const mpc_can_data mpc_can_DSCF[2];
extern const mpc_can_data mpc_can_Res [2];
extern const mpc_can_data mpc_can_Q [8][2];
extern const mpc_can_data mpc_can_Q1;
extern const mpc_can_data mpc_can_Q9up;

//Decoder globals (g_Y_L and g_Y_R do not fit into iram for all targets)
static mpc_decoder g_mpc_decoder                 IBSS_ATTR;
static MPC_SAMPLE_FORMAT g_Y_L[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM;
static MPC_SAMPLE_FORMAT g_Y_R[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM;

//SV7 globals (decoding results for bundled quantizers (3- and 5-step))
static const mpc_int32_t g_sv7_idx30[] ICONST_ATTR = 
{-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1};
static const mpc_int32_t g_sv7_idx31[] ICONST_ATTR = 
{-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1};
static const mpc_int32_t g_sv7_idx32[] ICONST_ATTR = 
{-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1};
static const mpc_int32_t g_sv7_idx50[] ICONST_ATTR = 
{-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
static const mpc_int32_t g_sv7_idx51[] ICONST_ATTR = 
{-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};

//SV8 globals (decoding results for bundled quantizers (3- and 5-step))
static const mpc_int8_t g_sv8_idx50[125] ICONST_ATTR = 
{-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, 
 -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
 -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
 -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
 -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
static const mpc_int8_t g_sv8_idx51[125] ICONST_ATTR = 
{-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
 -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
 -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
 -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
 -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
static const mpc_int8_t g_sv8_idx52[125] ICONST_ATTR = 
{-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
static const mpc_int8_t g_sv8_HuffQ2_var[125] ICONST_ATTR =
{ 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6,
  5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 
  4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 
  5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 
  6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6};

//------------------------------------------------------------------------------
// types
//------------------------------------------------------------------------------
enum
{
    MEMSIZE   = MPC_DECODER_MEMSIZE, // overall buffer size
    MEMSIZE2  = (MEMSIZE/2),         // size of one buffer
    MEMMASK   = (MEMSIZE-1)
};

//------------------------------------------------------------------------------
// forward declarations
//------------------------------------------------------------------------------
void mpc_decoder_requantisierung   (mpc_decoder *d) 
                                    ICODE_ATTR_MPC_LARGE_IRAM;
void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r) 
                                    ICODE_ATTR_MPC_LARGE_IRAM;
void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r,
                                    mpc_bool_t is_key_frame);

//------------------------------------------------------------------------------
// macros
//------------------------------------------------------------------------------
#define REQUANT_M1_S1_SAMPLES(IDX) \
    *(YL+=IDX) = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); \
    *(YR+=IDX) = templ - tempr;

#define REQUANT_M1_S1(SUBFRAME) \
    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_M1_S1_SAMPLES( 0); \
        REQUANT_M1_S1_SAMPLES(32); \
        REQUANT_M1_S1_SAMPLES(32); \
        REQUANT_M1_S1_SAMPLES(32); \
    }

#define REQUANT_M1_S0_SAMPLES(IDX) \
    *(YR+=IDX) = *(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++);

#define REQUANT_M1_S0(SUBFRAME) \
    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_M1_S0_SAMPLES( 0); \
        REQUANT_M1_S0_SAMPLES(32); \
        REQUANT_M1_S0_SAMPLES(32); \
        REQUANT_M1_S0_SAMPLES(32); \
    }

#define REQUANT_M0_S1_SAMPLES(IDX) \
    *(YR+=IDX) = -(*(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++));

#define REQUANT_M0_S1(SUBFRAME) \
    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_M0_S1_SAMPLES( 0); \
        REQUANT_M0_S1_SAMPLES(32); \
        REQUANT_M0_S1_SAMPLES(32); \
        REQUANT_M0_S1_SAMPLES(32); \
    }

#define REQUANT_L1_R1_SAMPLES(IDX) \
    *(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++); \
    *(YR+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++);

#define REQUANT_L1_R1(SUBFRAME) \
    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_L1_R1_SAMPLES( 0); \
        REQUANT_L1_R1_SAMPLES(32); \
        REQUANT_L1_R1_SAMPLES(32); \
        REQUANT_L1_R1_SAMPLES(32); \
    }

#define REQUANT_L1_R0_SAMPLES(IDX) \
    *(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++); \
    *(YR+=IDX) = 0;

#define REQUANT_L1_R0(SUBFRAME) \
    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_L1_R0_SAMPLES( 0); \
        REQUANT_L1_R0_SAMPLES(32); \
        REQUANT_L1_R0_SAMPLES(32); \
        REQUANT_L1_R0_SAMPLES(32); \
    }

#define REQUANT_L0_R1_SAMPLES(IDX) \
    *(YL+=IDX) = 0; \
    *(YR+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++);

#define REQUANT_L0_R1(SUBFRAME) \
    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_L0_R1_SAMPLES( 0); \
        REQUANT_L0_R1_SAMPLES(32); \
        REQUANT_L0_R1_SAMPLES(32); \
        REQUANT_L0_R1_SAMPLES(32); \
    }

#define REQUANT_SILENCE_SAMPLES(IDX) \
    *(YR+=IDX) = *(YL+=IDX) = 0;

#define REQUANT_SILENCE \
    for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
        REQUANT_SILENCE_SAMPLES( 0); \
        REQUANT_SILENCE_SAMPLES(32); \
        REQUANT_SILENCE_SAMPLES(32); \
        REQUANT_SILENCE_SAMPLES(32); \
    }

/**
 * set the scf indexes for seeking use
 * needed only for sv7 seeking
 * @param d
 */
void mpc_decoder_reset_scf(mpc_decoder * d, int value)
{
    memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L );
    memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R );
}

static void mpc_decoder_setup(mpc_decoder *d)
{
    memset(d, 0, sizeof *d);

    d->__r1 = 1;
    d->__r2 = 1;
    d->Y_L = g_Y_L;
    d->Y_R = g_Y_R;
    
    memset(d->Y_L, 0, sizeof(g_Y_L));
    memset(d->Y_R, 0, sizeof(g_Y_R));

    mpc_decoder_init_quant(d, 1.0f);
}

static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
{
    d->stream_version     = si->stream_version;
    d->ms                 = si->ms;
    d->max_band           = si->max_band;
    d->channels           = si->channels;
    d->samples_to_skip    = MPC_DECODER_SYNTH_DELAY + si->beg_silence;

    if (si->stream_version == 7 && si->is_true_gapless)
        d->samples = ((si->samples + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH) * MPC_FRAME_LENGTH;
    else
        d->samples = si->samples;
}

mpc_decoder * mpc_decoder_init(mpc_streaminfo *si)
{
    mpc_decoder* p_tmp = &g_mpc_decoder;

    if (p_tmp != 0) {
        mpc_decoder_setup(p_tmp);
        mpc_decoder_set_streaminfo(p_tmp, si);
        huff_init_lut(LUT_DEPTH);
    }

    return p_tmp;
}

void mpc_decoder_exit(mpc_decoder *d)
{
    (void)d;
}

void mpc_decoder_decode_frame(mpc_decoder * d,
                              mpc_bits_reader * r,
                              mpc_frame_info * i)
{
    mpc_bits_reader r_sav = *r;
    mpc_int64_t samples_left;

    samples_left = d->samples - d->decoded_samples + MPC_DECODER_SYNTH_DELAY;

    if (samples_left <= 0 && d->samples != 0) {
        i->samples = 0;
        i->bits = -1;
        return;
    }

    if (d->stream_version == 8) {
        mpc_decoder_read_bitstream_sv8(d, r, i->is_key_frame);
    } else {
        mpc_decoder_read_bitstream_sv7(d, r);
    }

    if (d->samples_to_skip < MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY) {
        mpc_decoder_requantisierung(d);
        mpc_decoder_synthese_filter_float(d, i->buffer, d->channels);
    }

    d->decoded_samples += MPC_FRAME_LENGTH;

    // reconstruct exact filelength
    if (d->decoded_samples - d->samples < MPC_FRAME_LENGTH && d->stream_version == 7) {
        int last_frame_samples = mpc_bits_read(r, 11);
        if (d->decoded_samples == d->samples) {
            if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH;
            d->samples += last_frame_samples - MPC_FRAME_LENGTH;
            samples_left += last_frame_samples - MPC_FRAME_LENGTH;
        }
    }

    i->samples = samples_left > MPC_FRAME_LENGTH ? MPC_FRAME_LENGTH : samples_left < 0 ? 0 : (mpc_uint32_t) samples_left;
    i->bits = (mpc_uint32_t) (((r->buff - r_sav.buff) << 3) + r_sav.count - r->count);

    if (d->samples_to_skip) {
        if (i->samples <= d->samples_to_skip) {
            d->samples_to_skip -= i->samples;
            i->samples = 0;
        } else {
            i->samples -= d->samples_to_skip;
            
            /* move valid samples to beginning for channel 0. noninterleaved! */
            memmove(i->buffer, 
                    i->buffer + d->samples_to_skip, 
                    i->samples * sizeof(MPC_SAMPLE_FORMAT));
            /* move valid samples to beginning for channel 1. noninterleaved! */
            memmove(i->buffer + MPC_FRAME_LENGTH, 
                    i->buffer + MPC_FRAME_LENGTH + d->samples_to_skip, 
                    i->samples * sizeof(MPC_SAMPLE_FORMAT));
                    
            d->samples_to_skip = 0;
        }
    }
}

void
mpc_decoder_requantisierung(mpc_decoder *d)
{
    mpc_int32_t     Band;
    mpc_int32_t     n;
    MPC_SAMPLE_FORMAT facL;
    MPC_SAMPLE_FORMAT facR;
    MPC_SAMPLE_FORMAT templ;
    MPC_SAMPLE_FORMAT tempr;
    MPC_SAMPLE_FORMAT* YL;
    MPC_SAMPLE_FORMAT* YR;
    mpc_int16_t*    L;
    mpc_int16_t*    R;
    const mpc_int32_t Last_Band = d->max_band;

#ifdef MPC_FIXED_POINT
#if MPC_FIXED_POINT_FRACTPART == 14
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
    MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx])
#else

#error FIXME, Cc table is in 18.14 format

#endif
#else
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
    MPC_MULTIPLY(CcVal, d->SCF[SCF_idx])
#endif
    // requantization and scaling of subband-samples
    for ( Band = 0; Band <= Last_Band; Band++ ) {   // setting pointers
        YL = d->Y_L + Band;
        YR = d->Y_R + Band;
        L  = d->Q[Band].L;
        R  = d->Q[Band].R;
        /************************** MS-coded **************************/
        if ( d->MS_Flag [Band] ) {
            if ( d->Res_L [Band] ) {
                if ( d->Res_R [Band] ) {    // M!=0, S!=0
                    REQUANT_M1_S1(0);
                    REQUANT_M1_S1(1);
                    REQUANT_M1_S1(2);
                } else {                    // M!=0, S==0
                    REQUANT_M1_S0(0);
                    REQUANT_M1_S0(1);
                    REQUANT_M1_S0(2);
                }
            } else {
                if ( d->Res_R[Band] )       // M==0, S!=0
                {
                    REQUANT_M0_S1(0);
                    REQUANT_M0_S1(1);
                    REQUANT_M0_S1(2);
                } else {                    // M==0, S==0
                    REQUANT_SILENCE;
                }
            }
        }
        /************************** LR-coded **************************/
        else {
            if ( d->Res_L [Band] ) {
                if ( d->Res_R [Band] ) {    // L!=0, R!=0
                    REQUANT_L1_R1(0);
                    REQUANT_L1_R1(1);
                    REQUANT_L1_R1(2);
                } else {                    // L!=0, R==0
                    REQUANT_L1_R0(0);
                    REQUANT_L1_R0(1);
                    REQUANT_L1_R0(2);
                }
            }
            else {
                if ( d->Res_R [Band] ) {    // L==0, R!=0
                    REQUANT_L0_R1(0);
                    REQUANT_L0_R1(1);
                    REQUANT_L0_R1(2);
                } else {                    // L==0, R==0
                    REQUANT_SILENCE;
                }
            }
        }
    }
}

void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r)
{
    mpc_int32_t n, idx, Max_used_Band = 0;

    /***************************** Header *****************************/

    // first subband
    d->Res_L[0] = mpc_bits_read(r, 4);
    d->Res_R[0] = mpc_bits_read(r, 4);
    if (!(d->Res_L[0] == 0 && d->Res_R[0] == 0)) {
        if (d->ms)
            d->MS_Flag[0] = mpc_bits_read(r, 1);
        Max_used_Band = 1;
    }

    // consecutive subbands
    for ( n = 1; n <= d->max_band; n++ ) {
        idx   = mpc_bits_huff_lut(r, & mpc_HuffHdr);
        d->Res_L[n] = (idx!=4) ? d->Res_L[n - 1] + idx : (int) mpc_bits_read(r, 4);

        idx   = mpc_bits_huff_lut(r, & mpc_HuffHdr);
        d->Res_R[n] = (idx!=4) ? d->Res_R[n - 1] + idx : (int) mpc_bits_read(r, 4);

        if (!(d->Res_L[n] == 0 && d->Res_R[n] == 0)) {
            if (d->ms)
                d->MS_Flag[n] = mpc_bits_read(r, 1);
            Max_used_Band = n + 1;
        }
    }

    /****************************** SCFI ******************************/
    for ( n = 0; n < Max_used_Band; n++ ) {
        if (d->Res_L[n])
            d->SCFI_L[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI);
        if (d->Res_R[n])
            d->SCFI_R[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI);
    }

    /**************************** SCF/DSCF ****************************/
    for ( n = 0; n < Max_used_Band; n++ ) {
        mpc_int32_t * SCF = d->SCF_Index_L[n];
        mpc_uint32_t Res  = d->Res_L[n], SCFI = d->SCFI_L[n];
        do {
            if (Res) {
                switch (SCFI) {
                    case 1:
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6);
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6);
                        SCF[2] = SCF[1];
                        break;
                    case 3:
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6);
                        SCF[1] = SCF[0];
                        SCF[2] = SCF[1];
                        break;
                    case 2:
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6);
                        SCF[1] = SCF[0];
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6);
                        break;
                    case 0:
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6);
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6);
                        idx  = mpc_bits_huff_lut(r, & mpc_HuffDSCF);
                        SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6);
                        break;
                    default:
                        return;
                }
                if (SCF[0] > 1024)
                    SCF[0] = 0x8080;
                if (SCF[1] > 1024)
                    SCF[1] = 0x8080;
                if (SCF[2] > 1024)
                    SCF[2] = 0x8080;
            }
            Res = d->Res_R[n];
            SCFI = d->SCFI_R[n];
        } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n]));
    }

//     if (d->seeking == TRUE)
//         return;

    /***************************** Samples ****************************/
    for ( n = 0; n < Max_used_Band; n++ ) {
        mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n];
        do {
            mpc_int32_t k;
            const mpc_lut_data *Table;
            switch (Res) {
                case  -2: case  -3: case  -4: case  -5: case  -6: case  -7: case  -8: case  -9:
                case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: case 0:
                    break;
                case -1:
                    for (k=0; k<36; k++ ) {
                        mpc_uint32_t tmp = mpc_random_int(d);
                        q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >>  8) & 0xFF) + ((tmp >>  0) & 0xFF) - 510;
                    }
                    break;
                case 1:
                    Table = & mpc_HuffQ[0][mpc_bits_read(r, 1)];
                    for ( k = 0; k < 36; k += 3) {
                        idx = mpc_bits_huff_lut(r, Table);
                        q[k]     = g_sv7_idx30[idx];
                        q[k + 1] = g_sv7_idx31[idx];
                        q[k + 2] = g_sv7_idx32[idx];
                    }
                    break;
                case 2:
                    Table = & mpc_HuffQ[1][mpc_bits_read(r, 1)];
                    for ( k = 0; k < 36; k += 2) {
                        idx = mpc_bits_huff_lut(r, Table);
                        q[k]     = g_sv7_idx50[idx];
                        q[k + 1] = g_sv7_idx51[idx];
                    }
                    break;
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    Table = & mpc_HuffQ[Res - 1][mpc_bits_read(r, 1)];
                    for ( k = 0; k < 36; k++ )
                        q[k] = mpc_bits_huff_lut(r, Table);
                    break;
                case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
                    for ( k = 0; k < 36; k++ )
                        q[k] = (mpc_int32_t)mpc_bits_read(r, Res_bit[Res]) - Dc[Res];
                    break;
                default:
                    return;
            }

            Res = d->Res_R[n];
        } while (q == d->Q[n].L && (q = d->Q[n].R));
    }
}

void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame)
{
    mpc_int32_t n, Max_used_Band;
    const mpc_can_data * Table, * Tables[2];

    /***************************** Header *****************************/

    if (is_key_frame == MPC_TRUE) {
        Max_used_Band = mpc_bits_log_dec(r, d->max_band + 1);
    } else {
        Max_used_Band = d->last_max_band + mpc_bits_can_dec(r, & mpc_can_Bands);
        if (Max_used_Band > 32) Max_used_Band -= 33;
    }
    d->last_max_band = Max_used_Band;

    if (Max_used_Band) {
        d->Res_L[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]);
        d->Res_R[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]);
        if (d->Res_L[Max_used_Band-1] > 15) d->Res_L[Max_used_Band-1] -= 17;
        if (d->Res_R[Max_used_Band-1] > 15) d->Res_R[Max_used_Band-1] -= 17;
        for ( n = Max_used_Band - 2; n >= 0; n--) {
            d->Res_L[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_L[n + 1] > 2]) + d->Res_L[n + 1];
            if (d->Res_L[n] > 15) d->Res_L[n] -= 17;
            d->Res_R[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_R[n + 1] > 2]) + d->Res_R[n + 1];
            if (d->Res_R[n] > 15) d->Res_R[n] -= 17;
        }

        if (d->ms) {
            int cnt = 0, tot = 0;
            mpc_uint32_t tmp = 0;
            for( n = 0; n < Max_used_Band; n++)
                if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 )
                    tot++;
            cnt = mpc_bits_log_dec(r, tot);
            if (cnt != 0 && cnt != tot)
                tmp = mpc_bits_enum_dec(r, mini(cnt, tot-cnt), tot);
            if (cnt * 2 > tot) tmp = ~tmp;
            for( n = Max_used_Band - 1; n >= 0; n--)
                if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) {
                    d->MS_Flag[n] = tmp & 1;
                    tmp >>= 1;
                }
        }
    }

    for( n = Max_used_Band; n <= d->max_band; n++)
        d->Res_L[n] = d->Res_R[n] = 0;

    /****************************** SCFI ******************************/
    if (is_key_frame == MPC_TRUE){
        for( n = 0; n < 32; n++)
            d->DSCF_Flag_L[n] = d->DSCF_Flag_R[n] = 1; // new block -> force key frame
    }

    Tables[0] = & mpc_can_SCFI[0];
    Tables[1] = & mpc_can_SCFI[1];
    for ( n = 0; n < Max_used_Band; n++ ) {
        int tmp = 0, cnt = -1;
        if (d->Res_L[n]) cnt++;
        if (d->Res_R[n]) cnt++;
        if (cnt >= 0) {
            tmp = mpc_bits_can_dec(r, Tables[cnt]);
            if (d->Res_L[n]) d->SCFI_L[n] = tmp >> (2 * cnt);
            if (d->Res_R[n]) d->SCFI_R[n] = tmp & 3;
        }
    }

    /**************************** SCF/DSCF ****************************/

    for ( n = 0; n < Max_used_Band; n++ ) {
        mpc_int32_t * SCF = d->SCF_Index_L[n];
        mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n];
        mpc_bool_t * DSCF_Flag = &d->DSCF_Flag_L[n];

        do {
            if ( Res ) {
                int m;
                if (*DSCF_Flag == 1) {
                    SCF[0] = (mpc_int32_t)mpc_bits_read(r, 7) - 6;
                    *DSCF_Flag = 0;
                } else {
                    mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[1]);
                    if (tmp == 64)
                        tmp += mpc_bits_read(r, 6);
                    SCF[0] = ((SCF[2] - 25 + tmp) & 127) - 6;
                }
                for( m = 0; m < 2; m++){
                    if (((SCFI << m) & 2) == 0) {
                        mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[0]);
                        if (tmp == 31)
                            tmp = 64 + mpc_bits_read(r, 6);
                        SCF[m + 1] = ((SCF[m] - 25 + tmp) & 127) - 6;
                    } else
                        SCF[m + 1] = SCF[m];
                }
            }
            Res = d->Res_R[n];
            SCFI = d->SCFI_R[n];
            DSCF_Flag = &d->DSCF_Flag_R[n];
        } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n]));
    }

    /***************************** Samples ****************************/
    for ( n = 0; n < Max_used_Band; n++ ) {
        mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n];
        static const int thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8};
        do {
            mpc_int32_t k = 0, idx = 1;
            if (Res != 0) {
                if (Res == 2) {
                    Tables[0] = & mpc_can_Q [0][0];
                    Tables[1] = & mpc_can_Q [0][1];
                    idx = 2 * thres[Res];
                    for ( ; k < 36; k += 3) {
                        int tmp = mpc_bits_can_dec(r, Tables[idx > thres[Res]]);
                        q[k]     = g_sv8_idx50[tmp];
                        q[k + 1] = g_sv8_idx51[tmp];
                        q[k + 2] = g_sv8_idx52[tmp];
                        idx = (idx >> 1) + g_sv8_HuffQ2_var[tmp];
                    }
                } else if (Res == 1) {
                    Table = & mpc_can_Q1;
                    for( ; k < 36; ){
                        int kmax = k + 18;
                        mpc_uint_t cnt = mpc_bits_can_dec(r, Table);
                        idx = 0;
                        if (cnt > 0 && cnt < 18)
                            idx = mpc_bits_enum_dec(r, cnt <= 9 ? cnt : 18 - cnt, 18);
                        if (cnt > 9) idx = ~idx;
                        for ( ; k < kmax; k++) {
                            q[k] = 0;
                            if ( idx & (1 << 17) )
                                q[k] = (mpc_bits_read(r, 1) << 1) - 1;
                            idx <<= 1;
                        }
                    }
                } else if (Res == -1) {
                    for ( ; k<36; k++ ) {
                        mpc_uint32_t tmp = mpc_random_int(d);
                        q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >>  8) & 0xFF) + ((tmp >>  0) & 0xFF) - 510;
                    }
                } else if (Res <= 4) {
                    Table = & mpc_can_Q[1][Res - 3];
                    for ( ; k < 36; k += 2 ) {
                        union {
                            mpc_int8_t sym;
                            struct { mpc_int8_t s1:4, s2:4; };
                        } tmp;
                        tmp.sym = mpc_bits_can_dec(r, Table);
                        q[k]     = tmp.s1;
                        q[k + 1] = tmp.s2;
                    }
                } else if (Res <= 8) {
                    Tables[0] = & mpc_can_Q [Res - 3][0];
                    Tables[1] = & mpc_can_Q [Res - 3][1];
                    idx = 2 * thres[Res];
                    for ( ; k < 36; k++ ) {
                        q[k] = mpc_bits_can_dec(r, Tables[idx > thres[Res]]);
                        idx = (idx >> 1) + absi(q[k]);
                    }
                } else {
                    for ( ; k < 36; k++ ) {
                        q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up);
                        if (Res != 9)
                            q[k] = (q[k] << (Res - 9)) | mpc_bits_read(r, Res - 9);
                        q[k] -= Dc[Res];
                    }
                }
            }

            Res = d->Res_R[n];
        } while (q == d->Q[n].L && (q = d->Q[n].R));
    }
}

