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

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxawbrinterface.h
/// @brief Auto White Balance - Refinement algorithm interfaces
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXAWBRINTERFACE_H
#define CAMXAWBRINTERFACE_H

#include "chistatsinterfacedefs.h"
#include "chistatsdebug.h"
#include "chiispstatsdefs.h"
#include "chiawbinterface.h"

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

// Data structures that are exposed to OEM must be packed to have the expected layout.
#pragma pack(push, CDK_PACK_SIZE)


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Describe AWBR Algorithm Input Data definition
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// @brief Defines the illuminant factors.
typedef struct
{
    BOOL    isAvailable;                ///< Indicates whether white balance calibration data is available.
                                        ///
                                        ///  @valuesbul
                                        ///  - 0 -- FALSE
                                        ///  - 1 -- TRUE @tablebulletend

    UINT32  correlatedColorTemperature; ///< CCT in degrees Kelvin.
    FLOAT   ratioRG;                    ///< Red-green ratio.
    FLOAT   ratioBG;                    ///< Blue-green ratio.
} AWBRAlgoIlluminatFactor;

/// @brief Defines the illuminant calibration factors.
typedef struct
{
    UINT32                      numberOfIlluminants;                ///< Number of illuminants that are calibrated.
    AWBRAlgoIlluminatFactor     illuminant[StatsIlluminantCount];   ///< Array of calibration factors.
} AWBRAlgoIlluminantsCalibrationFactor;

/// @brief Exposure information that is input to the AWBR algorithm.
typedef struct
{
    FLOAT   luxIndex;       ///< Indicates the scene brightness.

    BOOL    AECSettled;     ///< Indicates whether the AEC is currently settled.
                            ///
                            ///  @valuesbul
                            ///  - 0 -- FALSE
                            ///  - 1 -- TRUE @tablebulletend

    UINT64  frameDuration;  ///< Indicates the length of the frame (in milliseconds).
    FLOAT   frameLuma;      ///< Average brightness of the frame.
} AWBRAlgoAECData;

/// @brief Identifies the type of input to AWBR algorithm.
typedef struct
{
    AWBGainParams   gainParams;     ///< Applied WBGains
    AWBAlgoMode     awbMode;        ///< Auto white balance mode
    BOOL            awbLock;        ///< Auto white balance lock state
} AWBRAlgoAWBData;

/// @brief Identifies the type of input to AWBR algorithm.
typedef enum
{
    AWBRInputTypeInvalid         = -1,          ///< Type is unknown or invalid.

    AWBRInputTypeGSStats,                       ///< Payload: #AWBRStats
    AWBRInputTypeLastIndex,                     ///< Last valid index of the enumeration.
    AWBRInputTypeMax             = 0x7FFFFFFF,  ///< Indicates the last item in the definition.
} AWBRAlgoInputType;

/// @brief Base structure of a Process input parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoInputList.
typedef struct
{
    VOID*               pAWBRInput;       ///< Pointer to the parameter payload.
    UINT32              sizeOfAWBRInput;  ///< Size of the payload data (in bytes).
    AWBRAlgoInputType   inputType;       ///< Type of input payload.
} AWBRAlgoInput;

/// @brief List of Process input parameters that are passed to #AWBRAlgorithm::AWBRProcess().
typedef struct
{
    AWBRAlgoInput*   pAWBRInputs;   ///< Pointer to the array of  parameters.
    UINT32           inputCount;    ///< Number of elements in the array.
} AWBRAlgoInputList;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Describe AWBR Algorithm Output Data definition
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// @brief AWBR gains for red, green, and blue channels.
typedef struct
{
    FLOAT   red;    ///< Gains on the red channel.
    FLOAT   green;  ///< Gains on the green channel.
    FLOAT   blue;   ///< Gains on the blue channel.
} AWBRAlgoGains;


typedef struct
{
    ParsedGSStatsOutput     parsedStats;
    StatisticsStartUp       startupMode;                   ///< Startup mode for statistics data.
} AWBRStats;


