/*
 * 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.
 */

/*!\file
 * \brief Describes film grain parameters and film grain synthesis
 *
 */
#ifndef AOM_AOM_DSP_GRAIN_SYNTHESIS_H_
#define AOM_AOM_DSP_GRAIN_SYNTHESIS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <string.h>

#include "aom_dsp/aom_dsp_common.h"
#include "aom/aom_image.h"

/*!\brief Structure containing film grain synthesis parameters for a frame
 *
 * This structure contains input parameters for film grain synthesis
 */
typedef struct {
  // This structure is compared element-by-element in the function
  // aom_check_grain_params_equiv: this function must be updated if any changes
  // are made to this structure.
  int apply_grain;

  int update_parameters;

  // 8 bit values
  int scaling_points_y[14][2];
  int num_y_points;  // value: 0..14

  // 8 bit values
  int scaling_points_cb[10][2];
  int num_cb_points;  // value: 0..10

  // 8 bit values
  int scaling_points_cr[10][2];
  int num_cr_points;  // value: 0..10

  int scaling_shift;  // values : 8..11

  int ar_coeff_lag;  // values:  0..3

  // 8 bit values
  int ar_coeffs_y[24];
  int ar_coeffs_cb[25];
  int ar_coeffs_cr[25];

  // Shift value: AR coeffs range
  // 6: [-2, 2)
  // 7: [-1, 1)
  // 8: [-0.5, 0.5)
  // 9: [-0.25, 0.25)
  int ar_coeff_shift;  // values : 6..9

  int cb_mult;       // 8 bits
  int cb_luma_mult;  // 8 bits
  int cb_offset;     // 9 bits

  int cr_mult;       // 8 bits
  int cr_luma_mult;  // 8 bits
  int cr_offset;     // 9 bits

  int overlap_flag;

  int clip_to_restricted_range;

  unsigned int bit_depth;  // video bit depth

  int chroma_scaling_from_luma;

  int grain_scale_shift;

  uint16_t random_seed;
  // This structure is compared element-by-element in the function
  // aom_check_grain_params_equiv: this function must be updated if any changes
  // are made to this structure.
} aom_film_grain_t;

/*!\brief Check if two film grain parameters structs are equivalent
 *
 * Check if two film grain parameters are equal, except for the
 * update_parameters and random_seed elements which are ignored.
 *
 * \param[in]    pa               The first set of parameters to compare
 * \param[in]    pb               The second set of parameters to compare
 * \return       Returns 1 if the params are equivalent, 0 otherwise
 */
static INLINE int aom_check_grain_params_equiv(
    const aom_film_grain_t *const pa, const aom_film_grain_t *const pb) {
  if (pa->apply_grain != pb->apply_grain) return 0;
  // Don't compare update_parameters

  if (pa->num_y_points != pb->num_y_points) return 0;
  if (memcmp(pa->scaling_points_y, pb->scaling_points_y,
             pa->num_y_points * 2 * sizeof(*pa->scaling_points_y)) != 0)
    return 0;

  if (pa->num_cb_points != pb->num_cb_points) return 0;
  if (memcmp(pa->scaling_points_cb, pb->scaling_points_cb,
             pa->num_cb_points * 2 * sizeof(*pa->scaling_points_cb)) != 0)
    return 0;

  if (pa->num_cr_points != pb->num_cr_points) return 0;
  if (memcmp(pa->scaling_points_cr, pb->scaling_points_cr,
             pa->num_cr_points * 2 * sizeof(*pa->scaling_points_cr)) != 0)
    return 0;

  if (pa->scaling_shift != pb->scaling_shift) return 0;
  if (pa->ar_coeff_lag != pb->ar_coeff_lag) return 0;

  const int num_pos = 2 * pa->ar_coeff_lag * (pa->ar_coeff_lag + 1);
  if (memcmp(pa->ar_coeffs_y, pb->ar_coeffs_y,
             num_pos * sizeof(*pa->ar_coeffs_y)) != 0)
    return 0;
  if (memcmp(pa->ar_coeffs_cb, pb->ar_coeffs_cb,
             num_pos * sizeof(*pa->ar_coeffs_cb)) != 0)
    return 0;
  if (memcmp(pa->ar_coeffs_cr, pb->ar_coeffs_cr,
             num_pos * sizeof(*pa->ar_coeffs_cr)) != 0)
    return 0;

  if (pa->ar_coeff_shift != pb->ar_coeff_shift) return 0;

  if (pa->cb_mult != pb->cb_mult) return 0;
  if (pa->cb_luma_mult != pb->cb_luma_mult) return 0;
  if (pa->cb_offset != pb->cb_offset) return 0;

  if (pa->cr_mult != pb->cr_mult) return 0;
  if (pa->cr_luma_mult != pb->cr_luma_mult) return 0;
  if (pa->cr_offset != pb->cr_offset) return 0;

  if (pa->overlap_flag != pb->overlap_flag) return 0;
  if (pa->clip_to_restricted_range != pb->clip_to_restricted_range) return 0;
  if (pa->bit_depth != pb->bit_depth) return 0;
  if (pa->chroma_scaling_from_luma != pb->chroma_scaling_from_luma) return 0;
  if (pa->grain_scale_shift != pb->grain_scale_shift) return 0;

  return 1;
}

/*!\brief Add film grain
 *
 * Add film grain to an image
 *
 * Returns 0 for success, -1 for failure
 *
 * \param[in]    grain_params     Grain parameters
 * \param[in]    luma             luma plane
 * \param[in]    cb               cb plane
 * \param[in]    cr               cr plane
 * \param[in]    height           luma plane height
 * \param[in]    width            luma plane width
 * \param[in]    luma_stride      luma plane stride
 * \param[in]    chroma_stride    chroma plane stride
 */
int av1_add_film_grain_run(const aom_film_grain_t *grain_params, uint8_t *luma,
                           uint8_t *cb, uint8_t *cr, int height, int width,
                           int luma_stride, int chroma_stride,
                           int use_high_bit_depth, int chroma_subsamp_y,
                           int chroma_subsamp_x, int mc_identity);

/*!\brief Add film grain
 *
 * Add film grain to an image
 *
 * Returns 0 for success, -1 for failure
 *
 * \param[in]    grain_params     Grain parameters
 * \param[in]    src              Source image
 * \param[out]   dst              Resulting image with grain
 */
int av1_add_film_grain(const aom_film_grain_t *grain_params,
                       const aom_image_t *src, aom_image_t *dst);

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

#endif  // AOM_AOM_DSP_GRAIN_SYNTHESIS_H_
