static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,

                      uint8_t block_type, AVFormatContext *s)

{

    uint8_t * vidbuf_start = NULL;

    int vidbuf_nbytes = 0;

    int code;

    int bytes_copied = 0;

    int position, duration, npixels;

    unsigned int vidbuf_capacity;

    int ret = 0;

    AVStream *st;



    if (vid->video_index < 0) {

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        vid->video_index = st->index;

        if (vid->audio_index < 0) {

            av_log_ask_for_sample(s, "No audio packet before first video "

                                  "packet. Using default video time base.\n");

        }

        avpriv_set_pts_info(st, 64, 185, vid->sample_rate);

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;

        st->codec->width      = vid->width;

        st->codec->height     = vid->height;

    }

    st      = s->streams[vid->video_index];

    npixels = st->codec->width * st->codec->height;



    vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE);

    if(!vidbuf_start)

        return AVERROR(ENOMEM);



    // save the file position for the packet, include block type

    position = avio_tell(pb) - 1;



    vidbuf_start[vidbuf_nbytes++] = block_type;



    // get the current packet duration

    duration = vid->bethsoft_global_delay + avio_rl16(pb);



    // set the y offset if it exists (decoder header data should be in data section)

    if(block_type == VIDEO_YOFF_P_FRAME){

        if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) {

            ret = AVERROR(EIO);

            goto fail;

        }

        vidbuf_nbytes += 2;

    }



    do{

        vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE);

        if(!vidbuf_start)

            return AVERROR(ENOMEM);



        code = avio_r8(pb);

        vidbuf_start[vidbuf_nbytes++] = code;



        if(code >= 0x80){ // rle sequence

            if(block_type == VIDEO_I_FRAME)

                vidbuf_start[vidbuf_nbytes++] = avio_r8(pb);

        } else if(code){ // plain sequence

            if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) {

                ret = AVERROR(EIO);

                goto fail;

            }

            vidbuf_nbytes += code;

        }

        bytes_copied += code & 0x7F;

        if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied

            // may contain a 0 byte even if read all pixels

            if(avio_r8(pb))

                avio_seek(pb, -1, SEEK_CUR);

            break;

        }

        if (bytes_copied > npixels) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }

    } while(code);



    // copy data into packet

    if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)

        goto fail;

    memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);

    av_free(vidbuf_start);



    pkt->pos = position;

    pkt->stream_index = vid->video_index;

    pkt->duration = duration;

    if (block_type == VIDEO_I_FRAME)

        pkt->flags |= AV_PKT_FLAG_KEY;



    /* if there is a new palette available, add it to packet side data */

    if (vid->palette) {

        uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,

                                                 BVID_PALETTE_SIZE);

        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);

        av_freep(&vid->palette);

    }



    vid->nframes--;  // used to check if all the frames were read

    return 0;

fail:

    av_free(vidbuf_start);

    return ret;

}

static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,

                      uint8_t block_type, AVFormatContext *s)

{

    uint8_t * vidbuf_start = NULL;

    int vidbuf_nbytes = 0;

    int code;

    int bytes_copied = 0;

    int position, duration, npixels;

    unsigned int vidbuf_capacity;

    int ret = 0;

    AVStream *st;



    if (vid->video_index < 0) {

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        vid->video_index = st->index;

        if (vid->audio_index < 0) {

            av_log_ask_for_sample(s, "No audio packet before first video "

                                  "packet. Using default video time base.\n");

        }

        avpriv_set_pts_info(st, 64, 185, vid->sample_rate);

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;

        st->codec->width      = vid->width;

        st->codec->height     = vid->height;

    }

    st      = s->streams[vid->video_index];

    npixels = st->codec->width * st->codec->height;



    vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE);

    if(!vidbuf_start)

        return AVERROR(ENOMEM);



    

    position = avio_tell(pb) - 1;



    vidbuf_start[vidbuf_nbytes++] = block_type;



    

    duration = vid->bethsoft_global_delay + avio_rl16(pb);



    

    if(block_type == VIDEO_YOFF_P_FRAME){

        if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) {

            ret = AVERROR(EIO);

            goto fail;

        }

        vidbuf_nbytes += 2;

    }



    do{

        vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE);

        if(!vidbuf_start)

            return AVERROR(ENOMEM);



        code = avio_r8(pb);

        vidbuf_start[vidbuf_nbytes++] = code;



        if(code >= 0x80){ 

            if(block_type == VIDEO_I_FRAME)

                vidbuf_start[vidbuf_nbytes++] = avio_r8(pb);

        } else if(code){ 

            if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) {

                ret = AVERROR(EIO);

                goto fail;

            }

            vidbuf_nbytes += code;

        }

        bytes_copied += code & 0x7F;

        if(bytes_copied == npixels){ 

            

            if(avio_r8(pb))

                avio_seek(pb, -1, SEEK_CUR);

            break;

        }

        if (bytes_copied > npixels) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }

    } while(code);



    

    if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)

        goto fail;

    memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);

    av_free(vidbuf_start);



    pkt->pos = position;

    pkt->stream_index = vid->video_index;

    pkt->duration = duration;

    if (block_type == VIDEO_I_FRAME)

        pkt->flags |= AV_PKT_FLAG_KEY;



    

    if (vid->palette) {

        uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,

                                                 BVID_PALETTE_SIZE);

        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);

        av_freep(&vid->palette);

    }



    vid->nframes--;  

    return 0;