/// @brief Contains configuration parameters for IPE Grid statistics.
struct GSStatsConfig
{
    BOOL                   blackLevelOffsetEnable;                     ///< Indicates if blackLevelResOffset is set by IFE.
                                                                       ///  True --> Set by IFE
                                                                       ///  False --> Set to 0
    UINT32                 offsetSubtraction[RGBChannelCount];         ///< Offset Subtractionfor for each channel
                                                                       ///  indexed by one of the ChannelIndex values.
    FLOAT                  YStatsWeights[RGBChannelCount];             ///< Y statistics channel weights indexed by one of
                                                                       ///  the ChannelIndex values.
    INT32                  horizontalNum;                              ///< Number of horizontal regions.
    INT32                  verticalNum;                                ///< Number of vertical regions.
    RectangleCoordinate    ROI;                                        ///< ROI coordinates to configure.
    UINT32                 highChannelGainThreshold[RGBChannelCount];  ///< Maximum gain threshold for each channel.
    INT32                  lowChannelGainThreshold[RGBChannelCount];   ///< Lower gain threshold for each channel.
    UINT8                  inverseWBEnable;                            ///< Indicate inverse WB is enabled.
    FLOAT                  inverseWBGain[RGBChannelCount];             ///< Inverse WB gain indexed by one of
                                                                       ///  the ChannelIndex values.
    UINT32                 regionHeight;                               ///< Height of each statistics subgrid region.
    UINT32                 regionWidth;                                ///< Width of each statistics subgrid region.
    UINT32                 outputBitDepth;                             ///< Bit depth of stats
};

/// @brief Types of Process output parameters for the AWBR algorithm.
typedef enum
{
    AWBROutputTypeInvalid            = -1,           ///< Type is unknown or invalid.
    AWBROutputTypeGains,                             ///< Payload: #AWBRAlgoGains
                                                     ///  Payload: LocalGainAdjustData
    AWBROutputTypeGSConfig,                          ///< GSConfig
    AWBROutputTypeLastIndex,                         ///< Last valid index of the enumeration.
    AWBROutputTypeMax                = 0x7FFFFFFF,   ///< Indicates the last item in the definition.
} AWBRAlgoOutputType;

/// @brief Base structure of a Process output parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoOutputList.
typedef struct
{
    VOID*               pAWBROutput;                ///< Pointer to the payload that is the result of the query. The type of data
                                                    ///  depends on the value of outputType. The algorithm implementer must do a
                                                    ///  deep copy to the specified memory.
    UINT32              sizeOfAWBROutput;           ///< Size of the payload data (in bytes).
    UINT32              sizeOfWrittenAWBROutput;    ///< Size of the payload (in bytes) that is written back.
                                                    ///  If there is no output, set this parameter to 0.
    AWBRAlgoOutputType  outputType;                 ///< Type of output payload.
} AWBRAlgoOutput;

/// @brief List of Process output parameters that are passed to #AWBRAlgorithm::AWBRProcess().
typedef struct
{
    AWBRAlgoOutput*     pAWBROutputs;       ///< Pointer to the array of parameters.
    UINT32              outputCount;        ///< Number of elements in the array.
} AWBRAlgoOutputList;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Describe AWBR Algorithm Get Parameter definition
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// @brief Get parameters for queries from the AWBR algorithm.
typedef enum
{
    AWBRGetParamTypeInvalid                      = -1,          ///< Type is unknown or invalid.
    AWBRGetParamGSStatsRequired,                                ///< Query the AWB-R algo if the GS Stats Link is required.
                                                                ///  No Algo processing when link disabled.
                                                                ///  Payload: BOOL
    AWBRGetParamTypeLastIndex,                                  ///< Last valid index of the enumeration.
    AWBRGetParamTypeMax                          = 0x7FFFFFFF,  ///< Indicates the last item in the definition.
} AWBRAlgoGetParamType;

