shithub: libvpx

Download patch

ref: 18e90d744eba2d28ad96a566565bbf5642d24b59
parent: 3c872b6c27a5f03156b973fb359c9293049d6e84
author: Deb Mukherjee <debargha@google.com>
date: Thu Feb 16 04:29:54 EST 2012

Supporting high precision 1/8-pel motion vectors

This is the initial patch for supporting 1/8th pel
motion. Currently if we configure with enable-high-precision-mv,
all motion vectors would default to 1/8 pel. Encode and
decode syncs fine with the current code. In the next phase
the code will be refactored so that we can choose the 1/8
pel mode adaptively at a frame/segment/mb level.

Derf results:
http://www.corp.google.com/~debargha/vp8_results/enhinterp_hpmv.html
(about 0.83% better than 8-tap interpoaltion)

Patch 3: Rebased. Also adding 1/16th pel interpolation for U and V

Patch 4: HD results.
http://www.corp.google.com/~debargha/vp8_results/enhinterp_hd_hpmv.html
Seems impressive (unless I am doing something wrong).

Patch 5: Added mmx/sse for bilateral filtering, as well as enforced
use of c-versions of subpel filters with 8-taps and 1/16th pel;
Also redesigned the 8-tap filters to reduce the cut-off in order to
introduce a denoising effect. There is a new configure option
sixteenth-subpel-uv which will use 1/16 th pel interpolation for
uv, if the motion vectors have 1/8 pel accuracy.

With the fixes the results are promising on the derf set. The enhanced
interpolation option with 8-taps alone gives 3% improvement over thei
derf set:
http://www.corp.google.com/~debargha/vp8_results/enhinterpn.html

Results on high precision mv and on the hd set are to follow.

Patch 6: Adding a missing condition for CONFIG_SIXTEENTH_SUBPEL_UV in
vp8/common/x86/x86_systemdependent.c

Patch 7: Cleaning up various debug messages.

Patch 8: Merge conflict

Change-Id: I5b1d844457aefd7414a9e4e0e06c6ed38fd8cc04

--- a/configure
+++ b/configure
@@ -226,6 +226,8 @@
     enhanced_interp
     superblocks
     featureupdates
+    high_precision_mv
+    sixteenth_subpel_uv
 "
 CONFIG_LIST="
     external_build
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -290,8 +290,8 @@
     /* Delta values have the range +/- MAX_LOOP_FILTER */
     signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];                /* 0 = Intra, Last, GF, ARF */
     signed char ref_lf_deltas[MAX_REF_LF_DELTAS];                     /* 0 = Intra, Last, GF, ARF */
-    signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];                      /* 0 = BPRED, ZERO_MV, MV, SPLIT */
-    signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];                           /* 0 = BPRED, ZERO_MV, MV, SPLIT */
+    signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];              /* 0 = BPRED, ZERO_MV, MV, SPLIT */
+    signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];                   /* 0 = BPRED, ZERO_MV, MV, SPLIT */
 
     /* Distance of MB away from frame edges */
     int mb_to_left_edge;
@@ -310,6 +310,9 @@
     vp8_subpix_fn_t  subpixel_predict16x16;
     vp8_subpix_fn_t  subpixel_predict_avg8x8;
     vp8_subpix_fn_t  subpixel_predict_avg16x16;
+#if CONFIG_HIGH_PRECISION_MV
+    int allow_high_precision_mv;
+#endif /* CONFIG_HIGH_PRECISION_MV */
 
     void *current_bc;
 
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -225,7 +225,29 @@
 struct vp8_token_struct vp8_mv_ref_encoding_array    [VP8_MVREFS];
 struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
 
+#if CONFIG_HIGH_PRECISION_MV
+const vp8_tree_index vp8_small_mvtree [30] =
+{
+     2,  16,
+     4,  10,
+     6,   8,
+    -0,  -1,
+    -2,  -3,
+    12,  14,
+    -4,  -5,
+    -6,  -7,
+    18,  24,
+    20,  22,
+    -8,  -9,
+   -10, -11,
+    26,  28,
+   -12, -13,
+   -14, -15
+};
+struct vp8_token_struct vp8_small_mvencodings [16];
 
+#else
+
 const vp8_tree_index vp8_small_mvtree [14] =
 {
     2, 8,
@@ -236,9 +258,11 @@
     -4, -5,
     -6, -7
 };
-
 struct vp8_token_struct vp8_small_mvencodings [8];
 
+#endif  /* CONFIG_HIGH_PRECISION_MV */
+
+
 void vp8_init_mbmode_probs(VP8_COMMON *x)
 {
     unsigned int bct [VP8_YMODES] [2];      /* num Ymodes > num UV modes */
@@ -489,4 +513,3 @@
         printf("\n");
     }
 }
-
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -57,7 +57,11 @@
 
 extern const vp8_tree_index vp8_small_mvtree[];
 
+#if CONFIG_HIGH_PRECISION_MV
+extern struct vp8_token_struct vp8_small_mvencodings [16];
+#else
 extern struct vp8_token_struct vp8_small_mvencodings [8];
+#endif
 
 void vp8_entropy_mode_init(void);
 
--- a/vp8/common/entropymv.c
+++ b/vp8/common/entropymv.c
@@ -11,11 +11,45 @@
 
 #include "entropymv.h"
 
+#if CONFIG_HIGH_PRECISION_MV
 const MV_CONTEXT vp8_mv_update_probs[2] =
 {
     {{
         237,
         246,
+        253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+        254, 254, 254, 254, 254, 250, 250, 252, 254, 254, 254
+    }},
+    {{
+        231,
+        243,
+        245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+        254, 254, 254, 254, 254, 251, 251, 254, 254, 254, 254
+    }}
+};
+const MV_CONTEXT vp8_default_mv_context[2] =
+{
+    {{
+        /* row */
+        162,                                        /* is short */
+        128,                                        /* sign */
+        230, 215, 175, 140, 160, 180, 160, 140, 180, 214, 150, 39, 120, 156, 160, /* short tree */
+        128, 129, 132,  75, 145, 178, 206, 239, 254, 254, 254 /* long bits */
+    }},
+    {{
+        /* same for column */
+        164,                                        /* is short */
+        128,
+        220, 204, 180, 170, 140, 119, 180, 235, 180, 140, 185, 230, 229, 228, 200,
+        128, 130, 130,  74, 148, 180, 203, 236, 254, 254, 254 /* long bits */
+    }}
+};
+#else
+const MV_CONTEXT vp8_mv_update_probs[2] =
+{
+    {{
+        237,
+        246,
         253, 253, 254, 254, 254, 254, 254,
         254, 254, 254, 254, 254, 250, 250, 252, 254, 254
     }},
@@ -35,9 +69,6 @@
         225, 146, 172, 147, 214,  39, 156,          /* short tree */
         128, 129, 132,  75, 145, 178, 206, 239, 254, 254 /* long bits */
     }},
-
-
-
     {{
         /* same for column */
         164,                                        /* is short */
@@ -44,6 +75,6 @@
         128,
         204, 170, 119, 235, 140, 230, 228,
         128, 130, 130,  74, 148, 180, 203, 236, 254, 254 /* long bits */
-
     }}
 };
+#endif  /* CONFIG_HIGH_PRECISION_MV */
--- a/vp8/common/entropymv.h
+++ b/vp8/common/entropymv.h
@@ -13,16 +13,32 @@
 #define __INC_ENTROPYMV_H
 
 #include "treecoder.h"
+#include "vpx_config.h"
 
+#if CONFIG_HIGH_PRECISION_MV
+#define MV_SHIFT 0
+#else
+#define MV_SHIFT 1
+#endif
+
 enum
 {
+#if CONFIG_HIGH_PRECISION_MV
+    mv_max  = 2047,              /* max absolute value of a MV component */
+    MVvals = (2 * mv_max) + 1,   /* # possible values "" */
+    mvlong_width = 11,       /* Large MVs have 9 bit magnitudes */
+    mvnum_short = 16,         /* magnitudes 0 through 15 */
+    mvnum_short_bits = 4,         /* number of bits for short mvs */
+#else
     mv_max  = 1023,              /* max absolute value of a MV component */
     MVvals = (2 * mv_max) + 1,   /* # possible values "" */
-    mvfp_max  = 255,              /* max absolute value of a full pixel MV component */
-    MVfpvals = (2 * mvfp_max) +1, /* # possible full pixel MV values */
-
     mvlong_width = 10,       /* Large MVs have 9 bit magnitudes */
     mvnum_short = 8,         /* magnitudes 0 through 7 */
+    mvnum_short_bits = 3,         /* number of bits for short mvs */
+#endif
+
+    mvfp_max  = 255,              /* max absolute value of a full pixel MV component */
+    MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */
 
     /* probability offsets for coding each MV component */
 
--- a/vp8/common/filter.c
+++ b/vp8/common/filter.c
@@ -13,21 +13,42 @@
 #include "filter.h"
 #include "vpx_ports/mem.h"
 
-DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[8][2]) =
+//#define ANNOUNCE_FUNCTION
+
+DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[SUBPEL_SHIFTS][2]) =
 {
+#if SUBPEL_SHIFTS==16
     { 128,   0 },
+    { 120,   8 },
     { 112,  16 },
+    { 104,  24 },
     {  96,  32 },
+    {  88,  40 },
     {  80,  48 },
+    {  72,  56 },
     {  64,  64 },
+    {  56,  72 },
     {  48,  80 },
+    {  40,  88 },
     {  32,  96 },
+    {  24, 104 },
+    {  16, 112 },
+    {   8, 120 }
+#else
+    { 128,   0 },
+    { 112,  16 },
+    {  96,  32 },
+    {  80,  48 },
+    {  64,  64 },
+    {  48,  80 },
+    {  32,  96 },
     {  16, 112 }
+#endif  /* SUBPEL_SHIFTS==16 */
 };
 
 #if CONFIG_ENHANCED_INTERP
-#define FILTER_ALPHA 875
-DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[8][2*INTERP_EXTEND]) =
+#define FILTER_ALPHA 65
+DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[SUBPEL_SHIFTS][2*INTERP_EXTEND]) =
 {
     /* Generated using MATLAB:
      * alpha = 0.875;
@@ -37,37 +58,151 @@
      * % Now normalize the powers of the polyphase components
      * disp(num2str(ba, '%d,'))
      */
-#if FILTER_ALPHA == 90
-    /* alpha = 0.9 */
+#if SUBPEL_SHIFTS==16
+#if FILTER_ALPHA == 80
+    /* alpha = 0.80 */
     { 0,   0,   0, 128,   0,   0,   0,  0},
-    {-3,   6, -13, 126,  18,  -8,   5, -3},
-    {-6,  11, -22, 118,  39, -16,   9, -5},
-    {-8,  14, -27, 104,  62, -23,  13, -7},
-    {-8,  14, -27,  85,  85, -27,  14, -8},
-    {-7,  13, -23,  62, 104, -27,  14, -8},
-    {-5,   9, -16,  39, 118, -22,  11, -6},
-    {-3,   5,  -8,  18, 126, -13,   6, -3}
-#elif FILTER_ALPHA == 875
-    /* alpha = 0.875 */
+    {-1,   2,  -6, 127,   9,  -4,   2, -1},
+    {-2,   5, -12, 124,  18,  -7,   4, -2},
+    {-2,   7, -16, 119,  28, -11,   5, -2},
+    {-3,   8, -19, 114,  38, -14,   7, -3},
+    {-3,   9, -22, 107,  49, -17,   8, -3},
+    {-4,  10, -23,  99,  60, -20,  10, -4},
+    {-4,  11, -23,  90,  70, -22,  10, -4},
+    {-4,  11, -23,  80,  80, -23,  11, -4},
+    {-4,  10, -22,  70,  90, -23,  11, -4},
+    {-4,  10, -20,  60,  99, -23,  10, -4},
+    {-3,   8, -17,  49, 107, -22,   9, -3},
+    {-3,   7, -14,  38, 114, -19,   8, -3},
+    {-2,   5, -11,  28, 119, -16,   7, -2},
+    {-2,   4,  -7,  18, 124, -12,   5, -2},
+    {-1,   2,  -4,   9, 127,  -6,   2, -1}
+#elif FILTER_ALPHA == 75
+    /* alpha = 0.75 */
     { 0,   0,   0, 128,   0,   0,   0,  0},
-    {-3,   6, -13, 126,  18,  -8,   4, -2},
-    {-5,  10, -22, 118,  39, -16,   9, -5},
-    {-7,  13, -26, 104,  62, -23,  12, -7},
-    {-7,  13, -27,  85,  85, -27,  13, -7},
-    {-7,  12, -23,  62, 104, -26,  13, -7},
-    {-5,   9, -16,  39, 118, -22,  10, -5},
-    {-2,   4,  -8,  18, 126, -13,   6, -3}
-#elif FILTER_ALPHA == 85
-    /* alpha = 0.85 */
+    {-1,   2,  -6, 126,   9,  -3,   2, -1},
+    {-1,   4, -11, 123,  18,  -7,   3, -1},
+    {-2,   6, -16, 119,  28, -10,   5, -2},
+    {-2,   7, -19, 113,  38, -13,   6, -2},
+    {-3,   8, -21, 106,  49, -16,   7, -2},
+    {-3,   9, -22,  99,  59, -19,   8, -3},
+    {-3,   9, -23,  90,  70, -21,   9, -3},
+    {-3,   9, -22,  80,  80, -22,   9, -3},
+    {-3,   9, -21,  70,  90, -23,   9, -3},
+    {-3,   8, -19,  59,  99, -22,   9, -3},
+    {-2,   7, -16,  49, 106, -21,   8, -3},
+    {-2,   6, -13,  38, 113, -19,   7, -2},
+    {-2,   5, -10,  28, 119, -16,   6, -2},
+    {-1,   3,  -7,  18, 123, -11,   4, -1},
+    {-1,   2,  -3,   9, 126,  -6,   2, -1}
+#elif FILTER_ALPHA == 70
+    /* alpha = 0.70 */
     { 0,   0,   0, 128,   0,   0,   0,  0},
+    { 0,   2,  -6, 126,   8,  -3,   1,  0},
+    {-1,   4, -11, 123,  18,  -7,   3, -1},
+    {-1,   5, -15, 119,  27, -10,   4, -1},
+    {-2,   6, -18, 113,  38, -13,   5, -1},
+    {-2,   7, -20, 106,  49, -16,   6, -2},
+    {-2,   8, -22,  98,  59, -18,   7, -2},
+    {-2,   8, -22,  89,  69, -20,   8, -2},
+    {-2,   8, -21,  79,  79, -21,   8, -2},
+    {-2,   8, -20,  69,  89, -22,   8, -2},
+    {-2,   7, -18,  59,  98, -22,   8, -2},
+    {-2,   6, -16,  49, 106, -20,   7, -2},
+    {-1,   5, -13,  38, 113, -18,   6, -2},
+    {-1,   4, -10,  27, 119, -15,   5, -1},
+    {-1,   3,  -7,  18, 123, -11,   4, -1},
+    { 0,   1,  -3,   8, 126,  -6,   2,  0}
+#elif FILTER_ALPHA == 65
+    /* alpha = 0.65 */
+    { 0,   0,   0, 128,   0,   0,   0,  0},
+    { 0,   2,  -6, 126,   8,  -3,   1,  0},
+    {-1,   3, -10, 123,  18,  -6,   2, -1},
+    {-1,   5, -14, 118,  27, -10,   4, -1},
+    {-1,   5, -17, 112,  38, -13,   5, -1},
+    {-2,   6, -19, 106,  48, -15,   5, -1},
+    {-2,   7, -21,  98,  59, -17,   6, -2},
+    {-2,   7, -21,  89,  69, -19,   7, -2},
+    {-2,   7, -20,  79,  79, -20,   7, -2},
+    {-2,   7, -19,  69,  89, -21,   7, -2},
+    {-2,   6, -17,  59,  98, -21,   7, -2},
+    {-1,   5, -15,  48, 106, -19,   6, -2},
+    {-1,   5, -13,  38, 112, -17,   5, -1},
+    {-1,   4, -10,  27, 118, -14,   5, -1},
+    {-1,   2,  -6,  18, 123, -10,   3, -1},
+    {0,   1,  -3,   8, 126,  -6,   2, 0}
+#elif FILTER_ALPHA == 60
+    /* alpha = 0.60 */
+    { 0,   0,   0, 128,   0,   0,   0,  0},
+    { 0,   2,  -6, 126,   8,  -3,   1,  0},
+    {-1,   3, -10, 123,  18,  -6,   2, -1},
+    {-1,   4, -14, 118,  28,  -9,   3, -1},
+    {-1,   5, -17, 112,  38, -12,   4, -1},
+    {-1,   6, -19, 105,  48, -15,   5, -1},
+    {-1,   6, -20,  97,  58, -17,   6, -1},
+    {-1,   6, -20,  88,  69, -19,   6, -1},
+    {-1,   6, -20,  79,  79, -20,   6, -1},
+    {-1,   6, -19,  69,  88, -20,   6, -1},
+    {-1,   6, -17,  58,  97, -20,   6, -1},
+    {-1,   5, -15,  48, 105, -19,   6, -1},
+    {-1,   4, -12,  38, 112, -17,   5, -1},
+    {-1,   3,  -9,  28, 118, -14,   4, -1},
+    {-1,   2,  -6,  18, 123, -10,   3, -1},
+    {0,   1,  -3,   8, 126,  -6,   2, 0}
+#endif  /* FILTER_ALPHA */
+#else   /* SUBPEL_SHIFTS==16 */
+#if FILTER_ALPHA == 80
+    /* alpha = 0.80 */
+    { 0,   0,   0, 128,   0,   0,   0,  0},
     {-2,   5, -12, 124,  18,  -7,   4, -2},
-    {-4,  10, -20, 114,  39, -15,   8, -4},
-    {-5,  12, -24, 100,  60, -21,  11, -5},
-    {-5,  12, -24,  81,  81, -24,  12, -5},
-    {-5,  11, -21,  60, 100, -24,  12, -5},
-    {-4,   8, -15,  39, 114, -20,  10, -4},
+    {-3,   8, -19, 114,  38, -14,   7, -3},
+    {-4,  10, -23,  99,  60, -20,  10, -4},
+    {-4,  11, -23,  80,  80, -23,  11, -4},
+    {-4,  10, -20,  60,  99, -23,  10, -4},
+    {-3,   7, -14,  38, 114, -19,   8, -3},
     {-2,   4,  -7,  18, 124, -12,   5, -2}
-#endif
+#elif FILTER_ALPHA == 75
+    /* alpha = 0.75 */
+    { 0,   0,   0, 128,   0,   0,   0,  0},
+    {-1,   4, -11, 123,  18,  -7,   3, -1},
+    {-2,   7, -19, 113,  38, -13,   6, -2},
+    {-3,   9, -22,  99,  59, -19,   8, -3},
+    {-3,   9, -22,  80,  80, -22,   9, -3},
+    {-3,   8, -19,  59,  99, -22,   9, -3},
+    {-2,   6, -13,  38, 113, -19,   7, -2},
+    {-1,   3,  -7,  18, 123, -11,   4, -1}
+#elif FILTER_ALPHA == 70
+    /* alpha = 0.70 */
+    { 0,   0,   0, 128,   0,   0,   0,  0},
+    {-1,   4, -11, 123,  18,  -7,   3, -1},
+    {-2,   6, -18, 113,  38, -13,   5, -1},
+    {-2,   8, -22,  98,  59, -18,   7, -2},
+    {-2,   8, -21,  79,  79, -21,   8, -2},
+    {-2,   7, -18,  59,  98, -22,   8, -2},
+    {-1,   5, -13,  38, 113, -18,   6, -2},
+    {-1,   3,  -7,  18, 123, -11,   4, -1}
+#elif FILTER_ALPHA == 65
+    /* alpha = 0.65 */
+    { 0,   0,   0, 128,   0,   0,   0, 0},
+    {-1,   3, -10, 123,  18,  -6,   2, -1},
+    {-1,   5, -17, 112,  38, -13,   5, -1},
+    {-2,   7, -21,  98,  59, -17,   6, -2},
+    {-2,   7, -20,  79,  79, -20,   7, -2},
+    {-2,   6, -17,  59,  98, -21,   7, -2},
+    {-1,   5, -13,  38, 112, -17,   5, -1},
+    {-1,   2,  -6,  18, 123, -10,   3, -1}
+#elif FILTER_ALPHA == 60
+    /* alpha = 0.60 */
+    { 0,   0,   0, 128,   0,   0,   0, 0},
+    {-1,   3, -10, 123,  18,  -6,   2, -1},
+    {-1,   5, -17, 112,  38, -12,   4, -1},
+    {-1,   6, -20,  97,  58, -17,   6, -1},
+    {-1,   6, -20,  79,  79, -20,   6, -1},
+    {-1,   6, -17,  58,  97, -20,   6, -1},
+    {-1,   4, -12,  38, 112, -17,   5, -1},
+    {-1,   2,  -6,  18, 123, -10,   3, -1}
+#endif  /* FILTER_ALPHA */
+#endif  /* SUBPEL_SHIFTS==16 */
 };
 
 #if EDGE_PIXEL_FILTER > 0
@@ -76,139 +211,660 @@
 #define EDGE_GRAD_THRESH 128
 #define EDGE_GRADS2X2_THRESH 4
 /* TODO: Refine these filters */
-DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_ns[64][4*EDGE_PIXEL_FILTER_EXTEND*EDGE_PIXEL_FILTER_EXTEND]) =
+DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_ns[SUBPEL_SHIFTS*SUBPEL_SHIFTS][4*EDGE_PIXEL_FILTER_EXTEND*EDGE_PIXEL_FILTER_EXTEND]) =
 {
-#if EDGE_PIXEL_FILTER_EXTEND == 4
+#if SUBPEL_SHIFTS==16
+#if EDGE_PIXEL_FILTER_EXTEND == 2
     {0,   0,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,  -8, 124,  13,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0, -11, 112,  30,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0, -11,  94,  51,  -6,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,  0,  0,  0, -9, 73, 73, -9,  0,  0,  0,  0,  0,  0,  0, 0},
-    {0,   0,   0,   0,  -6,  51,  94, -11,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,  -3,  30, 112, -11,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,  -1,  13, 124,  -8,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,  -8,   0,   0,   0, 124,   0,   0,   0,  13,   0,   0,   0,  -1,   0, 0},
-    {0,  -8,  -1,   0,  -7, 120,  12,   0,  -1,  12,   1,   0,   0,   0,   0, 0},
-    {1,  -7,  -2,   0, -11, 108,  29,  -3,  -1,  11,   3,   0,   0,   0,   0, 0},
-    {0,  -6,  -3,   0, -10,  91,  49,  -6,  -1,   9,   5,   0,   0,   0,   0, 0},
-    {0, -4, -4,  0, -8, 70, 70, -8, -1,  7,  7, -1,  0,  0,  0, 0},
-    {0,  -3,  -6,   0,  -6,  49,  91, -10,   0,   5,   9,  -1,   0,   0,   0, 0},
-    {0,  -2,  -7,   1,  -3,  29, 108, -11,   0,   3,  11,  -1,   0,   0,   0, 0},
-    {0,  -1,  -8,   0,   0,  12, 120,  -7,   0,   1,  12,  -1,   0,   0,   0, 0},
-    {0, -11,   0,   0,   0, 112,   0,   0,   0,  30,   0,   0,   0,  -3,   0, 0},
-    {1, -11,  -1,   0,  -7, 108,  11,   0,  -2,  29,   3,   0,   0,  -3,   0, 0},
-    {1, -10,  -2,   0, -10,  98,  26,  -3,  -2,  26,   7,   0,   0,  -3,   0, 0},
-    {1,  -8,  -4,   0, -10,  82,  44,  -5,  -2,  22,  12,  -1,   0,  -2,  -1, 0},
-    {0, -6, -6,  0, -7, 64, 64, -7, -2, 17, 17, -2,  0, -2, -2, 0},
-    {0,  -4,  -8,   1,  -5,  44,  82, -10,  -1,  12,  22,  -2,   0,  -1,  -2, 0},
-    {0,  -2, -10,   1,  -3,  26,  98, -10,   0,   7,  26,  -2,   0,   0,  -3, 0},
-    {0,  -1, -11,   1,   0,  11, 108,  -7,   0,   3,  29,  -2,   0,   0,  -3, 0},
-    {0, -11,   0,   0,   0,  94,   0,   0,   0,  51,   0,   0,   0,  -6,   0, 0},
-    {0, -10,  -1,   0,  -6,  91,   9,   0,  -3,  49,   5,   0,   0,  -6,   0, 0},
-    {1, -10,  -2,   0,  -8,  82,  22,  -2,  -4,  44,  12,  -1,   0,  -5,  -1, 0},
-    {0, -8, -4,  0, -8, 70, 37, -4, -4, 37, 20, -2,  0, -4, -2, 0},
-    {0, -6, -6,  0, -6, 54, 54, -6, -3, 28, 28, -3,  0, -3, -3, 0},
-    {0, -4, -8,  0, -4, 37, 70, -8, -2, 20, 37, -4,  0, -2, -4, 0},
-    {0,  -2, -10,   1,  -2,  22,  82,  -8,  -1,  12,  44,  -4,   0,  -1,  -5, 0},
-    {0,  -1, -10,   0,   0,   9,  91,  -6,   0,   5,  49,  -3,   0,   0,  -6, 0},
-    {0, -9,  0,  0,  0, 73,  0,  0,  0, 73,  0,  0,  0, -9,  0, 0},
-    {0, -8, -1,  0, -4, 70,  7,  0, -4, 70,  7,  0,  0, -8, -1, 0},
-    {0, -7, -2,  0, -6, 64, 17, -2, -6, 64, 17, -2,  0, -7, -2, 0},
-    {0, -6, -3,  0, -6, 54, 28, -3, -6, 54, 28, -3,  0, -6, -3, 0},
-    {0, -5, -5,  0, -5, 42, 42, -5, -5, 42, 42, -5,  0, -5, -5, 0},
-    {0, -3, -6,  0, -3, 28, 54, -6, -3, 28, 54, -6,  0, -3, -6, 0},
-    {0, -2, -7,  0, -2, 17, 64, -6, -2, 17, 64, -6,  0, -2, -7, 0},
-    {0, -1, -8,  0,  0,  7, 70, -4,  0,  7, 70, -4,  0, -1, -8, 0},
-    {0,  -6,   0,   0,   0,  51,   0,   0,   0,  94,   0,   0,   0, -11,   0, 0},
-    {0,  -6,   0,   0,  -3,  49,   5,   0,  -6,  91,   9,   0,   0, -10,  -1, 0},
-    {0,  -5,  -1,   0,  -4,  44,  12,  -1,  -8,  82,  22,  -2,   1, -10,  -2, 0},
-    {0, -4, -2,  0, -4, 37, 20, -2, -8, 70, 37, -4,  0, -8, -4, 0},
-    {0, -3, -3,  0, -3, 28, 28, -3, -6, 54, 54, -6,  0, -6, -6, 0},
-    {0, -2, -4,  0, -2, 20, 37, -4, -4, 37, 70, -8,  0, -4, -8, 0},
-    {0,  -1,  -5,   0,  -1,  12,  44,  -4,  -2,  22,  82,  -8,   0,  -2, -10, 1},
-    {0,   0,  -6,   0,   0,   5,  49,  -3,   0,   9,  91,  -6,   0,  -1, -10, 0},
-    {0,  -3,   0,   0,   0,  30,   0,   0,   0, 112,   0,   0,   0, -11,   0, 0},
-    {0,  -3,   0,   0,  -2,  29,   3,   0,  -7, 108,  11,   0,   1, -11,  -1, 0},
-    {0,  -3,   0,   0,  -2,  26,   7,   0, -10,  98,  26,  -3,   1, -10,  -2, 0},
-    {0,  -2,  -1,   0,  -2,  22,  12,  -1, -10,  82,  44,  -5,   1,  -8,  -4, 0},
-    {0, -2, -2,  0, -2, 17, 17, -2, -7, 64, 64, -7,  0, -6, -6, 0},
-    {0,  -1,  -2,   0,  -1,  12,  22,  -2,  -5,  44,  82, -10,   0,  -4,  -8, 1},
-    {0,   0,  -3,   0,   0,   7,  26,  -2,  -3,  26,  98, -10,   0,  -2, -10, 1},
-    {0,   0,  -3,   0,   0,   3,  29,  -2,   0,  11, 108,  -7,   0,  -1, -11, 1},
-    {0,  -1,   0,   0,   0,  13,   0,   0,   0, 124,   0,   0,   0,  -8,   0, 0},
-    {0,   0,   0,   0,  -1,  12,   1,   0,  -8, 120,  12,   0,   0,  -7,  -1, 0},
-    {0,   0,   0,   0,  -1,  11,   3,   0, -11, 108,  29,  -3,   1,  -7,  -2, 0},
-    {0,   0,   0,   0,  -1,   9,   5,   0, -10,  91,  49,  -6,   0,  -6,  -3, 0},
-    {0,  0,  0,  0, -1,  7,  7, -1, -8, 70, 70, -8,  0, -4, -4, 0},
-    {0,   0,   0,   0,   0,   5,   9,  -1,  -6,  49,  91, -10,   0,  -3,  -6, 0},
-    {0,   0,   0,   0,   0,   3,  11,  -1,  -3,  29, 108, -11,   0,  -2,  -7, 1},
-    {0,   0,   0,   0,   0,   1,  12,  -1,   0,  12, 120,  -8,   0,  -1,  -7, 0}
-#elif EDGE_PIXEL_FILTER_EXTEND == 6
+    {0,   1,   0,   0,  -7, 128,   9,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   1,   1,   1, -13, 125,  18,  -7,   0,   1,   1,   0,   0,   0,   0, 0},
+    {0,   1,   1,   1, -18, 121,  28, -11,   0,   1,   1,   1,   1,   1,   0, 0},
+    {0,   1,   1,   1, -22, 116,  39, -15,   0,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -24, 109,  50, -19,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -25, 101,  61, -21,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -25,  92,  72, -23,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -25,  83,  83, -25,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -23,  72,  92, -25,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -21,  61, 101, -25,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -19,  50, 109, -24,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   0, -15,  39, 116, -22,   1,   1,   1,   0,   1,   1,   1, 1},
+    {1,   1,   1,   0, -11,  28, 121, -18,   1,   1,   1,   0,   1,   1,   0, 0},
+    {1,   1,   1,   0,  -7,  18, 125, -13,   0,   1,   1,   0,   0,   0,   0, 0},
+    {0,   0,   1,   0,  -3,   9, 128,  -7,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -7,   0,   0,   1, 128,   0,   0,   0,   9,   0,   0,   0,  -3,   0, 0},
+    {0,  -7,  -1,   0,  -7, 126,   8,   0,   0,   8,   1,   0,   0,   0,   0, 0},
+    {1,  -7,  -1,   1, -13, 124,  18,  -7,   0,   9,   2,   1,   0,   0,   0, 0},
+    {2,  -6,  -1,   1, -18, 120,  28, -11,  -1,   8,   2,   1,   1,   1,   1, 0},
+    {2,  -6,  -1,   1, -22, 115,  39, -15,  -1,   8,   3,   1,   1,   1,   1, 1},
+    {2,  -5,  -2,   1, -24, 109,  50, -18,  -1,   8,   4,   0,   1,   1,   1, 1},
+    {3,  -5,  -2,   1, -25, 101,  60, -21,  -1,   8,   5,   0,   1,   1,   1, 1},
+    {3,  -4,  -3,   3, -26,  92,  71, -23,  -1,   7,   6,  -1,   1,   1,   1, 1},
+    {3,  -3,  -3,   3, -25,  82,  82, -25,  -1,   6,   6,  -1,   1,   1,   1, 1},
+    {3,  -3,  -4,   3, -23,  71,  92, -26,  -1,   6,   7,  -1,   1,   1,   1, 1},
+    {1,  -2,  -5,   3, -21,  60, 101, -25,   0,   5,   8,  -1,   1,   1,   1, 1},
+    {1,  -2,  -5,   2, -18,  50, 109, -24,   0,   4,   8,  -1,   1,   1,   1, 1},
+    {1,  -1,  -6,   2, -15,  39, 115, -22,   1,   3,   8,  -1,   1,   1,   1, 1},
+    {1,  -1,  -6,   2, -11,  28, 120, -18,   1,   2,   8,  -1,   1,   1,   1, 0},
+    {1,  -1,  -7,   1,  -7,  18, 124, -13,   1,   2,   9,   0,   0,   0,   0, 0},
+    {0,  -1,  -7,   0,   0,   8, 126,  -7,   0,   1,   8,   0,   0,   0,   0, 0},
+    {0, -13,   0,   1,   1, 125,   1,   0,   1,  18,   1,   0,   0,  -7,   0, 0},
+    {1, -13,   0,   1,  -7, 124,   9,   1,  -1,  18,   2,   0,   0,  -7,   0, 0},
+    {2, -12,  -1,   1, -12, 122,  18,  -7,  -1,  18,   3,   1,   1,  -7,   1, 1},
+    {3, -12,  -2,   1, -17, 119,  28, -11,  -2,  18,   5,   1,   1,  -6,   1, 1},
+    {4, -11,  -3,   1, -21, 114,  38, -14,  -2,  17,   7,   1,   1,  -6,   1, 1},
+    {4, -10,  -4,   2, -23, 107,  49, -17,  -2,  16,   8,  -1,   2,  -5,   1, 1},
+    {4,  -9,  -5,   2, -24,  99,  60, -20,  -2,  15,  10,  -2,   2,  -5,   2, 1},
+    {4,  -8,  -6,   4, -25,  90,  70, -22,  -2,  14,  11,  -2,   2,  -4,   1, 1},
+    {4,  -8,  -8,   4, -24,  80,  80, -24,  -2,  12,  12,  -2,   1,   1,   1, 1},
+    {4,  -6,  -8,   4, -22,  70,  90, -25,  -2,  11,  14,  -2,   2,   1,  -4, 1},
+    {2,  -5,  -9,   4, -20,  60,  99, -24,  -2,  10,  15,  -2,   2,   2,  -5, 1},
+    {2,  -4, -10,   4, -17,  49, 107, -23,  -1,   8,  16,  -2,   2,   1,  -5, 1},
+    {1,  -3, -11,   4, -14,  38, 114, -21,   1,   7,  17,  -2,   1,   1,  -6, 1},
+    {1,  -2, -12,   3, -11,  28, 119, -17,   1,   5,  18,  -2,   1,   1,  -6, 1},
+    {1,  -1, -12,   2,  -7,  18, 122, -12,   1,   3,  18,  -1,   1,   1,  -7, 1},
+    {1,   0, -13,   1,   1,   9, 124,  -7,   0,   2,  18,  -1,   0,   0,  -7, 0},
+    {0, -18,   0,   1,   1, 121,   1,   1,   1,  28,   1,   1,   1, -11,   0, 0},
+    {2, -18,  -1,   1,  -6, 120,   8,   1,  -1,  28,   2,   1,   1, -11,   1, 0},
+    {3, -17,  -2,   1, -12, 119,  18,  -6,  -2,  28,   5,   1,   1, -11,   1, 1},
+    {4, -16,  -3,   2, -16, 115,  27, -10,  -3,  27,   7,   1,   1, -10,   1, 1},
+    {5, -15,  -4,   2, -20, 110,  37, -13,  -3,  26,  10,  -2,   2,  -9,   1, 1},
+    {5, -14,  -6,   2, -22, 104,  48, -17,  -4,  25,  12,  -3,   2,  -8,   2, 2},
+    {6, -12,  -7,   2, -23,  96,  59, -19,  -4,  24,  15,  -3,   2,  -7,  -3, 2},
+    {6, -11,  -8,   2, -23,  88,  69, -21,  -4,  22,  17,  -3,   2,  -6,  -4, 2},
+    {6, -10, -10,   6, -23,  79,  79, -23,  -4,  19,  19,  -4,   2,  -5,  -5, 2},
+    {2,  -8, -11,   6, -21,  69,  88, -23,  -3,  17,  22,  -4,   2,  -4,  -6, 2},
+    {2,  -7, -12,   6, -19,  59,  96, -23,  -3,  15,  24,  -4,   2,  -3,  -7, 2},
+    {2,  -6, -14,   5, -17,  48, 104, -22,  -3,  12,  25,  -4,   2,   2,  -8, 2},
+    {2,  -4, -15,   5, -13,  37, 110, -20,  -2,  10,  26,  -3,   2,   1,  -9, 1},
+    {2,  -3, -16,   4, -10,  27, 115, -16,   1,   7,  27,  -3,   1,   1, -10, 1},
+    {1,  -2, -17,   3,  -6,  18, 119, -12,   1,   5,  28,  -2,   1,   1, -11, 1},
+    {1,  -1, -18,   2,   1,   8, 120,  -6,   1,   2,  28,  -1,   1,   1, -11, 0},
+    {0, -22,   0,   1,   1, 116,   1,   1,   1,  39,   1,   1,   1, -15,   1, 1},
+    {2, -22,  -1,   1,  -6, 115,   8,   1,  -1,  39,   3,   1,   1, -15,   1, 1},
+    {4, -21,  -2,   1, -11, 114,  17,  -6,  -3,  38,   7,   1,   1, -14,   1, 1},
+    {5, -20,  -3,   2, -15, 110,  26,  -9,  -4,  37,  10,   2,   1, -13,  -2, 1},
+    {6, -18,  -5,   2, -18, 106,  36, -12,  -5,  36,  13,  -2,   2, -12,  -3, 2},
+    {7, -17,  -6,   2, -20, 100,  46, -15,  -5,  34,  17,  -4,   2, -11,  -4, 2},
+    {7, -15,  -8,   2, -21,  93,  56, -18,  -5,  32,  20,  -4,   2, -10,  -5, 2},
+    {7, -13, -10,   3, -22,  84,  66, -20,  -5,  30,  24,  -5,   2,  -9,  -6, 2},
+    {3, -12, -12,   3, -21,  76,  76, -21,  -5,  27,  27,  -5,   3,  -7,  -7, 3},
+    {3, -10, -13,   7, -20,  66,  84, -22,  -5,  24,  30,  -5,   2,  -6,  -9, 2},
+    {2,  -8, -15,   7, -18,  56,  93, -21,  -4,  20,  32,  -5,   2,  -5, -10, 2},
+    {2,  -6, -17,   7, -15,  46, 100, -20,  -4,  17,  34,  -5,   2,  -4, -11, 2},
+    {2,  -5, -18,   6, -12,  36, 106, -18,  -2,  13,  36,  -5,   2,  -3, -12, 2},
+    {2,  -3, -20,   5,  -9,  26, 110, -15,   2,  10,  37,  -4,   1,  -2, -13, 1},
+    {1,  -2, -21,   4,  -6,  17, 114, -11,   1,   7,  38,  -3,   1,   1, -14, 1},
+    {1,  -1, -22,   2,   1,   8, 115,  -6,   1,   3,  39,  -1,   1,   1, -15, 1},
+    {1, -24,   1,   1,   1, 109,   1,   1,   1,  50,   1,   1,   1, -19,   1, 1},
+    {2, -24,  -1,   1,  -5, 109,   8,   1,  -2,  50,   4,   1,   1, -18,   0, 1},
+    {4, -23,  -2,   2, -10, 107,  16,  -5,  -4,  49,   8,   2,   1, -17,  -1, 1},
+    {5, -22,  -4,   2, -14, 104,  25,  -8,  -6,  48,  12,   2,   2, -17,  -3, 2},
+    {7, -20,  -5,   2, -17, 100,  34, -11,  -6,  46,  17,  -4,   2, -15,  -4, 2},
+    {7, -19,  -7,   3, -19,  94,  44, -14,  -7,  44,  21,  -5,   3, -14,  -5, 2},
+    {8, -17,  -9,   3, -20,  87,  53, -16,  -8,  41,  25,  -6,   3, -12,  -6, 2},
+    {3, -15, -11,   3, -20,  80,  63, -18,  -7,  38,  30,  -6,   3, -11,  -7, 3},
+    {3, -13, -13,   3, -19,  72,  72, -19,  -7,  34,  34,  -7,   3,  -9,  -9, 3},
+    {3, -11, -15,   3, -18,  63,  80, -20,  -6,  30,  38,  -7,   3,  -7, -11, 3},
+    {3,  -9, -17,   8, -16,  53,  87, -20,  -6,  25,  41,  -8,   3,  -6, -12, 2},
+    {3,  -7, -19,   7, -14,  44,  94, -19,  -5,  21,  44,  -7,   3,  -5, -14, 2},
+    {2,  -5, -20,   7, -11,  34, 100, -17,  -4,  17,  46,  -6,   2,  -4, -15, 2},
+    {2,  -4, -22,   5,  -8,  25, 104, -14,   2,  12,  48,  -6,   2,  -3, -17, 2},
+    {2,  -2, -23,   4,  -5,  16, 107, -10,   2,   8,  49,  -4,   1,  -1, -17, 1},
+    {1,  -1, -24,   2,   1,   8, 109,  -5,   1,   4,  50,  -2,   1,   0, -18, 1},
+    {1, -25,   1,   1,   1, 101,   1,   1,   1,  61,   1,   1,   1, -21,   1, 1},
+    {3, -25,  -1,   1,  -5, 101,   8,   1,  -2,  60,   5,   1,   1, -21,   0, 1},
+    {4, -24,  -2,   2,  -9,  99,  15,  -5,  -5,  60,  10,   2,   2, -20,  -2, 1},
+    {6, -23,  -4,   2, -12,  96,  24,  -7,  -7,  59,  15,  -3,   2, -19,  -3, 2},
+    {7, -21,  -5,   2, -15,  93,  32, -10,  -8,  56,  20,  -5,   2, -18,  -4, 2},
+    {8, -20,  -8,   3, -17,  87,  41, -12,  -9,  53,  25,  -6,   3, -16,  -6, 2},
+    {3, -18,  -9,   3, -18,  81,  50, -14,  -9,  50,  31,  -7,   3, -14,  -7, 3},
+    {3, -16, -11,   3, -18,  75,  59, -16,  -9,  46,  36,  -8,   3, -13,  -9, 3},
+    {3, -13, -13,   3, -17,  67,  67, -17,  -9,  41,  41,  -9,   3, -11, -11, 3},
+    {3, -11, -16,   3, -16,  59,  75, -18,  -8,  36,  46,  -9,   3,  -9, -13, 3},
+    {3,  -9, -18,   3, -14,  50,  81, -18,  -7,  31,  50,  -9,   3,  -7, -14, 3},
+    {3,  -8, -20,   8, -12,  41,  87, -17,  -6,  25,  53,  -9,   3,  -6, -16, 2},
+    {2,  -5, -21,   7, -10,  32,  93, -15,  -5,  20,  56,  -8,   2,  -4, -18, 2},
+    {2,  -4, -23,   6,  -7,  24,  96, -12,  -3,  15,  59,  -7,   2,  -3, -19, 2},
+    {2,  -2, -24,   4,  -5,  15,  99,  -9,   2,  10,  60,  -5,   2,  -2, -20, 1},
+    {1,  -1, -25,   3,   1,   8, 101,  -5,   1,   5,  60,  -2,   1,   0, -21, 1},
+    {1, -25,   1,   1,   1,  92,   1,   1,   1,  72,   1,   1,   1, -23,   1, 1},
+    {3, -26,  -1,   1,  -4,  92,   7,   1,  -3,  71,   6,   1,   3, -23,  -1, 1},
+    {4, -25,  -2,   2,  -8,  90,  14,  -4,  -6,  70,  11,   1,   4, -22,  -2, 1},
+    {6, -23,  -4,   2, -11,  88,  22,  -6,  -8,  69,  17,  -4,   2, -21,  -3, 2},
+    {7, -22,  -5,   3, -13,  84,  30,  -9, -10,  66,  24,  -6,   2, -20,  -5, 2},
+    {3, -20,  -7,   3, -15,  80,  38, -11, -11,  63,  30,  -7,   3, -18,  -6, 3},
+    {3, -18,  -9,   3, -16,  75,  46, -13, -11,  59,  36,  -9,   3, -16,  -8, 3},
+    {3, -16, -11,   3, -16,  68,  54, -14, -11,  54,  42, -10,   3, -14, -10, 3},
+    {4, -14, -14,   4, -15,  61,  61, -15, -11,  48,  48, -11,   3, -12, -12, 3},
+    {3, -11, -16,   3, -14,  54,  68, -16, -10,  42,  54, -11,   3, -10, -14, 3},
+    {3,  -9, -18,   3, -13,  46,  75, -16,  -9,  36,  59, -11,   3,  -8, -16, 3},
+    {3,  -7, -20,   3, -11,  38,  80, -15,  -7,  30,  63, -11,   3,  -6, -18, 3},
+    {3,  -5, -22,   7,  -9,  30,  84, -13,  -6,  24,  66, -10,   2,  -5, -20, 2},
+    {2,  -4, -23,   6,  -6,  22,  88, -11,  -4,  17,  69,  -8,   2,  -3, -21, 2},
+    {2,  -2, -25,   4,  -4,  14,  90,  -8,   1,  11,  70,  -6,   1,  -2, -22, 4},
+    {1,  -1, -26,   3,   1,   7,  92,  -4,   1,   6,  71,  -3,   1,  -1, -23, 3},
+    {1, -25,   1,   1,   1,  83,   1,   1,   1,  83,   1,   1,   1, -25,   1, 1},
+    {3, -25,  -1,   1,  -3,  82,   6,   1,  -3,  82,   6,   1,   3, -25,  -1, 1},
+    {4, -24,  -2,   1,  -8,  80,  12,   1,  -8,  80,  12,   1,   4, -24,  -2, 1},
+    {6, -23,  -4,   2, -10,  79,  19,  -5, -10,  79,  19,  -5,   6, -23,  -4, 2},
+    {3, -21,  -5,   3, -12,  76,  27,  -7, -12,  76,  27,  -7,   3, -21,  -5, 3},
+    {3, -19,  -7,   3, -13,  72,  34,  -9, -13,  72,  34,  -9,   3, -19,  -7, 3},
+    {3, -17,  -9,   3, -13,  67,  41, -11, -13,  67,  41, -11,   3, -17,  -9, 3},
+    {4, -15, -11,   4, -14,  61,  48, -12, -14,  61,  48, -12,   3, -15, -11, 3},
+    {3, -13, -13,   3, -13,  55,  55, -13, -13,  55,  55, -13,   3, -13, -13, 3},
+    {4, -11, -15,   4, -12,  48,  61, -14, -12,  48,  61, -14,   3, -11, -15, 3},
+    {3,  -9, -17,   3, -11,  41,  67, -13, -11,  41,  67, -13,   3,  -9, -17, 3},
+    {3,  -7, -19,   3,  -9,  34,  72, -13,  -9,  34,  72, -13,   3,  -7, -19, 3},
+    {3,  -5, -21,   3,  -7,  27,  76, -12,  -7,  27,  76, -12,   3,  -5, -21, 3},
+    {2,  -4, -23,   6,  -5,  19,  79, -10,  -5,  19,  79, -10,   2,  -4, -23, 6},
+    {1,  -2, -24,   4,   1,  12,  80,  -8,   1,  12,  80,  -8,   1,  -2, -24, 4},
+    {1,  -1, -25,   3,   1,   6,  82,  -3,   1,   6,  82,  -3,   1,  -1, -25, 3},
+    {1, -23,   1,   1,   1,  72,   1,   1,   1,  92,   1,   1,   1, -25,   1, 1},
+    {3, -23,  -1,   1,  -3,  71,   6,   1,  -4,  92,   7,   1,   3, -26,  -1, 1},
+    {4, -22,  -2,   2,  -6,  70,  11,   1,  -8,  90,  14,  -4,   4, -25,  -2, 1},
+    {2, -21,  -3,   2,  -8,  69,  17,  -4, -11,  88,  22,  -6,   6, -23,  -4, 2},
+    {3, -20,  -5,   2, -10,  66,  24,  -6, -13,  84,  30,  -9,   7, -22,  -5, 2},
+    {3, -18,  -6,   3, -11,  63,  30,  -7, -15,  80,  38, -11,   3, -20,  -7, 3},
+    {3, -16,  -8,   3, -11,  59,  36,  -9, -16,  75,  46, -13,   3, -18,  -9, 3},
+    {3, -14, -10,   3, -11,  54,  42, -10, -16,  68,  54, -14,   3, -16, -11, 3},
+    {4, -12, -12,   4, -11,  48,  48, -11, -15,  61,  61, -15,   3, -14, -14, 3},
+    {3, -10, -14,   3, -10,  42,  54, -11, -14,  54,  68, -16,   3, -11, -16, 3},
+    {3,  -8, -16,   3,  -9,  36,  59, -11, -13,  46,  75, -16,   3,  -9, -18, 3},
+    {3,  -6, -18,   3,  -7,  30,  63, -11, -11,  38,  80, -15,   3,  -7, -20, 3},
+    {3,  -5, -20,   2,  -6,  24,  66, -10,  -9,  30,  84, -13,   2,  -5, -22, 7},
+    {2,  -3, -21,   2,  -4,  17,  69,  -8,  -6,  22,  88, -11,   2,  -4, -23, 6},
+    {2,  -2, -22,   4,   1,  11,  70,  -6,  -4,  14,  90,  -8,   1,  -2, -25, 4},
+    {1,  -1, -23,   3,   1,   6,  71,  -3,   1,   7,  92,  -4,   1,  -1, -26, 3},
+    {1, -21,   1,   1,   1,  61,   1,   1,   1, 101,   1,   1,   1, -25,   1, 1},
+    {1, -21,   0,   1,  -2,  60,   5,   1,  -5, 101,   8,   1,   3, -25,  -1, 1},
+    {2, -20,  -2,   2,  -5,  60,  10,   2,  -9,  99,  15,  -5,   4, -24,  -2, 1},
+    {2, -19,  -3,   2,  -7,  59,  15,  -3, -12,  96,  24,  -7,   6, -23,  -4, 2},
+    {2, -18,  -4,   2,  -8,  56,  20,  -5, -15,  93,  32, -10,   7, -21,  -5, 2},
+    {3, -16,  -6,   3,  -9,  53,  25,  -6, -17,  87,  41, -12,   8, -20,  -8, 2},
+    {3, -14,  -7,   3,  -9,  50,  31,  -7, -18,  81,  50, -14,   3, -18,  -9, 3},
+    {3, -13,  -9,   3,  -9,  46,  36,  -8, -18,  75,  59, -16,   3, -16, -11, 3},
+    {3, -11, -11,   3,  -9,  41,  41,  -9, -17,  67,  67, -17,   3, -13, -13, 3},
+    {3,  -9, -13,   3,  -8,  36,  46,  -9, -16,  59,  75, -18,   3, -11, -16, 3},
+    {3,  -7, -14,   3,  -7,  31,  50,  -9, -14,  50,  81, -18,   3,  -9, -18, 3},
+    {3,  -6, -16,   3,  -6,  25,  53,  -9, -12,  41,  87, -17,   2,  -8, -20, 8},
+    {2,  -4, -18,   2,  -5,  20,  56,  -8, -10,  32,  93, -15,   2,  -5, -21, 7},
+    {2,  -3, -19,   2,  -3,  15,  59,  -7,  -7,  24,  96, -12,   2,  -4, -23, 6},
+    {2,  -2, -20,   2,   2,  10,  60,  -5,  -5,  15,  99,  -9,   1,  -2, -24, 4},
+    {1,   0, -21,   1,   1,   5,  60,  -2,   1,   8, 101,  -5,   1,  -1, -25, 3},
+    {1, -19,   1,   1,   1,  50,   1,   1,   1, 109,   1,   1,   1, -24,   1, 1},
+    {1, -18,   0,   1,  -2,  50,   4,   1,  -5, 109,   8,   1,   2, -24,  -1, 1},
+    {2, -17,  -1,   2,  -4,  49,   8,   1, -10, 107,  16,  -5,   4, -23,  -2, 1},
+    {2, -17,  -3,   2,  -6,  48,  12,   2, -14, 104,  25,  -8,   5, -22,  -4, 2},
+    {2, -15,  -4,   2,  -6,  46,  17,  -4, -17, 100,  34, -11,   7, -20,  -5, 2},
+    {3, -14,  -5,   3,  -7,  44,  21,  -5, -19,  94,  44, -14,   7, -19,  -7, 2},
+    {3, -12,  -6,   3,  -8,  41,  25,  -6, -20,  87,  53, -16,   8, -17,  -9, 2},
+    {3, -11,  -7,   3,  -7,  38,  30,  -6, -20,  80,  63, -18,   3, -15, -11, 3},
+    {3,  -9,  -9,   3,  -7,  34,  34,  -7, -19,  72,  72, -19,   3, -13, -13, 3},
+    {3,  -7, -11,   3,  -6,  30,  38,  -7, -18,  63,  80, -20,   3, -11, -15, 3},
+    {3,  -6, -12,   3,  -6,  25,  41,  -8, -16,  53,  87, -20,   2,  -9, -17, 8},
+    {3,  -5, -14,   3,  -5,  21,  44,  -7, -14,  44,  94, -19,   2,  -7, -19, 7},
+    {2,  -4, -15,   2,  -4,  17,  46,  -6, -11,  34, 100, -17,   2,  -5, -20, 7},
+    {2,  -3, -17,   2,   2,  12,  48,  -6,  -8,  25, 104, -14,   2,  -4, -22, 5},
+    {2,  -1, -17,   2,   1,   8,  49,  -4,  -5,  16, 107, -10,   1,  -2, -23, 4},
+    {1,   0, -18,   1,   1,   4,  50,  -2,   1,   8, 109,  -5,   1,  -1, -24, 2},
+    {1, -15,   1,   1,   1,  39,   1,   1,   1, 116,   1,   1,   0, -22,   0, 1},
+    {1, -15,   1,   1,  -1,  39,   3,   1,  -6, 115,   8,   1,   2, -22,  -1, 1},
+    {1, -14,   1,   1,  -3,  38,   7,   1, -11, 114,  17,  -6,   4, -21,  -2, 1},
+    {2, -13,  -2,   2,  -4,  37,  10,   1, -15, 110,  26,  -9,   5, -20,  -3, 1},
+    {2, -12,  -2,   2,  -5,  36,  13,  -3, -18, 106,  36, -12,   6, -18,  -5, 2},
+    {2, -11,  -4,   2,  -5,  34,  17,  -4, -20, 100,  46, -15,   7, -17,  -6, 2},
+    {2, -10,  -5,   2,  -5,  32,  20,  -4, -21,  93,  56, -18,   7, -15,  -8, 2},
+    {3,  -9,  -6,   2,  -5,  30,  24,  -5, -22,  84,  66, -20,   7, -13, -10, 2},
+    {3,  -7,  -7,   3,  -5,  27,  27,  -5, -21,  76,  76, -21,   3, -12, -12, 3},
+    {3,  -6,  -9,   2,  -5,  24,  30,  -5, -20,  66,  84, -22,   2, -10, -13, 7},
+    {2,  -5, -10,   2,  -4,  20,  32,  -5, -18,  56,  93, -21,   2,  -8, -15, 7},
+    {2,  -4, -11,   2,  -4,  17,  34,  -5, -15,  46, 100, -20,   2,  -6, -17, 7},
+    {2,  -2, -12,   2,  -3,  13,  36,  -5, -12,  36, 106, -18,   2,  -5, -18, 6},
+    {2,  -2, -13,   2,   1,  10,  37,  -4,  -9,  26, 110, -15,   1,  -3, -20, 5},
+    {1,   1, -14,   1,   1,   7,  38,  -3,  -6,  17, 114, -11,   1,  -2, -21, 4},
+    {1,   1, -15,   1,   1,   3,  39,  -1,   1,   8, 115,  -6,   1,  -1, -22, 2},
+    {1, -11,   1,   1,   1,  28,   1,   1,   1, 121,   1,   0,   0, -18,   0, 0},
+    {1, -11,   1,   1,  -1,  28,   2,   1,  -6, 120,   8,   1,   2, -18,  -1, 0},
+    {1, -11,   1,   1,  -2,  28,   5,   1, -12, 119,  18,  -6,   3, -17,  -2, 1},
+    {2, -10,   1,   1,  -3,  27,   7,   1, -16, 115,  27, -10,   4, -16,  -3, 1},
+    {2,  -9,   2,   1,  -3,  26,  10,  -2, -20, 110,  37, -13,   5, -15,  -4, 1},
+    {2,  -8,   2,   2,  -4,  25,  12,  -3, -22, 104,  48, -17,   5, -14,  -6, 2},
+    {2,  -7,  -3,   2,  -4,  24,  15,  -3, -23,  96,  59, -19,   6, -12,  -7, 2},
+    {2,  -6,  -4,   2,  -4,  22,  17,  -3, -23,  88,  69, -21,   6, -11,  -8, 2},
+    {2,  -5,  -5,   2,  -4,  19,  19,  -4, -23,  79,  79, -23,   6, -10, -10, 6},
+    {2,  -4,  -6,   2,  -3,  17,  22,  -4, -21,  69,  88, -23,   2,  -8, -11, 6},
+    {2,  -3,  -7,   2,  -3,  15,  24,  -4, -19,  59,  96, -23,   2,  -7, -12, 6},
+    {2,   2,  -8,   2,  -3,  12,  25,  -4, -17,  48, 104, -22,   2,  -6, -14, 5},
+    {2,   2,  -9,   1,  -2,  10,  26,  -3, -13,  37, 110, -20,   1,  -4, -15, 5},
+    {2,   1, -10,   1,   1,   7,  27,  -3, -10,  27, 115, -16,   1,  -3, -16, 4},
+    {1,   1, -11,   1,   1,   5,  28,  -2,  -6,  18, 119, -12,   1,  -2, -17, 3},
+    {1,   1, -11,   1,   1,   2,  28,  -1,   1,   8, 120,  -6,   0,  -1, -18, 2},
+    {1,  -7,   0,   0,   1,  18,   1,   0,   1, 125,   1,   0,   0, -13,   0, 0},
+    {1,  -7,   1,   0,  -1,  18,   2,   0,  -7, 124,   9,   0,   1, -13,   0, 0},
+    {1,  -7,   1,   1,  -1,  18,   3,   1, -12, 122,  18,  -7,   2, -12,  -1, 1},
+    {1,  -6,   1,   1,  -2,  18,   5,   1, -17, 119,  28, -11,   3, -12,  -2, 1},
+    {1,  -6,   1,   1,  -2,  17,   7,   1, -21, 114,  38, -14,   4, -11,  -3, 1},
+    {2,  -5,   2,   1,  -2,  16,   8,  -1, -23, 107,  49, -17,   4, -10,  -4, 1},
+    {2,  -5,   2,   2,  -2,  15,  10,  -2, -24,  99,  60, -20,   4,  -9,  -5, 1},
+    {2,  -4,   1,   1,  -2,  14,  11,  -2, -25,  90,  70, -22,   4,  -8,  -6, 4},
+    {1,   1,   1,   1,  -2,  12,  12,  -2, -24,  80,  80, -24,   4,  -8,  -8, 4},
+    {2,   1,  -4,   1,  -2,  11,  14,  -2, -22,  70,  90, -25,   4,  -6,  -8, 4},
+    {2,   2,  -5,   2,  -2,  10,  15,  -2, -20,  60,  99, -24,   1,  -5,  -9, 4},
+    {2,   2,  -5,   1,  -1,   8,  16,  -2, -17,  49, 107, -23,   1,  -4, -10, 4},
+    {1,   1,  -6,   1,   1,   7,  17,  -2, -14,  38, 114, -21,   1,  -3, -11, 4},
+    {1,   1,  -6,   1,   1,   5,  18,  -2, -11,  28, 119, -17,   1,  -2, -12, 3},
+    {1,   1,  -7,   1,   1,   3,  18,  -1,  -7,  18, 122, -12,   1,  -1, -12, 2},
+    {1,   1,  -7,   0,   0,   2,  18,  -1,   0,   9, 124,  -7,   0,   0, -13, 1},
+    {0,  -3,   0,   0,   0,   9,   0,   0,   1, 128,   0,   0,   0,  -7,   0, 0},
+    {0,   0,   0,   0,  -1,   8,   1,   0,  -7, 126,   8,   0,   0,  -7,   0, 0},
+    {1,   1,   0,   0,   0,   9,   2,   0, -13, 124,  18,  -7,   1,  -7,  -1, 0},
+    {1,   1,   1,   1,  -1,   8,   2,   1, -18, 120,  28, -11,   2,  -6,  -1, 0},
+    {1,   1,   1,   1,  -1,   8,   3,   1, -22, 115,  39, -15,   2,  -6,  -1, 1},
+    {1,   1,   1,   1,  -1,   8,   4,   0, -24, 109,  50, -18,   2,  -5,  -2, 1},
+    {1,   1,   1,   1,  -1,   8,   5,   0, -25, 101,  60, -21,   3,  -5,  -2, 1},
+    {1,   1,   1,   1,  -1,   7,   6,  -1, -26,  92,  71, -23,   3,  -4,  -3, 3},
+    {1,   1,   1,   1,  -1,   6,   6,  -1, -25,  82,  82, -25,   3,  -3,  -3, 3},
+    {1,   1,   1,   1,  -1,   6,   7,  -1, -23,  71,  92, -26,   3,  -3,  -4, 3},
+    {1,   1,   1,   1,   0,   5,   8,  -1, -21,  60, 101, -25,   1,  -2,  -5, 3},
+    {1,   1,   1,   1,   0,   4,   8,  -1, -18,  50, 109, -24,   1,  -2,  -5, 2},
+    {1,   1,   1,   1,   1,   3,   8,  -1, -15,  39, 115, -22,   1,  -1,  -6, 2},
+    {1,   1,   1,   1,   1,   2,   8,  -1, -11,  28, 120, -18,   0,  -1,  -6, 2},
+    {1,   1,   0,   0,   0,   2,   9,   0,  -7,  18, 124, -13,   0,  -1,  -7, 1},
+    {0,   0,   0,   0,   0,   1,   8,  -1,   0,   8, 126,  -7,   0,   0,  -7, 0}
+#elif EDGE_PIXEL_FILTER_EXTEND == 3
     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3, -11, 124,  15,  -4,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   4, -17, 114,  34,  -9,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   4, -19,  98,  56, -14,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   4, -18,  78,  78, -18,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3, -14,  56,  98, -19,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,  -9,  34, 114, -17,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,  -4,  15, 124, -11,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   3,   0,   0,   0,   0,   0, -11,   0,   0,   0,   0,   0, 124,   0,   0,   0,   0,   0,  15,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   1,   0,   0, 0},
