// NOWHINE ENTIRE FILE
//-------------------------------------------------------------------------
// Copyright (c) 2017-2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//------------------------------------------------------------------------

#ifndef __NC_LIB_WARP_API__
#define __NC_LIB_WARP_API__

/** ------------------------------------------------------------------------
 * @file  NcLibWarp.h
 * @brief NcLib Warp API functions
 *
 *  Warping Order (this is true for any WarpDirection)
 *
 *                 ________    Intermediate    ___________
 *      Input     |        |   Image Domain   |           |     Output
 *      Image --->|  Grid  |----------------->|  Matrices |---> Image
 *      Domain    |________|                  |___________|     Domain
 *
 *------------------------------------------------------------------------*/

/*------------------------------------------------------------------------
*       Include Files
* ----------------------------------------------------------------------- */
#include <stdint.h>
#include "NcLibContext.h"               /* FD */
#include "NcLibWarpCommonDef.h"

/*------------------------------------------------------------------------
*       Definitions
* ----------------------------------------------------------------------- */

/** Extrapolation points */
#define NC_LIB_WARP_EXTRAP_TOP_LEFT_IDX       (0)                                       /**< Top left extrapolation point index */
#define NC_LIB_WARP_EXTRAP_TOP_RIGHT_IDX      (NC_LIB_WARP_EXTRAP_TOP_LEFT_IDX + 1)     /**< Top right extrapolation point index */
#define NC_LIB_WARP_EXTRAP_BOTTOM_LEFT_IDX    (NC_LIB_WARP_EXTRAP_TOP_RIGHT_IDX + 1)    /**< Bottom left extrapolation point index */
#define NC_LIB_WARP_EXTRAP_BOTTOM_RIGHT_IDX   (NC_LIB_WARP_EXTRAP_BOTTOM_LEFT_IDX + 1)  /**< Bottom right extrapolation point index */

/** NcLibCheckIcaTransformValidity() intermediate buffer size - required for internal calculations */
#define NC_LIB_WARP_CHECK_ICA20_INTERMEDIATE_BUFFER_SIZE     (sizeof(NcLibWarpGridCoord) * 3417)
#define NC_LIB_WARP_CHECK_ICA30_INTERMEDIATE_BUFFER_SIZE     (sizeof(NcLibWarpGridCoord) * 12969)

/*------------------------------------------------------------------------
*       Type Declarations
* ----------------------------------------------------------------------- */
#pragma pack(push)
#pragma pack(4)

/** Domain of alignment matrix */
typedef enum NcLibWarpImageDomain_t
{
    DISTORTED_IMAGE_DOMAIN = 0,     /**< Input image before LDC, RSC, and OISC */
    UNDISTORTED_IMAGE_DOMAIN,       /**< The domain after applying LDC, RSC, and OISC, but before stabilization */
    STABILIZED_IMAGE_DOMAIN         /**< Output image after stabilization */
}NcLibWarpImageDomain;

/**< Fractional ROI or FOV rectangle normalized on [0..1] */
struct NcLibRoi1x1
{
    NcLibFloat2         offset;         /**< on domain 1x1 */
    NcLibFloat2         size;           /**< on domain 1x1 */
};


/** Input struct for the NcLibWarpBuildAssistGrid() function */
typedef struct NcLibWarpBuildAssistGridIn_t
{
    const NcLibWarp*    in;             /**< Input Warp struct in virtual domain, as
                                         *   converted by NcLibWarpConvertToVirtualDomain().
                                         */
    uint32_t            numColumns;     /**< Number of columns in assists grid. Must be greater than 1. */
    uint32_t            numRows;        /**< Number of rows in assists grid. Must be greater than 1. */

}NcLibWarpBuildAssistGridIn;

/** Output struct of NcLibWarpBuildAssistGrid() function, should be buffer by the user for next frame */
typedef struct NcLibWarpBuildAssistGridOut_t
{
    NcLibWarpGrid*      assistGrid;     /**< Assist grid generated by NcLibWarpBuildAssistGrid() for current frame */
    NcLibWarp*          inputWarp;      /**< If NULL, assumed to be buffered by the user. And pointer assigned to
                                         *   inputWarp externally before calling to NcLibWarpGeometries(). Otherwise
                                         *   will contain the warp grid from previous input
                                         */
}NcLibWarpBuildAssistGridOut;

/** A struct containing all the warps of current and previous frames.
*  Example warps composition (arrows are drawn OUT_2_IN):
*   __________________                    ____________________                   ___________________
*  |                  |  distCorrection  |                    |  stabilization  |                   |
*  |current  distorted|<-----------------|current  undistorted|<----------------|current  stabilized|
*  |__________________|                  |____________________|                 |___________________|
*                                                 |
*                                                 | alignment
*                                                 |
*   __________________                    ________V___________                   ___________________
*  |                  |  distCorrection  |                    |  stabilization  |                   |
*  |previous distorted|<-----------------|previous undistorted|<----------------|previous stabilized|
*  |__________________|                  |____________________|                 |___________________|
*/
typedef struct NcLibFrameWarps_t
{
    NcLibWarpImageDomain          alignmentDomain;     /**< Domain of alignment transform */

    NcLibWarp*                    alignment;           /**< Alignment transform (grid or a single matrix)
                                                        *   Example: DME matrix.
                                                        */

    NcLibWarpBuildAssistGridOut*  currStabilization;   /**< Current frame stabilization transform
                                                        *   + assist grid in case of multiple matrices inversion.
                                                        *   Example: DIS grid and stabilization matrices as output by EIS.
                                                        *   Can be NULL if
                                                        *   (STABILIZED_IMAGE_DOMAIN != NcLibCalcMctfIn.frameWarps.alignmentDomain) &&
                                                        *   (STABILIZED_IMAGE_DOMAIN != NcLibCalcMctfIn.outDomain)
                                                        */

    NcLibWarpBuildAssistGridOut*  prevStabilization;   /**< Previous frame stabilization transform,
                                                        *   Can be NULL if
                                                        *   (STABILIZED_IMAGE_DOMAIN != NcLibCalcMctfIn.frameWarps.alignmentDomain) &&
                                                        *   (STABILIZED_IMAGE_DOMAIN != NcLibCalcMctfIn.outDomain)
                                                        */

    NcLibWarp*                    currDistCorrection;  /**< Current frame distortion correction.
                                                        *   Only supports grid here. Not matrices.
                                                        *   Example: LDC + RSC + OIS grid as output by EIS.
                                                        */

    NcLibWarp*                    prevDistCorrection;  /**< Previous frame distortion correction.
                                                        *   Only supports grid here. Not matrices.
                                                        */
}NcLibFrameWarps;

