/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#include <math.h>

#include "aom_ports/system_state.h"

#include "av1/common/av1_common_int.h"
#include "av1/common/blockd.h"
#include "av1/common/enums.h"

PREDICTION_MODE av1_get_joint_mode(const MB_MODE_INFO *mi) {
  if (!mi) return DC_PRED;
  if (is_inter_block(mi, SHARED_PART) || is_intrabc_block(mi, SHARED_PART))
    return DC_PRED;
  return mi->joint_y_mode_delta_angle;
}

void av1_reset_is_mi_coded_map(MACROBLOCKD *xd, int stride) {
  av1_zero(xd->is_mi_coded);
  xd->is_mi_coded_stride = stride;
}

void av1_mark_block_as_coded(MACROBLOCKD *xd, BLOCK_SIZE bsize,
                             BLOCK_SIZE sb_size) {
  const int mi_row = xd->mi_row;
  const int mi_col = xd->mi_col;
  const int sb_mi_size = mi_size_wide[sb_size];
  const int mi_row_offset = mi_row & (sb_mi_size - 1);
  const int mi_col_offset = mi_col & (sb_mi_size - 1);

  for (int r = 0; r < mi_size_high[bsize]; ++r)
    for (int c = 0; c < mi_size_wide[bsize]; ++c) {
      const int pos =
          (mi_row_offset + r) * xd->is_mi_coded_stride + mi_col_offset + c;
      switch (xd->tree_type) {
        case SHARED_PART:
          xd->is_mi_coded[0][pos] = 1;
          xd->is_mi_coded[1][pos] = 1;
          break;
        case LUMA_PART: xd->is_mi_coded[0][pos] = 1; break;
        case CHROMA_PART: xd->is_mi_coded[1][pos] = 1; break;
        default: assert(0 && "Invalid tree type");
      }
    }
}

void av1_mark_block_as_not_coded(MACROBLOCKD *xd, int mi_row, int mi_col,
                                 BLOCK_SIZE bsize, BLOCK_SIZE sb_size) {
  const int sb_mi_size = mi_size_wide[sb_size];
  const int mi_row_offset = mi_row & (sb_mi_size - 1);
  const int mi_col_offset = mi_col & (sb_mi_size - 1);

  for (int r = 0; r < mi_size_high[bsize]; ++r) {
    const int pos =
        (mi_row_offset + r) * xd->is_mi_coded_stride + mi_col_offset;
    uint8_t *row_ptr_luma = &xd->is_mi_coded[0][pos];
    uint8_t *row_ptr_chroma = &xd->is_mi_coded[1][pos];
    switch (xd->tree_type) {
      case SHARED_PART:
        av1_zero_array(row_ptr_luma, mi_size_wide[bsize]);
        av1_zero_array(row_ptr_chroma, mi_size_wide[bsize]);
        break;
      case LUMA_PART: av1_zero_array(row_ptr_luma, mi_size_wide[bsize]); break;
      case CHROMA_PART:
        av1_zero_array(row_ptr_chroma, mi_size_wide[bsize]);
        break;
      default: assert(0 && "Invalid tree type");
    }
  }
}

PARTITION_TREE *av1_alloc_ptree_node(PARTITION_TREE *parent, int index) {
  PARTITION_TREE *ptree = NULL;
  struct aom_internal_error_info error;

  AOM_CHECK_MEM_ERROR(&error, ptree, aom_calloc(1, sizeof(*ptree)));

  ptree->parent = parent;
  ptree->index = index;
  ptree->partition = PARTITION_INVALID;
  ptree->is_settled = 0;
  for (int i = 0; i < 4; ++i) ptree->sub_tree[i] = NULL;

  return ptree;
}

void av1_free_ptree_recursive(PARTITION_TREE *ptree) {
  if (ptree == NULL) return;

  for (int i = 0; i < 4; ++i) {
    av1_free_ptree_recursive(ptree->sub_tree[i]);
    ptree->sub_tree[i] = NULL;
  }

  aom_free(ptree);
}

void av1_reset_ptree_in_sbi(SB_INFO *sbi, TREE_TYPE tree_type) {
  const int idx = av1_get_sdp_idx(tree_type);
  if (sbi->ptree_root[idx]) av1_free_ptree_recursive(sbi->ptree_root[idx]);

  sbi->ptree_root[idx] = av1_alloc_ptree_node(NULL, 0);
}