/// @brief Types of Get input parameters for the AWBR algorithm.
typedef enum
{
    AWBRGetParamInputTypeInvalid             = -1,           ///< Type is unknown or invalid.
    AWBRGetParamInputAECData,                                ///< AEC Data passed to algo to retrieve isGSStatsRequired flag
                                                             ///  Payload: AWBRAlgoAECData
    AWBRGetParamInputTypeLastIndex,                          ///< Last valid index of the enumeration.
    AWBRGetParamInputTypeMax                 = 0x7FFFFFFF,   ///< Indicates the last item in the definition.
} AWBRAlgoGetParamInputType;

/// @brief Base structure of a Get input parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoGetParamInputList.
typedef struct
{
    VOID*                       pGetParamInput;         ///< Pointer to the parameter payload.
    UINT32                      sizeOfGetParamInput;    ///< Size of the payload data (in bytes).
    AWBRAlgoGetParamInputType   getParamInputType;      ///< Type of input payload.
} AWBRAlgoGetParamInput;

/// @brief List of Get input parameters for a query from the AWBR algorithm. This list is passed to #AWBRAlgoGetParam.
typedef struct
{
    AWBRAlgoGetParamInput*   pGetParamInputs;       ///< Pointer to the array of parameters.
    UINT32                   getParamInputCount;     ///< Number of elements in the array.
} AWBRAlgoGetParamInputList;

/// @brief Types of Get output parameters for queries from the AWBR algorithm.
typedef enum
{
    AWBRGetParamOutputTypeInvalid                    = -1,           ///< Type is unknown or invalid.
    AWBRGetParamOutputGSStatsRequired,                               ///<  Flag to enable/disable the GS Stats Link
                                                                     ///   Payload: Bool
    AWBRGetParamOutputTypeLastIndex,                                 ///< Last valid index of the enumeration.
    AWBRGetParamOutputTypeMax                        = 0x7FFFFFFF,   ///< Indicates the last item in the definition.
} AWBRAlgoGetParamOutputType;

/// @brief Base structure of a Get output parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoGetParamOutputList.
typedef struct
{
    VOID*                       pGetParamOutput;                ///< Pointer to the payload that is the result of the query.
                                                                ///  The type of data depends on the value of
                                                                ///  getParamOutputType. The algorithm implementer must do
                                                                ///  a deep copy to the specified memory.
    UINT32                      sizeOfGetParamOutput;           ///< Size of the payload data (in bytes).
    UINT32                      sizeOfWrittenGetParamOutput;    ///< Size of the payload (in bytes) that is written back.
                                                                ///  If there is no output, set this parameter to 0.
    AWBRAlgoGetParamOutputType  getParamOutputType;             ///< Type of output payload.
} AWBRAlgoGetParamOutput;

/// @brief Get output parameters for a query from the AWBR algorithm. This structure is used with #AWBRAlgoGetParam.
typedef struct
{
    AWBRAlgoGetParamOutput*  pGetParamOutputs;          ///< Pointer to the array of parameters.
    UINT32                   getParamOutputCount;       ///< Number of elements in the array.
} AWBRAlgoGetParamOutputList;

/// @brief List of Get parameters that are passed to #AWBRAlgorithm::AWBRGetParam().
typedef struct
{
    AWBRAlgoGetParamType         type;              ///< Type of information to get from the algorithm. This type describes the
                                                    ///  metadata for the caller.
    AWBRAlgoGetParamInputList    inputInfoList;     ///< Input data that is necessary to support the query.
    AWBRAlgoGetParamOutputList   outputInfoList;    ///< Output metadata that is returned as a result of the query.
} AWBRAlgoGetParam;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Describe AWBR Algorithm Set Parameter definition
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// @brief Identifies the type of input parameter to AWBR algorithm.
typedef enum
{
    AWBRSetParamTypeInvalid                          = -1,           ///< Type is unknown or invalid.
    AWBRSetParamTypeRequestId,
    AWBRSetParamTypeCameraInfo,
    AWBRSetParamTypeChromatixData,
    AWBRSetParamTypeAECData,                       ///< Payload: #AWBRAlgoAECData
    AWBRSetParamTypeAWBData,                       ///< Payload: #AWBRAlgoAWBData

    AWBRSetParamTypeOverrideSettings ,
    AWBRSetParamTypeIlluminantsCalibrationFactor,
    AWBRSetParamTypeLastIndex,                                       ///< Last valid index of the enumeration.
    AWBRSetParamTypeMax                              = 0x7FFFFFFF,   ///< Indicates the last item in the definition.
} AWBRAlgoSetParamType;

