#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <vector>

#include "src/buffer_pool.h"
#include "src/dsp/constants.h"
#include "src/motion_vector.h"
#include "src/obu_parser.h"
#include "src/prediction_mask.h"
#include "src/symbol_decoder_context.h"
#include "src/tile.h"
#include "src/utils/array_2d.h"
#include "src/utils/bit_mask_set.h"
#include "src/utils/block_parameters_holder.h"
#include "src/utils/common.h"
#include "src/utils/constants.h"
#include "src/utils/entropy_decoder.h"
#include "src/utils/logging.h"
#include "src/utils/segmentation.h"
#include "src/utils/segmentation_map.h"
#include "src/utils/types.h"

namespace libgav1 {
namespace {

constexpr int kDeltaQSmall = 3;
constexpr int kDeltaLfSmall = 3;
constexpr int kNoScale = 1 << kReferenceFrameScalePrecision;

constexpr uint8_t kIntraYModeContext[kIntraPredictionModesY] = {
    0, 1, 2, 3, 4, 4, 4, 4, 3, 0, 1, 2, 0};

constexpr uint8_t kSizeGroup[kMaxBlockSizes] = {
    0, 0, 0, 0, 1, 1, 1, 0, 1, 2, 2, 2, 1, 2, 3, 3, 2, 3, 3, 3, 3, 3};

constexpr int kCompoundModeNewMvContexts = 5;
constexpr uint8_t kCompoundModeContextMap[3][kCompoundModeNewMvContexts] = {
    {0, 1, 1, 1, 1}, {1, 2, 3, 4, 4}, {4, 4, 5, 6, 7}};

enum CflSign : uint8_t {
  kCflSignZero = 0,
  kCflSignNegative = 1,
  kCflSignPositive = 2
};

constexpr BitMaskSet kPredictionModeHasNearMvMask(kPredictionModeNearMv,
                                                  kPredictionModeNearNearMv,
                                                  kPredictionModeNearNewMv,
                                                  kPredictionModeNewNearMv);

constexpr BitMaskSet kIsInterIntraModeAllowedMask(kBlock8x8, kBlock8x16,
                                                  kBlock16x8, kBlock16x16,
                                                  kBlock16x32, kBlock32x16,
                                                  kBlock32x32);

bool IsBackwardReference(ReferenceFrameType type) {
  return type >= kReferenceFrameBackward && type <= kReferenceFrameAlternate;
}

bool IsSameDirectionReferencePair(ReferenceFrameType type1,
                                  ReferenceFrameType type2) {
  return (type1 >= kReferenceFrameBackward) ==
         (type2 >= kReferenceFrameBackward);
}

// This is called neg_deinterleave() in the spec.
int DecodeSegmentId(int diff, int reference, int max) {
  if (reference == 0) return diff;
  if (reference >= max - 1) return max - diff - 1;
  const int value = ((diff & 1) != 0) ? reference + ((diff + 1) >> 1)
                                      : reference - (diff >> 1);
  const int reference2 = (reference << 1);
  if (reference2 < max) {
    return (diff <= reference2) ? value : diff;
  }
  return (diff <= ((max - reference - 1) << 1)) ? value : max - (diff + 1);
}

// This is called DrlCtxStack in section 7.10.2.14 of the spec.
int GetRefMvIndexContext(
    const CandidateMotionVector ref_mv_stack[kMaxRefMvStackSize], int count,
    int index) {
  if (index + 1 >= count ||
      (ref_mv_stack[index].weight >= kExtraWeightForNearestMvs &&
       ref_mv_stack[index + 1].weight >= kExtraWeightForNearestMvs)) {
    return 0;
  }
  if (ref_mv_stack[index].weight >= kExtraWeightForNearestMvs &&
      ref_mv_stack[index + 1].weight < kExtraWeightForNearestMvs) {
    return 1;
  }
  if (ref_mv_stack[index].weight < kExtraWeightForNearestMvs &&
      ref_mv_stack[index + 1].weight < kExtraWeightForNearestMvs) {
    return 2;
  }
  return 0;
}

// Returns true if the either the width or the height of the block is equal to
// four.
bool IsBlockDimension4(BlockSize size) {
  return size < kBlock8x8 || size == kBlock16x4;
}

// Returns true if both the width and height of the block is less than 64.
bool IsBlockDimensionLessThan64(BlockSize size) {
  return size <= kBlock32x32 && size != kBlock16x64;
}

}  // namespace

bool Tile::ReadSegmentId(const Block& block) {
  int top_left = -1;
  if (block.top_available && block.left_available) {
    top_left =
        block_parameters_holder_.Find(block.row4x4 - 1, block.column4x4 - 1)
            ->segment_id;
  }
  int top = -1;
  if (block.top_available) {
    top = block.bp_top->segment_id;
  }
  int left = -1;
  if (block.left_available) {
    left = block.bp_left->segment_id;
  }
  int pred;
  if (top == -1) {
    pred = (left == -1) ? 0 : left;
  } else if (left == -1) {
    pred = top;
  } else {
    pred = (top_left == top) ? top : left;
  }
  BlockParameters& bp = *block.bp;
  if (bp.skip) {
    bp.segment_id = pred;
    return true;
  }
  int context = 0;
  if (top_left < 0) {
    context = 0;
  } else if (top_left == top && top_left == left) {
    context = 2;
  } else if (top_left == top || top_left == left || top == left) {
    context = 1;
  }
  uint16_t* const segment_id_cdf =
      symbol_decoder_context_.segment_id_cdf[context];
  const int encoded_segment_id =
      reader_.ReadSymbol<kMaxSegments>(segment_id_cdf);
  bp.segment_id =
      DecodeSegmentId(encoded_segment_id, pred,
                      frame_header_.segmentation.last_active_segment_id + 1);
  // Check the bitstream conformance requirement in Section 6.10.8 of the spec.
  if (bp.segment_id < 0 ||
      bp.segment_id > frame_header_.segmentation.last_active_segment_id) {
    LIBGAV1_DLOG(
        ERROR,
        "Corrupted segment_ids: encoded %d, last active %d, postprocessed %d",
        encoded_segment_id, frame_header_.segmentation.last_active_segment_id,
        bp.segment_id);
    return false;
  }
  return true;
}

bool Tile::ReadIntraSegmentId(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (!frame_header_.segmentation.enabled) {
    bp.segment_id = 0;
    return true;
  }
  return ReadSegmentId(block);
}

void Tile::ReadSkip(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (frame_header_.segmentation.segment_id_pre_skip &&
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureSkip)) {
    bp.skip = true;
    return;
  }
  int context = 0;
  if (block.top_available && block.bp_top->skip) {
    ++context;
  }
  if (block.left_available && block.bp_left->skip) {
    ++context;
  }
  uint16_t* const skip_cdf = symbol_decoder_context_.skip_cdf[context];
  bp.skip = reader_.ReadSymbol(skip_cdf);
}