-    {0,   0,   3,   0,   0,   0,   0,   1, -11,  -1,   0,   0,   3, -11, 121,  15,  -4,   0,   0,  -1,  15,   2,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   3,   1,   0,   0,   0,   1, -10,  -3,   1,   0,   4, -17, 111,  34,  -9,   2,   0,  -2,  14,   4,  -1,   0,   0,   0,  -4,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   2,   1,   0,   0,   0,   2,  -8,  -5,   1,   0,   4, -18,  95,  54, -13,   3,   0,  -2,  12,   7,  -2,   0,   0,   0,  -3,  -2,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   2,   2,   0,   0,   0,   1,  -7,  -7,   1,   0,   4, -17,  76,  76, -17,   4,   0,  -2,   9,   9,  -2,   0,   0,   0,  -2,  -2,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   1,   2,   0,   0,   0,   1,  -5,  -8,   2,   0,   3, -13,  54,  95, -18,   4,   0,  -2,   7,  12,  -2,   0,   0,   0,  -2,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   1,   3,   0,   0,   0,   1,  -3, -10,   1,   0,   2,  -9,  34, 111, -17,   4,   0,  -1,   4,  14,  -2,   0,   0,   0,  -1,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   0,   3,   0,   0,   0,   0,  -1, -11,   1,   0,   0,  -4,  15, 121, -11,   3,   0,   0,   2,  15,  -1,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   0, -17,   0,   0,   0,   0,   0, 114,   0,   0,   0,   0,   0,  34,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,   2,   0,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   1, -17,  -2,   0,   0,   3, -10, 111,  14,  -4,   0,   1,  -3,  34,   4,  -1,   0,   0,   1,  -9,  -1,   0,   0,   0,   0,   2,   0,   0, 0},
-    {0,   0,   4,   1,   0,   0,  -1,   2, -15,  -5,   1,   0,   4, -15, 101,  31,  -8,   1,   1,  -5,  31,   9,  -2,   0,   0,   1,  -8,  -2,   1,   0,   0,   0,   1,   0,   0, 0},
-    {0,  -1,   3,   2,   0,   0,  -1,   2, -13,  -7,   2,   0,   4, -17,  87,  50, -12,   2,   1,  -5,  26,  15,  -4,   1,   0,   1,  -7,  -4,   1,   0,   0,   0,   1,   1,   0, 0},
-    {0,  -1,   3,   3,  -1,   0,   0,   2, -10, -10,   2,   0,   3, -16,  69,  69, -16,   3,   1,  -5,  21,  21,  -5,   1,   0,   1,  -5,  -5,   1,   0,   0,   0,   1,   1,   0, 0},
-    {0,   0,   2,   3,  -1,   0,   0,   2,  -7, -13,   2,  -1,   2, -12,  50,  87, -17,   4,   1,  -4,  15,  26,  -5,   1,   0,   1,  -4,  -7,   1,   0,   0,   0,   1,   1,   0, 0},
-    {0,   0,   1,   4,   0,   0,   0,   1,  -5, -15,   2,  -1,   1,  -8,  31, 101, -15,   4,   0,  -2,   9,  31,  -5,   1,   0,   1,  -2,  -8,   1,   0,   0,   0,   0,   1,   0, 0},
-    {0,   0,   0,   4,   0,   0,   0,   0,  -2, -17,   1,   0,   0,  -4,  14, 111, -10,   3,   0,  -1,   4,  34,  -3,   1,   0,   0,  -1,  -9,   1,   0,   0,   0,   0,   2,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   0, -19,   0,   0,   0,   0,   0,  98,   0,   0,   0,   0,   0,  56,   0,   0,   0,   0,   0, -14,   0,   0,   0,   0,   0,   3,   0,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   2, -18,  -2,   0,   0,   2,  -8,  95,  12,  -3,   0,   1,  -5,  54,   7,  -2,   0,   0,   1, -13,  -2,   0,   0,   0,   0,   3,   0,   0, 0},
-    {0,  -1,   4,   1,   0,   0,  -1,   2, -17,  -5,   1,   0,   3, -13,  87,  26,  -7,   1,   2,  -7,  50,  15,  -4,   1,   0,   2, -12,  -4,   1,   0,   0,   0,   2,   1,   0, 0},
-    {0,  -1,   3,   2,   0,   0,  -1,   3, -15,  -8,   2,   0,   3, -15,  75,  43, -11,   2,   2,  -8,  43,  24,  -6,   1,   0,   2, -10,  -6,   1,   0,   0,   0,   2,   1,   0, 0},
-    {0,  -1,   3,   3,  -1,   0,  -1,   2, -12, -12,   2,  -1,   3, -13,  59,  59, -13,   3,   2,  -8,  34,  34,  -8,   2,   0,   2,  -8,  -8,   2,   0,   0,   0,   2,   2,   0, 0},
-    {0,   0,   2,   3,  -1,   0,   0,   2,  -8, -15,   3,  -1,   2, -11,  43,  75, -15,   3,   1,  -6,  24,  43,  -8,   2,   0,   1,  -6, -10,   2,   0,   0,   0,   1,   2,   0, 0},
-    {0,   0,   1,   4,  -1,   0,   0,   1,  -5, -17,   2,  -1,   1,  -7,  26,  87, -13,   3,   1,  -4,  15,  50,  -7,   2,   0,   1,  -4, -12,   2,   0,   0,   0,   1,   2,   0, 0},
-    {0,   0,   0,   4,   0,   0,   0,   0,  -2, -18,   2,   0,   0,  -3,  12,  95,  -8,   2,   0,  -2,   7,  54,  -5,   1,   0,   0,  -2, -13,   1,   0,   0,   0,   0,   3,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   0, -18,   0,   0,   0,   0,   0,  78,   0,   0,   0,   0,   0,  78,   0,   0,   0,   0,   0, -18,   0,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   4,   0,   0,   0,   0,   1, -17,  -2,   0,   0,   2,  -7,  76,   9,  -2,   0,   2,  -7,  76,   9,  -2,   0,   0,   1, -17,  -2,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   3,   1,   0,   0,  -1,   2, -16,  -5,   1,   0,   3, -10,  69,  21,  -5,   1,   3, -10,  69,  21,  -5,   1,  -1,   2, -16,  -5,   1,   0,   0,   0,   3,   1,   0, 0},
-    {0,  -1,   3,   2,   0,   0,  -1,   2, -13,  -8,   2,   0,   3, -12,  59,  34,  -8,   2,   3, -12,  59,  34,  -8,   2,  -1,   2, -13,  -8,   2,   0,   0,  -1,   3,   2,   0, 0},
-    {0,   0,   2,   2,   0,   0,   0,   2, -10, -10,   2,   0,   2, -10,  47,  47, -10,   2,   2, -11,  47,  47, -11,   2,   0,   2, -11, -11,   2,   0,   0,   0,   2,   2,   0, 0},
-    {0,   0,   2,   3,  -1,   0,   0,   2,  -8, -13,   2,  -1,   2,  -8,  34,  59, -12,   3,   2,  -8,  34,  59, -12,   3,   0,   2,  -8, -13,   2,  -1,   0,   0,   2,   3,  -1, 0},
-    {0,   0,   1,   3,   0,   0,   0,   1,  -5, -16,   2,  -1,   1,  -5,  21,  69, -10,   3,   1,  -5,  21,  69, -10,   3,   0,   1,  -5, -16,   2,  -1,   0,   0,   1,   3,   0, 0},
-    {0,   0,   0,   4,   0,   0,   0,   0,  -2, -17,   1,   0,   0,  -2,   9,  76,  -7,   2,   0,  -2,   9,  76,  -7,   2,   0,   0,  -2, -17,   1,   0,   0,   0,   0,   4,   0, 0},
-    {0,   0,   3,   0,   0,   0,   0,   0, -14,   0,   0,   0,   0,   0,  56,   0,   0,   0,   0,   0,  98,   0,   0,   0,   0,   0, -19,   0,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   3,   0,   0,   0,   0,   1, -13,  -2,   0,   0,   1,  -5,  54,   7,  -2,   0,   2,  -8,  95,  12,  -3,   0,   0,   2, -18,  -2,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   2,   1,   0,   0,   0,   2, -12,  -4,   1,   0,   2,  -7,  50,  15,  -4,   1,   3, -13,  87,  26,  -7,   1,  -1,   2, -17,  -5,   1,   0,   0,  -1,   4,   1,   0, 0},
-    {0,   0,   2,   1,   0,   0,   0,   2, -11,  -6,   1,   0,   2,  -8,  43,  24,  -6,   1,   3, -15,  75,  43, -10,   2,  -1,   3, -15,  -8,   2,   0,   0,  -1,   3,   2,   0, 0},
-    {0,   0,   2,   2,   0,   0,   0,   2,  -8,  -8,   2,   0,   2,  -8,  34,  34,  -8,   2,   3, -13,  59,  59, -13,   3,  -1,   2, -12, -12,   2,  -1,   0,  -1,   3,   3,  -1, 0},
-    {0,   0,   1,   2,   0,   0,   0,   1,  -6, -11,   2,   0,   1,  -6,  24,  43,  -8,   2,   2, -10,  43,  75, -15,   3,   0,   2,  -8, -15,   3,  -1,   0,   0,   2,   3,  -1, 0},
-    {0,   0,   1,   2,   0,   0,   0,   1,  -4, -12,   2,   0,   1,  -4,  15,  50,  -7,   2,   1,  -7,  26,  87, -13,   3,   0,   1,  -5, -17,   2,  -1,   0,   0,   1,   4,  -1, 0},
-    {0,   0,   0,   3,   0,   0,   0,   0,  -2, -13,   1,   0,   0,  -2,   7,  54,  -5,   1,   0,  -3,  12,  95,  -8,   2,   0,   0,  -2, -18,   2,   0,   0,   0,   0,   4,   0, 0},
-    {0,   0,   2,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,  34,   0,   0,   0,   0,   0, 114,   0,   0,   0,   0,   0, -17,   0,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   2,   0,   0,   0,   0,   1,  -9,  -1,   0,   0,   1,  -3,  34,   4,  -1,   0,   3, -10, 111,  14,  -4,   0,   0,   1, -17,  -2,   0,   0,   0,   0,   4,   0,   0, 0},
-    {0,   0,   1,   0,   0,   0,   0,   1,  -8,  -2,   1,   0,   1,  -5,  31,   9,  -2,   0,   4, -15, 101,  31,  -8,   1,   0,   2, -15,  -5,   1,   0,   0,  -1,   4,   1,   0, 0},
-    {0,   0,   1,   1,   0,   0,   0,   1,  -7,  -4,   1,   0,   1,  -5,  26,  15,  -4,   1,   4, -17,  87,  50, -12,   2,  -1,   2, -13,  -7,   2,   0,   0,  -1,   3,   2,   0, 0},
-    {0,   0,   1,   1,   0,   0,   0,   1,  -5,  -5,   1,   0,   1,  -5,  21,  21,  -5,   1,   3, -16,  69,  69, -16,   3,   0,   2, -10, -10,   2,   0,   0,  -1,   3,   3,  -1, 0},
-    {0,   0,   1,   1,   0,   0,   0,   1,  -4,  -7,   1,   0,   1,  -4,  15,  26,  -5,   1,   2, -12,  50,  87, -17,   4,   0,   2,  -7, -13,   2,  -1,   0,   0,   2,   3,  -1, 0},
-    {0,   0,   0,   1,   0,   0,   0,   1,  -2,  -8,   1,   0,   0,  -2,   9,  31,  -5,   1,   1,  -8,  31, 101, -15,   4,   0,   1,  -5, -15,   2,   0,   0,   0,   1,   4,  -1, 0},
-    {0,   0,   0,   2,   0,   0,   0,   0,  -1,  -9,   1,   0,   0,  -1,   4,  34,  -3,   1,   0,  -4,  14, 111, -10,   3,   0,   0,  -2, -17,   1,   0,   0,   0,   0,   4,   0, 0},
-    {0,   0,   1,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,  15,   0,   0,   0,   0,   0, 124,   0,   0,   0,   0,   0, -11,   0,   0,   0,   0,   0,   3,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,  -1,  15,   2,   0,   0,   3, -11, 121,  15,  -4,   0,   0,   1, -11,  -1,   0,   0,   0,   0,   3,   0,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -4,  -1,   0,   0,   0,  -2,  14,   4,  -1,   0,   4, -17, 111,  34,  -9,   2,   0,   1, -10,  -3,   1,   0,   0,   0,   3,   1,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -3,  -2,   0,   0,   0,  -2,  12,   7,  -2,   0,   4, -18,  95,  54, -13,   3,   0,   2,  -8,  -5,   1,   0,   0,   0,   2,   1,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -2,  -2,   0,   0,   0,  -2,   9,   9,  -2,   0,   4, -17,  76,  76, -17,   4,   0,   1,  -7,  -7,   1,   0,   0,   0,   2,   2,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -2,  -3,   0,   0,   0,  -2,   7,  12,  -2,   0,   3, -13,  54,  95, -18,   4,   0,   1,  -5,  -8,   2,   0,   0,   0,   1,   2,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,  -1,  -4,   0,   0,   0,  -1,   4,  14,  -2,   0,   2,  -9,  34, 111, -17,   4,   0,   1,  -3, -10,   1,   0,   0,   0,   1,   3,   0, 0},
-    {0,   0,   0,   0,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   2,  15,  -1,   0,   0,  -4,  15, 121, -11,   3,   0,   0,  -1, -11,   1,   0,   0,   0,   0,   3,   0, 0}
-#endif
+    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,  -8, 127,   8,  -4,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7, -14, 124,  17,  -9,   5,   0,   0,   0,   0,   0,   0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,  10, -19, 120,  27, -13,   7,   0,   0,   0,   0,   0,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,   0,   0,  12, -23, 115,  38, -17,   9,   0,  -1,   0,   0,   0,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  14, -26, 108,  49, -20,  11,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  15, -28, 100,  60, -23,  13,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  15, -28,  91,  70, -26,  14,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,  -1,   0,  -1,   0,   0,  -1,   0,  15, -27,  81,  81, -27,  15,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  14, -26,  70,  91, -28,  15,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  13, -23,  60, 100, -28,  15,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,  -1,   0,  11, -20,  49, 108, -26,  14,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,  -1,   0,   9, -17,  38, 115, -23,  12,   0,   0,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   7, -13,  27, 120, -19,  10,   0,   0,   0,   0,   0,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   5,  -9,  17, 124, -14,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,  -4,   8, 127,  -8,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   3,   0,   0,   0,   0,   0,  -8,   0,   0,   0,   0,   0, 127,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   2,   0,   0, 0},
+    {0,   0,   4,   0,   0,   0,   0,   0,  -7,  -1,   0,   0,   4,  -7, 126,   8,  -4,   0,   0,   0,   8,   1,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   4,   0,   0,   0,  -1,   1,  -7,  -1,   0,   0,   7, -14, 124,  17,  -8,   5,   0,  -1,   8,   1,  -1,   0,   0,   0,  -4,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   3,   1,  -1,   0,  -1,   1,  -7,  -2,   0,   0,  10, -19, 120,  27, -12,   7,   0,  -1,   8,   2,  -1,   0,  -1,   0,  -4,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   3,   1,  -1,   0,  -1,   1,  -7,  -3,   1,   0,  12, -23, 114,  38, -16,  10,   0,  -2,   7,   2,  -1,   0,   0,   0,  -4,  -2,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   3,   1,  -1,   0,  -1,   1,  -7,  -3,   1,  -1,  14, -26, 107,  48, -20,  12,   1,  -2,   7,   3,  -2,   0,   0,   0,  -4,  -2,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   2,   1,  -1,   0,  -1,   1,  -6,  -4,   1,  -1,  15, -27,  99,  59, -23,  13,   1,  -2,   6,   4,  -2,   0,   0,   0,  -4,  -2,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   2,   2,  -1,   0,  -1,   1,  -6,  -5,   1,  -1,  15, -28,  90,  70, -25,  14,   1,  -2,   6,   4,  -2,   0,   0,   0,  -3,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,  -1,   2,   2,  -1,  -1,  -1,   1,  -5,  -5,   1,  -1,  15, -27,  80,  80, -27,  15,   1,  -2,   5,   5,  -2,   1,   0,   0,  -3,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   2,   2,  -1,   0,  -1,   1,  -5,  -6,   1,  -1,  14, -25,  70,  90, -28,  15,   0,  -2,   4,   6,  -2,   1,   0,   0,  -3,  -3,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   1,   2,  -1,   0,  -1,   1,  -4,  -6,   1,  -1,  13, -23,  59,  99, -27,  15,   0,  -2,   4,   6,  -2,   1,   0,   0,  -2,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   1,   3,  -1,   0,  -1,   1,  -3,  -7,   1,  -1,  12, -20,  48, 107, -26,  14,   0,  -2,   3,   7,  -2,   1,   0,   0,  -2,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   1,   3,  -1,   0,   0,   1,  -3,  -7,   1,  -1,  10, -16,  38, 114, -23,  12,   0,  -1,   2,   7,  -2,   0,   0,   0,  -2,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   1,   3,  -1,   0,   0,   0,  -2,  -7,   1,  -1,   7, -12,  27, 120, -19,  10,   0,  -1,   2,   8,  -1,   0,   0,   0,  -1,  -4,   0,  -1,   0,   0,   0,   0,   0, 0},
+    {0,   0,   0,   4,  -1,   0,   0,   0,  -1,  -7,   1,  -1,   5,  -8,  17, 124, -14,   7,   0,  -1,   1,   8,  -1,   0,   0,   0,  -1,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   0,   4,   0,   0,   0,   0,  -1,  -7,   0,   0,   0,  -4,   8, 126,  -7,   4,   0,   0,   1,   8,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   7,   0,   0,   0,   0,   0, -14,   0,   0,   0,  -1,   0, 124,   0,  -1,   0,   0,   0,  17,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,   5,   0,   0, 0},
+    {0,  -1,   7,   0,   0,   0,  -1,   1, -14,  -1,   0,   0,   4,  -7, 124,   8,  -4,   0,   0,  -1,  17,   1,  -1,   0,   0,   0,  -8,  -1,   0,   0,   0,   0,   5,   0,   0, 0},
+    {0,  -1,   7,   1,  -1,   0,  -1,   1, -14,  -2,   0,   0,   7, -14, 121,  17,  -8,   5,   1,  -2,  17,   2,  -2,   0,  -1,   0,  -8,  -2,   0,   0,   0,   0,   5,   0,   0, 0},
+    {0,  -1,   6,   1,  -1,   0,  -2,   2, -13,  -3,   1,   0,   9, -19, 117,  27, -12,   7,   1,  -3,  16,   3,  -2,   0,  -1,   1,  -8,  -2,   0,   0,   0,   0,   4,   0,   0, 0},
+    {0,  -2,   6,   2,  -1,   0,  -2,   2, -13,  -5,   1,   0,  12, -23, 112,  37, -16,   9,   1,  -4,  15,   5,  -3,   1,  -1,   1,  -8,  -3,   1,   0,   0,   0,   4,   0,   0, 0},
+    {0,  -2,   6,   2,  -2,   0,  -2,   2, -12,  -6,   2,  -2,  13, -25, 105,  47, -20,  11,   1,  -4,  15,   6,  -3,   1,   0,   1,  -7,  -4,   1,   0,   0,   0,   4,   0,   0, 0},
+    {-1,  -2,   5,   3,  -2,   0,  -2,   2, -11,  -7,   2,  -2,  14, -27,  97,  58, -23,  13,   2,  -4,  13,   8,  -4,   1,   0,   1,  -7,  -4,   1,   0,   0,   0,   4,   0,   0, 0},
+    {-1,  -2,   5,   3,  -2,  -1,  -2,   2, -10,  -8,   2,  -2,  15, -27,  88,  69, -25,  14,   2,  -4,  12,   9,  -4,   2,  -1,   1,  -6,  -5,   1,  -1,  -1,   0,   3,   2,   0, 0},
+    {-1,  -2,   4,   4,  -2,  -1,  -2,   2,  -9,  -9,   2,  -2,  15, -27,  79,  79, -27,  15,   2,  -4,  11,  11,  -4,   2,  -1,   1,  -6,  -6,   1,  -1,  -1,  -1,   3,   3,   0, 0},
+    {-1,  -2,   3,   5,  -2,  -1,  -2,   2,  -8, -10,   2,  -2,  14, -25,  69,  88, -27,  15,   2,  -4,   9,  12,  -4,   2,  -1,   1,  -5,  -6,   1,  -1,  -1,   0,   2,   3,   0, 0},
+    {-1,  -2,   3,   5,  -2,   0,  -2,   2,  -7, -11,   2,  -2,  13, -23,  58,  97, -27,  14,   1,  -4,   8,  13,  -4,   2,   0,   1,  -4,  -7,   1,   0,   0,   0,   0,   4,   0, 0},
+    {0,  -2,   2,   6,  -2,   0,  -2,   2,  -6, -12,   2,  -2,  11, -20,  47, 105, -25,  13,   1,  -3,   6,  15,  -4,   1,   0,   1,  -4,  -7,   1,   0,   0,   0,   0,   4,   0, 0},
+    {0,  -1,   2,   6,  -2,   0,   0,   1,  -5, -13,   2,  -2,   9, -16,  37, 112, -23,  12,   1,  -3,   5,  15,  -4,   1,   0,   1,  -3,  -8,   1,  -1,   0,   0,   0,   4,   0, 0},
+    {0,  -1,   1,   6,  -1,   0,   0,   1,  -3, -13,   2,  -2,   7, -12,  27, 117, -19,   9,   0,  -2,   3,  16,  -3,   1,   0,   0,  -2,  -8,   1,  -1,   0,   0,   0,   4,   0, 0},
+    {0,  -1,   1,   7,  -1,   0,   0,   0,  -2, -14,   1,  -1,   5,  -8,  17, 121, -14,   7,   0,  -2,   2,  17,  -2,   1,   0,   0,  -2,  -8,   0,  -1,   0,   0,   0,   5,   0, 0},
+    {0,   0,   0,   7,  -1,   0,   0,   0,  -1, -14,   1,  -1,   0,  -4,   8, 124,  -7,   4,   0,  -1,   1,  17,  -1,   0,   0,   0,  -1,  -8,   0,   0,   0,   0,   0,   5,   0, 0},
+    {0,   0,  10,   0,   0,   0,   0,   0, -19,   0,   0,   0,  -1,   0, 120,   0,  -1,   0,  -1,   0,  27,   0,  -1,   0,   0,   0, -13,   0,   0,   0,   0,   0,   7,   0,   0, 0},
+    {0,  -1,  10,   0,  -1,   0,  -1,   1, -19,  -1,   0,   0,   3,  -7, 120,   8,  -4,   0,   1,  -2,  27,   2,  -1,   0,  -1,   0, -12,  -1,   0,   0,   0,   0,   7,   0,   0, 0},
+    {0,  -2,   9,   1,  -1,   0,  -1,   2, -19,  -3,   1,   0,   6, -13, 117,  16,  -8,   4,   1,  -3,  27,   3,  -2,   0,  -1,   1, -12,  -2,   0,   0,   0,   0,   7,   0,   0, 0},
+    {-1,  -2,   9,   2,  -1,  -1,  -2,   2, -18,  -5,   1,  -1,   9, -18, 113,  26, -12,   7,   2,  -5,  26,   6,  -3,   1,  -1,   1, -12,  -3,   1,  -1,   0,   0,   7,   1,   0, 0},
+    {-1,  -2,   9,   2,  -2,  -1,  -2,   3, -17,  -6,   2,  -1,  11, -22, 108,  36, -16,   9,   2,  -5,  24,   8,  -4,   2,  -2,   2, -11,  -4,   1,  -1,  -1,  -1,   6,   2,   0, 0},
+    {-1,  -2,   8,   3,  -2,  -1,  -3,   3, -16,  -8,   2,  -1,  13, -25, 102,  46, -19,  11,   3,  -6,  23,  10,  -5,   2,  -1,   2, -11,  -5,   1,  -1,  -1,  -1,   6,   2,   0, 0},
+    {-1,  -3,   7,   4,  -2,  -1,  -3,   3, -15,  -9,   3,  -3,  14, -26,  94,  56, -22,  12,   3,  -6,  21,  13,  -5,   2,  -1,   2, -10,  -6,   2,  -1,  -1,  -1,   5,   3,   0, 0},
+    {-1,  -3,   7,   5,  -2,  -1,  -3,   4, -14, -11,   3,  -3,  14, -26,  85,  66, -24,  13,   3,  -6,  19,  15,  -6,   3,  -1,   2,  -9,  -7,   2,  -1,  -1,  -1,   5,   4,  -1, -1},
+    {-1,  -3,   6,   6,  -3,  -1,  -3,   3, -12, -12,   3,  -3,  14, -26,  76,  76, -26,  14,   3,  -6,  17,  17,  -6,   3,  -1,   2,  -8,  -8,   2,  -1,  -1,  -1,   4,   4,   0, 0},
+    {-1,  -2,   5,   7,  -3,  -1,  -3,   3, -11, -14,   4,  -3,  13, -24,  66,  85, -26,  14,   3,  -6,  15,  19,  -6,   3,  -1,   2,  -7,  -9,   2,  -1,  -1,  -1,   4,   5,  -1, -1},
+    {-1,  -2,   4,   7,  -3,  -1,  -3,   3,  -9, -15,   3,  -3,  12, -22,  56,  94, -26,  14,   2,  -5,  13,  21,  -6,   3,  -1,   2,  -6, -10,   2,  -1,  -1,  -1,   3,   5,   0, 0},
+    {-1,  -2,   3,   8,  -2,  -1,  -1,   2,  -8, -16,   3,  -3,  11, -19,  46, 102, -25,  13,   2,  -5,  10,  23,  -6,   3,  -1,   1,  -5, -11,   2,  -1,  -1,  -1,   2,   6,   0, 0},
+    {-1,  -2,   2,   9,  -2,  -1,  -1,   2,  -6, -17,   3,  -2,   9, -16,  36, 108, -22,  11,   2,  -4,   8,  24,  -5,   2,  -1,   1,  -4, -11,   2,  -2,  -1,  -1,   2,   6,   0, 0},
+    {-1,  -1,   2,   9,  -2,  -1,  -1,   1,  -5, -18,   2,  -2,   7, -12,  26, 113, -18,   9,   1,  -3,   6,  26,  -5,   2,  -1,   1,  -3, -12,   1,  -1,   0,   0,   1,   7,   0, 0},
+    {0,  -1,   1,   9,  -2,   0,   0,   1,  -3, -19,   2,  -1,   4,  -8,  16, 117, -13,   6,   0,  -2,   3,  27,  -3,   1,   0,   0,  -2, -12,   1,  -1,   0,   0,   0,   7,   0, 0},
+    {0,  -1,   0,  10,  -1,   0,   0,   0,  -1, -19,   1,  -1,   0,  -4,   8, 120,  -7,   3,   0,  -1,   2,  27,  -2,   1,   0,   0,  -1, -12,   0,  -1,   0,   0,   0,   7,   0, 0},
+    {0,   0,  12,   0,   0,   0,   0,  -1, -23,  -1,   0,   0,  -1,   0, 115,   0,  -1,   0,  -1,   0,  38,   0,  -1,   0,   0,   0, -17,   0,   0,   0,   0,   0,   9,   0,   0, 0},
+    {0,  -1,  12,   0,   0,   0,  -1,   1, -23,  -2,   0,   0,   3,  -7, 114,   7,  -4,   0,   1,  -3,  38,   2,  -2,   0,  -1,   1, -16,  -1,   0,   0,   0,   0,  10,   0,   0, 0},
+    {0,  -2,  12,   1,  -1,   0,  -2,   2, -23,  -4,   1,   0,   6, -13, 112,  15,  -8,   4,   2,  -5,  37,   5,  -3,   0,  -1,   1, -16,  -3,   1,   0,   0,   0,   9,   1,   0, 0},
+    {-1,  -2,  11,   2,  -2,  -1,  -2,   3, -22,  -5,   2,  -1,   9, -17, 108,  24, -11,   6,   2,  -6,  36,   8,  -4,   2,  -2,   2, -16,  -4,   1,  -1,  -1,  -1,   9,   2,   0, 0},
+    {-1,  -3,  11,   3,  -2,  -1,  -3,   4, -21,  -7,   2,  -1,  11, -21, 103,  34, -15,   8,   3,  -7,  34,  11,  -5,   2,  -2,   2, -15,  -5,   2,  -1,  -1,  -1,   8,   2,   0, 0},
+    {-1,  -3,  10,   4,  -3,  -1,  -3,   4, -20,  -9,   3,  -1,  12, -24,  97,  44, -18,  10,   4,  -8,  32,  14,  -6,   3,  -2,   3, -14,  -7,   2,  -1,  -1,  -1,   8,   3,  -1, -1},
+    {-1,  -3,   9,   5,  -3,  -1,  -3,   4, -18, -11,   3,  -3,  13, -25,  90,  54, -21,  12,   4,  -9,  29,  17,  -7,   4,  -1,   3, -13,  -8,   2,  -1,  -1,  -1,   7,   4,  -1, -1},
+    {-1,  -3,   8,   6,  -3,  -1,  -3,   4, -17, -13,   4,  -3,  13, -25,  81,  63, -23,  13,   4,  -9,  27,  21,  -8,   4,  -1,   3, -12, -10,   3,  -1,  -1,  -1,   6,   5,  -1, -1},
+    {-1,  -3,   7,   7,  -3,  -1,  -3,   4, -15, -15,   4,  -3,  13, -25,  73,  73, -25,  13,   4,  -9,  24,  24,  -9,   4,  -1,   3, -11, -11,   3,  -1,  -1,  -1,   6,   6,  -1, -1},
+    {-1,  -3,   6,   8,  -3,  -1,  -3,   4, -13, -17,   4,  -3,  13, -23,  63,  81, -25,  13,   4,  -8,  21,  27,  -9,   4,  -1,   3, -10, -12,   3,  -1,  -1,  -1,   5,   6,  -1, -1},
+    {-1,  -3,   5,   9,  -3,  -1,  -3,   3, -11, -18,   4,  -3,  12, -21,  54,  90, -25,  13,   4,  -7,  17,  29,  -9,   4,  -1,   2,  -8, -13,   3,  -1,  -1,  -1,   4,   7,  -1, -1},
+    {-1,  -3,   4,  10,  -3,  -1,  -1,   3,  -9, -20,   4,  -3,  10, -18,  44,  97, -24,  12,   3,  -6,  14,  32,  -8,   4,  -1,   2,  -7, -14,   3,  -2,  -1,  -1,   3,   8,  -1, -1},
+    {-1,  -2,   3,  11,  -3,  -1,  -1,   2,  -7, -21,   4,  -3,   8, -15,  34, 103, -21,  11,   2,  -5,  11,  34,  -7,   3,  -1,   2,  -5, -15,   2,  -2,  -1,  -1,   2,   8,   0, 0},
+    {-1,  -2,   2,  11,  -2,  -1,  -1,   2,  -5, -22,   3,  -2,   6, -11,  24, 108, -17,   9,   2,  -4,   8,  36,  -6,   2,  -1,   1,  -4, -16,   2,  -2,  -1,  -1,   2,   9,   0, 0},
+    {0,  -1,   1,  12,  -2,   0,   0,   1,  -4, -23,   2,  -2,   4,  -8,  15, 112, -13,   6,   0,  -3,   5,  37,  -5,   2,   0,   1,  -3, -16,   1,  -1,   0,   0,   1,   9,   0, 0},
+    {0,   0,   0,  12,  -1,   0,   0,   0,  -2, -23,   1,  -1,   0,  -4,   7, 114,  -7,   3,   0,  -2,   2,  38,  -3,   1,   0,   0,  -1, -16,   1,  -1,   0,   0,   0,  10,   0, 0},
+    {0,   0,  14,   0,   0,   0,   0,  -1, -26,  -1,   0,   0,  -1,   0, 108,   0,  -1,   0,  -1,   0,  49,   0,  -1,   0,   0,  -1, -20,  -1,   0,   0,   0,   0,  11,   0,   0, 0},
+    {0,  -1,  14,   1,   0,   0,  -1,   1, -26,  -2,   0,   0,   3,  -7, 107,   7,  -4,   0,   1,  -3,  48,   3,  -2,   0,  -1,   1, -20,  -2,   0,   0,   0,  -1,  12,   0,   0, 0},
+    {0,  -2,  13,   1,   0,   0,  -2,   2, -25,  -4,   1,   0,   6, -12, 105,  15,  -7,   4,   2,  -6,  47,   6,  -4,   0,  -2,   2, -20,  -3,   1,   0,   0,  -2,  11,   1,   0, 0},
+    {-1,  -3,  13,   3,  -1,  -1,  -2,   3, -25,  -6,   2,  -1,   8, -16, 102,  23, -11,   6,   3,  -8,  46,  10,  -5,   2,  -2,   2, -19,  -5,   1,  -1,  -1,  -1,  11,   2,   0, 0},
+    {-1,  -3,  12,   4,  -2,  -1,  -3,   4, -24,  -8,   3,  -1,  10, -20,  97,  32, -14,   8,   4,  -9,  44,  14,  -7,   3,  -3,   3, -18,  -6,   2,  -1,  -1,  -1,  10,   3,  -1, -1},
+    {-1,  -3,  11,   5,  -3,  -1,  -3,   4, -22, -10,   3,  -1,  11, -22,  91,  41, -17,   9,   5, -10,  41,  18,  -8,   4,  -3,   3, -17,  -8,   2,  -1,  -1,  -1,  10,   4,  -1, -1},
+    {-1,  -4,  11,   6,  -3,  -1,  -4,   5, -21, -13,   4,  -3,  12, -23,  84,  50, -20,  11,   5, -11,  38,  23,  -9,   5,  -3,   4, -16, -10,   3,  -1,  -1,  -1,   9,   5,  -1, -1},
+    {-1,  -4,   9,   7,  -3,  -1,  -4,   5, -19, -15,   4,  -4,  13, -24,  77,  59, -22,  12,   5, -11,  34,  27, -10,   5,  -1,   4, -15, -11,   3,  -1,  -1,  -1,   8,   6,  -1, -1},
+    {-1,  -4,   8,   8,  -4,  -1,  -4,   5, -17, -17,   5,  -4,  13, -23,  68,  68, -23,  13,   5, -11,  31,  31, -11,   5,  -1,   3, -13, -13,   3,  -1,  -1,  -1,   7,   7,  -1, -1},
+    {-1,  -3,   7,   9,  -4,  -1,  -4,   4, -15, -19,   5,  -4,  12, -22,  59,  77, -24,  13,   5, -10,  27,  34, -11,   5,  -1,   3, -11, -15,   4,  -1,  -1,  -1,   6,   8,  -1, -1},
+    {-1,  -3,   6,  11,  -4,  -1,  -3,   4, -13, -21,   5,  -4,  11, -20,  50,  84, -23,  12,   5,  -9,  23,  38, -11,   5,  -1,   3, -10, -16,   4,  -3,  -1,  -1,   5,   9,  -1, -1},
+    {-1,  -3,   5,  11,  -3,  -1,  -1,   3, -10, -22,   4,  -3,   9, -17,  41,  91, -22,  11,   4,  -8,  18,  41, -10,   5,  -1,   2,  -8, -17,   3,  -3,  -1,  -1,   4,  10,  -1, -1},
+    {-1,  -2,   4,  12,  -3,  -1,  -1,   3,  -8, -24,   4,  -3,   8, -14,  32,  97, -20,  10,   3,  -7,  14,  44,  -9,   4,  -1,   2,  -6, -18,   3,  -3,  -1,  -1,   3,  10,  -1, -1},
+    {-1,  -1,   3,  13,  -3,  -1,  -1,   2,  -6, -25,   3,  -2,   6, -11,  23, 102, -16,   8,   2,  -5,  10,  46,  -8,   3,  -1,   1,  -5, -19,   2,  -2,  -1,  -1,   2,  11,   0, 0},
+    {0,   0,   1,  13,  -2,   0,   0,   1,  -4, -25,   2,  -2,   4,  -7,  15, 105, -12,   6,   0,  -4,   6,  47,  -6,   2,   0,   1,  -3, -20,   2,  -2,   0,   0,   1,  11,  -2, 0},
+    {0,   0,   1,  14,  -1,   0,   0,   0,  -2, -26,   1,  -1,   0,  -4,   7, 107,  -7,   3,   0,  -2,   3,  48,  -3,   1,   0,   0,  -2, -20,   1,  -1,   0,   0,   0,  12,  -1, 0},
+    {-1,   0,  15,   0,   0,   0,   0,  -1, -28,  -1,   0,   0,  -1,   0, 100,   0,  -1,   0,  -1,   0,  60,   0,  -1,   0,   0,  -1, -23,  -1,   0,   0,   0,   0,  13,   0,   0, 0},
+    {0,  -1,  15,   1,   0,   0,  -1,   1, -27,  -2,   0,   0,   2,  -6,  99,   6,  -4,   0,   1,  -4,  59,   4,  -2,   0,  -1,   1, -23,  -2,   0,   0,   0,  -1,  13,   0,   0, 0},
+    {-1,  -2,  14,   2,   0,   0,  -2,   2, -27,  -4,   1,   0,   5, -11,  97,  13,  -7,   4,   3,  -7,  58,   8,  -4,   0,  -2,   2, -23,  -4,   1,   0,   0,  -2,  13,   1,   0, 0},
+    {-1,  -3,  14,   3,  -1,  -1,  -3,   3, -26,  -6,   2,  -1,   7, -15,  94,  21, -10,   5,   4,  -9,  56,  13,  -6,   3,  -2,   3, -22,  -5,   2,  -1,  -1,  -3,  12,   2,   0, 0},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -25,  -9,   3,  -1,   9, -18,  90,  29, -13,   7,   5, -11,  54,  17,  -8,   4,  -3,   3, -21,  -7,   2,  -1,  -1,  -3,  12,   4,  -1, -1},
+    {-1,  -4,  12,   5,  -3,  -1,  -4,   5, -23, -11,   4,  -1,  11, -21,  84,  38, -16,   9,   6, -13,  50,  23, -10,   5,  -3,   4, -20,  -9,   3,  -1,  -1,  -3,  11,   5,  -1, -1},
+    {-1,  -4,  11,   6,  -3,  -1,  -4,   5, -22, -13,   4,  -1,  11, -22,  78,  46, -19,  10,   6, -13,  46,  27, -11,   6,  -3,   4, -18, -11,   3,  -1,  -1,  -1,  10,   6,  -1, -1},
+    {-1,  -4,  10,   8,  -4,  -1,  -4,   5, -20, -16,   5,  -4,  12, -22,  71,  55, -20,  11,   7, -14,  42,  33, -13,   6,  -3,   4, -17, -13,   4,  -1,  -1,  -1,   9,   7,  -1, -1},
+    {-1,  -4,   9,   9,  -4,  -1,  -4,   5, -18, -18,   5,  -4,  11, -22,  63,  63, -22,  11,   7, -13,  37,  37, -13,   7,  -1,   4, -15, -15,   4,  -1,  -1,  -1,   8,   8,  -1, -1},
+    {-1,  -4,   8,  10,  -4,  -1,  -4,   5, -16, -20,   5,  -4,  11, -20,  55,  71, -22,  12,   6, -13,  33,  42, -14,   7,  -1,   4, -13, -17,   4,  -3,  -1,  -1,   7,   9,  -1, -1},
+    {-1,  -3,   6,  11,  -4,  -1,  -1,   4, -13, -22,   5,  -4,  10, -19,  46,  78, -22,  11,   6, -11,  27,  46, -13,   6,  -1,   3, -11, -18,   4,  -3,  -1,  -1,   6,  10,  -1, -1},
+    {-1,  -3,   5,  12,  -4,  -1,  -1,   4, -11, -23,   5,  -4,   9, -16,  38,  84, -21,  11,   5, -10,  23,  50, -13,   6,  -1,   3,  -9, -20,   4,  -3,  -1,  -1,   5,  11,  -3, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -9, -25,   4,  -3,   7, -13,  29,  90, -18,   9,   4,  -8,  17,  54, -11,   5,  -1,   2,  -7, -21,   3,  -3,  -1,  -1,   4,  12,  -3, -1},
+    {-1,  -1,   3,  14,  -3,  -1,  -1,   2,  -6, -26,   3,  -3,   5, -10,  21,  94, -15,   7,   3,  -6,  13,  56,  -9,   4,  -1,   2,  -5, -22,   3,  -2,  -1,   0,   2,  12,  -3, 0},
+    {-1,   0,   2,  14,  -2,   0,   0,   1,  -4, -27,   2,  -2,   4,  -7,  13,  97, -11,   5,   0,  -4,   8,  58,  -7,   3,   0,   1,  -4, -23,   2,  -2,   0,   0,   1,  13,  -2, 0},
+    {0,   0,   1,  15,  -1,   0,   0,   0,  -2, -27,   1,  -1,   0,  -4,   6,  99,  -6,   2,   0,  -2,   4,  59,  -4,   1,   0,   0,  -2, -23,   1,  -1,   0,   0,   0,  13,  -1, 0},
+    {0,   0,  15,   0,   0,   0,   0,  -1, -28,  -1,   0,   0,  -1,   0,  91,   0,  -1,   0,  -1,   0,  70,   0,  -1,   0,   0,  -1, -26,  -1,   0,   0,   0,   0,  14,   0,   0, 0},
+    {0,  -1,  15,   1,   0,   0,  -1,   1, -28,  -2,   0,   0,   2,  -6,  90,   6,  -3,   0,   2,  -5,  70,   4,  -3,   0,  -1,   1, -25,  -2,   0,   0,   0,  -1,  14,   0,   0, 0},
+    {-1,  -2,  15,   2,  -1,  -1,  -2,   2, -27,  -4,   1,  -1,   5, -10,  88,  12,  -6,   3,   3,  -8,  69,   9,  -5,   2,  -2,   2, -25,  -4,   1,  -1,   0,  -2,  14,   2,   0, 0},
+    {-1,  -3,  14,   3,  -1,  -1,  -3,   4, -26,  -6,   2,  -1,   7, -14,  85,  19,  -9,   5,   5, -11,  66,  15,  -7,   4,  -2,   3, -24,  -6,   2,  -1,  -1,  -3,  13,   3,  -1, -1},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -25,  -9,   3,  -1,   8, -17,  81,  27, -12,   6,   6, -13,  63,  21, -10,   5,  -3,   4, -23,  -8,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -4,  13,   5,  -1,  -1,  -4,   5, -24, -11,   4,  -1,   9, -19,  77,  34, -15,   8,   7, -15,  59,  27, -11,   6,  -3,   4, -22, -10,   3,  -1,  -1,  -4,  12,   5,  -1, -1},
+    {-1,  -4,  12,   7,  -3,  -1,  -4,   5, -22, -14,   4,  -1,  10, -20,  71,  42, -17,   9,   8, -16,  55,  33, -13,   7,  -4,   5, -20, -13,   4,  -1,  -1,  -4,  11,   6,  -1, -1},
+    {-1,  -4,  10,   8,  -4,  -1,  -4,   5, -20, -16,   5,  -1,  10, -20,  64,  50, -19,  10,   8, -16,  50,  39, -15,   7,  -4,   5, -19, -15,   4,  -1,  -1,  -1,  10,   7,  -1, -1},
+    {-1,  -4,   9,   9,  -4,  -1,  -4,   5, -18, -18,   5,  -4,  10, -20,  57,  57, -20,  10,   8, -16,  44,  44, -16,   8,  -1,   5, -17, -17,   5,  -1,  -1,  -1,   9,   9,  -1, -1},
+    {-1,  -4,   8,  10,  -4,  -1,  -1,   5, -16, -20,   5,  -4,  10, -19,  50,  64, -20,  10,   7, -15,  39,  50, -16,   8,  -1,   4, -15, -19,   5,  -4,  -1,  -1,   7,  10,  -1, -1},
+    {-1,  -3,   7,  12,  -4,  -1,  -1,   4, -14, -22,   5,  -4,   9, -17,  42,  71, -20,  10,   7, -13,  33,  55, -16,   8,  -1,   4, -13, -20,   5,  -4,  -1,  -1,   6,  11,  -4, -1},
+    {-1,  -1,   5,  13,  -4,  -1,  -1,   4, -11, -24,   5,  -4,   8, -15,  34,  77, -19,   9,   6, -11,  27,  59, -15,   7,  -1,   3, -10, -22,   4,  -3,  -1,  -1,   5,  12,  -4, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -9, -25,   4,  -3,   6, -12,  27,  81, -17,   8,   5, -10,  21,  63, -13,   6,  -1,   3,  -8, -23,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {-1,  -1,   3,  14,  -3,  -1,  -1,   2,  -6, -26,   4,  -3,   5,  -9,  19,  85, -14,   7,   4,  -7,  15,  66, -11,   5,  -1,   2,  -6, -24,   3,  -2,  -1,  -1,   3,  13,  -3, -1},
+    {-1,  -1,   2,  15,  -2,  -1,  -1,   1,  -4, -27,   2,  -2,   3,  -6,  12,  88, -10,   5,   2,  -5,   9,  69,  -8,   3,  -1,   1,  -4, -25,   2,  -2,   0,   0,   2,  14,  -2, 0},
+    {0,   0,   1,  15,  -1,   0,   0,   0,  -2, -28,   1,  -1,   0,  -3,   6,  90,  -6,   2,   0,  -3,   4,  70,  -5,   2,   0,   0,  -2, -25,   1,  -1,   0,   0,   0,  14,  -1, 0},
+    {-1,   0,  15,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,  -1,   0,  81,   0,  -1,   0,  -1,   0,  81,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,   0,   0,  15,   0,   0, 0},
+    {-1,  -1,  15,   1,  -1,   0,  -1,   1, -27,  -2,   0,   0,   2,  -5,  80,   5,  -3,   0,   2,  -5,  80,   5,  -3,   0,  -1,   1, -27,  -2,   0,   0,   0,  -1,  15,   1,   0, 0},
+    {-1,  -2,  15,   2,  -1,  -1,  -2,   2, -27,  -4,   1,  -1,   4,  -9,  79,  11,  -6,   3,   4,  -9,  79,  11,  -6,   3,  -2,   2, -27,  -4,   1,  -1,  -1,  -2,  15,   2,   0, 0},
+    {-1,  -3,  14,   3,  -1,  -1,  -3,   3, -26,  -6,   2,  -1,   6, -12,  76,  17,  -8,   4,   6, -12,  76,  17,  -8,   4,  -3,   3, -26,  -6,   2,  -1,  -1,  -3,  14,   3,   0, 0},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -25,  -9,   3,  -1,   7, -15,  73,  24, -11,   6,   7, -15,  73,  24, -11,   6,  -3,   4, -25,  -9,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -4,  13,   5,  -1,  -1,  -4,   5, -23, -11,   3,  -1,   8, -17,  68,  31, -13,   7,   8, -17,  68,  31, -13,   7,  -4,   5, -23, -11,   3,  -1,  -1,  -4,  13,   5,  -1, -1},
+    {-1,  -4,  11,   7,  -1,  -1,  -4,   5, -22, -13,   4,  -1,   9, -18,  63,  37, -15,   8,   9, -18,  63,  37, -15,   8,  -4,   5, -22, -13,   4,  -1,  -1,  -4,  11,   7,  -1, -1},
+    {-1,  -4,  10,   8,  -1,  -1,  -4,   5, -20, -16,   5,  -1,   9, -18,  57,  44, -17,   9,   9, -18,  57,  44, -17,   9,  -4,   5, -20, -16,   5,  -1,  -1,  -4,  10,   8,  -1, -1},
+    {0,  -4,   9,   9,  -4,   0,  -4,   5, -17, -17,   5,  -4,   9, -17,  51,  51, -17,   9,   9, -17,  51,  51, -17,   9,  -4,   5, -17, -17,   5,  -4,   0,  -4,   9,   9,  -4, 0},
+    {-1,  -1,   8,  10,  -4,  -1,  -1,   5, -16, -20,   5,  -4,   9, -17,  44,  57, -18,   9,   9, -17,  44,  57, -18,   9,  -1,   5, -16, -20,   5,  -4,  -1,  -1,   8,  10,  -4, -1},
+    {-1,  -1,   7,  11,  -4,  -1,  -1,   4, -13, -22,   5,  -4,   8, -15,  37,  63, -18,   9,   8, -15,  37,  63, -18,   9,  -1,   4, -13, -22,   5,  -4,  -1,  -1,   7,  11,  -4, -1},
+    {-1,  -1,   5,  13,  -4,  -1,  -1,   3, -11, -23,   5,  -4,   7, -13,  31,  68, -17,   8,   7, -13,  31,  68, -17,   8,  -1,   3, -11, -23,   5,  -4,  -1,  -1,   5,  13,  -4, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -9, -25,   4,  -3,   6, -11,  24,  73, -15,   7,   6, -11,  24,  73, -15,   7,  -1,   3,  -9, -25,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {-1,  -1,   3,  14,  -3,  -1,  -1,   2,  -6, -26,   3,  -3,   4,  -8,  17,  76, -12,   6,   4,  -8,  17,  76, -12,   6,  -1,   2,  -6, -26,   3,  -3,  -1,   0,   3,  14,  -3, 0},
+    {-1,  -1,   2,  15,  -2,  -1,  -1,   1,  -4, -27,   2,  -2,   3,  -6,  11,  79,  -9,   4,   3,  -6,  11,  79,  -9,   4,  -1,   1,  -4, -27,   2,  -2,  -1,   0,   2,  15,  -2, 0},
+    {-1,  -1,   1,  15,  -1,   0,   0,   0,  -2, -27,   1,  -1,   0,  -3,   5,  80,  -5,   2,   0,  -3,   5,  80,  -5,   2,   0,   0,  -2, -27,   1,  -1,   0,   0,   1,  15,  -1, 0},
+    {0,   0,  14,   0,   0,   0,   0,  -1, -26,  -1,   0,   0,  -1,   0,  70,   0,  -1,   0,  -1,   0,  91,   0,  -1,   0,   0,  -1, -28,  -1,   0,   0,   0,   0,  15,   0,   0, 0},
+    {0,  -1,  14,   0,   0,   0,  -1,   1, -25,  -2,   0,   0,   2,  -5,  70,   4,  -3,   0,   2,  -6,  90,   6,  -3,   0,  -1,   1, -28,  -2,   0,   0,   0,  -1,  15,   1,   0, 0},
+    {-1,  -2,  14,   2,  -1,  -1,  -2,   2, -25,  -4,   1,  -1,   3,  -8,  69,   9,  -5,   2,   5, -10,  88,  12,  -6,   3,  -2,   2, -27,  -4,   1,  -1,   0,  -2,  15,   2,   0, 0},
+    {-1,  -3,  13,   3,  -1,  -1,  -2,   3, -24,  -6,   2,  -1,   5, -11,  66,  15,  -7,   4,   7, -14,  85,  19,  -9,   5,  -3,   4, -26,  -6,   2,  -1,  -1,  -3,  14,   3,  -1, -1},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -23,  -8,   3,  -1,   6, -13,  63,  21, -10,   5,   8, -17,  81,  27, -12,   6,  -3,   4, -25,  -9,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -4,  12,   5,  -1,  -1,  -3,   4, -22, -10,   3,  -1,   7, -15,  59,  27, -11,   6,   9, -19,  77,  34, -15,   8,  -4,   5, -24, -11,   4,  -1,  -1,  -4,  13,   5,  -1, -1},
+    {-1,  -4,  11,   6,  -1,  -1,  -4,   5, -20, -13,   4,  -1,   8, -16,  55,  33, -13,   7,  10, -20,  71,  42, -17,   9,  -4,   5, -22, -14,   4,  -1,  -1,  -4,  12,   7,  -3, -1},
+    {-1,  -1,  10,   7,  -1,  -1,  -4,   5, -19, -15,   4,  -1,   8, -16,  50,  39, -15,   7,  10, -20,  64,  50, -19,  10,  -4,   5, -20, -16,   5,  -1,  -1,  -4,  10,   8,  -4, -1},
+    {-1,  -1,   9,   9,  -1,  -1,  -1,   5, -17, -17,   5,  -1,   8, -16,  44,  44, -16,   8,  10, -20,  57,  57, -20,  10,  -4,   5, -18, -18,   5,  -4,  -1,  -4,   9,   9,  -4, -1},
+    {-1,  -1,   7,  10,  -1,  -1,  -1,   4, -15, -19,   5,  -4,   7, -15,  39,  50, -16,   8,  10, -19,  50,  64, -20,  10,  -1,   5, -16, -20,   5,  -4,  -1,  -4,   8,  10,  -4, -1},
+    {-1,  -1,   6,  11,  -4,  -1,  -1,   4, -13, -20,   5,  -4,   7, -13,  33,  55, -16,   8,   9, -17,  42,  71, -20,  10,  -1,   4, -14, -22,   5,  -4,  -1,  -3,   7,  12,  -4, -1},
+    {-1,  -1,   5,  12,  -4,  -1,  -1,   3, -10, -22,   4,  -3,   6, -11,  27,  59, -15,   7,   8, -15,  34,  77, -19,   9,  -1,   4, -11, -24,   5,  -4,  -1,  -1,   5,  13,  -4, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -8, -23,   4,  -3,   5, -10,  21,  63, -13,   6,   6, -12,  27,  81, -17,   8,  -1,   3,  -9, -25,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {-1,  -1,   3,  13,  -3,  -1,  -1,   2,  -6, -24,   3,  -2,   4,  -7,  15,  66, -11,   5,   5,  -9,  19,  85, -14,   7,  -1,   2,  -6, -26,   4,  -3,  -1,  -1,   3,  14,  -3, -1},
+    {-1,  -1,   2,  14,  -2,  -1,  -1,   1,  -4, -25,   2,  -2,   2,  -5,   9,  69,  -8,   3,   3,  -6,  12,  88, -10,   5,  -1,   1,  -4, -27,   2,  -2,   0,   0,   2,  15,  -2, 0},
+    {0,   0,   0,  14,  -1,   0,   0,   0,  -2, -25,   1,  -1,   0,  -3,   4,  70,  -5,   2,   0,  -3,   6,  90,  -6,   2,   0,   0,  -2, -28,   1,  -1,   0,   0,   1,  15,  -1, 0},
+    {-1,   0,  13,   0,   0,   0,   0,  -1, -23,  -1,   0,   0,  -1,   0,  60,   0,  -1,   0,  -1,   0, 100,   0,  -1,   0,   0,  -1, -28,  -1,   0,   0,   0,   0,  15,   0,   0, 0},
+    {0,  -1,  13,   0,   0,   0,  -1,   1, -23,  -2,   0,   0,   1,  -4,  59,   4,  -2,   0,   2,  -6,  99,   6,  -4,   0,  -1,   1, -27,  -2,   0,   0,   0,  -1,  15,   1,   0, 0},
+    {-1,  -2,  13,   1,   0,   0,  -2,   2, -23,  -4,   1,   0,   3,  -7,  58,   8,  -4,   0,   5, -11,  97,  13,  -7,   4,  -2,   2, -27,  -4,   1,   0,   0,  -2,  14,   2,   0, 0},
+    {-1,  -3,  12,   2,  -1,  -1,  -2,   3, -22,  -5,   2,  -1,   4,  -9,  56,  13,  -6,   3,   7, -15,  94,  21, -10,   5,  -3,   3, -26,  -6,   2,  -1,  -1,  -3,  14,   3,   0, 0},
+    {-1,  -3,  12,   4,  -1,  -1,  -3,   3, -21,  -7,   2,  -1,   5, -11,  54,  17,  -8,   4,   9, -18,  90,  29, -13,   7,  -3,   4, -25,  -9,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -3,  11,   5,  -1,  -1,  -3,   4, -20,  -9,   3,  -1,   6, -13,  50,  23, -10,   5,  11, -21,  84,  38, -16,   9,  -4,   5, -23, -11,   4,  -1,  -1,  -4,  12,   5,  -3, -1},
+    {-1,  -1,  10,   6,  -1,  -1,  -3,   4, -19, -11,   3,  -1,   6, -13,  46,  27, -11,   6,  11, -22,  78,  46, -18,  10,  -4,   5, -22, -13,   4,  -1,  -1,  -4,  11,   6,  -3, -1},
+    {-1,  -1,   9,   7,  -1,  -1,  -3,   4, -17, -13,   4,  -1,   7, -14,  42,  33, -13,   6,  12, -22,  71,  55, -20,  11,  -4,   5, -20, -16,   5,  -4,  -1,  -4,  10,   8,  -4, -1},
+    {-1,  -1,   8,   8,  -1,  -1,  -1,   4, -15, -15,   4,  -1,   7, -13,  37,  37, -13,   7,  11, -22,  63,  63, -22,  11,  -4,   5, -18, -18,   5,  -4,  -1,  -4,   9,   9,  -4, -1},
+    {-1,  -1,   7,   9,  -1,  -1,  -1,   4, -13, -17,   4,  -3,   6, -13,  33,  42, -14,   7,  11, -20,  55,  71, -22,  12,  -4,   5, -16, -20,   5,  -4,  -1,  -4,   8,  10,  -4, -1},
+    {-1,  -1,   6,  10,  -1,  -1,  -1,   3, -11, -19,   4,  -3,   6, -11,  27,  46, -13,   6,  10, -18,  46,  78, -22,  11,  -1,   4, -13, -22,   5,  -4,  -1,  -3,   6,  11,  -4, -1},
+    {-1,  -1,   5,  11,  -3,  -1,  -1,   3,  -9, -20,   4,  -3,   5, -10,  23,  50, -13,   6,   9, -16,  38,  84, -21,  11,  -1,   4, -11, -23,   5,  -4,  -1,  -3,   5,  12,  -4, -1},
+    {-1,  -1,   4,  12,  -3,  -1,  -1,   2,  -7, -21,   3,  -3,   4,  -8,  17,  54, -11,   5,   7, -13,  29,  90, -18,   9,  -1,   3,  -9, -25,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {-1,  -1,   2,  12,  -3,  -1,  -1,   2,  -5, -22,   3,  -2,   3,  -6,  13,  56,  -9,   4,   5, -10,  21,  94, -15,   7,  -1,   2,  -6, -26,   3,  -3,  -1,   0,   3,  14,  -3, 0},
+    {-1,   0,   1,  13,  -2,   0,   0,   1,  -4, -23,   2,  -2,   0,  -4,   8,  58,  -7,   3,   4,  -7,  13,  97, -11,   5,   0,   1,  -4, -27,   2,  -2,   0,   0,   2,  14,  -2, 0},
+    {0,   0,   0,  13,  -1,   0,   0,   0,  -2, -23,   1,  -1,   0,  -2,   4,  59,  -4,   1,   0,  -4,   6,  99,  -6,   2,   0,   0,  -2, -27,   1,  -1,   0,   0,   1,  15,  -1, 0},
+    {0,   0,  11,   0,   0,   0,   0,  -1, -20,  -1,   0,   0,  -1,   0,  49,   0,  -1,   0,  -1,   0, 108,   0,  -1,   0,   0,  -1, -26,  -1,   0,   0,   0,   0,  14,   0,   0, 0},
+    {0,  -1,  12,   0,   0,   0,  -1,   1, -20,  -2,   0,   0,   1,  -3,  48,   3,  -2,   0,   3,  -7, 107,   7,  -4,   0,  -1,   1, -26,  -2,   0,   0,   0,  -1,  14,   1,   0, 0},
+    {0,  -2,  11,   1,   0,   0,  -2,   2, -20,  -3,   1,   0,   2,  -6,  47,   6,  -4,   0,   6, -12, 105,  15,  -7,   4,  -2,   2, -25,  -4,   1,   0,   0,  -2,  13,   1,   0, 0},
+    {-1,  -1,  11,   2,  -1,  -1,  -2,   2, -19,  -5,   1,  -1,   3,  -8,  46,  10,  -5,   2,   8, -16, 102,  23, -11,   6,  -2,   3, -25,  -6,   2,  -1,  -1,  -3,  13,   3,   0, 0},
+    {-1,  -1,  10,   3,  -1,  -1,  -3,   3, -18,  -6,   2,  -1,   4,  -9,  44,  14,  -7,   3,  10, -20,  97,  32, -14,   8,  -3,   4, -24,  -8,   3,  -1,  -1,  -3,  12,   4,  -2, -1},
+    {-1,  -1,   9,   4,  -1,  -1,  -3,   3, -17,  -8,   2,  -1,   5, -10,  41,  18,  -8,   4,  11, -22,  91,  41, -17,  10,  -3,   4, -22, -10,   3,  -1,  -1,  -3,  11,   5,  -3, -1},
+    {-1,  -1,   9,   5,  -1,  -1,  -3,   4, -16, -10,   3,  -1,   5, -11,  38,  23,  -9,   5,  12, -23,  84,  50, -20,  11,  -4,   5, -21, -13,   4,  -3,  -1,  -4,  11,   6,  -3, -1},
+    {-1,  -1,   8,   6,  -1,  -1,  -1,   4, -15, -11,   3,  -1,   5, -11,  34,  27, -10,   5,  13, -24,  77,  59, -22,  12,  -4,   5, -19, -15,   4,  -4,  -1,  -4,   9,   7,  -3, -1},
+    {-1,  -1,   7,   7,  -1,  -1,  -1,   3, -13, -13,   3,  -1,   5, -11,  31,  31, -11,   5,  13, -23,  68,  68, -23,  13,  -4,   5, -17, -17,   5,  -4,  -1,  -4,   8,   8,  -4, -1},
+    {-1,  -1,   6,   8,  -1,  -1,  -1,   3, -11, -15,   4,  -1,   5, -10,  27,  34, -11,   5,  12, -22,  59,  77, -24,  13,  -4,   4, -15, -19,   5,  -4,  -1,  -3,   7,   9,  -4, -1},
+    {-1,  -1,   5,   9,  -1,  -1,  -1,   3, -10, -16,   4,  -3,   5,  -9,  23,  38, -11,   5,  11, -20,  50,  84, -23,  12,  -3,   4, -13, -21,   5,  -4,  -1,  -3,   6,  11,  -4, -1},
+    {-1,  -1,   4,   9,  -1,  -1,  -1,   2,  -8, -17,   3,  -3,   4,  -8,  18,  41, -10,   5,  10, -17,  41,  91, -22,  11,  -1,   3, -10, -22,   4,  -3,  -1,  -3,   5,  11,  -3, -1},
+    {-1,  -1,   3,  10,  -1,  -1,  -1,   2,  -6, -18,   3,  -3,   3,  -7,  14,  44,  -9,   4,   8, -14,  32,  97, -20,  10,  -1,   3,  -8, -24,   4,  -3,  -1,  -2,   4,  12,  -3, -1},
+    {-1,  -1,   2,  11,  -1,  -1,  -1,   1,  -5, -19,   2,  -2,   2,  -5,  10,  46,  -8,   3,   6, -11,  23, 102, -16,   8,  -1,   2,  -6, -25,   3,  -2,  -1,   0,   3,  13,  -3, 0},
+    {0,   0,   1,  11,  -2,   0,   0,   1,  -3, -20,   2,  -2,   0,  -4,   6,  47,  -6,   2,   4,  -7,  15, 105, -12,   6,   0,   1,  -4, -25,   2,  -2,   0,   0,   1,  13,  -2, 0},
+    {0,   0,   0,  12,  -1,   0,   0,   0,  -2, -20,   1,  -1,   0,  -2,   3,  48,  -3,   1,   0,  -4,   7, 107,  -7,   3,   0,   0,  -2, -26,   1,  -1,   0,   0,   1,  14,  -1, 0},
+    {0,   0,   9,   0,   0,   0,   0,   0, -17,   0,   0,   0,  -1,   0,  38,   0,  -1,   0,  -1,   0, 115,   0,  -1,   0,   0,  -1, -23,  -1,   0,   0,   0,   0,  12,   0,   0, 0},
+    {0,   0,  10,   0,   0,   0,  -1,   1, -16,  -1,   0,   0,   1,  -3,  38,   2,  -2,   0,   3,  -7, 114,   7,  -4,   0,  -1,   1, -23,  -2,   0,   0,   0,  -1,  12,   0,   0, 0},
+    {0,   0,   9,   1,   0,   0,  -1,   1, -16,  -3,   1,   0,   2,  -5,  37,   5,  -3,   0,   6, -13, 112,  15,  -8,   4,  -2,   2, -23,  -4,   1,   0,   0,  -2,  12,   1,  -1, 0},
+    {-1,  -1,   9,   2,  -1,  -1,  -2,   2, -16,  -4,   1,  -1,   2,  -6,  36,   8,  -4,   2,   9, -17, 108,  24, -11,   6,  -2,   3, -22,  -5,   2,  -1,   0,  -2,  11,   2,  -2, 0},
+    {-1,  -1,   8,   2,  -1,  -1,  -2,   2, -15,  -5,   2,  -1,   3,  -7,  34,  11,  -5,   2,  11, -21, 103,  34, -15,   8,  -3,   4, -21,  -7,   2,  -1,   0,  -3,  11,   3,  -2, 0},
+    {-1,  -1,   8,   3,  -1,  -1,  -2,   3, -14,  -7,   2,  -1,   4,  -8,  32,  14,  -6,   3,  12, -24,  97,  44, -18,  10,  -3,   4, -20,  -9,   3,  -1,  -1,  -3,  10,   4,  -3, -1},
+    {-1,  -1,   7,   4,  -1,  -1,  -1,   3, -13,  -8,   2,  -1,   4,  -9,  29,  17,  -7,   4,  13, -25,  90,  54, -21,  12,  -3,   4, -18, -11,   3,  -3,  -1,  -3,   9,   5,  -3, -1},
+    {-1,  -1,   6,   5,  -1,  -1,  -1,   3, -12, -10,   3,  -1,   4,  -9,  27,  21,  -8,   4,  13, -25,  81,  63, -23,  13,  -3,   4, -17, -13,   4,  -3,  -1,  -3,   8,   6,  -3, -1},
+    {-1,  -1,   6,   6,  -1,  -1,  -1,   3, -11, -11,   3,  -1,   4,  -9,  24,  24,  -9,   4,  13, -25,  73,  73, -25,  13,  -3,   4, -15, -15,   4,  -3,  -1,  -3,   7,   7,  -3, -1},
+    {-1,  -1,   5,   6,  -1,  -1,  -1,   3, -10, -12,   3,  -1,   4,  -8,  21,  27,  -9,   4,  13, -23,  63,  81, -25,  13,  -3,   4, -13, -17,   4,  -3,  -1,  -3,   6,   8,  -3, -1},
+    {-1,  -1,   4,   7,  -1,  -1,  -1,   2,  -8, -13,   3,  -1,   4,  -7,  17,  29,  -9,   4,  12, -21,  54,  90, -25,  13,  -3,   3, -11, -18,   4,  -3,  -1,  -3,   5,   9,  -3, -1},
+    {-1,  -1,   3,   8,  -1,  -1,  -1,   2,  -7, -14,   3,  -2,   3,  -6,  14,  32,  -8,   4,  10, -18,  44,  97, -24,  12,  -1,   3,  -9, -20,   4,  -3,  -1,  -3,   4,  10,  -3, -1},
+    {-1,  -1,   2,   8,  -1,  -1,  -1,   2,  -5, -15,   2,  -2,   2,  -5,  11,  34,  -7,   3,   8, -15,  34, 103, -21,  11,  -1,   2,  -7, -21,   4,  -3,   0,  -2,   3,  11,  -3, 0},
+    {-1,  -1,   2,   9,  -1,  -1,  -1,   1,  -4, -16,   2,  -2,   2,  -4,   8,  36,  -6,   2,   6, -11,  24, 108, -17,   9,  -1,   2,  -5, -22,   3,  -2,   0,  -2,   2,  11,  -2, 0},
+    {0,   0,   1,   9,   0,   0,   0,   1,  -3, -16,   1,  -1,   0,  -3,   5,  37,  -5,   2,   4,  -8,  15, 112, -13,   6,   0,   1,  -4, -23,   2,  -2,   0,  -1,   1,  12,  -2, 0},
+    {0,   0,   0,  10,   0,   0,   0,   0,  -1, -16,   1,  -1,   0,  -2,   2,  38,  -3,   1,   0,  -4,   7, 114,  -7,   3,   0,   0,  -2, -23,   1,  -1,   0,   0,   0,  12,  -1, 0},
+    {0,   0,   7,   0,   0,   0,   0,   0, -13,   0,   0,   0,  -1,   0,  27,   0,  -1,   0,  -1,   0, 120,   0,  -1,   0,   0,   0, -19,   0,   0,   0,   0,   0,  10,   0,   0, 0},
+    {0,   0,   7,   0,   0,   0,  -1,   0, -12,  -1,   0,   0,   1,  -2,  27,   2,  -1,   0,   3,  -7, 120,   8,  -4,   0,  -1,   1, -19,  -1,   0,   0,   0,  -1,  10,   0,  -1, 0},
+    {0,   0,   7,   0,   0,   0,  -1,   1, -12,  -2,   0,   0,   1,  -3,  27,   3,  -2,   0,   6, -13, 117,  16,  -8,   4,  -1,   2, -19,  -3,   1,   0,   0,  -2,   9,   1,  -1, 0},
+    {-1,  -1,   7,   1,  -1,  -1,  -1,   1, -12,  -3,   1,   0,   2,  -5,  26,   6,  -3,   1,   9, -18, 113,  26, -12,   7,  -2,   2, -18,  -5,   1,   0,   0,  -2,   9,   2,  -1, 0},
+    {-1,  -1,   6,   2,  -1,  -1,  -2,   2, -11,  -4,   1,  -1,   2,  -5,  24,   8,  -4,   2,  11, -22, 108,  36, -16,   9,  -2,   3, -17,  -6,   2,  -1,   0,  -2,   9,   2,  -2, 0},
+    {-1,  -1,   6,   2,  -1,  -1,  -1,   2, -11,  -5,   1,  -1,   3,  -6,  23,  10,  -5,   2,  13, -25, 102,  46, -19,  11,  -3,   3, -16,  -8,   2,  -1,   0,  -2,   8,   3,  -2, 0},
+    {-1,  -1,   5,   3,  -1,  -1,  -1,   2, -10,  -6,   2,  -1,   3,  -6,  21,  13,  -5,   2,  14, -26,  94,  56, -22,  12,  -3,   3, -15,  -9,   3,  -3,   0,  -3,   7,   4,  -2, 0},
+    {-1,  -1,   5,   4,  -1,  -1,  -1,   2,  -9,  -7,   2,  -1,   3,  -6,  19,  15,  -6,   3,  14, -26,  85,  66, -24,  13,  -3,   4, -14, -11,   3,  -3,  -1,  -3,   7,   5,  -2, -1},
+    {-1,  -1,   4,   4,  -1,  -1,  -1,   2,  -8,  -8,   2,  -1,   3,  -6,  17,  17,  -6,   3,  14, -26,  76,  76, -26,  14,  -3,   3, -12, -12,   3,  -3,   0,  -3,   6,   6,  -3, 0},
+    {-1,  -1,   4,   5,  -1,  -1,  -1,   2,  -7,  -9,   2,  -1,   3,  -6,  15,  19,  -6,   3,  13, -24,  66,  85, -26,  14,  -3,   3, -11, -14,   4,  -3,  -1,  -2,   5,   7,  -3, -1},
+    {-1,  -1,   3,   5,  -1,  -1,  -1,   2,  -6, -10,   2,  -1,   2,  -5,  13,  21,  -6,   3,  12, -22,  56,  94, -26,  14,  -3,   3,  -9, -15,   3,  -3,   0,  -2,   4,   7,  -3, 0},
+    {-1,  -1,   2,   6,  -1,  -1,  -1,   1,  -5, -11,   2,  -1,   2,  -5,  10,  23,  -6,   3,  11, -19,  46, 102, -25,  13,  -1,   2,  -8, -16,   3,  -3,   0,  -2,   3,   8,  -2, 0},
+    {-1,  -1,   2,   6,  -1,  -1,  -1,   1,  -4, -11,   2,  -2,   2,  -4,   8,  24,  -5,   2,   9, -16,  36, 108, -22,  11,  -1,   2,  -6, -17,   3,  -2,   0,  -2,   2,   9,  -2, 0},
+    {-1,  -1,   1,   7,  -1,  -1,   0,   1,  -3, -12,   1,  -1,   1,  -3,   6,  26,  -5,   2,   7, -12,  26, 113, -18,   9,   0,   1,  -5, -18,   2,  -2,   0,  -1,   2,   9,  -2, 0},
+    {0,   0,   0,   7,   0,   0,   0,   0,  -2, -12,   1,  -1,   0,  -2,   3,  27,  -3,   1,   4,  -8,  16, 117, -13,   6,   0,   1,  -3, -19,   2,  -1,   0,  -1,   1,   9,  -2, 0},
+    {0,   0,   0,   7,   0,   0,   0,   0,  -1, -12,   0,  -1,   0,  -1,   2,  27,  -2,   1,   0,  -4,   8, 120,  -7,   3,   0,   0,  -1, -19,   1,  -1,   0,  -1,   0,  10,  -1, 0},
+    {0,   0,   5,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,  17,   0,   0,   0,  -1,   0, 124,   0,  -1,   0,   0,   0, -14,   0,   0,   0,   0,   0,   7,   0,   0, 0},
+    {0,   0,   5,   0,   0,   0,   0,   0,  -8,  -1,   0,   0,   0,  -1,  17,   1,  -1,   0,   4,  -7, 124,   8,  -4,   0,  -1,   1, -14,  -1,   0,   0,   0,  -1,   7,   0,   0, 0},
+    {0,   0,   5,   0,   0,   0,  -1,   0,  -8,  -2,   0,   0,   1,  -2,  17,   2,  -2,   0,   7, -14, 121,  17,  -8,   5,  -1,   1, -14,  -2,   0,   0,   0,  -1,   7,   1,  -1, 0},
+    {0,   0,   4,   0,   0,   0,  -1,   1,  -8,  -2,   0,   0,   1,  -3,  16,   3,  -2,   0,   9, -19, 117,  27, -12,   7,  -2,   2, -13,  -3,   1,   0,   0,  -1,   6,   1,  -1, 0},
+    {0,   0,   4,   0,   0,   0,  -1,   1,  -8,  -3,   1,   0,   1,  -4,  15,   5,  -3,   1,  12, -23, 112,  37, -16,   9,  -2,   2, -13,  -5,   1,   0,   0,  -2,   6,   2,  -1, 0},
+    {0,   0,   4,   0,   0,   0,   0,   1,  -7,  -4,   1,   0,   1,  -4,  15,   6,  -3,   1,  13, -25, 105,  47, -20,  11,  -2,   2, -12,  -6,   2,  -2,   0,  -2,   6,   2,  -2, 0},
+    {-1,   0,   4,   0,   0,   0,   0,   1,  -7,  -4,   1,   0,   2,  -4,  13,   8,  -4,   1,  14, -27,  97,  58, -23,  13,  -2,   2, -11,  -7,   2,  -2,   0,  -2,   5,   3,  -2, 0},
+    {-1,  -1,   3,   2,  -1,  -1,  -1,   1,  -6,  -5,   1,   0,   2,  -4,  12,   9,  -4,   2,  15, -27,  88,  69, -25,  14,  -2,   2, -10,  -8,   2,  -2,   0,  -2,   5,   3,  -2, 0},
+    {-1,  -1,   3,   3,  -1,  -1,  -1,   1,  -6,  -6,   1,  -1,   2,  -4,  11,  11,  -4,   2,  15, -27,  79,  79, -27,  15,  -2,   2,  -9,  -9,   2,  -2,   0,  -2,   4,   4,  -2, 0},
+    {-1,  -1,   2,   3,  -1,  -1,  -1,   1,  -5,  -6,   1,   0,   2,  -4,   9,  12,  -4,   2,  14, -25,  69,  88, -27,  15,  -2,   2,  -8, -10,   2,  -2,   0,  -2,   3,   5,  -2, 0},
+    {-1,   0,   0,   4,   0,   0,   0,   1,  -4,  -7,   1,   0,   1,  -4,   8,  13,  -4,   2,  13, -23,  58,  97, -27,  14,  -2,   2,  -7, -11,   2,  -2,   0,  -2,   3,   5,  -2, 0},
+    {0,   0,   0,   4,   0,   0,   0,   1,  -4,  -7,   1,   0,   1,  -3,   6,  15,  -4,   1,  11, -20,  47, 105, -25,  13,  -2,   2,  -6, -12,   2,  -2,   0,  -2,   2,   6,  -2, 0},
+    {0,   0,   0,   4,   0,   0,   0,   1,  -3,  -8,   1,  -1,   1,  -3,   5,  15,  -4,   1,   9, -16,  37, 112, -23,  12,   0,   1,  -5, -13,   2,  -2,   0,  -1,   2,   6,  -2, 0},
+    {0,   0,   0,   4,   0,   0,   0,   0,  -2,  -8,   1,  -1,   0,  -2,   3,  16,  -3,   1,   7, -12,  27, 117, -19,   9,   0,   1,  -3, -13,   2,  -2,   0,  -1,   1,   6,  -1, 0},
+    {0,   0,   0,   5,   0,   0,   0,   0,  -2,  -8,   0,  -1,   0,  -2,   2,  17,  -2,   1,   5,  -8,  17, 121, -14,   7,   0,   0,  -2, -14,   1,  -1,   0,  -1,   1,   7,  -1, 0},
+    {0,   0,   0,   5,   0,   0,   0,   0,  -1,  -8,   0,   0,   0,  -1,   1,  17,  -1,   0,   0,  -4,   8, 124,  -7,   4,   0,   0,  -1, -14,   1,  -1,   0,   0,   0,   7,  -1, 0},
+    {0,   0,   2,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0, 127,   0,   0,   0,   0,   0,  -8,   0,   0,   0,   0,   0,   3,   0,   0, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,  -1,   8,   1,   0,   0,   4,  -7, 126,   8,  -4,   0,   0,   0,  -7,   0,   0,   0,   0,   0,   4,   0,   0, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -4,  -1,   0,   0,   0,  -1,   8,   1,  -1,   0,   7, -14, 124,  17,  -8,   5,  -1,   1,  -7,  -1,   0,   0,   0,  -1,   4,   0,   0, 0},
+    {0,   0,   0,   0,   0,   0,  -1,   0,  -4,  -1,   0,   0,   0,  -1,   8,   2,  -1,   0,  10, -19, 120,  27, -12,   7,  -1,   1,  -7,  -2,   0,   0,   0,  -1,   3,   1,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -4,  -2,   0,   0,   0,  -2,   7,   2,  -1,   0,  12, -23, 114,  38, -16,  10,  -1,   1,  -7,  -3,   1,   0,   0,  -1,   3,   1,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -4,  -2,   0,   0,   1,  -2,   7,   3,  -2,   0,  14, -26, 107,  48, -20,  12,  -1,   1,  -7,  -3,   1,  -1,   0,  -1,   3,   1,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -4,  -2,   0,   0,   1,  -2,   6,   4,  -2,   0,  15, -27,  99,  59, -23,  13,  -1,   1,  -6,  -4,   1,  -1,   0,  -1,   2,   1,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -3,  -3,   0,   0,   1,  -2,   6,   4,  -2,   0,  15, -28,  90,  70, -25,  14,  -1,   1,  -6,  -5,   1,  -1,   0,  -1,   2,   2,  -1, 0},
+    {-1,  -1,   0,   0,   0,   0,   0,   0,  -3,  -3,   0,   0,   1,  -2,   5,   5,  -2,   1,  15, -27,  80,  80, -27,  15,  -1,   1,  -5,  -5,   1,  -1,   0,  -1,   2,   2,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -3,  -3,   0,   0,   0,  -2,   4,   6,  -2,   1,  14, -25,  70,  90, -28,  15,  -1,   1,  -5,  -6,   1,  -1,   0,  -1,   2,   2,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -2,  -4,   0,   0,   0,  -2,   4,   6,  -2,   1,  13, -23,  59,  99, -27,  15,  -1,   1,  -4,  -6,   1,  -1,   0,  -1,   1,   2,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -2,  -4,   0,   0,   0,  -2,   3,   7,  -2,   1,  12, -20,  48, 107, -26,  14,  -1,   1,  -3,  -7,   1,  -1,   0,  -1,   1,   3,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -2,  -4,   0,   0,   0,  -1,   2,   7,  -2,   0,  10, -16,  38, 114, -23,  12,   0,   1,  -3,  -7,   1,  -1,   0,  -1,   1,   3,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -1,  -4,   0,  -1,   0,  -1,   2,   8,  -1,   0,   7, -12,  27, 120, -19,  10,   0,   0,  -2,  -7,   1,  -1,   0,  -1,   1,   3,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,  -1,  -4,   0,   0,   0,  -1,   1,   8,  -1,   0,   5,  -8,  17, 124, -14,   7,   0,   0,  -1,  -7,   1,  -1,   0,   0,   0,   4,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   0,   0,  -4,   0,   0,   0,   0,   1,   8,  -1,   0,   0,  -4,   8, 126,  -7,   4,   0,   0,   0,  -7,   0,   0,   0,   0,   0,   4,   0, 0}
+#endif  /* EDGE_PIXEL_FILTER_EXTEND */
+
+#else  /* SUBPEL_SHIFTS==16 */
+
+#if EDGE_PIXEL_FILTER_EXTEND == 2
+    {0,   0,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   1,   1,   1, -13, 125,  18,  -7,   0,   1,   1,   0,   0,   0,   0, 0},
+    {0,   1,   1,   1, -22, 116,  39, -15,   0,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -25, 101,  61, -21,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -25,  83,  83, -25,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   1, -21,  61, 101, -25,   1,   1,   1,   1,   1,   1,   1, 1},
+    {1,   1,   1,   0, -15,  39, 116, -22,   1,   1,   1,   0,   1,   1,   1, 1},
+    {1,   1,   1,   0,  -7,  18, 125, -13,   0,   1,   1,   0,   0,   0,   0, 0},
+    {0, -13,   0,   1,   1, 125,   1,   0,   1,  18,   1,   0,   0,  -7,   0, 0},
+    {1, -13,  -2,   0, -13, 121,  17,   0,  -2,  17,   2,   0,   0,   0,   0, 0},
+    {3, -12,  -3,   1, -21, 113,  38, -15,  -3,  16,   6,   1,   1,   1,   1, 1},
+    {4,  -9,  -5,   1, -25,  99,  59, -20,  -2,  15,   9,  -2,   1,   1,   1, 1},
+    {4,  -8,  -8,   4, -24,  80,  80, -24,  -2,  12,  12,  -2,   1,   1,   1, 1},
+    {1,  -5,  -9,   4, -20,  59,  99, -25,  -2,   9,  15,  -2,   1,   1,   1, 1},
+    {1,  -3, -12,   3, -15,  38, 113, -21,   1,   6,  16,  -3,   1,   1,   1, 1},
+    {0,  -2, -13,   1,   0,  17, 121, -13,   0,   2,  17,  -2,   0,   0,   0, 0},
+    {0, -22,   0,   1,   1, 116,   1,   1,   1,  39,   1,   1,   1, -15,   1, 1},
+    {3, -21,  -3,   1, -12, 113,  16,   1,  -3,  38,   6,   1,   1, -15,   1, 1},
+    {5, -19,  -5,   2, -19, 105,  36, -13,  -5,  36,  13,   2,   1, -13,   1, 1},
+    {7, -15,  -8,   2, -21,  92,  56, -17,  -5,  32,  20,  -4,   2, -10,  -5, 2},
+    {3, -12, -12,   3, -21,  76,  76, -21,  -5,  27,  27,  -5,   3,  -7,  -7, 3},
+    {2,  -8, -15,   7, -17,  56,  92, -21,  -4,  20,  32,  -5,   2,  -5, -10, 2},
+    {2,  -5, -19,   5, -13,  36, 105, -19,   2,  13,  36,  -5,   1,   1, -13, 1},
+    {1,  -3, -21,   3,   1,  16, 113, -12,   1,   6,  38,  -3,   1,   1, -15, 1},
+    {1, -25,   1,   1,   1, 101,   1,   1,   1,  61,   1,   1,   1, -21,   1, 1},
+    {4, -25,  -2,   1,  -9,  99,  15,   1,  -5,  59,   9,   1,   1, -20,  -2, 1},
+    {7, -21,  -5,   2, -15,  92,  32, -10,  -8,  56,  20,  -5,   2, -17,  -4, 2},
+    {3, -18,  -9,   3, -18,  81,  50, -14,  -9,  50,  31,  -7,   3, -14,  -7, 3},
+    {3, -13, -13,   3, -17,  67,  67, -17,  -9,  41,  41,  -9,   3, -11, -11, 3},
+    {3,  -9, -18,   3, -14,  50,  81, -18,  -7,  31,  50,  -9,   3,  -7, -14, 3},
+    {2,  -5, -21,   7, -10,  32,  92, -15,  -5,  20,  56,  -8,   2,  -4, -17, 2},
+    {1,  -2, -25,   4,   1,  15,  99,  -9,   1,   9,  59,  -5,   1,  -2, -20, 1},
+    {1, -25,   1,   1,   1,  83,   1,   1,   1,  83,   1,   1,   1, -25,   1, 1},
+    {4, -24,  -2,   1,  -8,  80,  12,   1,  -8,  80,  12,   1,   4, -24,  -2, 1},
+    {3, -21,  -5,   3, -12,  76,  27,  -7, -12,  76,  27,  -7,   3, -21,  -5, 3},
+    {3, -17,  -9,   3, -13,  67,  41, -11, -13,  67,  41, -11,   3, -17,  -9, 3},
+    {3, -13, -13,   3, -13,  55,  55, -13, -13,  55,  55, -13,   3, -13, -13, 3},
+    {3,  -9, -17,   3, -11,  41,  67, -13, -11,  41,  67, -13,   3,  -9, -17, 3},
+    {3,  -5, -21,   3,  -7,  27,  76, -12,  -7,  27,  76, -12,   3,  -5, -21, 3},
+    {1,  -2, -24,   4,   1,  12,  80,  -8,   1,  12,  80,  -8,   1,  -2, -24, 4},
+    {1, -21,   1,   1,   1,  61,   1,   1,   1, 101,   1,   1,   1, -25,   1, 1},
+    {1, -20,  -2,   1,  -5,  59,   9,   1,  -9,  99,  15,   1,   4, -25,  -2, 1},
+    {2, -17,  -4,   2,  -8,  56,  20,  -5, -15,  92,  32, -10,   7, -21,  -5, 2},
+    {3, -14,  -7,   3,  -9,  50,  31,  -7, -18,  81,  50, -14,   3, -18,  -9, 3},
+    {3, -11, -11,   3,  -9,  41,  41,  -9, -17,  67,  67, -17,   3, -13, -13, 3},
+    {3,  -7, -14,   3,  -7,  31,  50,  -9, -14,  50,  81, -18,   3,  -9, -18, 3},
+    {2,  -4, -17,   2,  -5,  20,  56,  -8, -10,  32,  92, -15,   2,  -5, -21, 7},
+    {1,  -2, -20,   1,   1,   9,  59,  -5,   1,  15,  99,  -9,   1,  -2, -25, 4},
+    {1, -15,   1,   1,   1,  39,   1,   1,   1, 116,   1,   1,   0, -22,   0, 1},
+    {1, -15,   1,   1,  -3,  38,   6,   1, -12, 113,  16,   1,   3, -21,  -3, 1},
+    {2, -13,   2,   1,  -5,  36,  13,   1, -19, 105,  36, -13,   5, -19,  -5, 1},
+    {2, -10,  -5,   2,  -5,  32,  20,  -4, -21,  92,  56, -17,   7, -15,  -8, 2},
+    {3,  -7,  -7,   3,  -5,  27,  27,  -5, -21,  76,  76, -21,   3, -12, -12, 3},
+    {2,  -5, -10,   2,  -4,  20,  32,  -5, -17,  56,  92, -21,   2,  -8, -15, 7},
+    {2,   2, -13,   1,   1,  13,  36,  -5, -13,  36, 105, -19,   1,  -5, -19, 5},
+    {1,   1, -15,   1,   1,   6,  38,  -3,   1,  16, 113, -12,   1,  -3, -21, 3},
+    {1,  -7,   0,   0,   1,  18,   1,   0,   1, 125,   1,   0,   0, -13,   0, 0},
+    {0,   0,   0,   0,  -2,  17,   2,   0, -13, 121,  17,   0,   1, -13,  -2, 0},
+    {1,   1,   1,   1,  -3,  16,   6,   1, -21, 113,  38, -15,   3, -12,  -3, 1},
+    {1,   1,   1,   1,  -2,  15,   9,  -2, -25,  99,  59, -20,   4,  -9,  -5, 1},
+    {1,   1,   1,   1,  -2,  12,  12,  -2, -24,  80,  80, -24,   4,  -8,  -8, 4},
+    {1,   1,   1,   1,  -2,   9,  15,  -2, -20,  59,  99, -25,   1,  -5,  -9, 4},
+    {1,   1,   1,   1,   1,   6,  16,  -3, -15,  38, 113, -21,   1,  -3, -12, 3},
+    {0,   0,   0,   0,   0,   2,  17,  -2,   0,  17, 121, -13,   0,  -2, -13, 1}
+#elif EDGE_PIXEL_FILTER_EXTEND == 3
+    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7, -14, 124,  17,  -9,   5,   0,   0,   0,   0,   0,   0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,  -1,   0,   0,   0,   0,  12, -23, 115,  38, -17,   9,   0,  -1,   0,   0,   0,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,  -1,   0,  -1,   0,   0,  -1,   0,  15, -27, 100,  60, -23,  13,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,  -1,   0,  -1,   0,   0,  -1,   0,  15, -27,  81,  81, -27,  15,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {-1,   0,  -1,  -1,   0,  -1,   0,  -1,   0,   0,  -1,   0,  13, -23,  60, 100, -27,  15,   0,  -1,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,  -1,   0,   9, -17,  38, 115, -23,  12,   0,   0,   0,   0,  -1,   0,   0,   0,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   5,  -9,  17, 124, -14,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,  -1,   0,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   7,   0,   0,   0,   0,   0, -14,   0,   0,   0,  -1,   0, 124,   0,  -1,   0,   0,   0,  17,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,   5,   0,   0, 0},
+    {0,  -1,   7,   1,   0,   0,  -1,   1, -13,  -2,   1,   0,   7, -13, 122,  17,  -8,   0,   1,  -2,  17,   2,  -1,   0,   0,   1,  -8,  -1,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -2,   6,   2,  -1,   0,  -2,   2, -13,  -4,   1,   0,  12, -22, 112,  37, -16,   9,   1,  -3,  16,   5,  -3,   0,   0,   1,  -8,  -3,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -2,   5,   3,  -2,   0,  -2,   3, -11,  -7,   2,  -2,  14, -27,  97,  58, -23,  13,   2,  -4,  14,   8,  -4,   2,   0,   1,  -7,  -4,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -2,   4,   4,  -2,   0,  -2,   2,  -9,  -9,   2,  -2,  15, -27,  79,  79, -27,  15,   2,  -4,  11,  11,  -4,   2,   0,   1,  -6,  -6,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -2,   3,   5,  -2,   0,  -2,   2,  -7, -11,   3,  -2,  13, -23,  58,  97, -27,  14,   2,  -4,   8,  14,  -4,   2,   0,   1,  -4,  -7,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,  -1,   2,   6,  -2,   0,   0,   1,  -4, -13,   2,  -2,   9, -16,  37, 112, -22,  12,   0,  -3,   5,  16,  -3,   1,   0,   1,  -3,  -8,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,   1,   7,  -1,   0,   0,   1,  -2, -13,   1,  -1,   0,  -8,  17, 122, -13,   7,   0,  -1,   2,  17,  -2,   1,   0,   1,  -1,  -8,   1,   0,   0,   0,   0,   0,   0, 0},
+    {0,   0,  12,   0,   0,   0,   0,  -1, -23,  -1,   0,   0,  -1,   0, 115,   0,  -1,   0,  -1,   0,  38,   0,  -1,   0,   0,   0, -17,   0,   0,   0,   0,   0,   9,   0,   0, 0},
+    {0,  -2,  12,   1,   0,   0,  -2,   2, -22,  -3,   1,   0,   6, -13, 112,  16,  -8,   0,   2,  -4,  37,   5,  -3,   0,  -1,   1, -16,  -3,   1,   0,   0,   0,   9,   0,   0, 0},
+    {-1,  -3,  11,   3,  -2,  -1,  -3,   4, -21,  -7,   2,  -1,  11, -21, 103,  34, -15,   8,   3,  -7,  34,  11,  -5,   2,  -2,   2, -15,  -5,   2,  -1,  -1,  -1,   8,   2,   0, 0},
+    {-1,  -3,   9,   5,  -3,  -1,  -3,   4, -18, -11,   3,  -1,  13, -25,  90,  53, -21,  12,   4,  -9,  29,  17,  -7,   3,  -1,   3, -13,  -8,   2,  -1,  -1,  -1,   7,   4,  -1, -1},
+    {-1,  -3,   7,   7,  -3,  -1,  -3,   4, -15, -15,   4,  -3,  13, -25,  73,  73, -25,  13,   4,  -9,  24,  24,  -9,   4,  -1,   3, -11, -11,   3,  -1,  -1,  -1,   6,   6,  -1, -1},
+    {-1,  -3,   5,   9,  -3,  -1,  -1,   3, -11, -18,   4,  -3,  12, -21,  53,  90, -25,  13,   3,  -7,  17,  29,  -9,   4,  -1,   2,  -8, -13,   3,  -1,  -1,  -1,   4,   7,  -1, -1},
+    {-1,  -2,   3,  11,  -3,  -1,  -1,   2,  -7, -21,   4,  -3,   8, -15,  34, 103, -21,  11,   2,  -5,  11,  34,  -7,   3,  -1,   2,  -5, -15,   2,  -2,  -1,  -1,   2,   8,   0, 0},
+    {0,   0,   1,  12,  -2,   0,   0,   1,  -3, -22,   2,  -2,   0,  -8,  16, 112, -13,   6,   0,  -3,   5,  37,  -4,   2,   0,   1,  -3, -16,   1,  -1,   0,   0,   0,   9,   0, 0},
+    {-1,   0,  15,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,  -1,   0, 100,   0,  -1,   0,  -1,   0,  60,   0,  -1,   0,   0,  -1, -23,  -1,   0,   0,   0,   0,  13,   0,   0, 0},
+    {0,  -2,  14,   2,   0,   0,  -2,   3, -27,  -4,   1,   0,   5, -11,  97,  14,  -7,   0,   3,  -7,  58,   8,  -4,   0,  -2,   2, -23,  -4,   1,   0,   0,  -2,  13,   2,   0, 0},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -25,  -9,   3,  -1,   9, -18,  90,  29, -13,   7,   5, -11,  53,  17,  -8,   4,  -3,   3, -21,  -7,   2,  -1,  -1,  -1,  12,   3,  -1, -1},
+    {-1,  -4,  11,   6,  -1,  -1,  -4,   5, -22, -14,   4,  -1,  11, -22,  78,  46, -19,  10,   6, -14,  46,  27, -12,   6,  -1,   4, -19, -11,   3,  -1,  -1,  -1,  10,   6,  -1, -1},
+    {-1,  -4,   9,   9,  -4,  -1,  -4,   5, -18, -18,   5,  -4,  11, -22,  63,  63, -22,  11,   7, -13,  37,  37, -13,   7,  -1,   4, -15, -15,   4,  -1,  -1,  -1,   8,   8,  -1, -1},
+    {-1,  -1,   6,  11,  -4,  -1,  -1,   4, -14, -22,   5,  -4,  10, -19,  46,  78, -22,  11,   6, -12,  27,  46, -14,   6,  -1,   3, -11, -19,   4,  -1,  -1,  -1,   6,  10,  -1, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -9, -25,   4,  -3,   7, -13,  29,  90, -18,   9,   4,  -8,  17,  53, -11,   5,  -1,   2,  -7, -21,   3,  -3,  -1,  -1,   3,  12,  -1, -1},
+    {0,   0,   2,  14,  -2,   0,   0,   1,  -4, -27,   3,  -2,   0,  -7,  14,  97, -11,   5,   0,  -4,   8,  58,  -7,   3,   0,   1,  -4, -23,   2,  -2,   0,   0,   2,  13,  -2, 0},
+    {-1,   0,  15,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,  -1,   0,  81,   0,  -1,   0,  -1,   0,  81,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,   0,   0,  15,   0,   0, 0},
+    {0,  -2,  15,   2,   0,   0,  -2,   2, -27,  -4,   1,   0,   4,  -9,  79,  11,  -6,   0,   4,  -9,  79,  11,  -6,   0,  -2,   2, -27,  -4,   1,   0,   0,  -2,  15,   2,   0, 0},
+    {-1,  -3,  13,   4,  -1,  -1,  -3,   4, -25,  -9,   3,  -1,   7, -15,  73,  24, -11,   6,   7, -15,  73,  24, -11,   6,  -3,   4, -25,  -9,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -4,  11,   7,  -1,  -1,  -4,   5, -22, -13,   4,  -1,   9, -18,  63,  37, -15,   8,   9, -18,  63,  37, -15,   8,  -4,   5, -22, -13,   4,  -1,  -1,  -4,  11,   7,  -1, -1},
+    {-1,  -1,   8,   8,  -1,  -1,  -1,   4, -18, -18,   4,  -1,   8, -18,  50,  50, -18,   8,   9, -18,  50,  50, -18,   9,  -1,   4, -18, -18,   4,  -1,  -1,  -1,   9,   9,  -1, -1},
+    {-1,  -1,   7,  11,  -4,  -1,  -1,   4, -13, -22,   5,  -4,   8, -15,  37,  63, -18,   9,   8, -15,  37,  63, -18,   9,  -1,   4, -13, -22,   5,  -4,  -1,  -1,   7,  11,  -4, -1},
+    {-1,  -1,   4,  13,  -3,  -1,  -1,   3,  -9, -25,   4,  -3,   6, -11,  24,  73, -15,   7,   6, -11,  24,  73, -15,   7,  -1,   3,  -9, -25,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {0,   0,   2,  15,  -2,   0,   0,   1,  -4, -27,   2,  -2,   0,  -6,  11,  79,  -9,   4,   0,  -6,  11,  79,  -9,   4,   0,   1,  -4, -27,   2,  -2,   0,   0,   2,  15,  -2, 0},
+    {-1,   0,  13,   0,  -1,   0,   0,  -1, -23,  -1,   0,   0,  -1,   0,  60,   0,  -1,   0,  -1,   0, 100,   0,  -1,   0,   0,  -1, -27,  -1,   0,   0,   0,   0,  15,   0,   0, 0},
+    {0,  -2,  13,   2,   0,   0,  -2,   2, -23,  -4,   1,   0,   3,  -7,  58,   8,  -4,   0,   5, -11,  97,  14,  -7,   0,  -2,   3, -27,  -4,   1,   0,   0,  -2,  14,   2,   0, 0},
+    {-1,  -1,  12,   3,  -1,  -1,  -3,   3, -21,  -7,   2,  -1,   5, -11,  53,  17,  -8,   4,   9, -18,  90,  29, -13,   7,  -3,   4, -25,  -9,   3,  -1,  -1,  -3,  13,   4,  -1, -1},
+    {-1,  -1,  10,   6,  -1,  -1,  -1,   4, -19, -12,   3,  -1,   6, -14,  46,  27, -11,   6,  11, -22,  78,  46, -19,  10,  -4,   5, -22, -14,   4,  -1,  -1,  -4,  11,   6,  -1, -1},
+    {-1,  -1,   8,   8,  -1,  -1,  -1,   4, -15, -15,   4,  -1,   7, -13,  37,  37, -13,   7,  11, -22,  63,  63, -22,  11,  -4,   5, -18, -18,   5,  -4,  -1,  -4,   9,   9,  -4, -1},
+    {-1,  -1,   6,  10,  -1,  -1,  -1,   3, -12, -19,   4,  -1,   6, -11,  27,  46, -14,   6,  10, -19,  46,  78, -22,  11,  -1,   4, -14, -22,   5,  -4,  -1,  -1,   6,  11,  -4, -1},
+    {-1,  -1,   3,  12,  -1,  -1,  -1,   2,  -7, -21,   3,  -3,   4,  -8,  17,  53, -11,   5,   7, -13,  29,  90, -18,   9,  -1,   3,  -9, -25,   4,  -3,  -1,  -1,   4,  13,  -3, -1},
+    {0,   0,   2,  13,  -2,   0,   0,   1,  -4, -23,   2,  -2,   0,  -4,   8,  58,  -7,   3,   0,  -7,  14,  97, -11,   5,   0,   1,  -4, -27,   3,  -2,   0,   0,   2,  14,  -2, 0},
+    {0,   0,   9,   0,   0,   0,   0,   0, -17,   0,   0,   0,  -1,   0,  38,   0,  -1,   0,  -1,   0, 115,   0,  -1,   0,   0,  -1, -23,  -1,   0,   0,   0,   0,  12,   0,   0, 0},
+    {0,   0,   9,   0,   0,   0,  -1,   1, -16,  -3,   1,   0,   2,  -4,  37,   5,  -3,   0,   6, -13, 112,  16,  -8,   0,  -2,   2, -22,  -3,   1,   0,   0,  -2,  12,   1,   0, 0},
+    {-1,  -1,   8,   2,  -1,  -1,  -2,   2, -15,  -5,   2,  -1,   3,  -7,  34,  11,  -5,   2,  11, -21, 103,  34, -15,   8,  -3,   4, -21,  -7,   2,  -1,   0,  -3,  11,   3,  -2, 0},
+    {-1,  -1,   7,   4,  -1,  -1,  -1,   3, -13,  -8,   2,  -1,   4,  -9,  29,  17,  -7,   3,  13, -25,  90,  53, -21,  12,  -3,   4, -18, -11,   3,  -1,  -1,  -3,   9,   5,  -3, -1},
+    {-1,  -1,   6,   6,  -1,  -1,  -1,   3, -11, -11,   3,  -1,   4,  -9,  24,  24,  -9,   4,  13, -25,  73,  73, -25,  13,  -3,   4, -15, -15,   4,  -3,  -1,  -3,   7,   7,  -3, -1},
+    {-1,  -1,   4,   7,  -1,  -1,  -1,   2,  -8, -13,   3,  -1,   3,  -7,  17,  29,  -9,   4,  12, -21,  53,  90, -25,  13,  -1,   3, -11, -18,   4,  -3,  -1,  -3,   5,   9,  -3, -1},
+    {-1,  -1,   2,   8,  -1,  -1,  -1,   2,  -5, -15,   2,  -2,   2,  -5,  11,  34,  -7,   3,   8, -15,  34, 103, -21,  11,  -1,   2,  -7, -21,   4,  -3,   0,  -2,   3,  11,  -3, 0},
+    {0,   0,   0,   9,   0,   0,   0,   1,  -3, -16,   1,  -1,   0,  -3,   5,  37,  -4,   2,   0,  -8,  16, 112, -13,   6,   0,   1,  -3, -22,   2,  -2,   0,   0,   1,  12,  -2, 0},
+    {0,   0,   5,   0,   0,   0,   0,   0,  -9,   0,   0,   0,   0,   0,  17,   0,   0,   0,  -1,   0, 124,   0,  -1,   0,   0,   0, -14,   0,   0,   0,   0,   0,   7,   0,   0, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -8,  -1,   1,   0,   1,  -2,  17,   2,  -1,   0,   7, -13, 122,  17,  -8,   0,  -1,   1, -13,  -2,   1,   0,   0,  -1,   7,   1,   0, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -8,  -3,   1,   0,   1,  -3,  16,   5,  -3,   0,  12, -22, 112,  37, -16,   9,  -2,   2, -13,  -4,   1,   0,   0,  -2,   6,   2,  -1, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -7,  -4,   1,   0,   2,  -4,  14,   8,  -4,   2,  14, -27,  97,  58, -23,  13,  -2,   3, -11,  -7,   2,  -2,   0,  -2,   5,   3,  -2, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -6,  -6,   1,   0,   2,  -4,  11,  11,  -4,   2,  15, -27,  79,  79, -27,  15,  -2,   2,  -9,  -9,   2,  -2,   0,  -2,   4,   4,  -2, 0},
+      0,   0,   0,   0,   0,   0,   1,  -4,  -7,   1,   0,   2,  -4,   8,  14,  -4,   2,  13, -23,  58,  97, -27,  14,  -2,   2,  -7, -11,   3,  -2,   0,  -2,   3,   5,  -2, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -3,  -8,   1,   0,   0,  -3,   5,  16,  -3,   1,   9, -16,  37, 112, -22,  12,   0,   1,  -4, -13,   2,  -2,   0,  -1,   2,   6,  -2, 0},
+    {0,   0,   0,   0,   0,   0,   0,   1,  -1,  -8,   1,   0,   0,  -1,   2,  17,  -2,   1,   0,  -8,  17, 122, -13,   7,   0,   1,  -2, -13,   1,  -1,   0,   0,   1,   7,  -1, 0}
+#endif  /* EDGE_PIXEL_FILTER_EXTEND */
+
+#endif  /* SUBPEL_SHIFTS==16 */
 };
 
 #endif  // EDGE_PIXEL_FILTER
