/*
 * COOK compatible decoder
 * Copyright (c) 2003 Sascha Sommer
 * Copyright (c) 2005 Benjamin Larsson
 *
 * 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
 * Cook compatible decoder. Bastardization of the G.722.1 standard.
 * This decoder handles RealNetworks, RealAudio G2 data.
 * Cook is identified by the codec name cook in RM files.
 *
 * To use this decoder, a calling application must supply the extradata
 * bytes provided from the RM container; 8+ bytes for mono streams and
 * 16+ for stereo streams (maybe more).
 *
 * Codec technicalities (all this assume a buffer length of 1024):
 * Cook works with several different techniques to achieve its compression.
 * In the timedomain the buffer is divided into 8 pieces and quantized. If
 * two neighboring pieces have different quantization index a smooth
 * quantization curve is used to get a smooth overlap between the different
 * pieces.
 * To get to the transformdomain Cook uses a modulated lapped transform.
 * The transform domain has 50 subbands with 20 elements each. This
 * means only a maximum of 50*20=1000 coefficients are used out of the 1024
 * available.
 */

#include "libavutil/channel_layout.h"
#include "libavutil/lfg.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "libavutil/tx.h"

#include "audiodsp.h"
#include "avcodec.h"
#include "get_bits.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
#include "sinewin.h"
#include "unary.h"

#include "cookdata.h"

/* the different Cook versions */
#define MONO            0x1000001
#define STEREO          0x1000002
#define JOINT_STEREO    0x1000003
#define MC_COOK         0x2000000

#define SUBBAND_SIZE    20
#define MAX_SUBPACKETS   5

#define QUANT_VLC_BITS    9
#define COUPLING_VLC_BITS 6

typedef struct cook_gains {
    int *now;
    int *previous;
} cook_gains;

typedef struct COOKSubpacket {
    int                 ch_idx;
    int                 size;
    int                 num_channels;
    int                 cookversion;
    int                 subbands;
    int                 js_subband_start;
    int                 js_vlc_bits;
    int                 samples_per_channel;
    int                 log2_numvector_size;
    unsigned int        channel_mask;
    VLC                 channel_coupling;
    int                 joint_stereo;
    int                 bits_per_subpacket;
    int                 bits_per_subpdiv;
    int                 total_subbands;
    int                 numvector_size;       // 1 << log2_numvector_size;

    float               mono_previous_buffer1[1024];
    float               mono_previous_buffer2[1024];

    cook_gains          gains1;
    cook_gains          gains2;
    int                 gain_1[9];
    int                 gain_2[9];
    int                 gain_3[9];
    int                 gain_4[9];
} COOKSubpacket;

typedef struct cook {
    /*
     * The following 5 functions provide the lowlevel arithmetic on
     * the internal audio buffers.
     */
    void (*scalar_dequant)(struct cook *q, int index, int quant_index,
                           int *subband_coef_index, int *subband_coef_sign,
                           float *mlt_p);

    void (*decouple)(struct cook *q,
                     COOKSubpacket *p,
                     int subband,
                     float f1, float f2,
                     float *decode_buffer,
                     float *mlt_buffer1, float *mlt_buffer2);

    void (*imlt_window)(struct cook *q, float *buffer1,
                        cook_gains *gains_ptr, float *previous_buffer);

    void (*interpolate)(struct cook *q, float *buffer,
                        int gain_index, int gain_index_next);

    void (*saturate_output)(struct cook *q, float *out);

    AVCodecContext*     avctx;
    AudioDSPContext     adsp;
    GetBitContext       gb;
    /* stream data */
    int                 num_vectors;
    int                 samples_per_channel;
    /* states */
    AVLFG               random_state;
    int                 discarded_packets;

    /* transform data */
    AVTXContext        *mdct_ctx;
    av_tx_fn            mdct_fn;
    float*              mlt_window;

    /* VLC data */
    VLC                 envelope_quant_index[13];
    VLC                 sqvh[7];          // scalar quantization

    /* generate tables and related variables */
    int                 gain_size_factor;
    float               gain_table[31];

    /* data buffers */

    uint8_t*            decoded_bytes_buffer;
    DECLARE_ALIGNED(32, float, mono_mdct_output)[2048];
    float               decode_buffer_1[1024];
    float               decode_buffer_2[1024];
    float               decode_buffer_0[1060]; /* static allocation for joint decode */

    const float         *cplscales[5];
    int                 num_subpackets;
    COOKSubpacket       subpacket[MAX_SUBPACKETS];
} COOKContext;

static float     pow2tab[127];
static float rootpow2tab[127];

/*************** init functions ***************/

/* table generator */
static av_cold void init_pow2table(void)
{
    /* fast way of computing 2^i and 2^(0.5*i) for -63 <= i < 64 */
    int i;
    static const float exp2_tab[2] = {1, M_SQRT2};
    float exp2_val = powf(2, -63);
    float root_val = powf(2, -32);
    for (i = -63; i < 64; i++) {
        if (!(i & 1))
            root_val *= 2;
        pow2tab[63 + i] = exp2_val;
        rootpow2tab[63 + i] = root_val * exp2_tab[i & 1];
        exp2_val *= 2;
    }
}

/* table generator */
static av_cold void init_gain_table(COOKContext *q)
{
    int i;
    q->gain_size_factor = q->samples_per_channel / 8;
    for (i = 0; i < 31; i++)
        q->gain_table[i] = pow(pow2tab[i + 48],
                               (1.0 / (double) q->gain_size_factor));
}

