/*
 * Duck TrueMotion 2.0 Real Time decoder
 *
 * 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
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

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

typedef struct TrueMotion2RTContext {
    GetBitContext gb;
    int delta_size;
    int hscale;
} TrueMotion2RTContext;

static const int16_t delta_tab2[] = {
    5, -7, 36, -36,
};

static const int16_t delta_tab3[] = {
    2, -3, 8, -8, 18, -18, 36, -36,
};

static const int16_t delta_tab4[] = {
    1, -1, 2, -3, 8, -8, 18, -18, 36, -36, 54, -54, 96, -96, 144, -144,
};

static const int16_t *const delta_tabs[] = {
    delta_tab2, delta_tab3, delta_tab4,
};

/* Returns the number of bytes consumed from the bytestream, or
 * AVERROR_INVALIDDATA if there was an error while decoding the header. */
static int truemotion2rt_decode_header(AVCodecContext *avctx, const AVPacket *avpkt)
{
    TrueMotion2RTContext *s = avctx->priv_data;
    int header_size;
    uint8_t header_buffer[128] = { 0 };  /* logical maximum header size */
    const uint8_t *buf = avpkt->data;
    int size = avpkt->size;
    int width, height;
    int ret, i;

    if (size < 1) {
        av_log(avctx, AV_LOG_ERROR, "input packet too small (%d)\n", size);
        return AVERROR_INVALIDDATA;
    }

    header_size = ((buf[0] >> 5) | (buf[0] << 3)) & 0x7f;
    if (header_size < 10) {
        av_log(avctx, AV_LOG_ERROR, "invalid header size (%d)\n", header_size);
        return AVERROR_INVALIDDATA;
    }

    if (header_size + 1 > size) {
        av_log(avctx, AV_LOG_ERROR, "input packet too small (%d)\n", size);
        return AVERROR_INVALIDDATA;
    }

    /* unscramble the header bytes with a XOR operation */
    for (i = 1; i < header_size; i++)
        header_buffer[i - 1] = buf[i] ^ buf[i + 1];

    s->delta_size = header_buffer[1];
    s->hscale = 1 + !!header_buffer[3];
    if (s->delta_size < 2 || s->delta_size > 4)
        return AVERROR_INVALIDDATA;

    height = AV_RL16(header_buffer + 5);
    width  = AV_RL16(header_buffer + 7);

    ret = ff_set_dimensions(avctx, width, height);
    if (ret < 0)
        return ret;

    av_log(avctx, AV_LOG_DEBUG, "Header size: %d\n", header_size);
    return header_size;
}

static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data,
                                      int *got_frame, AVPacket *avpkt)
{
    TrueMotion2RTContext *s = avctx->priv_data;
    AVFrame * const p = data;
    GetBitContext *gb = &s->gb;
    uint8_t *dst;
    int x, y, delta_mode;
    int ret;

    ret = truemotion2rt_decode_header(avctx, avpkt);
    if (ret < 0)
        return ret;

    if (avctx->width / s->hscale * avctx->height * s->delta_size > avpkt->size * 8LL * 4)
        return AVERROR_INVALIDDATA;

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

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

    skip_bits(gb, 32);
    delta_mode = s->delta_size - 2;
    dst = p->data[0];
    for (y = 0; y < avctx->height; y++) {
        int diff = 0;
        for (x = 0; x < avctx->width; x += s->hscale) {
            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[0]] : 0) + diff);
        }
        dst += p->linesize[0];
    }

    if (s->hscale > 1) {
        dst = p->data[0];
        for (y = 0; y < avctx->height; y++) {
            for (x = 1; x < avctx->width; x += s->hscale)
                dst[x] = dst[x - 1];
            dst += p->linesize[0];
        }
    }

    dst = p->data[0];
    for (y = 0; y < avctx->height; y++) {
        for (x = 0; x < avctx->width; x++)
            dst[x] = av_clip_uint8(dst[x] + (dst[x] - 128) / 3);
        dst += p->linesize[0];
    }

    dst = p->data[1];
    for (y = 0; y < avctx->height >> 2; y++) {
        int diff = 0;
        for (x = 0; x < avctx->width >> 2; x += s->hscale) {
            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[1]] : 128) + diff);
        }
        dst += p->linesize[1];
    }

    if (s->hscale > 1) {
        dst = p->data[1];
        for (y = 0; y < avctx->height >> 2; y++) {
            for (x = 1; x < avctx->width >> 2; x += s->hscale)
                dst[x] = dst[x - 1];
            dst += p->linesize[1];
        }
    }

    dst = p->data[1];
    for (y = 0; y < avctx->height >> 2; y++) {
        for (x = 0; x < avctx->width >> 2; x++)
            dst[x] += (dst[x] - 128) / 8;
        dst += p->linesize[1];
    }

    dst = p->data[2];
    for (y = 0; y < avctx->height >> 2; y++) {
        int diff = 0;
        for (x = 0; x < avctx->width >> 2; x += s->hscale) {
            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[2]] : 128) + diff);
        }
        dst += p->linesize[2];
    }

    if (s->hscale > 1) {
        dst = p->data[2];
        for (y = 0; y < avctx->height >> 2; y++) {
            for (x = 1; x < avctx->width >> 2; x += s->hscale)
                dst[x] = dst[x - 1];
            dst += p->linesize[2];
        }
    }

    dst = p->data[2];
    for (y = 0; y < avctx->height >> 2; y++) {
        for (x = 0; x < avctx->width >> 2; x++)
            dst[x] += (dst[x] - 128) / 8;
        dst += p->linesize[2];
    }

    p->pict_type = AV_PICTURE_TYPE_I;
    p->key_frame = 1;
    *got_frame = 1;

    return avpkt->size;
}

static av_cold int truemotion2rt_decode_init(AVCodecContext *avctx)
{
    avctx->pix_fmt = AV_PIX_FMT_YUV410P;
    return 0;
}

AVCodec ff_truemotion2rt_decoder = {
    .name           = "truemotion2rt",
    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_TRUEMOTION2RT,
    .priv_data_size = sizeof(TrueMotion2RTContext),
    .init           = truemotion2rt_decode_init,
    .decode         = truemotion2rt_decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
};
