/*
 * Smacker decoder
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * 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
 * Smacker decoder
 */

/*
 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
 */

#include <stddef.h>

#include "libavutil/channel_layout.h"
#include "libavutil/mem.h"

#include "avcodec.h"

#define SMKTREE_BITS 9
#define SMK_NODE 0x80000000

#define SMKTREE_DECODE_MAX_RECURSION FFMIN(32, 3 * SMKTREE_BITS)
#define SMKTREE_DECODE_BIG_MAX_RECURSION 500

/* The maximum possible unchecked overread happens in decode_header_trees:
 * Decoding the MMAP tree can overread by 6 * SMKTREE_BITS + 1, followed by
 * three get_bits1, followed by at most 2 + 3 * 16 read bits when reading
 * the TYPE tree before the next check. 64 is because of 64 bit reads. */
#if (6 * SMKTREE_BITS + 1 + 3 + (2 + 3 * 16) + 64) <= 8 * AV_INPUT_BUFFER_PADDING_SIZE
#define UNCHECKED_BITSTREAM_READER 1
#endif
#define BITSTREAM_READER_LE
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
#include "get_bits.h"

typedef struct SmackVContext {
    AVCodecContext *avctx;
    AVFrame *pic;

    int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl;
    int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
} SmackVContext;

typedef struct HuffEntry {
    uint8_t value;
    uint8_t length;
} HuffEntry;

/**
 * Context used for code reconstructing
 */
typedef struct HuffContext {
    int current;
    HuffEntry entries[256];
} HuffContext;

/* common parameters used for decode_bigtree */
typedef struct DBCtx {
    int current, length;
    int *values;
    VLC *v1, *v2;
    uint8_t vals[2];
    int escapes[3];
    int *last;
} DBCtx;

/* possible runs of blocks */
static const int block_runs[64] = {
      1,    2,    3,    4,    5,    6,    7,    8,
      9,   10,   11,   12,   13,   14,   15,   16,
     17,   18,   19,   20,   21,   22,   23,   24,
     25,   26,   27,   28,   29,   30,   31,   32,
     33,   34,   35,   36,   37,   38,   39,   40,
     41,   42,   43,   44,   45,   46,   47,   48,
     49,   50,   51,   52,   53,   54,   55,   56,
     57,   58,   59,  128,  256,  512, 1024, 2048 };

enum SmkBlockTypes {
    SMK_BLK_MONO = 0,
    SMK_BLK_FULL = 1,
    SMK_BLK_SKIP = 2,
    SMK_BLK_FILL = 3 };

/**
 * Decode local frame tree
 *
 * Can read SMKTREE_DECODE_MAX_RECURSION before the first check;
 * does not overread gb on success.
 */
static int smacker_decode_tree(AVCodecContext *avctx, GetBitContext *gb, HuffContext *hc, int length)
{
    if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) {
        av_log(avctx, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n");
        return AVERROR_INVALIDDATA;
    }

    if(!get_bits1(gb)){ //Leaf
        if (hc->current >= 256) {
            av_log(avctx, AV_LOG_ERROR, "Tree size exceeded!\n");
            return AVERROR_INVALIDDATA;
        }
        if (get_bits_left(gb) < 8)
            return AVERROR_INVALIDDATA;
        hc->entries[hc->current++] = (HuffEntry){ get_bits(gb, 8), length };
        return 0;
    } else { //Node
        int r;
        length++;
        r = smacker_decode_tree(avctx, gb, hc, length);
        if(r)
            return r;
        return smacker_decode_tree(avctx, gb, hc, length);
    }
}

/**
 * Decode header tree
 *
 * Checks before the first read, can overread by 6 * SMKTREE_BITS on success.
 */
