/*
 * RealAudio Lossless decoder
 *
 * Copyright (c) 2012 Konstantin Shishkov
 *
 * This file is part of Libav.
 *
 * Libav 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.
 *
 * Libav 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 Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * This is a decoder for Real Audio Lossless format.
 * Dedicated to the mastermind behind it, Ralph Wiggum.
 */

#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "avcodec.h"
#include "get_bits.h"
#include "golomb.h"
#include "internal.h"
#include "unary.h"
#include "ralfdata.h"

#define FILTER_NONE 0
#define FILTER_RAW  642

typedef struct VLCSet {
    VLC filter_params;
    VLC bias;
    VLC coding_mode;
    VLC filter_coeffs[10][11];
    VLC short_codes[15];
    VLC long_codes[125];
} VLCSet;

#define RALF_MAX_PKT_SIZE 8192

typedef struct RALFContext {
    int version;
    int max_frame_size;
    VLCSet sets[3];
    int32_t channel_data[2][4096];

    int     filter_params;   ///< combined filter parameters for the current channel data
    int     filter_length;   ///< length of the filter for the current channel data
    int     filter_bits;     ///< filter precision for the current channel data
    int32_t filter[64];

    int     bias[2];         ///< a constant value added to channel data after filtering

    int num_blocks;          ///< number of blocks inside the frame
    int sample_offset;
    int block_size[1 << 12]; ///< size of the blocks
    int block_pts[1 << 12];  ///< block start time (in milliseconds)

    uint8_t pkt[16384];
    int     has_pkt;
} RALFContext;

#define MAX_ELEMS 644 // no RALF table uses more than that

static av_cold int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)
{
    uint8_t  lens[MAX_ELEMS];
    uint16_t codes[MAX_ELEMS];
    int counts[17], prefixes[18];
    int i, cur_len;
    int max_bits = 0;
    int nb = 0;

    for (i = 0; i <= 16; i++)
        counts[i] = 0;
    for (i = 0; i < elems; i++) {
        cur_len  = (nb ? *data & 0xF : *data >> 4) + 1;
        counts[cur_len]++;
        max_bits = FFMAX(max_bits, cur_len);
        lens[i]  = cur_len;
        data    += nb;
        nb      ^= 1;
    }
    prefixes[1] = 0;
    for (i = 1; i <= 16; i++)
        prefixes[i + 1] = (prefixes[i] + counts[i]) << 1;

    for (i = 0; i < elems; i++)
        codes[i] = prefixes[lens[i]]++;

    return ff_init_vlc_sparse(vlc, FFMIN(max_bits, 9), elems,
                              lens, 1, 1, codes, 2, 2, NULL, 0, 0, 0);
}

static av_cold int decode_close(AVCodecContext *avctx)
{
    RALFContext *ctx = avctx->priv_data;
    int i, j, k;

    for (i = 0; i < 3; i++) {
        ff_free_vlc(&ctx->sets[i].filter_params);
        ff_free_vlc(&ctx->sets[i].bias);
        ff_free_vlc(&ctx->sets[i].coding_mode);
        for (j = 0; j < 10; j++)
            for (k = 0; k < 11; k++)
                ff_free_vlc(&ctx->sets[i].filter_coeffs[j][k]);
        for (j = 0; j < 15; j++)
            ff_free_vlc(&ctx->sets[i].short_codes[j]);
        for (j = 0; j < 125; j++)
            ff_free_vlc(&ctx->sets[i].long_codes[j]);
    }

    return 0;
}

