static int iff_read_header(AVFormatContext *s)

{

    IffDemuxContext *iff = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st;

    uint8_t *buf;

    uint32_t chunk_id, data_size;

    uint32_t screenmode = 0, num, den;

    unsigned transparency = 0;

    unsigned masking = 0; // no mask

    uint8_t fmt[16];

    int fmt_size;



    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    st->codec->channels = 1;

    st->codec->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);



    while(!url_feof(pb)) {

        uint64_t orig_pos;

        int res;

        const char *metadata_tag = NULL;

        chunk_id = avio_rl32(pb);

        data_size = avio_rb32(pb);

        orig_pos = avio_tell(pb);



        switch(chunk_id) {

        case ID_VHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            if (data_size < 14)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 12);

            st->codec->sample_rate = avio_rb16(pb);

            if (data_size >= 16) {

                avio_skip(pb, 1);

                iff->svx8_compression = avio_r8(pb);

            }

            break;



        case ID_MHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            iff->maud_bits = -1;

            iff->maud_compression = -1;

            if (data_size < 32)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 4);

            iff->maud_bits = avio_rb16(pb);

            avio_skip(pb, 2);

            num = avio_rb32(pb);

            den = avio_rb16(pb);

            if (!den)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 2);

            st->codec->sample_rate = num / den;

            st->codec->channels = avio_rb16(pb);

            iff->maud_compression = avio_rb16(pb);

            if (st->codec->channels == 1)

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            else if (st->codec->channels == 2)

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            break;



        case ID_ABIT:

        case ID_BODY:

        case ID_DBOD:

        case ID_MDAT:

            iff->body_pos = avio_tell(pb);

            iff->body_size = data_size;

            break;



        case ID_CHAN:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            if (avio_rb32(pb) < 6) {

                st->codec->channels       = 1;

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            } else {

                st->codec->channels       = 2;

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            }

            break;



        case ID_CAMG:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            screenmode                = avio_rb32(pb);

            break;



        case ID_CMAP:

            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)

                return AVERROR(EIO);

            break;



        case ID_BMHD:

            iff->bitmap_compression = -1;

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size <= 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            avio_skip(pb, 4); // x, y offset

            st->codec->bits_per_coded_sample = avio_r8(pb);

            if (data_size >= 10)

                masking                      = avio_r8(pb);

            if (data_size >= 11)

                iff->bitmap_compression      = avio_r8(pb);

            if (data_size >= 14) {

                avio_skip(pb, 1); // padding

                transparency                 = avio_rb16(pb);

            }

            if (data_size >= 16) {

                st->sample_aspect_ratio.num  = avio_r8(pb);

                st->sample_aspect_ratio.den  = avio_r8(pb);

            }

            break;



        case ID_DPEL:

            if (data_size < 4 || (data_size & 3))

                return AVERROR_INVALIDDATA;

            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)

                return fmt_size;

            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))

                st->codec->pix_fmt = AV_PIX_FMT_RGB24;

            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))

                st->codec->pix_fmt = AV_PIX_FMT_RGBA;

            else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))

                st->codec->pix_fmt = AV_PIX_FMT_BGRA;

            else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))

                st->codec->pix_fmt = AV_PIX_FMT_ARGB;

            else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))

                st->codec->pix_fmt = AV_PIX_FMT_ABGR;

            else {

                av_log_ask_for_sample(s, "unsupported color format\n");

                return AVERROR_PATCHWELCOME;

            }

            break;



        case ID_DGBL:

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size < 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            iff->bitmap_compression          = avio_rb16(pb);

            st->sample_aspect_ratio.num      = avio_r8(pb);

            st->sample_aspect_ratio.den      = avio_r8(pb);

            st->codec->bits_per_coded_sample = 24;

            break;



        case ID_DLOC:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            st->codec->width  = avio_rb16(pb);

            st->codec->height = avio_rb16(pb);

            break;



        case ID_ANNO:

        case ID_TEXT:      metadata_tag = "comment";   break;

        case ID_AUTH:      metadata_tag = "artist";    break;

        case ID_COPYRIGHT: metadata_tag = "copyright"; break;

        case ID_NAME:      metadata_tag = "title";     break;

        }



        if (metadata_tag) {

            if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {

                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);

                return res;

            }

        }

        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));

    }



    avio_seek(pb, iff->body_pos, SEEK_SET);



    switch(st->codec->codec_type) {

    case AVMEDIA_TYPE_AUDIO:

        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);



        if (st->codec->codec_tag == ID_16SV)

            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;

        else if (st->codec->codec_tag == ID_MAUD) {

            if (iff->maud_bits == 8 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_U8;

            } else if (iff->maud_bits == 16 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) {

                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) {

                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;

            } else {

                av_log_ask_for_sample(s, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits);

                return AVERROR_PATCHWELCOME;

            }



            st->codec->bits_per_coded_sample =

                av_get_bits_per_sample(st->codec->codec_id);



            st->codec->block_align =

                st->codec->bits_per_coded_sample * st->codec->channels / 8;

        } else {

        switch (iff->svx8_compression) {

        case COMP_NONE:

            st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;

            break;

        case COMP_FIB:

            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;

            break;

        case COMP_EXP:

            st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;

            break;

        default:

            av_log(s, AV_LOG_ERROR,

                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);

            return -1;

        }

        }



        st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);

        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;

        break;



    case AVMEDIA_TYPE_VIDEO:

        iff->bpp          = st->codec->bits_per_coded_sample;

        if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {

            iff->ham      = iff->bpp > 6 ? 6 : 4;

            st->codec->bits_per_coded_sample = 24;

        }

        iff->flags        = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;

        iff->masking      = masking;

        iff->transparency = transparency;



        if (!st->codec->extradata) {

            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

        }

        buf = st->codec->extradata;

        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);

        bytestream_put_byte(&buf, iff->bitmap_compression);

        bytestream_put_byte(&buf, iff->bpp);

        bytestream_put_byte(&buf, iff->ham);

        bytestream_put_byte(&buf, iff->flags);

        bytestream_put_be16(&buf, iff->transparency);

        bytestream_put_byte(&buf, iff->masking);

        st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;

        break;

    default:

        return -1;

    }



    return 0;

}

