/*
 * 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 *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[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
        if (!tmp_ptr)
            return AVERROR(ENOMEM);
        s->decoded[chan] = tmp_ptr;
        for (i=0; i<s->nwrap; i++)
            s->decoded[chan][i] = 0;
        s->decoded[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] -= s->nwrap;
        av_freep(&s->decoded[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"),
};
