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


#ifndef __EIS_UTIL_H__
#define __EIS_UTIL_H__

#include "is_interface.h"

#ifndef PLACE_HOLDER_BUILD_ID
#define PLACE_HOLDER_BUILD_ID
static const char _build_id[] = "19172";
#endif /* PLACE_HOLDER_BUILD_ID */

#ifndef EIS_MAX_NUM_SENSORS
#define EIS_MAX_NUM_SENSORS             (16)
#endif /* EIS_MAX_NUM_SENSORS */

#ifndef FREE
#define FREE(x)                     if (NULL != (x)) {free((x)); (x) = NULL;}
#endif /* FREE */

#ifndef _DELETE
#define _DELETE(x)                  if (NULL != (x)) {delete  (x); (x) = NULL;}
#endif /* _DELETE  */

#ifndef SIGN
#define SIGN(x)             (((x) >= 0) ? 1 : -1)
#endif

#ifndef ABS
#define ABS(x)              (((x) < 0) ? -(x) : (x))
#endif

#ifndef MIN
#define MIN(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#ifndef MIN3
#define MIN3(a, b, c)       MIN(MIN(a, b), c)
#endif /* !MIN3 */

#ifndef MIN4
#define MIN4(a, b, c, d)    MIN3(MIN(a, b), c, d)
#endif /* !MIN4 */

#ifndef MAX
#define MAX(a,b)            (((a) > (b)) ? (a) : (b))
#endif

#ifndef MAX3
#define MAX3(a, b, c)       MAX(MAX(a, b), c)
#endif /* !MAX3 */

#ifndef MAX4
#define MAX4(a, b, c, d)    MAX3(MAX(a, b), c, d)
#endif /* !MAX4 */

#ifndef LIMIT
#define LIMIT(in, minv, maxv)  MIN(MAX(in, minv), maxv)
#endif /* !LIMIT */

#ifndef POW3
#define POW3(x)             ((x)*(x)*(x))
#endif /* !POW3 */

#ifndef USEC_TO_SEC
#define USEC_TO_SEC(x)      ((double)(x)/1000000.0)
#endif

#ifndef IS_EPS
#define IS_EPS              (0.000001)
#endif

#ifndef IS_PI
#define IS_PI               (3.14159265358979323846)
#endif

#ifndef DEG_TO_RAD
#define DEG_TO_RAD( _deg ) ( (_deg) * IS_PI / 180)
#endif

#ifndef ARR_SIZE
#define ARR_SIZE(x)         ((sizeof((x))) / (sizeof((x)[0])))
#endif

#ifndef EIS_FLT_EPSILON
#define EIS_FLT_EPSILON      1.192092896e-07F        // smallest such that 1.0+EIS_FLT_EPSILON != 1.0
#endif /* EIS_FLT_EPSILON */

#ifndef IS_IN_INTERVAL
#define IS_IN_INTERVAL(center, radius, point)   ((((center) - (radius)) < (point)) && ((point) < ((center) + (radius))))
#endif /* IS_IN_INTERVAL */

#ifndef MILLI_TO_SEC
#define MILLI_TO_SEC(milli)             ((milli) / 1000.0)
#endif /* MILLI_TO_SEC */

#ifndef MICRO_TO_SEC
#define MICRO_TO_SEC(micro)             ((micro) / 1000000.0)
#endif /* MICRO_TO_SEC */

#ifndef SEC_TO_MILLI
#define SEC_TO_MILLI(sec)               ((sec) * 1000U)                 /**< Converts seconds into milliseconds */
#endif /* SEC_TO_MILLI */

#ifndef SEC_TO_USEC
#define SEC_TO_USEC(sec)                ((sec) * 1000000U)              /**< Converts seconds into microseconds */
#endif /* SEC_TO_USEC */

#ifndef MILLI_TO_USEC
#define MILLI_TO_USEC(msec)             ((msec) * 1000U)                /**< Convert milliseconds into microseconds */
#endif /* MILLI_TO_USEC */

#ifndef METER_TO_CM
#define METER_TO_CM(meter)              ((meter) * 100U)                /**< Convert meters into centimeters */
#endif /* METER_TO_CM */

#if !(defined(ANDROID))
#if defined (_LINUX)
#include "glib.h"
#define strlcpy g_strlcpy
#define strlcat g_strlcat
#else
#include <string.h>
#define strlcpy(dst, src, len)  strncpy_s((dst), (len), (src), _TRUNCATE)
#define strlcat(dst, src, len)  strncat_s((dst), (len), (src), _TRUNCATE);
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

void eis_internal_get_crop_size(
    uint32_t is_input_frame_height,             /**< Sensor input frame height */
    uint32_t is_input_frame_width,              /**< Sensor input frame width */
    uint32_t is_output_frame_height,            /**< Output frame height (final output after virtual margins upscale) */
    uint32_t is_output_frame_width,             /**< Output frame width (final output after virtual margins upscale)*/
    float    minimal_total_margin_y,            /**< Minimal total margins as supplied to chromatix struct */
    float    minimal_total_margin_x,            /**< Minimal total margins as supplied to chromatix struct */
    uint32_t *cropped_size_height,              /**< Cropped image size before virtual margins upscale (in matrix or otherwise) */
    uint32_t *cropped_size_width);              /**< Cropped image size before virtual margins upscale (in matrix or otherwise) */

int32_t eis_internal_get_stabilization_margin_ex(
    const is_get_stabilization_margin* in,
    ImageDimensions* stabilizationMargins);

int32_t eis_internal_get_stabilization_crop_ratio_ex(
    const is_get_stabilization_margin* in,
    double* _stabilization_crop_ratio_x,
    double* _stabilization_crop_ratio_y);

void NcLibWarpGrid_to_NcLibWarpMatrices(const NcLibWarpGrid* in, NcLibWarpMatrices* out);

uint64_t timestamp_interpolation(uint64_t ts_start, uint64_t ts_end, uint32_t num_points, uint32_t idx);

// ts_arr is array in size of num_points
void timestamp_interpolation_arr(uint64_t ts_start, uint64_t ts_end, uint32_t num_points, uint64_t *ts_arr);

#ifdef __cplusplus
}
#endif

#endif