@@ -674,6 +1330,9 @@
 )
 {
     int FData[(3+INTERP_EXTEND*2)*4]; /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_block2d\n");
+#endif
 
     /* First filter 1-D horizontally... */
     filter_block2d_first_pass(src_ptr - ((INTERP_EXTEND-1) * src_pixels_per_line), FData, src_pixels_per_line, 1,
@@ -697,6 +1356,9 @@
     const short  *HFilter;
     const short  *VFilter;
 
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict_c\n");
+#endif
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
     VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
 
@@ -720,6 +1382,9 @@
     const short  *VFilter;
     // int FData[(7+INTERP_EXTEND*2)*16];   /* Temp data buffer used in filtering */
     int FData[(7+INTERP_EXTEND*2)*8];   /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x8_c\n");
+#endif
 
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
     VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
@@ -752,6 +1417,9 @@
     const short  *VFilter;
     // int FData[(7+INTERP_EXTEND*2)*16];   /* Temp data buffer used in filtering */
     int FData[(7+INTERP_EXTEND*2)*8];   /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict_avg8x8_c\n");
+#endif
 
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
     VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
@@ -782,6 +1450,9 @@
     const short  *VFilter;
     // int FData[(7+INTERP_EXTEND*2)*16];   /* Temp data buffer used in filtering */
     int FData[(3+INTERP_EXTEND*2)*8];   /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x4_c\n");
+#endif
 
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
     VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
@@ -814,6 +1485,9 @@
     const short  *VFilter;
     // int FData[(15+INTERP_EXTEND*2)*24];   /* Temp data buffer used in filtering */
     int FData[(15+INTERP_EXTEND*2)*16];  /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict16x16_c\n");
+#endif
 
 
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
@@ -846,6 +1520,9 @@
     const short  *VFilter;
     // int FData[(15+INTERP_EXTEND*2)*24];   /* Temp data buffer used in filtering */
     int FData[(15+INTERP_EXTEND*2)*16];  /* Temp data buffer used in filtering */
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict_avg16x16_c\n");
+#endif
 
     HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
     VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
--- a/vp8/common/filter.h
+++ b/vp8/common/filter.h
@@ -18,15 +18,21 @@
 #define VP8_FILTER_WEIGHT 128
 #define VP8_FILTER_SHIFT  7
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define SUBPEL_SHIFTS 16
+#else
+#define SUBPEL_SHIFTS 8
+#endif
+
+extern const short vp8_bilinear_filters[SUBPEL_SHIFTS][2];
+extern const short vp8_sub_pel_filters[SUBPEL_SHIFTS][INTERP_EXTEND*2];
+
 /* whether to use a special filter for edge pixels */
 #define EDGE_PIXEL_FILTER 0
 
-extern const short vp8_bilinear_filters[8][2];
-extern const short vp8_sub_pel_filters[8][INTERP_EXTEND*2];
-
 #if EDGE_PIXEL_FILTER > 0
 #define EDGE_PIXEL_FILTER_EXTEND 2
-extern const short vp8_sub_pel_filters_ns[64][4*EDGE_PIXEL_FILTER_EXTEND*EDGE_PIXEL_FILTER_EXTEND];
+extern const short vp8_sub_pel_filters_ns[SUBPEL_SHIFTS*SUBPEL_SHIFTS][4*EDGE_PIXEL_FILTER_EXTEND*EDGE_PIXEL_FILTER_EXTEND];
 #endif
 
 #endif //FILTER_H
--- a/vp8/common/reconinter.c
+++ b/vp8/common/reconinter.c
@@ -180,7 +180,11 @@
     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
     {
         ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        sppf(ptr, d->pre_stride, (d->bmi.mv.as_mv.col & 7)<<1, (d->bmi.mv.as_mv.row & 7)<<1, pred_ptr, pitch);
+#else
         sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+#endif
     }
     else
     {
@@ -214,7 +218,11 @@
 
     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        x->subpixel_predict8x8(ptr, d->pre_stride, (d->bmi.mv.as_mv.col & 7)<<1, (d->bmi.mv.as_mv.row & 7)<<1, pred_ptr, pitch);
+#else
         x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+#endif
     }
     else
     {
@@ -233,7 +241,11 @@
 
     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        x->subpixel_predict8x4(ptr, d->pre_stride, (d->bmi.mv.as_mv.col & 7)<<1, (d->bmi.mv.as_mv.row & 7)<<1, pred_ptr, pitch);
+#else
         x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+#endif
     }
     else
     {
@@ -249,8 +261,10 @@
     unsigned char *upred_ptr = &x->predictor[256];
     unsigned char *vpred_ptr = &x->predictor[320];
 
-    int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
-    int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
+    int omv_row = x->mode_info_context->mbmi.mv.as_mv.row;
+    int omv_col = x->mode_info_context->mbmi.mv.as_mv.col;
+    int mv_row  = omv_row;
+    int mv_col  = omv_col;
     int offset;
     int pre_stride = x->block[16].pre_stride;
 
@@ -275,11 +289,19 @@
     uptr = x->pre.u_buffer + offset;
     vptr = x->pre.v_buffer + offset;
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    if ((omv_row | omv_col) & 15)
+    {
+        x->subpixel_predict8x8(uptr, pre_stride, omv_col & 15, omv_row & 15, upred_ptr, 8);
+        x->subpixel_predict8x8(vptr, pre_stride, omv_col & 15, omv_row & 15, vpred_ptr, 8);
+    }
+#else   /* CONFIG_SIXTEENTH_SUBPEL_UV */
     if ((mv_row | mv_col) & 7)
     {
         x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
         x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
     }
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
     else
     {
         RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
@@ -361,7 +383,11 @@
 
     if ((mv_row | mv_col) & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        x->subpixel_predict16x16(ptr, pre_stride, (mv_col & 7)<<1, (mv_row & 7)<<1, pred_ptr, 16);
+#else
         x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
+#endif
     }
     else
     {
@@ -418,6 +444,7 @@
     unsigned char *ptr;
     unsigned char *uptr, *vptr;
 
+    int_mv _o16x16mv;
     int_mv _16x16mv;
 
     unsigned char *ptr_base = x->pre.y_buffer;
@@ -434,7 +461,11 @@
 
     if ( _16x16mv.as_int & 0x00070007)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        x->subpixel_predict16x16(ptr, pre_stride, (_16x16mv.as_mv.col & 7)<<1, (_16x16mv.as_mv.row & 7)<<1, dst_y, dst_ystride);
+#else
         x->subpixel_predict16x16(ptr, pre_stride, _16x16mv.as_mv.col & 7,  _16x16mv.as_mv.row & 7, dst_y, dst_ystride);
+#endif
     }
     else
     {
@@ -441,6 +472,7 @@
         RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_y, dst_ystride);
     }
 
+    _o16x16mv = _16x16mv;
     /* calc uv motion vectors */
     if ( _16x16mv.as_mv.row < 0)
       _16x16mv.as_mv.row -= 1;
@@ -463,11 +495,19 @@
     uptr = x->pre.u_buffer + offset;
     vptr = x->pre.v_buffer + offset;
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    if ( _o16x16mv.as_int & 0x000f000f)
+    {
+        x->subpixel_predict8x8(uptr, pre_stride, _o16x16mv.as_mv.col & 15,  _o16x16mv.as_mv.row & 15, dst_u, dst_uvstride);
+        x->subpixel_predict8x8(vptr, pre_stride, _o16x16mv.as_mv.col & 15,  _o16x16mv.as_mv.row & 15, dst_v, dst_uvstride);
+    }
+#else  /* CONFIG_SIXTEENTH_SUBPEL_UV */
     if ( _16x16mv.as_int & 0x00070007)
     {
         x->subpixel_predict8x8(uptr, pre_stride, _16x16mv.as_mv.col & 7,  _16x16mv.as_mv.row & 7, dst_u, dst_uvstride);
         x->subpixel_predict8x8(vptr, pre_stride, _16x16mv.as_mv.col & 7,  _16x16mv.as_mv.row & 7, dst_v, dst_uvstride);
     }
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
     else
     {
         RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, dst_u, dst_uvstride);
@@ -503,6 +543,7 @@
 
     int mv_row = x->mode_info_context->mbmi.second_mv.as_mv.row;
     int mv_col = x->mode_info_context->mbmi.second_mv.as_mv.col;
+    int omv_row, omv_col;
 
     unsigned char *ptr_base = x->second_pre.y_buffer;
     int pre_stride = x->block[0].pre_stride;
@@ -511,7 +552,11 @@
 
     if ((mv_row | mv_col) & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+        x->subpixel_predict_avg16x16(ptr, pre_stride, (mv_col & 7)<<1, (mv_row & 7)<<1, dst_y, dst_ystride);
+#else
         x->subpixel_predict_avg16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, dst_ystride);
+#endif
     }
     else
     {
@@ -519,6 +564,8 @@
     }
 
     /* calc uv motion vectors */
+    omv_row = mv_row;
+    omv_col = mv_col;
     mv_row = (mv_row + (mv_row > 0)) >> 1;
     mv_col = (mv_col + (mv_col > 0)) >> 1;
 
@@ -530,11 +577,19 @@
     uptr = x->second_pre.u_buffer + offset;
     vptr = x->second_pre.v_buffer + offset;
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    if ((omv_row | omv_col) & 15)
+    {
+        x->subpixel_predict_avg8x8(uptr, pre_stride, omv_col & 15, omv_row & 15, dst_u, dst_uvstride);
+        x->subpixel_predict_avg8x8(vptr, pre_stride, omv_col & 15, omv_row & 15, dst_v, dst_uvstride);
+    }
+#else  /* CONFIG_SIXTEENTH_SUBPEL_UV */
     if ((mv_row | mv_col) & 7)
     {
         x->subpixel_predict_avg8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, dst_u, dst_uvstride);
         x->subpixel_predict_avg8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, dst_v, dst_uvstride);
     }
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
     else
     {
         RECON_INVOKE(&x->rtcd->recon, avg8x8)(uptr, pre_stride, dst_u, dst_uvstride);
--- a/vp8/common/x86/subpixel_ssse3.asm
+++ b/vp8/common/x86/subpixel_ssse3.asm
@@ -1495,13 +1495,33 @@
     times 8 db  36,  -11
     times 8 db  12,   -6
 align 16
+%if CONFIG_SIXTEENTH_SUBPEL_UV
 vp8_bilinear_filters_ssse3:
     times 8 db 128, 0
+    times 8 db 120, 8
     times 8 db 112, 16
+    times 8 db 104, 24
     times 8 db 96,  32
+    times 8 db 88,  40
     times 8 db 80,  48
+    times 8 db 72,  56
     times 8 db 64,  64
+    times 8 db 56,  72
     times 8 db 48,  80
+    times 8 db 40,  88
     times 8 db 32,  96
+    times 8 db 24,  104
     times 8 db 16,  112
+    times 8 db 8,   120
+%else
+vp8_bilinear_filters_ssse3:
+    times 8 db 128, 0
+    times 8 db 112, 16
+    times 8 db 96,  32
+    times 8 db 80,  48
+    times 8 db 64,  64
+    times 8 db 48,  80
+    times 8 db 32,  96
+    times 8 db 16,  112
+%endif
 
--- a/vp8/common/x86/vp8_asm_stubs.c
+++ b/vp8/common/x86/vp8_asm_stubs.c
@@ -13,9 +13,16 @@
 #include "vpx_ports/mem.h"
 #include "vp8/common/subpixel.h"
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+extern const short vp8_six_tap_mmx[16][6*8];
+extern const short vp8_bilinear_filters_mmx[16][2*8];
+#else
 extern const short vp8_six_tap_mmx[8][6*8];
 extern const short vp8_bilinear_filters_mmx[8][2*8];
+#endif
 
+//#define ANNOUNCE_FUNCTION
+
 extern void vp8_filter_block1d_h6_mmx
 (
     unsigned char   *src_ptr,
@@ -128,6 +135,9 @@
     int dst_pitch
 )
 {
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict4x4_mmx\n");
+#endif
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 16*16);  /* Temp data bufffer used in filtering */
     const short *HFilter, *VFilter;
     HFilter = vp8_six_tap_mmx[xoffset];
@@ -149,6 +159,9 @@
 )
 {
 
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict16x16_mmx\n");
+#endif
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 24*24);  /* Temp data bufffer used in filtering */
 
     const short *HFilter, *VFilter;
