static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)

{

    SmackVContext * const smk = avctx->priv_data;

    uint8_t *out;

    uint32_t *pal;

    GetBitContext gb;

    int blocks, blk, bw, bh;

    int i;

    int stride;



    if(buf_size == 769)

        return 0;

    if(smk->pic.data[0])

            avctx->release_buffer(avctx, &smk->pic);



    smk->pic.reference = 1;

    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;

    if(avctx->reget_buffer(avctx, &smk->pic) < 0){

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return -1;

    }



    /* make the palette available on the way out */

    pal = (uint32_t*)smk->pic.data[1];

    smk->pic.palette_has_changed = buf[0] & 1;

    smk->pic.key_frame = !!(buf[0] & 2);

    if(smk->pic.key_frame)

        smk->pic.pict_type = FF_I_TYPE;

    else

        smk->pic.pict_type = FF_P_TYPE;



    buf++;

    for(i = 0; i < 256; i++)

        *pal++ = bytestream_get_be24(&buf);

    buf_size -= 769;



    last_reset(smk->mmap_tbl, smk->mmap_last);

    last_reset(smk->mclr_tbl, smk->mclr_last);

    last_reset(smk->full_tbl, smk->full_last);

    last_reset(smk->type_tbl, smk->type_last);

    init_get_bits(&gb, buf, buf_size * 8);



    blk = 0;

    bw = avctx->width >> 2;

    bh = avctx->height >> 2;

    blocks = bw * bh;

    out = smk->pic.data[0];

    stride = smk->pic.linesize[0];

    while(blk < blocks) {

        int type, run, mode;

        uint16_t pix;



        type = smk_get_code(&gb, smk->type_tbl, smk->type_last);

        run = block_runs[(type >> 2) & 0x3F];

        switch(type & 3){

        case SMK_BLK_MONO:

            while(run-- && blk < blocks){

                int clr, map;

                int hi, lo;

                clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);

                map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                hi = clr >> 8;

                lo = clr & 0xFF;

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

                    if(map & 1) out[0] = hi; else out[0] = lo;

                    if(map & 2) out[1] = hi; else out[1] = lo;

                    if(map & 4) out[2] = hi; else out[2] = lo;

                    if(map & 8) out[3] = hi; else out[3] = lo;

                    map >>= 4;

                    out += stride;

                }

                blk++;

            }

            break;

        case SMK_BLK_FULL:

            mode = 0;

            if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes

                if(get_bits1(&gb)) mode = 1;

                else if(get_bits1(&gb)) mode = 2;

            }

            while(run-- && blk < blocks){

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                switch(mode){

                case 0:

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

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out+2,pix);

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix);

                        out += stride;

                    }

                    break;

                case 1:

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    break;

                case 2:

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

                        uint16_t pix1, pix2;

                        pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += stride;

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += stride;

                    }

                    break;

                }

                blk++;

            }

            break;

        case SMK_BLK_SKIP:

            while(run-- && blk < blocks)

                blk++;

            break;

        case SMK_BLK_FILL:

            mode = type >> 8;

            while(run-- && blk < blocks){

                uint32_t col;

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                col = mode * 0x01010101;

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

                    *((uint32_t*)out) = col;

                    out += stride;

                }

                blk++;

            }

            break;

        }



    }



    *data_size = sizeof(AVFrame);

    *(AVFrame*)data = smk->pic;



    /* always report that the buffer was completely consumed */

    return buf_size;

}

static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)

