/*
 * Cirrus Logic AccuPak (CLJR) codec
 * Copyright (c) 2003 Alex Beregszaszi
 *
 * 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/cljr.c
 * Cirrus Logic AccuPak codec.
 */

#include "avcodec.h"
#include "dsputil.h"
#include "bitstream.h"

/* Disable the encoder. */
#undef CONFIG_CLJR_ENCODER
#define CONFIG_CLJR_ENCODER 0

typedef struct CLJRContext{
    AVCodecContext *avctx;
    AVFrame picture;
    int delta[16];
    int offset[4];
    GetBitContext gb;
} CLJRContext;

static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        const uint8_t *buf, int buf_size)
{
    CLJRContext * const a = avctx->priv_data;
    AVFrame *picture = data;
    AVFrame * const p= (AVFrame*)&a->picture;
    int x, y;

    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");
        return -1;
    }
    p->pict_type= FF_I_TYPE;
    p->key_frame= 1;

    init_get_bits(&a->gb, buf, buf_size * 8);

    for(y=0; y<avctx->height; y++){
        uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
        uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ];
        uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ];
        for(x=0; x<avctx->width; x+=4){
                luma[3] = get_bits(&a->gb, 5) << 3;
            luma[2] = get_bits(&a->gb, 5) << 3;
            luma[1] = get_bits(&a->gb, 5) << 3;
            luma[0] = get_bits(&a->gb, 5) << 3;
            luma+= 4;
            *(cb++) = get_bits(&a->gb, 6) << 2;
            *(cr++) = get_bits(&a->gb, 6) << 2;
        }
    }

    *picture= *(AVFrame*)&a->picture;
    *data_size = sizeof(AVPicture);

    emms_c();

    return buf_size;
}

#if CONFIG_CLJR_ENCODER
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
    CLJRContext * const a = avctx->priv_data;
    AVFrame *pict = data;
    AVFrame * const p= (AVFrame*)&a->picture;
    int size;

    *p = *pict;
    p->pict_type= FF_I_TYPE;
    p->key_frame= 1;

    emms_c();

    align_put_bits(&a->pb);
    while(get_bit_count(&a->pb)&31)
        put_bits(&a->pb, 8, 0);

    size= get_bit_count(&a->pb)/32;

    return size*4;
}
#endif

static av_cold void common_init(AVCodecContext *avctx){
    CLJRContext * const a = avctx->priv_data;

    avctx->coded_frame= (AVFrame*)&a->picture;
    a->avctx= avctx;
}

static av_cold int decode_init(AVCodecContext *avctx){

    common_init(avctx);

    avctx->pix_fmt= PIX_FMT_YUV411P;

    return 0;
}

#if CONFIG_CLJR_ENCODER
static av_cold int encode_init(AVCodecContext *avctx){

    common_init(avctx);

    return 0;
}
#endif

AVCodec cljr_decoder = {
    "cljr",
    CODEC_TYPE_VIDEO,
    CODEC_ID_CLJR,
    sizeof(CLJRContext),
    decode_init,
    NULL,
    NULL,
    decode_frame,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
};

#if CONFIG_CLJR_ENCODER
AVCodec cljr_encoder = {
    "cljr",
    CODEC_TYPE_VIDEO,
    CODEC_ID_CLJR,
    sizeof(CLJRContext),
    encode_init,
    encode_frame,
    //encode_end,
    .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
};
#endif