static av_cold int decode_init(AVCodecContext *avctx)
{
    RALFContext *ctx = avctx->priv_data;
    int i, j, k;
    int ret;

    if (avctx->extradata_size < 24 || memcmp(avctx->extradata, "LSD:", 4)) {
        av_log(avctx, AV_LOG_ERROR, "Extradata is not groovy, dude\n");
        return AVERROR_INVALIDDATA;
    }

    ctx->version = AV_RB16(avctx->extradata + 4);
    if (ctx->version != 0x103) {
        avpriv_request_sample(avctx, "Unknown version %X", ctx->version);
        return AVERROR_PATCHWELCOME;
    }

    avctx->channels    = AV_RB16(avctx->extradata + 8);
    avctx->sample_rate = AV_RB32(avctx->extradata + 12);
    if (avctx->channels < 1 || avctx->channels > 2
        || avctx->sample_rate < 8000 || avctx->sample_rate > 96000) {
        av_log(avctx, AV_LOG_ERROR, "Invalid coding parameters %d Hz %d ch\n",
               avctx->sample_rate, avctx->channels);
        return AVERROR_INVALIDDATA;
    }
    avctx->sample_fmt     = AV_SAMPLE_FMT_S16P;
    avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO
                                                   : AV_CH_LAYOUT_MONO;

    ctx->max_frame_size = AV_RB32(avctx->extradata + 16);
    if (ctx->max_frame_size > (1 << 20) || !ctx->max_frame_size) {
        av_log(avctx, AV_LOG_ERROR, "invalid frame size %d\n",
               ctx->max_frame_size);
    }
    ctx->max_frame_size = FFMAX(ctx->max_frame_size, avctx->sample_rate);

    for (i = 0; i < 3; i++) {
        ret = init_ralf_vlc(&ctx->sets[i].filter_params, filter_param_def[i],
                            FILTERPARAM_ELEMENTS);
        if (ret < 0) {
            decode_close(avctx);
            return ret;
        }
        ret = init_ralf_vlc(&ctx->sets[i].bias, bias_def[i], BIAS_ELEMENTS);
        if (ret < 0) {
            decode_close(avctx);
            return ret;
        }
        ret = init_ralf_vlc(&ctx->sets[i].coding_mode, coding_mode_def[i],
                            CODING_MODE_ELEMENTS);
        if (ret < 0) {
            decode_close(avctx);
            return ret;
        }
        for (j = 0; j < 10; j++) {
            for (k = 0; k < 11; k++) {
                ret = init_ralf_vlc(&ctx->sets[i].filter_coeffs[j][k],
                                    filter_coeffs_def[i][j][k],
                                    FILTER_COEFFS_ELEMENTS);
                if (ret < 0) {
                    decode_close(avctx);
                    return ret;
                }
            }
        }
        for (j = 0; j < 15; j++) {
            ret = init_ralf_vlc(&ctx->sets[i].short_codes[j],
                                short_codes_def[i][j], SHORT_CODES_ELEMENTS);
            if (ret < 0) {
                decode_close(avctx);
                return ret;
            }
        }
        for (j = 0; j < 125; j++) {
            ret = init_ralf_vlc(&ctx->sets[i].long_codes[j],
                                long_codes_def[i][j], LONG_CODES_ELEMENTS);
            if (ret < 0) {
                decode_close(avctx);
                return ret;
            }
        }
    }

    return 0;
}

static inline int extend_code(GetBitContext *gb, int val, int range, int bits)
{
    if (val == 0) {
        val = -range - get_ue_golomb(gb);
    } else if (val == range * 2) {
        val =  range + get_ue_golomb(gb);
    } else {
        val -= range;
    }
    if (bits)
        val = (val << bits) | get_bits(gb, bits);
    return val;
}

static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch,
                          int length, int mode, int bits)
{
    int i, t;
    int code_params;
    VLCSet *set = ctx->sets + mode;
    VLC *code_vlc; int range, range2, add_bits;
    int *dst = ctx->channel_data[ch];

    ctx->filter_params = get_vlc2(gb, set->filter_params.table, 9, 2);
    ctx->filter_bits   = (ctx->filter_params - 2) >> 6;
    ctx->filter_length = ctx->filter_params - (ctx->filter_bits << 6) - 1;

    if (ctx->filter_params == FILTER_RAW) {
        for (i = 0; i < length; i++)
            dst[i] = get_bits(gb, bits);
        ctx->bias[ch] = 0;
        return 0;
    }

    ctx->bias[ch] = get_vlc2(gb, set->bias.table, 9, 2);
    ctx->bias[ch] = extend_code(gb, ctx->bias[ch], 127, 4);

    if (ctx->filter_params == FILTER_NONE) {
        memset(dst, 0, sizeof(*dst) * length);
        return 0;
    }

    if (ctx->filter_params > 1) {
        int cmode = 0, coeff = 0;
        VLC *vlc = set->filter_coeffs[ctx->filter_bits] + 5;

        add_bits = ctx->filter_bits;

        for (i = 0; i < ctx->filter_length; i++) {
            t = get_vlc2(gb, vlc[cmode].table, vlc[cmode].bits, 2);
            t = extend_code(gb, t, 21, add_bits);
            if (!cmode)
                coeff -= 12 << add_bits;
            coeff = t - coeff;
            ctx->filter[i] = coeff;

            cmode = coeff >> add_bits;
            if (cmode < 0) {
                cmode = -1 - av_log2(-cmode);
                if (cmode < -5)
                    cmode = -5;
            } else if (cmode > 0) {
                cmode =  1 + av_log2(cmode);
                if (cmode > 5)
                    cmode = 5;
            }
        }
    }

    code_params = get_vlc2(gb, set->coding_mode.table, set->coding_mode.bits, 2);
    if (code_params >= 15) {
        add_bits = av_clip((code_params / 5 - 3) / 2, 0, 10);
        if (add_bits > 9 && (code_params % 5) != 2)
            add_bits--;
        range    = 10;
        range2   = 21;
        code_vlc = set->long_codes + code_params - 15;
    } else {
        add_bits = 0;
        range    = 6;
        range2   = 13;
        code_vlc = set->short_codes + code_params;
    }

    for (i = 0; i < length; i += 2) {
        int code1, code2;

        t = get_vlc2(gb, code_vlc->table, code_vlc->bits, 2);
        code1 = t / range2;
        code2 = t % range2;
        dst[i]     = extend_code(gb, code1, range, 0) << add_bits;
        dst[i + 1] = extend_code(gb, code2, range, 0) << add_bits;
        if (add_bits) {
            dst[i]     |= get_bits(gb, add_bits);
            dst[i + 1] |= get_bits(gb, add_bits);
        }
    }

    return 0;
}

