/*
 * Copyright (c) 2022, 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 "aom_dsp/pyramid.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/bitops.h"
#include "aom_util/aom_thread.h"

// TODO(rachelbarker): Move needed code from av1/ to aom_dsp/
#include "av1/common/resize.h"

#include <assert.h>
#include <string.h>

// Lifecycle:
// * Frame buffer alloc code calls aom_get_pyramid_alloc_size()
//   to work out how much space is needed for a given number of pyramid
//   levels. This is counted in the size checked against the max allocation
//   limit
// * Then calls aom_alloc_pyramid() to actually create the pyramid
// * Pyramid is initially marked as invalid (no data)
// * Whenever pyramid is needed, we check the valid flag. If set, use existing
//   data. If not set, compute full pyramid
// * Whenever frame buffer is reused, clear the valid flag
// * Whenever frame buffer is resized, reallocate pyramid

size_t aom_get_pyramid_alloc_size(int width, int height, int n_levels,
                                  bool image_is_16bit) {
  // Limit number of levels on small frames
  const int msb = get_msb(AOMMIN(width, height));
  const int max_levels = AOMMAX(msb - MIN_PYRAMID_SIZE_LOG2, 1);
  n_levels = AOMMIN(n_levels, max_levels);

  size_t alloc_size = 0;
  alloc_size += sizeof(ImagePyramid);
  alloc_size += n_levels * sizeof(PyramidLayer);

  // Calculate how much memory is needed for downscaled frame buffers
  size_t buffer_size = 0;

  // Work out if we need to allocate a few extra bytes for alignment.
  // aom_memalign() will ensure that the start of the allocation is aligned
  // to a multiple of PYRAMID_ALIGNMENT. But we want the first image pixel
  // to be aligned, not the first byte of the allocation.
  //
  // In the loop below, we ensure that the stride of every image is a multiple
  // of PYRAMID_ALIGNMENT. Thus the allocated size of each pyramid level will
  // also be a multiple of PYRAMID_ALIGNMENT. Thus, as long as we can get the
  // first pixel in the first pyramid layer aligned properly, that will
  // automatically mean that the first pixel of every row of every layer is
  // properly aligned too.
  //
  // Thus all we need to consider is the first pixel in the first layer.
  // This is located at offset
  //   extra_bytes + level_stride * PYRAMID_PADDING + PYRAMID_PADDING
  // bytes into the buffer. Since level_stride is a multiple of
  // PYRAMID_ALIGNMENT, we can ignore that. So we need
  //   extra_bytes + PYRAMID_PADDING = multiple of PYRAMID_ALIGNMENT
  //
  // To solve this, we can round PYRAMID_PADDING up to the next multiple
  // of PYRAMID_ALIGNMENT, then subtract the orginal value to calculate
  // how many extra bytes are needed.
  size_t first_px_offset =
      (PYRAMID_PADDING + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);
  size_t extra_bytes = first_px_offset - PYRAMID_PADDING;
  buffer_size += extra_bytes;

  // If the original image is stored in an 8-bit buffer, then we can point the
  // lowest pyramid level at that buffer rather than allocating a new one.
  int first_allocated_level = image_is_16bit ? 0 : 1;

  for (int level = first_allocated_level; level < n_levels; level++) {
    int level_width = width >> level;
    int level_height = height >> level;

    // Allocate padding for each layer
    int padded_width = level_width + 2 * PYRAMID_PADDING;
    int padded_height = level_height + 2 * PYRAMID_PADDING;

    // Align the layer stride to be a multiple of PYRAMID_ALIGNMENT
    // This ensures that, as long as the top-left pixel in this pyramid level is
    // properly aligned, then so will the leftmost pixel in every row of the
    // pyramid level.
    int level_stride =
        (padded_width + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);

    buffer_size += level_stride * padded_height;
  }

  alloc_size += buffer_size;

  return alloc_size;
}

ImagePyramid *aom_alloc_pyramid(int width, int height, int n_levels,
                                bool image_is_16bit) {
  // Limit number of levels on small frames
  const int msb = get_msb(AOMMIN(width, height));
  const int max_levels = AOMMAX(msb - MIN_PYRAMID_SIZE_LOG2, 1);
  n_levels = AOMMIN(n_levels, max_levels);

  ImagePyramid *pyr = aom_calloc(1, sizeof(*pyr));
  if (!pyr) {
    return NULL;
  }

  pyr->layers = aom_calloc(n_levels, sizeof(PyramidLayer));
  if (!pyr->layers) {
    aom_free(pyr);
    return NULL;
  }

  pyr->valid = false;
  pyr->n_levels = n_levels;

  // Compute sizes and offsets for each pyramid level
  // These are gathered up first, so that we can allocate all pyramid levels
  // in a single buffer
  size_t buffer_size = 0;
  size_t *layer_offsets = aom_calloc(n_levels, sizeof(size_t));
  if (!layer_offsets) {
    aom_free(pyr);
    aom_free(pyr->layers);
    return NULL;
  }

  // Work out if we need to allocate a few extra bytes for alignment.
  // aom_memalign() will ensure that the start of the allocation is aligned
  // to a multiple of PYRAMID_ALIGNMENT. But we want the first image pixel
  // to be aligned, not the first byte of the allocation.
  //
  // In the loop below, we ensure that the stride of every image is a multiple
  // of PYRAMID_ALIGNMENT. Thus the allocated size of each pyramid level will
  // also be a multiple of PYRAMID_ALIGNMENT. Thus, as long as we can get the
  // first pixel in the first pyramid layer aligned properly, that will
  // automatically mean that the first pixel of every row of every layer is
  // properly aligned too.
  //
  // Thus all we need to consider is the first pixel in the first layer.
  // This is located at offset
  //   extra_bytes + level_stride * PYRAMID_PADDING + PYRAMID_PADDING
  // bytes into the buffer. Since level_stride is a multiple of
  // PYRAMID_ALIGNMENT, we can ignore that. So we need
  //   extra_bytes + PYRAMID_PADDING = multiple of PYRAMID_ALIGNMENT
  //
  // To solve this, we can round PYRAMID_PADDING up to the next multiple
  // of PYRAMID_ALIGNMENT, then subtract the orginal value to calculate
  // how many extra bytes are needed.
  size_t first_px_offset =
      (PYRAMID_PADDING + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);
  size_t extra_bytes = first_px_offset - PYRAMID_PADDING;
  buffer_size += extra_bytes;

  // If the original image is stored in an 8-bit buffer, then we can point the
  // lowest pyramid level at that buffer rather than allocating a new one.
  int first_allocated_level = image_is_16bit ? 0 : 1;

  for (int level = first_allocated_level; level < n_levels; level++) {
    PyramidLayer *layer = &pyr->layers[level];

    int level_width = width >> level;
    int level_height = height >> level;

    // Allocate padding for each layer
    int padded_width = level_width + 2 * PYRAMID_PADDING;
    int padded_height = level_height + 2 * PYRAMID_PADDING;

    // Align the layer stride to be a multiple of PYRAMID_ALIGNMENT
    // This ensures that, as long as the top-left pixel in this pyramid level is
    // properly aligned, then so will the leftmost pixel in every row of the
    // pyramid level.
    int level_stride =
        (padded_width + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);

    size_t level_alloc_start = buffer_size;
    size_t level_start =
        level_alloc_start + PYRAMID_PADDING * level_stride + PYRAMID_PADDING;

    buffer_size += level_stride * padded_height;

    layer_offsets[level] = level_start;
    layer->width = level_width;
    layer->height = level_height;
    layer->stride = level_stride;
  }

  pyr->buffer_alloc =
      aom_memalign(PYRAMID_ALIGNMENT, buffer_size * sizeof(*pyr->buffer_alloc));
  if (!pyr->buffer_alloc) {
    aom_free(pyr);
    aom_free(pyr->layers);
    aom_free(layer_offsets);
    return NULL;
  }

  // Fill in pointers for each level
  // If image is 8-bit, then the lowest level is left unconfigured for now,
  // and will be set up properly when the pyramid is filled in
  for (int level = first_allocated_level; level < n_levels; level++) {
    PyramidLayer *layer = &pyr->layers[level];
    layer->buffer = pyr->buffer_alloc + layer_offsets[level];
  }

#if CONFIG_MULTITHREAD
  pthread_mutex_init(&pyr->mutex, NULL);
#endif  // CONFIG_MULTITHREAD

  aom_free(layer_offsets);
  return pyr;
}

// Fill the border region of a pyramid frame.
// This must be called after the main image area is filled out.
// `img_buf` should point to the first pixel in the image area,
// ie. it should be pyr->level_buffer + pyr->level_loc[level].
static INLINE void fill_border(uint8_t *img_buf, const int width,
                               const int height, const int stride) {
  // Fill left and right areas
  for (int row = 0; row < height; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    uint8_t left_pixel = row_start[0];
    memset(row_start - PYRAMID_PADDING, left_pixel, PYRAMID_PADDING);
    uint8_t right_pixel = row_start[width - 1];
    memset(row_start + width, right_pixel, PYRAMID_PADDING);
  }

  // Fill top area
  for (int row = -PYRAMID_PADDING; row < 0; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    memcpy(row_start - PYRAMID_PADDING, img_buf - PYRAMID_PADDING,
           width + 2 * PYRAMID_PADDING);
  }

  // Fill bottom area
  uint8_t *last_row_start = &img_buf[(height - 1) * stride];
  for (int row = height; row < height + PYRAMID_PADDING; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    memcpy(row_start - PYRAMID_PADDING, last_row_start - PYRAMID_PADDING,
           width + 2 * PYRAMID_PADDING);
  }
}

// Compute coarse to fine pyramids for a frame
// This must only be called while holding frm_pyr->mutex
static INLINE void fill_pyramid(const YV12_BUFFER_CONFIG *frm, int bit_depth,
                                ImagePyramid *frm_pyr) {
  int n_levels = frm_pyr->n_levels;
  const int frm_width = frm->y_crop_width;
  const int frm_height = frm->y_crop_height;
  const int frm_stride = frm->y_stride;
  assert((frm_width >> n_levels) >= 0);
  assert((frm_height >> n_levels) >= 0);

  PyramidLayer *first_layer = &frm_pyr->layers[0];
  if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
    // For frames stored in a 16-bit buffer, we need to downconvert to 8 bits
    assert(first_layer->width == frm_width);
    assert(first_layer->height == frm_height);

    uint16_t *frm_buffer = CONVERT_TO_SHORTPTR(frm->y_buffer);
    uint8_t *pyr_buffer = first_layer->buffer;
    int pyr_stride = first_layer->stride;
    for (int y = 0; y < frm_height; y++) {
      uint16_t *frm_row = frm_buffer + y * frm_stride;
      uint8_t *pyr_row = pyr_buffer + y * pyr_stride;
      for (int x = 0; x < frm_width; x++) {
        pyr_row[x] = frm_row[x] >> (bit_depth - 8);
      }
    }

    fill_border(pyr_buffer, frm_width, frm_height, pyr_stride);
  } else {
    // For frames stored in an 8-bit buffer, we need to configure the first
    // pyramid layer to point at the original image buffer
    first_layer->buffer = frm->y_buffer;
    first_layer->width = frm_width;
    first_layer->height = frm_height;
    first_layer->stride = frm_stride;
  }

  // Fill in the remaining levels through progressive downsampling
  for (int level = 1; level < n_levels; ++level) {
    PyramidLayer *prev_layer = &frm_pyr->layers[level - 1];
    uint8_t *prev_buffer = prev_layer->buffer;
    int prev_stride = prev_layer->stride;

    PyramidLayer *this_layer = &frm_pyr->layers[level];
    uint8_t *this_buffer = this_layer->buffer;
    int this_width = this_layer->width;
    int this_height = this_layer->height;
    int this_stride = this_layer->stride;

    // Compute the this pyramid level by downsampling the current level.
    //
    // We downsample by a factor of exactly 2, clipping the rightmost and
    // bottommost pixel off of the current level if needed. We do this for
    // two main reasons:
    //
    // 1) In the disflow code, when stepping from a higher pyramid level to a
    //    lower pyramid level, we need to not just interpolate the flow field
    //    but also to scale each flow vector by the upsampling ratio.
    //    So it is much more convenient if this ratio is simply 2.
    //
    // 2) Up/downsampling by a factor of 2 can be implemented much more
    //    efficiently than up/downsampling by a generic ratio.
    //    TODO(rachelbarker): Use optimized downsample-by-2 function
    av1_resize_plane(prev_buffer, this_height << 1, this_width << 1,
                     prev_stride, this_buffer, this_height, this_width,
                     this_stride);
    fill_border(this_buffer, this_width, this_height, this_stride);
  }
}

// Fill out a downsampling pyramid for a given frame.
//
// The top level (index 0) will always be an 8-bit copy of the input frame,
// regardless of the input bit depth. Additional levels are then downscaled
// by powers of 2.
//
// For small input frames, the number of levels actually constructed
// will be limited so that the smallest image is at least MIN_PYRAMID_SIZE
// pixels along each side.
//
// However, if the input frame has a side of length < MIN_PYRAMID_SIZE,
// we will still construct the top level.
void aom_compute_pyramid(const YV12_BUFFER_CONFIG *frm, int bit_depth,
                         ImagePyramid *pyr) {
  assert(pyr);

  // Per the comments in the ImagePyramid struct, we must take this mutex
  // before reading or writing the "valid" flag, and hold it while computing
  // the pyramid, to ensure proper behaviour if multiple threads call this
  // function simultaneously
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  if (!pyr->valid) {
    fill_pyramid(frm, bit_depth, pyr);
    pyr->valid = true;
  }

  // At this point, the pyramid is guaranteed to be valid, and can be safely
  // read from without holding the mutex any more

#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
}

#ifndef NDEBUG
// Check if a pyramid has already been computed.
// This is mostly a debug helper - as it is necessary to hold pyr->mutex
// while reading the valid flag, we cannot just write:
//   assert(pyr->valid);
// This function allows the check to be correctly written as:
//   assert(aom_is_pyramid_valid(pyr));
bool aom_is_pyramid_valid(ImagePyramid *pyr) {
  assert(pyr);

  // Per the comments in the ImagePyramid struct, we must take this mutex
  // before reading or writing the "valid" flag, and hold it while computing
  // the pyramid, to ensure proper behaviour if multiple threads call this
  // function simultaneously
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  bool valid = pyr->valid;

#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  return valid;
}
#endif

// Mark a pyramid as no longer containing valid data.
// This must be done whenever the corresponding frame buffer is reused
void aom_invalidate_pyramid(ImagePyramid *pyr) {
  if (pyr) {
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
    pyr->valid = false;
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
  }
}

// Release the memory associated with a pyramid
void aom_free_pyramid(ImagePyramid *pyr) {
  if (pyr) {
#if CONFIG_MULTITHREAD
    pthread_mutex_destroy(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
    aom_free(pyr->buffer_alloc);
    aom_free(pyr->layers);
    aom_free(pyr);
  }
}
