/*
 * Copyright (c) 2016-2018 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "helpers.h"

/** Fill N pixel of the padding edge of a single channel image by replicating the closest valid pixel.
 *
 * @attention  The DATA_TYPE needs to be passed at the compile time.
 * e.g. -DDATA_TYPE=int
 *
 * @attention  The border size for top, bottom, left, right needs to be passed at the compile time.
 * e.g. --DBORDER_SIZE_TOP=0 -DBORDER_SIZE_BOTTOM=2 -DBORDER_SIZE_LEFT=0 -DBORDER_SIZE_RIGHT=2
 *
 * @param[in,out] buf_ptr                           Pointer to the source image. Supported data types: U8/U16/S16/U32/S32/F16/F32
 * @param[in]     buf_stride_x                      Stride of the source image in X dimension (in bytes)
 * @param[in]     buf_step_x                        buf_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]     buf_stride_y                      Stride of the source image in Y dimension (in bytes)
 * @param[in]     buf_step_y                        buf_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]     buf_stride_z                      Stride between images if batching images (in bytes)
 * @param[in]     buf_step_z                        buf_stride_z * number of elements along Z processed per workitem(in bytes)
 * @param[in]     buf_offset_first_element_in_bytes The offset of the first element in the source image
 * @param[in]     width                             Width of the valid region of the image
 * @param[in]     height                            Height of the valid region of the image
 * @param[in]     start_pos                         XY coordinate indicating the start point of the valid region
 */
__kernel void fill_image_borders_replicate(
    TENSOR3D_DECLARATION(buf),
    uint width,
    uint height,
    int2 start_pos)
{
    Image buf = CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(buf);

    // Update pointer to point to the starting point of the valid region
    buf.ptr += start_pos.y * buf.stride_y + start_pos.x * buf.stride_x;

    const int total_width = BORDER_SIZE_LEFT + width + BORDER_SIZE_RIGHT;
    const int gid0        = get_global_id(0);
    const int gidH        = gid0 - total_width;
    const int gidW        = gid0 - BORDER_SIZE_LEFT;

    if(gidH >= 0)
    {
        // Handle left border
        DATA_TYPE left_val = *(__global DATA_TYPE *)offset(&buf, 0, gidH);
        for(int i = -BORDER_SIZE_LEFT; i < 0; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, i, gidH) = left_val;
        }
        // Handle right border
        DATA_TYPE right_val = *(__global DATA_TYPE *)offset(&buf, width - 1, gidH);
        for(int i = 0; i < BORDER_SIZE_RIGHT; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, width + i, gidH) = right_val;
        }
    }
    else
    {
        // Get value for corners
        int val_idx = gidW;
        if(gidW < 0 || gidW > (width - 1))
        {
            val_idx = gidW < 0 ? 0 : width - 1;
        }

        // Handle top border
        DATA_TYPE top_val = *(__global DATA_TYPE *)offset(&buf, val_idx, 0);
        for(int i = -BORDER_SIZE_TOP; i < 0; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, gidW, i) = top_val;
        }
        // Handle bottom border
        DATA_TYPE bottom_val = *(__global DATA_TYPE *)offset(&buf, val_idx, height - 1);
        for(int i = 0; i < BORDER_SIZE_BOTTOM; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, gidW, height + i) = bottom_val;
        }
    }
}

/** Fill N pixels of the padding edge of a single channel image with a constant value.
 *
 * @attention  The DATA_TYPE needs to be passed at the compile time.
 * e.g. -DDATA_TYPE=int
 *
 * @attention  The border size for top, bottom, left, right needs to be passed at the compile time.
 * e.g. --DBORDER_SIZE_TOP=0 -DBORDER_SIZE_BOTTOM=2 -DBORDER_SIZE_LEFT=0 -DBORDER_SIZE_RIGHT=2
 *
 * @param[out] buf_ptr                           Pointer to the source image. Supported data types: U8/U16/S16/U32/S32/F16/F32
 * @param[in]  buf_stride_x                      Stride of the source image in X dimension (in bytes)
 * @param[in]  buf_step_x                        buf_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  buf_stride_y                      Stride of the source image in Y dimension (in bytes)
 * @param[in]  buf_step_y                        buf_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  buf_stride_z                      Stride between images if batching images (in bytes)
 * @param[in]  buf_step_z                        buf_stride_z * number of elements along Z processed per workitem(in bytes)
 * @param[in]  buf_offset_first_element_in_bytes The offset of the first element in the source image
 * @param[in]  width                             Width of the valid region of the image
 * @param[in]  height                            Height of the valid region of the image
 * @param[in]  start_pos                         XY coordinate indicating the start point of the valid region
 * @param[in]  constant_value                    Constant value to use to fill the edges
 */
__kernel void fill_image_borders_constant(
    TENSOR3D_DECLARATION(buf),
    uint      width,
    uint      height,
    int2      start_pos,
    DATA_TYPE constant_value)
{
    Image buf = CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(buf);

    // Update pointer to point to the starting point of the valid region
    buf.ptr += start_pos.y * buf.stride_y + start_pos.x * buf.stride_x;

    const int total_width = BORDER_SIZE_LEFT + width + BORDER_SIZE_RIGHT;
    const int gid0        = get_global_id(0);
    const int gidH        = gid0 - total_width;
    const int gidW        = gid0 - BORDER_SIZE_LEFT;

    if(gidH >= 0)
    {
        // Handle left border
        for(int i = -BORDER_SIZE_LEFT; i < 0; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, i, gidH) = constant_value;
        }
        // Handle right border
        for(int i = 0; i < BORDER_SIZE_RIGHT; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, width + i, gidH) = constant_value;
        }
    }
    else
    {
        // Handle top border
        for(int i = -BORDER_SIZE_TOP; i < 0; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, gidW, i) = constant_value;
        }
        // Handle bottom border
        for(int i = 0; i < BORDER_SIZE_BOTTOM; ++i)
        {
            *(__global DATA_TYPE *)offset(&buf, gidW, height + i) = constant_value;
        }
    }
}
