/*
 * Cinepak Video Decoder
 * Copyright (C) 2003 the ffmpeg project
 *
 * 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 libavcodec/cinepak.c
 * Cinepak video decoder
 * by Ewald Snel <ewald@rambo.its.tudelft.nl>
 * For more information on the Cinepak algorithm, visit:
 *   http://www.csse.monash.edu.au/~timf/
 * For more information on the quirky data inside Sega FILM/CPK files, visit:
 *   http://wiki.multimedia.cx/index.php?title=Sega_FILM
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "libavutil/intreadwrite.h"
#include "avcodec.h"


typedef struct {
    uint8_t  y0, y1, y2, y3;
    uint8_t  u, v;
} cvid_codebook;

#define MAX_STRIPS      32

typedef struct {
    uint16_t          id;
    uint16_t          x1, y1;
    uint16_t          x2, y2;
    cvid_codebook     v4_codebook[256];
    cvid_codebook     v1_codebook[256];
} cvid_strip;

typedef struct CinepakContext {

    AVCodecContext *avctx;
    AVFrame frame;

    const unsigned char *data;
    int size;

    int width, height;

    int palette_video;
    cvid_strip strips[MAX_STRIPS];

    int sega_film_skip_bytes;

} CinepakContext;

static void cinepak_decode_codebook (cvid_codebook *codebook,
                                     int chunk_id, int size, const uint8_t *data)
{
    const uint8_t *eod = (data + size);
    uint32_t flag, mask;
    int      i, n;

    /* check if this chunk contains 4- or 6-element vectors */
    n    = (chunk_id & 0x04) ? 4 : 6;
    flag = 0;
    mask = 0;

    for (i=0; i < 256; i++) {
        if ((chunk_id & 0x01) && !(mask >>= 1)) {
            if ((data + 4) > eod)
                break;

            flag  = AV_RB32 (data);
            data += 4;
            mask  = 0x80000000;
        }

        if (!(chunk_id & 0x01) || (flag & mask)) {
            if ((data + n) > eod)
                break;

            if (n == 6) {
                codebook[i].y0 = *data++;
                codebook[i].y1 = *data++;
                codebook[i].y2 = *data++;
                codebook[i].y3 = *data++;
                codebook[i].u  = 128 + *data++;
                codebook[i].v  = 128 + *data++;
            } else {
                /* this codebook type indicates either greyscale or
                 * palettized video; if palettized, U & V components will
                 * not be used so it is safe to set them to 128 for the
                 * benefit of greyscale rendering in YUV420P */
                codebook[i].y0 = *data++;
                codebook[i].y1 = *data++;
                codebook[i].y2 = *data++;
                codebook[i].y3 = *data++;
                codebook[i].u  = 128;
                codebook[i].v  = 128;
            }
        }
    }
}

