/*
 * Psygnosis YOP decoder
 *
 * Copyright (C) 2010 Mohamed Naufal Basheer <naufal11@gmail.com>
 * derived from the code by
 * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
 *
 * 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 "libavutil/intreadwrite.h"
#include "libavutil/imgutils.h"

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

typedef struct YopDecContext {
    AVFrame frame;
    AVCodecContext *avctx;

    int num_pal_colors;
    int first_color[2];
    int frame_data_length;
    int row_pos;

    uint8_t *low_nibble;
    uint8_t *srcptr;
    uint8_t *dstptr;
    uint8_t *dstbuf;
} YopDecContext;

// These tables are taken directly from:
// http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP

/**
 * Lookup table for painting macroblocks. Bytes 0-2 of each entry contain
 * the macroblock positions to be painted (taken as (0, B0, B1, B2)).
 * Byte 3 contains the number of bytes consumed on the input,
 * equal to max(bytes 0-2) + 1.
 */
static const uint8_t paint_lut[15][4] =
    {{1, 2, 3, 4}, {1, 2, 0, 3},
     {1, 2, 1, 3}, {1, 2, 2, 3},
     {1, 0, 2, 3}, {1, 0, 0, 2},
     {1, 0, 1, 2}, {1, 1, 2, 3},
     {0, 1, 2, 3}, {0, 1, 0, 2},
     {1, 1, 0, 2}, {0, 1, 1, 2},
     {0, 0, 1, 2}, {0, 0, 0, 1},
     {1, 1, 1, 2},
    };

/**
 * Lookup table for copying macroblocks. Each entry contains the respective
 * x and y pixel offset for the copy source.
 */
static const int8_t motion_vector[16][2] =
    {{-4, -4}, {-2, -4},
     { 0, -4}, { 2, -4},
     {-4, -2}, {-4,  0},
     {-3, -3}, {-1, -3},
     { 1, -3}, { 3, -3},
     {-3, -1}, {-2, -2},
     { 0, -2}, { 2, -2},
     { 4, -2}, {-2,  0},
    };

static av_cold int yop_decode_init(AVCodecContext *avctx)
{
    YopDecContext *s = avctx->priv_data;
    s->avctx = avctx;

    if (avctx->width & 1 || avctx->height & 1 ||
        av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
        av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n");
        return -1;
    }

    if (!avctx->extradata) {
        av_log(avctx, AV_LOG_ERROR, "extradata missing\n");
        return AVERROR_INVALIDDATA;
    }

    avctx->pix_fmt = PIX_FMT_PAL8;

    avcodec_get_frame_defaults(&s->frame);
    s->num_pal_colors = avctx->extradata[0];
    s->first_color[0] = avctx->extradata[1];
    s->first_color[1] = avctx->extradata[2];

    if (s->num_pal_colors + s->first_color[0] > 256 ||
        s->num_pal_colors + s->first_color[1] > 256) {
        av_log(avctx, AV_LOG_ERROR,
               "YOP: palette parameters invalid, header probably corrupt\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

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

/**
 * Paint a macroblock using the pattern in paint_lut.
 * @param s codec context
 * @param tag the tag that was in the nibble
 */
static void yop_paint_block(YopDecContext *s, int tag)
{
    s->dstptr[0]                        = s->srcptr[0];
    s->dstptr[1]                        = s->srcptr[paint_lut[tag][0]];
    s->dstptr[s->frame.linesize[0]]     = s->srcptr[paint_lut[tag][1]];
    s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]];

    // The number of src bytes consumed is in the last part of the lut entry.
    s->srcptr += paint_lut[tag][3];
}

/**
 * Copy a previously painted macroblock to the current_block.
 * @param copy_tag the tag that was in the nibble
 */
static int yop_copy_previous_block(YopDecContext *s, int copy_tag)
{
    uint8_t *bufptr;

    // Calculate position for the copy source
    bufptr = s->dstptr + motion_vector[copy_tag][0] +
             s->frame.linesize[0] * motion_vector[copy_tag][1];
    if (bufptr < s->dstbuf) {
        av_log(s->avctx, AV_LOG_ERROR,
               "YOP: cannot decode, file probably corrupt\n");
        return AVERROR_INVALIDDATA;
    }

    s->dstptr[0]                        = bufptr[0];
    s->dstptr[1]                        = bufptr[1];
    s->dstptr[s->frame.linesize[0]]     = bufptr[s->frame.linesize[0]];
    s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1];

    return 0;
}

