/*
 * QuickDraw (qdrw) codec
 * Copyright (c) 2004 Konstantin Shishkov
 * Copyright (c) 2015 Vittorio Giovara
 *
 * 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
 * Apple QuickDraw codec.
 * https://developer.apple.com/legacy/library/documentation/mac/QuickDraw/QuickDraw-461.html
 */

#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"

enum QuickdrawOpcodes {
    CLIP = 0x0001,
    PACKBITSRECT = 0x0098,
    PACKBITSRGN,
    DIRECTBITSRECT,
    DIRECTBITSRGN,
    SHORTCOMMENT = 0x00A0,
    LONGCOMMENT,

    EOP = 0x00FF,
};

static int parse_palette(AVCodecContext *avctx, GetByteContext *gbc,
                         uint32_t *pal, int colors, int pixmap)
{
    int i;

    for (i = 0; i <= colors; i++) {
        uint8_t r, g, b;
        unsigned int idx = bytestream2_get_be16(gbc); /* color index */
        if (idx > 255 && !pixmap) {
            av_log(avctx, AV_LOG_WARNING,
                   "Palette index out of range: %u\n", idx);
            bytestream2_skip(gbc, 6);
            continue;
        }
        if (avctx->pix_fmt != AV_PIX_FMT_PAL8)
            return AVERROR_INVALIDDATA;
        r = bytestream2_get_byte(gbc);
        bytestream2_skip(gbc, 1);
        g = bytestream2_get_byte(gbc);
        bytestream2_skip(gbc, 1);
        b = bytestream2_get_byte(gbc);
        bytestream2_skip(gbc, 1);
        pal[pixmap ? i : idx] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
    }
    return 0;
}

