/*
 * Bitmap Brothers JV demuxer
 * Copyright (c) 2005, 2011 Peter Ross <pross@xvid.org>
 *
 * 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
 * Bitmap Brothers JV demuxer
 * @author Peter Ross <pross@xvid.org>
 */

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

#include "avformat.h"
#include "internal.h"

#define JV_PREAMBLE_SIZE 5

typedef struct {
    int audio_size;    /**< audio packet size (bytes) */
    int video_size;    /**< video packet size (bytes) */
    int palette_size;  /**< palette size (bytes) */
    int video_type;    /**< per-frame video compression type */
} JVFrame;

typedef struct {
    JVFrame *frames;
    enum {
        JV_AUDIO = 0,
        JV_VIDEO,
        JV_PADDING
    } state;
    int64_t pts;
} JVDemuxContext;

#define MAGIC " Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."

static int read_probe(AVProbeData *pd)
{
    if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) <= pd->buf_size - 4 &&
        !memcmp(pd->buf + 4, MAGIC, strlen(MAGIC)))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int read_close(AVFormatContext *s)
{
    JVDemuxContext *jv = s->priv_data;

    av_freep(&jv->frames);

    return 0;
}

static int read_header(AVFormatContext *s)
{
    JVDemuxContext *jv = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *vst, *ast;
    int64_t audio_pts = 0;
    int64_t offset;
    int i;

    avio_skip(pb, 80);

    ast = avformat_new_stream(s, NULL);
    vst = avformat_new_stream(s, NULL);
    if (!ast || !vst)
        return AVERROR(ENOMEM);

    vst->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id    = AV_CODEC_ID_JV;
    vst->codec->codec_tag   = 0; /* no fourcc */
    vst->codec->width       = avio_rl16(pb);
    vst->codec->height      = avio_rl16(pb);
    vst->duration           =
    vst->nb_frames          =
    ast->nb_index_entries   = avio_rl16(pb);
    avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);

    avio_skip(pb, 4);

    ast->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
    ast->codec->codec_id       = AV_CODEC_ID_PCM_U8;
    ast->codec->codec_tag      = 0; /* no fourcc */
    ast->codec->sample_rate    = avio_rl16(pb);
    ast->codec->channels       = 1;
    ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
    avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);

    avio_skip(pb, 10);

    ast->index_entries = av_malloc(ast->nb_index_entries *
                                   sizeof(*ast->index_entries));
    if (!ast->index_entries)
        return AVERROR(ENOMEM);

    jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame));
    if (!jv->frames)
        return AVERROR(ENOMEM);

    offset = 0x68 + ast->nb_index_entries * 16;
    for (i = 0; i < ast->nb_index_entries; i++) {
        AVIndexEntry *e   = ast->index_entries + i;
        JVFrame      *jvf = jv->frames + i;

        /* total frame size including audio, video, palette data and padding */
        e->size      = avio_rl32(pb);
        e->timestamp = i;
        e->pos       = offset;
        offset      += e->size;

        jvf->audio_size   = avio_rl32(pb);
        jvf->video_size   = avio_rl32(pb);
        jvf->palette_size = avio_r8(pb) ? 768 : 0;

        if ((jvf->video_size | jvf->audio_size) & ~0xFFFFFF ||
            e->size - jvf->audio_size
                    - jvf->video_size
                    - jvf->palette_size < 0) {
            if (s->error_recognition & AV_EF_EXPLODE) {
                read_close(s);
                return AVERROR_INVALIDDATA;
            }
            jvf->audio_size   =
            jvf->video_size   =
            jvf->palette_size = 0;
        }

        if (avio_r8(pb))
            av_log(s, AV_LOG_WARNING, "unsupported audio codec\n");

        jvf->video_type = avio_r8(pb);
        avio_skip(pb, 1);

        e->timestamp = jvf->audio_size ? audio_pts : AV_NOPTS_VALUE;
        audio_pts   += jvf->audio_size;

        e->flags = jvf->video_type != 1 ? AVINDEX_KEYFRAME : 0;
    }

    jv->state = JV_AUDIO;
    return 0;
}

static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    JVDemuxContext *jv = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *ast = s->streams[0];

    while (!avio_feof(s->pb) && jv->pts < ast->nb_index_entries) {
        const AVIndexEntry *e   = ast->index_entries + jv->pts;
        const JVFrame      *jvf = jv->frames + jv->pts;

        switch (jv->state) {
        case JV_AUDIO:
            jv->state++;
            if (jvf->audio_size) {
                if (av_get_packet(s->pb, pkt, jvf->audio_size) < 0)
                    return AVERROR(ENOMEM);
                pkt->stream_index = 0;
                pkt->pts          = e->timestamp;
                pkt->flags       |= AV_PKT_FLAG_KEY;
                return 0;
            }
        case JV_VIDEO:
            jv->state++;
            if (jvf->video_size || jvf->palette_size) {
                int ret;
                int size = jvf->video_size + jvf->palette_size;
                if (av_new_packet(pkt, size + JV_PREAMBLE_SIZE))
                    return AVERROR(ENOMEM);

                AV_WL32(pkt->data, jvf->video_size);
                pkt->data[4] = jvf->video_type;
                ret = avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size);
                if (ret < 0)
                    return ret;
                if (ret < size) {
                    memset(pkt->data + JV_PREAMBLE_SIZE + ret, 0,
                           FF_INPUT_BUFFER_PADDING_SIZE);
                    pkt->flags |= AV_PKT_FLAG_CORRUPT;
                }
                pkt->size         = ret + JV_PREAMBLE_SIZE;
                pkt->stream_index = 1;
                pkt->pts          = jv->pts;
                if (jvf->video_type != 1)
                    pkt->flags |= AV_PKT_FLAG_KEY;
                return 0;
            }
        case JV_PADDING:
            avio_skip(pb, FFMAX(e->size - jvf->audio_size - jvf->video_size
                                        - jvf->palette_size, 0));
            jv->state = JV_AUDIO;
            jv->pts++;
        }
    }

    if (s->pb->eof_reached)
        return AVERROR_EOF;

    return AVERROR(EIO);
}

static int read_seek(AVFormatContext *s, int stream_index,
                     int64_t ts, int flags)
{
    JVDemuxContext *jv = s->priv_data;
    AVStream *ast = s->streams[0];
    int i;

    if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME))
        return AVERROR(ENOSYS);

    switch (stream_index) {
    case 0:
        i = av_index_search_timestamp(ast, ts, flags);
        break;
    case 1:
        i = ts;
        break;
    default:
        return 0;
    }

    if (i < 0 || i >= ast->nb_index_entries)
        return 0;
    if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0)
        return -1;

    jv->state = JV_AUDIO;
    jv->pts   = i;
    return 0;
}

AVInputFormat ff_jv_demuxer = {
    .name           = "jv",
    .long_name      = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"),
    .priv_data_size = sizeof(JVDemuxContext),
    .read_probe     = read_probe,
    .read_header    = read_header,
    .read_packet    = read_packet,
    .read_seek      = read_seek,
    .read_close     = read_close,
};
