* http://wiki.multimedia.cx/index.php?title=IFF
*/
+#include <inttypes.h>
+
+#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#define ID_8SVX MKTAG('8','S','V','X')
#define ID_VHDR MKTAG('V','H','D','R')
BITMAP_BYTERUN1
} bitmap_compression_type;
-typedef struct {
+typedef struct IffDemuxContext {
uint64_t body_pos;
uint32_t body_size;
uint32_t sent_bytes;
return 0;
}
-static int iff_read_header(AVFormatContext *s,
- AVFormatParameters *ap)
+static int iff_read_header(AVFormatContext *s)
{
IffDemuxContext *iff = s->priv_data;
AVIOContext *pb = s->pb;
if (!st)
return AVERROR(ENOMEM);
- st->codec->channels = 1;
+ st->codecpar->channels = 1;
+ st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
avio_skip(pb, 8);
// codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
- st->codec->codec_tag = avio_rl32(pb);
+ st->codecpar->codec_tag = avio_rl32(pb);
while(!pb->eof_reached) {
uint64_t orig_pos;
switch(chunk_id) {
case ID_VHDR:
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
if (data_size < 14)
return AVERROR_INVALIDDATA;
avio_skip(pb, 12);
- st->codec->sample_rate = avio_rb16(pb);
+ st->codecpar->sample_rate = avio_rb16(pb);
if (data_size >= 16) {
avio_skip(pb, 1);
compression = avio_r8(pb);
case ID_CHAN:
if (data_size < 4)
return AVERROR_INVALIDDATA;
- st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2;
+ if (avio_rb32(pb) < 6) {
+ st->codecpar->channels = 1;
+ st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
+ } else {
+ st->codecpar->channels = 2;
+ st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
+ }
break;
case ID_CMAP:
- st->codec->extradata_size = data_size;
- st->codec->extradata = av_malloc(data_size);
- if (!st->codec->extradata)
+ if (data_size < 3 || data_size > 768 || data_size % 3) {
+ av_log(s, AV_LOG_ERROR, "Invalid CMAP chunk size %"PRIu32"\n",
+ data_size);
+ return AVERROR_INVALIDDATA;
+ }
+ st->codecpar->extradata_size = data_size;
+ st->codecpar->extradata = av_malloc(data_size);
+ if (!st->codecpar->extradata)
return AVERROR(ENOMEM);
- if (avio_read(pb, st->codec->extradata, data_size) < 0)
+ if (avio_read(pb, st->codecpar->extradata, data_size) < 0)
return AVERROR(EIO);
break;
case ID_BMHD:
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
if (data_size <= 8)
return AVERROR_INVALIDDATA;
- st->codec->width = avio_rb16(pb);
- st->codec->height = avio_rb16(pb);
+ st->codecpar->width = avio_rb16(pb);
+ st->codecpar->height = avio_rb16(pb);
avio_skip(pb, 4); // x, y offset
- st->codec->bits_per_coded_sample = avio_r8(pb);
+ st->codecpar->bits_per_coded_sample = avio_r8(pb);
if (data_size >= 11) {
avio_skip(pb, 1); // masking
compression = avio_r8(pb);
}
if (data_size >= 16) {
- avio_skip(pb, 3); // paddding, transparent
+ avio_skip(pb, 3); // padding, transparent
st->sample_aspect_ratio.num = avio_r8(pb);
st->sample_aspect_ratio.den = avio_r8(pb);
}
avio_seek(pb, iff->body_pos, SEEK_SET);
- switch(st->codec->codec_type) {
+ switch(st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- av_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
switch(compression) {
case COMP_NONE:
- st->codec->codec_id = CODEC_ID_PCM_S8;
+ st->codecpar->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;
break;
case COMP_FIB:
- st->codec->codec_id = CODEC_ID_8SVX_FIB;
+ st->codecpar->codec_id = AV_CODEC_ID_8SVX_FIB;
break;
case COMP_EXP:
- st->codec->codec_id = CODEC_ID_8SVX_EXP;
+ st->codecpar->codec_id = AV_CODEC_ID_8SVX_EXP;
break;
default:
av_log(s, AV_LOG_ERROR, "unknown compression method\n");
return -1;
}
- st->codec->bits_per_coded_sample = 8;
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample;
- st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
+ st->codecpar->bits_per_coded_sample = 8;
+ st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * st->codecpar->bits_per_coded_sample;
+ st->codecpar->block_align = st->codecpar->channels * st->codecpar->bits_per_coded_sample;
break;
case AVMEDIA_TYPE_VIDEO:
switch (compression) {
case BITMAP_RAW:
- st->codec->codec_id = CODEC_ID_IFF_ILBM;
+ st->codecpar->codec_id = AV_CODEC_ID_IFF_ILBM;
break;
case BITMAP_BYTERUN1:
- st->codec->codec_id = CODEC_ID_IFF_BYTERUN1;
+ st->codecpar->codec_id = AV_CODEC_ID_IFF_BYTERUN1;
break;
default:
av_log(s, AV_LOG_ERROR, "unknown compression method\n");
}
AVInputFormat ff_iff_demuxer = {
- .name = "IFF",
- .long_name = NULL_IF_CONFIG_SMALL("IFF format"),
+ .name = "iff",
+ .long_name = NULL_IF_CONFIG_SMALL("IFF (Interchange File Format)"),
.priv_data_size = sizeof(IffDemuxContext),
.read_probe = iff_probe,
.read_header = iff_read_header,