static av_cold int build_vlc(VLC *vlc, int nb_bits, const uint8_t counts[16],
                             const void *syms, int symbol_size, int offset,
                             void *logctx)
{
    uint8_t lens[MAX_COOK_VLC_ENTRIES];
    unsigned num = 0;

    for (int i = 0; i < 16; i++)
        for (unsigned count = num + counts[i]; num < count; num++)
            lens[num] = i + 1;

    return ff_vlc_init_from_lengths(vlc, nb_bits, num, lens, 1,
                                    syms, symbol_size, symbol_size,
                                    offset, 0, logctx);
}

static av_cold int init_cook_vlc_tables(COOKContext *q)
{
    int i, result;

    result = 0;
    for (i = 0; i < 13; i++) {
        result |= build_vlc(&q->envelope_quant_index[i], QUANT_VLC_BITS,
                            envelope_quant_index_huffcounts[i],
                            envelope_quant_index_huffsyms[i], 1, -12, q->avctx);
    }
    av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n");
    for (i = 0; i < 7; i++) {
        int sym_size = 1 + (i == 3);
        result |= build_vlc(&q->sqvh[i], vhvlcsize_tab[i],
                            cvh_huffcounts[i],
                            cvh_huffsyms[i], sym_size, 0, q->avctx);
    }

    for (i = 0; i < q->num_subpackets; i++) {
        if (q->subpacket[i].joint_stereo == 1) {
            result |= build_vlc(&q->subpacket[i].channel_coupling, COUPLING_VLC_BITS,
                                ccpl_huffcounts[q->subpacket[i].js_vlc_bits - 2],
                                ccpl_huffsyms[q->subpacket[i].js_vlc_bits - 2], 1,
                                0, q->avctx);
            av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i);
        }
    }

    av_log(q->avctx, AV_LOG_DEBUG, "VLC tables initialized.\n");
    return result;
}

static av_cold int init_cook_mlt(COOKContext *q)
{
    int j, ret;
    int mlt_size = q->samples_per_channel;
    const float scale = 1.0 / 32768.0;

    if (!(q->mlt_window = av_malloc_array(mlt_size, sizeof(*q->mlt_window))))
        return AVERROR(ENOMEM);

    /* Initialize the MLT window: simple sine window. */
    ff_sine_window_init(q->mlt_window, mlt_size);
    for (j = 0; j < mlt_size; j++)
        q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel);

    /* Initialize the MDCT. */
    ret = av_tx_init(&q->mdct_ctx, &q->mdct_fn, AV_TX_FLOAT_MDCT,
                     1, mlt_size, &scale, AV_TX_FULL_IMDCT);
    if (ret < 0)
        return ret;

    return 0;
}

static av_cold void init_cplscales_table(COOKContext *q)
{
    int i;
    for (i = 0; i < 5; i++)
        q->cplscales[i] = cplscales[i];
}

/*************** init functions end ***********/

#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes) + 3) % 4)
#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes)))

/**
 * Cook indata decoding, every 32 bits are XORed with 0x37c511f2.
 * Why? No idea, some checksum/error detection method maybe.
 *
 * Out buffer size: extra bytes are needed to cope with
 * padding/misalignment.
 * Subpackets passed to the decoder can contain two, consecutive
 * half-subpackets, of identical but arbitrary size.
 *          1234 1234 1234 1234  extraA extraB
 * Case 1:  AAAA BBBB              0      0
 * Case 2:  AAAA ABBB BB--         3      3
 * Case 3:  AAAA AABB BBBB         2      2
 * Case 4:  AAAA AAAB BBBB BB--    1      5
 *
 * Nice way to waste CPU cycles.
 *
 * @param inbuffer  pointer to byte array of indata
 * @param out       pointer to byte array of outdata
 * @param bytes     number of bytes
 */
static inline int decode_bytes(const uint8_t *inbuffer, uint8_t *out, int bytes)
{
    static const uint32_t tab[4] = {
        AV_BE2NE32C(0x37c511f2u), AV_BE2NE32C(0xf237c511u),
        AV_BE2NE32C(0x11f237c5u), AV_BE2NE32C(0xc511f237u),
    };
    int i, off;
    uint32_t c;
    const uint32_t *buf;
    uint32_t *obuf = (uint32_t *) out;
    /* FIXME: 64 bit platforms would be able to do 64 bits at a time.
     * I'm too lazy though, should be something like
     * for (i = 0; i < bitamount / 64; i++)
     *     (int64_t) out[i] = 0x37c511f237c511f2 ^ av_be2ne64(int64_t) in[i]);
     * Buffer alignment needs to be checked. */

    off = (intptr_t) inbuffer & 3;
    buf = (const uint32_t *) (inbuffer - off);
    c = tab[off];
    bytes += 3 + off;
    for (i = 0; i < bytes / 4; i++)
        obuf[i] = c ^ buf[i];

    return off;
}

static av_cold int cook_decode_close(AVCodecContext *avctx)
{
    int i;
    COOKContext *q = avctx->priv_data;
    av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n");

    /* Free allocated memory buffers. */
    av_freep(&q->mlt_window);
    av_freep(&q->decoded_bytes_buffer);

    /* Free the transform. */
    av_tx_uninit(&q->mdct_ctx);

    /* Free the VLC tables. */
    for (i = 0; i < 13; i++)
        ff_vlc_free(&q->envelope_quant_index[i]);
    for (i = 0; i < 7; i++)
        ff_vlc_free(&q->sqvh[i]);
    for (i = 0; i < q->num_subpackets; i++)
        ff_vlc_free(&q->subpacket[i].channel_coupling);

    av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n");

    return 0;
}