static int iff_read_header(AVFormatContext *s)

{

    IffDemuxContext *iff = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st;

    uint8_t *buf;

    uint32_t chunk_id, data_size;

    uint32_t screenmode = 0, num, den;

    unsigned transparency = 0;

    unsigned masking = 0; 

    uint8_t fmt[16];

    int fmt_size;



    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    st->codec->channels = 1;

    st->codec->channel_layout = AV_CH_LAYOUT_MONO;

    avio_skip(pb, 8);

    

    st->codec->codec_tag = avio_rl32(pb);



    while(!url_feof(pb)) {

        uint64_t orig_pos;

        int res;

        const char *metadata_tag = NULL;

        chunk_id = avio_rl32(pb);

        data_size = avio_rb32(pb);

        orig_pos = avio_tell(pb);



        switch(chunk_id) {

        case ID_VHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            if (data_size < 14)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 12);

            st->codec->sample_rate = avio_rb16(pb);

            if (data_size >= 16) {

                avio_skip(pb, 1);

                iff->svx8_compression = avio_r8(pb);

            }

            break;



        case ID_MHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            iff->maud_bits = -1;

            iff->maud_compression = -1;

            if (data_size < 32)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 4);

            iff->maud_bits = avio_rb16(pb);

            avio_skip(pb, 2);

            num = avio_rb32(pb);

            den = avio_rb16(pb);

            if (!den)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 2);

            st->codec->sample_rate = num / den;

            st->codec->channels = avio_rb16(pb);

            iff->maud_compression = avio_rb16(pb);

            if (st->codec->channels == 1)

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            else if (st->codec->channels == 2)

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            break;



        case ID_ABIT:

        case ID_BODY:

        case ID_DBOD:

        case ID_MDAT:

            iff->body_pos = avio_tell(pb);

            iff->body_size = data_size;

            break;



        case ID_CHAN:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            if (avio_rb32(pb) < 6) {

                st->codec->channels       = 1;

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            } else {

                st->codec->channels       = 2;

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            }

            break;



        case ID_CAMG:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            screenmode                = avio_rb32(pb);

            break;



        case ID_CMAP:

            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)

                return AVERROR(EIO);

            break;



        case ID_BMHD:

            iff->bitmap_compression = -1;

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size <= 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            avio_skip(pb, 4); 

            st->codec->bits_per_coded_sample = avio_r8(pb);

            if (data_size >= 10)

                masking                      = avio_r8(pb);

            if (data_size >= 11)

                iff->bitmap_compression      = avio_r8(pb);

            if (data_size >= 14) {

                avio_skip(pb, 1); 

                transparency                 = avio_rb16(pb);

            }

            if (data_size >= 16) {

                st->sample_aspect_ratio.num  = avio_r8(pb);

                st->sample_aspect_ratio.den  = avio_r8(pb);

            }

            break;



        case ID_DPEL:

            if (data_size < 4 || (data_size & 3))

                return AVERROR_INVALIDDATA;

            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)

                return fmt_size;

            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))

                st->codec->pix_fmt = AV_PIX_FMT_RGB24;

            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))

                st->codec->pix_fmt = AV_PIX_FMT_RGBA;

            else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))

                st->codec->pix_fmt = AV_PIX_FMT_BGRA;

            else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))

                st->codec->pix_fmt = AV_PIX_FMT_ARGB;

            else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))

                st->codec->pix_fmt = AV_PIX_FMT_ABGR;

            else {

                av_log_ask_for_sample(s, "unsupported color format\n");

                return AVERROR_PATCHWELCOME;

            }

            break;



        case ID_DGBL:

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size < 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            iff->bitmap_compression          = avio_rb16(pb);

            st->sample_aspect_ratio.num      = avio_r8(pb);

            st->sample_aspect_ratio.den      = avio_r8(pb);

            st->codec->bits_per_coded_sample = 24;

            break;



        case ID_DLOC:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            st->codec->width  = avio_rb16(pb);

            st->codec->height = avio_rb16(pb);

            break;



        case ID_ANNO:

        case ID_TEXT:      metadata_tag = "comment";   break;

        case ID_AUTH:      metadata_tag = "artist";    break;

        case ID_COPYRIGHT: metadata_tag = "copyright"; break;

        case ID_NAME:      metadata_tag = "title";     break;

        }



        if (metadata_tag) {

            if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {

                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);

                return res;

            }

        }

        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));

    }



    avio_seek(pb, iff->body_pos, SEEK_SET);



    switch(st->codec->codec_type) {

    case AVMEDIA_TYPE_AUDIO:

        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);



        if (st->codec->codec_tag == ID_16SV)

            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;

        else if (st->codec->codec_tag == ID_MAUD) {

            if (iff->maud_bits == 8 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_U8;

            } else if (iff->maud_bits == 16 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) {

                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) {

                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;

            } else {

                av_log_ask_for_sample(s, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits);

                return AVERROR_PATCHWELCOME;

            }



            st->codec->bits_per_coded_sample =

                av_get_bits_per_sample(st->codec->codec_id);



            st->codec->block_align =

                st->codec->bits_per_coded_sample * st->codec->channels / 8;

        } else {

        switch (iff->svx8_compression) {

        case COMP_NONE:

            st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;

            break;

        case COMP_FIB:

            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;

            break;

        case COMP_EXP:

            st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;

            break;

        default:

            av_log(s, AV_LOG_ERROR,

                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);

            return -1;

        }

        }



        st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);

        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;

        break;



    case AVMEDIA_TYPE_VIDEO:

        iff->bpp          = st->codec->bits_per_coded_sample;

        if ((screenmode & 0x800 ) && iff->bpp <= 8) {

            iff->ham      = iff->bpp > 6 ? 6 : 4;

            st->codec->bits_per_coded_sample = 24;

        }

        iff->flags        = (screenmode & 0x80 ) && iff->bpp <= 8;

        iff->masking      = masking;

        iff->transparency = transparency;



        if (!st->codec->extradata) {

            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

        }

        buf = st->codec->extradata;

        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);

        bytestream_put_byte(&buf, iff->bitmap_compression);

        bytestream_put_byte(&buf, iff->bpp);

        bytestream_put_byte(&buf, iff->ham);

        bytestream_put_byte(&buf, iff->flags);

        bytestream_put_be16(&buf, iff->transparency);

        bytestream_put_byte(&buf, iff->masking);

        st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;

        break;

    default:

        return -1;

    }



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)