/** NcLibWarpGeometries() input struct */
typedef struct NcLibWarpGeomIn_t
{
    NcLibImageSize                      inputSize;              /**< Input image dimensions (as supplied to FW) */
    NcLibWindowRegion                   eisFOV;                 /**< Window defined by EIS FOV without margins. */
    NcLibWindowRegion                   zoomWindow;             /**< Output zoom window. (as supplied to FW) */
    NcLibWindowRegion                   ifeZoomWindow;          /**< IFE output zoom window. (as supplied to FW) */
    NcLibFrameWarps                     frameWarps;             /**< The warps of current and previous frame + alignment between them.
                                                                 *   All are in virtual domain as converted by NcLibWarpConvertToVirtualDomain().
                                                                 *   Previous frame's warps are allowed to be NULL if
                                                                 *   (false == isFdConfigFromPrevFrame) || (fdDomain == aligmentDomain)
                                                                 */

    /* FD parameters */

    const FD_CONFIG_CONTEXT*            fdConfig;               /**< Holds the latest available face detection
                                                                *   parameters (from current or previous frame).
                                                                *   Assumed to be in coordinates of inputSize.
                                                                */
    bool                                isFdConfigFromPrevFrame;/**< If true, then FD parameters are from previous
                                                                *   frame, otherwise from current frame
                                                                */
    NcLibWarpImageDomain                fdDomain;               /**< Domain of face detection */

    NcLibWarpImageDomain                lnrDomain;              /**< Domain of LNR */

    /* TF */
    uint32_t                            tf_lnr_opt_center_x;    /**< x-coordinate of TF LNR center as assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1].
                                                                *   format: 15uQ14
                                                                */
    uint32_t                            tf_lnr_opt_center_y;    /**< y-coordinate of TF LNR center as assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                */

    /* ANR */
    uint32_t                            anr_lnr_opt_center_x;   /**< Optical center of ANR LNR.as assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */
    uint32_t                            anr_lnr_opt_center_y;   /**< Optical center of ANR LNR. as assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */

    /* ASF */
    uint32_t                            asf_opt_center_x;       /**< Optical center of ASF. As assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */

    uint32_t                            asf_opt_center_y;       /**< Optical center of ASF. As assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */

    /* LENR */
    uint32_t                            lenr_opt_center_x;     /**< Optical center of LENR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */

    uint32_t                            lenr_opt_center_y;     /**< Optical center of LENR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */

    /* HNR */
    uint32_t                            hnr_opt_center_x;       /**< Optical center of HNR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */

    uint32_t                            hnr_opt_center_y;       /**< Optical center of HNR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */
}NcLibWarpGeomIn;

/** NcLibWarpGeometries() output struct */
typedef struct NcLibWarpGeomOut_t
{
    /* FD parameters */
    FD_CONFIG_CONTEXT*              fdConfig;                   /**< Corrected FD parameters in coordinates
                                                                 *   of after Warp (reduced image size).
                                                                 */

    /* TF */
    uint32_t                        tf_lnr_opt_center_x;        /**< x-coordinate of TF LNR center as assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */
    uint32_t                        tf_lnr_opt_center_y;        /**< y-coordinate of TF LNR center as assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */

    /* ANR */
    uint32_t                        anr_lnr_opt_center_x;       /**< Optical center of ANR LNR center as assigned
                                                                  *   to Chromatix input struct.
                                                                  *   A logical values between [0,1]
                                                                  *   format: 15uQ14
                                                                  */
    uint32_t                        anr_lnr_opt_center_y;       /**< Optical center of ANR LNR center as assigned
                                                                  *   to Chromatix input struct.
                                                                  *   A logical values between [0,1]
                                                                  *   format: 15uQ14
                                                                  */

    /* ASF  */
    uint32_t                        asf_opt_center_x;           /**< Optical center of ASF. As assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */

    uint32_t                        asf_opt_center_y;           /**< Optical center of ASF. As assigned
                                                                 *   to Chromatix input struct.
                                                                 *   A logical values between [0,1]
                                                                 *   format: 15uQ14
                                                                 */
    /* LENR */
    uint32_t                        lenr_opt_center_x;         /**< Optical center of LENR. As assigned
                                                               *   to Chromatix input struct.
                                                               *   A logical values between [0,1]
                                                               *   format: 15uQ14
                                                               */

    uint32_t                        lenr_opt_center_y;         /**< Optical center of LENR. As assigned
                                                               *   to Chromatix input struct.
                                                               *   A logical values between [0,1]
                                                               *   format: 15uQ14
                                                               */

    /* HNR */
    uint32_t                        hnr_opt_center_x;           /**< Optical center of HNR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */

    uint32_t                        hnr_opt_center_y;           /**< Optical center of HNR. As assigned
                                                                *   to Chromatix input struct.
                                                                *   A logical values between [0,1]
                                                                *   format: 15uQ14
                                                                */
}NcLibWarpGeomOut;

/** NcLibCalcMctfTransform() input struct */
typedef struct NcLibCalcMctfIn_t
{
    const NcLibImageSize*           inputSize;              /**< Input image dimensions */
    NcLibWindowRegion               zoomWindow;             /**< Output zoom window. (as supplied to FW) */
    NcLibWindowRegion               eisFOV;                 /**< Window defined by EIS FOV without margins. */

    NcLibFrameWarps                 frameWarps;             /**< The warps of current and previous frame + alignment between them.
                                                             *   All are in virtual domain,
                                                             *   as converted by NcLibWarpConvertToVirtualDomain().
                                                             */

    NcLibWarpImageDomain            outDomain;              /**< The domain that the output transform should be given in. */
}NcLibCalcMctfIn;

