static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],

                     int x, int y, int ref, int plane)

{

    Plane *p = &s->plane[plane];

    uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane];

    int motion_x = block->u.mv[ref][0];

    int motion_y = block->u.mv[ref][1];

    int mx, my, i, epel, nplanes = 0;



    if (plane) {

        motion_x >>= s->chroma_x_shift;

        motion_y >>= s->chroma_y_shift;

    }



    mx         = motion_x & ~(-1 << s->mv_precision);

    my         = motion_y & ~(-1 << s->mv_precision);

    motion_x >>= s->mv_precision;

    motion_y >>= s->mv_precision;

    /* normalize subpel coordinates to epel */

    /* TODO: template this function? */

    mx      <<= 3 - s->mv_precision;

    my      <<= 3 - s->mv_precision;



    x += motion_x;

    y += motion_y;

    epel = (mx|my)&1;



    /* hpel position */

    if (!((mx|my)&3)) {

        nplanes = 1;

        src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x;

    } else {

        /* qpel or epel */

        nplanes = 4;

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

            src[i] = ref_hpel[i] + y*p->stride + x;



        /* if we're interpolating in the right/bottom halves, adjust the planes as needed

           we increment x/y because the edge changes for half of the pixels */

        if (mx > 4) {

            src[0] += 1;

            src[2] += 1;

            x++;

        }

        if (my > 4) {

            src[0] += p->stride;

            src[1] += p->stride;

            y++;

        }



        /* hpel planes are:

           [0]: F  [1]: H

           [2]: V  [3]: C */

        if (!epel) {

            /* check if we really only need 2 planes since either mx or my is

               a hpel position. (epel weights of 0 handle this there) */

            if (!(mx&3)) {

                /* mx == 0: average [0] and [2]

                   mx == 4: average [1] and [3] */

                src[!mx] = src[2 + !!mx];

                nplanes = 2;

            } else if (!(my&3)) {

                src[0] = src[(my>>1)  ];

                src[1] = src[(my>>1)+1];

                nplanes = 2;

            }

        } else {

            /* adjust the ordering if needed so the weights work */

            if (mx > 4) {

                FFSWAP(const uint8_t *, src[0], src[1]);

                FFSWAP(const uint8_t *, src[2], src[3]);

            }

            if (my > 4) {

                FFSWAP(const uint8_t *, src[0], src[2]);

                FFSWAP(const uint8_t *, src[1], src[3]);

            }

            src[4] = epel_weights[my&3][mx&3];

        }

    }



    /* fixme: v/h _edge_pos */

    if ((unsigned)x > p->width +EDGE_WIDTH/2 - p->xblen ||

        (unsigned)y > p->height+EDGE_WIDTH/2 - p->yblen) {

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

            ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride,

                                p->xblen, p->yblen, x, y,

                                p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);

            src[i] = s->edge_emu_buffer[i];

        }

    }

    return (nplanes>>1) + epel;

}

static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],

                     int x, int y, int ref, int plane)

{

    Plane *p = &s->plane[plane];

    uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane];

    int motion_x = block->u.mv[ref][0];

    int motion_y = block->u.mv[ref][1];

    int mx, my, i, epel, nplanes = 0;



    if (plane) {

        motion_x >>= s->chroma_x_shift;

        motion_y >>= s->chroma_y_shift;

    }



    mx         = motion_x & ~(-1 << s->mv_precision);

    my         = motion_y & ~(-1 << s->mv_precision);

    motion_x >>= s->mv_precision;

    motion_y >>= s->mv_precision;

    

    

    mx      <<= 3 - s->mv_precision;

    my      <<= 3 - s->mv_precision;



    x += motion_x;

    y += motion_y;

    epel = (mx|my)&1;



    

    if (!((mx|my)&3)) {

        nplanes = 1;

        src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x;

    } else {

        

        nplanes = 4;

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

            src[i] = ref_hpel[i] + y*p->stride + x;



        



        if (mx > 4) {

            src[0] += 1;

            src[2] += 1;

            x++;

        }

        if (my > 4) {

            src[0] += p->stride;

            src[1] += p->stride;

            y++;

        }



        





        if (!epel) {

            



            if (!(mx&3)) {

                



                src[!mx] = src[2 + !!mx];

                nplanes = 2;

            } else if (!(my&3)) {

                src[0] = src[(my>>1)  ];

                src[1] = src[(my>>1)+1];

                nplanes = 2;

            }

        } else {

            

            if (mx > 4) {

                FFSWAP(const uint8_t *, src[0], src[1]);

                FFSWAP(const uint8_t *, src[2], src[3]);

            }

            if (my > 4) {

                FFSWAP(const uint8_t *, src[0], src[2]);

                FFSWAP(const uint8_t *, src[1], src[3]);

            }

            src[4] = epel_weights[my&3][mx&3];

        }

    }



    

    if ((unsigned)x > p->width +EDGE_WIDTH/2 - p->xblen ||

        (unsigned)y > p->height+EDGE_WIDTH/2 - p->yblen) {

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

            ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride,

                                p->xblen, p->yblen, x, y,

                                p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);

            src[i] = s->edge_emu_buffer[i];

        }

    }

    return (nplanes>>1) + epel;

}