static int decode_rle_bpp2(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
{
    int offset = avctx->width;
    uint8_t *outdata = p->data[0];
    int i, j;

    for (i = 0; i < avctx->height; i++) {
        int size, left, code, pix;
        uint8_t *out = outdata;
        int pos = 0;

        /* size of packed line */
        if (offset / 4 > 200)
            size = left = bytestream2_get_be16(gbc);
        else
            size = left = bytestream2_get_byte(gbc);
        if (bytestream2_get_bytes_left(gbc) < size)
            return AVERROR_INVALIDDATA;

        /* decode line */
        while (left > 0) {
            code = bytestream2_get_byte(gbc);
            if (code & 0x80 ) { /* run */
                pix = bytestream2_get_byte(gbc);
                for (j = 0; j < 257 - code; j++) {
                    if (pos < offset)
                        out[pos++] = (pix & 0xC0) >> 6;
                    if (pos < offset)
                        out[pos++] = (pix & 0x30) >> 4;
                    if (pos < offset)
                        out[pos++] = (pix & 0x0C) >> 2;
                    if (pos < offset)
                        out[pos++] = (pix & 0x03);
                }
                left  -= 2;
            } else { /* copy */
                for (j = 0; j < code + 1; j++) {
                    pix = bytestream2_get_byte(gbc);
                    if (pos < offset)
                        out[pos++] = (pix & 0xC0) >> 6;
                    if (pos < offset)
                        out[pos++] = (pix & 0x30) >> 4;
                    if (pos < offset)
                        out[pos++] = (pix & 0x0C) >> 2;
                    if (pos < offset)
                        out[pos++] = (pix & 0x03);
                }
                left  -= 1 + (code + 1);
            }
        }
        outdata += p->linesize[0];
    }
    return 0;
}

static int decode_rle_bpp4(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
{
    int offset = avctx->width;
    uint8_t *outdata = p->data[0];
    int i, j;

    for (i = 0; i < avctx->height; i++) {
        int size, left, code, pix;
        uint8_t *out = outdata;
        int pos = 0;

        /* size of packed line */
        size = left = bytestream2_get_be16(gbc);
        if (bytestream2_get_bytes_left(gbc) < size)
            return AVERROR_INVALIDDATA;

        /* decode line */
        while (left > 0) {
            code = bytestream2_get_byte(gbc);
            if (code & 0x80 ) { /* run */
                pix = bytestream2_get_byte(gbc);
                for (j = 0; j < 257 - code; j++) {
                    if (pos < offset)
                        out[pos++] = (pix & 0xF0) >> 4;
                    if (pos < offset)
                        out[pos++] = pix & 0xF;
                }
                left  -= 2;
            } else { /* copy */
                for (j = 0; j < code + 1; j++) {
                    pix = bytestream2_get_byte(gbc);
                    if (pos < offset)
                        out[pos++] = (pix & 0xF0) >> 4;
                    if (pos < offset)
                        out[pos++] = pix & 0xF;
                }
                left  -= 1 + (code + 1);
            }
        }
        outdata += p->linesize[0];
    }
    return 0;
}

static int decode_rle16(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
{
    int offset = avctx->width;
    uint8_t *outdata = p->data[0];
    int i, j;

    for (i = 0; i < avctx->height; i++) {
        int size, left, code, pix;
        uint16_t *out = (uint16_t *)outdata;
        int pos = 0;

        /* size of packed line */
        size = left = bytestream2_get_be16(gbc);
        if (bytestream2_get_bytes_left(gbc) < size)
            return AVERROR_INVALIDDATA;

        /* decode line */
        while (left > 0) {
            code = bytestream2_get_byte(gbc);
            if (code & 0x80 ) { /* run */
                pix = bytestream2_get_be16(gbc);
                for (j = 0; j < 257 - code; j++) {
                    if (pos < offset) {
                        out[pos++] = pix;
                    }
                }
                left  -= 3;
            } else { /* copy */
                for (j = 0; j < code + 1; j++) {
                    if (pos < offset) {
                        out[pos++] = bytestream2_get_be16(gbc);
                    } else {
                        bytestream2_skip(gbc, 2);
                    }
                }
                left  -= 1 + (code + 1) * 2;
            }
        }
        outdata += p->linesize[0];
    }
    return 0;
}

static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc,
                      int step)
{
    int i, j;
    int offset = avctx->width * step;
    uint8_t *outdata = p->data[0];

    for (i = 0; i < avctx->height; i++) {
        int size, left, code, pix;
        uint8_t *out = outdata;
        int pos = 0;

        /* size of packed line */
        size = left = bytestream2_get_be16(gbc);
        if (bytestream2_get_bytes_left(gbc) < size)
            return AVERROR_INVALIDDATA;

        /* decode line */
        while (left > 0) {
            code = bytestream2_get_byte(gbc);
            if (code & 0x80 ) { /* run */
                pix = bytestream2_get_byte(gbc);
                for (j = 0; j < 257 - code; j++) {
                    if (pos < offset)
                        out[pos] = pix;
                    pos += step;
                    if (pos >= offset && step > 1) {
                        pos -= offset;
                        pos++;
                    }
                }
                left  -= 2;
            } else { /* copy */
                for (j = 0; j < code + 1; j++) {
                    pix = bytestream2_get_byte(gbc);
                    if (pos < offset)
                        out[pos] = pix;
                    pos += step;
                    if (pos >= offset && step > 1) {
                        pos -= offset;
                        pos++;
                    }
                }
                left  -= 2 + code;
            }
        }
        outdata += p->linesize[0];
    }
    return 0;
}

static int check_header(const char *buf, int buf_size)
{
    unsigned w, h, v0, v1;

    if (buf_size < 40)
        return 0;

    w = AV_RB16(buf+6);
    h = AV_RB16(buf+8);
    v0 = AV_RB16(buf+10);
    v1 = AV_RB16(buf+12);

    if (!w || !h)
        return 0;

    if (v0 == 0x1101)
        return 1;
    if (v0 == 0x0011 && v1 == 0x02FF)
        return 2;
    return 0;
}


static int decode_frame(AVCodecContext *avctx, AVFrame *p,
                        int *got_frame, AVPacket *avpkt)
{
    GetByteContext gbc;
    int colors;
    int w, h, ret;
    int ver;

    bytestream2_init(&gbc, avpkt->data, avpkt->size);
    if (   bytestream2_get_bytes_left(&gbc) >= 552
           &&  check_header(gbc.buffer + 512, bytestream2_get_bytes_left(&gbc) - 512)
       )
        bytestream2_skip(&gbc, 512);

    ver = check_header(gbc.buffer, bytestream2_get_bytes_left(&gbc));

    /* smallest PICT header */
    if (bytestream2_get_bytes_left(&gbc) < 40) {
        av_log(avctx, AV_LOG_ERROR, "Frame is too small %d\n",
               bytestream2_get_bytes_left(&gbc));
        return AVERROR_INVALIDDATA;
    }

    bytestream2_skip(&gbc, 6);
    h = bytestream2_get_be16(&gbc);
    w = bytestream2_get_be16(&gbc);

    ret = ff_set_dimensions(avctx, w, h);
    if (ret < 0)
        return ret;

    /* version 1 is identified by 0x1101
     * it uses byte-aligned opcodes rather than word-aligned */
    if (ver == 1) {
        avpriv_request_sample(avctx, "QuickDraw version 1");
        return AVERROR_PATCHWELCOME;
    } else if (ver != 2) {
        avpriv_request_sample(avctx, "QuickDraw version unknown (%X)", bytestream2_get_be32(&gbc));
        return AVERROR_PATCHWELCOME;
    }

    bytestream2_skip(&gbc, 4+26);

    while (bytestream2_get_bytes_left(&gbc) >= 4) {
        int bppcnt, bpp;
        int rowbytes, pack_type;
        int flags;
        int opcode = bytestream2_get_be16(&gbc);

        switch(opcode) {
        case CLIP:
            bytestream2_skip(&gbc, 10);
            break;
        case PACKBITSRECT:
        case PACKBITSRGN:
            av_log(avctx, AV_LOG_DEBUG, "Parsing Packbit opcode\n");

            flags = bytestream2_get_be16(&gbc) & 0xC000;
            bytestream2_skip(&gbc, 28);
            bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
            bpp    = bytestream2_get_be16(&gbc); /* cmpSize */

            av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
            if (bppcnt == 1 && bpp == 8) {
                avctx->pix_fmt = AV_PIX_FMT_PAL8;
            } else if (bppcnt == 1 && (bpp == 4 || bpp == 2)) {
                avctx->pix_fmt = AV_PIX_FMT_PAL8;
            } else if (bppcnt == 3 && bpp == 5) {
                avctx->pix_fmt = AV_PIX_FMT_RGB555;
            } else {
                av_log(avctx, AV_LOG_ERROR,
                       "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n",
                       bppcnt, bpp);
                return AVERROR_INVALIDDATA;
            }

            /* jump to palette */
            bytestream2_skip(&gbc, 18);
            colors = bytestream2_get_be16(&gbc);

            if (colors < 0 || colors > 255) {
                av_log(avctx, AV_LOG_ERROR,
                       "Error color count - %i(0x%X)\n", colors, colors);
                return AVERROR_INVALIDDATA;
            }
            if (bytestream2_get_bytes_left(&gbc) < (colors + 1) * 8) {
                av_log(avctx, AV_LOG_ERROR, "Palette is too small %d\n",
                       bytestream2_get_bytes_left(&gbc));
                return AVERROR_INVALIDDATA;
            }
            if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
                return ret;

            ret = parse_palette(avctx, &gbc, (uint32_t *)p->data[1], colors, flags & 0x8000);
            if (ret < 0)
                return ret;
#if FF_API_PALETTE_HAS_CHANGED
FF_DISABLE_DEPRECATION_WARNINGS
            p->palette_has_changed = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

            /* jump to image data */
            bytestream2_skip(&gbc, 18);

            if (opcode == PACKBITSRGN) {
                bytestream2_skip(&gbc, 2 + 8); /* size + rect */
                avpriv_report_missing_feature(avctx, "Packbit mask region");
            }

            if (avctx->pix_fmt == AV_PIX_FMT_RGB555)
                ret = decode_rle16(avctx, p, &gbc);
            else if (bpp == 2)
                ret = decode_rle_bpp2(avctx, p, &gbc);
            else if (bpp == 4)
                ret = decode_rle_bpp4(avctx, p, &gbc);
            else
                ret = decode_rle(avctx, p, &gbc, bppcnt);
            if (ret < 0)
                return ret;
            *got_frame = 1;
            break;
        case DIRECTBITSRECT:
        case DIRECTBITSRGN:
            av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n");

            bytestream2_skip(&gbc, 4);
            rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF;
            if (rowbytes <= 250) {
                avpriv_report_missing_feature(avctx, "Short rowbytes");
                return AVERROR_PATCHWELCOME;
            }

            bytestream2_skip(&gbc, 4);
            h = bytestream2_get_be16(&gbc);
            w = bytestream2_get_be16(&gbc);
            bytestream2_skip(&gbc, 2);

            ret = ff_set_dimensions(avctx, w, h);
            if (ret < 0)
                return ret;

            pack_type = bytestream2_get_be16(&gbc);

            bytestream2_skip(&gbc, 16);
            bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
            bpp    = bytestream2_get_be16(&gbc); /* cmpSize */

            av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
            if (bppcnt == 3 && bpp == 8) {
                avctx->pix_fmt = AV_PIX_FMT_RGB24;
            } else if (bppcnt == 3 && bpp == 5 || bppcnt == 2 && bpp == 8) {
                avctx->pix_fmt = AV_PIX_FMT_RGB555;
            } else if (bppcnt == 4 && bpp == 8) {
                avctx->pix_fmt = AV_PIX_FMT_ARGB;
            } else {
                av_log(avctx, AV_LOG_ERROR,
                       "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n",
                       bppcnt, bpp);
                return AVERROR_INVALIDDATA;
            }

            /* set packing when default is selected */
            if (pack_type == 0)
                pack_type = bppcnt;

            if (pack_type != 3 && pack_type != 4) {
                avpriv_request_sample(avctx, "Pack type %d", pack_type);
                return AVERROR_PATCHWELCOME;
            }
            if (bytestream2_get_bytes_left(&gbc) < 30)
                return AVERROR_INVALIDDATA;
            if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
                return ret;

            /* jump to data */
            bytestream2_skip(&gbc, 30);

            if (opcode == DIRECTBITSRGN) {
                bytestream2_skip(&gbc, 2 + 8); /* size + rect */
                avpriv_report_missing_feature(avctx, "DirectBit mask region");
            }

            if (avctx->pix_fmt == AV_PIX_FMT_RGB555)
                ret = decode_rle16(avctx, p, &gbc);
            else
                ret = decode_rle(avctx, p, &gbc, bppcnt);
            if (ret < 0)
                return ret;
            *got_frame = 1;
            break;
        case LONGCOMMENT:
            bytestream2_get_be16(&gbc);
            bytestream2_skip(&gbc, bytestream2_get_be16(&gbc));
            break;
        default:
            av_log(avctx, AV_LOG_TRACE, "Unknown 0x%04X opcode\n", opcode);
            break;
        }
        /* exit the loop when a known pixel block has been found */
        if (*got_frame) {
            int eop, trail;

            /* re-align to a word */
            bytestream2_skip(&gbc, bytestream2_get_bytes_left(&gbc) % 2);

            eop = bytestream2_get_be16(&gbc);
            trail = bytestream2_get_bytes_left(&gbc);
            if (eop != EOP)
                av_log(avctx, AV_LOG_WARNING,
                       "Missing end of picture opcode (found 0x%04X)\n", eop);
            if (trail)
                av_log(avctx, AV_LOG_WARNING, "Got %d trailing bytes\n", trail);
            break;
        }
    }

    if (*got_frame) {
        return avpkt->size;
    } else {
        av_log(avctx, AV_LOG_ERROR, "Frame contained no usable data\n");

        return AVERROR_INVALIDDATA;
    }
}

const FFCodec ff_qdraw_decoder = {
    .p.name         = "qdraw",
    CODEC_LONG_NAME("Apple QuickDraw"),
    .p.type         = AVMEDIA_TYPE_VIDEO,
    .p.id           = AV_CODEC_ID_QDRAW,
    .p.capabilities = AV_CODEC_CAP_DR1,
    FF_CODEC_DECODE_CB(decode_frame),
};
