/*
* Copyright(c) 2019 Intel Corporation
* Copyright (c) 2019, 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 https://www.aomedia.org/license/software-license. 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 https://www.aomedia.org/license/patent-license.
*/

#ifndef EbPictureOperators_h
#define EbPictureOperators_h

#include "picture_operators_c.h"
#include "definitions.h"
#include "pic_buffer_desc.h"
#include "svt_log.h"
#include "common_dsp_rtcd.h"
#ifdef __cplusplus
extern "C" {
#endif
void svt_aom_picture_full_distortion32_bits_single(int32_t* coeff, int32_t* recon_coeff, uint32_t stride,
                                                   uint32_t bwidth, uint32_t bheight, uint64_t* distortion,
                                                   uint32_t cnt_nz_coeff);
//Residual Data

void svt_aom_compressed_pack_sb(uint8_t* in8_bit_buffer, uint32_t in8_stride, uint8_t* inn_bit_buffer,
                                uint32_t inn_stride, uint16_t* out16_bit_buffer, uint32_t out_stride, uint32_t width,
                                uint32_t height);

void svt_aom_pack2d_src(uint8_t* in8_bit_buffer, uint32_t in8_stride, uint8_t* inn_bit_buffer, uint32_t inn_stride,
                        uint16_t* out16_bit_buffer, uint32_t out_stride, uint32_t width, uint32_t height);

void svt_aom_un_pack2d(uint16_t* in16_bit_buffer, uint32_t in_stride, uint8_t* out8_bit_buffer, uint32_t out8_stride,
                       uint8_t* outn_bit_buffer, uint32_t outn_stride, uint32_t width, uint32_t height);

static INLINE void memset16bit(uint16_t* in_ptr, uint16_t value, uint64_t num_of_elements) {
    uint64_t i;

    for (i = 0; i < num_of_elements; i++) {
        in_ptr[i] = value;
    }
}

static INLINE void memset32bit(uint32_t* in_ptr, uint32_t value, uint64_t num_of_elements) {
    uint64_t i;

    for (i = 0; i < num_of_elements; i++) {
        in_ptr[i] = value;
    }
}

void svt_full_distortion_kernel_cbf_zero32_bits_c(int32_t* coeff, uint32_t coeff_stride,
                                                  uint64_t distortion_result[DIST_CALC_TOTAL], uint32_t area_width,
                                                  uint32_t area_height);

void svt_full_distortion_kernel32_bits_c(int32_t* coeff, int32_t* recon_coeff, uint32_t stride, uint32_t area_width,
                                         uint32_t area_height, uint64_t distortion_result[DIST_CALC_TOTAL]);

uint64_t svt_full_distortion_kernel16_bits_c(uint8_t* input, uint32_t input_offset, uint32_t input_stride,
                                             uint8_t* pred, int32_t pred_offset, uint32_t pred_stride,
                                             uint32_t area_width, uint32_t area_height);

void svt_residual_kernel16bit_c(uint16_t* input, uint32_t input_stride, uint16_t* pred, uint32_t pred_stride,
                                int16_t* residual, uint32_t residual_stride, uint32_t area_width, uint32_t area_height);

void svt_residual_kernel8bit_c(uint8_t* input, uint32_t input_stride, uint8_t* pred, uint32_t pred_stride,
                               int16_t* residual, uint32_t residual_stride, uint32_t area_width, uint32_t area_height);

void svt_aom_generate_padding(EbByte src_pic, uint32_t src_stride, uint32_t original_src_width,
                              uint32_t original_src_height, uint32_t padding_width, uint32_t padding_height);

void svt_aom_generate_padding_compressed_10bit(
    EbByte   src_pic, //output paramter, pointer to the source picture to be padded.
    uint32_t src_stride, //input paramter, the stride of the source picture to be padded.
    uint32_t original_src_width, //input paramter, the width of the source picture which excludes the padding.
    uint32_t original_src_height, //input paramter, the height of the source picture which excludes the padding.
    uint32_t padding_width, //input paramter, the padding width.
    uint32_t padding_height); //input paramter, the padding height.

void svt_aom_generate_padding16_bit(uint16_t* src_pic, uint32_t src_stride, uint32_t original_src_width,
                                    uint32_t original_src_height, uint32_t padding_width, uint32_t padding_height);

void pad_input_picture(EbByte src_pic, uint32_t src_stride, uint32_t original_src_width, uint32_t original_src_height,
                       uint32_t pad_right, uint32_t pad_bottom);

void svt_aom_pad_input_picture_16bit(uint16_t* src_pic, uint32_t src_stride, uint32_t original_src_width,
                                     uint32_t original_src_height, uint32_t pad_right, uint32_t pad_bottom);

void svt_aom_pack_2d_pic(EbPictureBufferDesc* input_picture, uint16_t* packed[3]);
void svt_aom_convert_pic_8bit_to_16bit(EbPictureBufferDesc* src_8bit, EbPictureBufferDesc* dst_16bit, uint16_t ss_x,
                                       uint16_t ss_y);
void svt_aom_copy_buffer_info(EbPictureBufferDesc* src_ptr, EbPictureBufferDesc* dst_ptr);
void svt_aom_yv12_copy_y_c(const Yv12BufferConfig* src_ybc, Yv12BufferConfig* dst_ybc);
void svt_aom_yv12_copy_u_c(const Yv12BufferConfig* src_bc, Yv12BufferConfig* dst_bc);
void svt_aom_yv12_copy_v_c(const Yv12BufferConfig* src_bc, Yv12BufferConfig* dst_bc);
void svt_aom_pack_highbd_pic(const EbPictureBufferDesc* pic_ptr, uint16_t* buffer_16bit[3], uint32_t ss_x,
                             uint32_t ss_y);
void svt_aom_unpack_highbd_pic(uint16_t* buffer_highbd[3], EbPictureBufferDesc* pic_ptr, uint32_t ss_x, uint32_t ss_y);

static inline void svt_av1_picture_copy_y(EbPictureBufferDesc* src, uint32_t src_origin_index, EbPictureBufferDesc* dst,
                                          uint32_t dst_origin_index, uint32_t area_width, uint32_t area_height,
                                          bool hbd) {
    if (hbd) {
        svt_av1_copy_wxh_16bit((uint16_t*)src->y_buffer + src_origin_index,
                               src->y_stride,
                               (uint16_t*)dst->y_buffer + dst_origin_index,
                               dst->y_stride,
                               area_height,
                               area_width);
    } else {
        svt_av1_copy_wxh_8bit(src->y_buffer + src_origin_index,
                              src->y_stride,
                              dst->y_buffer + dst_origin_index,
                              dst->y_stride,
                              area_height,
                              area_width);
    }
}

static inline void svt_av1_picture_copy_cb(EbPictureBufferDesc* src, uint32_t src_origin_index,
                                           EbPictureBufferDesc* dst, uint32_t dst_origin_index, uint32_t area_width,
                                           uint32_t area_height, bool hbd) {
    if (hbd) {
        svt_av1_copy_wxh_16bit((uint16_t*)src->u_buffer + src_origin_index,
                               src->u_stride,
                               (uint16_t*)dst->u_buffer + dst_origin_index,
                               dst->u_stride,
                               area_height,
                               area_width);
    } else {
        svt_av1_copy_wxh_8bit(src->u_buffer + src_origin_index,
                              src->u_stride,
                              dst->u_buffer + dst_origin_index,
                              dst->u_stride,
                              area_height,
                              area_width);
    }
}

static inline void svt_av1_picture_copy_cr(EbPictureBufferDesc* src, uint32_t src_origin_index,
                                           EbPictureBufferDesc* dst, uint32_t dst_origin_index, uint32_t area_width,
                                           uint32_t area_height, bool hbd) {
    if (hbd) {
        svt_av1_copy_wxh_16bit((uint16_t*)src->v_buffer + src_origin_index,
                               src->v_stride,
                               (uint16_t*)dst->v_buffer + dst_origin_index,
                               dst->v_stride,
                               area_height,
                               area_width);
    } else {
        svt_av1_copy_wxh_8bit(src->v_buffer + src_origin_index,
                              src->v_stride,
                              dst->v_buffer + dst_origin_index,
                              dst->v_stride,
                              area_height,
                              area_width);
    }
}

#ifdef __cplusplus
}
#endif
#endif // EbPictureOperators_h