fail:

    av_free(vidbuf_start);

    return ret;

}

        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
static int FUNC_0(BVID_DemuxContext *VAR_0, AVIOContext *VAR_1, AVPacket *VAR_2,

                      uint8_t VAR_3, AVFormatContext *VAR_4)

{

    uint8_t * vidbuf_start = NULL;

    int VAR_5 = 0;

    int VAR_6;

    int VAR_7 = 0;

    int VAR_8, VAR_9, VAR_10;

    unsigned int VAR_11;

    int VAR_12 = 0;

    AVStream *st;



    if (VAR_0->video_index < 0) {

        st = avformat_new_stream(VAR_4, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        VAR_0->video_index = st->index;

        if (VAR_0->audio_index < 0) {

            av_log_ask_for_sample(VAR_4, "No audio packet before first video "

                                  "packet. Using default video time base.\n");

        }

        avpriv_set_pts_info(st, 64, 185, VAR_0->sample_rate);

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;

        st->codec->width      = VAR_0->width;

        st->codec->height     = VAR_0->height;

    }

    st      = VAR_4->streams[VAR_0->video_index];

    VAR_10 = st->codec->width * st->codec->height;



    vidbuf_start = av_malloc(VAR_11 = BUFFER_PADDING_SIZE);

    if(!vidbuf_start)

        return AVERROR(ENOMEM);



    

    VAR_8 = avio_tell(VAR_1) - 1;



    vidbuf_start[VAR_5++] = VAR_3;



    

    VAR_9 = VAR_0->bethsoft_global_delay + avio_rl16(VAR_1);



    

    if(VAR_3 == VIDEO_YOFF_P_FRAME){

        if (avio_read(VAR_1, &vidbuf_start[VAR_5], 2) != 2) {

            VAR_12 = AVERROR(EIO);

            goto fail;

        }

        VAR_5 += 2;

    }



    do{

        vidbuf_start = av_fast_realloc(vidbuf_start, &VAR_11, VAR_5 + BUFFER_PADDING_SIZE);

        if(!vidbuf_start)

            return AVERROR(ENOMEM);



        VAR_6 = avio_r8(VAR_1);

        vidbuf_start[VAR_5++] = VAR_6;



        if(VAR_6 >= 0x80){ 

            if(VAR_3 == VIDEO_I_FRAME)

                vidbuf_start[VAR_5++] = avio_r8(VAR_1);

        } else if(VAR_6){ 

            if (avio_read(VAR_1, &vidbuf_start[VAR_5], VAR_6) != VAR_6) {

                VAR_12 = AVERROR(EIO);

                goto fail;

            }

            VAR_5 += VAR_6;

        }

        VAR_7 += VAR_6 & 0x7F;

        if(VAR_7 == VAR_10){ 

            

            if(avio_r8(VAR_1))

                avio_seek(VAR_1, -1, SEEK_CUR);

            break;

        }

        if (VAR_7 > VAR_10) {

            VAR_12 = AVERROR_INVALIDDATA;

            goto fail;

        }

    } while(VAR_6);



    

    if ((VAR_12 = av_new_packet(VAR_2, VAR_5)) < 0)

        goto fail;

    memcpy(VAR_2->data, vidbuf_start, VAR_5);

    av_free(vidbuf_start);



    VAR_2->pos = VAR_8;

    VAR_2->stream_index = VAR_0->video_index;

    VAR_2->VAR_9 = VAR_9;

    if (VAR_3 == VIDEO_I_FRAME)

        VAR_2->flags |= AV_PKT_FLAG_KEY;



    

    if (VAR_0->palette) {

        uint8_t *pdata = av_packet_new_side_data(VAR_2, AV_PKT_DATA_PALETTE,

                                                 BVID_PALETTE_SIZE);

        memcpy(pdata, VAR_0->palette, BVID_PALETTE_SIZE);

        av_freep(&VAR_0->palette);

    }



    VAR_0->nframes--;  

    return 0;

fail:

    av_free(vidbuf_start);

    return VAR_12;

}

static int FUNC_0(BVID_DemuxContext *VAR_0, AVIOContext *VAR_1, AVPacket *VAR_2,
uint8_t VAR_3, AVFormatContext *VAR_4)
{ uint8_t * vidbuf_start = NULL; int VAR_5 = 0; int VAR_6; int VAR_7 = 0; int VAR_8, VAR_9, VAR_10; unsigned int VAR_11; int VAR_12 = 0; AVStream *st; if (VAR_0->video_index < 0) { st = avformat_new_stream(VAR_4, NULL); if (!st)
return AVERROR(ENOMEM); VAR_0->video_index = st->index; if (VAR_0->audio_index < 0) { av_log_ask_for_sample(VAR_4, "No audio packet before first video "
"packet. Using default video time base.\n"); } avpriv_set_pts_info(st, 64, 185, VAR_0->sample_rate); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID; st->codec->width      = VAR_0->width; st->codec->height     = VAR_0->height; } st      = VAR_4->streams[VAR_0->video_index]; VAR_10 = st->codec->width * st->codec->height; vidbuf_start = av_malloc(VAR_11 = BUFFER_PADDING_SIZE); if(!vidbuf_start)
return AVERROR(ENOMEM); VAR_8 = avio_tell(VAR_1) - 1; vidbuf_start[VAR_5++] = VAR_3; VAR_9 = VAR_0->bethsoft_global_delay + avio_rl16(VAR_1); if(VAR_3 == VIDEO_YOFF_P_FRAME){ if (avio_read(VAR_1, &vidbuf_start[VAR_5], 2) != 2) { VAR_12 = AVERROR(EIO); goto fail; } VAR_5 += 2; } do{ vidbuf_start = av_fast_realloc(vidbuf_start, &VAR_11, VAR_5 + BUFFER_PADDING_SIZE); if(!vidbuf_start)
return AVERROR(ENOMEM); VAR_6 = avio_r8(VAR_1); vidbuf_start[VAR_5++] = VAR_6; if(VAR_6 >= 0x80){ if(VAR_3 == VIDEO_I_FRAME)
vidbuf_start[VAR_5++] = avio_r8(VAR_1); } else if(VAR_6){ if (avio_read(VAR_1, &vidbuf_start[VAR_5], VAR_6) != VAR_6) { VAR_12 = AVERROR(EIO); goto fail; } VAR_5 += VAR_6; } VAR_7 += VAR_6 & 0x7F; if(VAR_7 == VAR_10){ if(avio_r8(VAR_1))
avio_seek(VAR_1, -1, SEEK_CUR); break; } if (VAR_7 > VAR_10) { VAR_12 = AVERROR_INVALIDDATA; goto fail; } } while(VAR_6); if ((VAR_12 = av_new_packet(VAR_2, VAR_5)) < 0)
goto fail; memcpy(VAR_2->data, vidbuf_start, VAR_5); av_free(vidbuf_start); VAR_2->pos = VAR_8; VAR_2->stream_index = VAR_0->video_index; VAR_2->VAR_9 = VAR_9; if (VAR_3 == VIDEO_I_FRAME)
VAR_2->flags |= AV_PKT_FLAG_KEY; if (VAR_0->palette) { uint8_t *pdata = av_packet_new_side_data(VAR_2, AV_PKT_DATA_PALETTE,
BVID_PALETTE_SIZE); memcpy(pdata, VAR_0->palette, BVID_PALETTE_SIZE); av_freep(&VAR_0->palette); } VAR_0->nframes--; return 0; fail:
av_free(vidbuf_start); return VAR_12; }