static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    SmackerContext *smk = s->priv_data;

    int flags;

    int ret;

    int i;

    int frame_size = 0;

    int palchange = 0;



    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)

        return AVERROR_EOF;



    /* if we demuxed all streams, pass another frame */

    if(smk->curstream < 0) {

        avio_seek(s->pb, smk->nextpos, 0);

        frame_size = smk->frm_size[smk->cur_frame] & (~3);

        flags = smk->frm_flags[smk->cur_frame];

        /* handle palette change event */

        if(flags & SMACKER_PAL){

            int size, sz, t, off, j, pos;

            uint8_t *pal = smk->pal;

            uint8_t oldpal[768];



            memcpy(oldpal, pal, 768);

            size = avio_r8(s->pb);

            size = size * 4 - 1;

            frame_size -= size;

            frame_size--;

            sz = 0;

            pos = avio_tell(s->pb) + size;

            while(sz < 256){

                t = avio_r8(s->pb);

                if(t & 0x80){ /* skip palette entries */

                    sz += (t & 0x7F) + 1;

                    pal += ((t & 0x7F) + 1) * 3;

                } else if(t & 0x40){ /* copy with offset */

                    off = avio_r8(s->pb);

                    j = (t & 0x3F) + 1;

                    if (off + j > 0x100) {

                        av_log(s, AV_LOG_ERROR,

                               "Invalid palette update, offset=%d length=%d extends beyond palette size\n",

                               off, j);

                        return AVERROR_INVALIDDATA;

                    }

                    off *= 3;

                    while(j-- && sz < 256) {

                        *pal++ = oldpal[off + 0];

                        *pal++ = oldpal[off + 1];

                        *pal++ = oldpal[off + 2];

                        sz++;

                        off += 3;

                    }

                } else { /* new entries */

                    *pal++ = smk_pal[t];

                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];

                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];

                    sz++;

                }

            }

            avio_seek(s->pb, pos, 0);

            palchange |= 1;

        }

        flags >>= 1;

        smk->curstream = -1;

        /* if audio chunks are present, put them to stack and retrieve later */

        for(i = 0; i < 7; i++) {

            if(flags & 1) {

                int size;

                uint8_t *tmpbuf;



                size = avio_rl32(s->pb) - 4;

                frame_size -= size;

                frame_size -= 4;

                smk->curstream++;

                tmpbuf = av_realloc(smk->bufs[smk->curstream], size);

                if (!tmpbuf)

                    return AVERROR(ENOMEM);

                smk->bufs[smk->curstream] = tmpbuf;

                smk->buf_sizes[smk->curstream] = size;

                ret = avio_read(s->pb, smk->bufs[smk->curstream], size);

                if(ret != size)

                    return AVERROR(EIO);

                smk->stream_id[smk->curstream] = smk->indexes[i];

            }

            flags >>= 1;

        }

        if (frame_size < 0)

            return AVERROR_INVALIDDATA;

        if (av_new_packet(pkt, frame_size + 769))

            return AVERROR(ENOMEM);

        if(smk->frm_size[smk->cur_frame] & 1)

            palchange |= 2;

        pkt->data[0] = palchange;

        memcpy(pkt->data + 1, smk->pal, 768);

        ret = avio_read(s->pb, pkt->data + 769, frame_size);

        if(ret != frame_size)

            return AVERROR(EIO);

        pkt->stream_index = smk->videoindex;

        pkt->pts          = smk->cur_frame;

        pkt->size = ret + 769;

        smk->cur_frame++;

        smk->nextpos = avio_tell(s->pb);

    } else {

        if (av_new_packet(pkt, smk->buf_sizes[smk->curstream]))

            return AVERROR(ENOMEM);

        memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);

        pkt->size = smk->buf_sizes[smk->curstream];

        pkt->stream_index = smk->stream_id[smk->curstream];

        pkt->pts = smk->aud_pts[smk->curstream];

        smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);

        smk->curstream--;

    }



    return 0;

}