static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
                                   int chunk_id, int size, const uint8_t *data)
{
    const uint8_t   *eod = (data + size);
    uint32_t         flag, mask;
    cvid_codebook   *codebook;
    unsigned int     x, y;
    uint32_t         iy[4];
    uint32_t         iu[2];
    uint32_t         iv[2];

    flag = 0;
    mask = 0;

    for (y=strip->y1; y < strip->y2; y+=4) {

        iy[0] = strip->x1 + (y * s->frame.linesize[0]);
        iy[1] = iy[0] + s->frame.linesize[0];
        iy[2] = iy[1] + s->frame.linesize[0];
        iy[3] = iy[2] + s->frame.linesize[0];
        iu[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[1]);
        iu[1] = iu[0] + s->frame.linesize[1];
        iv[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[2]);
        iv[1] = iv[0] + s->frame.linesize[2];

        for (x=strip->x1; x < strip->x2; x+=4) {
            if ((chunk_id & 0x01) && !(mask >>= 1)) {
                if ((data + 4) > eod)
                    return -1;

                flag  = AV_RB32 (data);
                data += 4;
                mask  = 0x80000000;
            }

            if (!(chunk_id & 0x01) || (flag & mask)) {
                if (!(chunk_id & 0x02) && !(mask >>= 1)) {
                    if ((data + 4) > eod)
                        return -1;

                    flag  = AV_RB32 (data);
                    data += 4;
                    mask  = 0x80000000;
                }

                if ((chunk_id & 0x02) || (~flag & mask)) {
                    if (data >= eod)
                        return -1;

                    codebook = &strip->v1_codebook[*data++];
                    s->frame.data[0][iy[0] + 0] = codebook->y0;
                    s->frame.data[0][iy[0] + 1] = codebook->y0;
                    s->frame.data[0][iy[1] + 0] = codebook->y0;
                    s->frame.data[0][iy[1] + 1] = codebook->y0;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[0]] = codebook->u;
                        s->frame.data[2][iv[0]] = codebook->v;
                    }

                    s->frame.data[0][iy[0] + 2] = codebook->y1;
                    s->frame.data[0][iy[0] + 3] = codebook->y1;
                    s->frame.data[0][iy[1] + 2] = codebook->y1;
                    s->frame.data[0][iy[1] + 3] = codebook->y1;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[0] + 1] = codebook->u;
                        s->frame.data[2][iv[0] + 1] = codebook->v;
                    }

                    s->frame.data[0][iy[2] + 0] = codebook->y2;
                    s->frame.data[0][iy[2] + 1] = codebook->y2;
                    s->frame.data[0][iy[3] + 0] = codebook->y2;
                    s->frame.data[0][iy[3] + 1] = codebook->y2;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[1]] = codebook->u;
                        s->frame.data[2][iv[1]] = codebook->v;
                    }

                    s->frame.data[0][iy[2] + 2] = codebook->y3;
                    s->frame.data[0][iy[2] + 3] = codebook->y3;
                    s->frame.data[0][iy[3] + 2] = codebook->y3;
                    s->frame.data[0][iy[3] + 3] = codebook->y3;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[1] + 1] = codebook->u;
                        s->frame.data[2][iv[1] + 1] = codebook->v;
                    }

                } else if (flag & mask) {
                    if ((data + 4) > eod)
                        return -1;

                    codebook = &strip->v4_codebook[*data++];
                    s->frame.data[0][iy[0] + 0] = codebook->y0;
                    s->frame.data[0][iy[0] + 1] = codebook->y1;
                    s->frame.data[0][iy[1] + 0] = codebook->y2;
                    s->frame.data[0][iy[1] + 1] = codebook->y3;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[0]] = codebook->u;
                        s->frame.data[2][iv[0]] = codebook->v;
                    }

                    codebook = &strip->v4_codebook[*data++];
                    s->frame.data[0][iy[0] + 2] = codebook->y0;
                    s->frame.data[0][iy[0] + 3] = codebook->y1;
                    s->frame.data[0][iy[1] + 2] = codebook->y2;
                    s->frame.data[0][iy[1] + 3] = codebook->y3;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[0] + 1] = codebook->u;
                        s->frame.data[2][iv[0] + 1] = codebook->v;
                    }

                    codebook = &strip->v4_codebook[*data++];
                    s->frame.data[0][iy[2] + 0] = codebook->y0;
                    s->frame.data[0][iy[2] + 1] = codebook->y1;
                    s->frame.data[0][iy[3] + 0] = codebook->y2;
                    s->frame.data[0][iy[3] + 1] = codebook->y3;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[1]] = codebook->u;
                        s->frame.data[2][iv[1]] = codebook->v;
                    }

                    codebook = &strip->v4_codebook[*data++];
                    s->frame.data[0][iy[2] + 2] = codebook->y0;
                    s->frame.data[0][iy[2] + 3] = codebook->y1;
                    s->frame.data[0][iy[3] + 2] = codebook->y2;
                    s->frame.data[0][iy[3] + 3] = codebook->y3;
                    if (!s->palette_video) {
                        s->frame.data[1][iu[1] + 1] = codebook->u;
                        s->frame.data[2][iv[1] + 1] = codebook->v;
                    }

                }
            }

            iy[0] += 4;  iy[1] += 4;
            iy[2] += 4;  iy[3] += 4;
            iu[0] += 2;  iu[1] += 2;
            iv[0] += 2;  iv[1] += 2;
        }
    }

    return 0;
}

