/*
 * Shorten decoder
 * Copyright (c) 2005 Jeff Muizelaar
 *
 * 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
 * Shorten decoder
 * @author Jeff Muizelaar
 *
 */

#include <limits.h>
#include "avcodec.h"
#include "get_bits.h"
#include "golomb.h"

#define MAX_CHANNELS 8
#define MAX_BLOCKSIZE 65535

#define OUT_BUFFER_SIZE 16384

#define ULONGSIZE 2

#define WAVE_FORMAT_PCM 0x0001

#define DEFAULT_BLOCK_SIZE 256

#define TYPESIZE 4
#define CHANSIZE 0
#define LPCQSIZE 2
#define ENERGYSIZE 3
#define BITSHIFTSIZE 2

#define TYPE_S16HL 3
#define TYPE_S16LH 5

#define NWRAP 3
#define NSKIPSIZE 1

#define LPCQUANT 5
#define V2LPCQOFFSET (1 << LPCQUANT)

#define FNSIZE 2
#define FN_DIFF0        0
#define FN_DIFF1        1
#define FN_DIFF2        2
#define FN_DIFF3        3
#define FN_QUIT         4
#define FN_BLOCKSIZE    5
#define FN_BITSHIFT     6
#define FN_QLPC         7
#define FN_ZERO         8
#define FN_VERBATIM     9

#define VERBATIM_CKSIZE_SIZE 5
#define VERBATIM_BYTE_SIZE 8
#define CANONICAL_HEADER_SIZE 44

typedef struct ShortenContext {
    AVCodecContext *avctx;
    GetBitContext gb;

    int min_framesize, max_framesize;
    int channels;

    int32_t *decoded[MAX_CHANNELS];
    int32_t *decoded_base[MAX_CHANNELS];
    int32_t *offset[MAX_CHANNELS];
    int *coeffs;
    uint8_t *bitstream;
    int bitstream_size;
    int bitstream_index;
    unsigned int allocated_bitstream_size;
    int header_size;
    uint8_t header[OUT_BUFFER_SIZE];
    int version;
    int cur_chan;
    int bitshift;
    int nmean;
    int internal_ftype;
    int nwrap;
    int blocksize;
    int bitindex;
    int32_t lpcqoffset;
} ShortenContext;

static av_cold int shorten_decode_init(AVCodecContext * avctx)
{
    ShortenContext *s = avctx->priv_data;
    s->avctx = avctx;
    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    return 0;
}

static int allocate_buffers(ShortenContext *s)
{
    int i, chan;
    int *coeffs;
    void *tmp_ptr;

    for (chan=0; chan<s->channels; chan++) {
        if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){
            av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n");
            return -1;
        }
        if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){
            av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n");
            return -1;
        }

        tmp_ptr = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean));
        if (!tmp_ptr)
            return AVERROR(ENOMEM);
        s->offset[chan] = tmp_ptr;

        tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) *
                             sizeof(s->decoded_base[0][0]));
        if (!tmp_ptr)
            return AVERROR(ENOMEM);
        s->decoded_base[chan] = tmp_ptr;
        for (i=0; i<s->nwrap; i++)
            s->decoded_base[chan][i] = 0;
        s->decoded[chan] = s->decoded_base[chan] + s->nwrap;
    }

    coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs));
    if (!coeffs)
        return AVERROR(ENOMEM);
    s->coeffs = coeffs;

    return 0;
}


static inline unsigned int get_uint(ShortenContext *s, int k)
{
    if (s->version != 0)
        k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
    return get_ur_golomb_shorten(&s->gb, k);
}


static void fix_bitshift(ShortenContext *s, int32_t *buffer)
{
    int i;

    if (s->bitshift != 0)
        for (i = 0; i < s->blocksize; i++)
            buffer[i] <<= s->bitshift;
}


static void init_offset(ShortenContext *s)
{
    int32_t mean = 0;
    int  chan, i;
    int nblock = FFMAX(1, s->nmean);
    /* initialise offset */
    switch (s->internal_ftype)
    {
        case TYPE_S16HL:
        case TYPE_S16LH:
            mean = 0;
            break;
        default:
            av_log(s->avctx, AV_LOG_ERROR, "unknown audio type");
            abort();
    }

    for (chan = 0; chan < s->channels; chan++)
        for (i = 0; i < nblock; i++)
            s->offset[chan][i] = mean;
}

static inline int get_le32(GetBitContext *gb)
{
    return av_bswap32(get_bits_long(gb, 32));
}

static inline short get_le16(GetBitContext *gb)
{
    return av_bswap16(get_bits_long(gb, 16));
}