/**
 * Fill the gain array for the timedomain quantization.
 *
 * @param gb          pointer to the GetBitContext
 * @param gaininfo    array[9] of gain indexes
 */
static void decode_gain_info(GetBitContext *gb, int *gaininfo)
{
    int i, n;

    n = get_unary(gb, 0, get_bits_left(gb));     // amount of elements*2 to update

    i = 0;
    while (n--) {
        int index = get_bits(gb, 3);
        int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;

        while (i <= index)
            gaininfo[i++] = gain;
    }
    while (i <= 8)
        gaininfo[i++] = 0;
}

/**
 * Create the quant index table needed for the envelope.
 *
 * @param q                 pointer to the COOKContext
 * @param quant_index_table pointer to the array
 */
static int decode_envelope(COOKContext *q, COOKSubpacket *p,
                           int *quant_index_table)
{
    int i, j, vlc_index;

    quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize

    for (i = 1; i < p->total_subbands; i++) {
        vlc_index = i;
        if (i >= p->js_subband_start * 2) {
            vlc_index -= p->js_subband_start;
        } else {
            vlc_index /= 2;
            if (vlc_index < 1)
                vlc_index = 1;
        }
        if (vlc_index > 13)
            vlc_index = 13; // the VLC tables >13 are identical to No. 13

        j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table,
                     QUANT_VLC_BITS, 2);
        quant_index_table[i] = quant_index_table[i - 1] + j; // differential encoding
        if (quant_index_table[i] > 63 || quant_index_table[i] < -63) {
            av_log(q->avctx, AV_LOG_ERROR,
                   "Invalid quantizer %d at position %d, outside [-63, 63] range\n",
                   quant_index_table[i], i);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

/**
 * Calculate the category and category_index vector.
 *
 * @param q                     pointer to the COOKContext
 * @param quant_index_table     pointer to the array
 * @param category              pointer to the category array
 * @param category_index        pointer to the category_index array
 */
static void categorize(COOKContext *q, COOKSubpacket *p, const int *quant_index_table,
                       int *category, int *category_index)
{
    int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j;
    int exp_index2[102] = { 0 };
    int exp_index1[102] = { 0 };

    int tmp_categorize_array[128 * 2] = { 0 };
    int tmp_categorize_array1_idx = p->numvector_size;
    int tmp_categorize_array2_idx = p->numvector_size;

    bits_left = p->bits_per_subpacket - get_bits_count(&q->gb);

    if (bits_left > q->samples_per_channel)
        bits_left = q->samples_per_channel +
                    ((bits_left - q->samples_per_channel) * 5) / 8;

    bias = -32;

    /* Estimate bias. */
    for (i = 32; i > 0; i = i / 2) {
        num_bits = 0;
        index    = 0;
        for (j = p->total_subbands; j > 0; j--) {
            exp_idx = av_clip_uintp2((i - quant_index_table[index] + bias) / 2, 3);
            index++;
            num_bits += expbits_tab[exp_idx];
        }
        if (num_bits >= bits_left - 32)
            bias += i;
    }

    /* Calculate total number of bits. */
    num_bits = 0;
    for (i = 0; i < p->total_subbands; i++) {
        exp_idx = av_clip_uintp2((bias - quant_index_table[i]) / 2, 3);
        num_bits += expbits_tab[exp_idx];
        exp_index1[i] = exp_idx;
        exp_index2[i] = exp_idx;
    }
    tmpbias1 = tmpbias2 = num_bits;

    for (j = 1; j < p->numvector_size; j++) {
        if (tmpbias1 + tmpbias2 > 2 * bits_left) {  /* ---> */
            int max = -999999;
            index = -1;
            for (i = 0; i < p->total_subbands; i++) {
                if (exp_index1[i] < 7) {
                    v = (-2 * exp_index1[i]) - quant_index_table[i] + bias;
                    if (v >= max) {
                        max   = v;
                        index = i;
                    }
                }
            }
            if (index == -1)
                break;
            tmp_categorize_array[tmp_categorize_array1_idx++] = index;
            tmpbias1 -= expbits_tab[exp_index1[index]] -
                        expbits_tab[exp_index1[index] + 1];
            ++exp_index1[index];
        } else {  /* <--- */
            int min = 999999;
            index = -1;
            for (i = 0; i < p->total_subbands; i++) {
                if (exp_index2[i] > 0) {
                    v = (-2 * exp_index2[i]) - quant_index_table[i] + bias;
                    if (v < min) {
                        min   = v;
                        index = i;
                    }
                }
            }
            if (index == -1)
                break;
            tmp_categorize_array[--tmp_categorize_array2_idx] = index;
            tmpbias2 -= expbits_tab[exp_index2[index]] -
                        expbits_tab[exp_index2[index] - 1];
            --exp_index2[index];
        }
    }

    for (i = 0; i < p->total_subbands; i++)
        category[i] = exp_index2[i];

    for (i = 0; i < p->numvector_size - 1; i++)
        category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++];
}


/**
 * Expand the category vector.
 *
 * @param q                     pointer to the COOKContext
 * @param category              pointer to the category array
 * @param category_index        pointer to the category_index array
 */
static inline void expand_category(COOKContext *q, int *category,
                                   int *category_index)
{
    int i;
    for (i = 0; i < q->num_vectors; i++)
    {
        int idx = category_index[i];
        if (++category[idx] >= FF_ARRAY_ELEMS(dither_tab))
            --category[idx];
    }
}

/**
 * The real requantization of the mltcoefs
 *
 * @param q                     pointer to the COOKContext
 * @param index                 index
 * @param quant_index           quantisation index
 * @param subband_coef_index    array of indexes to quant_centroid_tab
 * @param subband_coef_sign     signs of coefficients
 * @param mlt_p                 pointer into the mlt buffer
 */
static void scalar_dequant_float(COOKContext *q, int index, int quant_index,
                                 int *subband_coef_index, int *subband_coef_sign,
                                 float *mlt_p)
{
    int i;
    float f1;

    for (i = 0; i < SUBBAND_SIZE; i++) {
        if (subband_coef_index[i]) {
            f1 = quant_centroid_tab[index][subband_coef_index[i]];
            if (subband_coef_sign[i])
                f1 = -f1;
        } else {
            /* noise coding if subband_coef_index[i] == 0 */
            f1 = dither_tab[index];
            if (av_lfg_get(&q->random_state) < 0x80000000)
                f1 = -f1;
        }
        mlt_p[i] = f1 * rootpow2tab[quant_index + 63];
    }
}
/**
 * Unpack the subband_coef_index and subband_coef_sign vectors.
 *
 * @param q                     pointer to the COOKContext
 * @param category              pointer to the category array
 * @param subband_coef_index    array of indexes to quant_centroid_tab
 * @param subband_coef_sign     signs of coefficients
 */
static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category,
                       int *subband_coef_index, int *subband_coef_sign)
{
    int i, j;
    int vlc, vd, tmp, result;

    vd = vd_tab[category];
    result = 0;
    for (i = 0; i < vpr_tab[category]; i++) {
        vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3);
        if (p->bits_per_subpacket < get_bits_count(&q->gb)) {
            vlc = 0;
            result = 1;
        }
        for (j = vd - 1; j >= 0; j--) {
            tmp = (vlc * invradix_tab[category]) / 0x100000;
            subband_coef_index[vd * i + j] = vlc - tmp * (kmax_tab[category] + 1);
            vlc = tmp;
        }
        for (j = 0; j < vd; j++) {
            if (subband_coef_index[i * vd + j]) {
                if (get_bits_count(&q->gb) < p->bits_per_subpacket) {
                    subband_coef_sign[i * vd + j] = get_bits1(&q->gb);
                } else {
                    result = 1;
                    subband_coef_sign[i * vd + j] = 0;
                }
            } else {
                subband_coef_sign[i * vd + j] = 0;
            }
        }
    }
    return result;
}


