/*
 * Electronic Arts TGV Video Decoder
 * Copyright (c) 2007-2008 Peter Ross
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * @file
 * Electronic Arts TGV Video Decoder
 * by Peter Ross (pross@xvid.org)
 *
 * Technical details here:
 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGV
 */

#include "libavutil/imgutils.h"
#include "libavutil/mem.h"

#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"

#define EA_PREAMBLE_SIZE    8
#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')

typedef struct TgvContext {
    AVCodecContext *avctx;
    AVFrame *last_frame;
    uint8_t *frame_buffer;
    int width,height;
    uint32_t palette[AVPALETTE_COUNT];

    int (*mv_codebook)[2];
    uint8_t (*block_codebook)[16];
    int num_mvs;           ///< current length of mv_codebook
    int num_blocks_packed; ///< current length of block_codebook
} TgvContext;

static av_cold int tgv_decode_init(AVCodecContext *avctx)
{
    TgvContext *s = avctx->priv_data;
    s->avctx         = avctx;
    avctx->framerate = (AVRational){ 15, 1 };
    avctx->pix_fmt   = AV_PIX_FMT_PAL8;

    s->last_frame = av_frame_alloc();
    if (!s->last_frame)
        return AVERROR(ENOMEM);

    return 0;
}

/**
 * Unpack buffer
 * @return 0 on success, -1 on critical buffer underflow
 */
static int unpack(const uint8_t *src, const uint8_t *src_end,
                  uint8_t *dst, int width, int height)
{
    uint8_t *dst_end = dst + width*height;
    int size, size1, size2, offset, run;
    uint8_t *dst_start = dst;

    if (src[0] & 0x01)
        src += 5;
    else
        src += 2;

    if (src_end - src < 3)
        return AVERROR_INVALIDDATA;
    size = AV_RB24(src);
    src += 3;

    while (size > 0 && src < src_end) {

        /* determine size1 and size2 */
        size1 = (src[0] & 3);
        if (src[0] & 0x80) {  // 1
            if (src[0] & 0x40 ) {  // 11
                if (src[0] & 0x20) {  // 111
                    if (src[0] < 0xFC)  // !(111111)
                        size1 = (((src[0] & 31) + 1) << 2);
                    src++;
                    size2 = 0;
                } else {  // 110
                    offset = ((src[0] & 0x10) << 12) + AV_RB16(&src[1]) + 1;
                    size2  = ((src[0] & 0xC) << 6) + src[3] + 5;
                    src   += 4;
                }
            } else {  // 10
                size1  = ((src[1] & 0xC0) >> 6);
                offset = (AV_RB16(&src[1]) & 0x3FFF) + 1;
                size2  = (src[0] & 0x3F) + 4;
                src   += 3;
            }
        } else {  // 0
            offset = ((src[0] & 0x60) << 3) + src[1] + 1;
            size2  = ((src[0] & 0x1C) >> 2) + 3;
            src   += 2;
        }


        /* fetch strip from src */
        if (size1 > src_end - src)
            break;

        if (size1 > 0) {
            size -= size1;
            run   = FFMIN(size1, dst_end - dst);
            memcpy(dst, src, run);
            dst += run;
            src += run;
        }

        if (size2 > 0) {
            if (dst - dst_start < offset)
                return 0;
            size -= size2;
            run   = FFMIN(size2, dst_end - dst);
            av_memcpy_backptr(dst, offset, run);
            dst += run;
        }
    }

    return 0;
}

/**
 * Decode inter-frame
 * @return 0 on success, -1 on critical buffer underflow
 */