/** NcLibCheckIcaTransformValidity() input struct */
typedef struct NcLibCheckIcaTransformValidityIn_t
{
    const NcLibWarp*          warp;                   /**< Warping transform to be checked for validity */
    NcLibImageSize            outputSize;             /**< Output image dimensions */
    uint32_t                  halfOutputW;            /**< Half output image width - special parameter present in ICA.
                                                       *   Usually = outputSize.widthPixels/2
                                                       */
    NcLibImageSize            inputSize;              /**< Input image dimensions */

    NcLibWindowRegion         outputRoi;              /**< ROI in output domain - output image is mapped to this ROI in
                                                       *   output virtual domain (the ROI is given in relative form - window size vs full size) */
    NcLibWindowRegion         inputRoi;               /**< ROI in input domain - input image is mapped to this ROI
                                                       *   in input virtual domain
                                                       */
    bool                      enableRoi;              /**< Whether ROI (zoom windows) in input and output domains are enabled */
} NcLibCheckIcaTransformValidityIn;

/** Grid triangulation type */
typedef enum NcLibUniformGridTriangulation_t
{
    TRIANGLE_STRIP_NE_DIRECTION = 0,        /**< |/|/|/|...   */
    TRIANGLE_STRIP_NW_DIRECTION = 1,        /**< |\|\|\|...   */
    TRIANGLE_STRIP_TOGGLING_DIRECTION = 2   /**< |/|\|/|...
                                                 |\|/|... */
} NcLibUniformGridTriangulation;

/** Extrapolation type */
typedef enum NcLibReverseGridExtrapolationType_t
{
    REVERSE_GRID_EXTRAPOLATION_NEAREST,                  /**< Duplicate the coordinate of nearest neighbor */
    REVERSE_GRID_EXTRAPOLATION_MV_NEAREST,               /**< Duplicate the motion vector of nearest neighbor */
    REVERSE_GRID_EXTRAPOLATION_APPROX_LINEAR             /**< Approximate linear extrapolation (this is the recommended value)  */
} NcLibReverseGridExtrapolationType;

/** NcLibWarpReverseGridDirection() input struct */
typedef struct NcLibWarpReverseGridDirectionIn_t
{
    uint32_t                      numRows;                           /**< Number of rows in (forward) arrays srcGridRowCoords and dstCoords */
    uint32_t                      numColumns;                        /**< Number of columns in (forward) arrays srcGridColumnCoords and dstCoords */
    float*                        srcGridRowCoords;                  /**< Source rectangular grid - location of rows */
    float*                        srcGridColumnCoords;               /**< Source rectangular grid - location of columns */
    NcLibWarpGridCoord*           dstCoords;                         /**< 2-dimensional array of destination coordinates */
    NcLibUniformGridTriangulation inputTriangulationType;            /**< Triangulation type to be used at source grid */
    NcLibReverseGridExtrapolationType extrapolationType;             /**< Extrapolation type used for out-of-grid samples.
                                                                      *   Recommended value is REVERSE_GRID_EXTRAPOLATION_APPROX_LINEAR. */
    uint32_t                      reversedGridNumRows;               /**< Number of rows in reversed grid */
    uint32_t                      reversedGridNumColumns;            /**< Number of columns in reversed grid */
    NcLibWarpGridCoord            reversedGridSourceTopLeft;         /**< Reversed grid: first x and y coordinate of source grid */
    NcLibWarpGridCoord            reversedGridSourceBottomRight;     /**< Reversed grid: last x and y coordinate of source grid */
    bool                          useExtraCalcsDuringExtrpolation;   /**< Relevant only when extrapolationType is equal to
                                                                      *   REVERSE_GRID_EXTRAPOLATION_NEAREST or REVERSE_GRID_EXTRAPOLATION_MV_NEAREST.
                                                                      *  Indicates that extra calculations will be done in order
                                                                      *  to handle corner cases during extrapolation (if required).
                                                                      *  By default should be false to avoid run time penalty.
                                                                      */
} NcLibWarpReverseGridDirectionIn;

/** Struct that contains the statistics on the operation of NcLibWarpReverseGridDirection() */
typedef struct NcLibWarpReverseGridStatistics_t
{
    float extrapolationPercentage;      /**< Percentage of the Grid points that were extrapolated */
}NcLibWarpReverseGridStatistics;
#pragma pack(pop)

/** Alignment mode */
enum NcLibAlignmentMode
{
    NCLIB_ALIGN_IMAGE_BASED_ONLY,
    NCLIB_ALIGN_GYRO_BASED_ONLY,
    NCLIB_ALIGN_AUTO
};

/** Alignment type */
enum NcLibAlignmentType
{
    NCLIB_ALIGN_IMAGE_BASED,
    NCLIB_ALIGN_GYRO_BASED,
    NCLIB_NO_ALIGNMENT
};

/** NcLibAlignmentFusion() input struct */
struct NcLibAlignmentFusionIn
{
    NcLibWarp*         imageAlign;                        /**< Alignment transform as received from CVP/LRME RANSAC. */
    bool               imageAlignForcedToIdentity;        /**< Is CVP/LRME RANSAC forced to identity, as indicated by RANSAC. */
    NcLibWarp*         gyroAlign;                         /**< Alignment transform received from EIS library. */

    NcLibAlignmentMode mode;                              /**< Alignment mode set in Chromatix. */
    int32_t           imageConfHighThreshold;             /**< RANSAC confidence high threshold set in Chromatix. Will switch from
                                                           *   gyro to image based only if RANSAC confidence is above this threshold.
                                                           *   Range: -1:257.
                                                           */
    int32_t           imageConfLowThreshold;              /**< Low threshold of RANSAC confidence set in Chromatix. Will switch from
                                                           *   image based to gyro only if RANSAC confidence is below this threshold.
                                                           *   Range: -1:257.
                                                           */
    uint32_t           minAge;                            /**< Minimum alignment type frames set in Chromatix. Will switch between gyro
                                                           *   and image based only if did not change type for this number of frames.
                                                           */
    float              absoluteMotion;                    /**< Optional motion indication in pixels, e.g. AMD result. TBD: resolution / dimension. */
    float              absoluteMotionThreshold;           /**< Threshold in pixels set in Chromatix. Absolute motion below this value
                                                           *   will be considered as no motion. TBD: resolution / dimension. */
    uint32_t           absoluteMotionConfidence;          /**< Confidence of motion indication. Range: 0:256. Set to 0 if no indication is present. */
    uint32_t           absoluteMotionConfidenceThreshold; /**< Threshold above which absolute motion is valid. */

