/*
 * Renderware TeXture Dictionary (.txd) demuxer
 * Copyright (c) 2007 Ivo van Poorten
 *
 * 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"

#define TXD_FILE            0x16
#define TXD_INFO            0x01
#define TXD_EXTRA           0x03
#define TXD_TEXTURE         0x15
#define TXD_TEXTURE_DATA    0x01
#define TXD_MARKER          0x1803ffff
#define TXD_MARKER2         0x1003ffff

static int txd_probe(AVProbeData * pd) {
    if (AV_RL32(pd->buf  ) == TXD_FILE &&
       (AV_RL32(pd->buf+8) == TXD_MARKER || AV_RL32(pd->buf+8) == TXD_MARKER2))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int txd_read_header(AVFormatContext *s, AVFormatParameters *ap) {
    AVStream *st;

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_TXD;
    st->codec->time_base.den = 5;
    st->codec->time_base.num = 1;
    /* the parameters will be extracted from the compressed bitstream */
    return 0;
}

static int txd_read_packet(AVFormatContext *s, AVPacket *pkt) {
    ByteIOContext *pb = s->pb;
    unsigned int id, chunk_size, marker;
    int ret;

next_chunk:
    id         = get_le32(pb);
    chunk_size = get_le32(pb);
    marker     = get_le32(pb);

    if (url_feof(s->pb))
        return AVERROR_EOF;
    if (marker != TXD_MARKER && marker != TXD_MARKER2) {
        av_log(s, AV_LOG_ERROR, "marker does not match\n");
        return AVERROR_INVALIDDATA;
    }

    switch (id) {
        case TXD_INFO:
            if (chunk_size > 100)
                break;
        case TXD_EXTRA:
            url_fskip(s->pb, chunk_size);
        case TXD_FILE:
        case TXD_TEXTURE:
            goto next_chunk;
        default:
            av_log(s, AV_LOG_ERROR, "unknown chunk id %i\n", id);
            return AVERROR_INVALIDDATA;
    }

    ret = av_get_packet(s->pb, pkt, chunk_size);
    if (ret < 0)
        return ret;
    pkt->stream_index = 0;

    return 0;
}

AVInputFormat txd_demuxer =
{
    "txd",
    NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
    0,
    txd_probe,
    txd_read_header,
    txd_read_packet,
};