void Tile::ReadSkipMode(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (!frame_header_.skip_mode_present ||
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureSkip) ||
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureReferenceFrame) ||
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureGlobalMv) ||
      IsBlockDimension4(block.size)) {
    bp.skip_mode = false;
    return;
  }
  const int context =
      (block.left_available ? static_cast<int>(block.bp_left->skip_mode) : 0) +
      (block.top_available ? static_cast<int>(block.bp_top->skip_mode) : 0);
  bp.skip_mode =
      reader_.ReadSymbol(symbol_decoder_context_.skip_mode_cdf[context]);
}

void Tile::ReadCdef(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (bp.skip || frame_header_.coded_lossless ||
      !sequence_header_.enable_cdef || frame_header_.allow_intrabc) {
    return;
  }
  const int cdef_size4x4 = kNum4x4BlocksWide[kBlock64x64];
  const int cdef_mask4x4 = ~(cdef_size4x4 - 1);
  const int row4x4 = block.row4x4 & cdef_mask4x4;
  const int column4x4 = block.column4x4 & cdef_mask4x4;
  const int row = DivideBy16(row4x4);
  const int column = DivideBy16(column4x4);
  if (cdef_index_[row][column] == -1) {
    cdef_index_[row][column] =
        static_cast<int16_t>(reader_.ReadLiteral(frame_header_.cdef.bits));
    const int width4x4 = kNum4x4BlocksWide[block.size];
    const int height4x4 = kNum4x4BlocksHigh[block.size];
    for (int i = row4x4; i < row4x4 + height4x4; i += cdef_size4x4) {
      for (int j = column4x4; j < column4x4 + width4x4; j += cdef_size4x4) {
        cdef_index_[DivideBy16(i)][DivideBy16(j)] = cdef_index_[row][column];
      }
    }
  }
}

int Tile::ReadAndClipDelta(uint16_t* const cdf, int delta_small, int scale,
                           int min_value, int max_value, int value) {
  int abs = reader_.ReadSymbol<kDeltaSymbolCount>(cdf);
  if (abs == delta_small) {
    const int remaining_bit_count =
        static_cast<int>(reader_.ReadLiteral(3)) + 1;
    const int abs_remaining_bits =
        static_cast<int>(reader_.ReadLiteral(remaining_bit_count));
    abs = abs_remaining_bits + (1 << remaining_bit_count) + 1;
  }
  if (abs != 0) {
    const bool sign = static_cast<bool>(reader_.ReadBit());
    const int scaled_abs = abs << scale;
    const int reduced_delta = sign ? -scaled_abs : scaled_abs;
    value += reduced_delta;
    value = Clip3(value, min_value, max_value);
  }
  return value;
}

void Tile::ReadQuantizerIndexDelta(const Block& block) {
  assert(read_deltas_);
  BlockParameters& bp = *block.bp;
  if ((block.size == SuperBlockSize() && bp.skip)) {
    return;
  }
  current_quantizer_index_ =
      ReadAndClipDelta(symbol_decoder_context_.delta_q_cdf, kDeltaQSmall,
                       frame_header_.delta_q.scale, kMinLossyQuantizer,
                       kMaxQuantizer, current_quantizer_index_);
}

void Tile::ReadLoopFilterDelta(const Block& block) {
  assert(read_deltas_);
  BlockParameters& bp = *block.bp;
  if (!frame_header_.delta_lf.present ||
      (block.size == SuperBlockSize() && bp.skip)) {
    return;
  }
  int frame_lf_count = 1;
  if (frame_header_.delta_lf.multi) {
    frame_lf_count = kFrameLfCount - (PlaneCount() > 1 ? 0 : 2);
  }
  bool recompute_deblock_filter_levels = false;
  for (int i = 0; i < frame_lf_count; ++i) {
    uint16_t* const delta_lf_abs_cdf =
        frame_header_.delta_lf.multi
            ? symbol_decoder_context_.delta_lf_multi_cdf[i]
            : symbol_decoder_context_.delta_lf_cdf;
    const int8_t old_delta_lf = delta_lf_[i];
    delta_lf_[i] = ReadAndClipDelta(
        delta_lf_abs_cdf, kDeltaLfSmall, frame_header_.delta_lf.scale,
        -kMaxLoopFilterValue, kMaxLoopFilterValue, delta_lf_[i]);
    recompute_deblock_filter_levels =
        recompute_deblock_filter_levels || (old_delta_lf != delta_lf_[i]);
  }
  delta_lf_all_zero_ =
      (delta_lf_[0] | delta_lf_[1] | delta_lf_[2] | delta_lf_[3]) == 0;
  if (!delta_lf_all_zero_ && recompute_deblock_filter_levels) {
    post_filter_.ComputeDeblockFilterLevels(delta_lf_, deblock_filter_levels_);
  }
}

void Tile::ReadPredictionModeY(const Block& block, bool intra_y_mode) {
  uint16_t* cdf;
  if (intra_y_mode) {
    const PredictionMode top_mode =
        block.top_available ? block.bp_top->y_mode : kPredictionModeDc;
    const PredictionMode left_mode =
        block.left_available ? block.bp_left->y_mode : kPredictionModeDc;
    const int top_context = kIntraYModeContext[top_mode];
    const int left_context = kIntraYModeContext[left_mode];
    cdf = symbol_decoder_context_
              .intra_frame_y_mode_cdf[top_context][left_context];
  } else {
    cdf = symbol_decoder_context_.y_mode_cdf[kSizeGroup[block.size]];
  }
  block.bp->y_mode = static_cast<PredictionMode>(
      reader_.ReadSymbol<kIntraPredictionModesY>(cdf));
}

void Tile::ReadIntraAngleInfo(const Block& block, PlaneType plane_type) {
  BlockParameters& bp = *block.bp;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.angle_delta[plane_type] = 0;
  const PredictionMode mode =
      (plane_type == kPlaneTypeY) ? bp.y_mode : bp.uv_mode;
  if (IsBlockSmallerThan8x8(block.size) || !IsDirectionalMode(mode)) return;
  uint16_t* const cdf =
      symbol_decoder_context_.angle_delta_cdf[mode - kPredictionModeVertical];
  prediction_parameters.angle_delta[plane_type] =
      reader_.ReadSymbol<kAngleDeltaSymbolCount>(cdf);
  prediction_parameters.angle_delta[plane_type] -= kMaxAngleDelta;
}