/**
 * Fill the mlt_buffer with mlt coefficients.
 *
 * @param q                 pointer to the COOKContext
 * @param category          pointer to the category array
 * @param quant_index_table pointer to the array
 * @param mlt_buffer        pointer to mlt coefficients
 */
static void decode_vectors(COOKContext *q, COOKSubpacket *p, int *category,
                           int *quant_index_table, float *mlt_buffer)
{
    /* A zero in this table means that the subband coefficient is
       random noise coded. */
    int subband_coef_index[SUBBAND_SIZE];
    /* A zero in this table means that the subband coefficient is a
       positive multiplicator. */
    int subband_coef_sign[SUBBAND_SIZE];
    int band, j;
    int index = 0;

    for (band = 0; band < p->total_subbands; band++) {
        index = category[band];
        if (category[band] < 7) {
            if (unpack_SQVH(q, p, category[band], subband_coef_index, subband_coef_sign)) {
                index = 7;
                for (j = 0; j < p->total_subbands; j++)
                    category[band + j] = 7;
            }
        }
        if (index >= 7) {
            memset(subband_coef_index, 0, sizeof(subband_coef_index));
            memset(subband_coef_sign,  0, sizeof(subband_coef_sign));
        }
        q->scalar_dequant(q, index, quant_index_table[band],
                          subband_coef_index, subband_coef_sign,
                          &mlt_buffer[band * SUBBAND_SIZE]);
    }

    /* FIXME: should this be removed, or moved into loop above? */
    if (p->total_subbands * SUBBAND_SIZE >= q->samples_per_channel)
        return;
}


static int mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer)
{
    int category_index[128] = { 0 };
    int category[128]       = { 0 };
    int quant_index_table[102];
    int res, i;

    if ((res = decode_envelope(q, p, quant_index_table)) < 0)
        return res;
    q->num_vectors = get_bits(&q->gb, p->log2_numvector_size);
    categorize(q, p, quant_index_table, category, category_index);
    expand_category(q, category, category_index);
    for (i=0; i<p->total_subbands; i++) {
        if (category[i] > 7)
            return AVERROR_INVALIDDATA;
    }
    decode_vectors(q, p, category, quant_index_table, mlt_buffer);

    return 0;
}


/**
 * the actual requantization of the timedomain samples
 *
 * @param q                 pointer to the COOKContext
 * @param buffer            pointer to the timedomain buffer
 * @param gain_index        index for the block multiplier
 * @param gain_index_next   index for the next block multiplier
 */
static void interpolate_float(COOKContext *q, float *buffer,
                              int gain_index, int gain_index_next)
{
    int i;
    float fc1, fc2;
    fc1 = pow2tab[gain_index + 63];

    if (gain_index == gain_index_next) {             // static gain
        for (i = 0; i < q->gain_size_factor; i++)
            buffer[i] *= fc1;
    } else {                                        // smooth gain
        fc2 = q->gain_table[15 + (gain_index_next - gain_index)];
        for (i = 0; i < q->gain_size_factor; i++) {
            buffer[i] *= fc1;
            fc1       *= fc2;
        }
    }
}