static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size)
{
    GetBitContext hb;
    int len;
    short wave_format;

    init_get_bits(&hb, header, header_size*8);
    if (get_le32(&hb) != MKTAG('R','I','F','F')) {
        av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
        return -1;
    }

    skip_bits_long(&hb, 32);    /* chunk_size */

    if (get_le32(&hb) != MKTAG('W','A','V','E')) {
        av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
        return -1;
    }

    while (get_le32(&hb) != MKTAG('f','m','t',' ')) {
        len = get_le32(&hb);
        skip_bits(&hb, 8*len);
    }
    len = get_le32(&hb);

    if (len < 16) {
        av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
        return -1;
    }

    wave_format = get_le16(&hb);

    switch (wave_format) {
        case WAVE_FORMAT_PCM:
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n");
            return -1;
    }

    avctx->channels = get_le16(&hb);
    avctx->sample_rate = get_le32(&hb);
    avctx->bit_rate = get_le32(&hb) * 8;
    avctx->block_align = get_le16(&hb);
    avctx->bits_per_coded_sample = get_le16(&hb);

    if (avctx->bits_per_coded_sample != 16) {
        av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n");
        return -1;
    }

    len -= 16;
    if (len > 0)
        av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len);

    return 0;
}

static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) {
    int i, chan;
    for (i=0; i<blocksize; i++)
        for (chan=0; chan < nchan; chan++)
            *samples++ = FFMIN(buffer[chan][i], 32768);
    return samples;
}

static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order)
{
    int sum, i, j;
    int *coeffs = s->coeffs;

    for (i=0; i<pred_order; i++)
        coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);

    for (i=0; i < s->blocksize; i++) {
        sum = s->lpcqoffset;
        for (j=0; j<pred_order; j++)
            sum += coeffs[j] * s->decoded[channel][i-j-1];
        s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT);
    }
}


