/*
 * Delphine Software International CIN Audio/Video Decoders
 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
 *
 * 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/dsicinav.c
 * Delphine Software International CIN audio/video decoders
 */

#include "avcodec.h"
#include "bytestream.h"


typedef enum CinVideoBitmapIndex {
    CIN_CUR_BMP = 0, /* current */
    CIN_PRE_BMP = 1, /* previous */
    CIN_INT_BMP = 2  /* intermediate */
} CinVideoBitmapIndex;

typedef struct CinVideoContext {
    AVCodecContext *avctx;
    AVFrame frame;
    unsigned int bitmap_size;
    uint32_t palette[256];
    uint8_t *bitmap_table[3];
} CinVideoContext;

typedef struct CinAudioContext {
    AVCodecContext *avctx;
    int initial_decode_frame;
    int delta;
} CinAudioContext;


/* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
static const int16_t cinaudio_delta16_table[256] = {
         0,      0,      0,      0,      0,      0,      0,      0,
         0,      0,      0,      0,      0,      0,      0,      0,
         0,      0,      0, -30210, -27853, -25680, -23677, -21829,
    -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
    -10508,  -9689,  -8933,  -8236,  -7593,  -7001,  -6455,  -5951,
     -5487,  -5059,  -4664,  -4300,  -3964,  -3655,  -3370,  -3107,
     -2865,  -2641,  -2435,  -2245,  -2070,  -1908,  -1759,  -1622,
     -1495,  -1379,  -1271,  -1172,  -1080,   -996,   -918,   -847,
      -781,   -720,   -663,   -612,   -564,   -520,   -479,   -442,
      -407,   -376,   -346,   -319,   -294,   -271,   -250,   -230,
      -212,   -196,   -181,   -166,   -153,   -141,   -130,   -120,
      -111,   -102,    -94,    -87,    -80,    -74,    -68,    -62,
       -58,    -53,    -49,    -45,    -41,    -38,    -35,    -32,
       -30,    -27,    -25,    -23,    -21,    -20,    -18,    -17,
       -15,    -14,    -13,    -12,    -11,    -10,     -9,     -8,
        -7,     -6,     -5,     -4,     -3,     -2,     -1,      0,
         0,      1,      2,      3,      4,      5,      6,      7,
         8,      9,     10,     11,     12,     13,     14,     15,
        17,     18,     20,     21,     23,     25,     27,     30,
        32,     35,     38,     41,     45,     49,     53,     58,
        62,     68,     74,     80,     87,     94,    102,    111,
       120,    130,    141,    153,    166,    181,    196,    212,
       230,    250,    271,    294,    319,    346,    376,    407,
       442,    479,    520,    564,    612,    663,    720,    781,
       847,    918,    996,   1080,   1172,   1271,   1379,   1495,
      1622,   1759,   1908,   2070,   2245,   2435,   2641,   2865,
      3107,   3370,   3655,   3964,   4300,   4664,   5059,   5487,
      5951,   6455,   7001,   7593,   8236,   8933,   9689,  10508,
     11398,  12362,  13408,  14543,  15774,  17108,  18556,  20126,
     21829,  23677,  25680,  27853,  30210,      0,      0,      0,
         0,      0,      0,      0,      0,      0,      0,      0,
         0,      0,      0,      0,      0,      0,      0,      0
};


static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
{
    CinVideoContext *cin = avctx->priv_data;
    unsigned int i;

    cin->avctx = avctx;
    avctx->pix_fmt = PIX_FMT_PAL8;

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

    cin->bitmap_size = avctx->width * avctx->height;
    for (i = 0; i < 3; ++i) {
        cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
        if (!cin->bitmap_table[i])
            av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
    }

    return 0;
}

static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
{
    while (size--)
        *dst++ += *src++;
}

static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
    int b, huff_code = 0;
    unsigned char huff_code_table[15];
    unsigned char *dst_cur = dst;
    unsigned char *dst_end = dst + dst_size;
    const unsigned char *src_end = src + src_size;

    memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;

    while (src < src_end) {
        huff_code = *src++;
        if ((huff_code >> 4) == 15) {
            b = huff_code << 4;
            huff_code = *src++;
            *dst_cur++ = b | (huff_code >> 4);
        } else
            *dst_cur++ = huff_code_table[huff_code >> 4];
        if (dst_cur >= dst_end)
            break;

        huff_code &= 15;
        if (huff_code == 15) {
            *dst_cur++ = *src++;
        } else
            *dst_cur++ = huff_code_table[huff_code];
        if (dst_cur >= dst_end)
            break;
    }

    return dst_cur - dst;
}

static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
    uint16_t cmd;
    int i, sz, offset, code;
    unsigned char *dst_end = dst + dst_size;
    const unsigned char *src_end = src + src_size;

    while (src < src_end && dst < dst_end) {
        code = *src++;
        for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
            if (code & (1 << i)) {
                *dst++ = *src++;
            } else {
                cmd = AV_RL16(src); src += 2;
                offset = cmd >> 4;
                sz = (cmd & 0xF) + 2;
                /* don't use memcpy/memmove here as the decoding routine (ab)uses */
                /* buffer overlappings to repeat bytes in the destination */
                sz = FFMIN(sz, dst_end - dst);
                while (sz--) {
                    *dst = *(dst - offset - 1);
                    ++dst;
                }
            }
        }
    }
}