static int FUNC_0(DiracContext *VAR_0, DiracBlock *VAR_1, const uint8_t *VAR_2[5],

                     int VAR_3, int VAR_4, int VAR_5, int VAR_6)

{

    Plane *p = &VAR_0->VAR_6[VAR_6];

    uint8_t **ref_hpel = VAR_0->ref_pics[VAR_5]->hpel[VAR_6];

    int VAR_7 = VAR_1->u.mv[VAR_5][0];

    int VAR_8 = VAR_1->u.mv[VAR_5][1];

    int VAR_9, VAR_10, VAR_11, VAR_12, VAR_13 = 0;



    if (VAR_6) {

        VAR_7 >>= VAR_0->chroma_x_shift;

        VAR_8 >>= VAR_0->chroma_y_shift;

    }



    VAR_9         = VAR_7 & ~(-1 << VAR_0->mv_precision);

    VAR_10         = VAR_8 & ~(-1 << VAR_0->mv_precision);

    VAR_7 >>= VAR_0->mv_precision;

    VAR_8 >>= VAR_0->mv_precision;

    

    

    VAR_9      <<= 3 - VAR_0->mv_precision;

    VAR_10      <<= 3 - VAR_0->mv_precision;



    VAR_3 += VAR_7;

    VAR_4 += VAR_8;

    VAR_12 = (VAR_9|VAR_10)&1;



    

    if (!((VAR_9|VAR_10)&3)) {

        VAR_13 = 1;

        VAR_2[0] = ref_hpel[(VAR_10>>1)+(VAR_9>>2)] + VAR_4*p->stride + VAR_3;

    } else {

        

        VAR_13 = 4;

        for (VAR_11 = 0; VAR_11 < 4; VAR_11++)

            VAR_2[VAR_11] = ref_hpel[VAR_11] + VAR_4*p->stride + VAR_3;



        



        if (VAR_9 > 4) {

            VAR_2[0] += 1;

            VAR_2[2] += 1;

            VAR_3++;

        }

        if (VAR_10 > 4) {

            VAR_2[0] += p->stride;

            VAR_2[1] += p->stride;

            VAR_4++;

        }



        





        if (!VAR_12) {

            



            if (!(VAR_9&3)) {

                



                VAR_2[!VAR_9] = VAR_2[2 + !!VAR_9];

                VAR_13 = 2;

            } else if (!(VAR_10&3)) {

                VAR_2[0] = VAR_2[(VAR_10>>1)  ];

                VAR_2[1] = VAR_2[(VAR_10>>1)+1];

                VAR_13 = 2;

            }

        } else {

            

            if (VAR_9 > 4) {

                FFSWAP(const uint8_t *, VAR_2[0], VAR_2[1]);

                FFSWAP(const uint8_t *, VAR_2[2], VAR_2[3]);

            }

            if (VAR_10 > 4) {

                FFSWAP(const uint8_t *, VAR_2[0], VAR_2[2]);

                FFSWAP(const uint8_t *, VAR_2[1], VAR_2[3]);

            }

            VAR_2[4] = epel_weights[VAR_10&3][VAR_9&3];

        }

    }



    

    if ((unsigned)VAR_3 > p->width +EDGE_WIDTH/2 - p->xblen ||

        (unsigned)VAR_4 > p->height+EDGE_WIDTH/2 - p->yblen) {

        for (VAR_11 = 0; VAR_11 < VAR_13; VAR_11++) {

            ff_emulated_edge_mc(VAR_0->edge_emu_buffer[VAR_11], VAR_2[VAR_11], p->stride,

                                p->xblen, p->yblen, VAR_3, VAR_4,

                                p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);

            VAR_2[VAR_11] = VAR_0->edge_emu_buffer[VAR_11];

        }

    }

    return (VAR_13>>1) + VAR_12;

}

