static int bit_allocation(IMCContext *q, IMCChannel *chctx,

                          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, chctx->flcoeffs1[i]);



    for (i = 0; i < BANDS - 1; i++)

        chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]);

    chctx->flcoeffs4[BANDS - 1] = limit;



    highest = highest * 0.25;



    for (i = 0; i < BANDS; i++) {

        indx = -1;

        if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i])

            indx = 0;



        if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i])

            indx = 1;



        if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i])

            indx = 2;



        if (indx == -1)

            return AVERROR_INVALIDDATA;



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

    }



    if (stream_format_code & 0x2) {

        chctx->flcoeffs4[0] = limit;

        chctx->flcoeffs4[1] = limit;

        chctx->flcoeffs4[2] = limit;

        chctx->flcoeffs4[3] = limit;

    }



    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) {

        iacc  += chctx->bandWidthT[i];

        summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];

    }



    if (!iacc)

        return AVERROR_INVALIDDATA;



    chctx->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(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);



            chctx->bitsBandT[j] = cwlen;

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



            if (cwlen > 0)

                iacc += chctx->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++)

            chctx->CWlengthT[j] = chctx->bitsBandT[i];

    }



    if (freebits > summer) {

        for (i = 0; i < BANDS; i++) {

            workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20

                                              : (chctx->bitsBandT[i] * -2 + chctx->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 (++chctx->bitsBandT[found_indx] == 6)

                    workT[found_indx] = -1.e20;



                for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) {

                    chctx->CWlengthT[j]++;

                    summer++;

                }

            }

        } while (freebits > summer);

    }

    if (freebits < summer) {

        for (i = 0; i < BANDS; i++) {

            workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->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 (!--chctx->bitsBandT[low_indx])

                workT[low_indx] = 1.e20;



            for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) {

                if (chctx->CWlengthT[j] > 0) {

                    chctx->CWlengthT[j]--;

                    summer--;

                }

            }

        }

    }

    return 0;

}
