/*
 * 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 PAFDemuxContext {
    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(*p->blocks_count_table));
    p->frames_offset_table = av_mallocz(p->nb_frames *
                                        sizeof(*p->frames_offset_table));
    p->blocks_offset_table = av_mallocz(p->frame_blks *
                                        sizeof(*p->blocks_offset_table));

    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 (avio_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,
};
