/*
 * IMC compatible decoder
 * Copyright (c) 2002-2004 Maxim Poliakovski
 * Copyright (c) 2006 Benjamin Larsson
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 *  @file libavcodec/imc.c IMC - Intel Music Coder
 *  A mdct based codec using a 256 points large transform
 *  divied into 32 bands with some mix of scale factors.
 *  Only mono is supported.
 *
 */


#include <math.h>
#include <stddef.h>
#include <stdio.h>

#define ALT_BITSTREAM_READER
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"

#include "imcdata.h"

#define IMC_BLOCK_SIZE 64
#define IMC_FRAME_ID 0x21
#define BANDS 32
#define COEFFS 256

typedef struct {
    float old_floor[BANDS];
    float flcoeffs1[BANDS];
    float flcoeffs2[BANDS];
    float flcoeffs3[BANDS];
    float flcoeffs4[BANDS];
    float flcoeffs5[BANDS];
    float flcoeffs6[BANDS];
    float CWdecoded[COEFFS];

    /** MDCT tables */
    //@{
    float mdct_sine_window[COEFFS];
    float post_cos[COEFFS];
    float post_sin[COEFFS];
    float pre_coef1[COEFFS];
    float pre_coef2[COEFFS];
    float last_fft_im[COEFFS];
    //@}

    int bandWidthT[BANDS];     ///< codewords per band
    int bitsBandT[BANDS];      ///< how many bits per codeword in band
    int CWlengthT[COEFFS];     ///< how many bits in each codeword
    int levlCoeffBuf[BANDS];
    int bandFlagsBuf[BANDS];   ///< flags for each band
    int sumLenArr[BANDS];      ///< bits for all coeffs in band
    int skipFlagRaw[BANDS];    ///< skip flags are stored in raw form or not
    int skipFlagBits[BANDS];   ///< bits used to code skip flags
    int skipFlagCount[BANDS];  ///< skipped coeffients per band
    int skipFlags[COEFFS];     ///< skip coefficient decoding or not
    int codewords[COEFFS];     ///< raw codewords read from bitstream
    float sqrt_tab[30];
    GetBitContext gb;
    int decoder_reset;
    float one_div_log2;

    DSPContext dsp;
    FFTContext fft;
    DECLARE_ALIGNED_16(FFTComplex, samples[COEFFS/2]);
    DECLARE_ALIGNED_16(float, out_samples[COEFFS]);
} IMCContext;

static VLC huffman_vlc[4][4];

#define VLC_TABLES_SIZE 9512

static const int vlc_offsets[17] = {
    0,     640, 1156, 1732, 2308, 2852, 3396, 3924,
    4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE};

static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2];

static av_cold int imc_decode_init(AVCodecContext * avctx)
{
    int i, j;
    IMCContext *q = avctx->priv_data;
    double r1, r2;

    q->decoder_reset = 1;

    for(i = 0; i < BANDS; i++)
        q->old_floor[i] = 1.0;

    /* Build mdct window, a simple sine window normalized with sqrt(2) */
    ff_sine_window_init(q->mdct_sine_window, COEFFS);
    for(i = 0; i < COEFFS; i++)
        q->mdct_sine_window[i] *= sqrt(2.0);
    for(i = 0; i < COEFFS/2; i++){
        q->post_cos[i] = cos(i / 256.0 * M_PI);
        q->post_sin[i] = sin(i / 256.0 * M_PI);

        r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
        r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);

        if (i & 0x1)
        {
            q->pre_coef1[i] =  (r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
        }
        else
        {
            q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] =  (r1 - r2) * sqrt(2.0);
        }

        q->last_fft_im[i] = 0;
    }

    /* Generate a square root table */

    for(i = 0; i < 30; i++) {
        q->sqrt_tab[i] = sqrt(i);
    }

    /* initialize the VLC tables */
    for(i = 0; i < 4 ; i++) {
        for(j = 0; j < 4; j++) {
            huffman_vlc[i][j].table = &vlc_tables[vlc_offsets[i * 4 + j]];
            huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j];
            init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i],
                     imc_huffman_lens[i][j], 1, 1,
                     imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC);
        }
    }
    q->one_div_log2 = 1/log(2);

    ff_fft_init(&q->fft, 7, 1);
    dsputil_init(&q->dsp, avctx);
    avctx->sample_fmt = SAMPLE_FMT_S16;
    avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO;
    return 0;
}

