/*
 * CDToons video decoder
 * Copyright (C) 2020 Alyssa Milburn <amilburn@zall.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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * CDToons video decoder
 * @author Alyssa Milburn <amilburn@zall.org>
 */

#include <stdint.h>

#include "libavutil/attributes.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"

#define CDTOONS_HEADER_SIZE   44
#define CDTOONS_MAX_SPRITES 1200

typedef struct CDToonsSprite {
    uint16_t flags;
    uint16_t owner_frame;
    uint16_t start_frame;
    uint16_t end_frame;
    unsigned int alloc_size;
    uint32_t size;
    uint8_t *data;
    int      active;
} CDToonsSprite;

typedef struct CDToonsContext {
    AVFrame *frame;

    uint16_t last_pal_id;   ///< The index of the active palette sprite.
    uint32_t pal[256];      ///< The currently-used palette data.
    CDToonsSprite sprites[CDTOONS_MAX_SPRITES];
} CDToonsContext;

static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data,
                                 uint32_t data_size,
                                 int dst_x, int dst_y, int width, int height)
{
    CDToonsContext *c = avctx->priv_data;
    const uint8_t *next_line = data;
    const uint8_t *end = data + data_size;
    uint16_t line_size;
    uint8_t *dest;
    int skip = 0, to_skip, x;

    if (dst_x + width > avctx->width)
        width = avctx->width - dst_x;
    if (dst_y + height > avctx->height)
        height = avctx->height - dst_y;

    if (dst_x < 0) {
        /* we need to skip the start of the scanlines */
        skip = -dst_x;
        if (width <= skip)
            return 0;
        dst_x = 0;
    }

    for (int y = 0; y < height; y++) {
        /* one scanline at a time, size is provided */
        data      = next_line;
        if (end - data < 2)
            return 1;
        line_size = bytestream_get_be16(&data);
        if (end - data < line_size)
            return 1;
        next_line = data + line_size;
        if (dst_y + y < 0)
            continue;

        dest = c->frame->data[0] + (dst_y + y) * c->frame->linesize[0] + dst_x;

        to_skip = skip;
        x       = 0;
        while (x < width - skip) {
            int raw, size, step;
            uint8_t val;

            if (data >= end)
                return 1;

            val  = bytestream_get_byte(&data);
            raw  = !(val & 0x80);
            size = (int)(val & 0x7F) + 1;

            /* skip the start of a scanline if it is off-screen */
            if (to_skip >= size) {
                to_skip -= size;
                if (raw) {
                    step = size;
                } else {
                    step = 1;
                }
                if (next_line - data < step)
                    return 1;
                data += step;
                continue;
            } else if (to_skip) {
                size -= to_skip;
                if (raw) {
                    if (next_line - data < to_skip)
                        return 1;
                    data += to_skip;
                }
                to_skip = 0;
            }

            if (x + size >= width - skip)
                size = width - skip - x;

            /* either raw data, or a run of a single color */
            if (raw) {
                if (next_line - data < size)
                    return 1;
                memcpy(dest + x, data, size);
                data += size;
            } else {
                uint8_t color = bytestream_get_byte(&data);
                /* ignore transparent runs */
                if (color)
                    memset(dest + x, color, size);
            }
            x += size;
        }
    }

    return 0;
}

