/*
 * Copyright (c) 2001-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.
 */

/* clang-format off */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>

#include "aom_dsp/bitwriter.h"
#include "av1/common/generic_code.h"
#include "av1/common/odintrin.h"
#include "pvq_encoder.h"

/** Encodes a value from 0 to N-1 (with N up to 16) based on a cdf and adapts
 * the cdf accordingly.
 *
 * @param [in,out] w     multi-symbol entropy encoder
 * @param [in]     val   variable being encoded
 * @param [in,out] cdf   CDF of the variable (Q15)
 * @param [in]     n     number of values possible
 * @param [in,out] count number of symbols encoded with that cdf so far
 * @param [in]     rate  adaptation rate shift (smaller is faster)
 */
void aom_encode_cdf_adapt_q15(aom_writer *w, int val, uint16_t *cdf, int n,
 int *count, int rate) {
  int i;
  if (*count == 0) {
    /* On the first call, we normalize the cdf to (32768 - n). This should
       eventually be moved to the state init, but for now it makes it much
       easier to experiment and convert symbols to the Q15 adaptation.*/
    int ft;
    ft = cdf[n - 1];
    for (i = 0; i < n; i++) {
      cdf[i] = cdf[i]*32768/ft;
    }
  }
  aom_write_cdf(w, val, cdf, n);
  aom_cdf_adapt_q15(val, cdf, n, count, rate);
}

/** Encodes a value from 0 to N-1 (with N up to 16) based on a cdf and adapts
 * the cdf accordingly.
 *
 * @param [in,out] enc   range encoder
 * @param [in]     val   variable being encoded
 * @param [in]     cdf   CDF of the variable (Q15)
 * @param [in]     n     number of values possible
 * @param [in]     increment adaptation speed (Q15)
 */
void aom_encode_cdf_adapt(aom_writer *w, int val, uint16_t *cdf, int n,
 int increment) {
  int i;
  aom_write_cdf_unscaled(w, val, cdf, n);
  if (cdf[n-1] + increment > 32767) {
    for (i = 0; i < n; i++) {
      /* Second term ensures that the pdf is non-null */
      cdf[i] = (cdf[i] >> 1) + i + 1;
    }
  }
  for (i = val; i < n; i++) cdf[i] += increment;
}

/** Encodes a random variable using a "generic" model, assuming that the
 * distribution is one-sided (zero and up), has a single mode, and decays
 * exponentially past the model.
 *
 * @param [in,out] w     multi-symbol entropy encoder
 * @param [in,out] model generic probability model
 * @param [in]     x     variable being encoded
 * @param [in]     max   largest value possible
 * @param [in,out] ExQ16 expectation of x (adapted)
 * @param [in]     integration integration period of ExQ16 (leaky average over
 * 1<<integration samples)
 */
void generic_encode(aom_writer *w, generic_encoder *model, int x, int max,
 int *ex_q16, int integration) {
  int lg_q1;
  int shift;
  int id;
  uint16_t *cdf;
  int xs;
  int ms;
  if (max == 0) return;
  lg_q1 = log_ex(*ex_q16);
  OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG,
   "%d %d", *ex_q16, lg_q1));
  /* If expectation is too large, shift x to ensure that
     all we have past xs=15 is the exponentially decaying tail
     of the distribution */
  shift = OD_MAXI(0, (lg_q1 - 5) >> 1);
  /* Choose the cdf to use: we have two per "octave" of ExQ16 */
  id = OD_MINI(GENERIC_TABLES - 1, lg_q1);
  cdf = model->cdf[id];
  xs = (x + (1 << shift >> 1)) >> shift;
  ms = (max + (1 << shift >> 1)) >> shift;
  OD_ASSERT(max == -1 || xs <= ms);
  if (max == -1) aom_write_cdf_unscaled(w, OD_MINI(15, xs), cdf, 16);
  else {
    aom_write_cdf_unscaled(w, OD_MINI(15, xs), cdf, OD_MINI(ms + 1, 16));
  }
  if (xs >= 15) {
    int e;
    unsigned decay;
    /* Estimate decay based on the assumption that the distribution is close
       to Laplacian for large values. We should probably have an adaptive
       estimate instead. Note: The 2* is a kludge that's not fully understood
       yet. */
    OD_ASSERT(*ex_q16 < INT_MAX >> 1);
    e = ((2**ex_q16 >> 8) + (1 << shift >> 1)) >> shift;
    decay = OD_MAXI(2, OD_MINI(254, 256*e/(e + 256)));
    /* Encode the tail of the distribution assuming exponential decay. */
    aom_laplace_encode_special(w, xs - 15, decay, (max == -1) ? -1 : ms - 15);
  }
  if (shift != 0) {
    int special;
    /* Because of the rounding, there's only half the number of possibilities
       for xs=0. */
    special = xs == 0;
    if (shift - special > 0) {
      aom_write_literal(w, x - (xs << shift) + (!special << (shift - 1)),
       shift - special);
    }
  }
  generic_model_update(model, ex_q16, x, xs, id, integration);
  OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG,
   "enc: %d %d %d %d %d %x", *ex_q16, x, shift, id, xs, enc->rng));
}

/** Estimates the cost of encoding a value with generic_encode().
 *
 * @param [in,out] model generic probability model
 * @param [in]     x     variable being encoded
 * @param [in]     max   largest value possible
 * @param [in,out] ExQ16 expectation of x (adapted)
 * @return number of bits (approximation)
 */
double generic_encode_cost(generic_encoder *model, int x, int max,
 int *ex_q16) {
  int lg_q1;
  int shift;
  int id;
  uint16_t *cdf;
  int xs;
  int ms;
  int extra;
  if (max == 0) return 0;
  lg_q1 = log_ex(*ex_q16);
  /* If expectation is too large, shift x to ensure that
       all we have past xs=15 is the exponentially decaying tail
       of the distribution */
  shift = OD_MAXI(0, (lg_q1 - 5) >> 1);
  /* Choose the cdf to use: we have two per "octave" of ExQ16 */
  id = OD_MINI(GENERIC_TABLES - 1, lg_q1);
  cdf = model->cdf[id];
  xs = (x + (1 << shift >> 1)) >> shift;
  ms = (max + (1 << shift >> 1)) >> shift;
  OD_ASSERT(max == -1 || xs <= ms);
  extra = 0;
  if (shift) extra = shift - (xs == 0);
  xs = OD_MINI(15, xs);
  /* Shortcut: assume it's going to cost 2 bits for the Laplace coder. */
  if (xs == 15) extra += 2;
  if (max == -1) {
    return extra - OD_LOG2((double)(cdf[xs] - (xs == 0 ? 0 : cdf[xs - 1]))/
     cdf[15]);
  }
  else {
    return extra - OD_LOG2((double)(cdf[xs] - (xs == 0 ? 0 : cdf[xs - 1]))/
     cdf[OD_MINI(ms, 15)]);
  }
}

/*Estimates the cost of encoding a value with a given CDF.*/
double od_encode_cdf_cost(int val, uint16_t *cdf, int n) {
  int total_prob;
  int prev_prob;
  double val_prob;
  OD_ASSERT(n > 0);
  total_prob = cdf[n - 1];
  if (val == 0) {
    prev_prob = 0;
  }
  else {
    prev_prob = cdf[val - 1];
  }
  val_prob = (cdf[val] - prev_prob) / (double)total_prob;
  return -OD_LOG2(val_prob);
}