void Tile::ReadCflAlpha(const Block& block) {
  const int signs = reader_.ReadSymbol<kCflAlphaSignsSymbolCount>(
      symbol_decoder_context_.cfl_alpha_signs_cdf);
  const auto sign_u = static_cast<CflSign>((signs + 1) / 3);
  const auto sign_v = static_cast<CflSign>((signs + 1) % 3);
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.cfl_alpha_u = 0;
  if (sign_u != kCflSignZero) {
    prediction_parameters.cfl_alpha_u =
        reader_.ReadSymbol<kCflAlphaSymbolCount>(
            symbol_decoder_context_.cfl_alpha_cdf[signs - 2]) +
        1;
    if (sign_u == kCflSignNegative) prediction_parameters.cfl_alpha_u *= -1;
  }
  prediction_parameters.cfl_alpha_v = 0;
  if (sign_v != kCflSignZero) {
    const int context = (sign_v - 1) * 3 + sign_u;
    prediction_parameters.cfl_alpha_v =
        reader_.ReadSymbol<kCflAlphaSymbolCount>(
            symbol_decoder_context_.cfl_alpha_cdf[context]) +
        1;
    if (sign_v == kCflSignNegative) prediction_parameters.cfl_alpha_v *= -1;
  }
}

void Tile::ReadPredictionModeUV(const Block& block) {
  BlockParameters& bp = *block.bp;
  bool chroma_from_luma_allowed;
  if (frame_header_.segmentation.lossless[bp.segment_id]) {
    chroma_from_luma_allowed =
        kPlaneResidualSize[block.size][subsampling_x_[kPlaneU]]
                          [subsampling_y_[kPlaneU]] == kBlock4x4;
  } else {
    chroma_from_luma_allowed = IsBlockDimensionLessThan64(block.size);
  }
  uint16_t* const cdf =
      symbol_decoder_context_
          .uv_mode_cdf[static_cast<int>(chroma_from_luma_allowed)][bp.y_mode];
  const int symbol_count =
      kIntraPredictionModesUV - static_cast<int>(!chroma_from_luma_allowed);
  bp.uv_mode =
      static_cast<PredictionMode>(reader_.ReadSymbol(cdf, symbol_count));
}

int Tile::ReadMotionVectorComponent(const Block& block, const int component) {
  const int context =
      static_cast<int>(block.bp->prediction_parameters->use_intra_block_copy);
  const bool sign = reader_.ReadSymbol(
      symbol_decoder_context_.mv_sign_cdf[component][context]);
  const int mv_class = reader_.ReadSymbol<kMvClassSymbolCount>(
      symbol_decoder_context_.mv_class_cdf[component][context]);
  int magnitude = 1;
  int value;
  uint16_t* fraction_cdf;
  uint16_t* precision_cdf;
  if (mv_class == 0) {
    value = static_cast<int>(reader_.ReadSymbol(
        symbol_decoder_context_.mv_class0_bit_cdf[component][context]));
    fraction_cdf = symbol_decoder_context_
                       .mv_class0_fraction_cdf[component][context][value];
    precision_cdf = symbol_decoder_context_
                        .mv_class0_high_precision_cdf[component][context];
  } else {
    assert(mv_class <= kMvBitSymbolCount);
    value = 0;
    for (int i = 0; i < mv_class; ++i) {
      const int bit = static_cast<int>(reader_.ReadSymbol(
          symbol_decoder_context_.mv_bit_cdf[component][context][i]));
      value |= bit << i;
    }
    magnitude += 2 << (mv_class + 2);
    fraction_cdf = symbol_decoder_context_.mv_fraction_cdf[component][context];
    precision_cdf =
        symbol_decoder_context_.mv_high_precision_cdf[component][context];
  }
  const int fraction =
      (frame_header_.force_integer_mv == 0)
          ? reader_.ReadSymbol<kMvFractionSymbolCount>(fraction_cdf)
          : 3;
  const int precision =
      frame_header_.allow_high_precision_mv
          ? static_cast<int>(reader_.ReadSymbol(precision_cdf))
          : 1;
  magnitude += (value << 3) | (fraction << 1) | precision;
  return sign ? -magnitude : magnitude;
}

void Tile::ReadMotionVector(const Block& block, int index) {
  BlockParameters& bp = *block.bp;
  const int context =
      static_cast<int>(block.bp->prediction_parameters->use_intra_block_copy);
  const auto mv_joint = static_cast<MvJointType>(
      reader_.ReadSymbol(symbol_decoder_context_.mv_joint_cdf[context],
                         static_cast<int>(kNumMvJointTypes)));
  if (mv_joint == kMvJointTypeHorizontalZeroVerticalNonZero ||
      mv_joint == kMvJointTypeNonZero) {
    bp.mv[index].mv[0] = ReadMotionVectorComponent(block, 0);
  }
  if (mv_joint == kMvJointTypeHorizontalNonZeroVerticalZero ||
      mv_joint == kMvJointTypeNonZero) {
    bp.mv[index].mv[1] = ReadMotionVectorComponent(block, 1);
  }
}

void Tile::ReadFilterIntraModeInfo(const Block& block) {
  BlockParameters& bp = *block.bp;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.use_filter_intra = false;
  if (!sequence_header_.enable_filter_intra || bp.y_mode != kPredictionModeDc ||
      bp.palette_mode_info.size[kPlaneTypeY] != 0 ||
      !IsBlockDimensionLessThan64(block.size)) {
    return;
  }
  prediction_parameters.use_filter_intra = reader_.ReadSymbol(
      symbol_decoder_context_.use_filter_intra_cdf[block.size]);
  if (prediction_parameters.use_filter_intra) {
    prediction_parameters.filter_intra_mode = static_cast<FilterIntraPredictor>(
        reader_.ReadSymbol<kNumFilterIntraPredictors>(
            symbol_decoder_context_.filter_intra_mode_cdf));
  }
}

bool Tile::DecodeIntraModeInfo(const Block& block) {
  BlockParameters& bp = *block.bp;
  bp.skip = false;
  if (frame_header_.segmentation.segment_id_pre_skip &&
      !ReadIntraSegmentId(block)) {
    return false;
  }
  bp.skip_mode = false;
  ReadSkip(block);
  if (!frame_header_.segmentation.segment_id_pre_skip &&
      !ReadIntraSegmentId(block)) {
    return false;
  }
  ReadCdef(block);
  if (read_deltas_) {
    ReadQuantizerIndexDelta(block);
    ReadLoopFilterDelta(block);
    read_deltas_ = false;
  }
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.use_intra_block_copy = false;
  if (frame_header_.allow_intrabc) {
    prediction_parameters.use_intra_block_copy =
        reader_.ReadSymbol(symbol_decoder_context_.intra_block_copy_cdf);
  }
  if (prediction_parameters.use_intra_block_copy) {
    bp.is_inter = true;
    bp.reference_frame[0] = kReferenceFrameIntra;
    bp.reference_frame[1] = kReferenceFrameNone;
    bp.y_mode = kPredictionModeDc;
    bp.uv_mode = kPredictionModeDc;
    prediction_parameters.motion_mode = kMotionModeSimple;
    prediction_parameters.compound_prediction_type =
        kCompoundPredictionTypeAverage;
    bp.palette_mode_info.size[kPlaneTypeY] = 0;
    bp.palette_mode_info.size[kPlaneTypeUV] = 0;
    bp.interpolation_filter[0] = kInterpolationFilterBilinear;
    bp.interpolation_filter[1] = kInterpolationFilterBilinear;
    FindMvStack(block, /*is_compound=*/false, reference_frame_sign_bias_,
                *motion_field_mv_, prediction_parameters.ref_mv_stack,
                &prediction_parameters.ref_mv_count, /*contexts=*/nullptr,
                prediction_parameters.global_mv);
    return AssignMv(block, /*is_compound=*/false);
  }
  bp.is_inter = false;
  return ReadIntraBlockModeInfo(block, /*intra_y_mode=*/true);
}

