/*
 * TTA (The Lossless True Audio) decoder
 * Copyright (c) 2006 Alex Beregszaszi
 *
 * 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
 * TTA (The Lossless True Audio) decoder
 * @see http://www.true-audio.com/
 * @see http://tta.corecodec.org/
 * @author Alex Beregszaszi
 */

#include <limits.h>

#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"

#define BITSTREAM_READER_LE
#include "ttadata.h"
#include "ttadsp.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "get_bits.h"
#include "thread.h"
#include "unary.h"

#define FORMAT_SIMPLE    1
#define FORMAT_ENCRYPTED 2

typedef struct TTAContext {
    AVClass *class;
    AVCodecContext *avctx;
    const AVCRC *crc_table;

    int format, channels, bps;
    unsigned data_length;
    int frame_length, last_frame_length;

    int32_t *decode_buffer;

    uint8_t crc_pass[8];
    uint8_t *pass;
    TTAChannel *ch_ctx;
    TTADSPContext dsp;
} TTAContext;

static const int64_t tta_channel_layouts[7] = {
    AV_CH_LAYOUT_STEREO,
    AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
    AV_CH_LAYOUT_QUAD,
    0,
    AV_CH_LAYOUT_5POINT1_BACK,
    AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER,
    AV_CH_LAYOUT_7POINT1_WIDE
};

static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size)
{
    uint32_t crc, CRC;

    CRC = AV_RL32(buf + buf_size);
    crc = av_crc(s->crc_table, 0xFFFFFFFFU, buf, buf_size);
    if (CRC != (crc ^ 0xFFFFFFFFU)) {
        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

static uint64_t tta_check_crc64(uint8_t *pass)
{
    uint64_t crc = UINT64_MAX, poly = 0x42F0E1EBA9EA3693U;
    uint8_t *end = pass + strlen(pass);
    int i;

    while (pass < end) {
        crc ^= (uint64_t)*pass++ << 56;
        for (i = 0; i < 8; i++)
            crc = (crc << 1) ^ (poly & (((int64_t) crc) >> 63));
    }

    return crc ^ UINT64_MAX;
}

static int allocate_buffers(AVCodecContext *avctx)
{
    TTAContext *s = avctx->priv_data;

    if (s->bps < 3) {
        s->decode_buffer = av_calloc(s->frame_length,
                                     sizeof(*s->decode_buffer) * s->channels);
        if (!s->decode_buffer)
            return AVERROR(ENOMEM);
    } else
        s->decode_buffer = NULL;
    s->ch_ctx = av_malloc_array(avctx->ch_layout.nb_channels, sizeof(*s->ch_ctx));
    if (!s->ch_ctx)
        return AVERROR(ENOMEM);

    return 0;
}

static av_cold int tta_decode_init(AVCodecContext * avctx)
{
    TTAContext *s = avctx->priv_data;
    GetBitContext gb;
    int total_frames;
    int ret;

    s->avctx = avctx;

    // 22 bytes for a TTA1 header
    if (avctx->extradata_size < 22)
        return AVERROR_INVALIDDATA;

    s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
    ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
    if (ret < 0)
        return ret;

    if (show_bits_long(&gb, 32) == AV_RL32("TTA1")) {
        /* signature */
        skip_bits_long(&gb, 32);

        s->format = get_bits(&gb, 16);
        if (s->format > 2) {
            av_log(avctx, AV_LOG_ERROR, "Invalid format\n");
            return AVERROR_INVALIDDATA;
        }
        if (s->format == FORMAT_ENCRYPTED) {
            if (!s->pass) {
                av_log(avctx, AV_LOG_ERROR, "Missing password for encrypted stream. Please use the -password option\n");
                return AVERROR(EINVAL);
            }
            AV_WL64(s->crc_pass, tta_check_crc64(s->pass));
        }

        s->channels = get_bits(&gb, 16);

        av_channel_layout_uninit(&avctx->ch_layout);
        if (s->channels > 1 && s->channels < 9) {
            av_channel_layout_from_mask(&avctx->ch_layout, tta_channel_layouts[s->channels-2]);
        }
        if (avctx->ch_layout.nb_channels == 0) {
            avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
            avctx->ch_layout.nb_channels = s->channels;
        }

        avctx->bits_per_raw_sample = get_bits(&gb, 16);
        s->bps = (avctx->bits_per_raw_sample + 7) / 8;
        avctx->sample_rate = get_bits_long(&gb, 32);
        s->data_length = get_bits_long(&gb, 32);
        skip_bits_long(&gb, 32); // CRC32 of header

        if (s->channels == 0 || s->channels > 16) {
            av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
            return AVERROR_INVALIDDATA;
        } else if (avctx->sample_rate == 0) {
            av_log(avctx, AV_LOG_ERROR, "Invalid samplerate\n");
            return AVERROR_INVALIDDATA;
        }

        switch(s->bps) {
        case 1: avctx->sample_fmt = AV_SAMPLE_FMT_U8; break;
        case 2:
            avctx->sample_fmt = AV_SAMPLE_FMT_S16;
            break;
        case 3:
            avctx->sample_fmt = AV_SAMPLE_FMT_S32;
            break;
        //case 4: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported sample format.\n");
            return AVERROR_INVALIDDATA;
        }

        // prevent overflow
        if (avctx->sample_rate > 0x7FFFFFu) {
            av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n");
            return AVERROR(EINVAL);
        }
        s->frame_length = 256 * avctx->sample_rate / 245;

        s->last_frame_length = s->data_length % s->frame_length;
        total_frames = s->data_length / s->frame_length +
                       (s->last_frame_length ? 1 : 0);

        av_log(avctx, AV_LOG_DEBUG, "format: %d chans: %d bps: %d rate: %d block: %d\n",
            s->format, avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample, avctx->sample_rate,
            avctx->block_align);
        av_log(avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n",
            s->data_length, s->frame_length, s->last_frame_length, total_frames);

        if (s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))) {
            av_log(avctx, AV_LOG_ERROR, "frame_length too large\n");
            return AVERROR_INVALIDDATA;
        }
    } else {
        av_log(avctx, AV_LOG_ERROR, "Wrong extradata present\n");
        return AVERROR_INVALIDDATA;
    }

    ff_ttadsp_init(&s->dsp);

    return allocate_buffers(avctx);
}