static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeffs2, int* bandWidthT,
                                float* flcoeffs3, float* flcoeffs5)
{
    float   workT1[BANDS];
    float   workT2[BANDS];
    float   workT3[BANDS];
    float   snr_limit = 1.e-30;
    float   accum = 0.0;
    int i, cnt2;

    for(i = 0; i < BANDS; i++) {
        flcoeffs5[i] = workT2[i] = 0.0;
        if (bandWidthT[i]){
            workT1[i] = flcoeffs1[i] * flcoeffs1[i];
            flcoeffs3[i] = 2.0 * flcoeffs2[i];
        } else {
            workT1[i] = 0.0;
            flcoeffs3[i] = -30000.0;
        }
        workT3[i] = bandWidthT[i] * workT1[i] * 0.01;
        if (workT3[i] <= snr_limit)
            workT3[i] = 0.0;
    }

    for(i = 0; i < BANDS; i++) {
        for(cnt2 = i; cnt2 < cyclTab[i]; cnt2++)
            flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];
        workT2[cnt2-1] = workT2[cnt2-1] + workT3[i];
    }

    for(i = 1; i < BANDS; i++) {
        accum = (workT2[i-1] + accum) * imc_weights1[i-1];
        flcoeffs5[i] += accum;
    }

    for(i = 0; i < BANDS; i++)
        workT2[i] = 0.0;

    for(i = 0; i < BANDS; i++) {
        for(cnt2 = i-1; cnt2 > cyclTab2[i]; cnt2--)
            flcoeffs5[cnt2] += workT3[i];
        workT2[cnt2+1] += workT3[i];
    }

    accum = 0.0;

    for(i = BANDS-2; i >= 0; i--) {
        accum = (workT2[i+1] + accum) * imc_weights2[i];
        flcoeffs5[i] += accum;
        //there is missing code here, but it seems to never be triggered
    }
}


static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* levlCoeffs)
{
    int i;
    VLC *hufftab[4];
    int start = 0;
    const uint8_t *cb_sel;
    int s;

    s = stream_format_code >> 1;
    hufftab[0] = &huffman_vlc[s][0];
    hufftab[1] = &huffman_vlc[s][1];
    hufftab[2] = &huffman_vlc[s][2];
    hufftab[3] = &huffman_vlc[s][3];
    cb_sel = imc_cb_select[s];

    if(stream_format_code & 4)
        start = 1;
    if(start)
        levlCoeffs[0] = get_bits(&q->gb, 7);
    for(i = start; i < BANDS; i++){
        levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, hufftab[cb_sel[i]]->bits, 2);
        if(levlCoeffs[i] == 17)
            levlCoeffs[i] += get_bits(&q->gb, 4);
    }
}

static void imc_decode_level_coefficients(IMCContext* q, int* levlCoeffBuf, float* flcoeffs1,
                                         float* flcoeffs2)
{
    int i, level;
    float tmp, tmp2;
    //maybe some frequency division thingy

    flcoeffs1[0] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
    flcoeffs2[0] = log(flcoeffs1[0])/log(2);
    tmp = flcoeffs1[0];
    tmp2 = flcoeffs2[0];

    for(i = 1; i < BANDS; i++) {
        level = levlCoeffBuf[i];
        if (level == 16) {
            flcoeffs1[i] = 1.0;
            flcoeffs2[i] = 0.0;
        } else {
            if (level < 17)
                level -=7;
            else if (level <= 24)
                level -=32;
            else
                level -=16;

            tmp  *= imc_exp_tab[15 + level];
            tmp2 += 0.83048 * level;  // 0.83048 = log2(10) * 0.25
            flcoeffs1[i] = tmp;
            flcoeffs2[i] = tmp2;
        }
    }
}


static void imc_decode_level_coefficients2(IMCContext* q, int* levlCoeffBuf, float* old_floor, float* flcoeffs1,
                                          float* flcoeffs2) {
    int i;
        //FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors
        //      and flcoeffs2 old scale factors
        //      might be incomplete due to a missing table that is in the binary code
    for(i = 0; i < BANDS; i++) {
        flcoeffs1[i] = 0;
        if(levlCoeffBuf[i] < 16) {
            flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i];
            flcoeffs2[i] = (levlCoeffBuf[i]-7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25
        } else {
            flcoeffs1[i] = old_floor[i];
        }
    }
}

/**
 * Perform bit allocation depending on bits available
 */