int8_t Tile::ComputePredictedSegmentId(const Block& block) const {
  // If prev_segment_ids_ is null, treat it as if it pointed to a segmentation
  // map containing all 0s.
  if (prev_segment_ids_ == nullptr) return 0;

  const int x_limit = std::min(frame_header_.columns4x4 - block.column4x4,
                               static_cast<int>(kNum4x4BlocksWide[block.size]));
  const int y_limit = std::min(frame_header_.rows4x4 - block.row4x4,
                               static_cast<int>(kNum4x4BlocksHigh[block.size]));
  int8_t id = 7;
  for (int y = 0; y < y_limit; ++y) {
    for (int x = 0; x < x_limit; ++x) {
      const int8_t prev_segment_id =
          prev_segment_ids_->segment_id(block.row4x4 + y, block.column4x4 + x);
      id = std::min(id, prev_segment_id);
    }
  }
  return id;
}

bool Tile::ReadInterSegmentId(const Block& block, bool pre_skip) {
  BlockParameters& bp = *block.bp;
  if (!frame_header_.segmentation.enabled) {
    bp.segment_id = 0;
    return true;
  }
  if (!frame_header_.segmentation.update_map) {
    bp.segment_id = ComputePredictedSegmentId(block);
    return true;
  }
  if (pre_skip) {
    if (!frame_header_.segmentation.segment_id_pre_skip) {
      bp.segment_id = 0;
      return true;
    }
  } else if (bp.skip) {
    bp.use_predicted_segment_id = false;
    return ReadSegmentId(block);
  }
  if (frame_header_.segmentation.temporal_update) {
    const int context =
        (block.left_available
             ? static_cast<int>(block.bp_left->use_predicted_segment_id)
             : 0) +
        (block.top_available
             ? static_cast<int>(block.bp_top->use_predicted_segment_id)
             : 0);
    bp.use_predicted_segment_id = reader_.ReadSymbol(
        symbol_decoder_context_.use_predicted_segment_id_cdf[context]);
    if (bp.use_predicted_segment_id) {
      bp.segment_id = ComputePredictedSegmentId(block);
      return true;
    }
  }
  return ReadSegmentId(block);
}

void Tile::ReadIsInter(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (bp.skip_mode) {
    bp.is_inter = true;
    return;
  }
  if (frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureReferenceFrame)) {
    bp.is_inter =
        frame_header_.segmentation
            .feature_data[bp.segment_id][kSegmentFeatureReferenceFrame] !=
        kReferenceFrameIntra;
    return;
  }
  if (frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureGlobalMv)) {
    bp.is_inter = true;
    return;
  }
  int context = 0;
  if (block.top_available && block.left_available) {
    context = (block.IsTopIntra() && block.IsLeftIntra())
                  ? 3
                  : static_cast<int>(block.IsTopIntra() || block.IsLeftIntra());
  } else if (block.top_available || block.left_available) {
    context = 2 * static_cast<int>(block.top_available ? block.IsTopIntra()
                                                       : block.IsLeftIntra());
  }
  bp.is_inter =
      reader_.ReadSymbol(symbol_decoder_context_.is_inter_cdf[context]);
}

bool Tile::ReadIntraBlockModeInfo(const Block& block, bool intra_y_mode) {
  BlockParameters& bp = *block.bp;
  bp.reference_frame[0] = kReferenceFrameIntra;
  bp.reference_frame[1] = kReferenceFrameNone;
  ReadPredictionModeY(block, intra_y_mode);
  ReadIntraAngleInfo(block, kPlaneTypeY);
  if (block.HasChroma()) {
    ReadPredictionModeUV(block);
    if (bp.uv_mode == kPredictionModeChromaFromLuma) {
      ReadCflAlpha(block);
    }
    ReadIntraAngleInfo(block, kPlaneTypeUV);
  }
  ReadPaletteModeInfo(block);
  ReadFilterIntraModeInfo(block);
  return true;
}

int Tile::GetUseCompoundReferenceContext(const Block& block) {
  if (block.top_available && block.left_available) {
    if (block.IsTopSingle() && block.IsLeftSingle()) {
      return static_cast<int>(IsBackwardReference(block.TopReference(0))) ^
             static_cast<int>(IsBackwardReference(block.LeftReference(0)));
    }
    if (block.IsTopSingle()) {
      return 2 + static_cast<int>(IsBackwardReference(block.TopReference(0)) ||
                                  block.IsTopIntra());
    }
    if (block.IsLeftSingle()) {
      return 2 + static_cast<int>(IsBackwardReference(block.LeftReference(0)) ||
                                  block.IsLeftIntra());
    }
    return 4;
  }
  if (block.top_available) {
    return block.IsTopSingle()
               ? static_cast<int>(IsBackwardReference(block.TopReference(0)))
               : 3;
  }
  if (block.left_available) {
    return block.IsLeftSingle()
               ? static_cast<int>(IsBackwardReference(block.LeftReference(0)))
               : 3;
  }
  return 1;
}