static int tgv_decode_inter(TgvContext *s, AVFrame *frame,
                            const uint8_t *buf, const uint8_t *buf_end)
{
    int num_mvs;
    int num_blocks_raw;
    int num_blocks_packed;
    int vector_bits;
    int i,j,x,y;
    GetBitContext gb;
    int mvbits;
    const uint8_t *blocks_raw;

    if(buf_end - buf < 12)
        return AVERROR_INVALIDDATA;

    num_mvs           = AV_RL16(&buf[0]);
    num_blocks_raw    = AV_RL16(&buf[2]);
    num_blocks_packed = AV_RL16(&buf[4]);
    vector_bits       = AV_RL16(&buf[6]);
    buf += 12;

    if (vector_bits > MIN_CACHE_BITS || !vector_bits) {
        av_log(s->avctx, AV_LOG_ERROR,
               "Invalid value for motion vector bits: %d\n", vector_bits);
        return AVERROR_INVALIDDATA;
    }

    /* allocate codebook buffers as necessary */
    if (num_mvs > s->num_mvs) {
        int err = av_reallocp_array(&s->mv_codebook, num_mvs, sizeof(*s->mv_codebook));
        if (err < 0) {
            s->num_mvs = 0;
            return err;
        }
        s->num_mvs = num_mvs;
    }

    if (num_blocks_packed > s->num_blocks_packed) {
        int err;
        if ((err = av_reallocp(&s->block_codebook, num_blocks_packed * 16)) < 0) {
            s->num_blocks_packed = 0;
            return err;
        }
        s->num_blocks_packed = num_blocks_packed;
    }

    /* read motion vectors */
    mvbits = (num_mvs * 2 * 10 + 31) & ~31;

    if (buf_end - buf < (mvbits>>3) + 16*num_blocks_raw + 8*num_blocks_packed)
        return AVERROR_INVALIDDATA;

    init_get_bits(&gb, buf, mvbits);
    for (i = 0; i < num_mvs; i++) {
        s->mv_codebook[i][0] = get_sbits(&gb, 10);
        s->mv_codebook[i][1] = get_sbits(&gb, 10);
    }
    buf += mvbits >> 3;

    /* note ptr to uncompressed blocks */
    blocks_raw = buf;
    buf       += num_blocks_raw * 16;

    /* read compressed blocks */
    init_get_bits(&gb, buf, (buf_end - buf) << 3);
    for (i = 0; i < num_blocks_packed; i++) {
        int tmp[4];
        for (j = 0; j < 4; j++)
            tmp[j] = get_bits(&gb, 8);
        for (j = 0; j < 16; j++)
            s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];
    }

    if (get_bits_left(&gb) < vector_bits *
        (s->avctx->height / 4) * (s->avctx->width / 4))
        return AVERROR_INVALIDDATA;

    /* read vectors and build frame */
    for (y = 0; y < s->avctx->height / 4; y++)
        for (x = 0; x < s->avctx->width / 4; x++) {
            unsigned int vector = get_bits(&gb, vector_bits);
            const uint8_t *src;
            ptrdiff_t src_stride;

            if (vector < num_mvs) {
                int mx = x * 4 + s->mv_codebook[vector][0];
                int my = y * 4 + s->mv_codebook[vector][1];

                if (mx < 0 || mx + 4 > s->avctx->width ||
                    my < 0 || my + 4 > s->avctx->height) {
                    av_log(s->avctx, AV_LOG_ERROR, "MV %d %d out of picture\n", mx, my);
                    continue;
                }

                src = s->last_frame->data[0] + mx + my * s->last_frame->linesize[0];
                src_stride = s->last_frame->linesize[0];
            } else {
                int offset = vector - num_mvs;
                if (offset < num_blocks_raw)
                    src = blocks_raw + 16*offset;
                else if (offset - num_blocks_raw < num_blocks_packed)
                    src = s->block_codebook[offset - num_blocks_raw];
                else
                    continue;
                src_stride = 4;
            }

            for (j = 0; j < 4; j++)
                for (i = 0; i < 4; i++)
                    frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] =
                        src[j * src_stride + i];
    }

    return 0;
}

static int tgv_decode_frame(AVCodecContext *avctx,
                            void *data, int *got_frame,
                            AVPacket *avpkt)
{
    const uint8_t *buf     = avpkt->data;
    int buf_size           = avpkt->size;
    TgvContext *s          = avctx->priv_data;
    const uint8_t *buf_end = buf + buf_size;
    AVFrame *frame         = data;
    int chunk_type, ret;

    if (buf_end - buf < EA_PREAMBLE_SIZE)
        return AVERROR_INVALIDDATA;

    chunk_type = AV_RL32(&buf[0]);
    buf       += EA_PREAMBLE_SIZE;

    if (chunk_type == kVGT_TAG) {
        int pal_count, i;
        if(buf_end - buf < 12) {
            av_log(avctx, AV_LOG_WARNING, "truncated header\n");
            return AVERROR_INVALIDDATA;
        }

        s->width  = AV_RL16(&buf[0]);
        s->height = AV_RL16(&buf[2]);
        if (s->avctx->width != s->width || s->avctx->height != s->height) {
            av_freep(&s->frame_buffer);
            av_frame_unref(s->last_frame);
            if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
                return ret;
        }

        pal_count = AV_RL16(&buf[6]);
        buf += 12;
        for(i = 0; i < pal_count && i < AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
            s->palette[i] = 0xFFU << 24 | AV_RB24(buf);
            buf += 3;
        }
        if (buf_end - buf < 5) {
            return AVERROR_INVALIDDATA;
        }
    }

    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
        return ret;

    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);

    if (chunk_type == kVGT_TAG) {
        int y;
        frame->key_frame = 1;
        frame->pict_type = AV_PICTURE_TYPE_I;

        if (!s->frame_buffer &&
            !(s->frame_buffer = av_mallocz(s->width * s->height)))
            return AVERROR(ENOMEM);

        if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) {
            av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
            return AVERROR_INVALIDDATA;
        }
        for (y = 0; y < s->height; y++)
            memcpy(frame->data[0]  + y * frame->linesize[0],
                   s->frame_buffer + y * s->width,
                   s->width);
    } else {
        if (!s->last_frame->data[0]) {
            av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
            return buf_size;
        }
        frame->key_frame = 0;
        frame->pict_type = AV_PICTURE_TYPE_P;
        if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
            av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
            return AVERROR_INVALIDDATA;
        }
    }

    av_frame_unref(s->last_frame);
    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
        return ret;

    *got_frame = 1;

    return buf_size;
}

static av_cold int tgv_decode_end(AVCodecContext *avctx)
{
    TgvContext *s = avctx->priv_data;
    av_frame_free(&s->last_frame);
    av_freep(&s->frame_buffer);
    av_freep(&s->mv_codebook);
    av_freep(&s->block_codebook);
    return 0;
}

AVCodec ff_eatgv_decoder = {
    .name           = "eatgv",
    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_TGV,
    .priv_data_size = sizeof(TgvContext),
    .init           = tgv_decode_init,
    .close          = tgv_decode_end,
    .decode         = tgv_decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
};
