/*
 * 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 "av1/common/scan.h"
#include "av1/common/idct.h"
#include "av1/common/txb_common.h"
#include "av1/decoder/decodemv.h"
#include "av1/decoder/decodetxb.h"
#include "av1/decoder/dsubexp.h"
#include "av1/decoder/symbolrate.h"

#define ACCT_STR __func__

static int read_golomb(MACROBLOCKD *xd, aom_reader *r, FRAME_COUNTS *counts) {
#if !CONFIG_SYMBOLRATE
  (void)counts;
#endif
  int x = 1;
  int length = 0;
  int i = 0;

  while (!i) {
    i = av1_read_record_bit(counts, r, ACCT_STR);
    ++length;
    if (length >= 32) {
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
                         "Invalid length in read_golomb");
      break;
    }
  }

  for (i = 0; i < length - 1; ++i) {
    x <<= 1;
    x += av1_read_record_bit(counts, r, ACCT_STR);
  }

  return x - 1;
}

static INLINE int rec_eob_pos(int16_t eob_token, int16_t extra) {
  int eob = k_eob_group_start[eob_token];
  if (eob > 2) {
    eob += extra;
  }
  return eob;
}

uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
                            aom_reader *r, int blk_row, int blk_col, int block,
                            int plane, tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
                            TX_SIZE tx_size, int16_t *max_scan_line, int *eob) {
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  FRAME_COUNTS *counts = xd->counts;
  TX_SIZE txs_ctx = get_txsize_context(tx_size);
  PLANE_TYPE plane_type = get_plane_type(plane);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  const int seg_eob = tx_size_2d[tx_size];
  int c = 0;
  int update_eob = -1;
  const int16_t *const dequant = xd->plane[plane].seg_dequant[mbmi->segment_id];
  const int shift = av1_get_tx_scale(tx_size);
  const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2;
  const int height = tx_size_high[tx_size];
  int cul_level = 0;
  uint8_t levels[MAX_TX_SQUARE];
  int8_t signs[MAX_TX_SQUARE];

  memset(tcoeffs, 0, sizeof(*tcoeffs) * seg_eob);

  int all_zero = av1_read_record_bin(
      counts, r, ec_ctx->txb_skip_cdf[txs_ctx][txb_ctx->txb_skip_ctx], 2,
      ACCT_STR);
  if (xd->counts)
    ++xd->counts->txb_skip[txs_ctx][txb_ctx->txb_skip_ctx][all_zero];

  *eob = 0;
  if (all_zero) {
    *max_scan_line = 0;
#if CONFIG_TXK_SEL
    if (plane == 0) mbmi->txk_type[(blk_row << 4) + blk_col] = DCT_DCT;
#endif
    return 0;
  }

  memset(levels, 0, sizeof(levels[0]) * seg_eob);
  memset(signs, 0, sizeof(signs[0]) * seg_eob);

  (void)blk_row;
  (void)blk_col;
#if CONFIG_TXK_SEL
  av1_read_tx_type(cm, xd, blk_row, blk_col, block, plane,
                   get_min_tx_size(tx_size), r);
#endif
  const TX_TYPE tx_type =
      av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
  const int16_t *scan = scan_order->scan;

  unsigned int(*nz_map_count)[SIG_COEF_CONTEXTS][2] =
      (counts) ? &counts->nz_map[txs_ctx][plane_type] : NULL;
  int16_t dummy;
  int16_t max_eob_pt = get_eob_pos_token(seg_eob, &dummy);

  int16_t eob_extra = 0;
  int16_t eob_pt = 0;
  int is_equal = 0;

  for (int i = 1; i < max_eob_pt; i++) {
    int eob_pos_ctx = av1_get_eob_pos_ctx(tx_type, i);
    is_equal = av1_read_record_bin(
        counts, r, ec_ctx->eob_flag_cdf[txs_ctx][plane_type][eob_pos_ctx], 2,
        ACCT_STR);

    // aom_read_symbol(r,
    // ec_ctx->eob_flag_cdf[AOMMIN(txs_ctx,3)][plane_type][eob_pos_ctx], 2,
    // ACCT_STR);
    if (counts) ++counts->eob_flag[txs_ctx][plane_type][eob_pos_ctx][is_equal];

    if (is_equal) {
      eob_pt = i;
      break;
    }
  }
  if (is_equal == 0) {
    eob_pt = max_eob_pt;
  }

  // printf("Dec: ");
  if (k_eob_offset_bits[eob_pt] > 0) {
    int eob_shift = k_eob_offset_bits[eob_pt] - 1;
    int bit = av1_read_record_bin(
        counts, r, ec_ctx->eob_extra_cdf[txs_ctx][plane_type][eob_pt], 2,
        ACCT_STR);
    if (counts) ++counts->eob_extra[txs_ctx][plane_type][eob_pt][bit];
    if (bit) {
      eob_extra += (1 << eob_shift);
    }

    for (int i = 1; i < k_eob_offset_bits[eob_pt]; i++) {
      eob_shift = k_eob_offset_bits[eob_pt] - 1 - i;
      bit = av1_read_record_bit(counts, r, ACCT_STR);
      if (bit) {
        eob_extra += (1 << eob_shift);
      }
      //  printf("%d ", bit);
    }
  }
  *eob = rec_eob_pos(eob_pt, eob_extra);
  // printf("=>[%d, %d], (%d, %d)\n", seg_eob, *eob, eob_pt, eob_extra);

  for (int i = 0; i < *eob; ++i) {
    c = *eob - 1 - i;
    int is_nz;
    int coeff_ctx = get_nz_map_ctx(levels, c, scan, bwl, height, tx_type);

    if (c < *eob - 1) {
      is_nz = av1_read_record_bin(
          counts, r, ec_ctx->nz_map_cdf[txs_ctx][plane_type][coeff_ctx], 2,
          ACCT_STR);
    } else {
      is_nz = 1;
    }

    // set non-zero coefficient map.
    levels[scan[c]] = is_nz;

    if (counts) ++(*nz_map_count)[coeff_ctx][is_nz];

#if USE_CAUSAL_BASE_CTX
    if (is_nz) {
      int k;
      for (k = 0; k < NUM_BASE_LEVELS; ++k) {
        int ctx = coeff_ctx;
        int is_k = av1_read_record_bin(
            counts, r, ec_ctx->coeff_base_cdf[txs_ctx][plane_type][k][ctx], 2,
            ACCT_STR);
        if (counts) ++counts->coeff_base[txs_ctx][plane_type][k][ctx][is_k];

        // semantic: is_k = 1 if level > (k+1)
        if (is_k == 0) {
          cul_level += k + 1;
          break;
        }
      }
      levels[scan[c]] = k + 1;
    }
#endif
  }

  *max_scan_line = *eob;

#if USE_CAUSAL_BASE_CTX
  update_eob = *eob - 1;
#else
  int i;
  for (i = 0; i < NUM_BASE_LEVELS; ++i) {
    update_eob = 0;
    for (c = *eob - 1; c >= 0; --c) {
      uint8_t *const level = &levels[scan[c]];
      int ctx;

      if (*level <= i) continue;

      ctx = get_base_ctx(levels, scan[c], bwl, height, i + 1);

      if (av1_read_record_bin(
              counts, r, ec_ctx->coeff_base_cdf[txs_ctx][plane_type][i][ctx], 2,
              ACCT_STR)) {
        assert(*level == i + 1);
        cul_level += i + 1;

        if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][1];

        continue;
      }
      *level = i + 2;
      if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][0];

      // update the eob flag for coefficients with magnitude above 1.
      update_eob = AOMMAX(update_eob, c);
    }
  }
#endif

  // Loop to decode all signs in the transform block,
  // starting with the sign of the DC (if applicable)
  for (c = 0; c < *eob; ++c) {
    int8_t *const sign = &signs[scan[c]];
    if (levels[scan[c]] == 0) continue;
    if (c == 0) {
      int dc_sign_ctx = txb_ctx->dc_sign_ctx;
#if LV_MAP_PROB
      *sign = av1_read_record_bin(
          counts, r, ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], 2, ACCT_STR);
#else
      *sign = aom_read(r, ec_ctx->dc_sign[plane_type][dc_sign_ctx], ACCT_STR);
#endif
      if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][*sign];
    } else {
      *sign = av1_read_record_bit(counts, r, ACCT_STR);
    }
  }

  for (c = update_eob; c >= 0; --c) {
    uint8_t *const level = &levels[scan[c]];
    int idx;
    int ctx;

    if (*level <= NUM_BASE_LEVELS) continue;

    ctx = get_br_ctx(levels, scan[c], bwl, height);

    for (idx = 0; idx < BASE_RANGE_SETS; ++idx) {
      if (av1_read_record_bin(
              counts, r, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][idx][ctx], 2,
              ACCT_STR)) {
        int extra_bits = (1 << br_extra_bits[idx]) - 1;
        //        int br_offset = aom_read_literal(r, extra_bits, ACCT_STR);
        int br_offset = 0;
        int tok;
        if (counts) ++counts->coeff_br[txs_ctx][plane_type][idx][ctx][1];
        for (tok = 0; tok < extra_bits; ++tok) {
          if (av1_read_record_bin(
                  counts, r, ec_ctx->coeff_lps_cdf[txs_ctx][plane_type][ctx], 2,
                  ACCT_STR)) {
            br_offset = tok;
            if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][1];
            break;
          }
          if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][0];
        }
        if (tok == extra_bits) br_offset = extra_bits;

        int br_base = br_index_to_coeff[idx];

        *level = NUM_BASE_LEVELS + 1 + br_base + br_offset;
        cul_level += *level;
        break;
      }
      if (counts) ++counts->coeff_br[txs_ctx][plane_type][idx][ctx][0];
    }

    if (idx < BASE_RANGE_SETS) continue;

    // decode 0-th order Golomb code
    *level = COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS;
    // Save golomb in tcoeffs because adding it to level may incur overflow
    tcoeffs[scan[c]] = read_golomb(xd, r, counts);
    cul_level += *level + tcoeffs[scan[c]];
  }

  for (c = 0; c < *eob; ++c) {
    const int16_t dqv = (c == 0) ? dequant[0] : dequant[1];
    const int level = levels[scan[c]];
    const tran_low_t t = ((level + tcoeffs[scan[c]]) * dqv) >> shift;
#if CONFIG_SYMBOLRATE
    av1_record_coeff(counts, level);
#endif
    tcoeffs[scan[c]] = signs[scan[c]] ? -t : t;
  }

  cul_level = AOMMIN(63, cul_level);

  // DC value
  set_dc_sign(&cul_level, tcoeffs[0]);

  return cul_level;
}

uint8_t av1_read_coeffs_txb_facade(AV1_COMMON *cm, MACROBLOCKD *xd,
                                   aom_reader *r, int row, int col, int block,
                                   int plane, tran_low_t *tcoeffs,
                                   TX_SIZE tx_size, int16_t *max_scan_line,
                                   int *eob) {
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  struct macroblockd_plane *pd = &xd->plane[plane];

  const BLOCK_SIZE bsize = mbmi->sb_type;
  const BLOCK_SIZE plane_bsize =
      AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));

  TXB_CTX txb_ctx;
  get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + col,
              pd->left_context + row, &txb_ctx);
  uint8_t cul_level =
      av1_read_coeffs_txb(cm, xd, r, row, col, block, plane, tcoeffs, &txb_ctx,
                          tx_size, max_scan_line, eob);
#if CONFIG_ADAPT_SCAN
  PLANE_TYPE plane_type = get_plane_type(plane);
  TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, block, tx_size);
  if (xd->counts && *eob > 0)
    av1_update_scan_count_facade(cm, xd->counts, tx_size, tx_type, pd->dqcoeff,
                                 *eob);
#endif
  av1_set_contexts(xd, pd, plane, tx_size, cul_level, col, row);
  return cul_level;
}