static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    SmackerContext *smk = s->priv_data;

    int flags;

    int ret;

    int i;

    int frame_size = 0;

    int palchange = 0;



    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)

        return AVERROR_EOF;



    

    if(smk->curstream < 0) {

        avio_seek(s->pb, smk->nextpos, 0);

        frame_size = smk->frm_size[smk->cur_frame] & (~3);

        flags = smk->frm_flags[smk->cur_frame];

        

        if(flags & SMACKER_PAL){

            int size, sz, t, off, j, pos;

            uint8_t *pal = smk->pal;

            uint8_t oldpal[768];



            memcpy(oldpal, pal, 768);

            size = avio_r8(s->pb);

            size = size * 4 - 1;

            frame_size -= size;

            frame_size--;

            sz = 0;

            pos = avio_tell(s->pb) + size;

            while(sz < 256){

                t = avio_r8(s->pb);

                if(t & 0x80){ 

                    sz += (t & 0x7F) + 1;

                    pal += ((t & 0x7F) + 1) * 3;

                } else if(t & 0x40){ 

                    off = avio_r8(s->pb);

                    j = (t & 0x3F) + 1;

                    if (off + j > 0x100) {

                        av_log(s, AV_LOG_ERROR,

                               "Invalid palette update, offset=%d length=%d extends beyond palette size\n",

                               off, j);

                        return AVERROR_INVALIDDATA;

                    }

                    off *= 3;

                    while(j-- && sz < 256) {

                        *pal++ = oldpal[off + 0];

                        *pal++ = oldpal[off + 1];

                        *pal++ = oldpal[off + 2];

                        sz++;

                        off += 3;

                    }

                } else { 

                    *pal++ = smk_pal[t];

                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];

                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];

                    sz++;

                }

            }

            avio_seek(s->pb, pos, 0);

            palchange |= 1;

        }

        flags >>= 1;

        smk->curstream = -1;

        

        for(i = 0; i < 7; i++) {

            if(flags & 1) {

                int size;

                uint8_t *tmpbuf;



                size = avio_rl32(s->pb) - 4;

                frame_size -= size;

                frame_size -= 4;

                smk->curstream++;

                tmpbuf = av_realloc(smk->bufs[smk->curstream], size);

                if (!tmpbuf)

                    return AVERROR(ENOMEM);

                smk->bufs[smk->curstream] = tmpbuf;

                smk->buf_sizes[smk->curstream] = size;

                ret = avio_read(s->pb, smk->bufs[smk->curstream], size);

                if(ret != size)

                    return AVERROR(EIO);

                smk->stream_id[smk->curstream] = smk->indexes[i];

            }

            flags >>= 1;

        }

        if (frame_size < 0)

            return AVERROR_INVALIDDATA;

        if (av_new_packet(pkt, frame_size + 769))

            return AVERROR(ENOMEM);

        if(smk->frm_size[smk->cur_frame] & 1)

            palchange |= 2;

        pkt->data[0] = palchange;

        memcpy(pkt->data + 1, smk->pal, 768);

        ret = avio_read(s->pb, pkt->data + 769, frame_size);

        if(ret != frame_size)

            return AVERROR(EIO);

        pkt->stream_index = smk->videoindex;

        pkt->pts          = smk->cur_frame;

        pkt->size = ret + 769;

        smk->cur_frame++;

        smk->nextpos = avio_tell(s->pb);

    } else {

        if (av_new_packet(pkt, smk->buf_sizes[smk->curstream]))

            return AVERROR(ENOMEM);

        memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);

        pkt->size = smk->buf_sizes[smk->curstream];

        pkt->stream_index = smk->stream_id[smk->curstream];

        pkt->pts = smk->aud_pts[smk->curstream];

        smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);

        smk->curstream--;

    }



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0, AVPacket *VAR_1)

