/*
 * Winnov WNV1 codec
 * Copyright (c) 2005 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
 * Winnov WNV1 codec.
 */

#include "avcodec.h"
#include "get_bits.h"
#include "libavutil/common.h"


typedef struct WNV1Context{
    AVCodecContext *avctx;
    AVFrame pic;

    int shift;
    GetBitContext gb;
} WNV1Context;

static const uint16_t code_tab[16][2]={
{0x1FD,9}, {0xFD,8}, {0x7D,7}, {0x3D,6}, {0x1D,5}, {0x0D,4}, {0x005,3},
{0x000,1},
{0x004,3}, {0x0C,4}, {0x1C,5}, {0x3C,6}, {0x7C,7}, {0xFC,8}, {0x1FC,9}, {0xFF,8}
};

#define CODE_VLC_BITS 9
static VLC code_vlc;

/* returns modified base_value */
static inline int wnv1_get_code(WNV1Context *w, int base_value)
{
    int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1);

    if(v==15)
        return av_reverse[ get_bits(&w->gb, 8 - w->shift) ];
    else
        return base_value + ((v - 7)<<w->shift);
}

static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    WNV1Context * const l = avctx->priv_data;
    AVFrame * const p= (AVFrame*)&l->pic;
    unsigned char *Y,*U,*V;
    int i, j;
    int prev_y = 0, prev_u = 0, prev_v = 0;
    uint8_t *rbuf;

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

    rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if(!rbuf){
        av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
        return -1;
    }

    if(p->data[0])
        avctx->release_buffer(avctx, p);

    p->reference = 0;
    if(avctx->get_buffer(avctx, p) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        av_free(rbuf);
        return -1;
    }
    p->key_frame = 1;

    for(i=8; i<buf_size; i++)
        rbuf[i]= av_reverse[ buf[i] ];
    init_get_bits(&l->gb, rbuf+8, (buf_size-8)*8);

    if (buf[2] >> 4 == 6)
        l->shift = 2;
    else {
        l->shift = 8 - (buf[2] >> 4);
        if (l->shift > 4) {
            av_log_ask_for_sample(avctx, "Unknown WNV1 frame header value %i\n",
                                  buf[2] >> 4);
            l->shift = 4;
        }
        if (l->shift < 1) {
            av_log_ask_for_sample(avctx, "Unknown WNV1 frame header value %i\n",
                                  buf[2] >> 4);
            l->shift = 1;
        }
    }

    Y = p->data[0];
    U = p->data[1];
    V = p->data[2];
    for (j = 0; j < avctx->height; j++) {
        for (i = 0; i < avctx->width / 2; i++) {
            Y[i * 2] = wnv1_get_code(l, prev_y);
            prev_u = U[i] = wnv1_get_code(l, prev_u);
            prev_y = Y[(i * 2) + 1] = wnv1_get_code(l, Y[i * 2]);
            prev_v = V[i] = wnv1_get_code(l, prev_v);
        }
        Y += p->linesize[0];
        U += p->linesize[1];
        V += p->linesize[2];
    }


    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = l->pic;
    av_free(rbuf);

    return buf_size;
}

static av_cold int decode_init(AVCodecContext *avctx){
    WNV1Context * const l = avctx->priv_data;
    static VLC_TYPE code_table[1 << CODE_VLC_BITS][2];

    l->avctx = avctx;
    avctx->pix_fmt = PIX_FMT_YUV422P;
    avcodec_get_frame_defaults(&l->pic);

    code_vlc.table = code_table;
    code_vlc.table_allocated = 1 << CODE_VLC_BITS;
    init_vlc(&code_vlc, CODE_VLC_BITS, 16,
             &code_tab[0][1], 4, 2,
             &code_tab[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);

    return 0;
}

static av_cold int decode_end(AVCodecContext *avctx){
    WNV1Context * const l = avctx->priv_data;
    AVFrame *pic = &l->pic;

    if (pic->data[0])
        avctx->release_buffer(avctx, pic);

    return 0;
}

AVCodec ff_wnv1_decoder = {
    .name           = "wnv1",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_WNV1,
    .priv_data_size = sizeof(WNV1Context),
    .init           = decode_init,
    .close          = decode_end,
    .decode         = decode_frame,
    .capabilities   = CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
};
