void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){

    if(block->type & BLOCK_INTRA){

        int x, y;

        const unsigned color  = block->color[plane_index];

        const unsigned color4 = color*0x01010101;

        if(b_w==32){

            for(y=0; y < b_h; y++){

                *(uint32_t*)&dst[0 + y*stride]= color4;

                *(uint32_t*)&dst[4 + y*stride]= color4;

                *(uint32_t*)&dst[8 + y*stride]= color4;

                *(uint32_t*)&dst[12+ y*stride]= color4;

                *(uint32_t*)&dst[16+ y*stride]= color4;

                *(uint32_t*)&dst[20+ y*stride]= color4;

                *(uint32_t*)&dst[24+ y*stride]= color4;

                *(uint32_t*)&dst[28+ y*stride]= color4;

            }

        }else if(b_w==16){

            for(y=0; y < b_h; y++){

                *(uint32_t*)&dst[0 + y*stride]= color4;

                *(uint32_t*)&dst[4 + y*stride]= color4;

                *(uint32_t*)&dst[8 + y*stride]= color4;

                *(uint32_t*)&dst[12+ y*stride]= color4;

            }

        }else if(b_w==8){

            for(y=0; y < b_h; y++){

                *(uint32_t*)&dst[0 + y*stride]= color4;

                *(uint32_t*)&dst[4 + y*stride]= color4;

            }

        }else if(b_w==4){

            for(y=0; y < b_h; y++){

                *(uint32_t*)&dst[0 + y*stride]= color4;

            }

        }else{

            for(y=0; y < b_h; y++){

                for(x=0; x < b_w; x++){

                    dst[x + y*stride]= color;

                }

            }

        }

    }else{

        uint8_t *src= s->last_picture[block->ref]->data[plane_index];

        const int scale= plane_index ?  (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale;

        int mx= block->mx*scale;

        int my= block->my*scale;

        const int dx= mx&15;

        const int dy= my&15;

        const int tab_index= 3 - (b_w>>2) + (b_w>>4);

        sx += (mx>>4) - (HTAPS_MAX/2-1);

        sy += (my>>4) - (HTAPS_MAX/2-1);

        src += sx + sy*stride;

        if(   (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0)

           || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){

            s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);

            src= tmp + MB_SIZE;

        }



        av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale



        av_assert2(b_w>1 && b_h>1);

        av_assert2((tab_index>=0 && tab_index<4) || b_w==32);

        if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc )

            mc_block(&s->plane[plane_index], dst, src, stride, b_w, b_h, dx, dy);

        else if(b_w==32){

            int y;

            for(y=0; y<b_h; y+=16){

                s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);

                s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);

            }

        }else if(b_w==b_h)

            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);

        else if(b_w==2*b_h){

            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);

            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);

        }else{

            av_assert2(2*b_w==b_h);

            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);

            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);

        }

    }

}