static int tta_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                            int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    TTAContext *s = avctx->priv_data;
    GetBitContext gb;
    int i, ret;
    int cur_chan = 0, framelen = s->frame_length;
    uint32_t *p;

    if (avctx->err_recognition & AV_EF_CRCCHECK) {
        if (buf_size < 4 ||
            (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE))
            return AVERROR_INVALIDDATA;
    }

    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
        return ret;

    /* get output buffer */
    frame->nb_samples = framelen;
    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
        return ret;

    // decode directly to output buffer for 24-bit sample format
    if (s->bps == 3)
        s->decode_buffer = (int32_t *)frame->data[0];

    // init per channel states
    for (i = 0; i < s->channels; i++) {
        TTAFilter *filter = &s->ch_ctx[i].filter;
        s->ch_ctx[i].predictor = 0;
        ff_tta_filter_init(filter, ff_tta_filter_configs[s->bps-1]);
        if (s->format == FORMAT_ENCRYPTED) {
            int i;
            for (i = 0; i < 8; i++)
                filter->qm[i] = sign_extend(s->crc_pass[i], 8);
        }
        ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10);
    }

    i = 0;
    for (p = s->decode_buffer; (int32_t*)p < s->decode_buffer + (framelen * s->channels); p++) {
        int32_t *predictor = &s->ch_ctx[cur_chan].predictor;
        TTAFilter *filter = &s->ch_ctx[cur_chan].filter;
        TTARice *rice = &s->ch_ctx[cur_chan].rice;
        uint32_t unary, depth, k;
        int32_t value;

        unary = get_unary(&gb, 0, get_bits_left(&gb));

        if (unary == 0) {
            depth = 0;
            k = rice->k0;
        } else {
            depth = 1;
            k = rice->k1;
            unary--;
        }

        if (get_bits_left(&gb) < k) {
            ret = AVERROR_INVALIDDATA;
            goto error;
        }

        if (k) {
            if (k > MIN_CACHE_BITS || unary > INT32_MAX >> k) {
                ret = AVERROR_INVALIDDATA;
                goto error;
            }
            value = (unary << k) + get_bits(&gb, k);
        } else
            value = unary;

        // FIXME: copy paste from original
        switch (depth) {
        case 1:
            rice->sum1 += value - (rice->sum1 >> 4);
            if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1])
                rice->k1--;
            else if (rice->sum1 > ff_tta_shift_16[rice->k1 + 1])
                rice->k1++;
            value += ff_tta_shift_1[rice->k0];
        default:
            rice->sum0 += value - (rice->sum0 >> 4);
            if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0])
                rice->k0--;
            else if (rice->sum0 > ff_tta_shift_16[rice->k0 + 1])
                rice->k0++;
        }

        // extract coded value
        *p = 1 + ((value >> 1) ^ ((value & 1) - 1));

        // run hybrid filter
        s->dsp.filter_process(filter->qm, filter->dx, filter->dl, &filter->error, p,
                              filter->shift, filter->round);

        // fixed order prediction
