/*
 * 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 <assert.h>

#include "aom/internal/aom_image_internal.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"
#include "aom_scale/yv12config.h"
#include "av1/common/enums.h"

/****************************************************************************
 *  Exports
 ****************************************************************************/

/****************************************************************************
 *
 ****************************************************************************/

// TODO(jkoleszar): Maybe replace this with struct aom_image
int aom_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
  if (ybf) {
    if (ybf->buffer_alloc_sz > 0) {
      aom_free(ybf->buffer_alloc);
    }
    if (ybf->y_buffer_8bit) aom_free(ybf->y_buffer_8bit);
    aom_remove_metadata_from_frame_buffer(ybf);
    /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
      u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
      all of this so that a freed pointer isn't inadvertently used */
    memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG));
    return 0;
  }

  return AOM_CODEC_MEM_ERROR;
}

static int realloc_frame_buffer_aligned(
    YV12_BUFFER_CONFIG *ybf, int width, int height, int ss_x, int ss_y,
    int use_highbitdepth, int border, int byte_alignment,
    aom_codec_frame_buffer_t *fb, aom_get_frame_buffer_cb_fn_t cb,
    void *cb_priv, const int y_stride, const uint64_t yplane_size,
    const uint64_t uvplane_size, const int aligned_width,
    const int aligned_height, const int uv_width, const int uv_height,
    const int uv_stride, const int uv_border_w, const int uv_border_h,
    int alloc_y_buffer_8bit) {
  if (ybf) {
    const int aom_byte_align = (byte_alignment == 0) ? 1 : byte_alignment;
    const uint64_t frame_size =
        (1 + use_highbitdepth) * (yplane_size + 2 * uvplane_size);

    uint8_t *buf = NULL;

#if defined AOM_MAX_ALLOCABLE_MEMORY
    // The size of ybf->buffer_alloc.
    uint64_t alloc_size = frame_size;
    // The size of ybf->y_buffer_8bit.
    if (use_highbitdepth) alloc_size += yplane_size;
    // The decoder may allocate REF_FRAMES frame buffers in the frame buffer
    // pool. Bound the total amount of allocated memory as if these REF_FRAMES
    // frame buffers were allocated in a single allocation.
    if (alloc_size > AOM_MAX_ALLOCABLE_MEMORY / REF_FRAMES)
      return AOM_CODEC_MEM_ERROR;
#endif

    if (cb != NULL) {
      const int align_addr_extra_size = 31;
      const uint64_t external_frame_size = frame_size + align_addr_extra_size;

      assert(fb != NULL);

      if (external_frame_size != (size_t)external_frame_size)
        return AOM_CODEC_MEM_ERROR;

      // Allocation to hold larger frame, or first allocation.
      if (cb(cb_priv, (size_t)external_frame_size, fb) < 0)
        return AOM_CODEC_MEM_ERROR;

      if (fb->data == NULL || fb->size < external_frame_size)
        return AOM_CODEC_MEM_ERROR;

      ybf->buffer_alloc = (uint8_t *)aom_align_addr(fb->data, 32);

#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
      // This memset is needed for fixing the issue of using uninitialized
      // value in msan test. It will cause a perf loss, so only do this for
      // msan test.
      memset(ybf->buffer_alloc, 0, (size_t)frame_size);
#endif
#endif
    } else if (frame_size > ybf->buffer_alloc_sz) {
      // Allocation to hold larger frame, or first allocation.
      aom_free(ybf->buffer_alloc);
      ybf->buffer_alloc = NULL;
      ybf->buffer_alloc_sz = 0;

      if (frame_size != (size_t)frame_size) return AOM_CODEC_MEM_ERROR;

      ybf->buffer_alloc = (uint8_t *)aom_memalign(32, (size_t)frame_size);
      if (!ybf->buffer_alloc) return AOM_CODEC_MEM_ERROR;

      ybf->buffer_alloc_sz = (size_t)frame_size;

      // This memset is needed for fixing valgrind error from C loop filter
      // due to access uninitialized memory in frame border. It could be
      // removed if border is totally removed.
      memset(ybf->buffer_alloc, 0, ybf->buffer_alloc_sz);
    }

    ybf->y_crop_width = width;
    ybf->y_crop_height = height;
    ybf->y_width = aligned_width;
    ybf->y_height = aligned_height;
    ybf->y_stride = y_stride;

    ybf->uv_crop_width = (width + ss_x) >> ss_x;
    ybf->uv_crop_height = (height + ss_y) >> ss_y;
    ybf->uv_width = uv_width;
    ybf->uv_height = uv_height;
    ybf->uv_stride = uv_stride;

    ybf->border = border;
    ybf->frame_size = (size_t)frame_size;
    ybf->subsampling_x = ss_x;
    ybf->subsampling_y = ss_y;

    buf = ybf->buffer_alloc;
    if (use_highbitdepth) {
      // Store uint16 addresses when using 16bit framebuffers
      buf = CONVERT_TO_BYTEPTR(ybf->buffer_alloc);
      ybf->flags = YV12_FLAG_HIGHBITDEPTH;
    } else {
      ybf->flags = 0;
    }

    ybf->y_buffer = (uint8_t *)aom_align_addr(
        buf + (border * y_stride) + border, aom_byte_align);
    ybf->u_buffer = (uint8_t *)aom_align_addr(
        buf + yplane_size + (uv_border_h * uv_stride) + uv_border_w,
        aom_byte_align);
    ybf->v_buffer =
        (uint8_t *)aom_align_addr(buf + yplane_size + uvplane_size +
                                      (uv_border_h * uv_stride) + uv_border_w,
                                  aom_byte_align);

    ybf->use_external_reference_buffers = 0;

    if (use_highbitdepth && alloc_y_buffer_8bit) {
      if (ybf->y_buffer_8bit) aom_free(ybf->y_buffer_8bit);
      ybf->y_buffer_8bit = (uint8_t *)aom_memalign(32, (size_t)yplane_size);
      if (!ybf->y_buffer_8bit) return AOM_CODEC_MEM_ERROR;
    } else {
      if (ybf->y_buffer_8bit) {
        aom_free(ybf->y_buffer_8bit);
        ybf->y_buffer_8bit = NULL;
        ybf->buf_8bit_valid = 0;
      }
    }

    ybf->corrupted = 0; /* assume not corrupted by errors */
    return 0;
  }
  return AOM_CODEC_MEM_ERROR;
}