    NcLibAlignmentType prevAlignment;                     /**< alignmentType returned from NcLibAlignmentFusion for previous frame. */
    uint32_t           prevAge;                           /**< age returned from NcLibAlignmentFusion for previous frame. */
};

/** NcLibAlignmentFusion() output struct */
struct NcLibAlignmentFusionOut
{
    NcLibWarp*            alignmentTransform;  /**< Will point to either imageAlign or gyroAlign. May be NULL if alignmentType
                                                *   is NCLIB_NO_ALIGNMENT, in which case unity matrix should be used.
                                                */
    NcLibAlignmentType    alignmentType;       /**< The selected alignment. Need to be saved for the next frame. */
    uint32_t              age;                 /**< The selected alignment age in frames. Need to be saved for the next frame. */
};


/** Input struct for NcLibTranslateFdDomains */
struct NcLibRectangle
{
    int32_t left;
    int32_t top;
    int32_t width;
    int32_t height;
};

/** Types of generic grids */
enum NcLibGridTypeBits
{
    NCLIB_GRID_SAMPLES_ON_EDGES = 1, /**< Set this bit if a grid has samples on the perimeter of the mapped area,
                                      *   leave it unset if the samples are in within the mapped area.
                                      *       Type 0           Type 1
                                      *   -------------    g---g---g---g
                                      *   | g | g | g |    |   |   |   |
                                      *   -------------    g---g---g---g
                                      *   | g | g | g |    |   |   |   |
                                      *   -------------    g---g---g---g
                                      *   | g | g | g |    |   |   |   |
                                      *   -------------    g---g---g---g  */
    NCLIB_GRID_CENTERED = 2          /**< Set this bit if the grid values are relative to the image center
                                     *    (e.g., grid[0][0] = {-width/2, -height/2}),
                                     *    leave it unset if the values are relative to the image top left corner
                                     *    (e.g., grid[0][0] = { 0,0 }),*/
};

// WindowRegionFl is same as WindowRegionF which EIS gets, had to rename to avoid redeclaration
typedef struct WindowRegionFl_s
{
    float    fullWidth;
    float    fullHeight;
    float    windowWidth;
    float    windowHeight;
    float    windowLeft;
    float    windowTop;
} WindowRegionFl;

/*------------------------------------------------------------------------
*       API Functions
* ----------------------------------------------------------------------- */

/**
*  @brief   Converts Warp struct from general domain into virtual domain
*
*  @param [in]      in      Input struct
*  @param [in,out]  out     Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpConvertToVirtualDomain(
    const NcLibWarp* in,
    NcLibWarp*       out);

/**
*  @brief   Converts Grid from general domain into virtual domain
*
*  @param [in]      in      Input grid
*  @param [out]     out     Output grid, can be same as in for in-place conversion
*
*  @return NC_LIB_SUCCESS for success, error code otherwise.
*/
int32_t NcLibConvertGridToVirtualDomain(
    const NcLibIcaGrid* in,
    NcLibIcaGrid*       out);