static int cinepak_decode_strip (CinepakContext *s,
                                 cvid_strip *strip, const uint8_t *data, int size)
{
    const uint8_t *eod = (data + size);
    int      chunk_id, chunk_size;

    /* coordinate sanity checks */
    if (strip->x1 >= s->width  || strip->x2 > s->width  ||
        strip->y1 >= s->height || strip->y2 > s->height ||
        strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
        return -1;

    while ((data + 4) <= eod) {
        chunk_id   = data[0];
        chunk_size = AV_RB24 (&data[1]) - 4;
        if(chunk_size < 0)
            return -1;

        data      += 4;
        chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;

        switch (chunk_id) {

        case 0x20:
        case 0x21:
        case 0x24:
        case 0x25:
            cinepak_decode_codebook (strip->v4_codebook, chunk_id,
                chunk_size, data);
            break;

        case 0x22:
        case 0x23:
        case 0x26:
        case 0x27:
            cinepak_decode_codebook (strip->v1_codebook, chunk_id,
                chunk_size, data);
            break;

        case 0x30:
        case 0x31:
        case 0x32:
            return cinepak_decode_vectors (s, strip, chunk_id,
                chunk_size, data);
        }

        data += chunk_size;
    }

    return -1;
}

static int cinepak_decode (CinepakContext *s)
{
    const uint8_t  *eod = (s->data + s->size);
    int           i, result, strip_size, frame_flags, num_strips;
    int           y0 = 0;
    int           encoded_buf_size;

    if (s->size < 10)
        return -1;

    frame_flags = s->data[0];
    num_strips  = AV_RB16 (&s->data[8]);
    encoded_buf_size = ((s->data[1] << 16) | AV_RB16 (&s->data[2]));

    /* if this is the first frame, check for deviant Sega FILM data */
    if (s->sega_film_skip_bytes == -1) {
        if (encoded_buf_size != s->size) {
            /* If the encoded frame size differs from the frame size as indicated
             * by the container file, this data likely comes from a Sega FILM/CPK file.
             * If the frame header is followed by the bytes FE 00 00 06 00 00 then
             * this is probably one of the two known files that have 6 extra bytes
             * after the frame header. Else, assume 2 extra bytes. */
            if (s->size >= 16 &&
                (s->data[10] == 0xFE) &&
                (s->data[11] == 0x00) &&
                (s->data[12] == 0x00) &&
                (s->data[13] == 0x06) &&
                (s->data[14] == 0x00) &&
                (s->data[15] == 0x00))
                s->sega_film_skip_bytes = 6;
            else
                s->sega_film_skip_bytes = 2;
        } else
            s->sega_film_skip_bytes = 0;
    }

    s->data += 10 + s->sega_film_skip_bytes;

    if (num_strips > MAX_STRIPS)
        num_strips = MAX_STRIPS;

    for (i=0; i < num_strips; i++) {
        if ((s->data + 12) > eod)
            return -1;

        s->strips[i].id = s->data[0];
        s->strips[i].y1 = y0;
        s->strips[i].x1 = 0;
        s->strips[i].y2 = y0 + AV_RB16 (&s->data[8]);
        s->strips[i].x2 = s->avctx->width;

        strip_size = AV_RB24 (&s->data[1]) - 12;
        if(strip_size < 0)
            return -1;
        s->data   += 12;
        strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;

        if ((i > 0) && !(frame_flags & 0x01)) {
            memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook,
                sizeof(s->strips[i].v4_codebook));
            memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook,
                sizeof(s->strips[i].v1_codebook));
        }

        result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size);

        if (result != 0)
            return result;

        s->data += strip_size;
        y0    = s->strips[i].y2;
    }
    return 0;
}

static av_cold int cinepak_decode_init(AVCodecContext *avctx)
{
    CinepakContext *s = avctx->priv_data;

    s->avctx = avctx;
    s->width = (avctx->width + 3) & ~3;
    s->height = (avctx->height + 3) & ~3;
    s->sega_film_skip_bytes = -1;  /* uninitialized state */

    // check for paletted data
    if ((avctx->palctrl == NULL) || (avctx->bits_per_coded_sample == 40)) {
        s->palette_video = 0;
        avctx->pix_fmt = PIX_FMT_YUV420P;
    } else {
        s->palette_video = 1;
        avctx->pix_fmt = PIX_FMT_PAL8;
    }

    s->frame.data[0] = NULL;

    return 0;
}

static int cinepak_decode_frame(AVCodecContext *avctx,
                                void *data, int *data_size,
                                const uint8_t *buf, int buf_size)
{
    CinepakContext *s = avctx->priv_data;

    s->data = buf;
    s->size = buf_size;

    s->frame.reference = 1;
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                            FF_BUFFER_HINTS_REUSABLE;
    if (avctx->reget_buffer(avctx, &s->frame)) {
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
        return -1;
    }

    cinepak_decode(s);

    if (s->palette_video) {
        memcpy (s->frame.data[1], avctx->palctrl->palette, AVPALETTE_SIZE);
        if (avctx->palctrl->palette_changed) {
            s->frame.palette_has_changed = 1;
            avctx->palctrl->palette_changed = 0;
        } else
            s->frame.palette_has_changed = 0;
    }

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;

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

static av_cold int cinepak_decode_end(AVCodecContext *avctx)
{
    CinepakContext *s = avctx->priv_data;

    if (s->frame.data[0])
        avctx->release_buffer(avctx, &s->frame);

    return 0;
}

AVCodec cinepak_decoder = {
    "cinepak",
    CODEC_TYPE_VIDEO,
    CODEC_ID_CINEPAK,
    sizeof(CinepakContext),
    cinepak_decode_init,
    NULL,
    cinepak_decode_end,
    cinepak_decode_frame,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
};