/**
 * Apply transform window, overlap buffers.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to the mltcoefficients
 * @param gains_ptr         current and previous gains
 * @param previous_buffer   pointer to the previous buffer to be used for overlapping
 */
static void imlt_window_float(COOKContext *q, float *inbuffer,
                              cook_gains *gains_ptr, float *previous_buffer)
{
    const float fc = pow2tab[gains_ptr->previous[0] + 63];
    int i;
    /* The weird thing here, is that the two halves of the time domain
     * buffer are swapped. Also, the newest data, that we save away for
     * next frame, has the wrong sign. Hence the subtraction below.
     * Almost sounds like a complex conjugate/reverse data/FFT effect.
     */

    /* Apply window and overlap */
    for (i = 0; i < q->samples_per_channel; i++)
        inbuffer[i] = inbuffer[i] * fc * q->mlt_window[i] -
                      previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i];
}

/**
 * The modulated lapped transform, this takes transform coefficients
 * and transforms them into timedomain samples.
 * Apply transform window, overlap buffers, apply gain profile
 * and buffer management.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to the mltcoefficients
 * @param gains_ptr         current and previous gains
 * @param previous_buffer   pointer to the previous buffer to be used for overlapping
 */
static void imlt_gain(COOKContext *q, float *inbuffer,
                      cook_gains *gains_ptr, float *previous_buffer)
{
    float *buffer0 = q->mono_mdct_output;
    float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
    int i;

    /* Inverse modified discrete cosine transform */
    q->mdct_fn(q->mdct_ctx, q->mono_mdct_output, inbuffer, sizeof(float));

    q->imlt_window(q, buffer1, gains_ptr, previous_buffer);

    /* Apply gain profile */
    for (i = 0; i < 8; i++)
        if (gains_ptr->now[i] || gains_ptr->now[i + 1])
            q->interpolate(q, &buffer1[q->gain_size_factor * i],
                           gains_ptr->now[i], gains_ptr->now[i + 1]);

    /* Save away the current to be previous block. */
    memcpy(previous_buffer, buffer0,
           q->samples_per_channel * sizeof(*previous_buffer));
}


/**
 * function for getting the jointstereo coupling information
 *
 * @param q                 pointer to the COOKContext
 * @param decouple_tab      decoupling array
 */
static int decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
{
    int i;
    int vlc    = get_bits1(&q->gb);
    int start  = cplband[p->js_subband_start];
    int end    = cplband[p->subbands - 1];
    int length = end - start + 1;

    if (start > end)
        return 0;

    if (vlc)
        for (i = 0; i < length; i++)
            decouple_tab[start + i] = get_vlc2(&q->gb,
                                               p->channel_coupling.table,
                                               COUPLING_VLC_BITS, 3);
    else
        for (i = 0; i < length; i++) {
            int v = get_bits(&q->gb, p->js_vlc_bits);
            if (v == (1<<p->js_vlc_bits)-1) {
                av_log(q->avctx, AV_LOG_ERROR, "decouple value too large\n");
                return AVERROR_INVALIDDATA;
            }
            decouple_tab[start + i] = v;
        }
    return 0;
}

/**
 * function decouples a pair of signals from a single signal via multiplication.
 *
 * @param q                 pointer to the COOKContext
 * @param subband           index of the current subband
 * @param f1                multiplier for channel 1 extraction
 * @param f2                multiplier for channel 2 extraction
 * @param decode_buffer     input buffer
 * @param mlt_buffer1       pointer to left channel mlt coefficients
 * @param mlt_buffer2       pointer to right channel mlt coefficients
 */
static void decouple_float(COOKContext *q,
                           COOKSubpacket *p,
                           int subband,
                           float f1, float f2,
                           float *decode_buffer,
                           float *mlt_buffer1, float *mlt_buffer2)
{
    int j, tmp_idx;
    for (j = 0; j < SUBBAND_SIZE; j++) {
        tmp_idx = ((p->js_subband_start + subband) * SUBBAND_SIZE) + j;
        mlt_buffer1[SUBBAND_SIZE * subband + j] = f1 * decode_buffer[tmp_idx];
        mlt_buffer2[SUBBAND_SIZE * subband + j] = f2 * decode_buffer[tmp_idx];
    }
}

/**
 * function for decoding joint stereo data
 *
 * @param q                 pointer to the COOKContext
 * @param mlt_buffer1       pointer to left channel mlt coefficients
 * @param mlt_buffer2       pointer to right channel mlt coefficients
 */
