/*
 * Electronic Arts TGQ Video Decoder
 * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
 *
 * 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 libavcodec/eatgq.c
 * Electronic Arts TGQ Video Decoder
 * @author Peter Ross <pross@xvid.org>
 *
 * Technical details here:
 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGQ
 */

#include "avcodec.h"
#define ALT_BITSTREAM_READER_LE
#include "bitstream.h"
#include "bytestream.h"
#include "dsputil.h"
#include "aandcttab.h"

typedef struct TgqContext {
    AVCodecContext *avctx;
    DSPContext dsp;
    AVFrame frame;
    int width,height;
    ScanTable scantable;
    int qtable[64];
} TgqContext;

static av_cold int tgq_decode_init(AVCodecContext *avctx){
    TgqContext *s = avctx->priv_data;
    s->avctx = avctx;
    if(avctx->idct_algo==FF_IDCT_AUTO)
        avctx->idct_algo=FF_IDCT_EA;
    dsputil_init(&s->dsp, avctx);
    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
    avctx->time_base = (AVRational){1, 15};
    avctx->pix_fmt = PIX_FMT_YUV420P;
    return 0;
}

static void tgq_decode_block(TgqContext *s, DCTELEM block[64], GetBitContext *gb){
    uint8_t *perm = s->scantable.permutated;
    int i,j,value;
    block[0] = get_sbits(gb,8) * s->qtable[0];
    for(i=1; i<64; ) {
        switch(show_bits(gb,3)) {
        case 4:
            block[perm[i++]] = 0;
        case 0:
            block[perm[i++]] = 0;
            skip_bits(gb,3);
            break;
        case 5:
        case 1:
            skip_bits(gb,2);
            value = get_bits(gb,6);
            for(j=0; j<value; j++)
                block[perm[i++]] = 0;
            break;
        case 6:
            skip_bits(gb,3);
            block[perm[i]] = -s->qtable[perm[i]];
            i++;
            break;
        case 2:
            skip_bits(gb,3);
            block[perm[i]] = s->qtable[perm[i]];
            i++;
            break;
        case 7: // 111b
        case 3: // 011b
            skip_bits(gb,2);
            if (show_bits(gb,6)==0x3F) {
                skip_bits(gb, 6);
                block[perm[i]] = get_sbits(gb,8)*s->qtable[perm[i]];
            }else{
                block[perm[i]] = get_sbits(gb,6)*s->qtable[perm[i]];
            }
            i++;
            break;
        }
    }
    block[0] += 128<<4;
}

static void tgq_idct_put_mb(TgqContext *s, DCTELEM (*block)[64], int mb_x, int mb_y){
    int linesize= s->frame.linesize[0];
    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;

    s->dsp.idct_put(dest_y                 , linesize, block[0]);
    s->dsp.idct_put(dest_y              + 8, linesize, block[1]);
    s->dsp.idct_put(dest_y + 8*linesize    , linesize, block[2]);
    s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
    if(!(s->avctx->flags&CODEC_FLAG_GRAY)){
         s->dsp.idct_put(dest_cb, s->frame.linesize[1], block[4]);
         s->dsp.idct_put(dest_cr, s->frame.linesize[2], block[5]);
    }
}

static inline void tgq_dconly(TgqContext *s, unsigned char *dst, int dst_stride, int dc){
    int level = av_clip_uint8((dc*s->qtable[0] + 2056)>>4);
    int j;
    for(j=0;j<8;j++)
        memset(dst+j*dst_stride, level, 8);
}

static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc)
{
    int linesize= s->frame.linesize[0];
    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;
    tgq_dconly(s,dest_y                 , linesize, dc[0]);
    tgq_dconly(s,dest_y              + 8, linesize, dc[1]);
    tgq_dconly(s,dest_y + 8*linesize    , linesize, dc[2]);
    tgq_dconly(s,dest_y + 8*linesize + 8, linesize, dc[3]);
    if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
        tgq_dconly(s,dest_cb, s->frame.linesize[1], dc[4]);
        tgq_dconly(s,dest_cr, s->frame.linesize[2], dc[5]);
    }
}

static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x, const int8_t **bs, const int8_t *buf_end){
    int mode;
    int i;
    int8_t dc[6];
    DCTELEM block[6][64];

    mode = bytestream_get_byte((const uint8_t**)bs);
    if (mode>buf_end-*bs) {
        av_log(s->avctx, AV_LOG_ERROR, "truncated macroblock\n");
        return;
    }

    if (mode>12) {
        GetBitContext gb;
        init_get_bits(&gb, *bs, mode*8);
        for(i=0; i<6; i++)
            tgq_decode_block(s, block[i], &gb);
        tgq_idct_put_mb(s, block, mb_x, mb_y);
    }else{
        if (mode==3) {
            memset(dc, (*bs)[0], 4);
            dc[4] = (*bs)[1];
            dc[5] = (*bs)[2];
        }else if (mode==6) {
            memcpy(dc, *bs, 6);
        }else if (mode==12) {
            for(i=0; i<6; i++)
                dc[i] = (*bs)[i*2];
        }else{
            av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
        }
        tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
    }
    *bs += mode;
}

static void tgq_calculate_qtable(TgqContext *s, int quant){
    int i,j;
    const int a = (14*(100-quant))/100 + 1;
    const int b = (11*(100-quant))/100 + 4;
    for(j=0;j<8;j++)
    for(i=0;i<8;i++)
        if (s->avctx->idct_algo==FF_IDCT_EA)
            s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4);
        else
            s->qtable[j*8+i] = (a*(j+i)/(7+7) + b)<<3;
}

static int tgq_decode_frame(AVCodecContext *avctx,
                            void *data, int *data_size,
                            const uint8_t *buf, int buf_size){
    const uint8_t *buf_start = buf;
    const uint8_t *buf_end = buf + buf_size;
    TgqContext *s = avctx->priv_data;
    int x,y;

    int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
    buf += 8;

    if(8>buf_end-buf) {
        av_log(avctx, AV_LOG_WARNING, "truncated header\n");
        return -1;
    }
    s->width  = big_endian ? AV_RB16(&buf[0]) : AV_RL16(&buf[0]);
    s->height = big_endian ? AV_RB16(&buf[2]) : AV_RL16(&buf[2]);

    if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
        avcodec_set_dimensions(s->avctx, s->width, s->height);
        if (s->frame.data[0])
            avctx->release_buffer(avctx, &s->frame);
    }
    tgq_calculate_qtable(s, buf[4]);
    buf += 8;

    if (!s->frame.data[0]) {
        s->frame.key_frame = 1;
        s->frame.pict_type = FF_I_TYPE;
        s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
        if (avctx->get_buffer(avctx, &s->frame)) {
            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
            return -1;
        }
    }

    for (y=0; y<(avctx->height+15)/16; y++)
    for (x=0; x<(avctx->width+15)/16; x++)
        tgq_decode_mb(s, y, x, (const int8_t**)&buf, (const int8_t*)buf_end);

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;

    return buf-buf_start;
}

static av_cold int tgq_decode_end(AVCodecContext *avctx){
    TgqContext *s = avctx->priv_data;
    if (s->frame.data[0])
        s->avctx->release_buffer(avctx, &s->frame);
    return 0;
}

AVCodec eatgq_decoder = {
    "eatgq",
    CODEC_TYPE_VIDEO,
    CODEC_ID_TGQ,
    sizeof(TgqContext),
    tgq_decode_init,
    NULL,
    tgq_decode_end,
    tgq_decode_frame,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
};