static int bit_allocation (IMCContext* q, int stream_format_code, int freebits, int flag) {
    int i, j;
    const float limit = -1.e20;
    float highest = 0.0;
    int indx;
    int t1 = 0;
    int t2 = 1;
    float summa = 0.0;
    int iacc = 0;
    int summer = 0;
    int rres, cwlen;
    float lowest = 1.e10;
    int low_indx = 0;
    float workT[32];
    int flg;
    int found_indx = 0;

    for(i = 0; i < BANDS; i++)
        highest = FFMAX(highest, q->flcoeffs1[i]);

    for(i = 0; i < BANDS-1; i++) {
        q->flcoeffs4[i] = q->flcoeffs3[i] - log(q->flcoeffs5[i])/log(2);
    }
    q->flcoeffs4[BANDS - 1] = limit;

    highest = highest * 0.25;

    for(i = 0; i < BANDS; i++) {
        indx = -1;
        if ((band_tab[i+1] - band_tab[i]) == q->bandWidthT[i])
            indx = 0;

        if ((band_tab[i+1] - band_tab[i]) > q->bandWidthT[i])
            indx = 1;

        if (((band_tab[i+1] - band_tab[i])/2) >= q->bandWidthT[i])
            indx = 2;

        if (indx == -1)
            return -1;

        q->flcoeffs4[i] = q->flcoeffs4[i] + xTab[(indx*2 + (q->flcoeffs1[i] < highest)) * 2 + flag];
    }

    if (stream_format_code & 0x2) {
        q->flcoeffs4[0] = limit;
        q->flcoeffs4[1] = limit;
        q->flcoeffs4[2] = limit;
        q->flcoeffs4[3] = limit;
    }

    for(i = (stream_format_code & 0x2)?4:0; i < BANDS-1; i++) {
        iacc += q->bandWidthT[i];
        summa += q->bandWidthT[i] * q->flcoeffs4[i];
    }
    q->bandWidthT[BANDS-1] = 0;
    summa = (summa * 0.5 - freebits) / iacc;


    for(i = 0; i < BANDS/2; i++) {
        rres = summer - freebits;
        if((rres >= -8) && (rres <= 8)) break;

        summer = 0;
        iacc = 0;

        for(j = (stream_format_code & 0x2)?4:0; j < BANDS; j++) {
            cwlen = av_clip((int)((q->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);

            q->bitsBandT[j] = cwlen;
            summer += q->bandWidthT[j] * cwlen;

            if (cwlen > 0)
                iacc += q->bandWidthT[j];
        }

        flg = t2;
        t2 = 1;
        if (freebits < summer)
            t2 = -1;
        if (i == 0)
            flg = t2;
        if(flg != t2)
            t1++;

        summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;
    }

    for(i = (stream_format_code & 0x2)?4:0; i < BANDS; i++) {
        for(j = band_tab[i]; j < band_tab[i+1]; j++)
            q->CWlengthT[j] = q->bitsBandT[i];
    }

    if (freebits > summer) {
        for(i = 0; i < BANDS; i++) {
            workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415);
        }

        highest = 0.0;

        do{
            if (highest <= -1.e20)
                break;

            found_indx = 0;
            highest = -1.e20;

            for(i = 0; i < BANDS; i++) {
                if (workT[i] > highest) {
                    highest = workT[i];
                    found_indx = i;
                }
            }

            if (highest > -1.e20) {
                workT[found_indx] -= 2.0;
                if (++(q->bitsBandT[found_indx]) == 6)
                    workT[found_indx] = -1.e20;

                for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (freebits > summer); j++){
                    q->CWlengthT[j]++;
                    summer++;
                }
            }
        }while (freebits > summer);
    }
    if (freebits < summer) {
        for(i = 0; i < BANDS; i++) {
            workT[i] = q->bitsBandT[i] ? (q->bitsBandT[i] * -2 + q->flcoeffs4[i] + 1.585) : 1.e20;
        }
        if (stream_format_code & 0x2) {
            workT[0] = 1.e20;
            workT[1] = 1.e20;
            workT[2] = 1.e20;
            workT[3] = 1.e20;
        }
        while (freebits < summer){
            lowest = 1.e10;
            low_indx = 0;
            for(i = 0; i < BANDS; i++) {
                if (workT[i] < lowest) {
                    lowest = workT[i];
                    low_indx = i;
                }
            }
            //if(lowest >= 1.e10) break;
            workT[low_indx] = lowest + 2.0;

            if (!(--q->bitsBandT[low_indx]))
                workT[low_indx] = 1.e20;

            for(j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++){
                if(q->CWlengthT[j] > 0){
                    q->CWlengthT[j]--;
                    summer--;
                }
            }
        }
    }
    return 0;
}

