/*
 * Copyright (c) 2016, 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 <stdbool.h>

#include "av1/common/av1_common_int.h"
#include "av1/common/resize.h"
#include "av1/common/tile_common.h"
#include "aom_dsp/aom_dsp_common.h"

void av1_tile_init(TileInfo *tile, const AV1_COMMON *cm, int row, int col) {
  av1_tile_set_row(tile, cm, row);
  av1_tile_set_col(tile, cm, col);
}

// Find smallest k>=0 such that (blk_size << k) >= target
static int tile_log2(int blk_size, int target) {
  int k;
  for (k = 0; (blk_size << k) < target; k++) {
  }
  return k;
}

void av1_get_tile_limits(AV1_COMMON *const cm) {
  const SequenceHeader *const seq_params = cm->seq_params;
  CommonTileParams *const tiles = &cm->tiles;
  const int sb_cols =
      CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, seq_params->mib_size_log2);
  const int sb_rows =
      CEIL_POWER_OF_TWO(cm->mi_params.mi_rows, seq_params->mib_size_log2);

  const int sb_size_log2 = seq_params->mib_size_log2 + MI_SIZE_LOG2;
  tiles->max_width_sb = MAX_TILE_WIDTH >> sb_size_log2;

  bool use_level_7_above = false;
  for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) {
    if ((seq_params->seq_level_idx[i] >= SEQ_LEVEL_7_0 &&
         seq_params->seq_level_idx[i] <= SEQ_LEVEL_8_3) ||
        seq_params->seq_level_idx[i] == SEQ_LEVEL_MAX) {
      // Currently it is assumed that levels >= 7.0 are either used for all
      // operating points, or none of them.
      if (i != 0 && !use_level_7_above) {
        aom_internal_error(
            cm->error, AOM_CODEC_UNSUP_BITSTREAM,
            "The levels of the operating points should be either all smaller "
            "than 7.0 or all larger than or equal to 7.0");
      }
      use_level_7_above = true;
    }
  }
  const int max_tile_area_sb =
      (use_level_7_above ? MAX_TILE_AREA_LEVEL_7_AND_ABOVE : MAX_TILE_AREA) >>
      (2 * sb_size_log2);

  tiles->min_log2_cols = tile_log2(tiles->max_width_sb, sb_cols);
  tiles->max_log2_cols = tile_log2(1, AOMMIN(sb_cols, MAX_TILE_COLS));
  tiles->max_log2_rows = tile_log2(1, AOMMIN(sb_rows, MAX_TILE_ROWS));
  tiles->min_log2 = tile_log2(max_tile_area_sb, sb_cols * sb_rows);
  tiles->min_log2 = AOMMAX(tiles->min_log2, tiles->min_log2_cols);
}

void av1_calculate_tile_cols(const SequenceHeader *const seq_params,
                             int cm_mi_rows, int cm_mi_cols,
                             CommonTileParams *const tiles) {
  int sb_cols = CEIL_POWER_OF_TWO(cm_mi_cols, seq_params->mib_size_log2);
  int sb_rows = CEIL_POWER_OF_TWO(cm_mi_rows, seq_params->mib_size_log2);
  int i;

  // This will be overridden if there is at least two columns of tiles
  // (otherwise there is no inner tile width)
  tiles->min_inner_width = -1;

  if (tiles->uniform_spacing) {
    int start_sb;
    int size_sb = CEIL_POWER_OF_TWO(sb_cols, tiles->log2_cols);
    assert(size_sb > 0);
    for (i = 0, start_sb = 0; start_sb < sb_cols; i++) {
      tiles->col_start_sb[i] = start_sb;
      start_sb += size_sb;
    }
    tiles->cols = i;
    tiles->col_start_sb[i] = sb_cols;
    tiles->min_log2_rows = AOMMAX(tiles->min_log2 - tiles->log2_cols, 0);
    tiles->max_height_sb = sb_rows >> tiles->min_log2_rows;

    tiles->width = size_sb << seq_params->mib_size_log2;
    tiles->width = AOMMIN(tiles->width, cm_mi_cols);
    if (tiles->cols > 1) {
      tiles->min_inner_width = tiles->width;
    }
  } else {
    int max_tile_area_sb = (sb_rows * sb_cols);
    int widest_tile_sb = 1;
    int narrowest_inner_tile_sb = 65536;
    tiles->log2_cols = tile_log2(1, tiles->cols);
    for (i = 0; i < tiles->cols; i++) {
      int size_sb = tiles->col_start_sb[i + 1] - tiles->col_start_sb[i];
      widest_tile_sb = AOMMAX(widest_tile_sb, size_sb);
      // ignore the rightmost tile in frame for determining the narrowest
      if (i < tiles->cols - 1)
        narrowest_inner_tile_sb = AOMMIN(narrowest_inner_tile_sb, size_sb);
    }
    if (tiles->min_log2) {
      max_tile_area_sb >>= (tiles->min_log2 + 1);
    }
    tiles->max_height_sb = AOMMAX(max_tile_area_sb / widest_tile_sb, 1);
    if (tiles->cols > 1) {
      tiles->min_inner_width = narrowest_inner_tile_sb
                               << seq_params->mib_size_log2;
    }
  }
}

void av1_calculate_tile_rows(const SequenceHeader *const seq_params,
                             int cm_mi_rows, CommonTileParams *const tiles) {
  int sb_rows = CEIL_POWER_OF_TWO(cm_mi_rows, seq_params->mib_size_log2);
  int start_sb, size_sb, i;

  if (tiles->uniform_spacing) {
    size_sb = CEIL_POWER_OF_TWO(sb_rows, tiles->log2_rows);
    assert(size_sb > 0);
    for (i = 0, start_sb = 0; start_sb < sb_rows; i++) {
      tiles->row_start_sb[i] = start_sb;
      start_sb += size_sb;
    }
    tiles->rows = i;
    tiles->row_start_sb[i] = sb_rows;

    tiles->height = size_sb << seq_params->mib_size_log2;
    tiles->height = AOMMIN(tiles->height, cm_mi_rows);
  } else {
    tiles->log2_rows = tile_log2(1, tiles->rows);
  }
}

void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) {
  assert(row < cm->tiles.rows);
  int mi_row_start = cm->tiles.row_start_sb[row]
                     << cm->seq_params->mib_size_log2;
  int mi_row_end = cm->tiles.row_start_sb[row + 1]
                   << cm->seq_params->mib_size_log2;
  tile->tile_row = row;
  tile->mi_row_start = mi_row_start;
  tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_params.mi_rows);
  assert(tile->mi_row_end > tile->mi_row_start);
}

void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) {
  assert(col < cm->tiles.cols);
  int mi_col_start = cm->tiles.col_start_sb[col]
                     << cm->seq_params->mib_size_log2;
  int mi_col_end = cm->tiles.col_start_sb[col + 1]
                   << cm->seq_params->mib_size_log2;
  tile->tile_col = col;
  tile->mi_col_start = mi_col_start;
  tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_params.mi_cols);
  assert(tile->mi_col_end > tile->mi_col_start);
}

int av1_get_sb_rows_in_tile(AV1_COMMON *cm, const TileInfo *tile) {
  return CEIL_POWER_OF_TWO(tile->mi_row_end - tile->mi_row_start,
                           cm->seq_params->mib_size_log2);
}

int av1_get_sb_cols_in_tile(AV1_COMMON *cm, const TileInfo *tile) {
  return CEIL_POWER_OF_TWO(tile->mi_col_end - tile->mi_col_start,
                           cm->seq_params->mib_size_log2);
}

AV1PixelRect av1_get_tile_rect(const TileInfo *tile_info, const AV1_COMMON *cm,
                               int is_uv) {
  AV1PixelRect r;

  // Calculate position in the Y plane
  r.left = tile_info->mi_col_start * MI_SIZE;
  r.right = tile_info->mi_col_end * MI_SIZE;
  r.top = tile_info->mi_row_start * MI_SIZE;
  r.bottom = tile_info->mi_row_end * MI_SIZE;

  // If upscaling is enabled, the tile limits need scaling to match the
  // upscaled frame where the restoration units live. To do this, scale up the
  // top-left and bottom-right of the tile.
  if (av1_superres_scaled(cm)) {
    av1_calculate_unscaled_superres_size(&r.left, &r.top,
                                         cm->superres_scale_denominator);
    av1_calculate_unscaled_superres_size(&r.right, &r.bottom,
                                         cm->superres_scale_denominator);
  }

  const int frame_w = cm->superres_upscaled_width;
  const int frame_h = cm->superres_upscaled_height;

  // Make sure we don't fall off the bottom-right of the frame.
  r.right = AOMMIN(r.right, frame_w);
  r.bottom = AOMMIN(r.bottom, frame_h);

  // Convert to coordinates in the appropriate plane
  const int ss_x = is_uv && cm->seq_params->subsampling_x;
  const int ss_y = is_uv && cm->seq_params->subsampling_y;

  r.left = ROUND_POWER_OF_TWO(r.left, ss_x);
  r.right = ROUND_POWER_OF_TWO(r.right, ss_x);
  r.top = ROUND_POWER_OF_TWO(r.top, ss_y);
  r.bottom = ROUND_POWER_OF_TWO(r.bottom, ss_y);

  return r;
}

void av1_get_uniform_tile_size(const AV1_COMMON *cm, int *w, int *h) {
  const CommonTileParams *const tiles = &cm->tiles;
  if (tiles->uniform_spacing) {
    *w = tiles->width;
    *h = tiles->height;
  } else {
    for (int i = 0; i < tiles->cols; ++i) {
      const int tile_width_sb =
          tiles->col_start_sb[i + 1] - tiles->col_start_sb[i];
      const int tile_w = tile_width_sb * cm->seq_params->mib_size;
      assert(i == 0 || tile_w == *w);  // ensure all tiles have same dimension
      *w = tile_w;
    }

    for (int i = 0; i < tiles->rows; ++i) {
      const int tile_height_sb =
          tiles->row_start_sb[i + 1] - tiles->row_start_sb[i];
      const int tile_h = tile_height_sb * cm->seq_params->mib_size;
      assert(i == 0 || tile_h == *h);  // ensure all tiles have same dimension
      *h = tile_h;
    }
  }
}

int av1_is_min_tile_width_satisfied(const AV1_COMMON *cm) {
  // Disable check if there is a single tile col in the frame
  if (cm->tiles.cols == 1) return 1;

  return ((cm->tiles.min_inner_width << MI_SIZE_LOG2) >=
          (64 << av1_superres_scaled(cm)));
}