CompoundReferenceType Tile::ReadCompoundReferenceType(const Block& block) {
  // compound and inter.
  const bool top_comp_inter =
      block.top_available && !block.IsTopIntra() && !block.IsTopSingle();
  const bool left_comp_inter =
      block.left_available && !block.IsLeftIntra() && !block.IsLeftSingle();
  // unidirectional compound.
  const bool top_uni_comp =
      top_comp_inter && IsSameDirectionReferencePair(block.TopReference(0),
                                                     block.TopReference(1));
  const bool left_uni_comp =
      left_comp_inter && IsSameDirectionReferencePair(block.LeftReference(0),
                                                      block.LeftReference(1));
  int context;
  if (block.top_available && !block.IsTopIntra() && block.left_available &&
      !block.IsLeftIntra()) {
    const int same_direction = static_cast<int>(IsSameDirectionReferencePair(
        block.TopReference(0), block.LeftReference(0)));
    if (!top_comp_inter && !left_comp_inter) {
      context = 1 + MultiplyBy2(same_direction);
    } else if (!top_comp_inter) {
      context = left_uni_comp ? 3 + same_direction : 1;
    } else if (!left_comp_inter) {
      context = top_uni_comp ? 3 + same_direction : 1;
    } else {
      if (!top_uni_comp && !left_uni_comp) {
        context = 0;
      } else if (!top_uni_comp || !left_uni_comp) {
        context = 2;
      } else {
        context = 3 + static_cast<int>(
                          (block.TopReference(0) == kReferenceFrameBackward) ==
                          (block.LeftReference(0) == kReferenceFrameBackward));
      }
    }
  } else if (block.top_available && block.left_available) {
    if (top_comp_inter) {
      context = 1 + MultiplyBy2(static_cast<int>(top_uni_comp));
    } else if (left_comp_inter) {
      context = 1 + MultiplyBy2(static_cast<int>(left_uni_comp));
    } else {
      context = 2;
    }
  } else if (top_comp_inter) {
    context = MultiplyBy4(static_cast<int>(top_uni_comp));
  } else if (left_comp_inter) {
    context = MultiplyBy4(static_cast<int>(left_uni_comp));
  } else {
    context = 2;
  }
  return static_cast<CompoundReferenceType>(reader_.ReadSymbol(
      symbol_decoder_context_.compound_reference_type_cdf[context]));
}

int Tile::GetReferenceContext(const Block& block,
                              ReferenceFrameType type0_start,
                              ReferenceFrameType type0_end,
                              ReferenceFrameType type1_start,
                              ReferenceFrameType type1_end) const {
  int count0 = 0;
  int count1 = 0;
  for (int type = type0_start; type <= type0_end; ++type) {
    count0 += block.CountReferences(static_cast<ReferenceFrameType>(type));
  }
  for (int type = type1_start; type <= type1_end; ++type) {
    count1 += block.CountReferences(static_cast<ReferenceFrameType>(type));
  }
  return (count0 < count1) ? 0 : (count0 == count1 ? 1 : 2);
}

template <bool is_single, bool is_backward, int index>
uint16_t* Tile::GetReferenceCdf(
    const Block& block,
    CompoundReferenceType type /*= kNumCompoundReferenceTypes*/) {
  int context = 0;
  if ((type == kCompoundReferenceUnidirectional && index == 0) ||
      (is_single && index == 1)) {
    // uni_comp_ref and single_ref_p1.
    context =
        GetReferenceContext(block, kReferenceFrameLast, kReferenceFrameGolden,
                            kReferenceFrameBackward, kReferenceFrameAlternate);
  } else if (type == kCompoundReferenceUnidirectional && index == 1) {
    // uni_comp_ref_p1.
    context =
        GetReferenceContext(block, kReferenceFrameLast2, kReferenceFrameLast2,
                            kReferenceFrameLast3, kReferenceFrameGolden);
  } else if ((type == kCompoundReferenceUnidirectional && index == 2) ||
             (type == kCompoundReferenceBidirectional && index == 2) ||
             (is_single && index == 5)) {
    // uni_comp_ref_p2, comp_ref_p2 and single_ref_p5.
    context =
        GetReferenceContext(block, kReferenceFrameLast3, kReferenceFrameLast3,
                            kReferenceFrameGolden, kReferenceFrameGolden);
  } else if ((type == kCompoundReferenceBidirectional && index == 0) ||
             (is_single && index == 3)) {
    // comp_ref and single_ref_p3.
    context =
        GetReferenceContext(block, kReferenceFrameLast, kReferenceFrameLast2,
                            kReferenceFrameLast3, kReferenceFrameGolden);
  } else if ((type == kCompoundReferenceBidirectional && index == 1) ||
             (is_single && index == 4)) {
    // comp_ref_p1 and single_ref_p4.
    context =
        GetReferenceContext(block, kReferenceFrameLast, kReferenceFrameLast,
                            kReferenceFrameLast2, kReferenceFrameLast2);
  } else if ((is_single && index == 2) || (is_backward && index == 0)) {
    // single_ref_p2 and comp_bwdref.
    context = GetReferenceContext(
        block, kReferenceFrameBackward, kReferenceFrameAlternate2,
        kReferenceFrameAlternate, kReferenceFrameAlternate);
  } else if ((is_single && index == 6) || (is_backward && index == 1)) {
    // single_ref_p6 and comp_bwdref_p1.
    context = GetReferenceContext(
        block, kReferenceFrameBackward, kReferenceFrameBackward,
        kReferenceFrameAlternate2, kReferenceFrameAlternate2);
  }
  if (is_single) {
    // The index parameter for single references is offset by one since the spec
    // uses 1-based index for these elements.
    return symbol_decoder_context_.single_reference_cdf[context][index - 1];
  }
  if (is_backward) {
    return symbol_decoder_context_
        .compound_backward_reference_cdf[context][index];
  }
  return symbol_decoder_context_.compound_reference_cdf[type][context][index];
}

