/*
 * QPEG codec
 * Copyright (c) 2004 Konstantin Shishkov
 *
 * 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
 * QPEG codec.
 */

#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"

typedef struct QpegContext{
    AVCodecContext *avctx;
    AVFrame *ref;
    uint32_t pal[256];
    GetByteContext buffer;
} QpegContext;

static void qpeg_decode_intra(QpegContext *qctx, uint8_t *dst,
                              int stride, int width, int height)
{
    int i;
    int code;
    int c0, c1;
    int run, copy;
    int filled = 0;
    int rows_to_go;

    rows_to_go = height;
    height--;
    dst = dst + height * stride;

    while ((bytestream2_get_bytes_left(&qctx->buffer) > 0) && (rows_to_go > 0)) {
        code = bytestream2_get_byte(&qctx->buffer);
        run = copy = 0;
        if(code == 0xFC) /* end-of-picture code */
            break;
        if(code >= 0xF8) { /* very long run */
            c0 = bytestream2_get_byte(&qctx->buffer);
            c1 = bytestream2_get_byte(&qctx->buffer);
            run = ((code & 0x7) << 16) + (c0 << 8) + c1 + 2;
        } else if (code >= 0xF0) { /* long run */
            c0 = bytestream2_get_byte(&qctx->buffer);
            run = ((code & 0xF) << 8) + c0 + 2;
        } else if (code >= 0xE0) { /* short run */
            run = (code & 0x1F) + 2;
        } else if (code >= 0xC0) { /* very long copy */
            c0 = bytestream2_get_byte(&qctx->buffer);
            c1 = bytestream2_get_byte(&qctx->buffer);
            copy = ((code & 0x3F) << 16) + (c0 << 8) + c1 + 1;
        } else if (code >= 0x80) { /* long copy */
            c0 = bytestream2_get_byte(&qctx->buffer);
            copy = ((code & 0x7F) << 8) + c0 + 1;
        } else { /* short copy */
            copy = code + 1;
        }

        /* perform actual run or copy */
        if(run) {
            int p;

            p = bytestream2_get_byte(&qctx->buffer);
            for(i = 0; i < run; i++) {
                int step = FFMIN(run - i, width - filled);
                memset(dst+filled, p, step);
                filled += step;
                i      += step - 1;
                if (filled >= width) {
                    filled = 0;
                    dst -= stride;
                    rows_to_go--;
                    while (run - i > width && rows_to_go > 0) {
                        memset(dst, p, width);
                        dst -= stride;
                        rows_to_go--;
                        i += width;
                    }
                    if(rows_to_go <= 0)
                        break;
                }
            }
        } else {
            if (bytestream2_get_bytes_left(&qctx->buffer) < copy)
                copy = bytestream2_get_bytes_left(&qctx->buffer);
            while (copy > 0) {
                int step = FFMIN(copy, width - filled);
                bytestream2_get_bufferu(&qctx->buffer, dst + filled, step);
                filled += step;
                copy -= step;
                if (filled >= width) {
                    filled = 0;
                    dst -= stride;
                    rows_to_go--;
                    if(rows_to_go <= 0)
                        break;
                }
            }
        }
    }
}

static const uint8_t qpeg_table_h[16] =
 { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04};
static const uint8_t qpeg_table_w[16] =
 { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04};

/* Decodes delta frames */
static void av_noinline qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
                              int stride, int width, int height,
                              int delta, const uint8_t *ctable,
                              uint8_t *refdata)
{
    int i, j;
    int code;
    int filled = 0;
    int orig_height;

    if (refdata) {
        /* copy prev frame */
        for (i = 0; i < height; i++)
            memcpy(dst + (i * stride), refdata + (i * stride), width);
    } else {
        refdata = dst;
    }

    orig_height = height;
    height--;
    dst = dst + height * stride;

    while ((bytestream2_get_bytes_left(&qctx->buffer) > 0) && (height >= 0)) {
        code = bytestream2_get_byte(&qctx->buffer);

        if(delta) {
            /* motion compensation */
            while(bytestream2_get_bytes_left(&qctx->buffer) > 0 && (code & 0xF0) == 0xF0) {
                if(delta == 1) {
                    int me_idx;
                    int me_w, me_h, me_x, me_y;
                    uint8_t *me_plane;
                    int corr, val;

                    /* get block size by index */
                    me_idx = code & 0xF;
                    me_w = qpeg_table_w[me_idx];
                    me_h = qpeg_table_h[me_idx];

                    /* extract motion vector */
                    corr = bytestream2_get_byte(&qctx->buffer);

                    val = corr >> 4;
                    if(val > 7)
                        val -= 16;
                    me_x = val;

                    val = corr & 0xF;
                    if(val > 7)
                        val -= 16;
                    me_y = val;

                    /* check motion vector */
                    if ((me_x + filled < 0) || (me_x + me_w + filled > width) ||
                       (height - me_y - me_h < 0) || (height - me_y >= orig_height) ||
                       (filled + me_w > width) || (height - me_h < 0))
                        av_log(qctx->avctx, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n",
                               me_x, me_y, me_w, me_h, filled, height);
                    else {
                        /* do motion compensation */
                        me_plane = refdata + (filled + me_x) + (height - me_y) * stride;
                        for(j = 0; j < me_h; j++) {
                            for(i = 0; i < me_w; i++)
                                dst[filled + i - (j * stride)] = me_plane[i - (j * stride)];
                        }
                    }
                }
                code = bytestream2_get_byte(&qctx->buffer);
            }
        }

        if(code == 0xE0) /* end-of-picture code */
            break;
        if(code > 0xE0) { /* run code: 0xE1..0xFF */
            int p;

            code &= 0x1F;
            p = bytestream2_get_byte(&qctx->buffer);
            for(i = 0; i <= code; i++) {
                dst[filled++] = p;
                if(filled >= width) {
                    filled = 0;
                    dst -= stride;
                    height--;
                    if (height < 0)
                        break;
                }
            }
        } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */
            code &= 0x1F;

            if(code + 1 > bytestream2_get_bytes_left(&qctx->buffer))
                break;

            for(i = 0; i <= code; i++) {
                dst[filled++] = bytestream2_get_byte(&qctx->buffer);
                if(filled >= width) {
                    filled = 0;
                    dst -= stride;
                    height--;
                    if (height < 0)
                        break;
                }
            }
        } else if(code >= 0x80) { /* skip code: 0x80..0xBF */
            int skip;

            code &= 0x3F;
            /* codes 0x80 and 0x81 are actually escape codes,
               skip value minus constant is in the next byte */
            if(!code)
                skip = bytestream2_get_byte(&qctx->buffer) +  64;
            else if(code == 1)
                skip = bytestream2_get_byte(&qctx->buffer) + 320;
            else
                skip = code;
            filled += skip;
            while( filled >= width) {
                filled -= width;
                dst -= stride;
                height--;
                if(height < 0)
                    break;
            }
        } else {
            /* zero code treated as one-pixel skip */
            if(code) {
                dst[filled++] = ctable[code & 0x7F];
            }
            else
                filled++;
            if(filled >= width) {
                filled = 0;
                dst -= stride;
                height--;
            }
        }
    }
}