static int joint_decode(COOKContext *q, COOKSubpacket *p,
                        float *mlt_buffer_left, float *mlt_buffer_right)
{
    int i, j, res;
    int decouple_tab[SUBBAND_SIZE] = { 0 };
    float *decode_buffer = q->decode_buffer_0;
    int idx, cpl_tmp;
    float f1, f2;
    const float *cplscale;

    memset(decode_buffer, 0, sizeof(q->decode_buffer_0));

    /* Make sure the buffers are zeroed out. */
    memset(mlt_buffer_left,  0, 1024 * sizeof(*mlt_buffer_left));
    memset(mlt_buffer_right, 0, 1024 * sizeof(*mlt_buffer_right));
    if ((res = decouple_info(q, p, decouple_tab)) < 0)
        return res;
    if ((res = mono_decode(q, p, decode_buffer)) < 0)
        return res;
    /* The two channels are stored interleaved in decode_buffer. */
    for (i = 0; i < p->js_subband_start; i++) {
        for (j = 0; j < SUBBAND_SIZE; j++) {
            mlt_buffer_left[i  * 20 + j] = decode_buffer[i * 40 + j];
            mlt_buffer_right[i * 20 + j] = decode_buffer[i * 40 + 20 + j];
        }
    }

    /* When we reach js_subband_start (the higher frequencies)
       the coefficients are stored in a coupling scheme. */
    idx = (1 << p->js_vlc_bits) - 1;
    for (i = p->js_subband_start; i < p->subbands; i++) {
        cpl_tmp = cplband[i];
        idx -= decouple_tab[cpl_tmp];
        cplscale = q->cplscales[p->js_vlc_bits - 2];  // choose decoupler table
        f1 = cplscale[decouple_tab[cpl_tmp] + 1];
        f2 = cplscale[idx];
        q->decouple(q, p, i, f1, f2, decode_buffer,
                    mlt_buffer_left, mlt_buffer_right);
        idx = (1 << p->js_vlc_bits) - 1;
    }

    return 0;
}

/**
 * First part of subpacket decoding:
 *  decode raw stream bytes and read gain info.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to raw stream data
 * @param gains_ptr         array of current/prev gain pointers
 */
static inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p,
                                         const uint8_t *inbuffer,
                                         cook_gains *gains_ptr)
{
    int offset;

    offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
                          p->bits_per_subpacket / 8);
    init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
                  p->bits_per_subpacket);
    decode_gain_info(&q->gb, gains_ptr->now);

    /* Swap current and previous gains */
    FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
}

/**
 * Saturate the output signal and interleave.
 *
 * @param q                 pointer to the COOKContext
 * @param out               pointer to the output vector
 */
static void saturate_output_float(COOKContext *q, float *out)
{
    q->adsp.vector_clipf(out, q->mono_mdct_output + q->samples_per_channel,
                         FFALIGN(q->samples_per_channel, 8), -1.0f, 1.0f);
}


/**
 * Final part of subpacket decoding:
 *  Apply modulated lapped transform, gain compensation,
 *  clip and convert to integer.
 *
 * @param q                 pointer to the COOKContext
 * @param decode_buffer     pointer to the mlt coefficients
 * @param gains_ptr         array of current/prev gain pointers
 * @param previous_buffer   pointer to the previous buffer to be used for overlapping
 * @param out               pointer to the output buffer
 */
static inline void mlt_compensate_output(COOKContext *q, float *decode_buffer,
                                         cook_gains *gains_ptr, float *previous_buffer,
                                         float *out)
{
    imlt_gain(q, decode_buffer, gains_ptr, previous_buffer);
    if (out)
        q->saturate_output(q, out);
}


/**
 * Cook subpacket decoding. This function returns one decoded subpacket,
 * usually 1024 samples per channel.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to the inbuffer
 * @param outbuffer         pointer to the outbuffer
 */
static int decode_subpacket(COOKContext *q, COOKSubpacket *p,
                            const uint8_t *inbuffer, float **outbuffer)
{
    int sub_packet_size = p->size;
    int res;

    memset(q->decode_buffer_1, 0, sizeof(q->decode_buffer_1));
    decode_bytes_and_gain(q, p, inbuffer, &p->gains1);

    if (p->joint_stereo) {
        if ((res = joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2)) < 0)
            return res;
    } else {
        if ((res = mono_decode(q, p, q->decode_buffer_1)) < 0)
            return res;

        if (p->num_channels == 2) {
            decode_bytes_and_gain(q, p, inbuffer + sub_packet_size / 2, &p->gains2);
            if ((res = mono_decode(q, p, q->decode_buffer_2)) < 0)
                return res;
        }
    }

    mlt_compensate_output(q, q->decode_buffer_1, &p->gains1,
                          p->mono_previous_buffer1,
                          outbuffer ? outbuffer[p->ch_idx] : NULL);

    if (p->num_channels == 2) {
        if (p->joint_stereo)
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains1,
                                  p->mono_previous_buffer2,
                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
        else
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains2,
                                  p->mono_previous_buffer2,
                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
    }

    return 0;
}


static int cook_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    COOKContext *q = avctx->priv_data;
    float **samples = NULL;
    int i, ret;
    int offset = 0;
    int chidx = 0;

    if (buf_size < avctx->block_align)
        return buf_size;

    /* get output buffer */
    if (q->discarded_packets >= 2) {
        frame->nb_samples = q->samples_per_channel;
        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
            return ret;
        samples = (float **)frame->extended_data;
    }

    /* estimate subpacket sizes */
    q->subpacket[0].size = avctx->block_align;

    for (i = 1; i < q->num_subpackets; i++) {
        q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i];
        q->subpacket[0].size -= q->subpacket[i].size + 1;
        if (q->subpacket[0].size < 0) {
            av_log(avctx, AV_LOG_DEBUG,
                   "frame subpacket size total > avctx->block_align!\n");
            return AVERROR_INVALIDDATA;
        }
    }

    /* decode supbackets */
    for (i = 0; i < q->num_subpackets; i++) {
        q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size * 8) >>
                                              q->subpacket[i].bits_per_subpdiv;
        q->subpacket[i].ch_idx = chidx;
        av_log(avctx, AV_LOG_DEBUG,
               "subpacket[%i] size %i js %i %i block_align %i\n",
               i, q->subpacket[i].size, q->subpacket[i].joint_stereo, offset,
               avctx->block_align);

        if ((ret = decode_subpacket(q, &q->subpacket[i], buf + offset, samples)) < 0)
            return ret;
        offset += q->subpacket[i].size;
        chidx += q->subpacket[i].num_channels;
        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i] %i %i\n",
               i, q->subpacket[i].size * 8, get_bits_count(&q->gb));
    }

    /* Discard the first two frames: no valid audio. */
    if (q->discarded_packets < 2) {
        q->discarded_packets++;
        *got_frame_ptr = 0;
        return avctx->block_align;
    }

    *got_frame_ptr = 1;

    return avctx->block_align;
}