void av1_set_entropy_contexts(const MACROBLOCKD *xd,
                              struct macroblockd_plane *pd, int plane,
                              BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                              int has_eob, int aoff, int loff) {
  ENTROPY_CONTEXT *const a = pd->above_entropy_context + aoff;
  ENTROPY_CONTEXT *const l = pd->left_entropy_context + loff;
  const int txs_wide = tx_size_wide_unit[tx_size];
  const int txs_high = tx_size_high_unit[tx_size];

  // above
  if (has_eob && xd->mb_to_right_edge < 0) {
    const int blocks_wide = max_block_wide(xd, plane_bsize, plane);
    const int above_contexts = AOMMIN(txs_wide, blocks_wide - aoff);
    memset(a, has_eob, sizeof(*a) * above_contexts);
    memset(a + above_contexts, 0, sizeof(*a) * (txs_wide - above_contexts));
  } else {
    memset(a, has_eob, sizeof(*a) * txs_wide);
  }

  // left
  if (has_eob && xd->mb_to_bottom_edge < 0) {
    const int blocks_high = max_block_high(xd, plane_bsize, plane);
    const int left_contexts = AOMMIN(txs_high, blocks_high - loff);
    memset(l, has_eob, sizeof(*l) * left_contexts);
    memset(l + left_contexts, 0, sizeof(*l) * (txs_high - left_contexts));
  } else {
    memset(l, has_eob, sizeof(*l) * txs_high);
  }
}

void av1_reset_entropy_context(MACROBLOCKD *xd, BLOCK_SIZE bsize,
                               const int num_planes) {
  // TODO(chiyotsai): This part is needed to avoid encoder/decoder mismatch.
  // Investigate why this is the case. It seems like on the decoder side, the
  // decoder is failing to clear the context after encoding a skip_txfm chroma
  // block.
  const int plane_start = (xd->tree_type == CHROMA_PART);
  int plane_end = 0;
  switch (xd->tree_type) {
    case LUMA_PART: plane_end = 1; break;
    case CHROMA_PART: plane_end = num_planes; break;
    case SHARED_PART:
      plane_end = 1 + (num_planes - 1) * xd->is_chroma_ref;
      break;
    default: assert(0);
  }
  for (int i = plane_start; i < plane_end; ++i) {
    struct macroblockd_plane *const pd = &xd->plane[i];
    const BLOCK_SIZE plane_bsize = get_mb_plane_block_size(
        xd, xd->mi[0], i, pd->subsampling_x, pd->subsampling_y);
    (void)bsize;
    const int txs_wide = mi_size_wide[plane_bsize];
    const int txs_high = mi_size_high[plane_bsize];
    memset(pd->above_entropy_context, 0, sizeof(ENTROPY_CONTEXT) * txs_wide);
    memset(pd->left_entropy_context, 0, sizeof(ENTROPY_CONTEXT) * txs_high);
  }
}

void av1_reset_loop_filter_delta(MACROBLOCKD *xd, int num_planes) {
  xd->delta_lf_from_base = 0;
  const int frame_lf_count =
      num_planes > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
  for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) xd->delta_lf[lf_id] = 0;
}

// Resets the LR decoding state before decoding each coded tile and
// associated LR coefficients
void av1_reset_loop_restoration(MACROBLOCKD *xd, int plane_start, int plane_end,
                                const int *num_filter_classes) {
  for (int p = plane_start; p < plane_end; ++p) {
    av1_reset_wiener_bank(&xd->wiener_info[p], p != AOM_PLANE_Y);
    av1_reset_sgrproj_bank(&xd->sgrproj_info[p]);
    av1_reset_wienerns_bank(&xd->wienerns_info[p], xd->current_base_qindex,
                            num_filter_classes[p], p != AOM_PLANE_Y);
  }
}

// Initialize bank
void av1_reset_wiener_bank(WienerInfoBank *bank, int chroma) {
  set_default_wiener(&bank->filter[0], chroma);
  bank->bank_size = 0;
  bank->bank_ptr = 0;
}

// Add a new filter to bank
void av1_add_to_wiener_bank(WienerInfoBank *bank, const WienerInfo *info) {
  if (bank->bank_size < LR_BANK_SIZE) {
    bank->bank_ptr = bank->bank_size;
    memcpy(&bank->filter[bank->bank_ptr], info, sizeof(*info));
    bank->bank_size++;
  } else {
    bank->bank_ptr = (bank->bank_ptr + 1) % LR_BANK_SIZE;
    memcpy(&bank->filter[bank->bank_ptr], info, sizeof(*info));
  }
}