static int smacker_decode_bigtree(AVCodecContext *avctx, GetBitContext *gb, DBCtx *ctx, int length)
{
    // Larger length can cause segmentation faults due to too deep recursion.
    if (length > SMKTREE_DECODE_BIG_MAX_RECURSION) {
        av_log(NULL, AV_LOG_ERROR, "Maximum bigtree recursion level exceeded.\n");
        return AVERROR_INVALIDDATA;
    }

    if (ctx->current >= ctx->length) {
        av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
        return AVERROR_INVALIDDATA;
    }
    if (get_bits_left(gb) <= 0)
        return AVERROR_INVALIDDATA;
    if(!get_bits1(gb)){ //Leaf
        int val, i1, i2;
        i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3)
                            : ctx->vals[0];
        i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3)
                            : ctx->vals[1];
        val = i1 | (i2 << 8);
        if(val == ctx->escapes[0]) {
            ctx->last[0] = ctx->current;
            val = 0;
        } else if(val == ctx->escapes[1]) {
            ctx->last[1] = ctx->current;
            val = 0;
        } else if(val == ctx->escapes[2]) {
            ctx->last[2] = ctx->current;
            val = 0;
        }

        ctx->values[ctx->current++] = val;
        return 1;
    } else { //Node
        int r = 0, r_new, t;

        t = ctx->current++;
        r = smacker_decode_bigtree(avctx, gb, ctx, length + 1);
        if(r < 0)
            return r;
        ctx->values[t] = SMK_NODE | r;
        r++;
        r_new = smacker_decode_bigtree(avctx, gb, ctx, length + 1);
        if (r_new < 0)
            return r_new;
        return r + r_new;
    }
}

/**
 * Store large tree as FFmpeg's vlc codes
 *
 * Can read FFMAX(1 + SMKTREE_DECODE_MAX_RECURSION, 2 + 3 * 16) bits
 * before the first check; can overread by 6 * SMKTREE_BITS + 1 on success.
 */
static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size)
{
    VLC vlc[2] = { { 0 } };
    int escapes[3];
    DBCtx ctx;
    int err;

    if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow
        av_log(smk->avctx, AV_LOG_ERROR, "size too large\n");
        return AVERROR_INVALIDDATA;
    }

    for (int i = 0; i < 2; i++) {
        HuffContext h;
        h.current = 0;
        if (!get_bits1(gb)) {
            ctx.vals[i] = 0;
            av_log(smk->avctx, AV_LOG_ERROR, "Skipping %s bytes tree\n",
                   i ? "high" : "low");
            continue;
        }
        err = smacker_decode_tree(smk->avctx, gb, &h, 0);
        if (err < 0)
            goto error;
        skip_bits1(gb);
        if (h.current > 1) {
            err = ff_vlc_init_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
                                           &h.entries[0].length, sizeof(*h.entries),
                                           &h.entries[0].value,  sizeof(*h.entries), 1,
                                           0, VLC_INIT_OUTPUT_LE, smk->avctx);
            if (err < 0) {
                av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
                goto error;
            }
        } else
            ctx.vals[i] = h.entries[0].value;
    }

    escapes[0]  = get_bits(gb, 16);
    escapes[1]  = get_bits(gb, 16);
    escapes[2]  = get_bits(gb, 16);

    last[0] = last[1] = last[2] = -1;

    ctx.escapes[0] = escapes[0];
    ctx.escapes[1] = escapes[1];
    ctx.escapes[2] = escapes[2];
    ctx.v1 = &vlc[0];
    ctx.v2 = &vlc[1];
    ctx.last = last;
    ctx.length  = (size + 3) >> 2;
    ctx.current = 0;
    ctx.values  = av_malloc_array(ctx.length + 3, sizeof(ctx.values[0]));
    if (!ctx.values) {
        err = AVERROR(ENOMEM);
        goto error;
    }
    *recodes = ctx.values;

    err = smacker_decode_bigtree(smk->avctx, gb, &ctx, 0);
    if (err < 0)
        goto error;
    skip_bits1(gb);
    if (ctx.last[0] == -1) ctx.last[0] = ctx.current++;
    if (ctx.last[1] == -1) ctx.last[1] = ctx.current++;
    if (ctx.last[2] == -1) ctx.last[2] = ctx.current++;

    err = 0;
error:
    for (int i = 0; i < 2; i++) {
        ff_vlc_free(&vlc[i]);
    }

    return err;
}

