anchor.diff:      return _clip8(kYScale * y + kUToB * u + kBCst);
     }
   
  -  static void _yuvToRgb(int y, int u, int v, uint8_t* const rgb) {
  +  void _yuvToRgb(int y, int u, int v, VP8List rgb) {
       rgb[0] = _yuvToR(y, v);
       rgb[1] = _yuvToG(y, u, v);
  -    rgb[2] = _yvToB(y, u);
  -  }
  -
  -  static void _yuvToRgba(uint8_t y, uint8_t u, uint8_t v, uint8_t* const rgba) {
  +    rgb[2] = _yuvToB(y, u);
  +  }
  +
  +  void _yuvToRgba(int y, int u, int v, VP8List rgba) {
       _yuvToRgb(y, u, v, rgba);
       rgba[3] = 0xff;
  -  }*/
  +  }
  +
  +  //#define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)
  +  void _upsample(VP8List topY, VP8List bottomY,
  +                 VP8List topU, VP8List topV,
  +                 VP8List curU, VP8List curV,
  +                 VP8List topDst, VP8List bottomDst, int len) {
  +
  +    int LOAD_UV(int u, int v) => ((u) | ((v) << 16));
  +
  +    final int last_pixel_pair = (len - 1) >> 1;
  +    int tl_uv = LOAD_UV(topU[0], topV[0]); // top-left sample
  +    int l_uv  = LOAD_UV(curU[0], curV[0]); // left-sample
  +
  +    final int uv0 = (3 * tl_uv + l_uv + 0x00020002) >> 2;
  +    _yuvToRgba(topY[0], uv0 & 0xff, (uv0 >> 16), topDst);
  +
  +    if (bottomY != null) {
  +      final int uv0 = (3 * l_uv + tl_uv + 0x00020002) >> 2;
  +      _yuvToRgba(bottomY[0], uv0 & 0xff, (uv0 >> 16), bottomDst);
  +    }
  +
  +    for (int x = 1; x <= last_pixel_pair; ++x) {
  +      final int t_uv = LOAD_UV(topU[x], topV[x]); // top sample
  +      final int uv   = LOAD_UV(curU[x], curV[x]); // sample
  +      // precompute invariant values associated with first and second diagonals
  +      final int avg = tl_uv + t_uv + l_uv + uv + 0x00080008;
  +      final int diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3;
  +      final int diag_03 = (avg + 2 * (tl_uv + uv)) >> 3;
  +
  +      final int uv0 = (diag_12 + tl_uv) >> 1;
  +      final int uv1 = (diag_03 + t_uv) >> 1;
  +
  +      _yuvToRgba(topY[2 * x - 1], uv0 & 0xff, (uv0 >> 16),
  +          topDst + (2 * x - 1) * 4);
  +
  +      _yuvToRgba(topY[2 * x - 0], uv1 & 0xff, (uv1 >> 16),
  +              topDst + (2 * x - 0) * 4);
  +
  +      if (bottomY != null) {
  +        final int uv0 = (diag_03 + l_uv) >> 1;
  +        final int uv1 = (diag_12 + uv) >> 1;
  +
  +        _yuvToRgba(bottomY[2 * x - 1], uv0 & 0xff, (uv0 >> 16),
  +            bottomDst + (2 * x - 1) * 4);
  +
  +        _yuvToRgba(bottomY[2 * x + 0], uv1 & 0xff, (uv1 >> 16),
  +                bottomDst + (2 * x + 0) * 4);
  +      }
  +
  +      tl_uv = t_uv;
  +      l_uv = uv;
  +    }
  +
  +    if ((len & 1) == 0) {
  +      final int uv0 = (3 * tl_uv + l_uv + 0x00020002) >> 2;
  +      _yuvToRgba(topY[len - 1], uv0 & 0xff, (uv0 >> 16),
  +           topDst + (len - 1) * 4);
  +    }
  +
  +    if (bottomY != null) {
  +      final int uv0 = (3 * l_uv + tl_uv + 0x00020002) >> 2;
  +      _yuvToRgba(bottomY[len - 1], uv0 & 0xff, (uv0 >> 16),
  +           bottomDst + (len - 1) * 4);
  +    }
  +  }
  +
   
     int _emitFancyRGB(int mbY, int mbW, int mbH) {
       int numLinesOut = mbH;   // a priori guess
  -    /*int dst = mbY * webp.width;
  +    VP8List dst = new VP8List(output.getBytes(), mbY * webp.width);
       VP8List curY = new VP8List(_y);
       VP8List curU = new VP8List(_u);
       VP8List curV = new VP8List(_v);
  
positive.code:   static const int Y_OFF = (BPS * 1 + 8);
    static const int U_OFF = (Y_OFF + BPS * 16 + BPS);
    static const int V_OFF = (U_OFF + 16);
  }
  
negative.code:     return true;
    }
  
    int _clip8(int v) {
      return ((v & ~YUV_MASK2) == 0) ? (v >> YUV_FIX2) : (v < 0) ? 0 : 255;
    }
  
  