static int shorten_decode_frame(AVCodecContext *avctx,
        void *data, int *data_size,
        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    ShortenContext *s = avctx->priv_data;
    int i, input_buf_size = 0;
    int16_t *samples = data;
    if(s->max_framesize == 0){
        void *tmp_ptr;
        s->max_framesize= 1024; // should hopefully be enough for the first header
        tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
                                  s->max_framesize);
        if (!tmp_ptr) {
            av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");
            return AVERROR(ENOMEM);
        }
        s->bitstream = tmp_ptr;
    }

    if(1 && s->max_framesize){//FIXME truncated
        buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
        input_buf_size= buf_size;

        if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){
            //                printf("memmove\n");
            memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
            s->bitstream_index=0;
        }
        memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
        buf= &s->bitstream[s->bitstream_index];
        buf_size += s->bitstream_size;
        s->bitstream_size= buf_size;

        if(buf_size < s->max_framesize){
            *data_size = 0;
            return input_buf_size;
        }
    }
    init_get_bits(&s->gb, buf, buf_size*8);
    skip_bits(&s->gb, s->bitindex);
    if (!s->blocksize)
    {
        int maxnlpc = 0;
        /* shorten signature */
        if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
            av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
            return -1;
        }

        s->lpcqoffset = 0;
        s->blocksize = DEFAULT_BLOCK_SIZE;
        s->channels = 1;
        s->nmean = -1;
        s->version = get_bits(&s->gb, 8);
        s->internal_ftype = get_uint(s, TYPESIZE);

        s->channels = get_uint(s, CHANSIZE);
        if (s->channels > MAX_CHANNELS) {
            av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
            return -1;
        }

        /* get blocksize if version > 0 */
        if (s->version > 0) {
            int skip_bytes;
            s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
            maxnlpc = get_uint(s, LPCQSIZE);
            s->nmean = get_uint(s, 0);

            skip_bytes = get_uint(s, NSKIPSIZE);
            for (i=0; i<skip_bytes; i++) {
                skip_bits(&s->gb, 8);
            }
        }
        s->nwrap = FFMAX(NWRAP, maxnlpc);

        if (allocate_buffers(s))
            return -1;

        init_offset(s);

        if (s->version > 1)
            s->lpcqoffset = V2LPCQOFFSET;

        if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
            av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n");
            return -1;
        }

        s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
        if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
            av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
            return -1;
        }

        for (i=0; i<s->header_size; i++)
            s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);

        if (decode_wave_header(avctx, s->header, s->header_size) < 0)
            return -1;

        s->cur_chan = 0;
        s->bitshift = 0;
    }
    else
    {
        int cmd;
        int len;
        cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
        switch (cmd) {
            case FN_ZERO:
            case FN_DIFF0:
            case FN_DIFF1:
            case FN_DIFF2:
            case FN_DIFF3:
            case FN_QLPC:
                {
                    int residual_size = 0;
                    int channel = s->cur_chan;
                    int32_t coffset;
                    if (cmd != FN_ZERO) {
                        residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
                        /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
                        if (s->version == 0)
                            residual_size--;
                    }

                    if (s->nmean == 0)
                        coffset = s->offset[channel][0];
                    else {
                        int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
                        for (i=0; i<s->nmean; i++)
                            sum += s->offset[channel][i];
                        coffset = sum / s->nmean;
                        if (s->version >= 2)
                            coffset >>= FFMIN(1, s->bitshift);
                    }
                    switch (cmd) {
                        case FN_ZERO:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = 0;
                            break;
                        case FN_DIFF0:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset;
                            break;
                        case FN_DIFF1:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1];
                            break;
                        case FN_DIFF2:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1]
                                                                                                      -   s->decoded[channel][i-2];
                            break;
                        case FN_DIFF3:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1]
                                                                                                      - 3*s->decoded[channel][i-2]
                                                                                                      +   s->decoded[channel][i-3];
                            break;
                        case FN_QLPC:
                            {
                                int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
                                if (pred_order > s->nwrap) {
                                    av_log(avctx, AV_LOG_ERROR,
                                           "invalid pred_order %d\n",
                                           pred_order);
                                    return -1;
                                }
                                for (i=0; i<pred_order; i++)
                                    s->decoded[channel][i - pred_order] -= coffset;
                                decode_subframe_lpc(s, channel, residual_size, pred_order);
                                if (coffset != 0)
                                    for (i=0; i < s->blocksize; i++)
                                        s->decoded[channel][i] += coffset;
                            }
                    }
                    if (s->nmean > 0) {
                        int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
                        for (i=0; i<s->blocksize; i++)
                            sum += s->decoded[channel][i];

                        for (i=1; i<s->nmean; i++)
                            s->offset[channel][i-1] = s->offset[channel][i];

                        if (s->version < 2)
                            s->offset[channel][s->nmean - 1] = sum / s->blocksize;
                        else
                            s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
                    }
                    for (i=-s->nwrap; i<0; i++)
                        s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];

                    fix_bitshift(s, s->decoded[channel]);

                    s->cur_chan++;
                    if (s->cur_chan == s->channels) {
                        int out_size = s->blocksize * s->channels *
                                       av_get_bytes_per_sample(avctx->sample_fmt);
                        if (*data_size < out_size) {
                            av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
                            return AVERROR(EINVAL);
                        }
                        samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
                        s->cur_chan = 0;
                        goto frame_done;
                    }
                    break;
                }
                break;
            case FN_VERBATIM:
                len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
                while (len--) {
                    get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
                }
                break;
            case FN_BITSHIFT:
                s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
                break;
            case FN_BLOCKSIZE: {
                int blocksize = get_uint(s, av_log2(s->blocksize));
                if (blocksize > s->blocksize) {
                    av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n");
                    return AVERROR_PATCHWELCOME;
                }
                s->blocksize = blocksize;
                break;
            }
            case FN_QUIT:
                *data_size = 0;
                return buf_size;
                break;
            default:
                av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
                return -1;
                break;
        }
    }
frame_done:
    *data_size = (int8_t *)samples - (int8_t *)data;

    //    s->last_blocksize = s->blocksize;
    s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
    i= (get_bits_count(&s->gb))/8;
    if (i > buf_size) {
        av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
        s->bitstream_size=0;
        s->bitstream_index=0;
        return -1;
    }
    if (s->bitstream_size) {
        s->bitstream_index += i;
        s->bitstream_size  -= i;
        return input_buf_size;
    } else
        return i;
}

static av_cold int shorten_decode_close(AVCodecContext *avctx)
{
    ShortenContext *s = avctx->priv_data;
    int i;

    for (i = 0; i < s->channels; i++) {
        s->decoded[i] = NULL;
        av_freep(&s->decoded_base[i]);
        av_freep(&s->offset[i]);
    }
    av_freep(&s->bitstream);
    av_freep(&s->coeffs);
    return 0;
}

static void shorten_flush(AVCodecContext *avctx){
    ShortenContext *s = avctx->priv_data;

    s->bitstream_size=
        s->bitstream_index= 0;
}

AVCodec ff_shorten_decoder = {
    "shorten",
    AVMEDIA_TYPE_AUDIO,
    CODEC_ID_SHORTEN,
    sizeof(ShortenContext),
    shorten_decode_init,
    NULL,
    shorten_decode_close,
    shorten_decode_frame,
    .flush= shorten_flush,
    .long_name= NULL_IF_CONFIG_SMALL("Shorten"),
};