void Tile::ReadReferenceFrames(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (bp.skip_mode) {
    bp.reference_frame[0] = frame_header_.skip_mode_frame[0];
    bp.reference_frame[1] = frame_header_.skip_mode_frame[1];
    return;
  }
  if (frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureReferenceFrame)) {
    bp.reference_frame[0] = static_cast<ReferenceFrameType>(
        frame_header_.segmentation
            .feature_data[bp.segment_id][kSegmentFeatureReferenceFrame]);
    bp.reference_frame[1] = kReferenceFrameNone;
    return;
  }
  if (frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureSkip) ||
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureGlobalMv)) {
    bp.reference_frame[0] = kReferenceFrameLast;
    bp.reference_frame[1] = kReferenceFrameNone;
    return;
  }
  const int block_width4x4 = kNum4x4BlocksWide[block.size];
  const int block_height4x4 = kNum4x4BlocksHigh[block.size];
  const bool use_compound_reference =
      frame_header_.reference_mode_select &&
      std::min(block_width4x4, block_height4x4) >= 2 &&
      reader_.ReadSymbol(symbol_decoder_context_.use_compound_reference_cdf
                             [GetUseCompoundReferenceContext(block)]);
  if (use_compound_reference) {
    CompoundReferenceType reference_type = ReadCompoundReferenceType(block);
    if (reference_type == kCompoundReferenceUnidirectional) {
      // uni_comp_ref.
      if (reader_.ReadSymbol(
              GetReferenceCdf<false, false, 0>(block, reference_type))) {
        bp.reference_frame[0] = kReferenceFrameBackward;
        bp.reference_frame[1] = kReferenceFrameAlternate;
        return;
      }
      // uni_comp_ref_p1.
      if (!reader_.ReadSymbol(
              GetReferenceCdf<false, false, 1>(block, reference_type))) {
        bp.reference_frame[0] = kReferenceFrameLast;
        bp.reference_frame[1] = kReferenceFrameLast2;
        return;
      }
      // uni_comp_ref_p2.
      if (reader_.ReadSymbol(
              GetReferenceCdf<false, false, 2>(block, reference_type))) {
        bp.reference_frame[0] = kReferenceFrameLast;
        bp.reference_frame[1] = kReferenceFrameGolden;
        return;
      }
      bp.reference_frame[0] = kReferenceFrameLast;
      bp.reference_frame[1] = kReferenceFrameLast3;
      return;
    }
    assert(reference_type == kCompoundReferenceBidirectional);
    // comp_ref.
    if (reader_.ReadSymbol(
            GetReferenceCdf<false, false, 0>(block, reference_type))) {
      // comp_ref_p2.
      bp.reference_frame[0] =
          reader_.ReadSymbol(
              GetReferenceCdf<false, false, 2>(block, reference_type))
              ? kReferenceFrameGolden
              : kReferenceFrameLast3;
    } else {
      // comp_ref_p1.
      bp.reference_frame[0] =
          reader_.ReadSymbol(
              GetReferenceCdf<false, false, 1>(block, reference_type))
              ? kReferenceFrameLast2
              : kReferenceFrameLast;
    }
    // comp_bwdref.
    if (reader_.ReadSymbol(GetReferenceCdf<false, true, 0>(block))) {
      bp.reference_frame[1] = kReferenceFrameAlternate;
    } else {
      // comp_bwdref_p1.
      bp.reference_frame[1] =
          reader_.ReadSymbol(GetReferenceCdf<false, true, 1>(block))
              ? kReferenceFrameAlternate2
              : kReferenceFrameBackward;
    }
    return;
  }
  assert(!use_compound_reference);
  bp.reference_frame[1] = kReferenceFrameNone;
  // single_ref_p1.
  if (reader_.ReadSymbol(GetReferenceCdf<true, false, 1>(block))) {
    // single_ref_p2.
    if (reader_.ReadSymbol(GetReferenceCdf<true, false, 2>(block))) {
      bp.reference_frame[0] = kReferenceFrameAlternate;
      return;
    }
    // single_ref_p6.
    bp.reference_frame[0] =
        reader_.ReadSymbol(GetReferenceCdf<true, false, 6>(block))
            ? kReferenceFrameAlternate2
            : kReferenceFrameBackward;
    return;
  }
  // single_ref_p3.
  if (reader_.ReadSymbol(GetReferenceCdf<true, false, 3>(block))) {
    // single_ref_p5.
    bp.reference_frame[0] =
        reader_.ReadSymbol(GetReferenceCdf<true, false, 5>(block))
            ? kReferenceFrameGolden
            : kReferenceFrameLast3;
    return;
  }
  // single_ref_p4.
  bp.reference_frame[0] =
      reader_.ReadSymbol(GetReferenceCdf<true, false, 4>(block))
          ? kReferenceFrameLast2
          : kReferenceFrameLast;
}

void Tile::ReadInterPredictionModeY(const Block& block,
                                    const MvContexts& mode_contexts) {
  BlockParameters& bp = *block.bp;
  if (bp.skip_mode) {
    bp.y_mode = kPredictionModeNearestNearestMv;
    return;
  }
  if (frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureSkip) ||
      frame_header_.segmentation.FeatureActive(bp.segment_id,
                                               kSegmentFeatureGlobalMv)) {
    bp.y_mode = kPredictionModeGlobalMv;
    return;
  }
  if (bp.reference_frame[1] > kReferenceFrameIntra) {
    const int idx0 = mode_contexts.reference_mv >> 1;
    const int idx1 =
        std::min(mode_contexts.new_mv, kCompoundModeNewMvContexts - 1);
    const int context = kCompoundModeContextMap[idx0][idx1];
    const int offset = reader_.ReadSymbol<kNumCompoundInterPredictionModes>(
        symbol_decoder_context_.compound_prediction_mode_cdf[context]);
    bp.y_mode =
        static_cast<PredictionMode>(kPredictionModeNearestNearestMv + offset);
    return;
  }
  // new_mv.
  if (!reader_.ReadSymbol(
          symbol_decoder_context_.new_mv_cdf[mode_contexts.new_mv])) {
    bp.y_mode = kPredictionModeNewMv;
    return;
  }
  // zero_mv.
  if (!reader_.ReadSymbol(
          symbol_decoder_context_.zero_mv_cdf[mode_contexts.zero_mv])) {
    bp.y_mode = kPredictionModeGlobalMv;
    return;
  }
  // ref_mv.
  bp.y_mode =
      reader_.ReadSymbol(
          symbol_decoder_context_.reference_mv_cdf[mode_contexts.reference_mv])
          ? kPredictionModeNearMv
          : kPredictionModeNearestMv;
}

void Tile::ReadRefMvIndex(const Block& block) {
  BlockParameters& bp = *block.bp;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.ref_mv_index = 0;
  if (bp.y_mode != kPredictionModeNewMv &&
      bp.y_mode != kPredictionModeNewNewMv &&
      !kPredictionModeHasNearMvMask.Contains(bp.y_mode)) {
    return;
  }
  const int start =
      static_cast<int>(kPredictionModeHasNearMvMask.Contains(bp.y_mode));
  prediction_parameters.ref_mv_index = start;
  for (int i = start; i < start + 2; ++i) {
    if (prediction_parameters.ref_mv_count <= i + 1) continue;
    // drl_mode in the spec.
    const bool ref_mv_index_bit = reader_.ReadSymbol(
        symbol_decoder_context_.ref_mv_index_cdf[GetRefMvIndexContext(
            prediction_parameters.ref_mv_stack,
            prediction_parameters.ref_mv_count, i)]);
    prediction_parameters.ref_mv_index = i + static_cast<int>(ref_mv_index_bit);
    if (!ref_mv_index_bit) return;
  }
}