/// @brief Base structure of a Set parameter for an AWBR algorithm instance. This structure is used with #AWBRAlgoSetParamList.
typedef struct
{
    const VOID*         pAWBRSetParam;          ///< Pointer to the parameter payload.
    UINT32              sizeOfInputParam;       ///< Size of the payload data (in bytes).
    AWBRAlgoSetParamType setParamType;          ///< Type of parameter that is passed to the algorithm.
} AWBRAlgoSetParam;

/// @brief List of Set parameters that are passed to #AWBRAlgorithm::AWBRSetParam().
typedef struct
{
    AWBRAlgoSetParam*    pAWBRSetParams;        ///< Pointer to the array of parameters.
    UINT32              inputParamsCount;       ///< Number of elements in the array.
} AWBRAlgoSetParamList;

/// @brief Parameters used when creating an AWBR algorithm instance.
typedef enum
{
    AWBRCreateParamsTypeInvalid              = -1,          ///< Type is unknown or invalid.
    AWBRCreateParamsTypeLogger,                             ///< Pointer to the logging function.
                                                            ///  Payload: Statistics logger function
    AWBRCreateParamsTypeTuningData,
    AWBRCreateParamsTypeCalibrationData,
    AWBRCreateParamsTypeCount,                              ///< Total number of parameters.
    AWBRCreateParamsTypeMax                  = 0x7FFFFFFF   ///< Indicates the last item in the definition.
} AWBRAlgoCreateParamType;

/// @brief Base structure of a Create parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoCreateParamList.
typedef struct
{
    VOID*                   pCreateParam;       ///< Pointer to the parameter payload.
    UINT32                  sizeOfCreateParam;  ///< Size of the payload data (in bytes).
    AWBRAlgoCreateParamType  createParamType;    ///< Type of parameter that is passed to the algorithm.
} AWBRAlgoCreateParam;

/// @brief List of Create parameters that are passed to CREATEAWBR().
typedef struct
{
    AWBRAlgoCreateParam* pCreateParams;        ///< Pointer to the array of parameters.
    UINT32              createParamsCount;    ///< Number of elements in the array.
} AWBRAlgoCreateParamList;

/// @brief Types of Destroy parameters used for the AWBR algorithm.
typedef enum
{
    AWBRDestroyParamTypeInvalid               = -1,          ///< Type is unknown or invalid.
    AWBRDestroyParamTypeCameraInfo,
    AWBRDestroyParamTypeMax                   = 0x7FFFFFFF   ///< Indicates the last item in the definition.
} AWBRAlgoDestroyParamType;

/// @brief Base structure of a Destroy parameter for an AWBR algorithm instance. This structure is used with
///        #AWBRAlgoDestroyParamList.
typedef struct
{
    AWBRAlgoDestroyParamType destroyParamType;       ///< Type of parameter that is passed to the algorithm.
    VOID*                   pParam;                 ///< Pointer to the parameter payload.
    UINT32                  sizeOfParam;            ///< Size of the payload data (in bytes).
} AWBRAlgoDestroyParam;

/// @brief List of Destroy parameters that are passed to #AWBRAlgorithm::AWBRDestroy().
typedef struct
{
    AWBRAlgoDestroyParam* pParamList;    ///< Pointer to the array of parameters.
    UINT32               paramCount;    ///< Number of elements in the array.
} AWBRAlgoDestroyParamList;

/// @brief Defines any manual override settings be set to the algorithm.
typedef struct
{
    // All the override flags will be added here
    // These setting will be used to override tuning settings
    UINT32 profile3A;                    ///< 3A Profiling value
    BOOL   enable3ADebugData;            ///< Flag to enable or disable 3A debug data.
    BOOL   enableConcise3ADebugData;     ///< Flag to enable or disable Concise 3A debug data.
                                         ///  @newpagetable
} AWBRAlgoOverrideSettingParam;