static int decode_header_trees(SmackVContext *smk) {
    GetBitContext gb;
    int mmap_size, mclr_size, full_size, type_size, ret;
    int skip = 0;

    mmap_size = AV_RL32(smk->avctx->extradata);
    mclr_size = AV_RL32(smk->avctx->extradata + 4);
    full_size = AV_RL32(smk->avctx->extradata + 8);
    type_size = AV_RL32(smk->avctx->extradata + 12);

    ret = init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16);
    if (ret < 0)
        return ret;

    if(!get_bits1(&gb)) {
        skip ++;
        av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n");
        smk->mmap_tbl = av_malloc(sizeof(int) * 2);
        if (!smk->mmap_tbl)
            return AVERROR(ENOMEM);
        smk->mmap_tbl[0] = 0;
        smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1;
    } else {
        ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size);
        if (ret < 0)
            return ret;
    }
    if(!get_bits1(&gb)) {
        skip ++;
        av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n");
        smk->mclr_tbl = av_malloc(sizeof(int) * 2);
        if (!smk->mclr_tbl)
            return AVERROR(ENOMEM);
        smk->mclr_tbl[0] = 0;
        smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1;
    } else {
        ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size);
        if (ret < 0)
            return ret;
    }
    if(!get_bits1(&gb)) {
        skip ++;
        av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n");
        smk->full_tbl = av_malloc(sizeof(int) * 2);
        if (!smk->full_tbl)
            return AVERROR(ENOMEM);
        smk->full_tbl[0] = 0;
        smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1;
    } else {
        ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size);
        if (ret < 0)
            return ret;
    }
    if(!get_bits1(&gb)) {
        skip ++;
        av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n");
        smk->type_tbl = av_malloc(sizeof(int) * 2);
        if (!smk->type_tbl)
            return AVERROR(ENOMEM);
        smk->type_tbl[0] = 0;
        smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1;
    } else {
        ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size);
        if (ret < 0)
            return ret;
    }
    if (skip == 4 || get_bits_left(&gb) < 0)
        return AVERROR_INVALIDDATA;

    return 0;
}

static av_always_inline void last_reset(int *recode, int *last) {
    recode[last[0]] = recode[last[1]] = recode[last[2]] = 0;
}

/* Get code and update history.
 * Checks before reading, does not overread. */
static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) {
    register int *table = recode;
    int v;

    while(*table & SMK_NODE) {
        if (get_bits_left(gb) < 1)
            return AVERROR_INVALIDDATA;
        if(get_bits1(gb))
            table += (*table) & (~SMK_NODE);
        table++;
    }
    v = *table;

    if(v != recode[last[0]]) {
        recode[last[2]] = recode[last[1]];
        recode[last[1]] = recode[last[0]];
        recode[last[0]] = v;
    }
    return v;
}

static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
                        int *got_frame, AVPacket *avpkt)
{
    SmackVContext * const smk = avctx->priv_data;
    uint8_t *out;
    uint32_t *pal;
    GetByteContext gb2;
    GetBitContext gb;
    int blocks, blk, bw, bh;
    int i, ret;
    int stride;
    int flags;

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

    if ((ret = ff_reget_buffer(avctx, smk->pic, 0)) < 0)
        return ret;

    /* make the palette available on the way out */
    pal = (uint32_t*)smk->pic->data[1];
    bytestream2_init(&gb2, avpkt->data, avpkt->size);
    flags = bytestream2_get_byteu(&gb2);
#if FF_API_PALETTE_HAS_CHANGED
FF_DISABLE_DEPRECATION_WARNINGS
    smk->pic->palette_has_changed = flags & 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    if (flags & 2) {
        smk->pic->flags |= AV_FRAME_FLAG_KEY;
        smk->pic->pict_type = AV_PICTURE_TYPE_I;
    } else {
        smk->pic->flags &= ~AV_FRAME_FLAG_KEY;
        smk->pic->pict_type = AV_PICTURE_TYPE_P;
    }

    for(i = 0; i < 256; i++)
        *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2);

    last_reset(smk->mmap_tbl, smk->mmap_last);
    last_reset(smk->mclr_tbl, smk->mclr_last);
    last_reset(smk->full_tbl, smk->full_last);
    last_reset(smk->type_tbl, smk->type_last);
    if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0)
        return ret;

    blk = 0;
    bw = avctx->width >> 2;
    bh = avctx->height >> 2;
    blocks = bw * bh;
    stride = smk->pic->linesize[0];
    while(blk < blocks) {
        int type, run, mode;
        uint16_t pix;

        type = smk_get_code(&gb, smk->type_tbl, smk->type_last);
        if (type < 0)
            return type;
        run = block_runs[(type >> 2) & 0x3F];
        switch(type & 3){
        case SMK_BLK_MONO:
            while(run-- && blk < blocks){
                int clr, map;
                int hi, lo;
                clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);
                map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);
                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                hi = clr >> 8;
                lo = clr & 0xFF;
                for(i = 0; i < 4; i++) {
                    if(map & 1) out[0] = hi; else out[0] = lo;
                    if(map & 2) out[1] = hi; else out[1] = lo;
                    if(map & 4) out[2] = hi; else out[2] = lo;
                    if(map & 8) out[3] = hi; else out[3] = lo;
                    map >>= 4;
                    out += stride;
                }
                blk++;
            }
            break;
        case SMK_BLK_FULL:
            mode = 0;
            if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes
                if (get_bits_left(&gb) < 1)
                    return AVERROR_INVALIDDATA;
                if(get_bits1(&gb)) mode = 1;
                else if(get_bits1(&gb)) mode = 2;
            }
            while(run-- && blk < blocks){
                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                switch(mode){
                case 0:
                    for(i = 0; i < 4; i++) {
                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                        AV_WL16(out+2,pix);
                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                        AV_WL16(out,pix);
                        out += stride;
                    }
                    break;
                case 1:
                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                    out[0] = out[1] = pix & 0xFF;
                    out[2] = out[3] = pix >> 8;
                    out += stride;
                    out[0] = out[1] = pix & 0xFF;
                    out[2] = out[3] = pix >> 8;
                    out += stride;
                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                    out[0] = out[1] = pix & 0xFF;
                    out[2] = out[3] = pix >> 8;
                    out += stride;
                    out[0] = out[1] = pix & 0xFF;
                    out[2] = out[3] = pix >> 8;
                    break;
                case 2:
                    for(i = 0; i < 2; i++) {
                        uint16_t pix1, pix2;
                        pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                        pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last);
                        AV_WL16(out,pix1);
                        AV_WL16(out+2,pix2);
                        out += stride;
                        AV_WL16(out,pix1);
                        AV_WL16(out+2,pix2);
                        out += stride;
                    }
                    break;
                }
                blk++;
            }
            break;
        case SMK_BLK_SKIP:
            while(run-- && blk < blocks)
                blk++;
            break;
        case SMK_BLK_FILL:
            mode = type >> 8;
            while(run-- && blk < blocks){
                uint32_t col;
                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                col = mode * 0x01010101U;
                for(i = 0; i < 4; i++) {
                    *((uint32_t*)out) = col;
                    out += stride;
                }
                blk++;
            }
            break;
        }

    }

    if ((ret = av_frame_ref(rframe, smk->pic)) < 0)
        return ret;

    *got_frame = 1;

    /* always report that the buffer was completely consumed */
    return avpkt->size;
}