/**
*  @brief   Generates assist grid from matrices
*
*  @param [in]      in      Input struct
*  @param [in,out]  out     Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpBuildAssistGrid(
    const NcLibWarpBuildAssistGridIn*    in,
    NcLibWarpBuildAssistGridOut*         out);

/**
*  @brief   NcLibGetMaxNumOfPasses used to determined maximal number of passes in IPE
*           All input sizes are defined for digital zoom of X1 (no digital zoom)
*           Number of passes does not depend on digital zoom. ( DC4/DC16/DC64 size won't be decrease )
*
*  @param [in]      ipeInputSize            Input image dimensions for IPE (as supplied to FW)
*  @param [in]      stabilizationMargins    Stabilization total margin (as supplied to FW)
*  @param [in]      icaUpScaleRatio_AtDZx1  upscale done in ICA for digital zoom X1, example upscale for
*                                                        MFSR in DZ=1 or upscale for virtual margins that is done in ICA
*                                                        (currently it is done in QSeed)
*  @param [in]      maxNumOfPassesByFlow    limit max number of passes according to flow decision,
*                                           for example video uses max of 3 passes regardless of image size
*
*  @param [out]     maxNumOfPasses          Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibGetMaxNumOfPasses(
    const NcLibImageSize*        ipeInputSize,
    const NcLibImageSize*        stabilizationMargins,
    float                        icaUpScaleRatio_AtDZx1,
    uint32_t                     maxNumOfPassesByFlow,
    uint32_t*                    maxNumOfPasses);


/**
*  @brief   Corrects LNR and FD parameters according to LDC / Stabilization that was performed.
*
*  @param [in]      in      Input struct
*  @param [in,out]  out     Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpGeometries(
    const NcLibWarpGeomIn*   in,
    NcLibWarpGeomOut*        out);

/**
*  @brief   Adjust alignment matrix with Stabilization to get MCTF alignment matrix, generates a transform
*           from previous stabilized image to current stabilized image.
*
*  @param [in]      in          Input struct
*  @param [in,out]  out         Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcMctfTransform(
    const NcLibCalcMctfIn*          in,
    NcLibWarp*                      out);

/**
*  @brief   Align input image transform to aggregated anchor MCTF image.
*
*  @param [in]      transform     Input Warp struct in virtual domain, as converted
*                                       by NcLibWarpConvertToVirtualDomain().
*  @param [in]      alignment     Alignment transform in virtual domain, as converted
*                                       by NcLibWarpConvertToVirtualDomain().
*  @param [in,out]  out           Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcMfnrTransform(
    const NcLibWarp*                transform,
    const NcLibWarp*                alignment,
    NcLibWarp*                      out);

/**
*  @brief   Check NcLib warp struct validity, when applied in ICA.
*
*  @param [in]      in              Input struct
*  @param [in]      fastMode        If true and high resolution grid, will perform a faster but less accurate calculation
*  @param [in,out]  intermediate    Buffer used for internal calculations,
*                                   size of buffer is defined by NC_LIB_WARP_CHECK_ICA_INTERMEDIATE_BUFFER_SIZE
*  @param [out]     valid           Whether the input transformation is valid
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCheckIcaTransformValidity(
    const NcLibCheckIcaTransformValidityIn* in,
    bool                                    fastMode,
    void*                                   intermediate,
    int32_t*                                valid);

/**
*  @brief   Given uniform input grid generates uniform inverse grid (AKA out2in conversion).
*           The function allocates a temporary buffer of approximately 16 * (grid width + height) bytes.
*
*  @param [in]  in              Input struct
*  @param [out] out             Output (reversed-direction) grid points. It is assumed to be pre-allocated (sizeof(NcLibWarpGridCoord) * grid size).
*  @param [out] outStats        (Optional) if not-NULL, then contains the statistics of NcLibWarpReverseGridDirection()
*                               execution.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpReverseGridDirection(
    const NcLibWarpReverseGridDirectionIn*  in,
    NcLibWarpGridCoord*                     out,
    NcLibWarpReverseGridStatistics*         outStats);

/**
*  @brief   Adjust transform grid (e.g. LDC) to a new cropped and zoomed window. The input grid is provided for full FOV mapped
*           to whole virtual domain and the output grid corresponds to new window mapped to whole virtual domain.
*
*  @param [in]  in              Original grid. Coordinates must be provided in virtual domain (i.e. transformDefinedOn should be
*                               VIRTUAL_DOMAIN_WIDTH x VIRTUAL_DOMAIN_HEIGHT).
*  @param [in]  winAtOut        Matching window in output domain.
*  @param [in]  winAtIn         The crop window in input domain.
*  @param [out] out             Output grid matching the IFE zoom window, in virtual domain. Assumed to be pre-allocated.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibResampleGrid(
    const NcLibIcaGrid*      in,
    const NcLibWindowRegion* winAtOut,
    const NcLibWindowRegion* winAtIn,
    NcLibIcaGrid*            out);

/**
*  @brief   Adjust transform grid (e.g. LDC) to a new cropped and zoomed ROI. The input grid is provided for full FOV mapped
*           to whole virtual domain and the output grid corresponds to new window mapped to whole virtual domain.
*
*  @param [in]  in              Original grid. Coordinates must be provided in virtual domain (i.e. transformDefinedOn should be
*                               VIRTUAL_DOMAIN_WIDTH x VIRTUAL_DOMAIN_HEIGHT).
*  @param [in]  winAtOut        Matching ROI in output domain. range: [0, ..., 1.0f]
*  @param [in]  winAtIn         The crop ROI in input domain.  range: [0, ..., 1.0f]
*  @param [out] out             Output grid matching the IFE zoom window, in virtual domain. Assumed to be pre-allocated.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibResampleGridFloat(
    const NcLibIcaGrid* in,
    const NcLibRoi1x1*  winAtOut,
    const NcLibRoi1x1*  winAtIn,
    NcLibIcaGrid*       out);

/**
*  @brief   Calculate minimal distorted window that holds the required data for production of given undistorted window.
*           The returned window is scaled to winAtOut size (winAtIn full size = winAtOut full size).
*           The calculated window does not respect any additional constraints like even number of pixels, centering, aspect
*           ratio, etc.; so further enlargement may be required.
*
*  @param [in]  winAtOut        Required window in undistorted domain.
*  @param [in]  grid            Out-to-in grid. Coordinates must be provided in virtual domain (i.e. transformDefinedOn
*                               should be VIRTUAL_DOMAIN_WIDTH x VIRTUAL_DOMAIN_HEIGHT).
*  @param [out] winAtIn         Matching window in distorted domain scaled to winAtOut size.
*                               Actual window should fully contain this window.
*  @param [in]  forceAr         Force winAtIn to have equal aspect ratio to winAtOut.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcMinInputWindow(
    const NcLibWindowRegion* winAtOut,
    const NcLibIcaGrid*      grid,
    NcLibWindowRegion*       winAtIn,
    bool                     forceAr = false);


/**
*  @brief   Calculate maximum undistorted window that can be produced from distorted window.
*           The out ROI center is assumed to be in the center of virtual domain. The aspect ratio and full output size are
*           derived from origWinAtOut. Other constraints are ignored, like even number of pixels, etc. Thus further reduction
*           may be required.
*
*  @param [in]  winAtIn         Available window in distorted domain.
*  @param [in]  origWinAtOut    Original window in undistorted domain, from which winAtIn was derived. Output aspect ratio and
*                               full size are derived from this window.
*  @param [in]  grid            In-to-out grid. Coordinates must be provided in virtual domain (i.e. transformDefinedOn
*                               should be VIRTUAL_DOMAIN_WIDTH x VIRTUAL_DOMAIN_HEIGHT).
*  @param [out] winAtOut        Matching window in undistorted domain. Actual window should be fully contained in this window.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcMaxOutputWindow(
    const NcLibWindowRegion* winAtIn,
    const NcLibWindowRegion* origWinAtOut,
    const NcLibIcaGrid*      grid,
    NcLibWindowRegion*       winAtOut);

/**
*  @brief   GMO is Global Motion transform provided to Video encoder.
            GMO is based on ICA2 transform - the only difference is PPS crop&upscale (usually due to DZ).
            ICA2 transform already defines the motion between current and previous full images.
            ICA2 is not aware of PPS scaling and offset that is done in PPS on current and previous images.

            It is assumed that matrices (alignmentMatrix and gmoMatrix) are in this format:
            x(n-1) = Mx(n)

*
*  @param [in]  alignmentMatrix              Original ICA2 alignment matrix.
*  @param [in]  isAlignmentMatrixCentralized If true, the alignmentMatrix is centralized (so that
                                             coordinate of the center of top-left pixel is
                                             [-(width-1)/2, -(height-1)/2]).
                                             If false, the alignmentMatrix is relative to top-left
                                             (assuming [0,0] is in the center of top-left pixel).
*  @param [in]  currZoomWindow               Current Zoom window (the window coordinates are relative to top-left).
                                             Defines crop done by PPS and it is assumed that the cropped
                                             window is upscaled to full window size.
*  @param [in]  prevZoomWindow               Previous Zoom window (the window coordinates are relative to top-left)
*  @param [out] gmoMatrix                    The GMO matrix. The matrix is centralized.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibGenerateGMO(
    const NcLibPerspTransformSingle* alignmentMatrix,
    bool                             isAlignmentMatrixCentralized,
    const NcLibWindowRegion*         currZoomWindow,
    const NcLibWindowRegion*         prevZoomWindow,
    NcLibPerspTransformSingle*       gmoMatrix);



/** NcLibGenerateGMOStatistics() input struct */
typedef struct NcLibGenerateGMOStatisticsIn_t
{
    NcLibWarp                alignmentTransform;    /**< The GMO transform.The transform origin(0, 0) is at center of image.
                                                         Transform is after consideration of zoom windows.
                                                         Transform must be defined on virtual domain sizes. */
    NcLibImageSize           dsXImageSize;          /**< Image size which is mapped to ICA1 ROI */

    NcLibWindowRegion        eisFOV;                /**< Window defined by EIS FOV without margins. */
}NcLibGenerateGMOStatisticsIn;