static void dump_cook_context(COOKContext *q)
{
    //int i=0;
#define PRINT(a, b) ff_dlog(q->avctx, " %s = %d\n", a, b);
    ff_dlog(q->avctx, "COOKextradata\n");
    ff_dlog(q->avctx, "cookversion=%x\n", q->subpacket[0].cookversion);
    if (q->subpacket[0].cookversion > STEREO) {
        PRINT("js_subband_start", q->subpacket[0].js_subband_start);
        PRINT("js_vlc_bits", q->subpacket[0].js_vlc_bits);
    }
    ff_dlog(q->avctx, "COOKContext\n");
    PRINT("nb_channels", q->avctx->ch_layout.nb_channels);
    PRINT("bit_rate", (int)q->avctx->bit_rate);
    PRINT("sample_rate", q->avctx->sample_rate);
    PRINT("samples_per_channel", q->subpacket[0].samples_per_channel);
    PRINT("subbands", q->subpacket[0].subbands);
    PRINT("js_subband_start", q->subpacket[0].js_subband_start);
    PRINT("log2_numvector_size", q->subpacket[0].log2_numvector_size);
    PRINT("numvector_size", q->subpacket[0].numvector_size);
    PRINT("total_subbands", q->subpacket[0].total_subbands);
}

/**
 * Cook initialization
 *
 * @param avctx     pointer to the AVCodecContext
 */
