/*
 * 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/runtime/CL/functions/CLEqualizeHistogram.h"

#include "arm_compute/core/CL/ICLDistribution1D.h"
#include "arm_compute/core/CL/ICLLut.h"
#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
#include "src/core/CL/kernels/CLHistogramKernel.h"
#include "src/core/CL/kernels/CLTableLookupKernel.h"

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <numeric>

using namespace arm_compute;

namespace
{
void calculate_cum_dist_and_lut(CLDistribution1D &dist, CLDistribution1D &cum_dist, CLLut &lut)
{
    dist.map(true);
    cum_dist.map(true);
    lut.map(true);

    const uint32_t *dist_ptr     = dist.buffer();
    uint32_t       *cum_dist_ptr = cum_dist.buffer();
    uint8_t        *lut_ptr      = lut.buffer();

    ARM_COMPUTE_ERROR_ON(dist_ptr == nullptr);
    ARM_COMPUTE_ERROR_ON(cum_dist_ptr == nullptr);
    ARM_COMPUTE_ERROR_ON(lut_ptr == nullptr);

    // Calculate cumulative distribution
    std::partial_sum(dist_ptr, dist_ptr + 256, cum_dist_ptr);

    // Get the number of pixels that have the lowest value in the input image
    const uint32_t num_lowest_pixels = *std::find_if(dist_ptr, dist_ptr + 256, [](const uint32_t &v)
    {
        return v > 0;
    });
    const size_t image_size = cum_dist_ptr[255];

    if(image_size == num_lowest_pixels)
    {
        std::iota(lut_ptr, lut_ptr + 256, 0);
    }
    else
    {
        const float diff = image_size - num_lowest_pixels;

        for(size_t i = 0; i < 256; ++i)
        {
            lut_ptr[i] = lround((cum_dist_ptr[i] - num_lowest_pixels) / diff * 255.f);
        }
    }

    dist.unmap();
    cum_dist.unmap();
    lut.unmap();
}
} // namespace

CLEqualizeHistogram::CLEqualizeHistogram()
    : _histogram_kernel(std::make_unique<CLHistogramKernel>()),
      _border_histogram_kernel(std::make_unique<CLHistogramBorderKernel>()),
      _map_histogram_kernel(std::make_unique<CLTableLookupKernel>()),
      _hist(nr_bins, 0, max_range),
      _cum_dist(nr_bins, 0, max_range),
      _cd_lut(nr_bins, DataType::U8)
{
}

CLEqualizeHistogram::~CLEqualizeHistogram() = default;

void CLEqualizeHistogram::configure(const ICLImage *input, ICLImage *output)
{
    configure(CLKernelLibrary::get().get_compile_context(), input, output);
}

void CLEqualizeHistogram::configure(const CLCompileContext &compile_context, const ICLImage *input, ICLImage *output)
{
    _histogram_kernel->configure(compile_context, input, &_hist);
    _border_histogram_kernel->configure(compile_context, input, &_hist);
    _map_histogram_kernel->configure(compile_context, input, &_cd_lut, output);
}

void CLEqualizeHistogram::run()
{
    // Calculate histogram of input.
    CLScheduler::get().enqueue(*_histogram_kernel, false);

    // Calculate remaining pixels when image is not multiple of the elements of histogram kernel
    CLScheduler::get().enqueue(*_border_histogram_kernel, false);

    // Calculate cumulative distribution of histogram and create LUT.
    calculate_cum_dist_and_lut(_hist, _cum_dist, _cd_lut);

    // Map input to output using created LUT.
    CLScheduler::get().enqueue(*_map_histogram_kernel);
}
