00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "avformat.h"
00024
00025 #define TXD_FILE 0x16
00026 #define TXD_INFO 0x01
00027 #define TXD_EXTRA 0x03
00028 #define TXD_TEXTURE 0x15
00029 #define TXD_TEXTURE_DATA 0x01
00030 #define TXD_MARKER 0x1803ffff
00031 #define TXD_MARKER2 0x1003ffff
00032
00033 static int txd_probe(AVProbeData * pd) {
00034 if (AV_RL32(pd->buf ) == TXD_FILE &&
00035 (AV_RL32(pd->buf+8) == TXD_MARKER || AV_RL32(pd->buf+8) == TXD_MARKER2))
00036 return AVPROBE_SCORE_MAX;
00037 return 0;
00038 }
00039
00040 static int txd_read_header(AVFormatContext *s) {
00041 AVStream *st;
00042
00043 st = avformat_new_stream(s, NULL);
00044 if (!st)
00045 return AVERROR(ENOMEM);
00046 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00047 st->codec->codec_id = AV_CODEC_ID_TXD;
00048 st->codec->time_base.den = 5;
00049 st->codec->time_base.num = 1;
00050
00051
00052 return 0;
00053 }
00054
00055 static int txd_read_packet(AVFormatContext *s, AVPacket *pkt) {
00056 AVIOContext *pb = s->pb;
00057 unsigned int id, chunk_size, marker;
00058 int ret;
00059
00060 next_chunk:
00061 id = avio_rl32(pb);
00062 chunk_size = avio_rl32(pb);
00063 marker = avio_rl32(pb);
00064
00065 if (url_feof(s->pb))
00066 return AVERROR_EOF;
00067 if (marker != TXD_MARKER && marker != TXD_MARKER2) {
00068 av_log(s, AV_LOG_ERROR, "marker does not match\n");
00069 return AVERROR_INVALIDDATA;
00070 }
00071
00072 switch (id) {
00073 case TXD_INFO:
00074 if (chunk_size > 100)
00075 break;
00076 case TXD_EXTRA:
00077 avio_skip(s->pb, chunk_size);
00078 case TXD_FILE:
00079 case TXD_TEXTURE:
00080 goto next_chunk;
00081 default:
00082 av_log(s, AV_LOG_ERROR, "unknown chunk id %i\n", id);
00083 return AVERROR_INVALIDDATA;
00084 }
00085
00086 ret = av_get_packet(s->pb, pkt, chunk_size);
00087 if (ret < 0)
00088 return ret;
00089 pkt->stream_index = 0;
00090
00091 return 0;
00092 }
00093
00094 AVInputFormat ff_txd_demuxer = {
00095 .name = "txd",
00096 .long_name = NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
00097 .read_probe = txd_probe,
00098 .read_header = txd_read_header,
00099 .read_packet = txd_read_packet,
00100 };