static int decode_q_branch(SnowContext *s, int level, int x, int y){

    const int w= s->b_width << s->block_max_depth;

    const int rem_depth= s->block_max_depth - level;

    const int index= (x + y*w) << rem_depth;

    int trx= (x+1)<<rem_depth;

    const BlockNode *left  = x ? &s->block[index-1] : &null_block;

    const BlockNode *top   = y ? &s->block[index-w] : &null_block;

    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;

    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt

    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;

    int res;



    if(s->keyframe){

        set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);

        return 0;

    }



    if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){

        int type, mx, my;

        int l = left->color[0];

        int cb= left->color[1];

        int cr= left->color[2];

        unsigned ref = 0;

        int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);

        int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));

        int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));



        type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;



        if(type){

            pred_mv(s, &mx, &my, 0, left, top, tr);

            l += get_symbol(&s->c, &s->block_state[32], 1);

            if (s->nb_planes > 2) {

                cb+= get_symbol(&s->c, &s->block_state[64], 1);

                cr+= get_symbol(&s->c, &s->block_state[96], 1);

            }

        }else{

            if(s->ref_frames > 1)

                ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);

            if (ref >= s->ref_frames) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");

                return AVERROR_INVALIDDATA;

            }

            pred_mv(s, &mx, &my, ref, left, top, tr);

            mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);

            my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);

        }

        set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);

    }else{

        if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||

            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||

            (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||

            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)

            return res;

    }

    return 0;

}