static av_cold int cook_decode_init(AVCodecContext *avctx)
{
    static AVOnce init_static_once = AV_ONCE_INIT;
    COOKContext *q = avctx->priv_data;
    GetByteContext gb;
    int s = 0;
    unsigned int channel_mask = 0;
    int samples_per_frame = 0;
    int ret;
    int channels = avctx->ch_layout.nb_channels;

    q->avctx = avctx;

    /* Take care of the codec specific extradata. */
    if (avctx->extradata_size < 8) {
        av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");
        return AVERROR_INVALIDDATA;
    }
    av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size);

    bytestream2_init(&gb, avctx->extradata, avctx->extradata_size);

    /* Take data from the AVCodecContext (RM container). */
    if (!channels) {
        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
        return AVERROR_INVALIDDATA;
    }

    if (avctx->block_align >= INT_MAX / 8)
        return AVERROR(EINVAL);

    /* Initialize RNG. */
    av_lfg_init(&q->random_state, 0);

    ff_audiodsp_init(&q->adsp);

    while (bytestream2_get_bytes_left(&gb)) {
        if (s >= FFMIN(MAX_SUBPACKETS, avctx->block_align)) {
            avpriv_request_sample(avctx, "subpackets > %d", FFMIN(MAX_SUBPACKETS, avctx->block_align));
            return AVERROR_PATCHWELCOME;
        }
        /* 8 for mono, 16 for stereo, ? for multichannel
           Swap to right endianness so we don't need to care later on. */
        q->subpacket[s].cookversion      = bytestream2_get_be32(&gb);
        samples_per_frame                = bytestream2_get_be16(&gb);
        q->subpacket[s].subbands         = bytestream2_get_be16(&gb);
        bytestream2_get_be32(&gb);    // Unknown unused
        q->subpacket[s].js_subband_start = bytestream2_get_be16(&gb);
        if (q->subpacket[s].js_subband_start >= 51) {
            av_log(avctx, AV_LOG_ERROR, "js_subband_start %d is too large\n", q->subpacket[s].js_subband_start);
            return AVERROR_INVALIDDATA;
        }
        q->subpacket[s].js_vlc_bits      = bytestream2_get_be16(&gb);

        /* Initialize extradata related variables. */
        q->subpacket[s].samples_per_channel = samples_per_frame / channels;
        q->subpacket[s].bits_per_subpacket = avctx->block_align * 8;

        /* Initialize default data states. */
        q->subpacket[s].log2_numvector_size = 5;
        q->subpacket[s].total_subbands = q->subpacket[s].subbands;
        q->subpacket[s].num_channels = 1;

        /* Initialize version-dependent variables */

        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s,
               q->subpacket[s].cookversion);
        q->subpacket[s].joint_stereo = 0;
        switch (q->subpacket[s].cookversion) {
        case MONO:
            if (channels != 1) {
                avpriv_request_sample(avctx, "Container channels != 1");
                return AVERROR_PATCHWELCOME;
            }
            av_log(avctx, AV_LOG_DEBUG, "MONO\n");
            break;
        case STEREO:
            if (channels != 1) {
                q->subpacket[s].bits_per_subpdiv = 1;
                q->subpacket[s].num_channels = 2;
            }
            av_log(avctx, AV_LOG_DEBUG, "STEREO\n");
            break;
        case JOINT_STEREO:
            if (channels != 2) {
                avpriv_request_sample(avctx, "Container channels != 2");
                return AVERROR_PATCHWELCOME;
            }
            av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");
            if (avctx->extradata_size >= 16) {
                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
                                                 q->subpacket[s].js_subband_start;
                q->subpacket[s].joint_stereo = 1;
                q->subpacket[s].num_channels = 2;
            }
            if (q->subpacket[s].samples_per_channel > 256) {
                q->subpacket[s].log2_numvector_size = 6;
            }
            if (q->subpacket[s].samples_per_channel > 512) {
                q->subpacket[s].log2_numvector_size = 7;
            }
            break;
        case MC_COOK:
            av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n");
            channel_mask |= q->subpacket[s].channel_mask = bytestream2_get_be32(&gb);

            if (av_popcount64(q->subpacket[s].channel_mask) > 1) {
                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
                                                 q->subpacket[s].js_subband_start;
                q->subpacket[s].joint_stereo = 1;
                q->subpacket[s].num_channels = 2;
                q->subpacket[s].samples_per_channel = samples_per_frame >> 1;

                if (q->subpacket[s].samples_per_channel > 256) {
                    q->subpacket[s].log2_numvector_size = 6;
                }
                if (q->subpacket[s].samples_per_channel > 512) {
                    q->subpacket[s].log2_numvector_size = 7;
                }
            } else
                q->subpacket[s].samples_per_channel = samples_per_frame;

            break;
        default:
            avpriv_request_sample(avctx, "Cook version %d",
                                  q->subpacket[s].cookversion);
            return AVERROR_PATCHWELCOME;
        }

        if (s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) {
            av_log(avctx, AV_LOG_ERROR, "different number of samples per channel!\n");
            return AVERROR_INVALIDDATA;
        } else
            q->samples_per_channel = q->subpacket[0].samples_per_channel;


        /* Initialize variable relations */
        q->subpacket[s].numvector_size = (1 << q->subpacket[s].log2_numvector_size);

        /* Try to catch some obviously faulty streams, otherwise it might be exploitable */
        if (q->subpacket[s].total_subbands > 53) {
            avpriv_request_sample(avctx, "total_subbands > 53");
            return AVERROR_PATCHWELCOME;
        }

        if ((q->subpacket[s].js_vlc_bits > 6) ||
            (q->subpacket[s].js_vlc_bits < 2 * q->subpacket[s].joint_stereo)) {
            av_log(avctx, AV_LOG_ERROR, "js_vlc_bits = %d, only >= %d and <= 6 allowed!\n",
                   q->subpacket[s].js_vlc_bits, 2 * q->subpacket[s].joint_stereo);
            return AVERROR_INVALIDDATA;
        }

        if (q->subpacket[s].subbands > 50) {
            avpriv_request_sample(avctx, "subbands > 50");
            return AVERROR_PATCHWELCOME;
        }
        if (q->subpacket[s].subbands == 0) {
            avpriv_request_sample(avctx, "subbands = 0");
            return AVERROR_PATCHWELCOME;
        }
        q->subpacket[s].gains1.now      = q->subpacket[s].gain_1;
        q->subpacket[s].gains1.previous = q->subpacket[s].gain_2;
        q->subpacket[s].gains2.now      = q->subpacket[s].gain_3;
        q->subpacket[s].gains2.previous = q->subpacket[s].gain_4;

        if (q->num_subpackets + q->subpacket[s].num_channels > channels) {
            av_log(avctx, AV_LOG_ERROR, "Too many subpackets %d for channels %d\n", q->num_subpackets, channels);
            return AVERROR_INVALIDDATA;
        }

        q->num_subpackets++;
        s++;
    }

    /* Try to catch some obviously faulty streams, otherwise it might be exploitable */
    if (q->samples_per_channel != 256 && q->samples_per_channel != 512 &&
        q->samples_per_channel != 1024) {
        avpriv_request_sample(avctx, "samples_per_channel = %d",
                              q->samples_per_channel);
        return AVERROR_PATCHWELCOME;
    }

    /* Generate tables */
    ff_thread_once(&init_static_once, init_pow2table);
    init_gain_table(q);
    init_cplscales_table(q);

    if ((ret = init_cook_vlc_tables(q)))
        return ret;

    /* Pad the databuffer with:
       DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
       AV_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */
    q->decoded_bytes_buffer =
        av_mallocz(avctx->block_align
                   + DECODE_BYTES_PAD1(avctx->block_align)
                   + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!q->decoded_bytes_buffer)
        return AVERROR(ENOMEM);

    /* Initialize transform. */
    if ((ret = init_cook_mlt(q)))
        return ret;

    /* Initialize COOK signal arithmetic handling */
    if (1) {
        q->scalar_dequant  = scalar_dequant_float;
        q->decouple        = decouple_float;
        q->imlt_window     = imlt_window_float;
        q->interpolate     = interpolate_float;
        q->saturate_output = saturate_output_float;
    }

    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
    av_channel_layout_uninit(&avctx->ch_layout);
    if (channel_mask)
        av_channel_layout_from_mask(&avctx->ch_layout, channel_mask);
    else
        av_channel_layout_default(&avctx->ch_layout, channels);


    dump_cook_context(q);

    return 0;
}

const FFCodec ff_cook_decoder = {
    .p.name         = "cook",
    CODEC_LONG_NAME("Cook / Cooker / Gecko (RealAudio G2)"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_COOK,
    .priv_data_size = sizeof(COOKContext),
    .init           = cook_decode_init,
    .close          = cook_decode_close,
    FF_CODEC_DECODE_CB(cook_decode_frame),
    .p.capabilities = AV_CODEC_CAP_DR1,
    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
};
