[CFL] Alpha signaling

Writes and reads alpha to and from the bitstream.

A special case is needed on the encoder side to handle prediction block
skips. Since whether or not a prediction block is skipped during CfL, a
rollback is required if the block was skipped and the alpha index was
not zero. The advantage of this is that no signaling is required when
the prediction block is skipped as it is assumed tha the alpha index is
zero.

A encode facade is added to the intra prediction facade as CfL requires
special encoder side operations.

Change-Id: Ic3b11d0fdbd51389d862112eb09d8785127a6b06
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 3adc235..075e52d 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -207,6 +207,37 @@
   return uv_mode;
 }
 
+#if CONFIG_CFL
+static int read_cfl_alphas(
+#if CONFIG_EC_ADAPT
+    MACROBLOCKD *xd,
+#elif CONFIG_EC_MULTISYMBOL
+    AV1_COMMON *cm,
+#endif
+    aom_reader *r, CFL_SIGN_TYPE signs[CFL_PRED_PLANES]) {
+
+#if CONFIG_EC_ADAPT
+  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
+#elif CONFIG_EC_MULTISYMBOL
+  FRAME_CONTEXT *ec_ctx = cm->fc;
+#endif
+
+  const int ind =
+      aom_read_symbol(r, ec_ctx->cfl_alpha_cdf, CFL_ALPHABET_SIZE, "cfl:alpha");
+  // Signs are only coded for nonzero values
+  // sign == 0 implies negative alpha
+  // sign == 1 implies positive alpha
+  signs[CFL_PRED_U] = (cfl_alpha_codes[ind][CFL_PRED_U] != 0.0)
+                          ? aom_read_bit(r, "cfl:sign")
+                          : CFL_SIGN_POS;
+  signs[CFL_PRED_V] = (cfl_alpha_codes[ind][CFL_PRED_V] != 0.0)
+                          ? aom_read_bit(r, "cfl:sign")
+                          : CFL_SIGN_POS;
+
+  return ind;
+}
+#endif
+
 #if CONFIG_EXT_INTER
 static INTERINTRA_MODE read_interintra_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                             aom_reader *r, int size_group) {
@@ -1096,6 +1127,25 @@
   mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
 #endif
 
+#if CONFIG_CFL
+  // TODO(ltrudeau) support PALETTE
+  if (mbmi->uv_mode == DC_PRED) {
+    if (mbmi->skip) {
+      mbmi->cfl_alpha_ind = 0;
+      mbmi->cfl_alpha_signs[CFL_PRED_U] = CFL_SIGN_POS;
+      mbmi->cfl_alpha_signs[CFL_PRED_V] = CFL_SIGN_POS;
+    } else {
+      mbmi->cfl_alpha_ind = read_cfl_alphas(
+#if CONFIG_EC_ADAPT
+          xd,
+#elif CONFIG_EC_MULTISYMBOL
+          cm,
+#endif
+          r, mbmi->cfl_alpha_signs);
+    }
+  }
+#endif
+
 #if CONFIG_EXT_INTRA
   read_intra_angle_info(cm, xd, r);
 #endif  // CONFIG_EXT_INTRA