1/*
2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  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.
9 */
10
11#ifndef VP9_DECODER_VP9_READER_H_
12#define VP9_DECODER_VP9_READER_H_
13
14#include <stddef.h>
15#include <limits.h>
16
17#include "./vpx_config.h"
18#include "vpx_ports/mem.h"
19#include "vpx/vpx_integer.h"
20
21#include "vp9/common/vp9_prob.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27typedef size_t BD_VALUE;
28
29#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
30
31typedef struct {
32  const uint8_t *buffer_end;
33  const uint8_t *buffer;
34  BD_VALUE value;
35  int count;
36  unsigned int range;
37} vp9_reader;
38
39int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size);
40
41void vp9_reader_fill(vp9_reader *r);
42
43int vp9_reader_has_error(vp9_reader *r);
44
45const uint8_t *vp9_reader_find_end(vp9_reader *r);
46
47static int vp9_read(vp9_reader *r, int prob) {
48  unsigned int bit = 0;
49  BD_VALUE value;
50  BD_VALUE bigsplit;
51  int count;
52  unsigned int range;
53  unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
54
55  if (r->count < 0)
56    vp9_reader_fill(r);
57
58  value = r->value;
59  count = r->count;
60
61  bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
62
63  range = split;
64
65  if (value >= bigsplit) {
66    range = r->range - split;
67    value = value - bigsplit;
68    bit = 1;
69  }
70
71  {
72    register unsigned int shift = vp9_norm[range];
73    range <<= shift;
74    value <<= shift;
75    count -= shift;
76  }
77  r->value = value;
78  r->count = count;
79  r->range = range;
80
81  return bit;
82}
83
84static int vp9_read_bit(vp9_reader *r) {
85  return vp9_read(r, 128);  // vp9_prob_half
86}
87
88static int vp9_read_literal(vp9_reader *r, int bits) {
89  int literal = 0, bit;
90
91  for (bit = bits - 1; bit >= 0; bit--)
92    literal |= vp9_read_bit(r) << bit;
93
94  return literal;
95}
96
97static int vp9_read_tree(vp9_reader *r, const vp9_tree_index *tree,
98                         const vp9_prob *probs) {
99  vp9_tree_index i = 0;
100
101  while ((i = tree[i + vp9_read(r, probs[i >> 1])]) > 0)
102    continue;
103
104  return -i;
105}
106
107#ifdef __cplusplus
108}  // extern "C"
109#endif
110
111#endif  // VP9_DECODER_VP9_READER_H_
112