static void apply_lpc(RALFContext *ctx, int ch, int length, int bits)
{
    int i, j, acc;
    int *audio = ctx->channel_data[ch];
    int bias = 1 << (ctx->filter_bits - 1);
    int max_clip = (1 << bits) - 1, min_clip = -max_clip - 1;

    for (i = 1; i < length; i++) {
        int flen = FFMIN(ctx->filter_length, i);

        acc = 0;
        for (j = 0; j < flen; j++)
            acc += ctx->filter[j] * audio[i - j - 1];
        if (acc < 0) {
            acc = (acc + bias - 1) >> ctx->filter_bits;
            acc = FFMAX(acc, min_clip);
        } else {
            acc = (acc + bias) >> ctx->filter_bits;
            acc = FFMIN(acc, max_clip);
        }
        audio[i] += acc;
    }
}

static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
                        int16_t *dst0, int16_t *dst1)
{
    RALFContext *ctx = avctx->priv_data;
    int len, ch, ret;
    int dmode, mode[2], bits[2];
    int *ch0, *ch1;
    int i, t, t2;

    len = 12 - get_unary(gb, 0, 6);

    if (len <= 7) len ^= 1; // codes for length = 6 and 7 are swapped
    len = 1 << len;

    if (ctx->sample_offset + len > ctx->max_frame_size) {
        av_log(avctx, AV_LOG_ERROR,
               "Decoder's stomach is crying, it ate too many samples\n");
        return AVERROR_INVALIDDATA;
    }

    if (avctx->channels > 1)
        dmode = get_bits(gb, 2) + 1;
    else
        dmode = 0;

    mode[0] = (dmode == 4) ? 1 : 0;
    mode[1] = (dmode >= 2) ? 2 : 0;
    bits[0] = 16;
    bits[1] = (mode[1] == 2) ? 17 : 16;

    for (ch = 0; ch < avctx->channels; ch++) {
        if ((ret = decode_channel(ctx, gb, ch, len, mode[ch], bits[ch])) < 0)
            return ret;
        if (ctx->filter_params > 1 && ctx->filter_params != FILTER_RAW) {
            ctx->filter_bits += 3;
            apply_lpc(ctx, ch, len, bits[ch]);
        }
        if (get_bits_left(gb) < 0)
            return AVERROR_INVALIDDATA;
    }
    ch0 = ctx->channel_data[0];
    ch1 = ctx->channel_data[1];
    switch (dmode) {
    case 0:
        for (i = 0; i < len; i++)
            dst0[i] = ch0[i] + ctx->bias[0];
        break;
    case 1:
        for (i = 0; i < len; i++) {
            dst0[i] = ch0[i] + ctx->bias[0];
            dst1[i] = ch1[i] + ctx->bias[1];
        }
        break;
    case 2:
        for (i = 0; i < len; i++) {
            ch0[i] += ctx->bias[0];
            dst0[i] = ch0[i];
            dst1[i] = ch0[i] - (ch1[i] + ctx->bias[1]);
        }
        break;
    case 3:
        for (i = 0; i < len; i++) {
            t  = ch0[i] + ctx->bias[0];
            t2 = ch1[i] + ctx->bias[1];
            dst0[i] = t + t2;
            dst1[i] = t;
        }
        break;
    case 4:
        for (i = 0; i < len; i++) {
            t  =   ch1[i] + ctx->bias[1];
            t2 = ((ch0[i] + ctx->bias[0]) << 1) | (t & 1);
            dst0[i] = (t2 + t) / 2;
            dst1[i] = (t2 - t) / 2;
        }
        break;
    }

    ctx->sample_offset += len;

    return 0;
}

