vp9_dboolhuff.c 2.51 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11
 */


12
#include "vp9/decoder/vp9_dboolhuff.h"
John Koleszar's avatar
John Koleszar committed
13 14 15
#include "vpx_ports/mem.h"
#include "vpx_mem/vpx_mem.h"

16 17 18
int vp9_start_decode(BOOL_DECODER *br,
                     const unsigned char *source,
                     unsigned int source_sz) {
John Koleszar's avatar
John Koleszar committed
19 20 21 22 23
  br->user_buffer_end = source + source_sz;
  br->user_buffer     = source;
  br->value    = 0;
  br->count    = -8;
  br->range    = 255;
John Koleszar's avatar
John Koleszar committed
24

John Koleszar's avatar
John Koleszar committed
25 26
  if (source_sz && !source)
    return 1;
John Koleszar's avatar
John Koleszar committed
27

John Koleszar's avatar
John Koleszar committed
28
  /* Populate the buffer */
29
  vp9_bool_decoder_fill(br);
John Koleszar's avatar
John Koleszar committed
30

John Koleszar's avatar
John Koleszar committed
31
  return 0;
John Koleszar's avatar
John Koleszar committed
32 33 34
}


35
void vp9_bool_decoder_fill(BOOL_DECODER *br) {
John Koleszar's avatar
John Koleszar committed
36 37
  const unsigned char *bufptr;
  const unsigned char *bufend;
38
  VP9_BD_VALUE         value;
John Koleszar's avatar
John Koleszar committed
39 40 41 42 43
  int                  count;
  bufend = br->user_buffer_end;
  bufptr = br->user_buffer;
  value = br->value;
  count = br->count;
44

45
  VP9DX_BOOL_DECODER_FILL(count, value, bufptr, bufend);
46

John Koleszar's avatar
John Koleszar committed
47 48 49
  br->user_buffer = bufptr;
  br->value = value;
  br->count = count;
John Koleszar's avatar
John Koleszar committed
50
}
51 52


John Koleszar's avatar
John Koleszar committed
53 54 55 56 57 58 59 60
static int get_unsigned_bits(unsigned num_values) {
  int cat = 0;
  if ((num_values--) <= 1) return 0;
  while (num_values > 0) {
    cat++;
    num_values >>= 1;
  }
  return cat;
61 62
}

63
int vp9_inv_recenter_nonneg(int v, int m) {
John Koleszar's avatar
John Koleszar committed
64 65 66
  if (v > (m << 1)) return v;
  else if ((v & 1) == 0) return (v >> 1) + m;
  else return m - ((v + 1) >> 1);
67 68
}

69
int vp9_decode_uniform(BOOL_DECODER *br, int n) {
John Koleszar's avatar
John Koleszar committed
70 71 72 73
  int v;
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
  if (!l) return 0;
74
  v = decode_value(br, l - 1);
John Koleszar's avatar
John Koleszar committed
75 76 77
  if (v < m)
    return v;
  else
78
    return (v << 1) - m + decode_value(br, 1);
79 80
}

81
int vp9_decode_term_subexp(BOOL_DECODER *br, int k, int num_syms) {
John Koleszar's avatar
John Koleszar committed
82 83 84 85 86
  int i = 0, mk = 0, word;
  while (1) {
    int b = (i ? k + i - 1 : k);
    int a = (1 << b);
    if (num_syms <= mk + 3 * a) {
87
      word = vp9_decode_uniform(br, num_syms - mk) + mk;
John Koleszar's avatar
John Koleszar committed
88 89
      break;
    } else {
90
      if (decode_value(br, 1)) {
John Koleszar's avatar
John Koleszar committed
91 92 93
        i++;
        mk += a;
      } else {
94
        word = decode_value(br, b) + mk;
John Koleszar's avatar
John Koleszar committed
95 96
        break;
      }
97
    }
John Koleszar's avatar
John Koleszar committed
98 99
  }
  return word;
100
}
John Koleszar's avatar
John Koleszar committed
101 102 103 104 105 106 107 108 109 110 111 112

int vp9_decode_unsigned_max(BOOL_DECODER *br, int max) {
  int data = 0, bit = 0, lmax = max;

  while (lmax) {
    data |= decode_bool(br, 128) << bit++;
    lmax >>= 1;
  }
  if (data > max)
    return max;
  return data;
}