From 18e90d744eba2d28ad96a566565bbf5642d24b59 Mon Sep 17 00:00:00 2001 From: Deb Mukherjee Date: Thu, 16 Feb 2012 09:29:54 -0800 Subject: 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 --- configure | 2 + vp8/common/blockd.h | 7 +- vp8/common/entropymode.c | 27 +- vp8/common/entropymode.h | 4 + vp8/common/entropymv.c | 39 +- vp8/common/entropymv.h | 22 +- vp8/common/filter.c | 995 +++++++++++++++++++++++++++----- vp8/common/filter.h | 14 +- vp8/common/reconinter.c | 59 +- vp8/common/x86/subpixel_ssse3.asm | 20 + vp8/common/x86/vp8_asm_stubs.c | 41 +- vp8/common/x86/x86_systemdependent.c | 8 +- vp8/decoder/decodemv.c | 25 +- vp8/decoder/decodframe.c | 7 +- vp8/encoder/arm/variance_arm.c | 18 +- vp8/encoder/bitstream.c | 5 + vp8/encoder/encodemv.c | 53 +- vp8/encoder/mcomp.c | 368 ++++++++++-- vp8/encoder/onyx_if.c | 6 + vp8/encoder/rdopt.c | 22 +- vp8/encoder/temporal_filter.c | 20 +- vp8/encoder/variance_c.c | 15 + vp8/encoder/x86/variance_impl_sse2.asm | 20 + vp8/encoder/x86/variance_impl_ssse3.asm | 20 + vp8/encoder/x86/variance_mmx.c | 39 +- vp8/encoder/x86/variance_sse2.c | 34 +- vp8/encoder/x86/variance_ssse3.c | 18 +- 27 files changed, 1631 insertions(+), 277 deletions(-) diff --git a/configure b/configure index 4646526c0..e865f8660 100755 --- a/configure +++ b/configure @@ -226,6 +226,8 @@ EXPERIMENT_LIST=" enhanced_interp superblocks featureupdates + high_precision_mv + sixteenth_subpel_uv " CONFIG_LIST=" external_build diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index 16bfc4c99..934c740b2 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -290,8 +290,8 @@ typedef struct MacroBlockD /* 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 @@ typedef struct MacroBlockD 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; diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index cdc510acf..540da33ed 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -225,6 +225,28 @@ struct vp8_token_struct vp8_mbsplit_encodings [VP8_NUMMBSPLITS]; 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] = { @@ -236,9 +258,11 @@ const vp8_tree_index vp8_small_mvtree [14] = -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 @@ void print_mv_ref_cts(VP8_COMMON *pc) printf("\n"); } } - diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h index 1c6d23560..31170677c 100644 --- a/vp8/common/entropymode.h +++ b/vp8/common/entropymode.h @@ -57,7 +57,11 @@ extern struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS]; 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); diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c index e5df1f095..1e0690a58 100644 --- a/vp8/common/entropymv.c +++ b/vp8/common/entropymv.c @@ -11,6 +11,40 @@ #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] = { {{ @@ -35,15 +69,12 @@ const MV_CONTEXT vp8_default_mv_context[2] = 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 */ 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 */ diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h index 2db1e385b..390c4f4a2 100644 --- 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 */ diff --git a/vp8/common/filter.c b/vp8/common/filter.c index 62f8b79d7..bcc35095e 100644 --- a/vp8/common/filter.c +++ b/vp8/common/filter.c @@ -13,8 +13,28 @@ #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 }, @@ -23,11 +43,12 @@ DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[8][2]) = { 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 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[8][2*INTERP_EXTEND]) = * % 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}, + {-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}, - {-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 */ + { 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 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[8][2*INTERP_EXTEND]) = #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 @@ static void filter_block2d ) { 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 @@ void vp8_sixtap_predict_c 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 @@ void vp8_sixtap_predict8x8_c 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 @@ void vp8_sixtap_predict_avg8x8_c 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 @@ void vp8_sixtap_predict8x4_c 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 @@ void vp8_sixtap_predict16x16_c 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 @@ void vp8_sixtap_predict_avg16x16_c 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 */ diff --git a/vp8/common/filter.h b/vp8/common/filter.h index 6c54285df..81ad5257a 100644 --- 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 diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c index 42502ad67..bd08e7f2c 100644 --- a/vp8/common/reconinter.c +++ b/vp8/common/reconinter.c @@ -180,7 +180,11 @@ void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf) 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 @@ static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch) 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 @@ static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch) 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 @@ void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x) 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 @@ void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x) 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 @@ void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x) 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 @@ void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, unsigned char *ptr; unsigned char *uptr, *vptr; + int_mv _o16x16mv; int_mv _16x16mv; unsigned char *ptr_base = x->pre.y_buffer; @@ -434,13 +461,18 @@ void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, 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 { 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 @@ void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, 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 @@ void vp8_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *x, 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 @@ void vp8_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *x, 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 @@ void vp8_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *x, } /* 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 @@ void vp8_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *x, 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); diff --git a/vp8/common/x86/subpixel_ssse3.asm b/vp8/common/x86/subpixel_ssse3.asm index 6bca82bfb..39f4f7b88 100644 --- a/vp8/common/x86/subpixel_ssse3.asm +++ b/vp8/common/x86/subpixel_ssse3.asm @@ -1495,13 +1495,33 @@ k2_k4: 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 diff --git a/vp8/common/x86/vp8_asm_stubs.c b/vp8/common/x86/vp8_asm_stubs.c index 790400609..458b3f638 100644 --- a/vp8/common/x86/vp8_asm_stubs.c +++ b/vp8/common/x86/vp8_asm_stubs.c @@ -13,8 +13,15 @@ #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 ( @@ -128,6 +135,9 @@ void vp8_sixtap_predict4x4_mmx 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 @@ void vp8_sixtap_predict16x16_mmx ) { +#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 @@ void vp8_sixtap_predict8x8_mmx ) { +#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 @@ void vp8_sixtap_predict8x4_mmx 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 @@ void vp8_sixtap_predict16x16_sse2 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 @@ void vp8_sixtap_predict8x8_sse2 { 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 @@ void vp8_sixtap_predict8x4_sse2 { 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 @@ void vp8_sixtap_predict16x16_ssse3 ) { 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 @@ void vp8_sixtap_predict8x8_ssse3 ) { DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 256); +#ifdef ANNOUNCE_FUNCTION + printf("vp8_sixtap_predict8x8_ssse3\n"); +#endif if (xoffset) { @@ -498,6 +531,9 @@ void vp8_sixtap_predict8x4_ssse3 ) { DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 256); +#ifdef ANNOUNCE_FUNCTION + printf("vp8_sixtap_predict8x4_ssse3\n"); +#endif if (xoffset) { @@ -530,6 +566,9 @@ void vp8_sixtap_predict4x4_ssse3 ) { DECLARE_ALIGNED_ARRAY(16, unsigned char, FData2, 4*9); +#ifdef ANNOUNCE_FUNCTION + printf("vp8_sixtap_predict4x4_ssse3\n"); +#endif if (xoffset) { diff --git a/vp8/common/x86/x86_systemdependent.c b/vp8/common/x86/x86_systemdependent.c index 33a984b79..53009502c 100644 --- a/vp8/common/x86/x86_systemdependent.c +++ b/vp8/common/x86/x86_systemdependent.c @@ -43,17 +43,17 @@ void vp8_arch_x86_common_init(VP8_COMMON *ctx) 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 @@ void vp8_arch_x86_common_init(VP8_COMMON *ctx) 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,12 +122,14 @@ void vp8_arch_x86_common_init(VP8_COMMON *ctx) 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; 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; diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 4d64ec366..d77340b0b 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -21,6 +21,12 @@ #if CONFIG_DEBUG #include #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 @@ static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc) { 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 @@ static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc) { 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<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; iprob[i]); printf("\n"); + for (i=0; iprob[i]); printf("\n"); +#endif } @@ -985,4 +997,3 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) } #endif /* CONFIG_SUPERBLOCKS */ - diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 010204358..52ea3bc88 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -1029,6 +1029,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) /* 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 @@ int vp8_decode_frame(VP8D_COMP *pbi) 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 @@ int vp8_decode_frame(VP8D_COMP *pbi) return 0; } - diff --git a/vp8/encoder/arm/variance_arm.c b/vp8/encoder/arm/variance_arm.c index e77be9f73..6e83c6e7b 100644 --- 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 @@ unsigned int vp8_sub_pixel_variance16x16_armv6 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 vp8_sub_pixel_variance16x16_neon 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); diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index c2613bfbd..72bc3d41d 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -2945,6 +2945,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) // 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) diff --git a/vp8/encoder/encodemv.c b/vp8/encoder/encodemv.c index a4849c654..4d5d8cb81 100644 --- 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 @@ static void encode_mvcomponent( 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,17 +50,17 @@ static void encode_mvcomponent( 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 */ 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, p [MVPbits + mvnum_short_bits]); } vp8_write(w, v < 0, p [MVPsign]); @@ -91,9 +95,17 @@ void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc } } #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; iprob[i]); printf("\n"); + for (i=0; iprob[i]); printf("\n"); + fflush(stdout); + } +#endif } @@ -106,7 +118,7 @@ static unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc) 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,17 +131,17 @@ static unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc) 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 */ 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); } return cost; // + vp8_cost_bit( p [MVPsign], v < 0); @@ -258,7 +270,7 @@ static void write_component_probs( { 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 @@ static void write_component_probs( 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 @@ void vp8_write_mvprobs(VP8_COMP *cpi) 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; ias_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 @@ void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) * 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 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, { 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 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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,26 +286,26 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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); 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,28 +319,29 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // 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); 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 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, #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 vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, } 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, } 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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,19 +721,19 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, 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; 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 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, *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 @@ void accum_mv_refs(MB_PREDICTION_MODE m, const int ct[4]) } #endif/* END MV ref count ENTROPY_STATS stats code */ - - diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 8a2fb8448..2b4418a0a 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -1365,6 +1365,9 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) (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 @@ static void encode_frame_to_data_rate // 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) diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 4f97e3c63..1491e645b 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -530,10 +530,17 @@ int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd) 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 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, 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,8 +1706,10 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, 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 */ @@ -1776,6 +1784,7 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, 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,18 +2155,18 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv) 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)]++; } } } 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)]++; } } @@ -2473,6 +2482,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int vp8_update_zbin_extra(cpi, x); } + if (!x->e_mbd.mode_info_context->mbmi.second_ref_frame) switch (this_mode) { diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c index 8455bb877..ede65d669 100644 --- a/vp8/encoder/temporal_filter.c +++ b/vp8/encoder/temporal_filter.c @@ -50,14 +50,20 @@ static void vp8_temporal_filter_predictors_mb_c { int offset; unsigned char *yptr, *uptr, *vptr; + int omv_row, omv_col; // Y yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3); 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 @@ static void vp8_temporal_filter_predictors_mb_c } // U & V + omv_row = mv_row; + omv_col = mv_col; mv_row >>= 1; mv_col >>= 1; stride = (stride + 1) >> 1; @@ -72,6 +80,15 @@ static void vp8_temporal_filter_predictors_mb_c 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 @@ static void vp8_temporal_filter_predictors_mb_c 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); diff --git a/vp8/encoder/variance_c.c b/vp8/encoder/variance_c.c index c7b9c2209..402ff0450 100644 --- a/vp8/encoder/variance_c.c +++ b/vp8/encoder/variance_c.c @@ -363,8 +363,13 @@ unsigned int vp8_variance_halfpixvar16x16_h_c( 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 @@ unsigned int vp8_variance_halfpixvar16x16_v_c( 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 @@ unsigned int vp8_variance_halfpixvar16x16_hv_c( 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 } diff --git a/vp8/encoder/x86/variance_impl_sse2.asm b/vp8/encoder/x86/variance_impl_sse2.asm index 762922091..b13beee6e 100644 --- a/vp8/encoder/x86/variance_impl_sse2.asm +++ b/vp8/encoder/x86/variance_impl_sse2.asm @@ -1348,12 +1348,32 @@ align 16 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 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 diff --git a/vp8/encoder/x86/variance_impl_ssse3.asm b/vp8/encoder/x86/variance_impl_ssse3.asm index 97e8b0e2e..d60d53daa 100644 --- a/vp8/encoder/x86/variance_impl_ssse3.asm +++ b/vp8/encoder/x86/variance_impl_ssse3.asm @@ -353,6 +353,25 @@ align 16 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 @@ -362,3 +381,4 @@ vp8_bilinear_filters_ssse3: times 8 db 48, 80 times 8 db 32, 96 times 8 db 16, 112 +%endif diff --git a/vp8/encoder/x86/variance_mmx.c b/vp8/encoder/x86/variance_mmx.c index 92b695f17..b84d00034 100644 --- a/vp8/encoder/x86/variance_mmx.c +++ b/vp8/encoder/x86/variance_mmx.c @@ -204,6 +204,27 @@ unsigned int vp8_variance8x16_mmx( // 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 @@ DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[8][8]) = { 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 @@ unsigned int vp8_sub_pixel_variance16x16_mmx 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 @@ unsigned int vp8_sub_pixel_variance16x16_mmx &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 @@ unsigned int vp8_variance_halfpixvar16x16_h_mmx( 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 @@ unsigned int vp8_variance_halfpixvar16x16_v_mmx( 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 @@ unsigned int vp8_variance_halfpixvar16x16_hv_mmx( 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 } diff --git a/vp8/encoder/x86/variance_sse2.c b/vp8/encoder/x86/variance_sse2.c index 24062eb9b..e3c6268ea 100644 --- 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 @@ void vp8_half_vert_variance16x_h_sse2 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,21 +294,21 @@ unsigned int vp8_sub_pixel_variance8x8_wmt 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, 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, 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,21 +345,21 @@ unsigned int vp8_sub_pixel_variance16x16_wmt // 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, 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, 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,21 +418,21 @@ unsigned int vp8_sub_pixel_variance16x8_wmt 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, 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, 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,21 +474,21 @@ unsigned int vp8_sub_pixel_variance8x16_wmt 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, 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, 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, diff --git a/vp8/encoder/x86/variance_ssse3.c b/vp8/encoder/x86/variance_ssse3.c index 73f2e01a2..59e14971a 100644 --- 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,21 +87,21 @@ unsigned int vp8_sub_pixel_variance16x16_ssse3 // 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, 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, 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,21 +136,21 @@ unsigned int vp8_sub_pixel_variance16x8_ssse3 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, 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, 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, -- cgit v1.2.3