static int FUNC_0(DiracContext *VAR_0, DiracBlock *VAR_1, const uint8_t *VAR_2[5],
int VAR_3, int VAR_4, int VAR_5, int VAR_6)
{ Plane *p = &VAR_0->VAR_6[VAR_6]; uint8_t **ref_hpel = VAR_0->ref_pics[VAR_5]->hpel[VAR_6]; int VAR_7 = VAR_1->u.mv[VAR_5][0]; int VAR_8 = VAR_1->u.mv[VAR_5][1]; int VAR_9, VAR_10, VAR_11, VAR_12, VAR_13 = 0; if (VAR_6) { VAR_7 >>= VAR_0->chroma_x_shift; VAR_8 >>= VAR_0->chroma_y_shift; } VAR_9         = VAR_7 & ~(-1 << VAR_0->mv_precision); VAR_10         = VAR_8 & ~(-1 << VAR_0->mv_precision); VAR_7 >>= VAR_0->mv_precision; VAR_8 >>= VAR_0->mv_precision; VAR_9      <<= 3 - VAR_0->mv_precision; VAR_10      <<= 3 - VAR_0->mv_precision; VAR_3 += VAR_7; VAR_4 += VAR_8; VAR_12 = (VAR_9|VAR_10)&1; if (!((VAR_9|VAR_10)&3)) { VAR_13 = 1; VAR_2[0] = ref_hpel[(VAR_10>>1)+(VAR_9>>2)] + VAR_4*p->stride + VAR_3; } else { VAR_13 = 4; for (VAR_11 = 0; VAR_11 < 4; VAR_11++) VAR_2[VAR_11] = ref_hpel[VAR_11] + VAR_4*p->stride + VAR_3; if (VAR_9 > 4) { VAR_2[0] += 1; VAR_2[2] += 1; VAR_3++; } if (VAR_10 > 4) { VAR_2[0] += p->stride; VAR_2[1] += p->stride; VAR_4++; } if (!VAR_12) { if (!(VAR_9&3)) { VAR_2[!VAR_9] = VAR_2[2 + !!VAR_9]; VAR_13 = 2; } else if (!(VAR_10&3)) { VAR_2[0] = VAR_2[(VAR_10>>1)  ]; VAR_2[1] = VAR_2[(VAR_10>>1)+1]; VAR_13 = 2; } } else { if (VAR_9 > 4) { FFSWAP(const uint8_t *, VAR_2[0], VAR_2[1]); FFSWAP(const uint8_t *, VAR_2[2], VAR_2[3]); } if (VAR_10 > 4) { FFSWAP(const uint8_t *, VAR_2[0], VAR_2[2]); FFSWAP(const uint8_t *, VAR_2[1], VAR_2[3]); } VAR_2[4] = epel_weights[VAR_10&3][VAR_9&3]; } } if ((unsigned)VAR_3 > p->width +EDGE_WIDTH/2 - p->xblen ||
(unsigned)VAR_4 > p->height+EDGE_WIDTH/2 - p->yblen) { for (VAR_11 = 0; VAR_11 < VAR_13; VAR_11++) { ff_emulated_edge_mc(VAR_0->edge_emu_buffer[VAR_11], VAR_2[VAR_11], p->stride,
p->xblen, p->yblen, VAR_3, VAR_4,
p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2); VAR_2[VAR_11] = VAR_0->edge_emu_buffer[VAR_11]; } } return (VAR_13>>1) + VAR_12; }