/** NcLibGenerateGMOStatistics() output struct */
typedef struct NcLibGenerateGMOStatisticsOut_t
{
    float                           MV_sum_x;     /**< Sum motion x axis. units are pixels in dsXImageSize*/
    float                           MV_sum_y;     /**< Sum motion y axis. units are pixels in dsXImageSize */
    uint32_t                        MV_num;       /**< Num of MV's */
    NcLibPerspTransformSingle       gmoMatrix;    /**< gmoMatrix defined on size of dsXImageSize */
} NcLibGenerateGMOStatisticsOut;

/**
*  @brief   GMOStatistics is Global Motion movement statistics provided to Video encoder.
alignmentTransform is the transform calculated for ICA2 + adaptations of zoomWindows of IPE if needed.

*  @param [in]   in      Input struct
*  @param [out]  out     Output struct
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibGenerateGMOStatistics(
    NcLibGenerateGMOStatisticsIn*    in,
    NcLibGenerateGMOStatisticsOut*   out);

/**
*  @brief HFR is done as batch processing. Alignment matrix is calculated up to 60 times per second.
          Interpolation is required to get ICA2 transforms at HFR frame rate.
          This function calculates identical ICA2 transforms for each frame in the batch based on alignment transform.
          List of limitations on function call:
          One of the next: grid.enable or matrices.enable should be set to true, but not both.
          if matrices are enabled, only one matrix is supported for HFR.
*
*  @param [in]  batchedAlignmentTransform    Original ICA2 alignment matrix.
                                             Right now only the next alignment transforms are supported (but not together):
                                             a. one matrix
                                             b. grid
                                             It is expected that matrix is aligned to the center before calling this function.
                                             Please note that moving matrix to center and then calling to this function
                                             will return different result than calling to this function and then
                                             moving it to the center.
*  @param [in]  numOfFramesInBatch           Number of frames in the batch (It is expected to be more than one).
*  @param [out] hfrTransform                 The calculated HFR transform.
*                                            It is assumed that same transform structure is allocated for
                                             batchedAlignmentTransform and hfrTransform.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibGenerateHfr(
    const NcLibWarp* batchedAlignmentTransform,
    uint32_t numOfFramesInBatch,
    NcLibWarp* hfrTransform );

/**
*  @brief   The alignment transform for MCTF can be calculated by:
            1. Image-based alignment (LRME/CVP)
            2. Gyro based alignment
            Each option has its advantages and vulnerabilities.
            This function gets the results of both these two alignments
            and choose the best alignment transform.
*
*  @param [in]   in      Input struct
*  @param [out]  out     Output struct
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibAlignmentFusion(
    const NcLibAlignmentFusionIn* in,
    NcLibAlignmentFusionOut* out);

/**
*  @brief   Translate faces coordinates from CVP post-ICA domain to still domain.
*
*  @param [in]   fdRois        Latest available faces data (current or previous frame).
*  @param [in]   roisNum       Number of detected faces (fdRois size).
*  @param [in]   fdDimensions  The CVP ICA out image dimensions.
*  @param [in]   warp          CVP ICA transform. Must be defined on virtual domain.
*  @param [in]   fullSize      Still input size (IFE in).
*  @param [out]  fdOutRois     Faces data in still domain.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibTranslateFdDomains(
    const NcLibRectangle* fdRois,
    uint32_t roisNum,
    const NcLibImageSize* fdDimensions,
    const NcLibWarp* warp,
    const NcLibImageSize* fullSize,
    NcLibRectangle* fdOutRois);

/**
*  @brief   Create WarpGrid struct that points to an existing IcaGrid buffer (shallow copy).
*
*  @param [in]   icaGrid       Original grid struct
*  @param [out]  warpGrid      Output grid struct. grid and gridExtrapolate will point to icaGrid buffers
*  @param [in]   ignoreErrors  Whether to continue if unsupported geometry is passed
*
*  @return true in case of success, false if error occurred and ignoreErrors is true.
*/
bool NcLibIcaGridToWarpGridRef(const NcLibIcaGrid& icaGrid, NcLibWarpGrid& warpGrid, bool ignoreErrors = false);

/**
*  @brief   Copy grid meta data from WarpGrid to IcaGrid.
*
*  @param [in]   warpGrid      Original grid struct
*  @param [out]  icaGrid       Output grid struct. The following fields are not set: reuseGridTransform, grid, gridCorners.
*
*  @return true in case of success, false in case of error.
*/
bool NcLibWarpGridToIcaGridMeta(const NcLibWarpGrid& warpGrid, NcLibIcaGrid& icaGrid);

/**
*  @brief   Copy WarpGrid to IcaGrid (deep copy).
*
*  @param [in]   warpGrid      Original grid struct
*  @param [out]  icaGrid       Output grid struct
*
*  @return true in case of success, false in case of error.
*/
bool NcLibWarpGridToIcaGrid(const NcLibWarpGrid& warpGrid, NcLibIcaGrid& icaGrid);

/**
*  @brief   Copy IcaMatrices to WarpMatrices (deep copy).
*
*  @param [in]   icaMatrices       Original matrices struct
*  @param [out]  warpMatrices      Output matrices struct
*
*  @return true in case of success, false in case of error.
*/
bool NcLibIcaMatricesToWarpMatrices(const NcLibIcaMatrices& icaMatrices, NcLibWarpMatrices& warpMatrices);

/** Mode dictating whether to merge output warp components. */
enum NcLibWarpMergeMode
{
    NCLIB_WARP_MERGE_FORCE_OFF,     /**< Output warp is {Matrices, Grid} */
    NCLIB_WARP_MERGE_FORCE_ON,      /**< Output warp is a merged grid or matrices only */
    NCLIB_WARP_MERGE_AUTO_FIX       /**< Output warp is {Matrices, Grid} for optimization unless matrices cause breach */
};