@@ -181,6 +194,9 @@
 )
 {
 
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x8_mmx\n");
+#endif
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);    /* Temp data bufffer used in filtering */
 
     const short *HFilter, *VFilter;
@@ -206,7 +222,9 @@
     int dst_pitch
 )
 {
-
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x4_mmx\n");
+#endif
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);    /* Temp data bufffer used in filtering */
 
     const short *HFilter, *VFilter;
@@ -256,6 +274,9 @@
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 24*24);    /* Temp data bufffer used in filtering */
 
     const short *HFilter, *VFilter;
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict16x16_sse2\n");
+#endif
 
     if (xoffset)
     {
@@ -295,6 +316,9 @@
 {
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);  /* Temp data bufffer used in filtering */
     const short *HFilter, *VFilter;
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x8_sse2\n");
+#endif
 
     if (xoffset)
     {
@@ -333,6 +357,9 @@
 {
     DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);  /* Temp data bufffer used in filtering */
     const short *HFilter, *VFilter;
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x4_sse2\n");
+#endif
 
     if (xoffset)
     {
@@ -434,6 +461,9 @@
 )
 {
     DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 24*24);
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict16x16_ssse3\n");
+#endif
 
     if (xoffset)
     {
@@ -466,6 +496,9 @@
 )
 {
     DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 256);
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x8_ssse3\n");
+#endif
 
     if (xoffset)
     {
@@ -498,6 +531,9 @@
 )
 {
     DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 256);
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict8x4_ssse3\n");
+#endif
 
     if (xoffset)
     {
@@ -530,6 +566,9 @@
 )
 {
   DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 4*9);
+#ifdef ANNOUNCE_FUNCTION
+    printf("vp8_sixtap_predict4x4_ssse3\n");
+#endif
 
   if (xoffset)
   {
--- a/vp8/common/x86/x86_systemdependent.c
+++ b/vp8/common/x86/x86_systemdependent.c
@@ -43,17 +43,17 @@
         rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_mmx;
         rtcd->idct.iwalsh1     = vp8_short_inv_walsh4x4_1_mmx;
 
-
-
         rtcd->recon.recon       = vp8_recon_b_mmx;
         rtcd->recon.copy8x8     = vp8_copy_mem8x8_mmx;
         rtcd->recon.copy8x4     = vp8_copy_mem8x4_mmx;
         rtcd->recon.copy16x16   = vp8_copy_mem16x16_mmx;
 
+#if CONFIG_ENHANCED_INTERP == 0 && CONFIG_HIGH_PRECISION_MV == 0 && CONFIG_SIXTEENTH_SUBPEL_UV == 0
         rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_mmx;
         rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_mmx;
         rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_mmx;
         rtcd->subpix.sixtap4x4     = vp8_sixtap_predict4x4_mmx;
+#endif
         rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_mmx;
         rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_mmx;
         rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_mmx;
@@ -91,9 +91,11 @@
 
         rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_sse2;
 
+#if CONFIG_ENHANCED_INTERP == 0 && CONFIG_HIGH_PRECISION_MV == 0 && CONFIG_SIXTEENTH_SUBPEL_UV == 0
         rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_sse2;
         rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_sse2;
         rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_sse2;
+#endif
         rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_sse2;
         rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_sse2;
 
@@ -120,6 +122,7 @@
 
     if (flags & HAS_SSSE3)
     {
+#if CONFIG_ENHANCED_INTERP == 0 && CONFIG_HIGH_PRECISION_MV == 0
         rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_ssse3;
         rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_ssse3;
         rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_ssse3;
@@ -126,6 +129,7 @@
         rtcd->subpix.sixtap4x4     = vp8_sixtap_predict4x4_ssse3;
         rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_ssse3;
         rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_ssse3;
+#endif
 
         rtcd->recon.build_intra_predictors_mbuv =
             vp8_build_intra_predictors_mbuv_ssse3;
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -21,6 +21,12 @@
 #if CONFIG_DEBUG
 #include <assert.h>
 #endif
+
+//#define DEBUG_DEC_MV
+#ifdef DEBUG_DEC_MV
+int dec_mvcount = 0;
+#endif
+
 static int vp8_read_bmode(vp8_reader *bc, const vp8_prob *p)
 {
     const int i = vp8_treed_read(bc, vp8_bmode_tree, p);
@@ -173,7 +179,7 @@
         {
             x += vp8_read(r, p [MVPbits + i]) << i;
         }
-        while (++i < 3);
+        while (++i < mvnum_short_bits);
 
         i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
 
@@ -181,10 +187,10 @@
         {
             x += vp8_read(r, p [MVPbits + i]) << i;
         }
-        while (--i > 3);
+        while (--i > mvnum_short_bits);
 
-        if (!(x & 0xFFF0)  ||  vp8_read(r, p [MVPbits + 3]))
-            x += 8;
+        if (!(x & ~((2<<mvnum_short_bits)-1))  ||  vp8_read(r, p [MVPbits + mvnum_short_bits]))
+            x += (mvnum_short);
     }
     else   /* small */
         x = vp8_treed_read(r, vp8_small_mvtree, p + MVPshort);
@@ -197,8 +203,14 @@
 
 static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc)
 {
-    mv->row = (short)(read_mvcomponent(r,   mvc) << 1);
-    mv->col = (short)(read_mvcomponent(r, ++mvc) << 1);
+    mv->row = (short)(read_mvcomponent(r,   mvc) << MV_SHIFT);
+    mv->col = (short)(read_mvcomponent(r, ++mvc) << MV_SHIFT);
+#ifdef DEBUG_DEC_MV
+    int i;
+    printf("%d: %d %d\n", dec_mvcount++, mv->row, mv->col);
+    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[-1])->prob[i]); printf("\n");
+    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[0])->prob[i]); printf("\n");
+#endif
 }
 
 