static int cdtoons_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame, AVPacket *avpkt)
{
    CDToonsContext *c = avctx->priv_data;
    const uint8_t *buf = avpkt->data;
    const uint8_t *eod = avpkt->data + avpkt->size;
    const int buf_size = avpkt->size;
    uint16_t frame_id;
    uint8_t background_color;
    uint16_t sprite_count, sprite_offset;
    uint8_t referenced_count;
    uint16_t palette_id;
    uint8_t palette_set;
    int ret;
    int saw_embedded_sprites = 0;

    if (buf_size < CDTOONS_HEADER_SIZE)
        return AVERROR_INVALIDDATA;

    if ((ret = ff_reget_buffer(avctx, c->frame, 0)) < 0)
        return ret;

    /* a lot of the header is useless junk in the absence of
     * dirty rectangling etc */
    buf               += 2; /* version? (always 9?) */
    frame_id           = bytestream_get_be16(&buf);
    buf               += 2; /* blocks_valid_until */
    buf               += 1;
    background_color   = bytestream_get_byte(&buf);
    buf               += 16; /* clip rect, dirty rect */
    buf               += 4; /* flags */
    sprite_count       = bytestream_get_be16(&buf);
    sprite_offset      = bytestream_get_be16(&buf);
    buf               += 2; /* max block id? */
    referenced_count   = bytestream_get_byte(&buf);
    buf               += 1;
    palette_id         = bytestream_get_be16(&buf);
    palette_set        = bytestream_get_byte(&buf);
    buf               += 5;

    /* read new sprites introduced in this frame */
    buf = avpkt->data + sprite_offset;
    while (sprite_count--) {
        uint32_t size;
        uint16_t sprite_id;

        if (buf + 14 > eod)
            return AVERROR_INVALIDDATA;

        sprite_id = bytestream_get_be16(&buf);
        if (sprite_id >= CDTOONS_MAX_SPRITES) {
            av_log(avctx, AV_LOG_ERROR,
                   "Sprite ID %d is too high.\n", sprite_id);
            return AVERROR_INVALIDDATA;
        }
        if (c->sprites[sprite_id].active) {
            av_log(avctx, AV_LOG_ERROR,
                   "Sprite ID %d is a duplicate.\n", sprite_id);
            return AVERROR_INVALIDDATA;
        }

        c->sprites[sprite_id].flags = bytestream_get_be16(&buf);
        size                        = bytestream_get_be32(&buf);
        if (size < 14) {
            av_log(avctx, AV_LOG_ERROR,
                   "Sprite only has %d bytes of data.\n", size);
            return AVERROR_INVALIDDATA;
        }
        size -= 14;
        c->sprites[sprite_id].size        = size;
        c->sprites[sprite_id].owner_frame = frame_id;
        c->sprites[sprite_id].start_frame = bytestream_get_be16(&buf);
        c->sprites[sprite_id].end_frame   = bytestream_get_be16(&buf);
        buf += 2;

        if (size > buf_size || buf + size > eod)
            return AVERROR_INVALIDDATA;

        av_fast_padded_malloc(&c->sprites[sprite_id].data, &c->sprites[sprite_id].alloc_size, size);
        if (!c->sprites[sprite_id].data)
            return AVERROR(ENOMEM);

        c->sprites[sprite_id].active = 1;

        bytestream_get_buffer(&buf, c->sprites[sprite_id].data, size);
    }

    /* render any embedded sprites */
    while (buf < eod) {
        uint32_t tag, size;
        if (buf + 8 > eod) {
            av_log(avctx, AV_LOG_WARNING, "Ran (seriously) out of data for embedded sprites.\n");
            return AVERROR_INVALIDDATA;
        }
        tag  = bytestream_get_be32(&buf);
        size = bytestream_get_be32(&buf);
        if (tag == MKBETAG('D', 'i', 'f', 'f')) {
            uint16_t diff_count;
            if (buf + 10 > eod) {
                av_log(avctx, AV_LOG_WARNING, "Ran (seriously) out of data for Diff frame.\n");
                return AVERROR_INVALIDDATA;
            }
            diff_count = bytestream_get_be16(&buf);
            buf       += 8; /* clip rect? */
            for (int i = 0; i < diff_count; i++) {
                int16_t top, left;
                uint16_t diff_size, width, height;

                if (buf + 16 > eod) {
                    av_log(avctx, AV_LOG_WARNING, "Ran (seriously) out of data for Diff frame header.\n");
                    return AVERROR_INVALIDDATA;
                }

                top        = bytestream_get_be16(&buf);
                left       = bytestream_get_be16(&buf);
                buf       += 4; /* bottom, right */
                diff_size  = bytestream_get_be32(&buf);
                width      = bytestream_get_be16(&buf);
                height     = bytestream_get_be16(&buf);
                if (diff_size < 8 || diff_size - 4 > eod - buf) {
                    av_log(avctx, AV_LOG_WARNING, "Ran (seriously) out of data for Diff frame data.\n");
                    return AVERROR_INVALIDDATA;
                }
                if (cdtoons_render_sprite(avctx, buf + 4, diff_size - 8,
                                      left, top, width, height)) {
                    av_log(avctx, AV_LOG_WARNING, "Ran beyond end of sprite while rendering.\n");
                }
                buf += diff_size - 4;
            }
            saw_embedded_sprites = 1;
        } else {
            /* we don't care about any other entries */
            if (size < 8 || size - 8 > eod - buf) {
                av_log(avctx, AV_LOG_WARNING, "Ran out of data for ignored entry (size %X, %d left).\n", size, (int)(eod - buf));
                return AVERROR_INVALIDDATA;
            }
            buf += (size - 8);
        }
    }

    /* was an intra frame? */
    if (saw_embedded_sprites)
        goto done;

    /* render any referenced sprites */
    buf = avpkt->data + CDTOONS_HEADER_SIZE;
    eod = avpkt->data + sprite_offset;
    for (int i = 0; i < referenced_count; i++) {
        const uint8_t *block_data;
        uint16_t sprite_id, width, height;
        int16_t top, left, right;

        if (buf + 10 > eod) {
            av_log(avctx, AV_LOG_WARNING, "Ran (seriously) out of data when rendering.\n");
            return AVERROR_INVALIDDATA;
        }

        sprite_id = bytestream_get_be16(&buf);
        top       = bytestream_get_be16(&buf);
        left      = bytestream_get_be16(&buf);
        buf      += 2; /* bottom */
        right     = bytestream_get_be16(&buf);

        if ((i == 0) && (sprite_id == 0)) {
            /* clear background */
            memset(c->frame->data[0], background_color,
                   c->frame->linesize[0] * avctx->height);
        }

        if (!right)
            continue;
        if (sprite_id >= CDTOONS_MAX_SPRITES) {
            av_log(avctx, AV_LOG_ERROR,
                   "Sprite ID %d is too high.\n", sprite_id);
            return AVERROR_INVALIDDATA;
        }

        block_data = c->sprites[sprite_id].data;
        if (!c->sprites[sprite_id].active) {
            /* this can happen when seeking around */
            av_log(avctx, AV_LOG_WARNING, "Sprite %d is missing.\n", sprite_id);
            continue;
        }
        if (c->sprites[sprite_id].size < 14) {
            av_log(avctx, AV_LOG_ERROR, "Sprite %d is too small.\n", sprite_id);
            continue;
        }

        height      = bytestream_get_be16(&block_data);
        width       = bytestream_get_be16(&block_data);
        block_data += 10;
        if (cdtoons_render_sprite(avctx, block_data,
                              c->sprites[sprite_id].size - 14,
                              left, top, width, height)) {
            av_log(avctx, AV_LOG_WARNING, "Ran beyond end of sprite while rendering.\n");
        }
    }

    if (palette_id && (palette_id != c->last_pal_id)) {
        if (palette_id >= CDTOONS_MAX_SPRITES) {
            av_log(avctx, AV_LOG_ERROR,
                   "Palette ID %d is too high.\n", palette_id);
            return AVERROR_INVALIDDATA;
        }
        if (!c->sprites[palette_id].active) {
            /* this can happen when seeking around */
            av_log(avctx, AV_LOG_WARNING,
                   "Palette ID %d is missing.\n", palette_id);
            goto done;
        }
        if (c->sprites[palette_id].size != 256 * 2 * 3) {
            av_log(avctx, AV_LOG_ERROR,
                   "Palette ID %d is wrong size (%d).\n",
                   palette_id, c->sprites[palette_id].size);
            return AVERROR_INVALIDDATA;
        }
        c->last_pal_id = palette_id;
        if (!palette_set) {
            uint8_t *palette_data = c->sprites[palette_id].data;
            for (int i = 0; i < 256; i++) {
                /* QuickTime-ish palette: 16-bit RGB components */
                unsigned r, g, b;
                r             = *palette_data;
                g             = *(palette_data + 2);
                b             = *(palette_data + 4);
                c->pal[i]     = (0xFFU << 24) | (r << 16) | (g << 8) | b;
                palette_data += 6;
            }
            /* first palette entry indicates transparency */
            c->pal[0]                     = 0;
            c->frame->palette_has_changed = 1;
        }
    }

done:
    /* discard outdated blocks */
    for (int i = 0; i < CDTOONS_MAX_SPRITES; i++) {
        if (c->sprites[i].end_frame > frame_id)
            continue;
        c->sprites[i].active = 0;
    }

    memcpy(c->frame->data[1], c->pal, AVPALETTE_SIZE);

    if ((ret = av_frame_ref(data, c->frame)) < 0)
        return ret;

    *got_frame = 1;

    /* always report that the buffer was completely consumed */
    return buf_size;
}