/**
*  @brief   Combines two warp transformation structures. Mathematically speaking, OutputWarp() = firstWarp(secondWarp()).
*           Note that all enabled transformations must be in virtual domain.
*
*                                       Composition Order:
*                ______________      __________________      _______________     ___________________
*            In |              |    |                  |    |               |   |                   | Out
*           <---|firstWarp.Grid|<---|firstWarp.Matrices|<---|secondWarp.Grid|<--|secondWarp.Matrices|<--
*               |______________|    |__________________|    |_______________|   |___________________|
*
*
*  @param [in]              firstWarp       The first warp (For ICA 3.0: grid is OIS+LDC+RSC, matrix is either anchor alignment or disabled).
*  @param [in]              secondWarp      The second warp (For ICA 3.0: grid is DIS, matrices are EIS+SAT).
*  @param [in]              mergeMode       If enabled (or auto-mode & matrices cause breach) the output warp will be merged.
*                                           This is less optimized and should only be done when restricted by flow.
*  @param [in]              output_crop_fov (MERGE_AUTO_FIX mode only) Output crop FOV from the virtual domain.
*  @param [in, out]         output          The resulting composite warp, buffer is allocated by the user. Could be grid, matrices, or both.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpComposition(
    const NcLibWarp* firstWarp,
    const NcLibWarp* secondWarp,
    const NcLibWarpMergeMode mergeMode,
    const WindowRegionFl* output_crop_fov,
    NcLibWarp* output);

/**
*  @brief   Combines three warp transformation structures.
*           Mathematically speaking, OutputWarp() = perspective2in(perspectiveTransform(out2perspective())).
*           Note that all grid transformations must be in virtual domain.
*           perspectiveTransform is defined on image domain.
*
*                                     Composition Order
*       ____________________        ____________________       ____________________
* In   |                    |      |                    |     |                    |  Out
*<---  |perspective2in.Grid | <--- |perspectiveTransform|<--- |out2perspective.Grid|  <--
*      |____________________|      |____________________|     |____________________|
*
*
*  @param [in]       out2perspective              out2in grid defined in virtual domain. E.g. current rectification grid.
*  @param [in]       perspectiveTransform         out2in perspective centered transform that is fixed. Defined on image domain.
*  @param [in]       perspective2in               Inverse out2in grid defined in virtual domain. E.g. previous derectification grid.
*  @param [in]       perspectiveDefinedOnSize     The domain in pixels of perspectiveTransform
*  @param [in]       outPerspectiveDefinedOnSize  The domain in pixels of outPerspectiveTransform
*  @param [out]      outPerspectiveTransform      The resulting composite centered matrix.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibPerspectiveTransformDomainChange(
    const NcLibWarpGrid &out2perspective,
    const NcLibPerspTransformSingle &perspectiveTransform,
    const NcLibWarpGrid &perspective2in,
    const NcLibImageSize perspectiveDefinedOnSize,
    const NcLibImageSize outPerspectiveDefinedOnSize,
    NcLibPerspTransformSingle &outPerspectiveTransform);

/**
*  @brief   Combines three warp transformation structures.
*           Mathematically speaking, OutputWarp() = perspective2in(perspectiveTransform(out2perspective())).
*           Note that perspective2in and out2perspective transformations must be in virtual domain.
*           perspectiveTransform is defined on image domain.
*
*                                       Composition Order
*              ________________        ____________________       _________________
*        In   |                |      |                    |     |                 |  Out
*       <---  | perspective2in | <--- |perspectiveTransform|<--- | out2perspective |  <--
*             |________________|      |____________________|     |_________________|
*
*
*  @param [in]       out2perspective              out2in perspective defined in virtual domain. E.g. current rectification perspective.
*  @param [in]       perspectiveTransform         out2in perspective centered transform that is fixed. Defined on image domain.
*  @param [in]       perspective2in               Inverse out2in perspective defined in virtual domain. E.g. previous derectification perspective.
*  @param [in]       perspectiveDefinedOnSize     The domain in pixels of perspectiveTransform
*  @param [in]       outPerspectiveDefinedOnSize  The domain in pixels of outPerspectiveTransform
*  @param [out]      outPerspectiveTransform      The resulting composite centered matrix.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibPerspectiveTransformDomainChange(
    const NcLibPerspTransformSingle &out2perspective,
    const NcLibPerspTransformSingle &perspectiveTransform,
    const NcLibPerspTransformSingle &perspective2in,
    const NcLibImageSize perspectiveDefinedOnSize,
    const NcLibImageSize outPerspectiveDefinedOnSize,
    NcLibPerspTransformSingle &outPerspectiveTransform);

/**
*  @brief   Transforms an alignment from one domain to another via a common base domain.
*           E.g., if an alignment was calculated on ERS-corrected frames but is needed for LDC-only frames.
*           The needed alignment can be calculated using grid transforms from ERS to distorted and from LDC to distorted.
*           All transforms must be in virtual domain and out-to-in direction.
*
*                                     Composition Order
*                ____________       ___________________       _________       ___________________       ____________
*            In |            |     |                   |     |         |     |                   |     |            | Out
*           <-- |prevOut2Base| <-- |prevAlign2Base(inv)| <-- |alignment| <-- |currAlign2Base(inv)| <-- |currOut2Base| <--
*               |____________|     |___________________|     |_________|     |___________________|     |____________|
*
*  @param [in]       currOut2Base                 Transform from output domain to common base domain for the current frame.
*                                                 In the above example - LDC grid. Out-2-in, in Virtual Domain.
*  @param [in]       currAlign2Base               Transform from alignment domain to common base domain for the current frame.
*                                                 In the above example - current ERS grid. Out-2-in, in Virtual Domain.
*  @param [in]       alignment                    Alignment transform. Out-2-in, centered in Virtual Domain.
*  @param [in]       prevOut2Base                 Transform from output domain to common base domain for the previous frame.
*                                                 In the above example - LDC grid. Out-2-in, in Virtual Domain.
*  @param [in]       prevAlign2Base               Transform from alignment domain to common base domain for the previous frame.
*                                                 In the above example - previous ERS grid. Out-2-in, in Virtual Domain.
*  @param [out]      outAlignment                 Alignment matrix in output domain.
*
*  @return NC_LIB_SUCCESS for success, error code otherwise.
*/
int32_t NcLibAlignmentDomainChange(
    const NcLibWarpGrid& currOut2Base,
    const NcLibWarpGrid& currAlign2Base,
    const NcLibWarpMatrices& alignment,
    const NcLibWarpGrid& prevOut2Base,
    const NcLibWarpGrid& prevAlign2Base,
    NcLibWarpMatrices& outAlignment);