@@ -985,4 +997,3 @@
 
 }
 #endif /* CONFIG_SUPERBLOCKS */
-
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -1029,6 +1029,7 @@
 
     /* Is segmentation enabled */
     xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc);
+
     if (xd->segmentation_enabled)
     {
         // Read whether or not the segmentation map is being explicitly
@@ -1285,6 +1286,11 @@
 
         pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp8_read_bit(bc);
         pc->ref_frame_sign_bias[ALTREF_FRAME] = vp8_read_bit(bc);
+
+#if CONFIG_HIGH_PRECISION_MV
+        /* Is high precision mv allowed */
+        xd->allow_high_precision_mv = (unsigned char)vp8_read_bit(bc);
+#endif
     }
 
     pc->refresh_entropy_probs = vp8_read_bit(bc);
@@ -1471,4 +1477,3 @@
 
     return 0;
 }
-
--- a/vp8/encoder/arm/variance_arm.c
+++ b/vp8/encoder/arm/variance_arm.c
@@ -13,6 +13,12 @@
 #include "vp8/common/filter.h"
 #include "vp8/common/arm/bilinearfilter_arm.h"
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define HALFNDX 8
+#else
+#define HALFNDX 4
+#endif
+
 #if HAVE_ARMV6
 
 unsigned int vp8_sub_pixel_variance8x8_armv6