/**
 * Return the next nibble in sequence, consuming a new byte on the input
 * only if necessary.
 */
static uint8_t yop_get_next_nibble(YopDecContext *s)
{
    int ret;

    if (s->low_nibble) {
        ret           = *s->low_nibble & 0xf;
        s->low_nibble = NULL;
    }else {
        s->low_nibble = s->srcptr++;
        ret           = *s->low_nibble >> 4;
    }
    return ret;
}

/**
 * Take s->dstptr to the next macroblock in sequence.
 */
static void yop_next_macroblock(YopDecContext *s)
{
    // If we are advancing to the next row of macroblocks
    if (s->row_pos == s->frame.linesize[0] - 2) {
        s->dstptr  += s->frame.linesize[0];
        s->row_pos =  0;
    }else {
        s->row_pos += 2;
    }
    s->dstptr += 2;
}

static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                            AVPacket *avpkt)
{
    YopDecContext *s = avctx->priv_data;
    int tag, firstcolor, is_odd_frame;
    int ret, i;
    uint32_t *palette;

    if (s->frame.data[0])
        avctx->release_buffer(avctx, &s->frame);

    if (avpkt->size < 4 + 3*s->num_pal_colors) {
        av_log(avctx, AV_LOG_ERROR, "packet of size %d too small\n", avpkt->size);
        return AVERROR_INVALIDDATA;
    }

    ret = ff_get_buffer(avctx, &s->frame);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }

    s->frame.linesize[0] = avctx->width;

    s->dstbuf     = s->frame.data[0];
    s->dstptr     = s->frame.data[0];
    s->srcptr     = avpkt->data + 4;
    s->row_pos    = 0;
    s->low_nibble = NULL;

    is_odd_frame = avpkt->data[0];
    if(is_odd_frame>1){
        av_log(avctx, AV_LOG_ERROR, "frame is too odd %d\n", is_odd_frame);
        return AVERROR_INVALIDDATA;
    }
    firstcolor   = s->first_color[is_odd_frame];
    palette      = (uint32_t *)s->frame.data[1];

    for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) {
        palette[i + firstcolor] = (s->srcptr[0] << 18) |
                                  (s->srcptr[1] << 10) |
                                  (s->srcptr[2] << 2);
        palette[i + firstcolor] |= 0xFF << 24 |
                                   (palette[i + firstcolor] >> 6) & 0x30303;
    }

    s->frame.palette_has_changed = 1;

    while (s->dstptr - s->dstbuf <
           avctx->width * avctx->height &&
           s->srcptr - avpkt->data < avpkt->size) {

        tag = yop_get_next_nibble(s);

        if (tag != 0xf) {
            yop_paint_block(s, tag);
        }else {
            tag = yop_get_next_nibble(s);
            ret = yop_copy_previous_block(s, tag);
            if (ret < 0) {
                avctx->release_buffer(avctx, &s->frame);
                return ret;
            }
        }
        yop_next_macroblock(s);
    }

    *data_size        = sizeof(AVFrame);
    *(AVFrame *) data = s->frame;
    return avpkt->size;
}

AVCodec ff_yop_decoder = {
    .name           = "yop",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_YOP,
    .priv_data_size = sizeof(YopDecContext),
    .init           = yop_decode_init,
    .close          = yop_decode_close,
    .decode         = yop_decode_frame,
    .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
};
