/*
 * Packed Animation File demuxer
 * Copyright (c) 2012 Paul B Mahol
 *
 * 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/channel_layout.h"
#include "libavcodec/paf.h"
#include "avformat.h"
#include "internal.h"

#define MAGIC "Packed Animation File V1.0\n(c) 1992-96 Amazing Studio\x0a\x1a"

typedef struct {
    uint32_t buffer_size;
    uint32_t frame_blks;
    uint32_t nb_frames;
    uint32_t start_offset;
    uint32_t preload_count;
    uint32_t max_video_blks;
    uint32_t max_audio_blks;

    uint32_t current_frame;
    uint32_t current_frame_count;
    uint32_t current_frame_block;

    uint32_t *blocks_count_table;
    uint32_t *frames_offset_table;
    uint32_t *blocks_offset_table;

    uint8_t  *video_frame;
    int      video_size;

    uint8_t  *audio_frame;
    uint8_t  *temp_audio_frame;
    int      audio_size;

    int      got_audio;
} PAFDemuxContext;

static int read_probe(AVProbeData *p)
{
    if ((p->buf_size >= strlen(MAGIC)) &&
        !memcmp(p->buf, MAGIC, strlen(MAGIC)))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int read_close(AVFormatContext *s)
{
    PAFDemuxContext *p = s->priv_data;

    av_freep(&p->blocks_count_table);
    av_freep(&p->frames_offset_table);
    av_freep(&p->blocks_offset_table);
    av_freep(&p->video_frame);
    av_freep(&p->audio_frame);
    av_freep(&p->temp_audio_frame);

    return 0;
}

static void read_table(AVFormatContext *s, uint32_t *table, uint32_t count)
{
    int i;

    for (i = 0; i < count; i++)
        table[i] = avio_rl32(s->pb);

    avio_skip(s->pb, 4 * (FFALIGN(count, 512) - count));
}

static int read_header(AVFormatContext *s)
{
    PAFDemuxContext *p = s->priv_data;
    AVIOContext     *pb = s->pb;
    AVStream        *ast, *vst;
    int             ret = 0;

    avio_skip(pb, 132);

    vst = avformat_new_stream(s, 0);
    if (!vst)
        return AVERROR(ENOMEM);

    vst->start_time = 0;
    vst->nb_frames  =
    vst->duration   =
    p->nb_frames = avio_rl32(pb);
    avio_skip(pb, 4);
    vst->codec->width  = avio_rl32(pb);
    vst->codec->height = avio_rl32(pb);
    avio_skip(pb, 4);
    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_tag  = 0;
    vst->codec->codec_id   = AV_CODEC_ID_PAF_VIDEO;
    avpriv_set_pts_info(vst, 64, 1, 10);

    ast = avformat_new_stream(s, 0);
    if (!ast)
        return AVERROR(ENOMEM);

    ast->start_time         = 0;
    ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    ast->codec->codec_tag   = 0;
    ast->codec->codec_id    = AV_CODEC_ID_PAF_AUDIO;
    ast->codec->channels    = 2;
    ast->codec->channel_layout = AV_CH_LAYOUT_STEREO;
    ast->codec->sample_rate = 22050;
    avpriv_set_pts_info(ast, 64, 1, 22050);

    p->buffer_size    = avio_rl32(pb);
    p->preload_count  = avio_rl32(pb);
    p->frame_blks     = avio_rl32(pb);
    p->start_offset   = avio_rl32(pb);
    p->max_video_blks = avio_rl32(pb);
    p->max_audio_blks = avio_rl32(pb);
    if (p->buffer_size    < 175  ||
        p->max_audio_blks < 2    ||
        p->max_video_blks < 1    ||
        p->frame_blks     < 1    ||
        p->nb_frames      < 1    ||
        p->preload_count  < 1    ||
        p->buffer_size    > 2048 ||
        p->max_video_blks > 2048 ||
        p->max_audio_blks > 2048 ||
        p->nb_frames      > INT_MAX / sizeof(uint32_t) ||
        p->frame_blks     > INT_MAX / sizeof(uint32_t))
        return AVERROR_INVALIDDATA;

    p->blocks_count_table  = av_mallocz(p->nb_frames  * sizeof(uint32_t));
    p->frames_offset_table = av_mallocz(p->nb_frames  * sizeof(uint32_t));
    p->blocks_offset_table = av_mallocz(p->frame_blks * sizeof(uint32_t));

    p->video_size          = p->max_video_blks * p->buffer_size;
    p->video_frame         = av_mallocz(p->video_size);

    p->audio_size          = p->max_audio_blks * p->buffer_size;
    p->audio_frame         = av_mallocz(p->audio_size);
    p->temp_audio_frame    = av_mallocz(p->audio_size);

    if (!p->blocks_count_table  ||
        !p->frames_offset_table ||
        !p->blocks_offset_table ||
        !p->video_frame         ||
        !p->audio_frame         ||
        !p->temp_audio_frame) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    avio_seek(pb, p->buffer_size, SEEK_SET);

    read_table(s, p->blocks_count_table,  p->nb_frames);
    read_table(s, p->frames_offset_table, p->nb_frames);
    read_table(s, p->blocks_offset_table, p->frame_blks);

    p->got_audio = 0;
    p->current_frame = 0;
    p->current_frame_block = 0;

    avio_seek(pb, p->start_offset, SEEK_SET);

    return 0;

fail:
    read_close(s);

    return ret;
}

static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    PAFDemuxContext *p = s->priv_data;
    AVIOContext     *pb = s->pb;
    uint32_t        count, offset;
    int             size, i;

    if (p->current_frame >= p->nb_frames)
        return AVERROR_EOF;

    if (url_feof(pb))
        return AVERROR_EOF;

    if (p->got_audio) {
        if (av_new_packet(pkt, p->audio_size) < 0)
            return AVERROR(ENOMEM);

        memcpy(pkt->data, p->temp_audio_frame, p->audio_size);
        pkt->duration     = PAF_SOUND_SAMPLES * (p->audio_size / PAF_SOUND_FRAME_SIZE);
        pkt->flags       |= AV_PKT_FLAG_KEY;
        pkt->stream_index = 1;
        p->got_audio      = 0;
        return pkt->size;
    }

    count = (p->current_frame == 0) ? p->preload_count : p->blocks_count_table[p->current_frame - 1];
    for (i = 0; i < count; i++) {
        if (p->current_frame_block >= p->frame_blks)
            return AVERROR_INVALIDDATA;

        offset = p->blocks_offset_table[p->current_frame_block] & ~(1U << 31);
        if (p->blocks_offset_table[p->current_frame_block] & (1U << 31)) {
            if (offset > p->audio_size - p->buffer_size)
                return AVERROR_INVALIDDATA;

            avio_read(pb, p->audio_frame + offset, p->buffer_size);
            if (offset == (p->max_audio_blks - 2) * p->buffer_size) {
                memcpy(p->temp_audio_frame, p->audio_frame, p->audio_size);
                p->got_audio = 1;
            }
        } else {
            if (offset > p->video_size - p->buffer_size)
                return AVERROR_INVALIDDATA;

            avio_read(pb, p->video_frame + offset, p->buffer_size);
        }
        p->current_frame_block++;
    }

    if (p->frames_offset_table[p->current_frame] >= p->video_size)
        return AVERROR_INVALIDDATA;

    size = p->video_size - p->frames_offset_table[p->current_frame];

    if (av_new_packet(pkt, size) < 0)
        return AVERROR(ENOMEM);

    pkt->stream_index = 0;
    pkt->duration     = 1;
    memcpy(pkt->data, p->video_frame + p->frames_offset_table[p->current_frame], size);
    if (pkt->data[0] & 0x20)
        pkt->flags   |= AV_PKT_FLAG_KEY;
    p->current_frame++;

    return pkt->size;
}

AVInputFormat ff_paf_demuxer = {
    .name           = "paf",
    .long_name      = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File"),
    .priv_data_size = sizeof(PAFDemuxContext),
    .read_probe     = read_probe,
    .read_header    = read_header,
    .read_packet    = read_packet,
    .read_close     = read_close,
};