@@ -59,17 +65,17 @@
     const short *HFilter, *VFilter;
     unsigned int var;
 
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         var = vp8_variance_halfpixvar16x16_h_armv6(src_ptr, src_pixels_per_line,
                                                    dst_ptr, dst_pixels_per_line, sse);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         var = vp8_variance_halfpixvar16x16_v_armv6(src_ptr, src_pixels_per_line,
                                                    dst_ptr, dst_pixels_per_line, sse);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         var = vp8_variance_halfpixvar16x16_hv_armv6(src_ptr, src_pixels_per_line,
                                                    dst_ptr, dst_pixels_per_line, sse);
@@ -107,11 +113,11 @@
     unsigned int *sse
 )
 {
-  if (xoffset == 4 && yoffset == 0)
+  if (xoffset == HALFNDX && yoffset == 0)
     return vp8_variance_halfpixvar16x16_h_neon(src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
-  else if (xoffset == 0 && yoffset == 4)
+  else if (xoffset == 0 && yoffset == HALFNDX)
     return vp8_variance_halfpixvar16x16_v_neon(src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
-  else if (xoffset == 4 && yoffset == 4)
+  else if (xoffset == HALFNDX && yoffset == HALFNDX)
     return vp8_variance_halfpixvar16x16_hv_neon(src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
   else
     return vp8_sub_pixel_variance16x16_neon_func(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -2945,6 +2945,11 @@
         // Indicate reference frame sign bias for Golden and ARF frames (always 0 for last frame buffer)
         vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
         vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
+
+#if CONFIG_HIGH_PRECISION_MV
+        // Signal whether to allow high MV precision
+        vp8_write_bit(bc, (xd->allow_high_precision_mv) ? 1 : 0);
+#endif
     }
 
     if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
--- a/vp8/encoder/encodemv.c
+++ b/vp8/encoder/encodemv.c
@@ -20,6 +20,11 @@
 extern unsigned int active_section;
 #endif
 
+//#define DEBUG_ENC_MV
+#ifdef DEBUG_ENC_MV
+int enc_mvcount = 0;
+#endif
+
 static void encode_mvcomponent(
     vp8_writer *const w,
     const int v,
@@ -32,8 +37,7 @@
     if (x < mvnum_short)     // Small
     {
         vp8_write(w, 0, p [mvpis_short]);
-        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
-
+        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, mvnum_short_bits);
         if (!x)
             return;         // no sign bit
     }
@@ -46,7 +50,7 @@
         do
             vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
 
-        while (++i < 3);
+        while (++i < mvnum_short_bits);
 
         i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
 
@@ -53,10 +57,10 @@
         do
             vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
 
-        while (--i > 3);
+        while (--i > mvnum_short_bits);
 
-        if (x & 0xFFF0)
-            vp8_write(w, (x >> 3) & 1, p [MVPbits + 3]);
+        if (x & ~((2<<mvnum_short_bits)-1))
+            vp8_write(w, (x >> mvnum_short_bits) & 1, p [MVPbits + mvnum_short_bits]);
     }
 
     vp8_write(w, v < 0, p [MVPsign]);
@@ -91,9 +95,17 @@
         }
     }
 #endif
-
-    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
-    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
+    encode_mvcomponent(w, mv->row >> MV_SHIFT, &mvc[0]);
+    encode_mvcomponent(w, mv->col >> MV_SHIFT, &mvc[1]);
+#ifdef DEBUG_ENC_MV
+    {
+    int i;
+    printf("%d: %d %d\n", enc_mvcount++, mv->row, mv->col);
+    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[0])->prob[i]); printf("\n");
+    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[1])->prob[i]); printf("\n");
+    fflush(stdout);
+    }
+#endif
 }
 
 
@@ -106,7 +118,7 @@
     if (x < mvnum_short)
     {
         cost = vp8_cost_zero(p [mvpis_short])
-               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
+               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, mvnum_short_bits);
 
         if (!x)
             return cost;
@@ -119,7 +131,7 @@
         do
             cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
 
-        while (++i < 3);
+        while (++i < mvnum_short_bits);
 
         i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
 
@@ -126,10 +138,10 @@
         do
             cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
 
-        while (--i > 3);
+        while (--i > mvnum_short_bits);
 
-        if (x & 0xFFF0)
-            cost += vp8_cost_bit(p [MVPbits + 3], (x >> 3) & 1);
+        if (x & ~((2<<mvnum_short_bits)-1))
+            cost += vp8_cost_bit(p [MVPbits + mvnum_short_bits], (x >> mvnum_short_bits) & 1);
     }
 
     return cost;   // + vp8_cost_bit( p [MVPsign], v < 0);
@@ -258,7 +270,7 @@
     {
         const int c = events [mv_max];
 
-        is_short_ct [0] += c;     // Short vector
+        is_short_ct [0] += c;    // Short vector
         short_ct [0] += c;       // Magnitude distribution
     }
 
@@ -342,7 +354,7 @@
         int j = 0;
 
         vp8_tree_probs_from_distribution(
-            8, vp8_small_mvencodings, vp8_small_mvtree,
+            mvnum_short, vp8_small_mvencodings, vp8_small_mvtree,
             p, short_bct, short_ct,
             256, 1
         );
@@ -398,6 +410,15 @@
     vp8_writer *const w  = & cpi->bc;
     MV_CONTEXT *mvc = cpi->common.fc.mvc;
     int flags[2] = {0, 0};
+#ifdef DEBUG_ENC_MV
+    {
+    int i;
+    printf("Writing probs\n");
+    for (i=0; i<MVPcount;++i) printf("  %d", vp8_default_mv_context[0].prob[i]); printf("\n");
+    for (i=0; i<MVPcount;++i) printf("  %d", vp8_default_mv_context[1].prob[i]); printf("\n");
+    fflush(stdout);
+    }
+#endif
 #ifdef ENTROPY_STATS
     active_section = 4;
 #endif
--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -28,13 +28,13 @@
     // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
     // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
     // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
-    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1]) * Weight) >> 7;
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> MV_SHIFT] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> MV_SHIFT]) * Weight) >> 7;
 }
 
 static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit)
 {
-    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
-        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> MV_SHIFT] +
+        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> MV_SHIFT])
         * error_per_bit + 128) >> 8;
 }
 
@@ -175,13 +175,33 @@
  * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
  * could reduce the area.
  */
-#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+
+#if CONFIG_HIGH_PRECISION_MV
+
+#define PRE(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) // pointer to predictor base of a motionvector
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
+#else
+#define SP(x) ((x)&7) // convert motion vector component to offset for svf calc
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
+
+#else   /* CONFIG_HIGH_PRECISION_MV */
+
 #define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define SP(x) (((x)&3)<<2) // convert motion vector component to offset for svf calc
+#else
 #define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
+
+#endif  /* CONFIG_HIGH_PRECISION_MV */
+
+#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c)-rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
 #define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
 #define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
 #define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
 #define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = DIST(r,c); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
+
 #define MIN(x,y) (((x)<(y))?(x):(y))
 #define MAX(x,y) (((x)>(y))?(x):(y))
 
@@ -194,8 +214,15 @@
 {
     unsigned char *z = (*(b->base_src) + b->src);
 
+#if CONFIG_HIGH_PRECISION_MV
+    int rr = ref_mv->as_mv.row, rc = ref_mv->as_mv.col;
+    int br = bestmv->as_mv.row << 3, bc = bestmv->as_mv.col << 3;
+    int hstep = 4;
+#else
     int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
     int br = bestmv->as_mv.row << 2, bc = bestmv->as_mv.col << 2;
+    int hstep = 2;
+#endif
     int tr = br, tc = bc;
     unsigned int besterr = INT_MAX;
     unsigned int left, right, up, down, diag;
@@ -203,12 +230,22 @@
     unsigned int whichdir;
     unsigned int halfiters = 4;
     unsigned int quarteriters = 4;
+#if CONFIG_HIGH_PRECISION_MV
+    unsigned int eighthiters = 4;
+#endif
     int thismse;
 
+#if CONFIG_HIGH_PRECISION_MV
+    int minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << mvlong_width) - 1));
+    int maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width) - 1));
+    int minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width) - 1));
+    int maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width) - 1));
+#else
     int minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
     int maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
     int minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
     int maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
+#endif
 
     int y_stride;
     int offset;
@@ -220,10 +257,10 @@
     int buf_r1, buf_r2, buf_c1, buf_c2;
 
     // Clamping to avoid out-of-range data access
-    buf_r1 = ((bestmv->as_mv.row - 3) < x->mv_row_min)?(bestmv->as_mv.row - x->mv_row_min):3;
-    buf_r2 = ((bestmv->as_mv.row + 3) > x->mv_row_max)?(x->mv_row_max - bestmv->as_mv.row):3;
-    buf_c1 = ((bestmv->as_mv.col - 3) < x->mv_col_min)?(bestmv->as_mv.col - x->mv_col_min):3;
-    buf_c2 = ((bestmv->as_mv.col + 3) > x->mv_col_max)?(x->mv_col_max - bestmv->as_mv.col):3;
+    buf_r1 = ((bestmv->as_mv.row - INTERP_EXTEND) < x->mv_row_min)?(bestmv->as_mv.row - x->mv_row_min):INTERP_EXTEND;
+    buf_r2 = ((bestmv->as_mv.row + INTERP_EXTEND) > x->mv_row_max)?(x->mv_row_max - bestmv->as_mv.row):INTERP_EXTEND;
+    buf_c1 = ((bestmv->as_mv.col - INTERP_EXTEND) < x->mv_col_min)?(bestmv->as_mv.col - x->mv_col_min):INTERP_EXTEND;
+    buf_c2 = ((bestmv->as_mv.col + INTERP_EXTEND) > x->mv_col_max)?(x->mv_col_max - bestmv->as_mv.col):INTERP_EXTEND;
     y_stride = 32;
 
     /* Copy to intermediate buffer before searching. */