static av_cold int decode_end(AVCodecContext *avctx)
{
    SmackVContext * const smk = avctx->priv_data;

    av_freep(&smk->mmap_tbl);
    av_freep(&smk->mclr_tbl);
    av_freep(&smk->full_tbl);
    av_freep(&smk->type_tbl);

    av_frame_free(&smk->pic);

    return 0;
}


static av_cold int decode_init(AVCodecContext *avctx)
{
    SmackVContext * const c = avctx->priv_data;
    int ret;

    c->avctx = avctx;

    avctx->pix_fmt = AV_PIX_FMT_PAL8;

    c->pic = av_frame_alloc();
    if (!c->pic)
        return AVERROR(ENOMEM);

    /* decode huffman trees from extradata */
    if (avctx->extradata_size <= 16){
        av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
        return AVERROR(EINVAL);
    }

    ret = decode_header_trees(c);
    if (ret < 0) {
        return ret;
    }

    return 0;
}


static av_cold int smka_decode_init(AVCodecContext *avctx)
{
    int channels = avctx->ch_layout.nb_channels;
    if (channels < 1 || channels > 2) {
        av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
        return AVERROR_INVALIDDATA;
    }
    av_channel_layout_uninit(&avctx->ch_layout);
    av_channel_layout_default(&avctx->ch_layout, channels);
    avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16;

    return 0;
}

/**
 * Decode Smacker audio data
 */
