/*
 * Copyright (c) 2021 Paul B Mahol
 *
 * 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/common.h"
#include "libavutil/mem.h"
#include "avcodec.h"
#include "get_bits.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"

#define PALDATA_FOLLOWS_TILEDATA 4
#define HAVE_COMPRESSED_TILEMAP 32
#define HAVE_TILEMAP 128

typedef struct SGAVideoContext {
    GetByteContext gb;

    int metadata_size;
    int tiledata_size;
    int tiledata_offset;
    int tilemapdata_size;
    int tilemapdata_offset;
    int paldata_size;
    int paldata_offset;
    int palmapdata_offset;
    int palmapdata_size;

    int flags;
    int nb_pal;
    int nb_tiles;
    int tiles_w, tiles_h;
    int shift;
    int plus;
    int swap;

    uint32_t pal[256];
    uint8_t *tileindex_data;
    unsigned tileindex_size;
    uint8_t *palmapindex_data;
    unsigned palmapindex_size;
    uint8_t uncompressed[65536];
} SGAVideoContext;

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

static int decode_palette(GetByteContext *gb, uint32_t *pal)
{
    GetBitContext gbit;

    if (bytestream2_get_bytes_left(gb) < 18)
        return AVERROR_INVALIDDATA;

    memset(pal, 0, 16 * sizeof(*pal));
    init_get_bits8(&gbit, gb->buffer, 18);

    for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
        for (int index = 0; index < 16; index++) {
            unsigned color = get_bits1(&gbit) << RGBIndex;
            pal[15 - index] |= color << (5 + 16);
        }
    }

    for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
        for (int index = 0; index < 16; index++) {
            unsigned color = get_bits1(&gbit) << RGBIndex;
            pal[15 - index] |= color << (5 + 8);
        }
    }

    for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
        for (int index = 0; index < 16; index++) {
            unsigned color = get_bits1(&gbit) << RGBIndex;
            pal[15 - index] |= color << (5 + 0);
        }
    }

    for (int index = 0; index < 16; index++)
        pal[index] = (0xFFU << 24) | pal[index] | (pal[index] >> 3);

    bytestream2_skip(gb, 18);

    return 0;
}

static int decode_index_palmap(SGAVideoContext *s, AVFrame *frame)
{
    const uint8_t *tt = s->tileindex_data;

    for (int y = 0; y < s->tiles_h; y++) {
        for (int x = 0; x < s->tiles_w; x++) {
            int pal_idx = s->palmapindex_data[y * s->tiles_w + x] * 16;
            uint8_t *dst = frame->data[0] + y * 8 * frame->linesize[0] + x * 8;

            for (int yy = 0; yy < 8; yy++) {
                for (int xx = 0; xx < 8; xx++)
                    dst[xx] = pal_idx + tt[xx];
                tt += 8;

                dst += frame->linesize[0];
            }
        }
    }

    return 0;
}

static int decode_index_tilemap(SGAVideoContext *s, AVFrame *frame)
{
    GetByteContext *gb = &s->gb, gb2;

    bytestream2_seek(gb, s->tilemapdata_offset, SEEK_SET);
    if (bytestream2_get_bytes_left(gb) < s->tilemapdata_size)
        return AVERROR_INVALIDDATA;

    gb2 = *gb;

    for (int y = 0; y < s->tiles_h; y++) {
        for (int x = 0; x < s->tiles_w; x++) {
            uint8_t tile[64];
            int tilemap = bytestream2_get_be16u(&gb2);
            int flip_x = (tilemap >> 11) & 1;
            int flip_y = (tilemap >> 12) & 1;
            int tindex = av_clip((tilemap & 511) - 1, 0, s->nb_tiles - 1);
            const uint8_t *tt = s->tileindex_data + tindex * 64;
            int pal_idx = ((tilemap >> 13) & 3) * 16;
            uint8_t *dst = frame->data[0] + y * 8 * frame->linesize[0] + x * 8;

            if (!flip_x && !flip_y) {
                memcpy(tile, tt, 64);
            } else if (flip_x && flip_y) {
                for (int i = 0; i < 8; i++) {
                    for (int j = 0; j < 8; j++)
                        tile[i * 8 + j] = tt[(7 - i) * 8 + 7 - j];
                }
            } else if (flip_x) {
                for (int i = 0; i < 8; i++) {
                    for (int j = 0; j < 8; j++)
                        tile[i * 8 + j] = tt[i * 8 + 7 - j];
                }
            } else {
                for (int i = 0; i < 8; i++) {
                    for (int j = 0; j < 8; j++)
                        tile[i * 8 + j] = tt[(7 - i) * 8 + j];
                }
            }

            for (int yy = 0; yy < 8; yy++) {
                for (int xx = 0; xx < 8; xx++)
                    dst[xx] = pal_idx + tile[xx + yy * 8];

                dst += frame->linesize[0];
            }
        }
    }

    return 0;
}

static int decode_index(SGAVideoContext *s, AVFrame *frame)
{
    const uint8_t *src = s->tileindex_data;
    uint8_t *dst = frame->data[0];

    for (int y = 0; y < frame->height; y += 8) {
        for (int x = 0; x < frame->width; x += 8) {
            for (int yy = 0; yy < 8; yy++) {
                for (int xx = 0; xx < 8; xx++)
                    dst[x + xx + yy * frame->linesize[0]] = src[xx];
                src += 8;
            }
        }

        dst += 8 * frame->linesize[0];
    }

    return 0;
}

static int lzss_decompress(AVCodecContext *avctx,
                           GetByteContext *gb, uint8_t *dst,
                           int dst_size, int shift, int plus)
{
    int oi = 0;

    while (bytestream2_get_bytes_left(gb) > 0 && oi < dst_size) {
        uint16_t displace, header = bytestream2_get_be16(gb);
        int count, offset;

        for (int i = 0; i < 16; i++) {
            switch (header >> 15) {
            case 0:
                if (oi + 2 < dst_size) {
                    dst[oi++] = bytestream2_get_byte(gb);
                    dst[oi++] = bytestream2_get_byte(gb);
                }
                break;
            case 1:
                displace = bytestream2_get_be16(gb);
                count = displace >> shift;
                offset = displace & ((1 << shift) - 1);

                if (displace == 0) {
                    while (bytestream2_get_bytes_left(gb) > 0 &&
                           oi < dst_size)
                        dst[oi++] = bytestream2_get_byte(gb);
                    return oi;
                }

                count += plus;

                if (offset <= 0)
                    offset = 1;
                if (oi < offset || oi + count * 2 > dst_size)
                    return AVERROR_INVALIDDATA;
                for (int j = 0; j < count * 2; j++) {
                    dst[oi] = dst[oi - offset];
                    oi++;
                }
                break;
            }

            header <<= 1;
        }
    }

    return AVERROR_INVALIDDATA;
}

static int decode_palmapdata(AVCodecContext *avctx)
{
    SGAVideoContext *s = avctx->priv_data;
    const int bits = (s->nb_pal + 1) / 2;
    GetByteContext *gb = &s->gb;
    GetBitContext pm;

    bytestream2_seek(gb, s->palmapdata_offset, SEEK_SET);
    if (bytestream2_get_bytes_left(gb) < s->palmapdata_size)
        return AVERROR_INVALIDDATA;
    init_get_bits8(&pm, gb->buffer, s->palmapdata_size);

    for (int y = 0; y < s->tiles_h; y++) {
        uint8_t *dst = s->palmapindex_data + y * s->tiles_w;

        for (int x = 0; x < s->tiles_w; x++)
            dst[x] = get_bits(&pm, bits);

        dst += s->tiles_w;
    }

    return 0;
}

static int decode_tiledata(AVCodecContext *avctx)
{
    SGAVideoContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    GetBitContext tm;

    bytestream2_seek(gb, s->tiledata_offset, SEEK_SET);
    if (bytestream2_get_bytes_left(gb) < s->tiledata_size)
        return AVERROR_INVALIDDATA;
    init_get_bits8(&tm, gb->buffer, s->tiledata_size);

    for (int n = 0; n < s->nb_tiles; n++) {
        uint8_t *dst = s->tileindex_data + n * 64;

        for (int yy = 0; yy < 8; yy++) {
            for (int xx = 0; xx < 8; xx++)
                dst[xx] = get_bits(&tm, 4);

            dst += 8;
        }
    }

    for (int i = 0; i < s->nb_tiles && s->swap; i++) {
        uint8_t *dst = s->tileindex_data + i * 64;

        for (int j = 8; j < 64; j += 16) {
            for (int k = 0; k < 8; k += 2)
                FFSWAP(uint8_t, dst[j + k], dst[j+k+1]);
        }
    }

    return 0;
}

static int sga_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                            int *got_frame, AVPacket *avpkt)
{
    SGAVideoContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    int ret, type;

    if (avpkt->size <= 14)
        return AVERROR_INVALIDDATA;

    s->flags  = avpkt->data[8];
    s->nb_pal = avpkt->data[9];
    s->tiles_w = avpkt->data[10];
    s->tiles_h = avpkt->data[11];

    if (s->nb_pal > 4)
        return AVERROR_INVALIDDATA;

    if ((ret = ff_set_dimensions(avctx,
                                 s->tiles_w * 8,
                                 s->tiles_h * 8)) < 0)
        return ret;

    av_fast_padded_malloc(&s->tileindex_data, &s->tileindex_size,
                          avctx->width * avctx->height);
    if (!s->tileindex_data)
        return AVERROR(ENOMEM);

    av_fast_padded_malloc(&s->palmapindex_data, &s->palmapindex_size,
                          s->tiles_w * s->tiles_h);
    if (!s->palmapindex_data)
        return AVERROR(ENOMEM);

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

    bytestream2_init(gb, avpkt->data, avpkt->size);

    type = bytestream2_get_byte(gb);
    s->metadata_size = 12 + ((!!(s->flags & HAVE_TILEMAP)) * 2);
    s->nb_tiles = s->flags & HAVE_TILEMAP ? AV_RB16(avpkt->data + 12) : s->tiles_w * s->tiles_h;
    if (s->nb_tiles > s->tiles_w * s->tiles_h)
        return AVERROR_INVALIDDATA;

    av_log(avctx, AV_LOG_DEBUG, "type: %X flags: %X nb_tiles: %d\n", type, s->flags, s->nb_tiles);

    switch (type) {
    case 0xE7:
    case 0xCB:
    case 0xCD:
        s->swap = 1;
        s->shift = 12;
        s->plus = 1;
        break;
    case 0xC9:
        s->swap = 1;
        s->shift = 13;
        s->plus = 1;
        break;
    case 0xC8:
        s->swap = 1;
        s->shift = 13;
        s->plus = 0;
        break;
    case 0xC7:
        s->swap = 0;
        s->shift = 13;
        s->plus = 1;
        break;
    case 0xC6:
        s->swap = 0;
        s->shift = 13;
        s->plus = 0;
        break;
    }

    if (type == 0xE7) {
        int offset = s->metadata_size, left;
        int sizes[3];

        bytestream2_seek(gb, s->metadata_size, SEEK_SET);

        for (int i = 0; i < 3; i++)
            sizes[i] = bytestream2_get_be16(gb);

        for (int i = 0; i < 3; i++) {
            int size = sizes[i];
            int raw = size >> 15;

            size &= (1 << 15) - 1;

            if (raw) {
                if (bytestream2_get_bytes_left(gb) < size)
                    return AVERROR_INVALIDDATA;

                if (sizeof(s->uncompressed) - offset < size)
                    return AVERROR_INVALIDDATA;

                memcpy(s->uncompressed + offset, gb->buffer, size);
                bytestream2_skip(gb, size);
            } else {
                GetByteContext gb2;

                if (bytestream2_get_bytes_left(gb) < size)
                    return AVERROR_INVALIDDATA;

                bytestream2_init(&gb2, gb->buffer, size);
                ret = lzss_decompress(avctx, &gb2, s->uncompressed + offset,
                                      sizeof(s->uncompressed) - offset, s->shift, s->plus);
                if (ret < 0)
                    return ret;
                bytestream2_skip(gb, size);
                size = ret;
            }

            offset += size;
        }

        left = bytestream2_get_bytes_left(gb);
        if (sizeof(s->uncompressed) - offset < left)
            return AVERROR_INVALIDDATA;

        bytestream2_get_buffer(gb, s->uncompressed + offset, left);

        offset += left;
        bytestream2_init(gb, s->uncompressed, offset);
    }

    switch (type) {
    case 0xCD:
    case 0xCB:
    case 0xC9:
    case 0xC8:
    case 0xC7:
    case 0xC6:
        bytestream2_seek(gb, s->metadata_size, SEEK_SET);
        ret = lzss_decompress(avctx, gb, s->uncompressed + s->metadata_size,
                              sizeof(s->uncompressed) - s->metadata_size, s->shift, s->plus);
        if (ret < 0)
            return ret;
        bytestream2_init(gb, s->uncompressed, ret + s->metadata_size);
    case 0xE7:
    case 0xC1:
        s->tiledata_size = s->nb_tiles * 32;
        s->paldata_size = s->nb_pal * 18;
        s->tiledata_offset = s->flags & PALDATA_FOLLOWS_TILEDATA ? s->metadata_size : s->metadata_size + s->paldata_size;
        s->paldata_offset = s->flags & PALDATA_FOLLOWS_TILEDATA ? s->metadata_size + s->tiledata_size : s->metadata_size;
        s->palmapdata_offset = (s->flags & HAVE_TILEMAP) ? -1 : s->paldata_offset + s->paldata_size;
        s->palmapdata_size = (s->flags & HAVE_TILEMAP) || s->nb_pal < 2 ? 0 : (s->tiles_w * s->tiles_h * ((s->nb_pal + 1) / 2) + 7) / 8;
        s->tilemapdata_size = (s->flags & HAVE_TILEMAP) ? s->tiles_w * s->tiles_h * 2 : 0;
        s->tilemapdata_offset = (s->flags & HAVE_TILEMAP) ? s->paldata_offset + s->paldata_size: -1;

        bytestream2_seek(gb, s->paldata_offset, SEEK_SET);
        for (int n = 0; n < s->nb_pal; n++) {
            ret = decode_palette(gb, s->pal + 16 * n);
            if (ret < 0)
                return ret;
        }

        if (s->tiledata_size > 0) {
            ret = decode_tiledata(avctx);
            if (ret < 0)
                return ret;
        }

        if (s->palmapdata_size > 0) {
            ret = decode_palmapdata(avctx);
            if (ret < 0)
                return ret;
        }

        if (s->palmapdata_size > 0 && s->tiledata_size > 0) {
            ret = decode_index_palmap(s, frame);
            if (ret < 0)
                return ret;
        } else if (s->tilemapdata_size > 0 && s->tiledata_size > 0) {
            ret = decode_index_tilemap(s, frame);
            if (ret < 0)
                return ret;
        } else if (s->tiledata_size > 0) {
            ret = decode_index(s, frame);
            if (ret < 0)
                return ret;
        }
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown type: %X\n", type);
        return AVERROR_INVALIDDATA;
    }

    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
#if FF_API_PALETTE_HAS_CHANGED
FF_DISABLE_DEPRECATION_WARNINGS
    frame->palette_has_changed = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    frame->pict_type = AV_PICTURE_TYPE_I;
    frame->flags |= AV_FRAME_FLAG_KEY;

    *got_frame = 1;

    return avpkt->size;
}

static av_cold int sga_decode_end(AVCodecContext *avctx)
{
    SGAVideoContext *s = avctx->priv_data;

    av_freep(&s->tileindex_data);
    s->tileindex_size = 0;

    av_freep(&s->palmapindex_data);
    s->palmapindex_size = 0;

    return 0;
}

const FFCodec ff_sga_decoder = {
    .p.name         = "sga",
    CODEC_LONG_NAME("Digital Pictures SGA Video"),
    .p.type         = AVMEDIA_TYPE_VIDEO,
    .p.id           = AV_CODEC_ID_SGA_VIDEO,
    .priv_data_size = sizeof(SGAVideoContext),
    .init           = sga_decode_init,
    FF_CODEC_DECODE_CB(sga_decode_frame),
    .close          = sga_decode_end,
    .p.capabilities = AV_CODEC_CAP_DR1,
};
