/*
 * Beam Software SIFF demuxer
 * Copyright (c) 2007 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
 */

#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"
#include "avio_internal.h"

enum SIFFTags{
    TAG_SIFF = MKTAG('S', 'I', 'F', 'F'),
    TAG_BODY = MKTAG('B', 'O', 'D', 'Y'),
    TAG_VBHD = MKTAG('V', 'B', 'H', 'D'),
    TAG_SHDR = MKTAG('S', 'H', 'D', 'R'),
    TAG_VBV1 = MKTAG('V', 'B', 'V', '1'),
    TAG_SOUN = MKTAG('S', 'O', 'U', 'N'),
};

enum VBFlags{
    VB_HAS_GMC     = 0x01,
    VB_HAS_AUDIO   = 0x04,
    VB_HAS_VIDEO   = 0x08,
    VB_HAS_PALETTE = 0x10,
    VB_HAS_LENGTH  = 0x20
};

typedef struct SIFFContext{
    int frames;
    int cur_frame;
    int rate;
    int bits;
    int block_align;

    int has_video;
    int has_audio;

    int curstrm;
    int pktsize;
    int gmcsize;
    int sndsize;

    int flags;
    uint8_t gmc[4];
}SIFFContext;

static int siff_probe(AVProbeData *p)
{
    uint32_t tag = AV_RL32(p->buf + 8);
    /* check file header */
    if (AV_RL32(p->buf) != TAG_SIFF ||
        (tag != TAG_VBV1 && tag != TAG_SOUN))
        return 0;
    return AVPROBE_SCORE_MAX;
}

static int create_audio_stream(AVFormatContext *s, SIFFContext *c)
{
    AVStream *ast;
    ast = avformat_new_stream(s, NULL);
    if (!ast)
        return -1;
    ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
    ast->codec->codec_id        = AV_CODEC_ID_PCM_U8;
    ast->codec->channels        = 1;
    ast->codec->bits_per_coded_sample = 8;
    ast->codec->sample_rate     = c->rate;
    avpriv_set_pts_info(ast, 16, 1, c->rate);
    ast->start_time = 0;
    return 0;
}

static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, AVIOContext *pb)
{
    AVStream *st;
    int width, height;

    if (avio_rl32(pb) != TAG_VBHD){
        av_log(s, AV_LOG_ERROR, "Header chunk is missing\n");
        return -1;
    }
    if(avio_rb32(pb) != 32){
        av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n");
        return -1;
    }
    if(avio_rl16(pb) != 1){
        av_log(s, AV_LOG_ERROR, "Incorrect header version\n");
        return -1;
    }
    width = avio_rl16(pb);
    height = avio_rl16(pb);
    avio_skip(pb, 4);
    c->frames = avio_rl16(pb);
    if(!c->frames){
        av_log(s, AV_LOG_ERROR, "File contains no frames ???\n");
        return -1;
    }
    c->bits = avio_rl16(pb);
    c->rate = avio_rl16(pb);
    c->block_align = c->rate * (c->bits >> 3);

    avio_skip(pb, 16); //zeroes

    st = avformat_new_stream(s, NULL);
    if (!st)
        return -1;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = AV_CODEC_ID_VB;
    st->codec->codec_tag  = MKTAG('V', 'B', 'V', '1');
    st->codec->width      = width;
    st->codec->height     = height;
    st->codec->pix_fmt    = PIX_FMT_PAL8;
    avpriv_set_pts_info(st, 16, 1, 12);

    c->cur_frame = 0;
    c->has_video = 1;
    c->has_audio = !!c->rate;
    c->curstrm = -1;
    if (c->has_audio && create_audio_stream(s, c) < 0)
        return -1;
    return 0;
}

static int siff_parse_soun(AVFormatContext *s, SIFFContext *c, AVIOContext *pb)
{
    if (avio_rl32(pb) != TAG_SHDR){
        av_log(s, AV_LOG_ERROR, "Header chunk is missing\n");
        return -1;
    }
    if(avio_rb32(pb) != 8){
        av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n");
        return -1;
    }
    avio_skip(pb, 4); //unknown value
    c->rate = avio_rl16(pb);
    c->bits = avio_rl16(pb);
    c->block_align = c->rate * (c->bits >> 3);
    return create_audio_stream(s, c);
}

static int siff_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    SIFFContext *c = s->priv_data;
    uint32_t tag;

    if (avio_rl32(pb) != TAG_SIFF)
        return -1;
    avio_skip(pb, 4); //ignore size
    tag = avio_rl32(pb);

    if (tag != TAG_VBV1 && tag != TAG_SOUN){
        av_log(s, AV_LOG_ERROR, "Not a VBV file\n");
        return -1;
    }

    if (tag == TAG_VBV1 && siff_parse_vbv1(s, c, pb) < 0)
        return -1;
    if (tag == TAG_SOUN && siff_parse_soun(s, c, pb) < 0)
        return -1;
    if (avio_rl32(pb) != MKTAG('B', 'O', 'D', 'Y')){
        av_log(s, AV_LOG_ERROR, "'BODY' chunk is missing\n");
        return -1;
    }
    avio_skip(pb, 4); //ignore size

    return 0;
}

static int siff_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    SIFFContext *c = s->priv_data;
    int size;

    if (c->has_video){
        if (c->cur_frame >= c->frames)
            return AVERROR(EIO);
        if (c->curstrm == -1){
            c->pktsize = avio_rl32(s->pb) - 4;
            c->flags = avio_rl16(s->pb);
            c->gmcsize = (c->flags & VB_HAS_GMC) ? 4 : 0;
            if (c->gmcsize)
                avio_read(s->pb, c->gmc, c->gmcsize);
            c->sndsize = (c->flags & VB_HAS_AUDIO) ? avio_rl32(s->pb): 0;
            c->curstrm = !!(c->flags & VB_HAS_AUDIO);
        }

        if (!c->curstrm){
            size = c->pktsize - c->sndsize - c->gmcsize - 2;
            size = ffio_limit(s->pb, size);
            if(size < 0 || c->pktsize < c->sndsize)
                return AVERROR_INVALIDDATA;
            if (av_new_packet(pkt, size + c->gmcsize + 2) < 0)
                return AVERROR(ENOMEM);
            AV_WL16(pkt->data, c->flags);
            if (c->gmcsize)
                memcpy(pkt->data + 2, c->gmc, c->gmcsize);
            avio_read(s->pb, pkt->data + 2 + c->gmcsize, size);
            pkt->stream_index = 0;
            c->curstrm = -1;
        }else{
            if ((size = av_get_packet(s->pb, pkt, c->sndsize - 4)) < 0)
                return AVERROR(EIO);
            pkt->stream_index = 1;
            pkt->duration     = size;
            c->curstrm = 0;
        }
        if(!c->cur_frame || c->curstrm)
            pkt->flags |= AV_PKT_FLAG_KEY;
        if (c->curstrm == -1)
            c->cur_frame++;
    }else{
        size = av_get_packet(s->pb, pkt, c->block_align);
        if(size <= 0)
            return AVERROR(EIO);
        pkt->duration = size;
    }
    return pkt->size;
}

AVInputFormat ff_siff_demuxer = {
    .name           = "siff",
    .long_name      = NULL_IF_CONFIG_SMALL("Beam Software SIFF"),
    .priv_data_size = sizeof(SIFFContext),
    .read_probe     = siff_probe,
    .read_header    = siff_read_header,
    .read_packet    = siff_read_packet,
    .extensions     = "vb,son",
};