/**
*  @brief   Inverts the warp (either grid or single matrix) provided as input.
*
*  @param [in]      in          Input warp struct.
*  @param [in,out]  out         Output Warp struct, buffer is allocated by the user.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcInverseWarp(const NcLibWarp& in, NcLibWarp& out);

/**
*  @brief   Warp input coordinates based on transform.
*
*  @param [in]      inPoints           Array of input coordinates that will be warped.
*                                      The coordinates are defined on inSize and relative to the ROI mapped to warp domain.
*  @param [in]      numOfPoints        number of inPoints/outPoints in the array.
*  @param [in]      warp               Pointer to input warp struct. Needs to be defined on virtual domain.
*  @param [in]      inSize             Image size on which the input points were sampled. The warp ROI is assumed to match this size.
*  @param [in]      outSize            Image size on which the output points are defined. The warp ROI is assumed to match this size.
*  @param [out]     outPoints          The warped coordinates relative to outSize.
*                                      The buffer should be allocated by the caller: sizeof(NcLibWarpGridCoord) * numOfPoints.
*                                      Only the first numOfPoints entries are valid.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpPoints(
    const NcLibWarpGridCoord* inPoints,
    const uint32_t numOfPoints,
    const NcLibWarp* warp,
    const NcLibFloat2* inSize,
    const NcLibFloat2* outSize,
    NcLibWarpGridCoord* outPoints);

/**
*  @brief   Resample a grid to an ICA grid
*
*  @param [in]      rawGridX           X part of the source grid
*  @param [in]      rawGridY           Y part of the source grid
*  @param [in]      gridSize           Number of samples in the source grid.
*  @param [in]      gridType           Combination of optional NcLibGridTypeBits.
*  @param [in]      gridArea           The size of the image on which the grid is defined, and the area of the grid relative to
*                                      the image. This size is assumed to be mapped to ICA virtual domain.
*  @param [in]      icaGridGeometry    Required output grid size, either NcLibIcaGrid35x27 or NcLibIcaGrid67x51
*  @param [out]     icaGrid            Output grid
*
*  @return NC_LIB_SUCCESS in case of success, error code in case of failure.
*/
int32_t NcLibResampleGridForIca(
    const double* rawGridX,
    const double* rawGridY,
    NcLibImageSize gridSize,
    uint32_t gridType,
    NcLibROI gridArea,
    NcLibIcaGridGeometry icaGridGeometry,
    NcLibIcaGrid* icaGrid);

/**
*  @brief   Center a top-left matrix and then scale it.
*           Use to calculate ICA transform based on DME processing.
*           Can run in-place (in == out).
*
*  @param [in]   centerW              Image center X, before scaling
*  @param [in]   centerH              Image center Y, before scaling
*  @param [in]   upscaleW             Transform upscale factor X. > 1 means the new domain is larger than the old domain.
*                                     Pass 1 for no scaling.
*  @param [in]   upscaleH             Transform upscale factor Y. > 1 means the new domain is larger than the old domain.
*  @param [in]   in                   Input transform perspective matrix, 9 floats
*  @param [out]  out                  Output transform perspective matrix, 9 floats allocated by the caller.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCenterAndScaleMatrix(float centerW, float centerH, float upscaleW, float upscaleH, const float* in, float* out);

/**
*  @brief   Combines two warp transformation structures similar to NcLibWarpComposition but make sure that overall
*           transform doesn't breach as a result of the MFHDR alignment matrix
*           To be use only if operating alignment matrix on the anchor itself for MFHDR only
*           Otherwise will cause issues for any other flow used in
*
*           WARNING : The function is not general and composite ica1 in case of Lahaina MFHDR flow.
*                     There is assumption that firstWarp matrix is alignment from short to long
*                     and can be disabled without harming any other flow.
*
*           Note that all enabled transformations must be in virtual domain.
*
*                                     Composition Order
*       UD grid short        align short to long            None          Stab matrix long (+DIS+SAT)
*      ______________        __________________        _______________       ___________________
* In  |              |      |                  |      |               |     |                   | Out
*<--- |firstWarp.Grid| <--  |firstWarp.Matrices| <--- |secondWarp.Grid| <-- |secondWarp.Matrices| <--
*     |______________|      |__________________|      |_______________|     |___________________|
*
*                               OutputWarp() = firstWarp(secondWarp())
*
*
*  @param[in]       firstWarp         The first warp(For ICA 3.0: grid is OIS + LDC + RSC, matrix is either anchor alignment or disabled)
*  @param[in]       secondWarp        The second warp(For ICA 3.0: grid is DIS, matrices are EIS + SAT)
*  @param[in]       output_crop_fov   ICA crop FOV, same values exactly as fed to EIS
*  @param[in, out]  output            The resulting composite warp, buffer is allocated by the user.Could be grid, matrices, or both.
*  @param[out]      alignmentMatrixStrengthFinal Alignment strength that is chosen (so it doesn't breach).
*                                     Set to 1.0 if transformed is not fixed, 0.0 is for Identity transform was taken due to breach.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpComposition_MFHDR_NoBreach(
    const NcLibWarp* firstWarp,
    const NcLibWarp* secondWarp,
    WindowRegionFl   output_crop_fov,
    NcLibWarp*       output,
    float*           alignmentMatrixStrengthFinal);

/**
* @brief   Enforce grid transform so that, excluding the alignment margins,
*          no point along the grid is mapped (o2i) outside the virtual domain.
*
*  @param[in, out]  grid                Grid transform to be verified and modified in case of breach
*  @param[in]       alignmentMargins    Alignment margins in ratio [0, 1) e.g. 0.02f means 2% of the grid is allocated to alignment margins
*  @param[out]      bFactor             Blend factor [0, 1]: 1 = grid unchanged, 0 = grid fully replaced with unity
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibWarpVerifyGrid_NoBreach(
    NcLibWarpGrid* grid,
    const float alignmentMargins,
    float* bFactor);

#endif /* __NC_LIB_WARP_API__ */
