[CFL] Store size changed to use TX_SIZE

To facilitate an upcoming work on constant propagation in luma
subsampling, CfL now store and subsamples values using the luma
transform size. There's no behavior change to CfL. Before it expected
the width and height of the chroma transform size, now it expects the
luma transform size.

Change-Id: Iaff7f4a94ba0e8a78539a917adeb70051a514795
diff --git a/av1/common/cfl.c b/av1/common/cfl.c
index c99cf64..3ecfda2 100644
--- a/av1/common/cfl.c
+++ b/av1/common/cfl.c
@@ -257,12 +257,11 @@
 static void cfl_luma_subsampling_420_lbd_c(const uint8_t *input,
                                            int input_stride, int16_t *output_q3,
                                            int width, int height) {
-  for (int j = 0; j < height; j++) {
-    for (int i = 0; i < width; i++) {
-      int top = i << 1;
-      int bot = top + input_stride;
-      output_q3[i] = (input[top] + input[top + 1] + input[bot] + input[bot + 1])
-                     << 1;
+  for (int j = 0; j < height; j += 2) {
+    for (int i = 0; i < width; i += 2) {
+      const int bot = i + input_stride;
+      output_q3[i >> 1] =
+          (input[i] + input[i + 1] + input[bot] + input[bot + 1]) << 1;
     }
     input += input_stride << 1;
     output_q3 += CFL_BUF_LINE;
@@ -273,9 +272,8 @@
                                     int16_t *output_q3, int width, int height) {
   assert((height - 1) * CFL_BUF_LINE + width <= CFL_BUF_SQUARE);
   for (int j = 0; j < height; j++) {
-    for (int i = 0; i < width; i++) {
-      int left = i << 1;
-      output_q3[i] = (input[left] + input[left + 1]) << 2;
+    for (int i = 0; i < width; i += 2) {
+      output_q3[i >> 1] = (input[i] + input[i + 1]) << 2;
     }
     input += input_stride;
     output_q3 += CFL_BUF_LINE;
@@ -296,12 +294,11 @@
 
 void cfl_luma_subsampling_420_hbd_c(const uint16_t *input, int input_stride,
                                     int16_t *output_q3, int width, int height) {
-  for (int j = 0; j < height; j++) {
-    for (int i = 0; i < width; i++) {
-      int top = i << 1;
-      int bot = top + input_stride;
-      output_q3[i] = (input[top] + input[top + 1] + input[bot] + input[bot + 1])
-                     << 1;
+  for (int j = 0; j < height; j += 2) {
+    for (int i = 0; i < width; i += 2) {
+      const int bot = i + input_stride;
+      output_q3[i >> 1] =
+          (input[i] + input[i + 1] + input[bot] + input[bot + 1]) << 1;
     }
     input += input_stride << 1;
     output_q3 += CFL_BUF_LINE;
@@ -312,9 +309,8 @@
                                     int16_t *output_q3, int width, int height) {
   assert((height - 1) * CFL_BUF_LINE + width <= CFL_BUF_SQUARE);
   for (int j = 0; j < height; j++) {
-    for (int i = 0; i < width; i++) {
-      int left = i << 1;
-      output_q3[i] = (input[left] + input[left + 1]) << 2;
+    for (int i = 0; i < width; i += 2) {
+      output_q3[i >> 1] = (input[i] + input[i + 1]) << 2;
     }
     input += input_stride;
     output_q3 += CFL_BUF_LINE;
@@ -336,7 +332,9 @@
 CFL_GET_SUBSAMPLE_FUNCTION(c)
 
 static void cfl_store(CFL_CTX *cfl, const uint8_t *input, int input_stride,
-                      int row, int col, int width, int height, int use_hbd) {
+                      int row, int col, TX_SIZE tx_size, int use_hbd) {
+  const int width = tx_size_wide[tx_size];
+  const int height = tx_size_high[tx_size];
   const int tx_off_log2 = tx_size_wide_log2[0];
   const int sub_x = cfl->subsampling_x;
   const int sub_y = cfl->subsampling_y;
@@ -370,11 +368,11 @@
   if (use_hbd) {
     const uint16_t *input_16 = CONVERT_TO_SHORTPTR(input);
     get_subsample_hbd_fn(sub_x, sub_y)(input_16, input_stride, pred_buf_q3,
-                                       store_width, store_height);
+                                       width, height);
     return;
   }
-  get_subsample_lbd_fn(sub_x, sub_y)(input, input_stride, pred_buf_q3,
-                                     store_width, store_height);
+  get_subsample_lbd_fn(sub_x, sub_y)(input, input_stride, pred_buf_q3, width,
+                                     height);
 }
 
 // Adjust the row and column of blocks smaller than 8X8, as chroma-referenced
@@ -469,8 +467,8 @@
     sub8x8_set_val(cfl, row, col, tx_size);
 #endif  // CONFIG_DEBUG && !CONFIG_RECT_TX_EXT_INTRA
   }
-  cfl_store(cfl, dst, pd->dst.stride, row, col, tx_size_wide[tx_size],
-            tx_size_high[tx_size], get_bitdepth_data_path_index(xd));
+  cfl_store(cfl, dst, pd->dst.stride, row, col, tx_size,
+            get_bitdepth_data_path_index(xd));
 }
 
 void cfl_store_block(MACROBLOCKD *const xd, BLOCK_SIZE bsize, TX_SIZE tx_size) {
@@ -493,6 +491,7 @@
   }
   const int width = max_intra_block_width(xd, bsize, AOM_PLANE_Y, tx_size);
   const int height = max_intra_block_height(xd, bsize, AOM_PLANE_Y, tx_size);
-  cfl_store(cfl, pd->dst.buf, pd->dst.stride, row, col, width, height,
+  tx_size = get_tx_size(width, height);
+  cfl_store(cfl, pd->dst.buf, pd->dst.stride, row, col, tx_size,
             get_bitdepth_data_path_index(xd));
 }
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 12ff735..59ac69b 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -1284,6 +1284,45 @@
   }
 }
 
+static INLINE TX_SIZE get_tx_size(int width, int height) {
+  if (width == height) {
+    return get_sqr_tx_size(width);
+  }
+  if (width < height) {
+    if (width + width == height) {
+      switch (width) {
+        case 4: return TX_4X8; break;
+        case 8: return TX_8X16; break;
+        case 16: return TX_16X32; break;
+        case 32: return TX_32X64; break;
+      }
+    } else {
+      switch (width) {
+        case 4: return TX_4X16; break;
+        case 8: return TX_8X32; break;
+        case 16: return TX_16X64; break;
+      }
+    }
+  } else {
+    if (height + height == width) {
+      switch (height) {
+        case 4: return TX_8X4; break;
+        case 8: return TX_16X8; break;
+        case 16: return TX_32X16; break;
+        case 32: return TX_64X32; break;
+      }
+    } else {
+      switch (height) {
+        case 4: return TX_16X4; break;
+        case 8: return TX_32X8; break;
+        case 16: return TX_64X16; break;
+      }
+    }
+  }
+  assert(0);
+  return TX_4X4;
+}
+
 static INLINE int txfm_partition_context(TXFM_CONTEXT *above_ctx,
                                          TXFM_CONTEXT *left_ctx,
                                          BLOCK_SIZE bsize, TX_SIZE tx_size) {
diff --git a/av1/common/x86/cfl_avx2.c b/av1/common/x86/cfl_avx2.c
index 167a96e..730bffd 100644
--- a/av1/common/x86/cfl_avx2.c
+++ b/av1/common/x86/cfl_avx2.c
@@ -34,7 +34,7 @@
 
   const __m256i twos = _mm256_set1_epi8(2);  // Thirty two twos
   const int luma_stride = input_stride << 1;
-  const int16_t *end = pred_buf_q3 + height * CFL_BUF_LINE;
+  const int16_t *end = pred_buf_q3 + (height >> 1) * CFL_BUF_LINE;
   do {
     // Load 32 values for the top and bottom rows.
     // t_0, t_1, ... t_31
diff --git a/av1/common/x86/cfl_ssse3.c b/av1/common/x86/cfl_ssse3.c
index 6f18f57..913131d 100644
--- a/av1/common/x86/cfl_ssse3.c
+++ b/av1/common/x86/cfl_ssse3.c
@@ -36,18 +36,18 @@
   // Sixteen int8 values fit in one __m128i register. If this is enough to do
   // the entire row, the next value is two rows down, otherwise we move to the
   // next sixteen values.
-  const int next = (width == 16) ? 16 : input_stride << 1;
+  const int next = (width == 32) ? 16 : input_stride << 1;
 
   // Values in the prediction buffer are subsampled, so we only need to move
   // down one row or forward by eight values.
-  const int next_chroma = (width == 16) ? 8 : CFL_BUF_LINE;
+  const int next_chroma = (width == 32) ? 8 : CFL_BUF_LINE;
 
   // When the width is less than 16, we double the stride, because we process
   // four lines by iteration (instead of two).
-  const int luma_stride = input_stride << (1 + (width < 16));
-  const int chroma_stride = CFL_BUF_LINE << (width < 16);
+  const int luma_stride = input_stride << (1 + (width < 32));
+  const int chroma_stride = CFL_BUF_LINE << (width < 32);
 
-  const int16_t *end = pred_buf_q3 + height * CFL_BUF_LINE;
+  const int16_t *end = pred_buf_q3 + (height >> 1) * CFL_BUF_LINE;
   do {
     // Load 16 values for the top and bottom rows.
     // t_0, t_1, ... t_15
diff --git a/test/cfl_test.cc b/test/cfl_test.cc
index d23c1b1..42e21e3 100644
--- a/test/cfl_test.cc
+++ b/test/cfl_test.cc
@@ -22,19 +22,6 @@
 #define NUM_ITERATIONS (100)
 #define NUM_ITERATIONS_SPEED (INT16_MAX)
 
-#define ALL_CFL_SIZES(function)                                     \
-  make_tuple(4, 4, &function), make_tuple(8, 4, &function),         \
-      make_tuple(4, 8, &function), make_tuple(8, 8, &function),     \
-      make_tuple(16, 8, &function), make_tuple(8, 16, &function),   \
-      make_tuple(16, 16, &function), make_tuple(32, 16, &function), \
-      make_tuple(16, 32, &function), make_tuple(32, 32, &function)
-
-#define CHROMA_420_CFL_SIZES(function)                            \
-  make_tuple(4, 4, &function), make_tuple(8, 4, &function),       \
-      make_tuple(4, 8, &function), make_tuple(8, 8, &function),   \
-      make_tuple(16, 8, &function), make_tuple(8, 16, &function), \
-      make_tuple(16, 16, &function)
-
 #define ALL_CFL_TX_SIZES(function)                                     \
   make_tuple(TX_4X4, &function), make_tuple(TX_4X8, &function),        \
       make_tuple(TX_4X16, &function), make_tuple(TX_8X4, &function),   \
@@ -45,7 +32,7 @@
       make_tuple(TX_32X16, &function), make_tuple(TX_32X32, &function)
 
 namespace {
-typedef cfl_subsample_lbd_fn (*get_subsample_fn)(int width, int height);
+typedef cfl_subsample_lbd_fn (*get_subsample_fn)(int sub_x, int sub_y);
 
 typedef cfl_predict_lbd_fn (*get_predict_fn)(TX_SIZE tx_size);
 
@@ -53,7 +40,7 @@
 
 typedef cfl_subtract_average_fn (*sub_avg_fn)(TX_SIZE tx_size);
 
-typedef std::tr1::tuple<int, int, get_subsample_fn> subsample_param;
+typedef std::tr1::tuple<TX_SIZE, get_subsample_fn> subsample_param;
 
 typedef std::tr1::tuple<TX_SIZE, get_predict_fn> predict_param;
 
@@ -107,11 +94,12 @@
 class CFLSubsampleTest : public ::testing::TestWithParam<subsample_param> {
  public:
   virtual ~CFLSubsampleTest() {}
-  virtual void SetUp() { subsample = GET_PARAM(2); }
+  virtual void SetUp() { subsample = GET_PARAM(1); }
 
  protected:
-  int Width() const { return GET_PARAM(0); }
-  int Height() const { return GET_PARAM(1); }
+  int Width() const { return tx_size_wide[GET_PARAM(0)]; }
+  int Height() const { return tx_size_high[GET_PARAM(0)]; }
+  TX_SIZE Tx_size() const { return GET_PARAM(0); }
   get_subsample_fn subsample;
   uint8_t luma_pels[CFL_BUF_SQUARE];
   uint8_t luma_pels_ref[CFL_BUF_SQUARE];
@@ -119,8 +107,8 @@
   int16_t sub_luma_pels_ref[CFL_BUF_SQUARE];
   void init(int width, int height) {
     ACMRandom rnd(ACMRandom::DeterministicSeed());
-    for (int j = 0; j < height * 2; j++) {
-      for (int i = 0; i < width * 2; i++) {
+    for (int j = 0; j < height; j++) {
+      for (int i = 0; i < width; i++) {
         const int val = rnd.Rand8();
         luma_pels[j * CFL_BUF_LINE + i] = val;
         luma_pels_ref[j * CFL_BUF_LINE + i] = val;
@@ -283,14 +271,16 @@
 TEST_P(CFLSubsampleTest, SubsampleTest) {
   const int width = Width();
   const int height = Height();
+  const int sub_width = width >> 1;
+  const int sub_height = height >> 1;
 
   for (int it = 0; it < NUM_ITERATIONS; it++) {
     init(width, height);
     subsample(1, 1)(luma_pels, CFL_BUF_LINE, sub_luma_pels, width, height);
     get_subsample_lbd_fn_c(1, 1)(luma_pels_ref, CFL_BUF_LINE, sub_luma_pels_ref,
                                  width, height);
-    for (int j = 0; j < height; j++) {
-      for (int i = 0; i < width; i++) {
+    for (int j = 0; j < sub_height; j++) {
+      for (int i = 0; i < sub_width; i++) {
         ASSERT_EQ(sub_luma_pels_ref[j * CFL_BUF_LINE + i],
                   sub_luma_pels[j * CFL_BUF_LINE + i]);
       }
@@ -440,7 +430,7 @@
 
 #if HAVE_SSSE3
 
-const subsample_param subsample_sizes_ssse3[] = { CHROMA_420_CFL_SIZES(
+const subsample_param subsample_sizes_ssse3[] = { ALL_CFL_TX_SIZES(
     get_subsample_lbd_fn_ssse3) };
 
 const predict_param predict_sizes_ssse3[] = { ALL_CFL_TX_SIZES(
@@ -463,7 +453,7 @@
 const sub_avg_param sub_avg_sizes_avx2[] = { ALL_CFL_TX_SIZES(
     get_subtract_average_fn_avx2) };
 
-const subsample_param subsample_sizes_avx2[] = { CHROMA_420_CFL_SIZES(
+const subsample_param subsample_sizes_avx2[] = { ALL_CFL_TX_SIZES(
     get_subsample_lbd_fn_avx2) };
 
 const predict_param predict_sizes_avx2[] = { ALL_CFL_TX_SIZES(
diff --git a/test/onyxc_int_test.cc b/test/onyxc_int_test.cc
new file mode 100644
index 0000000..3889595
--- /dev/null
+++ b/test/onyxc_int_test.cc
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
+
+#include "av1/common/onyxc_int.h"
+
+TEST(OnyxcInt, TestGetTxSize) {
+  for (int t = TX_4X4; t < TX_SIZES_ALL; t++) {
+    TX_SIZE t2 = get_tx_size(tx_size_wide[t], tx_size_high[t]);
+    GTEST_ASSERT_EQ(tx_size_wide[t], tx_size_wide[t2]);
+    GTEST_ASSERT_EQ(tx_size_high[t], tx_size_high[t2]);
+  }
+}
diff --git a/test/test.cmake b/test/test.cmake
index f49e141..c62b21b 100644
--- a/test/test.cmake
+++ b/test/test.cmake
@@ -133,6 +133,7 @@
         "${AOM_ROOT}/test/intrapred_test.cc"
         "${AOM_ROOT}/test/lpf_test.cc"
         "${AOM_ROOT}/test/scan_test.cc"
+        "${AOM_ROOT}/test/onyxc_int_test.cc"
         "${AOM_ROOT}/test/simd_cmp_impl.h")
 
     set(AOM_UNIT_TEST_ENCODER_SOURCES