static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
                        AVPacket *avpkt)
{
    RALFContext *ctx = avctx->priv_data;
    AVFrame *frame   = data;
    int16_t *samples0;
    int16_t *samples1;
    int ret;
    GetBitContext gb;
    int table_size, table_bytes, i;
    const uint8_t *src, *block_pointer;
    int src_size;
    int bytes_left;

    if (ctx->has_pkt) {
        ctx->has_pkt = 0;
        table_bytes = (AV_RB16(avpkt->data) + 7) >> 3;
        if (table_bytes + 3 > avpkt->size || avpkt->size > RALF_MAX_PKT_SIZE) {
            av_log(avctx, AV_LOG_ERROR, "Wrong packet's breath smells of wrong data!\n");
            return AVERROR_INVALIDDATA;
        }
        if (memcmp(ctx->pkt, avpkt->data, 2 + table_bytes)) {
            av_log(avctx, AV_LOG_ERROR, "Wrong packet tails are wrong!\n");
            return AVERROR_INVALIDDATA;
        }

        src      = ctx->pkt;
        src_size = RALF_MAX_PKT_SIZE + avpkt->size;
        memcpy(ctx->pkt + RALF_MAX_PKT_SIZE, avpkt->data + 2 + table_bytes,
               avpkt->size - 2 - table_bytes);
    } else {
        if (avpkt->size == RALF_MAX_PKT_SIZE) {
            memcpy(ctx->pkt, avpkt->data, avpkt->size);
            ctx->has_pkt   = 1;
            *got_frame_ptr = 0;

            return avpkt->size;
        }
        src      = avpkt->data;
        src_size = avpkt->size;
    }

    frame->nb_samples = ctx->max_frame_size;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    samples0 = (int16_t *)frame->data[0];
    samples1 = (int16_t *)frame->data[1];

    if (src_size < 5) {
        av_log(avctx, AV_LOG_ERROR, "too short packets are too short!\n");
        return AVERROR_INVALIDDATA;
    }
    table_size  = AV_RB16(src);
    table_bytes = (table_size + 7) >> 3;
    if (src_size < table_bytes + 3) {
        av_log(avctx, AV_LOG_ERROR, "short packets are short!\n");
        return AVERROR_INVALIDDATA;
    }
    init_get_bits(&gb, src + 2, table_size);
    ctx->num_blocks = 0;
    while (get_bits_left(&gb) > 0) {
        ctx->block_size[ctx->num_blocks] = get_bits(&gb, 15);
        if (get_bits1(&gb)) {
            ctx->block_pts[ctx->num_blocks] = get_bits(&gb, 9);
        } else {
            ctx->block_pts[ctx->num_blocks] = 0;
        }
        ctx->num_blocks++;
    }

    block_pointer = src      + table_bytes + 2;
    bytes_left    = src_size - table_bytes - 2;
    ctx->sample_offset = 0;
    for (i = 0; i < ctx->num_blocks; i++) {
        if (bytes_left < ctx->block_size[i]) {
            av_log(avctx, AV_LOG_ERROR, "I'm pedaling backwards\n");
            break;
        }
        init_get_bits(&gb, block_pointer, ctx->block_size[i] * 8);
        if (decode_block(avctx, &gb, samples0 + ctx->sample_offset,
                                     samples1 + ctx->sample_offset) < 0) {
            av_log(avctx, AV_LOG_ERROR, "Sir, I got carsick in your office. Not decoding the rest of packet.\n");
            break;
        }
        block_pointer += ctx->block_size[i];
        bytes_left    -= ctx->block_size[i];
    }

    frame->nb_samples = ctx->sample_offset;
    *got_frame_ptr    = ctx->sample_offset > 0;

    return avpkt->size;
}

static void decode_flush(AVCodecContext *avctx)
{
    RALFContext *ctx = avctx->priv_data;

    ctx->has_pkt = 0;
}


AVCodec ff_ralf_decoder = {
    .name           = "ralf",
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_RALF,
    .priv_data_size = sizeof(RALFContext),
    .init           = decode_init,
    .close          = decode_close,
    .decode         = decode_frame,
    .flush          = decode_flush,
    .capabilities   = CODEC_CAP_DR1,
    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio Lossless"),
    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_NONE },
};