#define PRED(x, k) (int32_t)((((uint64_t)(x) << (k)) - (x)) >> (k))
        switch (s->bps) {
        case 1: *p += PRED(*predictor, 4); break;
        case 2:
        case 3: *p += PRED(*predictor, 5); break;
        case 4: *p +=      *predictor;     break;
        }
        *predictor = *p;

        // flip channels
        if (cur_chan < (s->channels-1))
            cur_chan++;
        else {
            // decorrelate in case of multiple channels
            if (s->channels > 1) {
                int32_t *r = p - 1;
                for (*p += *r / 2; r > (int32_t*)p - s->channels; r--)
                    *r = *(r + 1) - (unsigned)*r;
            }
            cur_chan = 0;
            i++;
            // check for last frame
            if (i == s->last_frame_length && get_bits_left(&gb) / 8 == 4) {
                frame->nb_samples = framelen = s->last_frame_length;
                break;
            }
        }
    }

    align_get_bits(&gb);
    if (get_bits_left(&gb) < 32) {
        ret = AVERROR_INVALIDDATA;
        goto error;
    }
    skip_bits_long(&gb, 32); // frame crc

    // convert to output buffer
    switch (s->bps) {
    case 1: {
        uint8_t *samples = (uint8_t *)frame->data[0];
        p = s->decode_buffer;
        for (i = 0; i < framelen * s->channels; i++)
            samples[i] = p[i] + 0x80;
        break;
        }
    case 2: {
        int16_t *samples = (int16_t *)frame->data[0];
        p = s->decode_buffer;
        for (i = 0; i < framelen * s->channels; i++)
            samples[i] = p[i];
        break;
        }
    case 3: {
        // shift samples for 24-bit sample format
        int32_t *samples = (int32_t *)frame->data[0];

        for (i = 0; i < framelen * s->channels; i++)
            samples[i] = samples[i] * 256U;
        // reset decode buffer
        s->decode_buffer = NULL;
        break;
        }
    }

    *got_frame_ptr = 1;

    return buf_size;
error:
    // reset decode buffer
    if (s->bps == 3)
        s->decode_buffer = NULL;
    return ret;
}

static av_cold int tta_decode_close(AVCodecContext *avctx)
{
    TTAContext *s = avctx->priv_data;

    if (s->bps < 3)
        av_freep(&s->decode_buffer);
    s->decode_buffer = NULL;
    av_freep(&s->ch_ctx);

    return 0;
}

#define OFFSET(x) offsetof(TTAContext, x)
#define DEC (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
static const AVOption options[] = {
    { "password", "Set decoding password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, DEC },
    { NULL },
};

static const AVClass tta_decoder_class = {
    .class_name = "TTA Decoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

const FFCodec ff_tta_decoder = {
    .p.name         = "tta",
    CODEC_LONG_NAME("TTA (True Audio)"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_TTA,
    .priv_data_size = sizeof(TTAContext),
    .init           = tta_decode_init,
    .close          = tta_decode_close,
    FF_CODEC_DECODE_CB(tta_decode_frame),
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
    .p.priv_class   = &tta_decoder_class,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
};