static void imc_get_skip_coeff(IMCContext* q) {
    int i, j;

    memset(q->skipFlagBits, 0, sizeof(q->skipFlagBits));
    memset(q->skipFlagCount, 0, sizeof(q->skipFlagCount));
    for(i = 0; i < BANDS; i++) {
        if (!q->bandFlagsBuf[i] || !q->bandWidthT[i])
            continue;

        if (!q->skipFlagRaw[i]) {
            q->skipFlagBits[i] = band_tab[i+1] - band_tab[i];

            for(j = band_tab[i]; j < band_tab[i+1]; j++) {
                if ((q->skipFlags[j] = get_bits1(&q->gb)))
                    q->skipFlagCount[i]++;
            }
        } else {
            for(j = band_tab[i]; j < (band_tab[i+1]-1); j += 2) {
                if(!get_bits1(&q->gb)){//0
                    q->skipFlagBits[i]++;
                    q->skipFlags[j]=1;
                    q->skipFlags[j+1]=1;
                    q->skipFlagCount[i] += 2;
                }else{
                    if(get_bits1(&q->gb)){//11
                        q->skipFlagBits[i] +=2;
                        q->skipFlags[j]=0;
                        q->skipFlags[j+1]=1;
                        q->skipFlagCount[i]++;
                    }else{
                        q->skipFlagBits[i] +=3;
                        q->skipFlags[j+1]=0;
                        if(!get_bits1(&q->gb)){//100
                            q->skipFlags[j]=1;
                            q->skipFlagCount[i]++;
                        }else{//101
                            q->skipFlags[j]=0;
                        }
                    }
                }
            }

            if (j < band_tab[i+1]) {
                q->skipFlagBits[i]++;
                if ((q->skipFlags[j] = get_bits1(&q->gb)))
                    q->skipFlagCount[i]++;
            }
        }
    }
}

/**
 * Increase highest' band coefficient sizes as some bits won't be used
 */
static void imc_adjust_bit_allocation (IMCContext* q, int summer) {
    float workT[32];
    int corrected = 0;
    int i, j;
    float highest = 0;
    int found_indx=0;

    for(i = 0; i < BANDS; i++) {
        workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415);
    }

    while (corrected < summer) {
        if(highest <= -1.e20)
            break;

        highest = -1.e20;

        for(i = 0; i < BANDS; i++) {
            if (workT[i] > highest) {
                highest = workT[i];
                found_indx = i;
            }
        }

        if (highest > -1.e20) {
            workT[found_indx] -= 2.0;
            if (++(q->bitsBandT[found_indx]) == 6)
                workT[found_indx] = -1.e20;

            for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) {
                if (!q->skipFlags[j] && (q->CWlengthT[j] < 6)) {
                    q->CWlengthT[j]++;
                    corrected++;
                }
            }
        }
    }
}

