/*
 * 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.
 */
#ifndef ARM_COMPUTE_NEHOGDESCRIPTORKERNEL_H
#define ARM_COMPUTE_NEHOGDESCRIPTORKERNEL_H

#include "arm_compute/core/IHOG.h"
#include "arm_compute/core/Size2D.h"
#include "src/core/NEON/INEKernel.h"

namespace arm_compute
{
class ITensor;

/** NEON kernel to perform HOG Orientation Binning */
class NEHOGOrientationBinningKernel : public INEKernel
{
public:
    const char *name() const override
    {
        return "NEHOGOrientationBinningKernel";
    }
    /** Default constructor */
    NEHOGOrientationBinningKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHOGOrientationBinningKernel(const NEHOGOrientationBinningKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHOGOrientationBinningKernel &operator=(const NEHOGOrientationBinningKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEHOGOrientationBinningKernel(NEHOGOrientationBinningKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEHOGOrientationBinningKernel &operator=(NEHOGOrientationBinningKernel &&) = default;
    /** Default destructor */
    ~NEHOGOrientationBinningKernel() = default;

    /**  Initialise the kernel's inputs, output and HOG's metadata
     *
     * @param[in]  input_magnitude Input tensor which stores the magnitude of the gradient for each pixel. Data type supported: S16.
     * @param[in]  input_phase     Input tensor which stores the phase of the gradient for each pixel. Data type supported: U8
     * @param[out] output          Output tensor which stores the local HOG for each cell. Data type supported: F32. Number of channels supported: equal to the number of histogram bins per cell
     * @param[in]  hog_info        HOG's metadata
     */
    void configure(const ITensor *input_magnitude, const ITensor *input_phase, ITensor *output, const HOGInfo *hog_info);

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

private:
    /** Common signature for all the specialised block normalization functions
     *
     * @param[in]  mag_row_ptr   Pointer to the first row of the cell in the magnitude tensor
     * @param[in]  phase_row_ptr Pointer to the first row of the cell in the phase tensor
     * @param[out] output_ptr    Pointer to the output cell of hog space tensor
     * @param[in]  mag_stride    Stride of the magnitude tensor
     * @param[in]  phase_stride  Stride of the phase tensor
     * @param[in]  cell_width    Width of the cell
     * @param[in]  cell_height   Height of the cell
     * @param[in]  num_bins      Number of bins for each cell
     * @param[in]  phase_scale   Scale factor to apply to the phase in order to calculate the histogram index
     */
    using OrientBinFunc = void(const int16_t *__restrict mag_row_ptr, const uint8_t *__restrict phase_row_ptr, float *__restrict output_ptr, size_t mag_stride, size_t phase_stride, size_t cell_width,
                               size_t cell_height, size_t num_bins, float phase_scale);
    /** Orientation binning function to use for the particular cell width passed to configure() */
    OrientBinFunc *_func;
    const ITensor *_input_magnitude;
    const ITensor *_input_phase;
    ITensor       *_output;
    size_t         _cell_width;
    size_t         _cell_height;
    size_t         _num_bins;
    float          _phase_scale;
};

/** NEON kernel to perform HOG block normalization */
class NEHOGBlockNormalizationKernel : public INEKernel
{
public:
    const char *name() const override
    {
        return "NEHOGBlockNormalizationKernel";
    }
    /** Default constructor */
    NEHOGBlockNormalizationKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHOGBlockNormalizationKernel(const NEHOGBlockNormalizationKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEHOGBlockNormalizationKernel &operator=(const NEHOGBlockNormalizationKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEHOGBlockNormalizationKernel(NEHOGBlockNormalizationKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEHOGBlockNormalizationKernel &operator=(NEHOGBlockNormalizationKernel &&) = default;
    /** Default destructor */
    ~NEHOGBlockNormalizationKernel() = default;

    /** Initialise the kernel's input, output and HOG's metadata
     *
     * @param[in]  input    Input tensor which stores the local HOG for each cell. Data type supported: F32. Number of channels supported: equal to the number of histogram bins per cell
     * @param[out] output   Output tensor which stores the normalised blocks. Data type supported: F32. Number of channels supported: equal to the number of histogram bins per block
     * @param[in]  hog_info HOG's metadata
     */
    void configure(const ITensor *input, ITensor *output, const HOGInfo *hog_info);

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

private:
    /** Common signature for all the specialised block normalization functions
     *
     * @param[in]  input_row_ptr              Pointer to the first row of the block in the input hog space tensor
     * @param[out] output_ptr                 Pointer to the output block of the hog normalized space
     * @param[in]  input_stride               Stride of the input hog space tensor
     * @param[in]  num_cells_per_block_height Number of cells per block along the Y direction
     * @param[in]  num_bins_block_x           Number of bins per block along the X direction
     * @param[in]  num_bins_block             Number of total bins per block
     * @param[in]  l2_hyst_threshold          Threshold to use for l2 hysteresis normalization
     */
    using BlockNormFunc = void(const float *input_row_ptr, float *output_ptr, size_t input_stride, size_t num_cells_per_block_height, size_t num_bins_block_x, size_t num_bins_block,
                               float l2_hyst_threshold);
    /** Block normalization function to use for the particular normalization type passed to configure() */
    BlockNormFunc *_func;
    const ITensor *_input;
    ITensor       *_output;
    Size2D         _num_cells_per_block;
    Size2D         _num_cells_per_block_stride;
    size_t         _num_bins;
    float          _l2_hyst_threshold;
};
} // namespace arm_compute
#endif /* ARM_COMPUTE_NEHOGDESCRIPTORKERNEL_H */
