/*
 * 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 "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 <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(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);
}

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(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);
}

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(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);
}

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(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);
}

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);
        }
        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);
        }
        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);
        }
        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);
        }
        while(window.slide_window_slice_2D(slice));
    }
    else
    {
        ARM_COMPUTE_ERROR("Not supported");
    }
}