void Tile::ReadInterIntraMode(const Block& block, bool is_compound) {
  BlockParameters& bp = *block.bp;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  prediction_parameters.inter_intra_mode = kNumInterIntraModes;
  prediction_parameters.is_wedge_inter_intra = false;
  if (bp.skip_mode || !sequence_header_.enable_interintra_compound ||
      is_compound || !kIsInterIntraModeAllowedMask.Contains(block.size)) {
    return;
  }
  // kSizeGroup[block.size] is guaranteed to be non-zero because of the block
  // size constraint enforced in the above condition.
  assert(kSizeGroup[block.size] - 1 >= 0);
  if (!reader_.ReadSymbol(
          symbol_decoder_context_
              .is_inter_intra_cdf[kSizeGroup[block.size] - 1])) {
    prediction_parameters.inter_intra_mode = kNumInterIntraModes;
    return;
  }
  prediction_parameters.inter_intra_mode =
      static_cast<InterIntraMode>(reader_.ReadSymbol<kNumInterIntraModes>(
          symbol_decoder_context_
              .inter_intra_mode_cdf[kSizeGroup[block.size] - 1]));
  bp.reference_frame[1] = kReferenceFrameIntra;
  prediction_parameters.angle_delta[kPlaneTypeY] = 0;
  prediction_parameters.angle_delta[kPlaneTypeUV] = 0;
  prediction_parameters.use_filter_intra = false;
  prediction_parameters.is_wedge_inter_intra = reader_.ReadSymbol(
      symbol_decoder_context_.is_wedge_inter_intra_cdf[block.size]);
  if (!prediction_parameters.is_wedge_inter_intra) return;
  prediction_parameters.wedge_index =
      reader_.ReadSymbol<kWedgeIndexSymbolCount>(
          symbol_decoder_context_.wedge_index_cdf[block.size]);
  prediction_parameters.wedge_sign = 0;
}

bool Tile::IsScaled(ReferenceFrameType type) const {
  const int index =
      frame_header_.reference_frame_index[type - kReferenceFrameLast];
  const int x_scale = ((reference_frames_[index]->upscaled_width()
                        << kReferenceFrameScalePrecision) +
                       DivideBy2(frame_header_.width)) /
                      frame_header_.width;
  if (x_scale != kNoScale) return true;
  const int y_scale = ((reference_frames_[index]->frame_height()
                        << kReferenceFrameScalePrecision) +
                       DivideBy2(frame_header_.height)) /
                      frame_header_.height;
  return y_scale != kNoScale;
}

void Tile::ReadMotionMode(const Block& block, bool is_compound) {
  BlockParameters& bp = *block.bp;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  const auto global_motion_type =
      frame_header_.global_motion[bp.reference_frame[0]].type;
  if (bp.skip_mode || !frame_header_.is_motion_mode_switchable ||
      IsBlockDimension4(block.size) ||
      (frame_header_.force_integer_mv == 0 &&
       (bp.y_mode == kPredictionModeGlobalMv ||
        bp.y_mode == kPredictionModeGlobalGlobalMv) &&
       global_motion_type > kGlobalMotionTransformationTypeTranslation) ||
      is_compound || bp.reference_frame[1] == kReferenceFrameIntra ||
      !block.HasOverlappableCandidates()) {
    prediction_parameters.motion_mode = kMotionModeSimple;
    return;
  }
  prediction_parameters.num_warp_samples = 0;
  int num_samples_scanned = 0;
  memset(prediction_parameters.warp_estimate_candidates, 0,
         sizeof(prediction_parameters.warp_estimate_candidates));
  FindWarpSamples(block, &prediction_parameters.num_warp_samples,
                  &num_samples_scanned,
                  prediction_parameters.warp_estimate_candidates);
  if (frame_header_.force_integer_mv != 0 ||
      prediction_parameters.num_warp_samples == 0 ||
      !frame_header_.allow_warped_motion || IsScaled(bp.reference_frame[0])) {
    prediction_parameters.motion_mode =
        reader_.ReadSymbol(symbol_decoder_context_.use_obmc_cdf[block.size])
            ? kMotionModeObmc
            : kMotionModeSimple;
    return;
  }
  prediction_parameters.motion_mode =
      static_cast<MotionMode>(reader_.ReadSymbol<kNumMotionModes>(
          symbol_decoder_context_.motion_mode_cdf[block.size]));
}

uint16_t* Tile::GetIsExplicitCompoundTypeCdf(const Block& block) {
  int context = 0;
  if (block.top_available) {
    if (!block.IsTopSingle()) {
      context += static_cast<int>(block.bp_top->is_explicit_compound_type);
    } else if (block.TopReference(0) == kReferenceFrameAlternate) {
      context += 3;
    }
  }
  if (block.left_available) {
    if (!block.IsLeftSingle()) {
      context += static_cast<int>(block.bp_left->is_explicit_compound_type);
    } else if (block.LeftReference(0) == kReferenceFrameAlternate) {
      context += 3;
    }
  }
  return symbol_decoder_context_.is_explicit_compound_type_cdf[std::min(
      context, kIsExplicitCompoundTypeContexts - 1)];
}

uint16_t* Tile::GetIsCompoundTypeAverageCdf(const Block& block) {
  const BlockParameters& bp = *block.bp;
  const int forward = std::abs(GetRelativeDistance(
      current_frame_.order_hint(bp.reference_frame[0]),
      frame_header_.order_hint, sequence_header_.enable_order_hint,
      sequence_header_.order_hint_bits));
  const int backward = std::abs(GetRelativeDistance(
      current_frame_.order_hint(bp.reference_frame[1]),
      frame_header_.order_hint, sequence_header_.enable_order_hint,
      sequence_header_.order_hint_bits));
  int context = (forward == backward) ? 3 : 0;
  if (block.top_available) {
    if (!block.IsTopSingle()) {
      context += static_cast<int>(block.bp_top->is_compound_type_average);
    } else if (block.TopReference(0) == kReferenceFrameAlternate) {
      ++context;
    }
  }
  if (block.left_available) {
    if (!block.IsLeftSingle()) {
      context += static_cast<int>(block.bp_left->is_compound_type_average);
    } else if (block.LeftReference(0) == kReferenceFrameAlternate) {
      ++context;
    }
  }
  return symbol_decoder_context_.is_compound_type_average_cdf[context];
}