static int decode_frame(AVCodecContext *avctx, AVFrame *p,
                        int *got_frame, AVPacket *avpkt)
{
    uint8_t ctable[128];
    QpegContext * const a = avctx->priv_data;
    AVFrame * const ref = a->ref;
    uint8_t* outdata;
    int delta, intra, ret;

    if (avpkt->size < 0x86) {
        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
        return AVERROR_INVALIDDATA;
    }

    bytestream2_init(&a->buffer, avpkt->data, avpkt->size);

    if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0)
        return ret;
    outdata = p->data[0];
    bytestream2_skip(&a->buffer, 4);
    bytestream2_get_buffer(&a->buffer, ctable, 128);
    bytestream2_skip(&a->buffer, 1);

    delta = bytestream2_get_byte(&a->buffer);
    intra = delta == 0x10;
    if (intra) {
        qpeg_decode_intra(a, outdata, p->linesize[0], avctx->width, avctx->height);
    } else {
        qpeg_decode_inter(a, outdata, p->linesize[0], avctx->width, avctx->height, delta, ctable, ref->data[0]);
    }

    /* make the palette available on the way out */
#if FF_API_PALETTE_HAS_CHANGED
FF_DISABLE_DEPRECATION_WARNINGS
    p->palette_has_changed =
#endif
    ff_copy_palette(a->pal, avpkt, avctx);
#if FF_API_PALETTE_HAS_CHANGED
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    memcpy(p->data[1], a->pal, AVPALETTE_SIZE);

    if ((ret = av_frame_replace(ref, p)) < 0)
        return ret;

    if (intra)
        p->flags |= AV_FRAME_FLAG_KEY;
    else
        p->flags &= ~AV_FRAME_FLAG_KEY;
    p->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;

    *got_frame      = 1;

    return avpkt->size;
}

static void decode_flush(AVCodecContext *avctx){
    QpegContext * const a = avctx->priv_data;
    int i, pal_size;
    const uint8_t *pal_src;

    av_frame_unref(a->ref);

    pal_size = FFMIN(1024U, avctx->extradata_size);
    pal_src = avctx->extradata + avctx->extradata_size - pal_size;

    for (i=0; i<pal_size/4; i++)
        a->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
}

static av_cold int decode_end(AVCodecContext *avctx)
{
    QpegContext * const a = avctx->priv_data;

    av_frame_free(&a->ref);

    return 0;
}

static av_cold int decode_init(AVCodecContext *avctx){
    QpegContext * const a = avctx->priv_data;

    a->avctx = avctx;
    avctx->pix_fmt= AV_PIX_FMT_PAL8;

    a->ref = av_frame_alloc();
    if (!a->ref)
        return AVERROR(ENOMEM);

    decode_flush(avctx);

    return 0;
}

const FFCodec ff_qpeg_decoder = {
    .p.name         = "qpeg",
    CODEC_LONG_NAME("Q-team QPEG"),
    .p.type         = AVMEDIA_TYPE_VIDEO,
    .p.id           = AV_CODEC_ID_QPEG,
    .priv_data_size = sizeof(QpegContext),
    .init           = decode_init,
    .close          = decode_end,
    FF_CODEC_DECODE_CB(decode_frame),
    .flush          = decode_flush,
    .p.capabilities = AV_CODEC_CAP_DR1,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
};
