/*
 * Copyright (c) 2016-2020 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 "arm_compute/core/CL/kernels/CLColorConvertKernel.h"

#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/CL/ICLMultiImage.h"
#include "arm_compute/core/CL/ICLTensor.h"
#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/MultiImageInfo.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Utils.h"
#include "arm_compute/core/Validate.h"
#include "arm_compute/core/Window.h"
#include "support/StringSupport.h"

#include <sstream>

using namespace arm_compute;

CLColorConvertKernel::CLColorConvertKernel()
    : _input(nullptr), _output(nullptr), _multi_input(nullptr), _multi_output(nullptr)
{
}

void CLColorConvertKernel::configure(const ICLTensor *input, ICLTensor *output)
{
    ARM_COMPUTE_ERROR_ON(input == nullptr);
    ARM_COMPUTE_ERROR_ON(output == nullptr);

    unsigned int num_elems_processed_per_iteration = 0;
    switch(input->info()->format())
    {
        case Format::RGBA8888:
        {
            switch(output->info()->format())
            {
                case Format::RGB888:
                    num_elems_processed_per_iteration = 16;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        case Format::UYVY422:
        case Format::YUYV422:
        {
            switch(output->info()->format())
            {
                case Format::RGB888:
                case Format::RGBA8888:
                    num_elems_processed_per_iteration = 8;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        case Format::RGB888:
        {
            switch(output->info()->format())
            {
                case Format::RGBA8888:
                case Format::U8:
                    num_elems_processed_per_iteration = 16;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        default:
            break;
    }
    ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
                                 string_from_format(input->info()->format()).c_str(),
                                 string_from_format(output->info()->format()).c_str());

    std::stringstream kernel_name;

    kernel_name << string_from_format(input->info()->format());
    kernel_name << "_to_";
    kernel_name << string_from_format(output->info()->format());
    kernel_name << "_bt709";

    _input  = input;
    _output = output;

    // Create kernel
    _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name.str()));

    // Configure kernel window
    Window                 win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
    AccessWindowHorizontal input_access(input->info(), 0, num_elems_processed_per_iteration);
    AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);

    update_window_and_padding(win, input_access, output_access);

    output_access.set_valid_region(win, input->info()->valid_region());

    ICLKernel::configure_internal(win);

    // Set config_id for enabling LWS tuning
    _config_id = kernel_name.str();
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->info()->dimension(1));
}

void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLImage *output)
{
    ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(output);
    ARM_COMPUTE_ERROR_ON(output == nullptr);

    unsigned int num_elems_processed_per_iteration = 0;

    switch(input->info()->format())
    {
        case Format::NV12:
        case Format::NV21:
        case Format::IYUV:
        {
            switch(output->info()->format())
            {
                case Format::RGB888:
                case Format::RGBA8888:
                    num_elems_processed_per_iteration = 4;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        default:
            break;
    }
    ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
                                 string_from_format(input->info()->format()).c_str(),
                                 string_from_format(output->info()->format()).c_str());

    std::stringstream kernel_name;

    kernel_name << string_from_format(input->info()->format());
    kernel_name << "_to_";
    kernel_name << string_from_format(output->info()->format());
    kernel_name << "_bt709";

    _multi_input = input;
    _output      = output;

    // Create kernel
    _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name.str()));

    // Configure kernel window
    const bool  has_two_planes = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
    const float sub_sampling   = (has_two_planes || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;

    Window win = calculate_max_window(*output->info(), Steps(num_elems_processed_per_iteration));
    win.set_dimension_step(Window::DimY, 2);

    AccessWindowHorizontal plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
    AccessWindowRectangle  plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
                                         sub_sampling, sub_sampling);
    AccessWindowRectangle plane2_access(has_two_planes ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
                                        sub_sampling, sub_sampling);
    AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);

    update_window_and_padding(win,
                              plane0_access, plane1_access, plane2_access,
                              output_access);

    ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
                                                           input->plane(2)->info()->valid_region());
    output_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->info()->tensor_shape()));

    ICLKernel::configure_internal(win);

    // Set config_id for enabling LWS tuning
    _config_id = kernel_name.str();
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
}

void CLColorConvertKernel::configure(const ICLImage *input, ICLMultiImage *output)
{
    ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(input);
    ARM_COMPUTE_ERROR_ON(output == nullptr);

    unsigned int num_elems_processed_per_iteration = 0;
    unsigned int num_elems_read_per_iteration_x    = 0;

    bool  has_two_planes = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);
    float sub_sampling   = (has_two_planes || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;

    switch(input->info()->format())
    {
        case Format::RGB888:
        case Format::RGBA8888:
        {
            switch(output->info()->format())
            {
                case Format::NV12:
                case Format::IYUV:
                    num_elems_processed_per_iteration = 2;
                    num_elems_read_per_iteration_x    = 8;
                    break;
                case Format::YUV444:
                    num_elems_processed_per_iteration = 4;
                    num_elems_read_per_iteration_x    = 16;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        case Format::UYVY422:
        case Format::YUYV422:
        {
            switch(output->info()->format())
            {
                case Format::NV12:
                case Format::IYUV:
                    num_elems_processed_per_iteration = 8;
                    num_elems_read_per_iteration_x    = 8;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        default:
            break;
    }

    ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
                                 string_from_format(input->info()->format()).c_str(),
                                 string_from_format(output->info()->format()).c_str());

    std::stringstream kernel_name;

    kernel_name << string_from_format(input->info()->format());
    kernel_name << "_to_";
    kernel_name << string_from_format(output->info()->format());
    kernel_name << "_bt709";
    _input        = input;
    _multi_output = output;

    // Create kernel
    _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name.str()));

    // Configure kernel window
    Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
    if((input->info()->format() != Format::RGB888 || output->info()->format() != Format::YUV444) && (input->info()->format() != Format::RGBA8888 || output->info()->format() != Format::YUV444))
    {
        win.set_dimension_step(Window::DimY, 2);
    }

    AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
    AccessWindowRectangle  output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);
    AccessWindowRectangle  output_plane2_access(has_two_planes ? nullptr : output->plane(2)->info(), 0, 0,
                                                num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);

    AccessWindowHorizontal input_access(input->info(), 0, num_elems_read_per_iteration_x);

    update_window_and_padding(win,
                              input_access,
                              output_plane0_access,
                              output_plane1_access,
                              output_plane2_access);

    ValidRegion input_region = input->info()->valid_region();

    output_plane0_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(0)->info()->tensor_shape()));
    output_plane1_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(1)->info()->tensor_shape()));
    output_plane2_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(2)->info()->tensor_shape()));

    ICLKernel::configure_internal(win);

    // Set config_id for enabling LWS tuning
    _config_id = kernel_name.str();
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->info()->dimension(1));
}

void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLMultiImage *output)
{
    unsigned int num_elems_processed_per_iteration = 0;
    switch(input->info()->format())
    {
        case Format::NV12:
        case Format::NV21:
        {
            switch(output->info()->format())
            {
                case Format::IYUV:
                case Format::YUV444:
                    num_elems_processed_per_iteration = 16;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        case Format::IYUV:
        {
            switch(output->info()->format())
            {
                case Format::YUV444:
                case Format::NV12:
                    num_elems_processed_per_iteration = 16;
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not supported");
                    break;
            }
            break;
        }
        default:
            break;
    }
    ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
                                 string_from_format(input->info()->format()).c_str(),
                                 string_from_format(output->info()->format()).c_str());

    std::stringstream kernel_name;

    kernel_name << string_from_format(input->info()->format());
    kernel_name << "_to_";
    kernel_name << string_from_format(output->info()->format());
    kernel_name << "_bt709";

    _multi_input  = input;
    _multi_output = output;

    // Create kernel
    bool has_two_input_planars  = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
    bool has_two_output_planars = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);

    float sub_sampling_input  = (has_two_input_planars || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;
    float sub_sampling_output = (has_two_output_planars || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;

    _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name.str()));

    Window win = calculate_max_window(*input->cl_plane(0)->info(), Steps(num_elems_processed_per_iteration));
    win.set_dimension_step(Window::DimY, 2);

    AccessWindowHorizontal input_plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
    AccessWindowRectangle  input_plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
                                               sub_sampling_input, sub_sampling_input);
    AccessWindowRectangle input_plane2_access(has_two_input_planars ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
                                              sub_sampling_input, sub_sampling_input);
    AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
    AccessWindowRectangle  output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);
    AccessWindowRectangle  output_plane2_access(has_two_output_planars ? nullptr : output->plane(2)->info(), 0, 0,
                                                num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);

    update_window_and_padding(win,
                              input_plane0_access, input_plane1_access, input_plane2_access,
                              output_plane0_access, output_plane1_access, output_plane2_access);

    ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
                                                           input->plane(2)->info()->valid_region());
    output_plane0_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(0)->info()->tensor_shape()));
    output_plane1_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(1)->info()->tensor_shape()));
    output_plane2_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(2)->info()->tensor_shape()));

    ICLKernel::configure_internal(win);

    // Set config_id for enabling LWS tuning
    _config_id = kernel_name.str();
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
    _config_id += "_";
    _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
    _config_id += "_";
    _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
}

void CLColorConvertKernel::run(const Window &window, cl::CommandQueue &queue)
{
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window);

    Window slice = window.first_slice_window_2D();

    if(nullptr != _input && nullptr != _output)
    {
        do
        {
            unsigned int idx = 0;
            add_2D_tensor_argument(idx, _input, slice);
            add_2D_tensor_argument(idx, _output, slice);
            enqueue(queue, *this, slice, lws_hint());
        }
        while(window.slide_window_slice_2D(slice));
    }
    else if(nullptr != _input && nullptr != _multi_output)
    {
        Format format = _multi_output->info()->format();
        do
        {
            Window win_uv(slice);

            if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
            {
                win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
                win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
            }
            unsigned int idx = 0;
            add_2D_tensor_argument(idx, _input, slice);
            add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
            for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
            {
                add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_uv);
            }
            enqueue(queue, *this, slice, lws_hint());
        }
        while(window.slide_window_slice_2D(slice));
    }
    else if(nullptr != _multi_input && nullptr != _output)
    {
        Format format = _multi_input->info()->format();
        do
        {
            Window win_uv(slice);

            if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
            {
                win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
                win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
            }

            unsigned int idx = 0;
            add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);

            for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
            {
                add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_uv);
            }
            add_2D_tensor_argument(idx, _output, slice);
            enqueue(queue, *this, slice, lws_hint());
        }
        while(window.slide_window_slice_2D(slice));
    }
    else if(nullptr != _multi_input && nullptr != _multi_output)
    {
        Format in_format  = _multi_input->info()->format();
        Format out_format = _multi_output->info()->format();
        do
        {
            Window win_in_uv(slice);
            if((Format::NV12 == in_format) || (Format::NV21 == in_format) || (Format::IYUV == in_format))
            {
                win_in_uv.set(Window::DimX, Window::Dimension(win_in_uv.x().start() / 2,
                                                              win_in_uv.x().end() / 2, win_in_uv.x().step() / 2));
                win_in_uv.set(Window::DimY, Window::Dimension(win_in_uv.y().start() / 2, win_in_uv.y().end() / 2, 1));
            }
            unsigned int idx = 0;
            add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);
            for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
            {
                add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_in_uv);
            }

            Window win_out_uv(slice);
            if((Format::NV12 == out_format) || (Format::NV21 == out_format) || (Format::IYUV == out_format))
            {
                win_out_uv.set(Window::DimX, Window::Dimension(win_out_uv.x().start() / 2,
                                                               win_out_uv.x().end() / 2, win_out_uv.x().step() / 2));
                win_out_uv.set(Window::DimY, Window::Dimension(win_out_uv.y().start() / 2, win_out_uv.y().end() / 2, 1));
            }

            add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
            for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
            {
                add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_out_uv);
            }
            enqueue(queue, *this, slice, lws_hint());
        }
        while(window.slide_window_slice_2D(slice));
    }
    else
    {
        ARM_COMPUTE_ERROR("Not supported");
    }
}
