/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#ifndef AV1_COMMON_MV_H_
#define AV1_COMMON_MV_H_

#include "av1/common/common.h"
#include "aom_dsp/aom_filter.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct mv {
  int16_t row;
  int16_t col;
} MV;

typedef union int_mv {
  uint32_t as_int;
  MV as_mv;
} int_mv; /* facilitates faster equality tests and copies */

typedef struct mv32 {
  int32_t row;
  int32_t col;
} MV32;

#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
// Bits of precision used for the model
#define WARPEDMODEL_PREC_BITS 8
#define WARPEDMODEL_ROW3HOMO_PREC_BITS 12

// Bits of subpel precision for warped interpolation
#define WARPEDPIXEL_PREC_BITS 6
#define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS)

// Taps for ntap filter
#define WARPEDPIXEL_FILTER_TAPS 6

// Precision of filter taps
#define WARPEDPIXEL_FILTER_BITS 7

#define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)

typedef enum {
  UNKNOWN_TRANSFORM = -1,
  HOMOGRAPHY,   // homography, 8-parameter
  AFFINE,       // affine, 6-parameter
  ROTZOOM,      // simplified affine with rotation and zoom only, 4-parameter
  TRANSLATION,  // translational motion 2-parameter
  TRANS_TYPES
} TransformationType;

// number of parameters used by each transformation in TransformationTypes
static const int n_trans_model_params[TRANS_TYPES] = { 9, 6, 4, 2 };

typedef struct {
  TransformationType wmtype;
  int_mv wmmat[4];  // For homography wmmat[9] is assumed to be 1
} WarpedMotionParams;
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION

#if CONFIG_GLOBAL_MOTION
// ALPHA here refers to parameters a and b in rotzoom model:
// | a   b|
// |-b   a|
//
// and a, b, c, d in affine model:
// | a   b|
// | c   d|
//
// Anything ending in PREC_BITS is the number of bits of precision
// to maintain when converting from double to integer.
//
// The ABS parameters are used to create an upper and lower bound
// for each parameter. In other words, after a parameter is integerized
// it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS).
//
// XXX_PREC_DIFF and XXX_DECODE_FACTOR
// are computed once here to prevent repetitive
// computation on the decoder side. These are
// to allow the global motion parameters to be encoded in a lower
// precision than the warped model precision. This means that they
// need to be changed to warped precision when they are decoded.
//
// XX_MIN, XX_MAX are also computed to avoid repeated computation

#define GM_TRANS_PREC_BITS 8
#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)

#define GM_ALPHA_PREC_BITS 8
#define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
#define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF)

#define GM_ABS_ALPHA_BITS 8
#define GM_ABS_TRANS_BITS 8

#define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS)
#define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS)
#define GM_TRANS_MIN -GM_TRANS_MAX
#define GM_ALPHA_MIN -GM_ALPHA_MAX

typedef enum {
  GLOBAL_ZERO = 0,
  GLOBAL_TRANSLATION = 1,
  GLOBAL_ROTZOOM = 2,
  GLOBAL_AFFINE = 3,
  GLOBAL_MOTION_TYPES
} GLOBAL_MOTION_TYPE;

typedef struct {
  GLOBAL_MOTION_TYPE gmtype;
  WarpedMotionParams motion_params;
} Global_Motion_Params;

static INLINE TransformationType gm_to_trans_type(GLOBAL_MOTION_TYPE gmtype) {
  switch (gmtype) {
    case GLOBAL_ZERO: return UNKNOWN_TRANSFORM; break;
    case GLOBAL_TRANSLATION: return TRANSLATION; break;
    case GLOBAL_ROTZOOM: return ROTZOOM; break;
    case GLOBAL_AFFINE: return AFFINE; break;
    default: assert(0);
  }
  return UNKNOWN_TRANSFORM;
}

static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) {
  if (!gm->motion_params.wmmat[2].as_int) {
    if (!gm->motion_params.wmmat[1].as_int) {
      return (gm->motion_params.wmmat[0].as_int ? GLOBAL_TRANSLATION
                                                : GLOBAL_ZERO);
    } else {
      return GLOBAL_ROTZOOM;
    }
  } else {
    return GLOBAL_AFFINE;
  }
}
#endif  // CONFIG_GLOBAL_MOTION

#if CONFIG_REF_MV
typedef struct candidate_mv {
  int_mv this_mv;
  int_mv comp_mv;
  int_mv pred_mv[2];
  int weight;
} CANDIDATE_MV;
#endif

static INLINE int is_zero_mv(const MV *mv) {
  return *((const uint32_t *)mv) == 0;
}

static INLINE int is_equal_mv(const MV *a, const MV *b) {
  return *((const uint32_t *)a) == *((const uint32_t *)b);
}

static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row,
                            int max_row) {
  mv->col = clamp(mv->col, min_col, max_col);
  mv->row = clamp(mv->row, min_row, max_row);
}

static INLINE int mv_has_subpel(const MV *mv) {
  return (mv->row & SUBPEL_MASK) || (mv->col & SUBPEL_MASK);
}
#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // AV1_COMMON_MV_H_
