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) {
                uint32_t size;
                int err;
                size = avio_rl32(s->pb) - 4;
                if (!size || size > frame_size) {
                    av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
                    return AVERROR_INVALIDDATA;
                }
                frame_size -= size;
                frame_size -= 4;
                smk->curstream++;
                if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
                    smk->buf_sizes[smk->curstream] = 0;
                    return err;
                }
                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 || frame_size >= INT_MAX/2)
            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 (smk->stream_id[smk->curstream] < 0)
            return AVERROR_INVALIDDATA;
        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)\n{\n    SmackerContext *smk = s->priv_data;\n    int flags;\n    int ret;\n    int i;\n    int frame_size = 0;\n    int palchange = 0;\n    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)\n        return AVERROR_EOF;\n    if(smk->curstream < 0) {\n        avio_seek(s->pb, smk->nextpos, 0);\n        frame_size = smk->frm_size[smk->cur_frame] & (~3);\n        flags = smk->frm_flags[smk->cur_frame];\n        if(flags & SMACKER_PAL){\n            int size, sz, t, off, j, pos;\n            uint8_t *pal = smk->pal;\n            uint8_t oldpal[768];\n            memcpy(oldpal, pal, 768);\n            size = avio_r8(s->pb);\n            size = size * 4 - 1;\n            frame_size -= size;\n            frame_size--;\n            sz = 0;\n            pos = avio_tell(s->pb) + size;\n            while(sz < 256){\n                t = avio_r8(s->pb);\n                if(t & 0x80){\n                    sz += (t & 0x7F) + 1;\n                    pal += ((t & 0x7F) + 1) * 3;\n                } else if(t & 0x40){\n                    off = avio_r8(s->pb);\n                    j = (t & 0x3F) + 1;\n                    if (off + j > 0x100) {\n                        av_log(s, AV_LOG_ERROR,\n                               "Invalid palette update, offset=%d length=%d extends beyond palette size\\n",\n                               off, j);\n                        return AVERROR_INVALIDDATA;\n                    }\n                    off *= 3;\n                    while(j-- && sz < 256) {\n                        *pal++ = oldpal[off + 0];\n                        *pal++ = oldpal[off + 1];\n                        *pal++ = oldpal[off + 2];\n                        sz++;\n                        off += 3;\n                    }\n                } else {\n                    *pal++ = smk_pal[t];\n                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];\n                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];\n                    sz++;\n                }\n            }\n            avio_seek(s->pb, pos, 0);\n            palchange |= 1;\n        }\n        flags >>= 1;\n        smk->curstream = -1;\n        for(i = 0; i < 7; i++) {\n            if(flags & 1) {\n                uint32_t size;\n                int err;\n                size = avio_rl32(s->pb) - 4;\n                if (!size || size > frame_size) {\n                    av_log(s, AV_LOG_ERROR, "Invalid audio part size\\n");\n                    return AVERROR_INVALIDDATA;\n                }\n                frame_size -= size;\n                frame_size -= 4;\n                smk->curstream++;\n                if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {\n                    smk->buf_sizes[smk->curstream] = 0;\n                    return err;\n                }\n                smk->buf_sizes[smk->curstream] = size;\n                ret = avio_read(s->pb, smk->bufs[smk->curstream], size);\n                if(ret != size)\n                    return AVERROR(EIO);\n                smk->stream_id[smk->curstream] = smk->indexes[i];\n            }\n            flags >>= 1;\n        }\n        if (frame_size < 0 || frame_size >= INT_MAX/2)\n            return AVERROR_INVALIDDATA;\n        if (av_new_packet(pkt, frame_size + 769))\n            return AVERROR(ENOMEM);\n        if(smk->frm_size[smk->cur_frame] & 1)\n            palchange |= 2;\n        pkt->data[0] = palchange;\n        memcpy(pkt->data + 1, smk->pal, 768);\n        ret = avio_read(s->pb, pkt->data + 769, frame_size);\n        if(ret != frame_size)\n            return AVERROR(EIO);\n        pkt->stream_index = smk->videoindex;\n        pkt->pts          = smk->cur_frame;\n        pkt->size = ret + 769;\n        smk->cur_frame++;\n        smk->nextpos = avio_tell(s->pb);\n    } else {\n        if (smk->stream_id[smk->curstream] < 0)\n            return AVERROR_INVALIDDATA;\n        if (av_new_packet(pkt, smk->buf_sizes[smk->curstream]))\n            return AVERROR(ENOMEM);\n        memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);\n        pkt->size = smk->buf_sizes[smk->curstream];\n        pkt->stream_index = smk->stream_id[smk->curstream];\n        pkt->pts = smk->aud_pts[smk->curstream];\n        smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);\n        smk->curstream--;\n    }\n    return 0;\n}', 'unsigned int avio_rl32(AVIOContext *s)\n{\n    unsigned int val;\n    val = avio_rl16(s);\n    val |= avio_rl16(s) << 16;\n    return val;\n}', 'unsigned int avio_rl16(AVIOContext *s)\n{\n    unsigned int val;\n    val = avio_r8(s);\n    val |= avio_r8(s) << 8;\n    return val;\n}', 'int avio_r8(AVIOContext *s)\n{\n    if (s->buf_ptr >= s->buf_end)\n        fill_buffer(s);\n    if (s->buf_ptr < s->buf_end)\n        return *s->buf_ptr++;\n    return 0;\n}', 'int av_reallocp(void *ptr, size_t size)\n{\n    void **ptrptr = ptr;\n    void *ret;\n    if (!size) {\n        av_freep(ptr);\n        return 0;\n    }\n    ret = av_realloc(*ptrptr, size);\n    if (!ret) {\n        av_freep(ptr);\n        return AVERROR(ENOMEM);\n    }\n    *ptrptr = ret;\n    return 0;\n}', 'void *av_realloc(void *ptr, size_t size)\n{\n#if CONFIG_MEMALIGN_HACK\n    int diff;\n#endif\n    if (size > (INT_MAX - 16))\n        return NULL;\n#if CONFIG_MEMALIGN_HACK\n    if (!ptr)\n        return av_malloc(size);\n    diff = ((char *)ptr)[-1];\n    return (char *)realloc((char *)ptr - diff, size + diff) + diff;\n#elif HAVE_ALIGNED_MALLOC\n    return _aligned_realloc(ptr, size, 32);\n#else\n    return realloc(ptr, size);\n#endif\n}']