/// @brief Function wrapper for the AWBR algorithm.
typedef struct /** @cond */ AWBRAlgorithm /** @endcond */
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AWBRProcess @endcond
    ///
    /// @brief Runs the AWBR algorithm on the given inputs.
    ///
    /// @datatypes
    /// #AWBRAlgoInputList \n
    /// #AWBRAlgoOutputList
    ///
    /// @param[in] pCHIAWBRAlgorithm  Pointer to the algorithm instance.
    /// @param[in] pInputs           Pointer to the statistics inputs interface.
    /// @param[in] pOutputs          Pointer to the statistics data that the algorithm outputs.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*AWBRProcess)(
        AWBRAlgorithm*           pCHIAWBRAlgorithm,
        const AWBRAlgoInputList*    pInputs,
        AWBRAlgoOutputList*         pOutputs);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AWBRGetParam @endcond
    ///
    /// @brief Retrieves the most up-to-date AWBR algorithm information. Typically, the output is updated after calling
    ///        AWBRProcess().
    ///
    /// @datatypes
    /// #AWBRAlgoGetParam
    ///
    /// @param[in]  pCHIAWBRAlgorithm  Pointer to the algorithm instance.
    /// @param[out] pGetParam         Pointer to the metadata and associated data that is necessary to support the query.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}).
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*AWBRGetParam)(
        AWBRAlgorithm*    pCHIAWBRAlgorithm,
        AWBRAlgoGetParam*    pGetParam);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AWBRSetParam @endcond
    ///
    /// @brief Sets configuration parameters to the AWBR algorithm.
    ///
    /// @datatypes
    /// #AWBRAlgoSetParamList
    ///
    /// @param[in] pCHIAWBRAlgorithm  Pointer to the algorithm instance.
    /// @param[in] pSetParams        Pointer to the input parameter list. Each element in the list is of
    ///                              type #AWBRAlgoSetParamType.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*AWBRSetParam)(
        AWBRAlgorithm*             pCHIAWBRAlgorithm,
        const AWBRAlgoSetParamList*   pSetParams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AWBRGetFeatureCapability @endcond
    ///
    /// @brief Gets the features supported by the AWBR algorithm. This interface can be invoked after the algorithm is created.
    ///
    /// @param[in] pCHIAWBRAlgorithm  Pointer to the algorithm instance.
    /// @param[in] pFeatures         Pointer to the feature capabilities that the algorithm supports.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}).
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*AWBRGetFeatureCapability)(
        AWBRAlgorithm*   pCHIAWBRAlgorithm,
        UINT64*            pFeatures);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AWBRDestroy @endcond
    ///
    /// @brief Destroys a derived instance of the AWBR algorithm interface.
    ///
    /// @datatypes
    /// #AWBRAlgoDestroyParamList
    ///
    /// @param[in] pCHIAWBRAlgorithm  Pointer to the algorithm instance.
    /// @param[in] pDestroyParams    Pointer to the list of parameters.
    ///
    /// @detdesc
    /// After the algorithm is destroyed, the client does not store any data or state associated with the current session.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*AWBRDestroy)(
        AWBRAlgorithm*                 pCHIAWBRAlgorithm,
        const AWBRAlgoDestroyParamList*   pDestroyParams);
} AWBRAlgorithm; // AWBRAlgorithm interface

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond CreateAWBR @endcond
///
/// @brief Creates an instance of the AWBR algorithm.
///
/// @datatypes
/// #AWBRAlgoCreateParamList \n
/// #AWBRAlgorithm
///
/// @param[in] pCreateParams      Pointer to the parameters used to create the instance.
/// @param[in] ppCHIAWBRAlgorithm  Double pointer to the created algorithm instance.
///
/// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef CDKResult (*CREATEAWBR)(
    const AWBRAlgoCreateParamList*   pCreateParams,
    AWBRAlgorithm**               ppCHIAWBRAlgorithm);

/** @} */ /* end_addtogroup chi_stats_awb */

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // CHIAWBRINTERFACE_H
