/*
 * Copyright (c) 2016, 2017 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.
 */
#ifndef __ARM_COMPUTE_NEHISTOGRAMKERNEL_H__
#define __ARM_COMPUTE_NEHISTOGRAMKERNEL_H__

#include "arm_compute/core/NEON/INEKernel.h"

#include <cstddef>
#include <cstdint>
#include <mutex>

namespace arm_compute
{
class IDistribution1D;
class ITensor;
using IImage = ITensor;

/** Interface for the histogram kernel */
class NEHistogramKernel : public INEKernel
{
public:
    /** Default constructor */
    NEHistogramKernel();
    /** Default destructor */
    ~NEHistogramKernel() = default;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHistogramKernel(const NEHistogramKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHistogramKernel &operator=(const NEHistogramKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEHistogramKernel(NEHistogramKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEHistogramKernel &operator=(NEHistogramKernel &&) = default;

    /** Set the input image and the distribution output.
     *
     * @param[in]     input      Source image. Data type supported: U8.
     * @param[out]    output     Destination distribution.
     * @param[in,out] local_hist Array that the threads use to save their local histograms.
     *                           It's size should be equal to (number_of_threads * num_bins),
     *                           and the Window::thread_id() is used to determine the part of the array
     *                           used by each thread.
     * @param[out]    window_lut LUT with pre-calculated possible window values.
     *                           The size of the LUT should be equal to max_range_size and it will be filled
     *                           during the configure stage, while it re-used in every run, therefore can be
     *                           safely shared among threads.
     */
    void configure(const IImage *input, IDistribution1D *output, uint32_t *local_hist, uint32_t *window_lut);
    /** Set the input image and the distribution output.
     *
     * @note Used for histogram of fixed size equal to 256
     *
     * @param[in]  input  Source image. Data type supported: U8.
     * @param[out] output Destination distribution which must be of 256 bins..
     */
    void configure(const IImage *input, IDistribution1D *output);

    // Inherited methods overridden:
    void run(const Window &window) override;

private:
    /** Function to merge multiple partial histograms.
     *
     *  @param[out] global_hist Pointer to the final histogram.
     *  @param[in]  local_hist  Pointer to the partial histograms.
     *  @param[in]  bins        Number of bins.
     */
    void merge_histogram(uint32_t *global_hist, const uint32_t *local_hist, size_t bins);
    /** Function to merge multiple minimum values of partial histograms.
     *
     *  @param[out] global_min Pointer to the global min value.
     *  @param[in]  local_min  Local min value.
     */
    void merge_min(uint8_t *global_min, const uint8_t &local_min);
    /** Function to perform histogram on the given window
      *
     *  @param[in] win Region on which to execute the kernel
     */
    void histogram_U8(Window win);
    /** Function to perform histogram on the given window where histogram is
     *         of fixed size 256 without ranges and offsets.
     *
     *  @param[in] win Region on which to execute the kernel
     */
    void histogram_fixed_U8(Window win);
    /** Pre-calculate the pixel windowing for every possible pixel
     *
     * Calculate (V - offset) * numBins / range where V is every possible pixel value.
     *
     * @note We currently support U8 image thus possible pixel values are between 0 and 255
     */
    void calculate_window_lut() const;
    /** Common signature for all the specialised Histogram functions
     *
     * @param[in] window Region on which to execute the kernel.
     */
    using HistogramFunctionPtr = void (NEHistogramKernel::*)(Window window);

    HistogramFunctionPtr          _func; ///< Histogram function to use for the particular image types passed to configure()
    const IImage                 *_input;
    IDistribution1D              *_output;
    uint32_t                     *_local_hist;
    uint32_t                     *_window_lut;
    std::mutex                    _hist_mtx;
    static constexpr unsigned int _max_range_size{ 256 }; ///< 256 possible pixel values as we handle only U8 images
};
}
#endif /*__ARM_COMPUTE_NEHISTOGRAMKERNEL_H__ */
