/*
 * LucasArts Smush demuxer
 * Copyright (c) 2006 Cyril Zorin
 *
 * 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 "avio.h"
#include "internal.h"

typedef struct SMUSHContext {
    int version;
    int audio_stream_index;
    int video_stream_index;
} SMUSHContext;

static int smush_read_probe(AVProbeData *p)
{
    if (((AV_RL32(p->buf)     == MKTAG('S', 'A', 'N', 'M') &&
          AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) ||
         (AV_RL32(p->buf)     == MKTAG('A', 'N', 'I', 'M') &&
          AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) {
        return AVPROBE_SCORE_MAX;
    }

    return 0;
}

static int smush_read_header(AVFormatContext *ctx)
{
    SMUSHContext *smush = ctx->priv_data;
    AVIOContext *pb = ctx->pb;
    AVStream *vst, *ast;
    uint32_t magic, nframes, size, subversion, i;
    uint32_t width = 0, height = 0, got_audio = 0, read = 0;
    uint32_t sample_rate, channels, palette[256];

    magic = avio_rb32(pb);
    avio_skip(pb, 4); // skip movie size

    if (magic == MKBETAG('A', 'N', 'I', 'M')) {
        if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        if (size < 3 * 256 + 6)
            return AVERROR_INVALIDDATA;

        smush->version = 0;
        subversion     = avio_rl16(pb);
        nframes        = avio_rl16(pb);
        if (!nframes)
            return AVERROR_INVALIDDATA;

        avio_skip(pb, 2); // skip pad

        for (i = 0; i < 256; i++)
            palette[i] = avio_rb24(pb);

        avio_skip(pb, size - (3 * 256 + 6));
    } else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
        if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        if (size < 14)
            return AVERROR_INVALIDDATA;

        smush->version = 1;
        subversion = avio_rl16(pb);
        nframes = avio_rl32(pb);
        if (!nframes)
            return AVERROR_INVALIDDATA;

        avio_skip(pb, 2); // skip pad
        width  = avio_rl16(pb);
        height = avio_rl16(pb);
        avio_skip(pb, 2); // skip pad
        avio_skip(pb, size - 14);

        if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        while (!got_audio && ((read + 8) < size)) {
            uint32_t sig, chunk_size;

            if (avio_feof(pb))
                return AVERROR_EOF;

            sig        = avio_rb32(pb);
            chunk_size = avio_rb32(pb);
            read      += 8;
            switch (sig) {
            case MKBETAG('W', 'a', 'v', 'e'):
                got_audio = 1;
                sample_rate = avio_rl32(pb);
                if (!sample_rate)
                    return AVERROR_INVALIDDATA;

                channels = avio_rl32(pb);
                if (!channels)
                    return AVERROR_INVALIDDATA;

                avio_skip(pb, chunk_size - 8);
                read += chunk_size;
                break;
            case MKBETAG('B', 'l', '1', '6'):
            case MKBETAG('A', 'N', 'N', 'O'):
                avio_skip(pb, chunk_size);
                read += chunk_size;
                break;
            default:
                return AVERROR_INVALIDDATA;
                break;
            }
        }

        avio_skip(pb, size - read);
    } else {
        av_log(ctx, AV_LOG_ERROR, "Wrong magic\n");
        return AVERROR_INVALIDDATA;
    }

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

    smush->video_stream_index = vst->index;

    avpriv_set_pts_info(vst, 64, 1, 15);

    vst->start_time        = 0;
    vst->duration          =
    vst->nb_frames         = nframes;
    vst->avg_frame_rate    = av_inv_q(vst->time_base);
    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id   = AV_CODEC_ID_SANM;
    vst->codec->codec_tag  = 0;
    vst->codec->width      = width;
    vst->codec->height     = height;

    if (!smush->version) {
        if (ff_alloc_extradata(vst->codec, 1024 + 2))
            return AVERROR(ENOMEM);

        AV_WL16(vst->codec->extradata, subversion);
        for (i = 0; i < 256; i++)
            AV_WL32(vst->codec->extradata + 2 + i * 4, palette[i]);
    }

    if (got_audio) {
        ast = avformat_new_stream(ctx, 0);
        if (!ast)
            return AVERROR(ENOMEM);

        smush->audio_stream_index = ast->index;

        ast->start_time         = 0;
        ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
        ast->codec->codec_id    = AV_CODEC_ID_ADPCM_VIMA;
        ast->codec->codec_tag   = 0;
        ast->codec->sample_rate = sample_rate;
        ast->codec->channels    = channels;

        avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
    }

    return 0;
}

static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
{
    SMUSHContext *smush = ctx->priv_data;
    AVIOContext *pb = ctx->pb;
    int done = 0;
    int ret;

    while (!done) {
        uint32_t sig, size;

        if (avio_feof(pb))
            return AVERROR_EOF;

        sig  = avio_rb32(pb);
        size = avio_rb32(pb);

        switch (sig) {
        case MKBETAG('F', 'R', 'M', 'E'):
            if (smush->version)
                break;
            if ((ret = av_get_packet(pb, pkt, size)) < 0)
                return ret;

            pkt->stream_index = smush->video_stream_index;
            done = 1;
            break;
        case MKBETAG('B', 'l', '1', '6'):
            if ((ret = av_get_packet(pb, pkt, size)) < 0)
                return ret;

            pkt->stream_index = smush->video_stream_index;
            pkt->duration = 1;
            done = 1;
            break;
        case MKBETAG('W', 'a', 'v', 'e'):
            if (size < 13)
                return AVERROR_INVALIDDATA;
            if (av_get_packet(pb, pkt, size) < 13)
                return AVERROR(EIO);

            pkt->stream_index = smush->audio_stream_index;
            pkt->flags       |= AV_PKT_FLAG_KEY;
            pkt->duration     = AV_RB32(pkt->data);
            if (pkt->duration == 0xFFFFFFFFu)
                pkt->duration = AV_RB32(pkt->data + 8);
            done = 1;
            break;
        default:
            avio_skip(pb, size);
            break;
        }
    }

    return 0;
}

AVInputFormat ff_smush_demuxer = {
    .name           = "smush",
    .long_name      = NULL_IF_CONFIG_SMALL("LucasArts Smush"),
    .priv_data_size = sizeof(SMUSHContext),
    .read_probe     = smush_read_probe,
    .read_header    = smush_read_header,
    .read_packet    = smush_read_packet,
};
