/*
 * BRender PIX (.pix) image decoder
 * Copyright (c) 2012 Aleksi Nurmi
 *
 * 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
 */

/*
 * Tested against samples from I-War / Independence War and Defiance.
 * If the PIX file does not contain a palette, the
 * palette_has_changed property of the AVFrame is set to 0.
 */

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

typedef struct BRPixHeader {
    int format;
    unsigned int width, height;
} BRPixHeader;

static int brpix_decode_header(BRPixHeader *out, GetByteContext *pgb)
{
    unsigned int header_len = bytestream2_get_be32(pgb);

    out->format = bytestream2_get_byte(pgb);
    bytestream2_skip(pgb, 2);
    out->width = bytestream2_get_be16(pgb);
    out->height = bytestream2_get_be16(pgb);

    // the header is at least 11 bytes long; we read the first 7
    if (header_len < 11) {
        return 0;
    }

    // skip the rest of the header
    bytestream2_skip(pgb, header_len-7);

    return 1;
}

static int brpix_decode_frame(AVCodecContext *avctx,
                              void *data, int *got_frame,
                              AVPacket *avpkt)
{
    AVFrame *frame = data;

    int ret;
    GetByteContext gb;

    unsigned int bytes_pp;

    unsigned int magic[4];
    unsigned int chunk_type;
    unsigned int data_len;
    BRPixHeader hdr;

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

    magic[0] = bytestream2_get_be32(&gb);
    magic[1] = bytestream2_get_be32(&gb);
    magic[2] = bytestream2_get_be32(&gb);
    magic[3] = bytestream2_get_be32(&gb);

    if (magic[0] != 0x12 ||
        magic[1] != 0x8 ||
        magic[2] != 0x2 ||
        magic[3] != 0x2) {
        av_log(avctx, AV_LOG_ERROR, "Not a BRender PIX file\n");
        return AVERROR_INVALIDDATA;
    }

    chunk_type = bytestream2_get_be32(&gb);
    if (chunk_type != 0x3 && chunk_type != 0x3d) {
        av_log(avctx, AV_LOG_ERROR, "Invalid chunk type %d\n", chunk_type);
        return AVERROR_INVALIDDATA;
    }

    ret = brpix_decode_header(&hdr, &gb);
    if (!ret) {
        av_log(avctx, AV_LOG_ERROR, "Invalid header length\n");
        return AVERROR_INVALIDDATA;
    }
    switch (hdr.format) {
    case 3:
        avctx->pix_fmt = AV_PIX_FMT_PAL8;
        bytes_pp = 1;
        break;
    case 4:
        avctx->pix_fmt = AV_PIX_FMT_RGB555BE;
        bytes_pp = 2;
        break;
    case 5:
        avctx->pix_fmt = AV_PIX_FMT_RGB565BE;
        bytes_pp = 2;
        break;
    case 6:
        avctx->pix_fmt = AV_PIX_FMT_RGB24;
        bytes_pp = 3;
        break;
    case 7:
        avctx->pix_fmt = AV_PIX_FMT_0RGB;
        bytes_pp = 4;
        break;
    case 18:
        avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
        bytes_pp = 2;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Format %d is not supported\n",
                                    hdr.format);
        return AVERROR_PATCHWELCOME;
    }

    if ((ret = ff_set_dimensions(avctx, hdr.width, hdr.height)) < 0)
        return ret;

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

    chunk_type = bytestream2_get_be32(&gb);

    if (avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
        (chunk_type == 0x3 || chunk_type == 0x3d)) {
        BRPixHeader palhdr;
        uint32_t *pal_out = (uint32_t *)frame->data[1];
        int i;

        ret = brpix_decode_header(&palhdr, &gb);
        if (!ret) {
            av_log(avctx, AV_LOG_ERROR, "Invalid palette header length\n");
            return AVERROR_INVALIDDATA;
        }
        if (palhdr.format != 7) {
            av_log(avctx, AV_LOG_ERROR, "Palette is not in 0RGB format\n");
            return AVERROR_INVALIDDATA;
        }

        chunk_type = bytestream2_get_be32(&gb);
        data_len = bytestream2_get_be32(&gb);
        bytestream2_skip(&gb, 8);
        if (chunk_type != 0x21 || data_len != 1032 ||
            bytestream2_get_bytes_left(&gb) < 1032) {
            av_log(avctx, AV_LOG_ERROR, "Invalid palette data\n");
            return AVERROR_INVALIDDATA;
        }
        // convert 0RGB to machine endian format (ARGB32)
        for (i = 0; i < 256; ++i) {
            bytestream2_skipu(&gb, 1);
            *pal_out++ = (0xFFU << 24) | bytestream2_get_be24u(&gb);
        }
        bytestream2_skip(&gb, 8);

        frame->palette_has_changed = 1;

        chunk_type = bytestream2_get_be32(&gb);
    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
        uint32_t *pal_out = (uint32_t *)frame->data[1];
        int i;

        for (i = 0; i < 256; ++i) {
            *pal_out++ = (0xFFU << 24) | (i * 0x010101);
        }
        frame->palette_has_changed = 1;
    }

    data_len = bytestream2_get_be32(&gb);
    bytestream2_skip(&gb, 8);

    // read the image data to the buffer
    {
        unsigned int bytes_per_scanline = bytes_pp * hdr.width;
        unsigned int bytes_left = bytestream2_get_bytes_left(&gb);

        if (chunk_type != 0x21 || data_len != bytes_left ||
            bytes_left / bytes_per_scanline < hdr.height)
        {
            av_log(avctx, AV_LOG_ERROR, "Invalid image data\n");
            return AVERROR_INVALIDDATA;
        }

        av_image_copy_plane(frame->data[0], frame->linesize[0],
                            avpkt->data + bytestream2_tell(&gb),
                            bytes_per_scanline,
                            bytes_per_scanline, hdr.height);
    }

    *got_frame = 1;

    return avpkt->size;
}

AVCodec ff_brender_pix_decoder = {
    .name           = "brender_pix",
    .long_name      = NULL_IF_CONFIG_SMALL("BRender PIX image"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_BRENDER_PIX,
    .decode         = brpix_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
};
