/*
 * 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;

    if (sprite_offset > buf_size)
        return AVERROR_INVALIDDATA;

    /* 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,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
};