void Tile::ReadCompoundType(const Block& block, bool is_compound) {
  BlockParameters& bp = *block.bp;
  bp.is_explicit_compound_type = false;
  bp.is_compound_type_average = true;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  if (bp.skip_mode) {
    prediction_parameters.compound_prediction_type =
        kCompoundPredictionTypeAverage;
    return;
  }
  if (is_compound) {
    if (sequence_header_.enable_masked_compound) {
      bp.is_explicit_compound_type =
          reader_.ReadSymbol(GetIsExplicitCompoundTypeCdf(block));
    }
    if (bp.is_explicit_compound_type) {
      if (kIsWedgeCompoundModeAllowed.Contains(block.size)) {
        // Only kCompoundPredictionTypeWedge and
        // kCompoundPredictionTypeDiffWeighted are signaled explicitly.
        prediction_parameters.compound_prediction_type =
            static_cast<CompoundPredictionType>(reader_.ReadSymbol(
                symbol_decoder_context_.compound_type_cdf[block.size]));
      } else {
        prediction_parameters.compound_prediction_type =
            kCompoundPredictionTypeDiffWeighted;
      }
    } else {
      if (sequence_header_.enable_jnt_comp) {
        bp.is_compound_type_average =
            reader_.ReadSymbol(GetIsCompoundTypeAverageCdf(block));
        prediction_parameters.compound_prediction_type =
            bp.is_compound_type_average ? kCompoundPredictionTypeAverage
                                        : kCompoundPredictionTypeDistance;
      } else {
        prediction_parameters.compound_prediction_type =
            kCompoundPredictionTypeAverage;
        return;
      }
    }
    if (prediction_parameters.compound_prediction_type ==
        kCompoundPredictionTypeWedge) {
      prediction_parameters.wedge_index =
          reader_.ReadSymbol<kWedgeIndexSymbolCount>(
              symbol_decoder_context_.wedge_index_cdf[block.size]);
      prediction_parameters.wedge_sign =
          static_cast<int>(reader_.ReadLiteral(1));
    } else if (prediction_parameters.compound_prediction_type ==
               kCompoundPredictionTypeDiffWeighted) {
      prediction_parameters.mask_is_inverse =
          static_cast<bool>(reader_.ReadLiteral(1));
    }
    return;
  }
  if (prediction_parameters.inter_intra_mode != kNumInterIntraModes) {
    prediction_parameters.compound_prediction_type =
        prediction_parameters.is_wedge_inter_intra
            ? kCompoundPredictionTypeWedge
            : kCompoundPredictionTypeIntra;
    return;
  }
  prediction_parameters.compound_prediction_type =
      kCompoundPredictionTypeAverage;
}

uint16_t* Tile::GetInterpolationFilterCdf(const Block& block, int direction) {
  const BlockParameters& bp = *block.bp;
  int context = MultiplyBy8(direction) +
                MultiplyBy4(static_cast<int>(bp.reference_frame[1] >
                                             kReferenceFrameIntra));
  int top_type = kNumExplicitInterpolationFilters;
  if (block.top_available) {
    if (block.bp_top->reference_frame[0] == bp.reference_frame[0] ||
        block.bp_top->reference_frame[1] == bp.reference_frame[0]) {
      top_type = block.bp_top->interpolation_filter[direction];
    }
  }
  int left_type = kNumExplicitInterpolationFilters;
  if (block.left_available) {
    if (block.bp_left->reference_frame[0] == bp.reference_frame[0] ||
        block.bp_left->reference_frame[1] == bp.reference_frame[0]) {
      left_type = block.bp_left->interpolation_filter[direction];
    }
  }
  if (left_type == top_type) {
    context += left_type;
  } else if (left_type == kNumExplicitInterpolationFilters) {
    context += top_type;
  } else if (top_type == kNumExplicitInterpolationFilters) {
    context += left_type;
  } else {
    context += kNumExplicitInterpolationFilters;
  }
  return symbol_decoder_context_.interpolation_filter_cdf[context];
}

void Tile::ReadInterpolationFilter(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (frame_header_.interpolation_filter != kInterpolationFilterSwitchable) {
    static_assert(
        sizeof(bp.interpolation_filter) / sizeof(bp.interpolation_filter[0]) ==
            2,
        "Interpolation filter array size is not 2");
    for (auto& interpolation_filter : bp.interpolation_filter) {
      interpolation_filter = frame_header_.interpolation_filter;
    }
    return;
  }
  bool interpolation_filter_present = true;
  if (bp.skip_mode ||
      block.bp->prediction_parameters->motion_mode == kMotionModeLocalWarp) {
    interpolation_filter_present = false;
  } else if (!IsBlockDimension4(block.size) &&
             bp.y_mode == kPredictionModeGlobalMv) {
    interpolation_filter_present =
        frame_header_.global_motion[bp.reference_frame[0]].type ==
        kGlobalMotionTransformationTypeTranslation;
  } else if (!IsBlockDimension4(block.size) &&
             bp.y_mode == kPredictionModeGlobalGlobalMv) {
    interpolation_filter_present =
        frame_header_.global_motion[bp.reference_frame[0]].type ==
            kGlobalMotionTransformationTypeTranslation ||
        frame_header_.global_motion[bp.reference_frame[1]].type ==
            kGlobalMotionTransformationTypeTranslation;
  }
  for (int i = 0; i < (sequence_header_.enable_dual_filter ? 2 : 1); ++i) {
    bp.interpolation_filter[i] =
        interpolation_filter_present
            ? static_cast<InterpolationFilter>(
                  reader_.ReadSymbol<kNumExplicitInterpolationFilters>(
                      GetInterpolationFilterCdf(block, i)))
            : kInterpolationFilterEightTap;
  }
  if (!sequence_header_.enable_dual_filter) {
    bp.interpolation_filter[1] = bp.interpolation_filter[0];
  }
}

bool Tile::ReadInterBlockModeInfo(const Block& block) {
  BlockParameters& bp = *block.bp;
  bp.palette_mode_info.size[kPlaneTypeY] = 0;
  bp.palette_mode_info.size[kPlaneTypeUV] = 0;
  ReadReferenceFrames(block);
  const bool is_compound = bp.reference_frame[1] > kReferenceFrameIntra;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  MvContexts mode_contexts;
  FindMvStack(block, is_compound, reference_frame_sign_bias_, *motion_field_mv_,
              prediction_parameters.ref_mv_stack,
              &prediction_parameters.ref_mv_count, &mode_contexts,
              prediction_parameters.global_mv);
  ReadInterPredictionModeY(block, mode_contexts);
  ReadRefMvIndex(block);
  if (!AssignMv(block, is_compound)) return false;
  ReadInterIntraMode(block, is_compound);
  ReadMotionMode(block, is_compound);
  ReadCompoundType(block, is_compound);
  ReadInterpolationFilter(block);
  return true;
}

bool Tile::DecodeInterModeInfo(const Block& block) {
  BlockParameters& bp = *block.bp;
  block.bp->prediction_parameters->use_intra_block_copy = false;
  bp.skip = false;
  if (!ReadInterSegmentId(block, /*pre_skip=*/true)) return false;
  ReadSkipMode(block);
  if (bp.skip_mode) {
    bp.skip = true;
  } else {
    ReadSkip(block);
  }
  if (!frame_header_.segmentation.segment_id_pre_skip &&
      !ReadInterSegmentId(block, /*pre_skip=*/false)) {
    return false;
  }
  ReadCdef(block);
  if (read_deltas_) {
    ReadQuantizerIndexDelta(block);
    ReadLoopFilterDelta(block);
    read_deltas_ = false;
  }
  ReadIsInter(block);
  return bp.is_inter ? ReadInterBlockModeInfo(block)
                     : ReadIntraBlockModeInfo(block, /*intra_y_mode=*/false);
}

bool Tile::DecodeModeInfo(const Block& block) {
  return IsIntraFrame(frame_header_.frame_type) ? DecodeIntraModeInfo(block)
                                                : DecodeInterModeInfo(block);
}

}  // namespace libgav1