{

    SmackerContext *smk = VAR_0->priv_data;

    int VAR_2;

    int VAR_3;

    int VAR_4;

    int VAR_5 = 0;

    int VAR_6 = 0;



    if (VAR_0->pb->eof_reached || smk->cur_frame >= smk->frames)

        return AVERROR_EOF;



    

    if(smk->curstream < 0) {

        avio_seek(VAR_0->pb, smk->nextpos, 0);

        VAR_5 = smk->frm_size[smk->cur_frame] & (~3);

        VAR_2 = smk->frm_flags[smk->cur_frame];

        

        if(VAR_2 & SMACKER_PAL){

            int VAR_13, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12;

            uint8_t *pal = smk->pal;

            uint8_t oldpal[768];



            memcpy(oldpal, pal, 768);

            VAR_13 = avio_r8(VAR_0->pb);

            VAR_13 = VAR_13 * 4 - 1;

            VAR_5 -= VAR_13;

            VAR_5--;

            VAR_8 = 0;

            VAR_12 = avio_tell(VAR_0->pb) + VAR_13;

            while(VAR_8 < 256){

                VAR_9 = avio_r8(VAR_0->pb);

                if(VAR_9 & 0x80){ 

                    VAR_8 += (VAR_9 & 0x7F) + 1;

                    pal += ((VAR_9 & 0x7F) + 1) * 3;

                } else if(VAR_9 & 0x40){ 

                    VAR_10 = avio_r8(VAR_0->pb);

                    VAR_11 = (VAR_9 & 0x3F) + 1;

                    if (VAR_10 + VAR_11 > 0x100) {

                        av_log(VAR_0, AV_LOG_ERROR,

                               "Invalid palette update, offset=%d length=%d extends beyond palette VAR_13\n",

                               VAR_10, VAR_11);

                        return AVERROR_INVALIDDATA;

                    }

                    VAR_10 *= 3;

                    while(VAR_11-- && VAR_8 < 256) {

                        *pal++ = oldpal[VAR_10 + 0];

                        *pal++ = oldpal[VAR_10 + 1];

                        *pal++ = oldpal[VAR_10 + 2];

                        VAR_8++;

                        VAR_10 += 3;

                    }

                } else { 

                    *pal++ = smk_pal[VAR_9];

                    *pal++ = smk_pal[avio_r8(VAR_0->pb) & 0x3F];

                    *pal++ = smk_pal[avio_r8(VAR_0->pb) & 0x3F];

                    VAR_8++;

                }

            }

            avio_seek(VAR_0->pb, VAR_12, 0);

            VAR_6 |= 1;

        }

        VAR_2 >>= 1;

        smk->curstream = -1;

        

        for(VAR_4 = 0; VAR_4 < 7; VAR_4++) {

            if(VAR_2 & 1) {

                int VAR_13;

                uint8_t *tmpbuf;



                VAR_13 = avio_rl32(VAR_0->pb) - 4;

                VAR_5 -= VAR_13;

                VAR_5 -= 4;

                smk->curstream++;

                tmpbuf = av_realloc(smk->bufs[smk->curstream], VAR_13);

                if (!tmpbuf)

                    return AVERROR(ENOMEM);

                smk->bufs[smk->curstream] = tmpbuf;

                smk->buf_sizes[smk->curstream] = VAR_13;

                VAR_3 = avio_read(VAR_0->pb, smk->bufs[smk->curstream], VAR_13);

                if(VAR_3 != VAR_13)

                    return AVERROR(EIO);

                smk->stream_id[smk->curstream] = smk->indexes[VAR_4];

            }

            VAR_2 >>= 1;

        }

        if (VAR_5 < 0)

            return AVERROR_INVALIDDATA;

        if (av_new_packet(VAR_1, VAR_5 + 769))

            return AVERROR(ENOMEM);

        if(smk->frm_size[smk->cur_frame] & 1)

            VAR_6 |= 2;

        VAR_1->data[0] = VAR_6;

        memcpy(VAR_1->data + 1, smk->pal, 768);

        VAR_3 = avio_read(VAR_0->pb, VAR_1->data + 769, VAR_5);

        if(VAR_3 != VAR_5)

            return AVERROR(EIO);

        VAR_1->stream_index = smk->videoindex;

        VAR_1->pts          = smk->cur_frame;

        VAR_1->VAR_13 = VAR_3 + 769;

        smk->cur_frame++;

        smk->nextpos = avio_tell(VAR_0->pb);

    } else {

        if (av_new_packet(VAR_1, smk->buf_sizes[smk->curstream]))

            return AVERROR(ENOMEM);

        memcpy(VAR_1->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);

        VAR_1->VAR_13 = smk->buf_sizes[smk->curstream];

        VAR_1->stream_index = smk->stream_id[smk->curstream];

        VAR_1->pts = smk->aud_pts[smk->curstream];

        smk->aud_pts[smk->curstream] += AV_RL32(VAR_1->data);

        smk->curstream--;

    }



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0, AVPacket *VAR_1)
{ SmackerContext *smk = VAR_0->priv_data; int VAR_2; int VAR_3; int VAR_4; int VAR_5 = 0; int VAR_6 = 0; if (VAR_0->pb->eof_reached || smk->cur_frame >= smk->frames)
return AVERROR_EOF; if(smk->curstream < 0) { avio_seek(VAR_0->pb, smk->nextpos, 0); VAR_5 = smk->frm_size[smk->cur_frame] & (~3); VAR_2 = smk->frm_flags[smk->cur_frame]; if(VAR_2 & SMACKER_PAL){ int VAR_13, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12; uint8_t *pal = smk->pal; uint8_t oldpal[768]; memcpy(oldpal, pal, 768); VAR_13 = avio_r8(VAR_0->pb); VAR_13 = VAR_13 * 4 - 1; VAR_5 -= VAR_13; VAR_5--; VAR_8 = 0; VAR_12 = avio_tell(VAR_0->pb) + VAR_13; while(VAR_8 < 256){ VAR_9 = avio_r8(VAR_0->pb); if(VAR_9 & 0x80){ VAR_8 += (VAR_9 & 0x7F) + 1; pal += ((VAR_9 & 0x7F) + 1) * 3; } else if(VAR_9 & 0x40){ VAR_10 = avio_r8(VAR_0->pb); VAR_11 = (VAR_9 & 0x3F) + 1; if (VAR_10 + VAR_11 > 0x100) { av_log(VAR_0, AV_LOG_ERROR,
"Invalid palette update, offset=%d length=%d extends beyond palette VAR_13\n",
VAR_10, VAR_11); return AVERROR_INVALIDDATA; } VAR_10 *= 3; while(VAR_11-- && VAR_8 < 256) { *pal++ = oldpal[VAR_10 + 0]; *pal++ = oldpal[VAR_10 + 1]; *pal++ = oldpal[VAR_10 + 2]; VAR_8++; VAR_10 += 3; } } else { *pal++ = smk_pal[VAR_9]; *pal++ = smk_pal[avio_r8(VAR_0->pb) & 0x3F]; *pal++ = smk_pal[avio_r8(VAR_0->pb) & 0x3F]; VAR_8++; } } avio_seek(VAR_0->pb, VAR_12, 0); VAR_6 |= 1; } VAR_2 >>= 1; smk->curstream = -1; for(VAR_4 = 0; VAR_4 < 7; VAR_4++) { if(VAR_2 & 1) { int VAR_13; uint8_t *tmpbuf; VAR_13 = avio_rl32(VAR_0->pb) - 4; VAR_5 -= VAR_13; VAR_5 -= 4; smk->curstream++; tmpbuf = av_realloc(smk->bufs[smk->curstream], VAR_13); if (!tmpbuf)
return AVERROR(ENOMEM); smk->bufs[smk->curstream] = tmpbuf; smk->buf_sizes[smk->curstream] = VAR_13; VAR_3 = avio_read(VAR_0->pb, smk->bufs[smk->curstream], VAR_13); if(VAR_3 != VAR_13)
return AVERROR(EIO); smk->stream_id[smk->curstream] = smk->indexes[VAR_4]; } VAR_2 >>= 1; } if (VAR_5 < 0)
return AVERROR_INVALIDDATA; if (av_new_packet(VAR_1, VAR_5 + 769))
return AVERROR(ENOMEM); if(smk->frm_size[smk->cur_frame] & 1)
VAR_6 |= 2; VAR_1->data[0] = VAR_6; memcpy(VAR_1->data + 1, smk->pal, 768); VAR_3 = avio_read(VAR_0->pb, VAR_1->data + 769, VAR_5); if(VAR_3 != VAR_5)
return AVERROR(EIO); VAR_1->stream_index = smk->videoindex; VAR_1->pts          = smk->cur_frame; VAR_1->VAR_13 = VAR_3 + 769; smk->cur_frame++; smk->nextpos = avio_tell(VAR_0->pb); } else { if (av_new_packet(VAR_1, smk->buf_sizes[smk->curstream]))
return AVERROR(ENOMEM); memcpy(VAR_1->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]); VAR_1->VAR_13 = smk->buf_sizes[smk->curstream]; VAR_1->stream_index = smk->stream_id[smk->curstream]; VAR_1->pts = smk->aud_pts[smk->curstream]; smk->aud_pts[smk->curstream] += AV_RL32(VAR_1->data); smk->curstream--; } return 0; }