static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
{
    int i, j;
    int bw, bh;
    int type;
    int keyframe = 1;
    uint8_t *Y, *U, *V;
    int *src;
    bw = ctx->avctx->width >> 2;
    bh = ctx->avctx->height >> 2;
    for(i = 0; i < TM2_NUM_STREAMS; i++)
        ctx->tok_ptrs[i] = 0;
    if (ctx->tok_lens[TM2_TYPE]<bw*bh){
        av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
        return -1;
    }
    memset(ctx->last, 0, 4 * bw * sizeof(int));
    memset(ctx->clast, 0, 4 * bw * sizeof(int));
    for(j = 0; j < bh; j++) {
        memset(ctx->D, 0, 4 * sizeof(int));
        memset(ctx->CD, 0, 4 * sizeof(int));
        for(i = 0; i < bw; i++) {
            type = GET_TOK(ctx, TM2_TYPE);
            switch(type) {
            case TM2_HI_RES:
                tm2_hi_res_block(ctx, p, i, j);
                break;
            case TM2_MED_RES:
                tm2_med_res_block(ctx, p, i, j);
                break;
            case TM2_LOW_RES:
                tm2_low_res_block(ctx, p, i, j);
                break;
            case TM2_NULL_RES:
                tm2_null_res_block(ctx, p, i, j);
                break;
            case TM2_UPDATE:
                tm2_update_block(ctx, p, i, j);
                keyframe = 0;
                break;
            case TM2_STILL:
                tm2_still_block(ctx, p, i, j);
                keyframe = 0;
                break;
            case TM2_MOTION:
                tm2_motion_block(ctx, p, i, j);
                keyframe = 0;
                break;
            default:
                av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
            }
        }
    }
    Y = p->data[0];
    src = (ctx->cur?ctx->Y2:ctx->Y1);
    for(j = 0; j < ctx->avctx->height; j++){
        for(i = 0; i < ctx->avctx->width; i++){
            Y[i] = av_clip_uint8(*src++);
        }
        Y += p->linesize[0];
    }
    U = p->data[2];
    src = (ctx->cur?ctx->U2:ctx->U1);
    for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){
        for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){
            U[i] = av_clip_uint8(*src++);
        }
        U += p->linesize[2];
    }
    V = p->data[1];
    src = (ctx->cur?ctx->V2:ctx->V1);
    for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){
        for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){
            V[i] = av_clip_uint8(*src++);
        }
        V += p->linesize[1];
    }
    return keyframe;
}
['static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)\n{\n    int i, j;\n    int bw, bh;\n    int type;\n    int keyframe = 1;\n    uint8_t *Y, *U, *V;\n    int *src;\n    bw = ctx->avctx->width >> 2;\n    bh = ctx->avctx->height >> 2;\n    for(i = 0; i < TM2_NUM_STREAMS; i++)\n        ctx->tok_ptrs[i] = 0;\n    if (ctx->tok_lens[TM2_TYPE]<bw*bh){\n        av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\\n",ctx->tok_lens[TM2_TYPE],bw*bh);\n        return -1;\n    }\n    memset(ctx->last, 0, 4 * bw * sizeof(int));\n    memset(ctx->clast, 0, 4 * bw * sizeof(int));\n    for(j = 0; j < bh; j++) {\n        memset(ctx->D, 0, 4 * sizeof(int));\n        memset(ctx->CD, 0, 4 * sizeof(int));\n        for(i = 0; i < bw; i++) {\n            type = GET_TOK(ctx, TM2_TYPE);\n            switch(type) {\n            case TM2_HI_RES:\n                tm2_hi_res_block(ctx, p, i, j);\n                break;\n            case TM2_MED_RES:\n                tm2_med_res_block(ctx, p, i, j);\n                break;\n            case TM2_LOW_RES:\n                tm2_low_res_block(ctx, p, i, j);\n                break;\n            case TM2_NULL_RES:\n                tm2_null_res_block(ctx, p, i, j);\n                break;\n            case TM2_UPDATE:\n                tm2_update_block(ctx, p, i, j);\n                keyframe = 0;\n                break;\n            case TM2_STILL:\n                tm2_still_block(ctx, p, i, j);\n                keyframe = 0;\n                break;\n            case TM2_MOTION:\n                tm2_motion_block(ctx, p, i, j);\n                keyframe = 0;\n                break;\n            default:\n                av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\\n", type);\n            }\n        }\n    }\n    Y = p->data[0];\n    src = (ctx->cur?ctx->Y2:ctx->Y1);\n    for(j = 0; j < ctx->avctx->height; j++){\n        for(i = 0; i < ctx->avctx->width; i++){\n            Y[i] = av_clip_uint8(*src++);\n        }\n        Y += p->linesize[0];\n    }\n    U = p->data[2];\n    src = (ctx->cur?ctx->U2:ctx->U1);\n    for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){\n        for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){\n            U[i] = av_clip_uint8(*src++);\n        }\n        U += p->linesize[2];\n    }\n    V = p->data[1];\n    src = (ctx->cur?ctx->V2:ctx->V1);\n    for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){\n        for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){\n            V[i] = av_clip_uint8(*src++);\n        }\n        V += p->linesize[1];\n    }\n    return keyframe;\n}']