@@ -249,10 +286,10 @@
     while (--halfiters)
     {
         // 1/2 pel
-        CHECK_BETTER(left, tr, tc - 2);
-        CHECK_BETTER(right, tr, tc + 2);
-        CHECK_BETTER(up, tr - 2, tc);
-        CHECK_BETTER(down, tr + 2, tc);
+        CHECK_BETTER(left, tr, tc - hstep);
+        CHECK_BETTER(right, tr, tc + hstep);
+        CHECK_BETTER(up, tr - hstep, tc);
+        CHECK_BETTER(down, tr + hstep, tc);
 
         whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
 
@@ -259,16 +296,16 @@
         switch (whichdir)
         {
         case 0:
-            CHECK_BETTER(diag, tr - 2, tc - 2);
+            CHECK_BETTER(diag, tr - hstep, tc - hstep);
             break;
         case 1:
-            CHECK_BETTER(diag, tr - 2, tc + 2);
+            CHECK_BETTER(diag, tr - hstep, tc + hstep);
             break;
         case 2:
-            CHECK_BETTER(diag, tr + 2, tc - 2);
+            CHECK_BETTER(diag, tr + hstep, tc - hstep);
             break;
         case 3:
-            CHECK_BETTER(diag, tr + 2, tc + 2);
+            CHECK_BETTER(diag, tr + hstep, tc + hstep);
             break;
         }
 
@@ -282,12 +319,13 @@
 
     // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
     // 1/4 pel
+    hstep >>= 1;
     while (--quarteriters)
     {
-        CHECK_BETTER(left, tr, tc - 1);
-        CHECK_BETTER(right, tr, tc + 1);
-        CHECK_BETTER(up, tr - 1, tc);
-        CHECK_BETTER(down, tr + 1, tc);
+        CHECK_BETTER(left, tr, tc - hstep);
+        CHECK_BETTER(right, tr, tc + hstep);
+        CHECK_BETTER(up, tr - hstep, tc);
+        CHECK_BETTER(down, tr + hstep, tc);
 
         whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
 
@@ -294,16 +332,16 @@
         switch (whichdir)
         {
         case 0:
-            CHECK_BETTER(diag, tr - 1, tc - 1);
+            CHECK_BETTER(diag, tr - hstep, tc - hstep);
             break;
         case 1:
-            CHECK_BETTER(diag, tr - 1, tc + 1);
+            CHECK_BETTER(diag, tr - hstep, tc + hstep);
             break;
         case 2:
-            CHECK_BETTER(diag, tr + 1, tc - 1);
+            CHECK_BETTER(diag, tr + hstep, tc - hstep);
             break;
         case 3:
-            CHECK_BETTER(diag, tr + 1, tc + 1);
+            CHECK_BETTER(diag, tr + hstep, tc + hstep);
             break;
         }
 
@@ -315,8 +353,49 @@
         tc = bc;
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    if (x->e_mbd.allow_high_precision_mv)
+    {
+        hstep >>= 1;
+        while (--eighthiters)
+        {
+            CHECK_BETTER(left, tr, tc - hstep);
+            CHECK_BETTER(right, tr, tc + hstep);
+            CHECK_BETTER(up, tr - hstep, tc);
+            CHECK_BETTER(down, tr + hstep, tc);
+
+            whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+            switch (whichdir)
+            {
+            case 0:
+                CHECK_BETTER(diag, tr - hstep, tc - hstep);
+                break;
+            case 1:
+                CHECK_BETTER(diag, tr - hstep, tc + hstep);
+                break;
+            case 2:
+                CHECK_BETTER(diag, tr + hstep, tc - hstep);
+                break;
+            case 3:
+                CHECK_BETTER(diag, tr + hstep, tc + hstep);
+                break;
+            }
+
+            // no reason to check the same one again.
+            if (tr == br && tc == bc)
+                break;
+
+            tr = br;
+            tc = bc;
+        }
+    }
+    bestmv->as_mv.row = br;
+    bestmv->as_mv.col = bc;
+#else
     bestmv->as_mv.row = br << 1;
     bestmv->as_mv.col = bc << 1;
+#endif  /* CONFIG_HIGH_PRECISION_MV */
 
     if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL<<3)) ||
         (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL<<3)))
@@ -333,6 +412,12 @@
 #undef CHECK_BETTER
 #undef MIN
 #undef MAX
+
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
+#else
+#define SP(x) ((x)&7) // convert motion vector component to offset for svf calc
+#endif  /* CONFIG_HIGH_PRECISION_MV */
 int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
@@ -343,6 +428,10 @@
     int bestmse = INT_MAX;
     int_mv startmv;
     int_mv this_mv;
+#if CONFIG_HIGH_PRECISION_MV
+    int_mv orig_mv;
+    int yrow_movedback=0, ycol_movedback=0;
+#endif
     unsigned char *z = (*(b->base_src) + b->src);
     int left, right, up, down, diag;
     unsigned int sse;
@@ -368,6 +457,9 @@
     bestmv->as_mv.row <<= 3;
     bestmv->as_mv.col <<= 3;
     startmv = *bestmv;
+#if CONFIG_HIGH_PRECISION_MV
+    orig_mv = *bestmv;
+#endif
 
     // calculate central point error
     bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
@@ -473,10 +565,20 @@
 
     // time to check quarter pels.
     if (bestmv->as_mv.row < startmv.as_mv.row)
+    {
         y -= y_stride;
+#if CONFIG_HIGH_PRECISION_MV
+        yrow_movedback = 1;
+#endif
+    }
 
     if (bestmv->as_mv.col < startmv.as_mv.col)
+    {
         y--;
+#if CONFIG_HIGH_PRECISION_MV
+        ycol_movedback = 1;
+#endif
+    }
 
     startmv = *bestmv;
 
@@ -488,12 +590,12 @@
     if (startmv.as_mv.col & 7)
     {
         this_mv.as_mv.col = startmv.as_mv.col - 2;
-        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     }
     else
     {
         this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
-        thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+        thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     }
 
     left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
@@ -507,7 +609,7 @@
     }
 
     this_mv.as_mv.col += 4;
-    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
 
     if (right < bestmse)
@@ -524,12 +626,12 @@
     if (startmv.as_mv.row & 7)
     {
         this_mv.as_mv.row = startmv.as_mv.row - 2;
-        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     }
     else
     {
         this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
-        thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
+        thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
     }
 
     up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
@@ -543,7 +645,7 @@
     }
 
     this_mv.as_mv.row += 4;
-    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
 
     if (down < bestmse)
@@ -573,12 +675,12 @@
             if (startmv.as_mv.col & 7)
             {
                 this_mv.as_mv.col -= 2;
-                thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+                thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
             }
             else
             {
                 this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
-                thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);;
+                thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);;
             }
         }
         else
@@ -588,12 +690,12 @@
             if (startmv.as_mv.col & 7)
             {
                 this_mv.as_mv.col -= 2;
-                thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
+                thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
             }
             else
             {
                 this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
-                thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride, &sse);
+                thismse = vfp->svf(y - y_stride - 1, y_stride, SP(6), SP(6), z, b->src_stride, &sse);
             }
         }
 
@@ -604,12 +706,12 @@
         if (startmv.as_mv.row & 7)
         {
             this_mv.as_mv.row -= 2;
-            thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+            thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
         }
         else
         {
             this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
-            thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
+            thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
         }
 
         break;
@@ -619,12 +721,12 @@
         if (startmv.as_mv.col & 7)
         {
             this_mv.as_mv.col -= 2;
-            thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+            thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
         }
         else
         {
             this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
-            thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+            thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
         }
 
         break;
@@ -631,7 +733,7 @@
     case 3:
         this_mv.as_mv.col += 2;
         this_mv.as_mv.row += 2;
-        thismse = vfp->svf(y, y_stride,  this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
+        thismse = vfp->svf(y, y_stride,  SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
         break;
     }
 
@@ -645,9 +747,195 @@
         *sse1 = sse;
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    if (!x->e_mbd.allow_high_precision_mv)
+        return bestmse;
+
+    /* Now do 1/8th pixel */
+    if (bestmv->as_mv.row < orig_mv.as_mv.row && !yrow_movedback)
+    {
+        y -= y_stride;
+        yrow_movedback = 1;
+    }
+
+    if (bestmv->as_mv.col < orig_mv.as_mv.col && !ycol_movedback)
+    {
+        y--;
+        ycol_movedback = 1;
+    }
+
+    startmv = *bestmv;
+
+    // go left then right and check error
+    this_mv.as_mv.row = startmv.as_mv.row;
+
+    if (startmv.as_mv.col & 7)
+    {
+        this_mv.as_mv.col = startmv.as_mv.col - 1;
+        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
+        thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+    }
+
+    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+        *distortion = thismse;
+        *sse1 = sse;
+    }
+
+    this_mv.as_mv.col += 2;
+    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+        *distortion = thismse;
+        *sse1 = sse;
+    }
+
+    // go up then down and check error
+    this_mv.as_mv.col = startmv.as_mv.col;
+
+    if (startmv.as_mv.row & 7)
+    {
+        this_mv.as_mv.row = startmv.as_mv.row - 1;
+        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 7;
+        thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
+    }
+
+    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+        *distortion = thismse;
+        *sse1 = sse;
+    }
+
+    this_mv.as_mv.row += 2;
+    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+        *distortion = thismse;
+        *sse1 = sse;
+    }
+
+
+    // now check 1 more diagonal
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+//  for(whichdir=0;whichdir<4;whichdir++)
+//  {
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+
+        if (startmv.as_mv.row & 7)
+        {
+            this_mv.as_mv.row -= 1;
+
+            if (startmv.as_mv.col & 7)
+            {
+                this_mv.as_mv.col -= 1;
+                thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
+                thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);;
+            }
+        }
+        else
+        {
+            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 7;
+
+            if (startmv.as_mv.col & 7)
+            {
+                this_mv.as_mv.col -= 1;
+                thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
+                thismse = vfp->svf(y - y_stride - 1, y_stride, SP(7), SP(7), z, b->src_stride, &sse);
+            }
+        }
+
+        break;
+    case 1:
+        this_mv.as_mv.col += 1;
+
+        if (startmv.as_mv.row & 7)
+        {
+            this_mv.as_mv.row -= 1;
+            thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 7;
+            thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
+        }
+
+        break;
+    case 2:
+        this_mv.as_mv.row += 1;
+
+        if (startmv.as_mv.col & 7)
+        {
+            this_mv.as_mv.col -= 1;
+            thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
+            thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+        }
+
+        break;
+    case 3:
+        this_mv.as_mv.col += 1;
+        this_mv.as_mv.row += 1;
+        thismse = vfp->svf(y, y_stride,  SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+        break;
+    }
+
+    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+        *distortion = thismse;
+        *sse1 = sse;
+    }
+
+#endif  /* CONFIG_HIGH_PRECISION_MV */
+
     return bestmse;
 }
 
+#undef SP
+
 int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                   int_mv *bestmv, int_mv *ref_mv,
                                   int error_per_bit,
@@ -1945,5 +2233,3 @@
 }
 
 #endif/* END MV ref count ENTROPY_STATS stats code */
-
-
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -1365,6 +1365,9 @@
             (TOKEN_PARTITION) cpi->oxcf.token_partitions;
 
     setup_features(cpi);
+#if CONFIG_HIGH_PRECISION_MV
+    cpi->mb.e_mbd.allow_high_precision_mv = 1;   // Default mv precision adaptation
+#endif
 
     {
         int i;
@@ -2994,6 +2997,9 @@
 
         // Reset the loop filter deltas and segmentation map
         setup_features(cpi);
+#if CONFIG_HIGH_PRECISION_MV
+        xd->allow_high_precision_mv = 1;   // Default mv precision adaptation
+#endif
 
         // If segmentation is enabled force a map update for key frames
         if (xd->segmentation_enabled)
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -530,10 +530,17 @@
 
     if ((mv_row | mv_col) & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
         VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride,
+            (mv_col & 7)<<1, (mv_row & 7)<<1, upred_ptr, uv_stride, &sse2);
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride,
+            (mv_col & 7)<<1, (mv_row & 7)<<1, vpred_ptr, uv_stride, &sse1);
+#else
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride,
             mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
         VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride,
             mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
+#endif
         sse2 += sse1;
     }
     else
@@ -1654,7 +1661,6 @@
                     cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4],
                         bsi->ref_mv, x->errorperbit, v_fn_ptr, x->mvcost,
                         &distortion, &sse);
-
                 }
             } /* NEW4X4 */
 
@@ -1700,9 +1706,11 @@
         segmentyrate += bestlabelyrate;
         this_segment_rd += best_label_rd;
 
-        if (this_segment_rd >= bsi->segment_rd)
+        if (this_segment_rd >= bsi->segment_rd) {
             break;
+        }
 
+
     } /* for each label */
 
     if (this_segment_rd < bsi->segment_rd)
@@ -1776,6 +1784,7 @@
 
         rd_check_segment(cpi, x, &bsi, BLOCK_8X8);
 
+
         if (bsi.segment_rd < best_rd)
         {
             int col_min = (best_ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv->as_mv.col & 7)?1:0);
@@ -2146,9 +2155,9 @@
             if (x->partition_info->bmi[i].mode == NEW4X4)
             {
                 cpi->MVcount[0][mv_max+((x->partition_info->bmi[i].mv.as_mv.row
-                                          - best_ref_mv->as_mv.row) >> 1)]++;
+                                          - best_ref_mv->as_mv.row) >> MV_SHIFT)]++;
                 cpi->MVcount[1][mv_max+((x->partition_info->bmi[i].mv.as_mv.col
-                                          - best_ref_mv->as_mv.col) >> 1)]++;
+                                          - best_ref_mv->as_mv.col) >> MV_SHIFT)]++;
             }
         }
     }
@@ -2155,9 +2164,9 @@
     else if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV)
     {
         cpi->MVcount[0][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.row
-                                          - best_ref_mv->as_mv.row) >> 1)]++;
+                                          - best_ref_mv->as_mv.row) >> MV_SHIFT)]++;
         cpi->MVcount[1][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.col
-                                          - best_ref_mv->as_mv.col) >> 1)]++;
+                                          - best_ref_mv->as_mv.col) >> MV_SHIFT)]++;
     }
 }
 
@@ -2472,6 +2481,7 @@
 
             vp8_update_zbin_extra(cpi, x);
         }
+
 
         if (!x->e_mbd.mode_info_context->mbmi.second_ref_frame)
         switch (this_mode)
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -50,6 +50,7 @@
 {
     int offset;
     unsigned char *yptr, *uptr, *vptr;
+    int omv_row, omv_col;
 
     // Y
     yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3);
@@ -56,8 +57,13 @@
 
     if ((mv_row | mv_col) & 7)
     {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
         x->subpixel_predict16x16(yptr, stride,
-                                    mv_col & 7, mv_row & 7, &pred[0], 16);
+                                 (mv_col & 7)<<1, (mv_row & 7)<<1, &pred[0], 16);
+#else
+        x->subpixel_predict16x16(yptr, stride,
+                                 mv_col & 7, mv_row & 7, &pred[0], 16);
+#endif
     }
     else
     {
@@ -65,6 +71,8 @@
     }
 
     // U & V
+    omv_row = mv_row;
+    omv_col = mv_col;
     mv_row >>= 1;
     mv_col >>= 1;
     stride = (stride + 1) >> 1;
@@ -72,6 +80,15 @@
     uptr = u_mb_ptr + offset;
     vptr = v_mb_ptr + offset;
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    if ((omv_row | omv_col) & 15)
+    {
+        x->subpixel_predict8x8(uptr, stride,
+                            (omv_col & 15), (omv_row & 15), &pred[256], 8);
+        x->subpixel_predict8x8(vptr, stride,
+                            (omv_col & 15), (omv_row & 15), &pred[320], 8);
+    }
+#else
     if ((mv_row | mv_col) & 7)
     {
         x->subpixel_predict8x8(uptr, stride,
@@ -79,6 +96,7 @@
         x->subpixel_predict8x8(vptr, stride,
                             mv_col & 7, mv_row & 7, &pred[320], 8);
     }
+#endif
     else
     {
         RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, stride, &pred[256], 8);
--- a/vp8/encoder/variance_c.c
+++ b/vp8/encoder/variance_c.c
@@ -363,8 +363,13 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 8, 0,
+                                         ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 4, 0,
                                          ref_ptr, recon_stride, sse);
+#endif
 }
 
 
@@ -375,8 +380,13 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 0, 8,
+                                         ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 0, 4,
                                          ref_ptr, recon_stride, sse);
+#endif
 }
 
 
@@ -387,8 +397,13 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 8, 8,
+                                         ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 4, 4,
                                          ref_ptr, recon_stride, sse);
+#endif
 }
 
 
--- a/vp8/encoder/x86/variance_impl_sse2.asm
+++ b/vp8/encoder/x86/variance_impl_sse2.asm
@@ -1348,12 +1348,32 @@
 xmm_bi_rd:
     times 8 dw 64
 align 16
+%if CONFIG_SIXTEENTH_SUBPEL_UV
 vp8_bilinear_filters_sse2:
     dw 128, 128, 128, 128, 128, 128, 128, 128,  0,  0,  0,  0,  0,  0,  0,  0
+    dw 120, 120, 120, 120, 120, 120, 120, 120,  8,  8,  8,  8,  8,  8,  8,  8
     dw 112, 112, 112, 112, 112, 112, 112, 112, 16, 16, 16, 16, 16, 16, 16, 16
+    dw 104, 104, 104, 104, 104, 104, 104, 104, 24, 24, 24, 24, 24, 24, 24, 24
     dw 96, 96, 96, 96, 96, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32
-    dw 80, 80, 80, 80, 80, 80, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48
-    dw 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-    dw 48, 48, 48, 48, 48, 48, 48, 48, 80, 80, 80, 80, 80, 80, 80, 80
-    dw 32, 32, 32, 32, 32, 32, 32, 32, 96, 96, 96, 96, 96, 96, 96, 96
+    dw 88, 88, 88, 88, 88, 88, 88, 88, 40, 40, 40, 40, 40, 40, 40, 40
+    dw 80, 80, 80, 80, 80, 80, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48
+    dw 72, 72, 72, 72, 72, 72, 72, 72, 56, 56, 56, 56, 56, 56, 56, 56
+    dw 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    dw 56, 56, 56, 56, 56, 56, 56, 56, 72, 72, 72, 72, 72, 72, 72, 72
+    dw 48, 48, 48, 48, 48, 48, 48, 48, 80, 80, 80, 80, 80, 80, 80, 80
+    dw 40, 40, 40, 40, 40, 40, 40, 40, 88, 88, 88, 88, 88, 88, 88, 88
+    dw 32, 32, 32, 32, 32, 32, 32, 32, 96, 96, 96, 96, 96, 96, 96, 96
+    dw 24, 24, 24, 24, 24, 24, 24, 24, 104, 104, 104, 104, 104, 104, 104, 104
     dw 16, 16, 16, 16, 16, 16, 16, 16, 112, 112, 112, 112, 112, 112, 112, 112
+    dw 8, 8, 8, 8, 8, 8, 8, 8, 120, 120, 120, 120, 120, 120, 120, 120
+%else
+vp8_bilinear_filters_sse2:
+    dw 128, 128, 128, 128, 128, 128, 128, 128,  0,  0,  0,  0,  0,  0,  0,  0
+    dw 112, 112, 112, 112, 112, 112, 112, 112, 16, 16, 16, 16, 16, 16, 16, 16
+    dw 96, 96, 96, 96, 96, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32
+    dw 80, 80, 80, 80, 80, 80, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48
+    dw 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    dw 48, 48, 48, 48, 48, 48, 48, 48, 80, 80, 80, 80, 80, 80, 80, 80
+    dw 32, 32, 32, 32, 32, 32, 32, 32, 96, 96, 96, 96, 96, 96, 96, 96
+    dw 16, 16, 16, 16, 16, 16, 16, 16, 112, 112, 112, 112, 112, 112, 112, 112
+%endif
--- a/vp8/encoder/x86/variance_impl_ssse3.asm
+++ b/vp8/encoder/x86/variance_impl_ssse3.asm
@@ -353,9 +353,28 @@
 xmm_bi_rd:
     times 8 dw 64
 align 16
+%if CONFIG_SIXTEENTH_SUBPEL_UV
 vp8_bilinear_filters_ssse3:
     times 8 db 128, 0
+    times 8 db 120, 8
     times 8 db 112, 16
+    times 8 db 104, 24
+    times 8 db  96, 32
+    times 8 db  88, 40
+    times 8 db  80, 48
+    times 8 db  72, 56
+    times 8 db  64, 64
+    times 8 db  56, 72
+    times 8 db  48, 80
+    times 8 db  40, 88
+    times 8 db  32, 96
+    times 8 db  24, 104
+    times 8 db  16, 112
+    times 8 db   8, 120
+%else
+vp8_bilinear_filters_ssse3:
+    times 8 db 128, 0
+    times 8 db 112, 16
     times 8 db 96,  32
     times 8 db 80,  48
     times 8 db 64,  64
@@ -362,3 +381,4 @@
     times 8 db 48,  80
     times 8 db 32,  96
     times 8 db 16,  112
+%endif
--- a/vp8/encoder/x86/variance_mmx.c
+++ b/vp8/encoder/x86/variance_mmx.c
@@ -204,6 +204,27 @@
 // the mmx function that does the bilinear filtering and var calculation //
 // int one pass                                                          //
 ///////////////////////////////////////////////////////////////////////////
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[16][8]) =
+{
+    { 128, 128, 128, 128,  0,  0,  0,  0 },
+    { 120, 120, 120, 120,  8,  8,  8,  8 },
+    { 112, 112, 112, 112, 16, 16, 16, 16 },
+    { 104, 104, 104, 104, 24, 24, 24, 24 },
+    {  96, 96, 96, 96, 32, 32, 32, 32 },
+    {  88, 88, 88, 88, 40, 40, 40, 40 },
+    {  80, 80, 80, 80, 48, 48, 48, 48 },
+    {  72, 72, 72, 72, 56, 56, 56, 56 },
+    {  64, 64, 64, 64, 64, 64, 64, 64 },
+    {  56, 56, 56, 56, 72, 72, 72, 72 },
+    {  48, 48, 48, 48, 80, 80, 80, 80 },
+    {  40, 40, 40, 40, 88, 88, 88, 88 },
+    {  32, 32, 32, 32, 96, 96, 96, 96 },
+    {  24, 24, 24, 24, 104, 104, 104, 104 },
+    {  16, 16, 16, 16, 112, 112, 112, 112 },
+    {   8,  8,  8,  8, 120, 120, 120, 120 }
+};
+#else
 DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[8][8]) =
 {
     { 128, 128, 128, 128,  0,  0,  0,  0 },
@@ -215,6 +236,7 @@
     {  32, 32, 32, 32, 96, 96, 96, 96 },
     {  16, 16, 16, 16, 112, 112, 112, 112 }
 };
+#endif
 
 unsigned int vp8_sub_pixel_variance4x4_mmx
 (
@@ -279,7 +301,6 @@
     int xsum0, xsum1;
     unsigned int xxsum0, xxsum1;
 
-
     vp8_filter_block2d_bil_var_mmx(
         src_ptr, src_pixels_per_line,
         dst_ptr, dst_pixels_per_line, 16,
@@ -287,7 +308,6 @@
         &xsum0, &xxsum0
     );
 
-
     vp8_filter_block2d_bil_var_mmx(
         src_ptr + 8, src_pixels_per_line,
         dst_ptr + 8, dst_pixels_per_line, 16,
@@ -386,8 +406,13 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 8, 0,
+                                           ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 4, 0,
                                            ref_ptr, recon_stride, sse);
+#endif
 }
 
 
@@ -398,8 +423,13 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 0, 8,
+                                           ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 0, 4,
                                            ref_ptr, recon_stride, sse);
+#endif
 }
 
 
@@ -410,6 +440,11 @@
     int  recon_stride,
     unsigned int *sse)
 {
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+    return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 8, 8,
+                                           ref_ptr, recon_stride, sse);
+#else
     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 4, 4,
                                            ref_ptr, recon_stride, sse);
+#endif
 }
--- a/vp8/encoder/x86/variance_sse2.c
+++ b/vp8/encoder/x86/variance_sse2.c
@@ -13,6 +13,12 @@
 #include "vp8/common/pragmas.h"
 #include "vpx_ports/mem.h"
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define HALFNDX 8
+#else
+#define HALFNDX 4
+#endif
+
 extern void filter_block1d_h6_mmx(const unsigned char *src_ptr, unsigned short *output_ptr, unsigned int src_pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
 extern void filter_block1d_v6_mmx(const short *src_ptr, unsigned char *output_ptr, unsigned int pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
 extern void filter_block1d8_h6_sse2(const unsigned char *src_ptr, unsigned short *output_ptr, unsigned int src_pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
@@ -135,7 +141,11 @@
     unsigned int *sumsquared
 );
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+DECLARE_ALIGNED(16, extern short, vp8_vp7_bilinear_filters_mmx[16][8]);
+#else
 DECLARE_ALIGNED(16, extern short, vp8_vp7_bilinear_filters_mmx[8][8]);
+#endif
 
 unsigned int vp8_variance4x4_wmt(
     const unsigned char *src_ptr,
@@ -284,7 +294,7 @@
     int xsum;
     unsigned int xxsum;
 
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         vp8_half_horiz_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -291,7 +301,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum, &xxsum);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -298,7 +308,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum, &xxsum);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -335,7 +345,7 @@
 
     // note we could avoid these if statements if the calling function
     // just called the appropriate functions inside.
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         vp8_half_horiz_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -342,7 +352,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -349,7 +359,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -408,7 +418,7 @@
     int xsum0, xsum1;
     unsigned int xxsum0, xxsum1;
 
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         vp8_half_horiz_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -415,7 +425,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -422,7 +432,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -464,7 +474,7 @@
     int xsum;
     unsigned int xxsum;
 
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         vp8_half_horiz_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -471,7 +481,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum, &xxsum);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -478,7 +488,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum, &xxsum);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance8x_h_sse2(
             src_ptr, src_pixels_per_line,
--- a/vp8/encoder/x86/variance_ssse3.c
+++ b/vp8/encoder/x86/variance_ssse3.c
@@ -13,6 +13,12 @@
 #include "vp8/common/pragmas.h"
 #include "vpx_ports/mem.h"
 
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define HALFNDX 8
+#else
+#define HALFNDX 4
+#endif
+
 extern unsigned int vp8_get16x16var_sse2
 (
     const unsigned char *src_ptr,
@@ -81,7 +87,7 @@
 
     // note we could avoid these if statements if the calling function
     // just called the appropriate functions inside.
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -88,7 +94,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -95,7 +101,7 @@
             dst_ptr, dst_pixels_per_line, 16,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -130,7 +136,7 @@
     int xsum0;
     unsigned int xxsum0;
 
-    if (xoffset == 4 && yoffset == 0)
+    if (xoffset == HALFNDX && yoffset == 0)
     {
         vp8_half_horiz_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -137,7 +143,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 0 && yoffset == 4)
+    else if (xoffset == 0 && yoffset == HALFNDX)
     {
         vp8_half_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,
@@ -144,7 +150,7 @@
             dst_ptr, dst_pixels_per_line, 8,
             &xsum0, &xxsum0);
     }
-    else if (xoffset == 4 && yoffset == 4)
+    else if (xoffset == HALFNDX && yoffset == HALFNDX)
     {
         vp8_half_horiz_vert_variance16x_h_sse2(
             src_ptr, src_pixels_per_line,