static int calc_stride_and_planesize(const int ss_x, const int ss_y,
                                     const int aligned_width,
                                     const int aligned_height, const int border,
                                     const int byte_alignment, int *y_stride,
                                     int *uv_stride, uint64_t *yplane_size,
                                     uint64_t *uvplane_size,
                                     const int uv_height) {
  /* Only support allocating buffers that have a border that's a multiple
   * of 32. The border restriction is required to get 16-byte alignment of
   * the start of the chroma rows without introducing an arbitrary gap
   * between planes, which would break the semantics of things like
   * aom_img_set_rect(). */
  if (border & 0x1f) return AOM_CODEC_MEM_ERROR;
  *y_stride = ((aligned_width + 2 * border) + 31) & ~31;
  *yplane_size =
      (aligned_height + 2 * border) * (uint64_t)(*y_stride) + byte_alignment;

  *uv_stride = *y_stride >> ss_x;
  *uvplane_size = (uv_height + 2 * (border >> ss_y)) * (uint64_t)(*uv_stride) +
                  byte_alignment;
  return 0;
}

int aom_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
                             int ss_x, int ss_y, int use_highbitdepth,
                             int border, int byte_alignment,
                             aom_codec_frame_buffer_t *fb,
                             aom_get_frame_buffer_cb_fn_t cb, void *cb_priv,
                             int alloc_y_buffer_8bit) {
#if CONFIG_SIZE_LIMIT
  if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
    return AOM_CODEC_MEM_ERROR;
#endif

  if (ybf) {
    int y_stride = 0;
    int uv_stride = 0;
    uint64_t yplane_size = 0;
    uint64_t uvplane_size = 0;
    const int aligned_width = (width + 7) & ~7;
    const int aligned_height = (height + 7) & ~7;
    const int uv_width = aligned_width >> ss_x;
    const int uv_height = aligned_height >> ss_y;
    const int uv_border_w = border >> ss_x;
    const int uv_border_h = border >> ss_y;

    int error = calc_stride_and_planesize(
        ss_x, ss_y, aligned_width, aligned_height, border, byte_alignment,
        &y_stride, &uv_stride, &yplane_size, &uvplane_size, uv_height);
    if (error) return error;
    return realloc_frame_buffer_aligned(
        ybf, width, height, ss_x, ss_y, use_highbitdepth, border,
        byte_alignment, fb, cb, cb_priv, y_stride, yplane_size, uvplane_size,
        aligned_width, aligned_height, uv_width, uv_height, uv_stride,
        uv_border_w, uv_border_h, alloc_y_buffer_8bit);
  }
  return AOM_CODEC_MEM_ERROR;
}

int aom_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
                           int ss_x, int ss_y, int use_highbitdepth, int border,
                           int byte_alignment) {
  if (ybf) {
    aom_free_frame_buffer(ybf);
    return aom_realloc_frame_buffer(ybf, width, height, ss_x, ss_y,
                                    use_highbitdepth, border, byte_alignment,
                                    NULL, NULL, NULL, 0);
  }
  return AOM_CODEC_MEM_ERROR;
}

void aom_remove_metadata_from_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
  if (ybf && ybf->metadata) {
    aom_img_metadata_array_free(ybf->metadata);
    ybf->metadata = NULL;
  }
}

int aom_copy_metadata_to_frame_buffer(YV12_BUFFER_CONFIG *ybf,
                                      const aom_metadata_array_t *arr) {
  if (!ybf || !arr || !arr->metadata_array) return -1;
  if (ybf->metadata == arr) return 0;
  aom_remove_metadata_from_frame_buffer(ybf);
  ybf->metadata = aom_img_metadata_array_alloc(arr->sz);
  if (!ybf->metadata) return -1;
  for (size_t i = 0; i < ybf->metadata->sz; i++) {
    ybf->metadata->metadata_array[i] = aom_img_metadata_alloc(
        arr->metadata_array[i]->type, arr->metadata_array[i]->payload,
        arr->metadata_array[i]->sz, arr->metadata_array[i]->insert_flag);
    if (ybf->metadata->metadata_array[i] == NULL) {
      aom_img_metadata_array_free(ybf->metadata);
      ybf->metadata = NULL;
      return -1;
    }
  }
  ybf->metadata->sz = arr->sz;
  return 0;
}