static av_cold int cdtoons_decode_init(AVCodecContext *avctx)
{
    CDToonsContext *c = avctx->priv_data;

    avctx->pix_fmt = AV_PIX_FMT_PAL8;
    c->last_pal_id = 0;
    c->frame       = av_frame_alloc();
    if (!c->frame)
        return AVERROR(ENOMEM);

    return 0;
}

static void cdtoons_flush(AVCodecContext *avctx)
{
    CDToonsContext *c = avctx->priv_data;

    c->last_pal_id = 0;
    for (int i = 0; i < CDTOONS_MAX_SPRITES; i++)
        c->sprites[i].active = 0;
}

static av_cold int cdtoons_decode_end(AVCodecContext *avctx)
{
    CDToonsContext *c = avctx->priv_data;

    for (int i = 0; i < CDTOONS_MAX_SPRITES; i++) {
        av_freep(&c->sprites[i].data);
        c->sprites[i].active = 0;
    }

    av_frame_free(&c->frame);

    return 0;
}

AVCodec ff_cdtoons_decoder = {
    .name           = "cdtoons",
    .long_name      = NULL_IF_CONFIG_SMALL("CDToons video"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_CDTOONS,
    .priv_data_size = sizeof(CDToonsContext),
    .init           = cdtoons_decode_init,
    .close          = cdtoons_decode_end,
    .decode         = cdtoons_decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
    .flush          = cdtoons_flush,
};