{

    SmackVContext * const smk = avctx->priv_data;

    uint8_t *out;

    uint32_t *pal;

    GetBitContext gb;

    int blocks, blk, bw, bh;

    int i;

    int stride;



    if(buf_size == 769)

        return 0;

    if(smk->pic.data[0])

            avctx->release_buffer(avctx, &smk->pic);



    smk->pic.reference = 1;

    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;

    if(avctx->reget_buffer(avctx, &smk->pic) < 0){

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return -1;

    }



    

    pal = (uint32_t*)smk->pic.data[1];

    smk->pic.palette_has_changed = buf[0] & 1;

    smk->pic.key_frame = !!(buf[0] & 2);

    if(smk->pic.key_frame)

        smk->pic.pict_type = FF_I_TYPE;

    else

        smk->pic.pict_type = FF_P_TYPE;



    buf++;

    for(i = 0; i < 256; i++)

        *pal++ = bytestream_get_be24(&buf);

    buf_size -= 769;



    last_reset(smk->mmap_tbl, smk->mmap_last);

    last_reset(smk->mclr_tbl, smk->mclr_last);

    last_reset(smk->full_tbl, smk->full_last);

    last_reset(smk->type_tbl, smk->type_last);

    init_get_bits(&gb, buf, buf_size * 8);



    blk = 0;

    bw = avctx->width >> 2;

    bh = avctx->height >> 2;

    blocks = bw * bh;

    out = smk->pic.data[0];

    stride = smk->pic.linesize[0];

    while(blk < blocks) {

        int type, run, mode;

        uint16_t pix;



        type = smk_get_code(&gb, smk->type_tbl, smk->type_last);

        run = block_runs[(type >> 2) & 0x3F];

        switch(type & 3){

        case SMK_BLK_MONO:

            while(run-- && blk < blocks){

                int clr, map;

                int hi, lo;

                clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);

                map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                hi = clr >> 8;

                lo = clr & 0xFF;

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

                    if(map & 1) out[0] = hi; else out[0] = lo;

                    if(map & 2) out[1] = hi; else out[1] = lo;

                    if(map & 4) out[2] = hi; else out[2] = lo;

                    if(map & 8) out[3] = hi; else out[3] = lo;

                    map >>= 4;

                    out += stride;

                }

                blk++;

            }

            break;

        case SMK_BLK_FULL:

            mode = 0;

            if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { 

                if(get_bits1(&gb)) mode = 1;

                else if(get_bits1(&gb)) mode = 2;

            }

            while(run-- && blk < blocks){

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                switch(mode){

                case 0:

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

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out+2,pix);

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix);

                        out += stride;

                    }

                    break;

                case 1:

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += stride;

                    break;

                case 2:

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

                        uint16_t pix1, pix2;

                        pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += stride;

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += stride;

                    }

                    break;

                }

                blk++;

            }

            break;

        case SMK_BLK_SKIP:

            while(run-- && blk < blocks)

                blk++;

            break;

        case SMK_BLK_FILL:

            mode = type >> 8;

            while(run-- && blk < blocks){

                uint32_t col;

                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;

                col = mode * 0x01010101;

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

                    *((uint32_t*)out) = col;

                    out += stride;

                }

                blk++;

            }

            break;

        }



    }



    *data_size = sizeof(AVFrame);

    *(AVFrame*)data = smk->pic;



    

    return buf_size;

}

    if(buf_size == 769)
static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1, int *VAR_2, const uint8_t *VAR_3, int VAR_4)

