/*
  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>

#include "vp10/common/entropy.h"

#include "vp10/decoder/dsubexp.h"

static int inv_recenter_nonneg(int v, int m) {
  if (v > 2 * m)
    return v;

  return (v & 1) ? m - ((v + 1) >> 1) : m + (v >> 1);
}

static int decode_uniform(vp10_reader *r) {
  const int l = 8;
  const int m = (1 << l) - 190;
  const int v = vp10_read_literal(r, l - 1);
  return v < m ?  v : (v << 1) - m + vp10_read_bit(r);
}

static int inv_remap_prob(int v, int m) {
  static uint8_t inv_map_table[MAX_PROB - 1] = {
      7,  20,  33,  46,  59,  72,  85,  98, 111, 124, 137, 150, 163, 176, 189,
    202, 215, 228, 241, 254,   1,   2,   3,   4,   5,   6,   8,   9,  10,  11,
     12,  13,  14,  15,  16,  17,  18,  19,  21,  22,  23,  24,  25,  26,  27,
     28,  29,  30,  31,  32,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
     44,  45,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  60,
     61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  73,  74,  75,  76,
     77,  78,  79,  80,  81,  82,  83,  84,  86,  87,  88,  89,  90,  91,  92,
     93,  94,  95,  96,  97,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
    109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125,
    126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141,
    142, 143, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157,
    158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
    174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190,
    191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
    207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222,
    223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
    239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  };
  assert(v < (int)(sizeof(inv_map_table) / sizeof(inv_map_table[0])));
  v = inv_map_table[v];
  m--;
  if ((m << 1) <= MAX_PROB) {
    return 1 + inv_recenter_nonneg(v, m);
  } else {
    return MAX_PROB - inv_recenter_nonneg(v, MAX_PROB - 1 - m);
  }
}

static int decode_term_subexp(vp10_reader *r) {
  if (!vp10_read_bit(r))
    return vp10_read_literal(r, 4);
  if (!vp10_read_bit(r))
    return vp10_read_literal(r, 4) + 16;
  if (!vp10_read_bit(r))
    return vp10_read_literal(r, 5) + 32;
  return decode_uniform(r) + 64;
}

void vp10_diff_update_prob(vp10_reader *r, vpx_prob* p) {
  if (vp10_read(r, DIFF_UPDATE_PROB)) {
    const int delp = decode_term_subexp(r);
    *p = (vpx_prob)inv_remap_prob(delp, *p);
  }
}

int vp10_read_primitive_symmetric(vp10_reader *r, unsigned int mag_bits) {
  if (vp10_read_bit(r)) {
    int s = vp10_read_bit(r);
    int x = vp10_read_literal(r, mag_bits) + 1;
    return (s > 0 ? -x : x);
  } else {
    return 0;
  }
}