static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
    int len, code;
    unsigned char *dst_end = dst + dst_size;
    const unsigned char *src_end = src + src_size;

    while (src < src_end && dst < dst_end) {
        code = *src++;
        if (code & 0x80) {
            len = code - 0x7F;
            memset(dst, *src++, FFMIN(len, dst_end - dst));
        } else {
            len = code + 1;
            memcpy(dst, src, FFMIN(len, dst_end - dst));
            src += len;
        }
        dst += len;
    }
}

static int cinvideo_decode_frame(AVCodecContext *avctx,
                                 void *data, int *data_size,
                                 const uint8_t *buf, int buf_size)
{
    CinVideoContext *cin = avctx->priv_data;
    int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size;

    cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
    if (avctx->reget_buffer(avctx, &cin->frame)) {
        av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
        return -1;
    }

    palette_type = buf[0];
    palette_colors_count = AV_RL16(buf+1);
    bitmap_frame_type = buf[3];
    buf += 4;

    bitmap_frame_size = buf_size - 4;

    /* handle palette */
    if (palette_type == 0) {
        if (palette_colors_count > 256)
            return AVERROR_INVALIDDATA;
        for (i = 0; i < palette_colors_count; ++i) {
            cin->palette[i] = bytestream_get_le24(&buf);
            bitmap_frame_size -= 3;
        }
    } else {
        for (i = 0; i < palette_colors_count; ++i) {
            cin->palette[buf[0]] = AV_RL24(buf+1);
            buf += 4;
            bitmap_frame_size -= 4;
        }
    }
    memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
    cin->frame.palette_has_changed = 1;

    /* note: the decoding routines below assumes that surface.width = surface.pitch */
    switch (bitmap_frame_type) {
    case 9:
        cin_decode_rle(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 34:
        cin_decode_rle(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 35:
        cin_decode_huffman(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
        cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 36:
        bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
        cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 37:
        cin_decode_huffman(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 38:
        cin_decode_lzss(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    case 39:
        cin_decode_lzss(buf, bitmap_frame_size,
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
          cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
        break;
    }

    for (y = 0; y < cin->avctx->height; ++y)
        memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
          cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
          cin->avctx->width);

    FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);

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

    return buf_size;
}

static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
{
    CinVideoContext *cin = avctx->priv_data;
    int i;

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

    for (i = 0; i < 3; ++i)
        av_free(cin->bitmap_table[i]);

    return 0;
}

static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
{
    CinAudioContext *cin = avctx->priv_data;

    cin->avctx = avctx;
    cin->initial_decode_frame = 1;
    cin->delta = 0;
    avctx->sample_fmt = SAMPLE_FMT_S16;

    return 0;
}

static int cinaudio_decode_frame(AVCodecContext *avctx,
                                 void *data, int *data_size,
                                 const uint8_t *buf, int buf_size)
{
    CinAudioContext *cin = avctx->priv_data;
    const uint8_t *src = buf;
    int16_t *samples = (int16_t *)data;

    buf_size = FFMIN(buf_size, *data_size/2);

    if (cin->initial_decode_frame) {
        cin->initial_decode_frame = 0;
        cin->delta = (int16_t)AV_RL16(src); src += 2;
        *samples++ = cin->delta;
        buf_size -= 2;
    }
    while (buf_size > 0) {
        cin->delta += cinaudio_delta16_table[*src++];
        cin->delta = av_clip_int16(cin->delta);
        *samples++ = cin->delta;
        --buf_size;
    }

    *data_size = (uint8_t *)samples - (uint8_t *)data;

    return src - buf;
}


AVCodec dsicinvideo_decoder = {
    "dsicinvideo",
    CODEC_TYPE_VIDEO,
    CODEC_ID_DSICINVIDEO,
    sizeof(CinVideoContext),
    cinvideo_decode_init,
    NULL,
    cinvideo_decode_end,
    cinvideo_decode_frame,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
};

AVCodec dsicinaudio_decoder = {
    "dsicinaudio",
    CODEC_TYPE_AUDIO,
    CODEC_ID_DSICINAUDIO,
    sizeof(CinAudioContext),
    cinaudio_decode_init,
    NULL,
    NULL,
    cinaudio_decode_frame,
    .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
};
