/*
 * 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_rtcd.h"
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "av1/common/daala_tx.h"
#include "av1/encoder/daala_fwd_txfm.h"

#if CONFIG_DAALA_TX

// Complete Daala TX map, sans lossless which is special cased
typedef void (*daala_ftx)(od_coeff[], const od_coeff *, int);

static daala_ftx tx_map[TX_SIZES][TX_TYPES_1D] = {
  //  4-point transforms
  { od_bin_fdct4, od_bin_fdst4, od_bin_fdst4, od_bin_fidtx4 },

  //  8-point transforms
  { od_bin_fdct8, od_bin_fdst8, od_bin_fdst8, od_bin_fidtx8 },

  //  16-point transforms
  { od_bin_fdct16, od_bin_fdst16, od_bin_fdst16, od_bin_fidtx16 },

  //  32-point transforms
  { od_bin_fdct32, od_bin_fdst32, od_bin_fdst32, od_bin_fidtx32 },

#if CONFIG_TX64X64
  //  64-point transforms
  { od_bin_fdct64, NULL, NULL, od_bin_fidtx64 },
#endif
};

static int tx_flip(TX_TYPE_1D t) { return t == 2; }

// Daala TX toplevel entry point, same interface as av1 low-bidepth
// and high-bitdepth TX (av1_fwd_txfm and av1_highbd_fwd_txfm).  This
// same function is intended for both low and high bitdepth cases with
// a tran_low_t of 32 bits (matching od_coeff).
void daala_fwd_txfm(const int16_t *input_pixels, tran_low_t *output_coeffs,
                    int input_stride, TxfmParam *txfm_param) {
  const TX_SIZE tx_size = txfm_param->tx_size;
  const TX_TYPE tx_type = txfm_param->tx_type;
  assert(tx_size <= TX_SIZES_ALL);
  assert(tx_type <= TX_TYPES);

  if (txfm_param->lossless) {
    // Transform function special-cased for lossless
    assert(tx_type == DCT_DCT);
    assert(tx_size == TX_4X4);
    av1_fwht4x4(input_pixels, output_coeffs, input_stride);
  } else {
    // General TX case
    const int upshift = TX_COEFF_DEPTH - txfm_param->bd;
    assert(upshift >= 0);
    assert(sizeof(tran_low_t) == sizeof(od_coeff));
    assert(sizeof(tran_low_t) >= 4);

    // Hook into existing map translation infrastructure to select
    // appropriate TX functions
    const int cols = tx_size_wide[tx_size];
    const int rows = tx_size_high[tx_size];
    const TX_SIZE col_idx = txsize_vert_map[tx_size];
    const TX_SIZE row_idx = txsize_horz_map[tx_size];
    assert(col_idx <= TX_SIZES);
    assert(row_idx <= TX_SIZES);
    assert(vtx_tab[tx_type] <= (int)TX_TYPES_1D);
    assert(htx_tab[tx_type] <= (int)TX_TYPES_1D);
    daala_ftx col_tx = tx_map[col_idx][vtx_tab[tx_type]];
    daala_ftx row_tx = tx_map[row_idx][htx_tab[tx_type]];
    int col_flip = tx_flip(vtx_tab[tx_type]);
    int row_flip = tx_flip(htx_tab[tx_type]);
    od_coeff tmp[MAX_TX_SIZE];
    int r;
    int c;

    assert(col_tx);
    assert(row_tx);

    // Transform columns
    for (c = 0; c < cols; ++c) {
      // Cast and shift
      for (r = 0; r < rows; ++r)
        tmp[r] =
            ((od_coeff)(input_pixels[r * input_stride + c])) * (1 << upshift);
      if (col_flip)
        col_tx(tmp, tmp + (rows - 1), -1);
      else
        col_tx(tmp, tmp, 1);
      // No ystride in daala_tx lowlevel functions, store output vector
      // into column the long way
      for (r = 0; r < rows; ++r) output_coeffs[r * cols + c] = tmp[r];
    }

    // Transform rows
    for (r = 0; r < rows; ++r) {
      if (row_flip)
        row_tx(output_coeffs + r * cols, output_coeffs + r * cols + cols - 1,
               -1);
      else
        row_tx(output_coeffs + r * cols, output_coeffs + r * cols, 1);
    }
#if CONFIG_TX64X64
    // Re-pack coeffs in the first 32x32 indices.
    if (cols > 32) {
      int avail_rows;
      int avail_cols;
      avail_rows = AOMMIN(rows, 32);
      avail_cols = AOMMIN(cols, 32);
      for (r = 1; r < avail_rows; r++) {
        memmove(output_coeffs + r * avail_cols, output_coeffs + r * cols,
                avail_cols * sizeof(*output_coeffs));
      }
    }
#endif
  }
}

#endif
