/*
 * 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
 *  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>

#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
#include "fft.h"
#include "libavutil/audioconvert.h"
#include "sinewin.h"

#include "imcdata.h"

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

typedef struct {
    AVFrame frame;

    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(32, FFTComplex, samples)[COEFFS/2];
    float *out_samples;
} 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, ret;
    IMCContext *q = avctx->priv_data;
    double r1, r2;

    if (avctx->channels != 1) {
        av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
        return AVERROR_PATCHWELCOME;
    }

    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] = (1.0f / 32768) * cos(i / 256.0 * M_PI);
        q->post_sin[i] = (1.0f / 32768) * 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);

    if ((ret = ff_fft_init(&q->fft, 7, 1))) {
        av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
        return ret;
    }
    dsputil_init(&q->dsp, avctx);
    avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
    avctx->channel_layout = AV_CH_LAYOUT_MONO;

    avcodec_get_frame_defaults(&q->frame);
    avctx->coded_frame = &q->frame;

    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 AVERROR_INVALIDDATA;

        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_clipf(((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 */
    q->fft.fft_permute(&q->fft, q->samples);
    q->fft.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 AVERROR_INVALIDDATA;

            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 AVERROR_INVALIDDATA;
                }

                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 *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;

    IMCContext *q = avctx->priv_data;

    int stream_format_code;
    int imc_hdr, i, j, ret;
    int flag;
    int bits, summer;
    int counter, bitscount;
    LOCAL_ALIGNED_16(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 AVERROR_INVALIDDATA;
    }

    /* get output buffer */
    q->frame.nb_samples = COEFFS;
    if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }
    q->out_samples = (float *)q->frame.data[0];

    q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);

    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 AVERROR_INVALIDDATA;
    }
    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 AVERROR_INVALIDDATA;
    }

//    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((ret = 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 ret;
    }

    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 AVERROR_INVALIDDATA;
    }

    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 AVERROR_INVALIDDATA;
    }

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

    imc_imdct256(q);

    *got_frame_ptr   = 1;
    *(AVFrame *)data = q->frame;

    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 ff_imc_decoder = {
    .name = "imc",
    .type = AVMEDIA_TYPE_AUDIO,
    .id = CODEC_ID_IMC,
    .priv_data_size = sizeof(IMCContext),
    .init = imc_decode_init,
    .close = imc_decode_close,
    .decode = imc_decode_frame,
    .capabilities = CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
};