{

    SmackVContext * const smk = VAR_0->priv_data;

    uint8_t *out;

    uint32_t *pal;

    GetBitContext gb;

    int VAR_5, VAR_6, VAR_7, VAR_8;

    int VAR_9;

    int VAR_10;



    if(VAR_4 == 769)

        return 0;

    if(smk->pic.VAR_1[0])

            VAR_0->release_buffer(VAR_0, &smk->pic);



    smk->pic.reference = 1;

    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;

    if(VAR_0->reget_buffer(VAR_0, &smk->pic) < 0){

        av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n");

        return -1;

    }



    

    pal = (uint32_t*)smk->pic.VAR_1[1];

    smk->pic.palette_has_changed = VAR_3[0] & 1;

    smk->pic.key_frame = !!(VAR_3[0] & 2);

    if(smk->pic.key_frame)

        smk->pic.pict_type = FF_I_TYPE;

    else

        smk->pic.pict_type = FF_P_TYPE;



    VAR_3++;

    for(VAR_9 = 0; VAR_9 < 256; VAR_9++)

        *pal++ = bytestream_get_be24(&VAR_3);

    VAR_4 -= 769;



    last_reset(smk->mmap_tbl, smk->mmap_last);

    last_reset(smk->mclr_tbl, smk->mclr_last);

    last_reset(smk->full_tbl, smk->full_last);

    last_reset(smk->type_tbl, smk->type_last);

    init_get_bits(&gb, VAR_3, VAR_4 * 8);



    VAR_6 = 0;

    VAR_7 = VAR_0->width >> 2;

    VAR_8 = VAR_0->height >> 2;

    VAR_5 = VAR_7 * VAR_8;

    out = smk->pic.VAR_1[0];

    VAR_10 = smk->pic.linesize[0];

    while(VAR_6 < VAR_5) {

        int VAR_11, VAR_12, VAR_13;

        uint16_t pix;



        VAR_11 = smk_get_code(&gb, smk->type_tbl, smk->type_last);

        VAR_12 = block_runs[(VAR_11 >> 2) & 0x3F];

        switch(VAR_11 & 3){

        case SMK_BLK_MONO:

            while(VAR_12-- && VAR_6 < VAR_5){

                int VAR_14, VAR_15;

                int VAR_16, VAR_17;

                VAR_14 = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);

                VAR_15 = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);

                out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4;

                VAR_16 = VAR_14 >> 8;

                VAR_17 = VAR_14 & 0xFF;

                for(VAR_9 = 0; VAR_9 < 4; VAR_9++) {

                    if(VAR_15 & 1) out[0] = VAR_16; else out[0] = VAR_17;

                    if(VAR_15 & 2) out[1] = VAR_16; else out[1] = VAR_17;

                    if(VAR_15 & 4) out[2] = VAR_16; else out[2] = VAR_17;

                    if(VAR_15 & 8) out[3] = VAR_16; else out[3] = VAR_17;

                    VAR_15 >>= 4;

                    out += VAR_10;

                }

                VAR_6++;

            }

            break;

        case SMK_BLK_FULL:

            VAR_13 = 0;

            if(VAR_0->codec_tag == MKTAG('S', 'M', 'K', '4')) { 

                if(get_bits1(&gb)) VAR_13 = 1;

                else if(get_bits1(&gb)) VAR_13 = 2;

            }

            while(VAR_12-- && VAR_6 < VAR_5){

                out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4;

                switch(VAR_13){

                case 0:

                    for(VAR_9 = 0; VAR_9 < 4; VAR_9++) {

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out+2,pix);

                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix);

                        out += VAR_10;

                    }

                    break;

                case 1:

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += VAR_10;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += VAR_10;

                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += VAR_10;

                    out[0] = out[1] = pix & 0xFF;

                    out[2] = out[3] = pix >> 8;

                    out += VAR_10;

                    break;

                case 2:

                    for(VAR_9 = 0; VAR_9 < 2; VAR_9++) {

                        uint16_t pix1, pix2;

                        pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last);

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += VAR_10;

                        AV_WL16(out,pix1);

                        AV_WL16(out+2,pix2);

                        out += VAR_10;

                    }

                    break;

                }

                VAR_6++;

            }

            break;

        case SMK_BLK_SKIP:

            while(VAR_12-- && VAR_6 < VAR_5)

                VAR_6++;

            break;

        case SMK_BLK_FILL:

            VAR_13 = VAR_11 >> 8;

            while(VAR_12-- && VAR_6 < VAR_5){

                uint32_t col;

                out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4;

                col = VAR_13 * 0x01010101;

                for(VAR_9 = 0; VAR_9 < 4; VAR_9++) {

                    *((uint32_t*)out) = col;

                    out += VAR_10;

                }

                VAR_6++;

            }

            break;

        }



    }



    *VAR_2 = sizeof(AVFrame);

    *(AVFrame*)VAR_1 = smk->pic;



    

    return VAR_4;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1, int *VAR_2, const uint8_t *VAR_3, int VAR_4)
{ SmackVContext * const smk = VAR_0->priv_data; uint8_t *out; uint32_t *pal; GetBitContext gb; int VAR_5, VAR_6, VAR_7, VAR_8; int VAR_9; int VAR_10; if(VAR_4 == 769)
return 0; if(smk->pic.VAR_1[0])
VAR_0->release_buffer(VAR_0, &smk->pic); smk->pic.reference = 1; smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if(VAR_0->reget_buffer(VAR_0, &smk->pic) < 0){ av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } pal = (uint32_t*)smk->pic.VAR_1[1]; smk->pic.palette_has_changed = VAR_3[0] & 1; smk->pic.key_frame = !!(VAR_3[0] & 2); if(smk->pic.key_frame)
smk->pic.pict_type = FF_I_TYPE; else
smk->pic.pict_type = FF_P_TYPE; VAR_3++; for(VAR_9 = 0; VAR_9 < 256; VAR_9++) *pal++ = bytestream_get_be24(&VAR_3); VAR_4 -= 769; last_reset(smk->mmap_tbl, smk->mmap_last); last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); init_get_bits(&gb, VAR_3, VAR_4 * 8); VAR_6 = 0; VAR_7 = VAR_0->width >> 2; VAR_8 = VAR_0->height >> 2; VAR_5 = VAR_7 * VAR_8; out = smk->pic.VAR_1[0]; VAR_10 = smk->pic.linesize[0]; while(VAR_6 < VAR_5) { int VAR_11, VAR_12, VAR_13; uint16_t pix; VAR_11 = smk_get_code(&gb, smk->type_tbl, smk->type_last); VAR_12 = block_runs[(VAR_11 >> 2) & 0x3F]; switch(VAR_11 & 3){ case SMK_BLK_MONO:
while(VAR_12-- && VAR_6 < VAR_5){ int VAR_14, VAR_15; int VAR_16, VAR_17; VAR_14 = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); VAR_15 = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4; VAR_16 = VAR_14 >> 8; VAR_17 = VAR_14 & 0xFF; for(VAR_9 = 0; VAR_9 < 4; VAR_9++) { if(VAR_15 & 1) out[0] = VAR_16; else out[0] = VAR_17; if(VAR_15 & 2) out[1] = VAR_16; else out[1] = VAR_17; if(VAR_15 & 4) out[2] = VAR_16; else out[2] = VAR_17; if(VAR_15 & 8) out[3] = VAR_16; else out[3] = VAR_17; VAR_15 >>= 4; out += VAR_10; } VAR_6++; } break; case SMK_BLK_FULL:
VAR_13 = 0; if(VAR_0->codec_tag == MKTAG('S', 'M', 'K', '4')) { if(get_bits1(&gb)) VAR_13 = 1; else if(get_bits1(&gb)) VAR_13 = 2; } while(VAR_12-- && VAR_6 < VAR_5){ out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4; switch(VAR_13){ case 0:
for(VAR_9 = 0; VAR_9 < 4; VAR_9++) { pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out+2,pix); pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out,pix); out += VAR_10; } break; case 1:
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += VAR_10; out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += VAR_10; pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += VAR_10; out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += VAR_10; break; case 2:
for(VAR_9 = 0; VAR_9 < 2; VAR_9++) { uint16_t pix1, pix2; pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out,pix1); AV_WL16(out+2,pix2); out += VAR_10; AV_WL16(out,pix1); AV_WL16(out+2,pix2); out += VAR_10; } break; } VAR_6++; } break; case SMK_BLK_SKIP:
while(VAR_12-- && VAR_6 < VAR_5)
VAR_6++; break; case SMK_BLK_FILL:
VAR_13 = VAR_11 >> 8; while(VAR_12-- && VAR_6 < VAR_5){ uint32_t col; out = smk->pic.VAR_1[0] + (VAR_6 / VAR_7) * (VAR_10 * 4) + (VAR_6 % VAR_7) * 4; col = VAR_13 * 0x01010101; for(VAR_9 = 0; VAR_9 < 4; VAR_9++) { *((uint32_t*)out) = col; out += VAR_10; } VAR_6++; } break; } } *VAR_2 = sizeof(AVFrame); *(AVFrame*)VAR_1 = smk->pic; return VAR_4; }