{

    IffDemuxContext *iff = VAR_0->priv_data;

    AVIOContext *pb = VAR_0->pb;

    AVStream *st;

    uint8_t *buf;

    uint32_t chunk_id, data_size;

    uint32_t screenmode = 0, num, den;

    unsigned VAR_1 = 0;

    unsigned VAR_2 = 0; 

    uint8_t fmt[16];

    int VAR_3;



    st = avformat_new_stream(VAR_0, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    st->codec->channels = 1;

    st->codec->channel_layout = AV_CH_LAYOUT_MONO;

    avio_skip(pb, 8);

    

    st->codec->codec_tag = avio_rl32(pb);



    while(!url_feof(pb)) {

        uint64_t orig_pos;

        int VAR_4;

        const char *VAR_5 = NULL;

        chunk_id = avio_rl32(pb);

        data_size = avio_rb32(pb);

        orig_pos = avio_tell(pb);



        switch(chunk_id) {

        case ID_VHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            if (data_size < 14)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 12);

            st->codec->sample_rate = avio_rb16(pb);

            if (data_size >= 16) {

                avio_skip(pb, 1);

                iff->svx8_compression = avio_r8(pb);

            }

            break;



        case ID_MHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;



            iff->maud_bits = -1;

            iff->maud_compression = -1;

            if (data_size < 32)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 4);

            iff->maud_bits = avio_rb16(pb);

            avio_skip(pb, 2);

            num = avio_rb32(pb);

            den = avio_rb16(pb);

            if (!den)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 2);

            st->codec->sample_rate = num / den;

            st->codec->channels = avio_rb16(pb);

            iff->maud_compression = avio_rb16(pb);

            if (st->codec->channels == 1)

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            else if (st->codec->channels == 2)

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            break;



        case ID_ABIT:

        case ID_BODY:

        case ID_DBOD:

        case ID_MDAT:

            iff->body_pos = avio_tell(pb);

            iff->body_size = data_size;

            break;



        case ID_CHAN:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            if (avio_rb32(pb) < 6) {

                st->codec->channels       = 1;

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            } else {

                st->codec->channels       = 2;

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            }

            break;



        case ID_CAMG:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            screenmode                = avio_rb32(pb);

            break;



        case ID_CMAP:

            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)

                return AVERROR(EIO);

            break;



        case ID_BMHD:

            iff->bitmap_compression = -1;

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size <= 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            avio_skip(pb, 4); 

            st->codec->bits_per_coded_sample = avio_r8(pb);

            if (data_size >= 10)

                VAR_2                      = avio_r8(pb);

            if (data_size >= 11)

                iff->bitmap_compression      = avio_r8(pb);

            if (data_size >= 14) {

                avio_skip(pb, 1); 

                VAR_1                 = avio_rb16(pb);

            }

            if (data_size >= 16) {

                st->sample_aspect_ratio.num  = avio_r8(pb);

                st->sample_aspect_ratio.den  = avio_r8(pb);

            }

            break;



        case ID_DPEL:

            if (data_size < 4 || (data_size & 3))

                return AVERROR_INVALIDDATA;

            if ((VAR_3 = avio_read(pb, fmt, sizeof(fmt))) < 0)

                return VAR_3;

            if (VAR_3 == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))

                st->codec->pix_fmt = AV_PIX_FMT_RGB24;

            else if (VAR_3 == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))

                st->codec->pix_fmt = AV_PIX_FMT_RGBA;

            else if (VAR_3 == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))

                st->codec->pix_fmt = AV_PIX_FMT_BGRA;

            else if (VAR_3 == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))

                st->codec->pix_fmt = AV_PIX_FMT_ARGB;

            else if (VAR_3 == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))

                st->codec->pix_fmt = AV_PIX_FMT_ABGR;

            else {

                av_log_ask_for_sample(VAR_0, "unsupported color format\n");

                return AVERROR_PATCHWELCOME;

            }

            break;



        case ID_DGBL:

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size < 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            iff->bitmap_compression          = avio_rb16(pb);

            st->sample_aspect_ratio.num      = avio_r8(pb);

            st->sample_aspect_ratio.den      = avio_r8(pb);

            st->codec->bits_per_coded_sample = 24;

            break;



        case ID_DLOC:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            st->codec->width  = avio_rb16(pb);

            st->codec->height = avio_rb16(pb);

            break;



        case ID_ANNO:

        case ID_TEXT:      VAR_5 = "comment";   break;

        case ID_AUTH:      VAR_5 = "artist";    break;

        case ID_COPYRIGHT: VAR_5 = "copyright"; break;

        case ID_NAME:      VAR_5 = "title";     break;

        }



        if (VAR_5) {

            if ((VAR_4 = get_metadata(VAR_0, VAR_5, data_size)) < 0) {

                av_log(VAR_0, AV_LOG_ERROR, "cannot allocate metadata tag %VAR_0!\n", VAR_5);

                return VAR_4;

            }

        }

        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));

    }



    avio_seek(pb, iff->body_pos, SEEK_SET);



    switch(st->codec->codec_type) {

    case AVMEDIA_TYPE_AUDIO:

        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);



        if (st->codec->codec_tag == ID_16SV)

            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;

        else if (st->codec->codec_tag == ID_MAUD) {

            if (iff->maud_bits == 8 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_U8;

            } else if (iff->maud_bits == 16 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) {

                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) {

                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;

            } else {

                av_log_ask_for_sample(VAR_0, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits);

                return AVERROR_PATCHWELCOME;

            }



            st->codec->bits_per_coded_sample =

                av_get_bits_per_sample(st->codec->codec_id);



            st->codec->block_align =

                st->codec->bits_per_coded_sample * st->codec->channels / 8;

        } else {

        switch (iff->svx8_compression) {

        case COMP_NONE:

            st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;

            break;

        case COMP_FIB:

            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;

            break;

        case COMP_EXP:

            st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;

            break;

        default:

            av_log(VAR_0, AV_LOG_ERROR,

                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);

            return -1;

        }

        }



        st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);

        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;

        break;



    case AVMEDIA_TYPE_VIDEO:

        iff->bpp          = st->codec->bits_per_coded_sample;

        if ((screenmode & 0x800 ) && iff->bpp <= 8) {

            iff->ham      = iff->bpp > 6 ? 6 : 4;

            st->codec->bits_per_coded_sample = 24;

        }

        iff->flags        = (screenmode & 0x80 ) && iff->bpp <= 8;

        iff->VAR_2      = VAR_2;

        iff->VAR_1 = VAR_1;



        if (!st->codec->extradata) {

            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

        }

        buf = st->codec->extradata;

        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);

        bytestream_put_byte(&buf, iff->bitmap_compression);

        bytestream_put_byte(&buf, iff->bpp);

        bytestream_put_byte(&buf, iff->ham);

        bytestream_put_byte(&buf, iff->flags);

        bytestream_put_be16(&buf, iff->VAR_1);

        bytestream_put_byte(&buf, iff->VAR_2);

        st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;

        break;

    default:

        return -1;

    }



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)
{ IffDemuxContext *iff = VAR_0->priv_data; AVIOContext *pb = VAR_0->pb; AVStream *st; uint8_t *buf; uint32_t chunk_id, data_size; uint32_t screenmode = 0, num, den; unsigned VAR_1 = 0; unsigned VAR_2 = 0; uint8_t fmt[16]; int VAR_3; st = avformat_new_stream(VAR_0, NULL); if (!st)
return AVERROR(ENOMEM); st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; avio_skip(pb, 8); st->codec->codec_tag = avio_rl32(pb); while(!url_feof(pb)) { uint64_t orig_pos; int VAR_4; const char *VAR_5 = NULL; chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); orig_pos = avio_tell(pb); switch(chunk_id) { case ID_VHDR:
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 14)
return AVERROR_INVALIDDATA; avio_skip(pb, 12); st->codec->sample_rate = avio_rb16(pb); if (data_size >= 16) { avio_skip(pb, 1); iff->svx8_compression = avio_r8(pb); } break; case ID_MHDR:
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; iff->maud_bits = -1; iff->maud_compression = -1; if (data_size < 32)
return AVERROR_INVALIDDATA; avio_skip(pb, 4); iff->maud_bits = avio_rb16(pb); avio_skip(pb, 2); num = avio_rb32(pb); den = avio_rb16(pb); if (!den)
return AVERROR_INVALIDDATA; avio_skip(pb, 2); st->codec->sample_rate = num / den; st->codec->channels = avio_rb16(pb); iff->maud_compression = avio_rb16(pb); if (st->codec->channels == 1)
st->codec->channel_layout = AV_CH_LAYOUT_MONO; else if (st->codec->channels == 2)
st->codec->channel_layout = AV_CH_LAYOUT_STEREO; break; case ID_ABIT:
case ID_BODY:
case ID_DBOD:
case ID_MDAT:
iff->body_pos = avio_tell(pb); iff->body_size = data_size; break; case ID_CHAN:
if (data_size < 4)
return AVERROR_INVALIDDATA; if (avio_rb32(pb) < 6) { st->codec->channels       = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; } else { st->codec->channels       = 2; st->codec->channel_layout = AV_CH_LAYOUT_STEREO; } break; case ID_CAMG:
if (data_size < 4)
return AVERROR_INVALIDDATA; screenmode                = avio_rb32(pb); break; case ID_CMAP:
st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata)
return AVERROR(ENOMEM); if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
return AVERROR(EIO); break; case ID_BMHD:
iff->bitmap_compression = -1; st->codec->codec_type            = AVMEDIA_TYPE_VIDEO; if (data_size <= 8)
return AVERROR_INVALIDDATA; st->codec->width                 = avio_rb16(pb); st->codec->height                = avio_rb16(pb); avio_skip(pb, 4); st->codec->bits_per_coded_sample = avio_r8(pb); if (data_size >= 10)
VAR_2                      = avio_r8(pb); if (data_size >= 11)
iff->bitmap_compression      = avio_r8(pb); if (data_size >= 14) { avio_skip(pb, 1); VAR_1                 = avio_rb16(pb); } if (data_size >= 16) { st->sample_aspect_ratio.num  = avio_r8(pb); st->sample_aspect_ratio.den  = avio_r8(pb); } break; case ID_DPEL:
if (data_size < 4 || (data_size & 3))
return AVERROR_INVALIDDATA; if ((VAR_3 = avio_read(pb, fmt, sizeof(fmt))) < 0)
return VAR_3; if (VAR_3 == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))
st->codec->pix_fmt = AV_PIX_FMT_RGB24; else if (VAR_3 == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))
st->codec->pix_fmt = AV_PIX_FMT_RGBA; else if (VAR_3 == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))
st->codec->pix_fmt = AV_PIX_FMT_BGRA; else if (VAR_3 == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))
st->codec->pix_fmt = AV_PIX_FMT_ARGB; else if (VAR_3 == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))
st->codec->pix_fmt = AV_PIX_FMT_ABGR; else { av_log_ask_for_sample(VAR_0, "unsupported color format\n"); return AVERROR_PATCHWELCOME; } break; case ID_DGBL:
st->codec->codec_type            = AVMEDIA_TYPE_VIDEO; if (data_size < 8)
return AVERROR_INVALIDDATA; st->codec->width                 = avio_rb16(pb); st->codec->height                = avio_rb16(pb); iff->bitmap_compression          = avio_rb16(pb); st->sample_aspect_ratio.num      = avio_r8(pb); st->sample_aspect_ratio.den      = avio_r8(pb); st->codec->bits_per_coded_sample = 24; break; case ID_DLOC:
if (data_size < 4)
return AVERROR_INVALIDDATA; st->codec->width  = avio_rb16(pb); st->codec->height = avio_rb16(pb); break; case ID_ANNO:
case ID_TEXT:      VAR_5 = "comment";   break; case ID_AUTH:      VAR_5 = "artist";    break; case ID_COPYRIGHT: VAR_5 = "copyright"; break; case ID_NAME:      VAR_5 = "title";     break; } if (VAR_5) { if ((VAR_4 = get_metadata(VAR_0, VAR_5, data_size)) < 0) { av_log(VAR_0, AV_LOG_ERROR, "cannot allocate metadata tag %VAR_0!\n", VAR_5); return VAR_4; } } avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); } avio_seek(pb, iff->body_pos, SEEK_SET); switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO:
avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); if (st->codec->codec_tag == ID_16SV)
st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR; else if (st->codec->codec_tag == ID_MAUD) { if (iff->maud_bits == 8 && !iff->maud_compression) { st->codec->codec_id = AV_CODEC_ID_PCM_U8; } else if (iff->maud_bits == 16 && !iff->maud_compression) { st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) { st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) { st->codec->codec_id = AV_CODEC_ID_PCM_MULAW; } else { av_log_ask_for_sample(VAR_0, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits); return AVERROR_PATCHWELCOME; } st->codec->bits_per_coded_sample =
av_get_bits_per_sample(st->codec->codec_id); st->codec->block_align =
st->codec->bits_per_coded_sample * st->codec->channels / 8; } else { switch (iff->svx8_compression) { case COMP_NONE:
st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR; break; case COMP_FIB:
st->codec->codec_id = AV_CODEC_ID_8SVX_FIB; break; case COMP_EXP:
st->codec->codec_id = AV_CODEC_ID_8SVX_EXP; break; default:
av_log(VAR_0, AV_LOG_ERROR,
"Unknown SVX8 compression method '%d'\n", iff->svx8_compression); return -1; } } st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); 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; break; case AVMEDIA_TYPE_VIDEO:
iff->bpp          = st->codec->bits_per_coded_sample; if ((screenmode & 0x800 ) && iff->bpp <= 8) { iff->ham      = iff->bpp > 6 ? 6 : 4; st->codec->bits_per_coded_sample = 24; } iff->flags        = (screenmode & 0x80 ) && iff->bpp <= 8; iff->VAR_2      = VAR_2; iff->VAR_1 = VAR_1; if (!st->codec->extradata) { st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE; st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata)
return AVERROR(ENOMEM); } buf = st->codec->extradata; bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); bytestream_put_byte(&buf, iff->bitmap_compression); bytestream_put_byte(&buf, iff->bpp); bytestream_put_byte(&buf, iff->ham); bytestream_put_byte(&buf, iff->flags); bytestream_put_be16(&buf, iff->VAR_1); bytestream_put_byte(&buf, iff->VAR_2); st->codec->codec_id = AV_CODEC_ID_IFF_ILBM; break; default:
return -1; } return 0; }