// Get a reference to a filter given the index
WienerInfo *av1_ref_from_wiener_bank(WienerInfoBank *bank, int ndx) {
  if (bank->bank_size == 0) {
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size);
    const int ptr =
        bank->bank_ptr - ndx + (bank->bank_ptr < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Get a const reference to a filter given the index
const WienerInfo *av1_constref_from_wiener_bank(const WienerInfoBank *bank,
                                                int ndx) {
  if (bank->bank_size == 0) {
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size);
    const int ptr =
        bank->bank_ptr - ndx + (bank->bank_ptr < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Directly replace a filter in the bank at given index
void av1_upd_to_wiener_bank(WienerInfoBank *bank, int ndx,
                            const WienerInfo *info) {
  memcpy(av1_ref_from_wiener_bank(bank, ndx), info, sizeof(*info));
}

// Initialize bank
void av1_reset_sgrproj_bank(SgrprojInfoBank *bank) {
  set_default_sgrproj(&bank->filter[0]);
  bank->bank_size = 0;
  bank->bank_ptr = 0;
}

// Add a new filter to bank
void av1_add_to_sgrproj_bank(SgrprojInfoBank *bank, const SgrprojInfo *info) {
  if (bank->bank_size < LR_BANK_SIZE) {
    bank->bank_ptr = bank->bank_size;
    memcpy(&bank->filter[bank->bank_ptr], info, sizeof(*info));
    bank->bank_size++;
  } else {
    bank->bank_ptr = (bank->bank_ptr + 1) % LR_BANK_SIZE;
    memcpy(&bank->filter[bank->bank_ptr], info, sizeof(*info));
  }
}

// Get a reference to a filter given the index
SgrprojInfo *av1_ref_from_sgrproj_bank(SgrprojInfoBank *bank, int ndx) {
  if (bank->bank_size == 0) {
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size);
    const int ptr =
        bank->bank_ptr - ndx + (bank->bank_ptr < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Get a const reference to a filter given the index
const SgrprojInfo *av1_constref_from_sgrproj_bank(const SgrprojInfoBank *bank,
                                                  int ndx) {
  if (bank->bank_size == 0) {
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size);
    const int ptr =
        bank->bank_ptr - ndx + (bank->bank_ptr < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Directly replace a filter in the bank at given index
void av1_upd_to_sgrproj_bank(SgrprojInfoBank *bank, int ndx,
                             const SgrprojInfo *info) {
  memcpy(av1_ref_from_sgrproj_bank(bank, ndx), info, sizeof(*info));
}

// Initialize bank
void av1_reset_wienerns_bank(WienerNonsepInfoBank *bank, int qindex,
                             int num_classes, int chroma) {
  for (int i = 0; i < LR_BANK_SIZE; ++i) {
    set_default_wienerns(&bank->filter[i], qindex, num_classes, chroma);
  }

  for (int c_id = 0; c_id < num_classes; ++c_id) {
    bank->bank_size_for_class[c_id] = 0;
    bank->bank_ptr_for_class[c_id] = 0;
  }
}

// Add a new filter to bank
void av1_add_to_wienerns_bank(WienerNonsepInfoBank *bank,
                              const WienerNonsepInfo *info,
                              int wiener_class_id) {
  int c_id_begin = wiener_class_id;
  int c_id_end = wiener_class_id + 1;
  if (wiener_class_id == ALL_WIENERNS_CLASSES) {
    c_id_begin = 0;
    c_id_end = info->num_classes;
  }
  for (int c_id = c_id_begin; c_id < c_id_end; ++c_id) {
    if (bank->bank_size_for_class[c_id] < LR_BANK_SIZE) {
      bank->bank_ptr_for_class[c_id] = bank->bank_size_for_class[c_id];
      bank->bank_size_for_class[c_id]++;
    } else {
      bank->bank_ptr_for_class[c_id] =
          (bank->bank_ptr_for_class[c_id] + 1) % LR_BANK_SIZE;
    }
    copy_nsfilter_taps_for_class(&bank->filter[bank->bank_ptr_for_class[c_id]],
                                 info, c_id);
  }
}

// Returns the filter that is at slot ndx from last. When ndx is zero the last
// filter added is returned. When ndx is one the filter added before the last
// and so on.
WienerNonsepInfo *av1_ref_from_wienerns_bank(WienerNonsepInfoBank *bank,
                                             int ndx, int wiener_class_id) {
  assert(wiener_class_id != ALL_WIENERNS_CLASSES);
  if (bank->bank_size_for_class[wiener_class_id] == 0) {
    assert(ndx == 0);
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size_for_class[wiener_class_id]);
    const int ptr =
        bank->bank_ptr_for_class[wiener_class_id] - ndx +
        (bank->bank_ptr_for_class[wiener_class_id] < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Get a const reference to a filter given the index
const WienerNonsepInfo *av1_constref_from_wienerns_bank(
    const WienerNonsepInfoBank *bank, int ndx, int wiener_class_id) {
  assert(wiener_class_id != ALL_WIENERNS_CLASSES);
  if (bank->bank_size_for_class[wiener_class_id] == 0) {
    return &bank->filter[0];
  } else {
    assert(ndx < bank->bank_size_for_class[wiener_class_id]);
    const int ptr =
        bank->bank_ptr_for_class[wiener_class_id] - ndx +
        (bank->bank_ptr_for_class[wiener_class_id] < ndx ? LR_BANK_SIZE : 0);
    return &bank->filter[ptr];
  }
}

// Directly replace a filter in the bank at given index
void av1_upd_to_wienerns_bank(WienerNonsepInfoBank *bank, int ndx,
                              const WienerNonsepInfo *info,
                              int wiener_class_id) {
  copy_nsfilter_taps_for_class(
      av1_ref_from_wienerns_bank(bank, ndx, wiener_class_id), info,
      wiener_class_id);
}

int16_t *nsfilter_taps(WienerNonsepInfo *nsinfo, int wiener_class_id) {
  assert(wiener_class_id >= 0 && wiener_class_id < nsinfo->num_classes);
  return nsinfo->allfiltertaps + wiener_class_id * WIENERNS_TAPS_MAX;
}

const int16_t *const_nsfilter_taps(const WienerNonsepInfo *nsinfo,
                                   int wiener_class_id) {
  assert(wiener_class_id >= 0 && wiener_class_id < nsinfo->num_classes);
  return nsinfo->allfiltertaps + wiener_class_id * WIENERNS_TAPS_MAX;
}

void copy_nsfilter_taps_for_class(WienerNonsepInfo *to_info,
                                  const WienerNonsepInfo *from_info,
                                  int wiener_class_id) {
  assert(wiener_class_id >= 0 && wiener_class_id < to_info->num_classes);
  assert(wiener_class_id >= 0 && wiener_class_id < from_info->num_classes);
  const int offset = wiener_class_id * WIENERNS_TAPS_MAX;
  memcpy(to_info->allfiltertaps + offset, from_info->allfiltertaps + offset,
         WIENERNS_TAPS_MAX * sizeof(*to_info->allfiltertaps));
  to_info->bank_ref_for_class[wiener_class_id] =
      from_info->bank_ref_for_class[wiener_class_id];
}

void copy_nsfilter_taps(WienerNonsepInfo *to_info,
                        const WienerNonsepInfo *from_info) {
  assert(to_info->num_classes == from_info->num_classes);
  memcpy(to_info->allfiltertaps, from_info->allfiltertaps,
         sizeof(to_info->allfiltertaps));
  memcpy(to_info->bank_ref_for_class, from_info->bank_ref_for_class,
         sizeof(to_info->bank_ref_for_class));
}

void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y,
                            const int num_planes) {
  int i;

  for (i = 0; i < num_planes; i++) {
    xd->plane[i].plane_type = get_plane_type(i);
    xd->plane[i].subsampling_x = i ? ss_x : 0;
    xd->plane[i].subsampling_y = i ? ss_y : 0;
  }
  for (i = num_planes; i < MAX_MB_PLANE; i++) {
    xd->plane[i].subsampling_x = 1;
    xd->plane[i].subsampling_y = 1;
  }
}

#if CONFIG_COMBINE_PC_NS_WIENER

int max_dictionary_size(int nopcw) {
  const int max_num_predictors =
      num_dictionary_slots(WIENERNS_MAX_CLASSES, nopcw);
  return max_num_predictors * MAX_NUM_DICTIONARY_TAPS;
}

void allocate_frame_filter_dictionary(AV1_COMMON *cm) {
  // Use max_dictionary_size(0) below instead of max_dictionary_size(nopcw)
  // to always allocate for the largest possible dictionary size.
  // If nopcw is solely based on sequence level parameters, this
  // should not be strictly necessary, since reallocation should
  // happen with every new sequence parameter set. However the current
  // reference decoder does not appear to reallocate when the sequence
  // level parameters change. Hence this change is needed.
  const int nopcw = disable_pcwiener_filters_in_framefilters(&cm->seq_params);
  (void)nopcw;
  cm->frame_filter_dictionary =
      aom_calloc(max_dictionary_size(0), sizeof(*cm->frame_filter_dictionary));
  cm->translated_pcwiener_filters =
      aom_calloc(NUM_PC_WIENER_FILTERS * MAX_NUM_DICTIONARY_TAPS,
                 sizeof(*cm->translated_pcwiener_filters));
  cm->translation_done = 0;
  cm->frame_filter_dictionary_stride = MAX_NUM_DICTIONARY_TAPS;
  cm->num_ref_filters = aom_calloc(1, sizeof(*cm->num_ref_filters));
}

void free_frame_filter_dictionary(AV1_COMMON *cm) {
  aom_free(cm->frame_filter_dictionary);
  aom_free(cm->translated_pcwiener_filters);
  aom_free(cm->num_ref_filters);
  cm->frame_filter_dictionary = NULL;
  cm->translated_pcwiener_filters = NULL;
  cm->num_ref_filters = NULL;
  cm->translation_done = 0;
  cm->frame_filter_dictionary_stride = 0;
}

// TODO: Refactor so that this gets called only once during encoding/decoding.
// Useful when using pre-trained filters (with different config and precision)
// to predict transmitetd filters to reduce side-information.
void translate_pcwiener_filters_to_wienerns(AV1_COMMON *cm) {
  if (cm->translation_done) {
    return;
  }
  const int base_qindex = cm->quant_params.base_qindex;
  const int is_uv = 0;
  const WienernsFilterParameters *nsfilter_params =
      get_wienerns_parameters(base_qindex, is_uv);
  assert(nsfilter_params->ncoeffs <= MAX_NUM_DICTIONARY_TAPS);
  const int num_feat = nsfilter_params->ncoeffs;

  /* Assuming the pc-wiener tap configuration is the same as the
   * simd tap configuration, the translation below can be deprecated.
   * int tap_translator[WIENERNS_TAPS_MAX];
   * const int num_taps = wienerns_to_pcwiener_tap_config_translator(
   *     &nsfilter_params->nsfilter_config, tap_translator, WIENERNS_TAPS_MAX);
   * (void)num_taps;
   * assert(num_taps == num_feat);
   */
  const int set_index = 0;  // get_filter_set_index(base_qindex, qindex_offset);

  const int num_pc_wiener_filters = NUM_PC_WIENER_FILTERS;
  const int(*wienerns_coeffs)[WIENERNS_COEFCFG_LEN] = nsfilter_params->coeffs;
  const int16_t(*pcwiener_filters_luma)[NUM_PC_WIENER_TAPS_LUMA] =
      get_filter_set(set_index);
  const int precision_diff =
      PC_WIENER_PREC_FILTER - nsfilter_params->nsfilter_config.prec_bits;
  assert(precision_diff >= 0);

  for (int pc_wiener_cnt = 0; pc_wiener_cnt < num_pc_wiener_filters;
       ++pc_wiener_cnt) {
    int filter_index = pc_wiener_cnt;
    const int16_t *pcwiener_filter = pcwiener_filters_luma[filter_index];

    const int dict_index = pc_wiener_cnt;

    assert(cm->translated_pcwiener_filters != NULL);
    for (int i = 0; i < AOMMIN(num_feat, NUM_PC_WIENER_TAPS_LUMA - 1); ++i) {
      const int16_t scaled_tap = ROUND_POWER_OF_TWO_SIGNED(
          pcwiener_filter[i], precision_diff);  // Assuming no translation
      // pcwiener_filter[tap_translator[i]], precision_diff); // deprecated
      cm->translated_pcwiener_filters[dict_index * MAX_NUM_DICTIONARY_TAPS +
                                      i] =
          clip_to_wienerns_range(scaled_tap,
                                 wienerns_coeffs[i][WIENERNS_MIN_ID],
                                 (1 << wienerns_coeffs[i][WIENERNS_BIT_ID]));
    }
  }
  cm->translation_done = 1;
}

static inline int num_sampled_pc_wiener_filters(int plane, int num_ref_filters,
                                                int num_classes, int nopcw) {
  if (plane != AOM_PLANE_Y) return 0;
  if (nopcw) return 0;
  return AOMMIN(
      AOMMAX(max_num_base_filters(num_classes, 0) - num_ref_filters, 0),
      NUM_PC_WIENER_FILTERS);
}

void set_group_counts(int plane, int num_classes, int num_ref_frames,
                      int *group_counts, int nopcw) {
  int total_slots = num_dictionary_slots(num_classes, nopcw);
  (void)total_slots;
  group_counts[0] = num_classes;
  total_slots -= group_counts[0];
  assert(total_slots >= 0);
  group_counts[1] = num_ref_frames;
  total_slots -= group_counts[1];
  assert(total_slots >= 0);
  group_counts[2] =
      num_sampled_pc_wiener_filters(plane, num_ref_frames, num_classes, nopcw);
}

int set_frame_filter_dictionary(int plane, const AV1_COMMON *cm,
                                int num_classes,
                                int16_t *frame_filter_dictionary,
                                int dict_stride) {
  assert(frame_filter_dictionary != NULL);
  assert(dict_stride > 0);
  const int base_qindex = cm->quant_params.base_qindex;
  const int is_uv = plane > 0;
  const WienernsFilterParameters *nsfilter_params =
      get_wienerns_parameters(base_qindex, is_uv);

  const int nopcw = disable_pcwiener_filters_in_framefilters(&cm->seq_params);
  if (!nopcw) assert(nsfilter_params->ncoeffs <= MAX_NUM_DICTIONARY_TAPS);
  const int num_feat = nsfilter_params->ncoeffs;

  memset(frame_filter_dictionary, 0,
         max_dictionary_size(nopcw) * sizeof(*frame_filter_dictionary));
  const int max_predictors = num_dictionary_slots(num_classes, nopcw);

  // Filters prior to ref_filter_offset are all zeros via calloc. --------------
  const int ref_filter_offset = reference_filters_begin(num_classes);
  // ---------------------------------------------------------------------------

  // Copy available reference filters to the dictionary. -----------------------
  int num_ref_filters = 0;
#if CONFIG_TEMP_LR
  const int min_pc_wiener = plane == AOM_PLANE_Y ? (nopcw ? 0 : 16) : 0;
  assert(min_pc_wiener <= NUM_PC_WIENER_FILTERS);
  const int allowed_num_base_filters =
      max_num_base_filters(num_classes, nopcw) - min_pc_wiener;
  assert(allowed_num_base_filters >= 0);
  assert(allowed_num_base_filters < max_predictors);
  const int num_ref_frames =
      (frame_is_intra_only(cm) || cm->features.error_resilient_mode)
          ? 0
          : cm->ref_frames_info.num_total_refs;
  for (int ref_idx = 0; ref_idx < num_ref_frames; ref_idx++) {
    const RefCntBuffer *ref_frame_buf = get_ref_frame_buf(cm, ref_idx);
    if (ref_frame_buf == NULL) {
      assert(0);
      continue;
    }
    int planes_to_check[2] = { plane, -1 };
    int num_planes_to_check = 1;
#if CONFIG_COMBINE_PC_NS_WIENER_ADD
    const int mix_planes = 1;
    if (plane != AOM_PLANE_Y && mix_planes) {
      num_planes_to_check = 2;
      planes_to_check[1] = (plane == AOM_PLANE_U) ? AOM_PLANE_V : AOM_PLANE_U;
    }
#endif  // CONFIG_COMBINE_PC_NS_WIENER_ADD
    for (int chk = 0; chk < num_planes_to_check; ++chk) {
      const int p = planes_to_check[chk];
      RestorationInfo rsi = ref_frame_buf->rst_info[p];
      if (rsi.frame_filters_on) {
        for (int c_id = 0; c_id < rsi.num_filter_classes; ++c_id) {
          if (num_ref_filters >= allowed_num_base_filters) break;

          int16_t *match_filter =
              frame_filter_dictionary +
              (num_ref_filters + ref_filter_offset) * dict_stride;
          const int16_t *wienerns_filter =
              const_nsfilter_taps(&rsi.frame_filters, c_id);
          for (int i = 0; i < num_feat; ++i) {
            match_filter[i] = wienerns_filter[i];
          }
          ++num_ref_filters;
        }
      }
    }
  }
#endif  // CONFIG_TEMP_LR
  // ---------------------------------------------------------------------------

  // Sample from the pc-wiener filters for the remaining allowed slots. --------
  const int shuffled_index[] = { 16, 7,  58, 21, 12, 61, 26, 38, 18, 30, 50,
                                 45, 23, 49, 43, 62, 42, 54, 27, 36, 17, 44,
                                 32, 34, 4,  24, 52, 31, 37, 11, 33, 19, 35,
                                 6,  22, 53, 63, 25, 41, 47, 1,  59, 0,  28,
                                 40, 55, 48, 8,  5,  51, 9,  46, 56, 60, 15,
                                 2,  13, 14, 57, 29, 3,  20, 39, 10 };
  const int num_pc_wiener_filters =
      num_sampled_pc_wiener_filters(plane, num_ref_filters, num_classes, nopcw);
  assert(num_pc_wiener_filters >= 0 &&
         num_pc_wiener_filters <= NUM_PC_WIENER_FILTERS);

  assert(cm->translated_pcwiener_filters != NULL);
  assert(cm->translation_done);
  for (int pc_wiener_cnt = 0; pc_wiener_cnt < num_pc_wiener_filters;
       ++pc_wiener_cnt) {
    int filter_index = shuffled_index[pc_wiener_cnt];
    assert(filter_index < NUM_PC_WIENER_FILTERS);
    if (filter_index >= NUM_PC_WIENER_FILTERS) {
      filter_index = NUM_PC_WIENER_FILTERS - 1;
    }

    const int16_t *pcwiener_filter = cm->translated_pcwiener_filters +
                                     filter_index * MAX_NUM_DICTIONARY_TAPS;

    const int dict_index = ref_filter_offset + num_ref_filters + pc_wiener_cnt;
    assert(dict_index < max_predictors);
    if (dict_index >= max_predictors) {
      break;
    }

    int16_t *match_filter = frame_filter_dictionary + dict_index * dict_stride;
    for (int i = 0; i < num_feat; ++i) {
      match_filter[i] = pcwiener_filter[i];
    }
  }
  // ---------------------------------------------------------------------------

  // One or more match filters are all zeros via calloc. -----------------------
  // ---------------------------------------------------------------------------
  return num_ref_filters;
}

void add_filter_to_dictionary(const WienerNonsepInfo *filter, int class_id,
                              const WienernsFilterParameters *nsfilter_params,
                              int16_t *frame_filter_dictionary, int dict_stride,
                              int nopcw) {
  (void)nopcw;
  assert(frame_filter_dictionary != NULL);
  assert(dict_stride > 0);
  if (class_id == filter->num_classes - 1) return;
  const int filter_index = prev_filters_begin(filter->num_classes) + class_id;
  assert(filter_index < num_dictionary_slots(filter->num_classes, nopcw));
  int16_t *match_filter = frame_filter_dictionary + filter_index * dict_stride;
  const int16_t *wienerns_filter = const_nsfilter_taps(filter, class_id);
  const int num_feat = nsfilter_params->ncoeffs;
  for (int i = 0; i < num_feat; ++i) {
    match_filter[i] = wienerns_filter[i];
  }
}

#endif  // CONFIG_COMBINE_PC_NS_WIENER

void av1_alloc_txk_skip_array(CommonModeInfoParams *mi_params, AV1_COMMON *cm) {
  // Allocate based on the MIN_TX_SIZE, which is a 4x4 block.
  (void)cm;
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    int w = mi_params->mi_cols << MI_SIZE_LOG2;
    int h = mi_params->mi_rows << MI_SIZE_LOG2;
    w = ((w + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    h = ((h + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    int stride = (w + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    int rows = (h + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    mi_params->tx_skip[plane] = aom_calloc(rows * stride, sizeof(uint8_t));
    mi_params->tx_skip_buf_size[plane] = rows * stride;
    mi_params->tx_skip_stride[plane] = stride;
  }
#ifndef NDEBUG
  av1_reset_txk_skip_array(cm);
#endif  // NDEBUG
}

void av1_set_txk_skip_array_stride(CommonModeInfoParams *mi_params,
                                   AV1_COMMON *cm) {
  (void)cm;
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    int w = mi_params->mi_cols << MI_SIZE_LOG2;
    int h = mi_params->mi_rows << MI_SIZE_LOG2;
    w = ((w + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    h = ((h + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    int stride = (w + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    int rows = (h + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    if (rows * stride > (int)mi_params->tx_skip_buf_size[plane]) {
      aom_free(mi_params->tx_skip[plane]);
      mi_params->tx_skip[plane] = aom_calloc(rows * stride, sizeof(uint8_t));
      mi_params->tx_skip_buf_size[plane] = rows * stride;
    }
    mi_params->tx_skip_stride[plane] = stride;
  }
}

void av1_dealloc_txk_skip_array(CommonModeInfoParams *mi_params) {
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    aom_free(mi_params->tx_skip[plane]);
    mi_params->tx_skip[plane] = NULL;
  }
}

void av1_reset_txk_skip_array(AV1_COMMON *cm) {
  // Allocate based on the MIN_TX_SIZE, which is a 4x4 block.
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    int h = cm->mi_params.mi_rows << MI_SIZE_LOG2;
    h = ((h + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    h >>= ((plane == 0) ? 0 : cm->seq_params.subsampling_y);
    int stride = cm->mi_params.tx_skip_stride[plane];
    int rows = (h + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    memset(cm->mi_params.tx_skip[plane], ILLEGAL_TXK_SKIP_VALUE, rows * stride);
  }
}

void av1_reset_txk_skip_array_using_mi_params(CommonModeInfoParams *mi_params) {
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    memset(mi_params->tx_skip[plane], ILLEGAL_TXK_SKIP_VALUE,
           mi_params->tx_skip_buf_size[plane]);
  }
}

void av1_init_txk_skip_array(const AV1_COMMON *cm, int mi_row, int mi_col,
                             BLOCK_SIZE bsize, uint8_t value,
                             TREE_TYPE tree_type,
                             const CHROMA_REF_INFO *chroma_ref_info,
                             int plane_start, int plane_end) {
  const bool is_chroma_ref = chroma_ref_info->is_chroma_ref;
  for (int plane = plane_start; plane < plane_end; plane++) {
    if (plane && !is_chroma_ref) {
      break;
    }
    const int plane_mi_row =
        plane ? chroma_ref_info->mi_row_chroma_base : mi_row;
    const int plane_mi_col =
        plane ? chroma_ref_info->mi_col_chroma_base : mi_col;
    const BLOCK_SIZE bsize_base = (tree_type == SHARED_PART && plane)
                                      ? chroma_ref_info->bsize_base
                                      : bsize;
    int stride = cm->mi_params.tx_skip_stride[plane];
    int x = (plane_mi_col << MI_SIZE_LOG2) >>
            ((plane == 0) ? 0 : cm->seq_params.subsampling_x);
    int y = (plane_mi_row << MI_SIZE_LOG2) >>
            ((plane == 0) ? 0 : cm->seq_params.subsampling_y);
    int row = y >> MIN_TX_SIZE_LOG2;
    int col = x >> MIN_TX_SIZE_LOG2;
    int blk_w = block_size_wide[bsize_base] >>
                ((plane == 0) ? 0 : cm->seq_params.subsampling_x);
    int blk_h = block_size_high[bsize_base] >>
                ((plane == 0) ? 0 : cm->seq_params.subsampling_y);
    blk_w >>= MIN_TX_SIZE_LOG2;
    blk_h >>= MIN_TX_SIZE_LOG2;

    if (plane && (blk_w == 0 || blk_h == 0) && is_chroma_ref) {
      blk_w = blk_w == 0 ? 1 : blk_w;
      blk_h = blk_h == 0 ? 1 : blk_h;
    }

    for (int r = 0; r < blk_h; r++) {
      for (int c = 0; c < blk_w; c++) {
        uint32_t idx = (row + r) * stride + col + c;
        assert(idx < cm->mi_params.tx_skip_buf_size[plane]);
        cm->mi_params.tx_skip[plane][idx] = value;
      }
    }
  }
}

void av1_update_txk_skip_array(const AV1_COMMON *cm, int mi_row, int mi_col,
                               TREE_TYPE tree_type,
                               const CHROMA_REF_INFO *chroma_ref_info,
                               int plane, int blk_row, int blk_col,
                               TX_SIZE tx_size) {
  blk_row *= 4;
  blk_col *= 4;
  mi_row = (tree_type == SHARED_PART && plane)
               ? chroma_ref_info->mi_row_chroma_base
               : mi_row;
  mi_col = (tree_type == SHARED_PART && plane)
               ? chroma_ref_info->mi_col_chroma_base
               : mi_col;
  int stride = cm->mi_params.tx_skip_stride[plane];
  int tx_w = tx_size_wide[tx_size];
  int tx_h = tx_size_high[tx_size];
  int cols = tx_w >> MIN_TX_SIZE_LOG2;
  int rows = tx_h >> MIN_TX_SIZE_LOG2;
  int x = (mi_col << MI_SIZE_LOG2) >>
          ((plane == 0) ? 0 : cm->seq_params.subsampling_x);
  int y = (mi_row << MI_SIZE_LOG2) >>
          ((plane == 0) ? 0 : cm->seq_params.subsampling_y);
  x = (x + blk_col) >> MIN_TX_SIZE_LOG2;
  y = (y + blk_row) >> MIN_TX_SIZE_LOG2;
  for (int r = 0; r < rows; r++) {
    for (int c = 0; c < cols; c++) {
      uint32_t idx = (y + r) * stride + x + c;
      assert(idx < cm->mi_params.tx_skip_buf_size[plane]);
      cm->mi_params.tx_skip[plane][idx] = 1;
    }
  }
}

uint8_t av1_get_txk_skip(const AV1_COMMON *cm, int mi_row, int mi_col,
                         int plane, int blk_row, int blk_col) {
  blk_row *= 4;
  blk_col *= 4;
  int stride = cm->mi_params.tx_skip_stride[plane];
  int x = (mi_col << MI_SIZE_LOG2) >>
          ((plane == 0) ? 0 : cm->seq_params.subsampling_x);
  int y = (mi_row << MI_SIZE_LOG2) >>
          ((plane == 0) ? 0 : cm->seq_params.subsampling_y);
  x = (x + blk_col) >> MIN_TX_SIZE_LOG2;
  y = (y + blk_row) >> MIN_TX_SIZE_LOG2;
  uint32_t idx = y * stride + x;
  assert(idx < cm->mi_params.tx_skip_buf_size[plane]);
  assert(cm->mi_params.tx_skip[plane][idx] != ILLEGAL_TXK_SKIP_VALUE);
  return cm->mi_params.tx_skip[plane][idx];
}

void av1_alloc_class_id_array(CommonModeInfoParams *mi_params, AV1_COMMON *cm
#if !CONFIG_ENABLE_SR
                              ,
                              int height
#endif  // !CONFIG_ENABLE_SR
) {
  (void)cm;
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
#if CONFIG_ENABLE_SR
    // Allocate for the maximum possible value of cm->superres_upscaled_width,
    // which is the coded frame width * 2, instead of just
    // cm->superres_upscaled_width
    int w = (mi_params->mi_cols << MI_SIZE_LOG2) * 2;
    int h = cm->superres_upscaled_height;
#else
    int w = (mi_params->mi_cols << MI_SIZE_LOG2);
    int h = height;
#endif  // CONFIG_ENABLE_SR
    w = ((w + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    h = ((h + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    int stride = (w + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    int rows = (h + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    mi_params->wiener_class_id[plane] =
        aom_calloc(rows * stride, sizeof(uint8_t));
    mi_params->wiener_class_id_buf_size[plane] = rows * stride;
    mi_params->wiener_class_id_stride[plane] = stride;
  }
}

void av1_set_class_id_array_stride(CommonModeInfoParams *mi_params,
                                   AV1_COMMON *cm
#if !CONFIG_ENABLE_SR
                                   ,
                                   int height
#endif  // !CONFIG_ENABLE_SR
) {
  (void)cm;
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
#if CONFIG_ENABLE_SR
    // Allocate for the maximum possible value of cm->superres_upscaled_width,
    // which is the coded frame width * 2, instead of just
    // cm->superres_upscaled_width
    int w = (mi_params->mi_cols << MI_SIZE_LOG2) * 2;
    int h = cm->superres_upscaled_height;
#else
    int w = (mi_params->mi_cols << MI_SIZE_LOG2);
    int h = height;
#endif  // CONFIG_ENABLE_SR
    w = ((w + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    h = ((h + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2;
    int stride = (w + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    int rows = (h + MIN_TX_SIZE - 1) >> MIN_TX_SIZE_LOG2;
    if (rows * stride > (int)mi_params->wiener_class_id_buf_size[plane]) {
      aom_free(mi_params->wiener_class_id[plane]);
      mi_params->wiener_class_id[plane] =
          aom_calloc(rows * stride, sizeof(uint8_t));
      mi_params->wiener_class_id_buf_size[plane] = rows * stride;
    }
    mi_params->wiener_class_id_stride[plane] = stride;
  }
}

void av1_dealloc_class_id_array(CommonModeInfoParams *mi_params) {
  for (int plane = 0; plane < MAX_MB_PLANE; plane++) {
    aom_free(mi_params->wiener_class_id[plane]);
    mi_params->wiener_class_id[plane] = NULL;
  }
}