static void imc_imdct256(IMCContext *q) {
    int i;
    float re, im;

    /* prerotation */
    for(i=0; i < COEFFS/2; i++){
        q->samples[i].re = -(q->pre_coef1[i] * q->CWdecoded[COEFFS-1-i*2]) -
                           (q->pre_coef2[i] * q->CWdecoded[i*2]);
        q->samples[i].im = (q->pre_coef2[i] * q->CWdecoded[COEFFS-1-i*2]) -
                           (q->pre_coef1[i] * q->CWdecoded[i*2]);
    }

    /* FFT */
    ff_fft_permute(&q->fft, q->samples);
    ff_fft_calc (&q->fft, q->samples);

    /* postrotation, window and reorder */
    for(i = 0; i < COEFFS/2; i++){
        re = (q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
        im = (-q->samples[i].im * q->post_cos[i]) - (q->samples[i].re * q->post_sin[i]);
        q->out_samples[i*2] = (q->mdct_sine_window[COEFFS-1-i*2] * q->last_fft_im[i]) + (q->mdct_sine_window[i*2] * re);
        q->out_samples[COEFFS-1-i*2] = (q->mdct_sine_window[i*2] * q->last_fft_im[i]) - (q->mdct_sine_window[COEFFS-1-i*2] * re);
        q->last_fft_im[i] = im;
    }
}

static int inverse_quant_coeff (IMCContext* q, int stream_format_code) {
    int i, j;
    int middle_value, cw_len, max_size;
    const float* quantizer;

    for(i = 0; i < BANDS; i++) {
        for(j = band_tab[i]; j < band_tab[i+1]; j++) {
            q->CWdecoded[j] = 0;
            cw_len = q->CWlengthT[j];

            if (cw_len <= 0 || q->skipFlags[j])
                continue;

            max_size = 1 << cw_len;
            middle_value = max_size >> 1;

            if (q->codewords[j] >= max_size || q->codewords[j] < 0)
                return -1;

            if (cw_len >= 4){
                quantizer = imc_quantizer2[(stream_format_code & 2) >> 1];
                if (q->codewords[j] >= middle_value)
                    q->CWdecoded[j] = quantizer[q->codewords[j] - 8] * q->flcoeffs6[i];
                else
                    q->CWdecoded[j] = -quantizer[max_size - q->codewords[j] - 8 - 1] * q->flcoeffs6[i];
            }else{
                quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (q->bandFlagsBuf[i] << 1)];
                if (q->codewords[j] >= middle_value)
                    q->CWdecoded[j] = quantizer[q->codewords[j] - 1] * q->flcoeffs6[i];
                else
                    q->CWdecoded[j] = -quantizer[max_size - 2 - q->codewords[j]] * q->flcoeffs6[i];
            }
        }
    }
    return 0;
}


static int imc_get_coeffs (IMCContext* q) {
    int i, j, cw_len, cw;

    for(i = 0; i < BANDS; i++) {
        if(!q->sumLenArr[i]) continue;
        if (q->bandFlagsBuf[i] || q->bandWidthT[i]) {
            for(j = band_tab[i]; j < band_tab[i+1]; j++) {
                cw_len = q->CWlengthT[j];
                cw = 0;

                if (get_bits_count(&q->gb) + cw_len > 512){
//av_log(NULL,0,"Band %i coeff %i cw_len %i\n",i,j,cw_len);
                    return -1;
                }

                if(cw_len && (!q->bandFlagsBuf[i] || !q->skipFlags[j]))
                    cw = get_bits(&q->gb, cw_len);

                q->codewords[j] = cw;
            }
        }
    }
    return 0;
}

static int imc_decode_frame(AVCodecContext * avctx,
                            void *data, int *data_size,
                            const uint8_t * buf, int buf_size)
{

    IMCContext *q = avctx->priv_data;

    int stream_format_code;
    int imc_hdr, i, j;
    int flag;
    int bits, summer;
    int counter, bitscount;
    uint16_t buf16[IMC_BLOCK_SIZE / 2];

    if (buf_size < IMC_BLOCK_SIZE) {
        av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n");
        return -1;
    }
    for(i = 0; i < IMC_BLOCK_SIZE / 2; i++)
        buf16[i] = bswap_16(((const uint16_t*)buf)[i]);

    init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);

    /* Check the frame header */
    imc_hdr = get_bits(&q->gb, 9);
    if (imc_hdr != IMC_FRAME_ID) {
        av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n");
        av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr);
        return -1;
    }
    stream_format_code = get_bits(&q->gb, 3);

    if(stream_format_code & 1){
        av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code);
        return -1;
    }