static int smka_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    GetBitContext gb;
    VLC vlc[4]       = { { 0 } };
    int16_t *samples;
    uint8_t *samples8;
    uint8_t values[4];
    int i, res, ret;
    int unp_size;
    int bits, stereo;
    unsigned pred[2], val, val2;

    if (buf_size <= 4) {
        av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
        return AVERROR_INVALIDDATA;
    }

    unp_size = AV_RL32(buf);

    if (unp_size > (1U<<24)) {
        av_log(avctx, AV_LOG_ERROR, "packet is too big\n");
        return AVERROR_INVALIDDATA;
    }

    if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0)
        return ret;

    if(!get_bits1(&gb)){
        av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
        *got_frame_ptr = 0;
        return 1;
    }
    stereo = get_bits1(&gb);
    bits = get_bits1(&gb);
    if (stereo ^ (avctx->ch_layout.nb_channels != 1)) {
        av_log(avctx, AV_LOG_ERROR, "channels mismatch\n");
        return AVERROR_INVALIDDATA;
    }
    if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) {
        av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n");
        return AVERROR_INVALIDDATA;
    }

    /* get output buffer */
    frame->nb_samples = unp_size / (avctx->ch_layout.nb_channels * (bits + 1));
    if (unp_size % (avctx->ch_layout.nb_channels * (bits + 1))) {
        av_log(avctx, AV_LOG_ERROR,
               "The buffer does not contain an integer number of samples\n");
        return AVERROR_INVALIDDATA;
    }
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    samples  = (int16_t *)frame->data[0];
    samples8 =            frame->data[0];

    // Initialize
    for(i = 0; i < (1 << (bits + stereo)); i++) {
        HuffContext h;
        h.current = 0;
        skip_bits1(&gb);
        if ((ret = smacker_decode_tree(avctx, &gb, &h, 0)) < 0)
            goto error;
        skip_bits1(&gb);
        if (h.current > 1) {
            ret = ff_vlc_init_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
                                           &h.entries[0].length, sizeof(*h.entries),
                                           &h.entries[0].value,  sizeof(*h.entries), 1,
                                           0, VLC_INIT_OUTPUT_LE, avctx);
            if (ret < 0) {
                av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
                goto error;
            }
        } else
            values[i] = h.entries[0].value;
    }
    /* this codec relies on wraparound instead of clipping audio */
    if(bits) { //decode 16-bit data
        for(i = stereo; i >= 0; i--)
            pred[i] = av_bswap16(get_bits(&gb, 16));
        for(i = 0; i <= stereo; i++)
            *samples++ = pred[i];
        unp_size /= 2;

        if (vlc[0       ].table || vlc[         1].table ||
            vlc[2*stereo].table || vlc[2*stereo+1].table) {
            for(; i < unp_size ; i++) {
                unsigned idx = 2 * (i & stereo);
                if (get_bits_left(&gb) < 0) {
                    ret = AVERROR_INVALIDDATA;
                    goto error;
                }
                if (vlc[idx].table)
                    res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
                else
                    res = values[idx];
                val  = res;
                if (vlc[++idx].table)
                    res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
                else
                    res = values[idx];
                val |= res << 8;
                pred[idx / 2] += val;
                *samples++ = pred[idx / 2];
            }
        } else if (stereo) {
            val  = 256*values[1] + values[0];
            val2 = 256*values[3] + values[2];
            for(; i < unp_size; i+=2) {
                pred[0] += val;
                pred[1] += val2;
                *samples++ = pred[0];
                *samples++ = pred[1];
            }
        } else {
            val = 256*values[1] + values[0];
            for(; i < unp_size; i++) {
                pred[0] += val;
                *samples++ = pred[0];
            }
        }
    } else { //8-bit data
        for(i = stereo; i >= 0; i--)
            pred[i] = get_bits(&gb, 8);
        for(i = 0; i <= stereo; i++)
            *samples8++ = pred[i];
        for(; i < unp_size; i++) {
            unsigned idx = i & stereo;
            if (get_bits_left(&gb) < 0) {
                ret = AVERROR_INVALIDDATA;
                goto error;
            }
            if (vlc[idx].table)
                val = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
            else
                val = values[idx];
            pred[idx] += val;
            *samples8++ = pred[idx];
        }
    }

    *got_frame_ptr = 1;
    ret = buf_size;

error:
    for(i = 0; i < 4; i++) {
        ff_vlc_free(&vlc[i]);
    }

    return ret;
}

const FFCodec ff_smacker_decoder = {
    .p.name         = "smackvid",
    CODEC_LONG_NAME("Smacker video"),
    .p.type         = AVMEDIA_TYPE_VIDEO,
    .p.id           = AV_CODEC_ID_SMACKVIDEO,
    .priv_data_size = sizeof(SmackVContext),
    .init           = decode_init,
    .close          = decode_end,
    FF_CODEC_DECODE_CB(decode_frame),
    .p.capabilities = AV_CODEC_CAP_DR1,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
};

const FFCodec ff_smackaud_decoder = {
    .p.name         = "smackaud",
    CODEC_LONG_NAME("Smacker audio"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_SMACKAUDIO,
    .init           = smka_decode_init,
    FF_CODEC_DECODE_CB(smka_decode_frame),
    .p.capabilities = AV_CODEC_CAP_DR1,
};