//    av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code);

    if (stream_format_code & 0x04)
        q->decoder_reset = 1;

    if(q->decoder_reset) {
        memset(q->out_samples, 0, sizeof(q->out_samples));
        for(i = 0; i < BANDS; i++)q->old_floor[i] = 1.0;
        for(i = 0; i < COEFFS; i++)q->CWdecoded[i] = 0;
        q->decoder_reset = 0;
    }

    flag = get_bits1(&q->gb);
    imc_read_level_coeffs(q, stream_format_code, q->levlCoeffBuf);

    if (stream_format_code & 0x4)
        imc_decode_level_coefficients(q, q->levlCoeffBuf, q->flcoeffs1, q->flcoeffs2);
    else
        imc_decode_level_coefficients2(q, q->levlCoeffBuf, q->old_floor, q->flcoeffs1, q->flcoeffs2);

    memcpy(q->old_floor, q->flcoeffs1, 32 * sizeof(float));

    counter = 0;
    for (i=0 ; i<BANDS ; i++) {
        if (q->levlCoeffBuf[i] == 16) {
            q->bandWidthT[i] = 0;
            counter++;
        } else
            q->bandWidthT[i] = band_tab[i+1] - band_tab[i];
    }
    memset(q->bandFlagsBuf, 0, BANDS * sizeof(int));
    for(i = 0; i < BANDS-1; i++) {
        if (q->bandWidthT[i])
            q->bandFlagsBuf[i] = get_bits1(&q->gb);
    }

    imc_calculate_coeffs(q, q->flcoeffs1, q->flcoeffs2, q->bandWidthT, q->flcoeffs3, q->flcoeffs5);

    bitscount = 0;
    /* first 4 bands will be assigned 5 bits per coefficient */
    if (stream_format_code & 0x2) {
        bitscount += 15;

        q->bitsBandT[0] = 5;
        q->CWlengthT[0] = 5;
        q->CWlengthT[1] = 5;
        q->CWlengthT[2] = 5;
        for(i = 1; i < 4; i++){
            bits = (q->levlCoeffBuf[i] == 16) ? 0 : 5;
            q->bitsBandT[i] = bits;
            for(j = band_tab[i]; j < band_tab[i+1]; j++) {
                q->CWlengthT[j] = bits;
                bitscount += bits;
            }
        }
    }

    if(bit_allocation (q, stream_format_code, 512 - bitscount - get_bits_count(&q->gb), flag) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
        q->decoder_reset = 1;
        return -1;
    }

    for(i = 0; i < BANDS; i++) {
        q->sumLenArr[i] = 0;
        q->skipFlagRaw[i] = 0;
        for(j = band_tab[i]; j < band_tab[i+1]; j++)
            q->sumLenArr[i] += q->CWlengthT[j];
        if (q->bandFlagsBuf[i])
            if( (((band_tab[i+1] - band_tab[i]) * 1.5) > q->sumLenArr[i]) && (q->sumLenArr[i] > 0))
                q->skipFlagRaw[i] = 1;
    }

    imc_get_skip_coeff(q);

    for(i = 0; i < BANDS; i++) {
        q->flcoeffs6[i] = q->flcoeffs1[i];
        /* band has flag set and at least one coded coefficient */
        if (q->bandFlagsBuf[i] && (band_tab[i+1] - band_tab[i]) != q->skipFlagCount[i]){
                q->flcoeffs6[i] *= q->sqrt_tab[band_tab[i+1] - band_tab[i]] /
                                   q->sqrt_tab[(band_tab[i+1] - band_tab[i] - q->skipFlagCount[i])];
        }
    }

    /* calculate bits left, bits needed and adjust bit allocation */
    bits = summer = 0;

    for(i = 0; i < BANDS; i++) {
        if (q->bandFlagsBuf[i]) {
            for(j = band_tab[i]; j < band_tab[i+1]; j++) {
                if(q->skipFlags[j]) {
                    summer += q->CWlengthT[j];
                    q->CWlengthT[j] = 0;
                }
            }
            bits += q->skipFlagBits[i];
            summer -= q->skipFlagBits[i];
        }
    }
    imc_adjust_bit_allocation(q, summer);

    for(i = 0; i < BANDS; i++) {
        q->sumLenArr[i] = 0;

        for(j = band_tab[i]; j < band_tab[i+1]; j++)
            if (!q->skipFlags[j])
                q->sumLenArr[i] += q->CWlengthT[j];
    }

    memset(q->codewords, 0, sizeof(q->codewords));

    if(imc_get_coeffs(q) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n");
        q->decoder_reset = 1;
        return 0;
    }

    if(inverse_quant_coeff(q, stream_format_code) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n");
        q->decoder_reset = 1;
        return 0;
    }

    memset(q->skipFlags, 0, sizeof(q->skipFlags));

    imc_imdct256(q);

    q->dsp.float_to_int16(data, q->out_samples, COEFFS);

    *data_size = COEFFS * sizeof(int16_t);

    return IMC_BLOCK_SIZE;
}


static av_cold int imc_decode_close(AVCodecContext * avctx)
{
    IMCContext *q = avctx->priv_data;

    ff_fft_end(&q->fft);
    return 0;
}


AVCodec imc_decoder = {
    .name = "imc",
    .type = CODEC_TYPE_AUDIO,
    .id = CODEC_ID_IMC,
    .priv_data_size = sizeof(IMCContext),
    .init = imc_decode_init,
    .close = imc_decode_close,
    .decode = imc_decode_frame,
    .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
};
