16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
110e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org#ifndef VP9_DECODER_VP9_READER_H_
120e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org#define VP9_DECODER_VP9_READER_H_
13d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org
146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <stddef.h>
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <limits.h>
163358b313481c08268259f41f6c0ebeb5272c18cfjohannkoenig@chromium.org
17d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "./vpx_config.h"
186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx_ports/mem.h"
19693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vpx/vp8dx.h"
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx/vpx_integer.h"
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
220e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org#include "vp9/common/vp9_prob.h"
236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
24dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
25dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgextern "C" {
26dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
27dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
28d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgtypedef size_t BD_VALUE;
29d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
30d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
31d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgtypedef struct {
3310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const uint8_t *buffer_end;
3410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const uint8_t *buffer;
35693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  uint8_t clear_buffer[sizeof(BD_VALUE) + 1];
36d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  BD_VALUE value;
3710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  int count;
3810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  unsigned int range;
39693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  vpx_decrypt_cb decrypt_cb;
40693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  void *decrypt_state;
4110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org} vp9_reader;
426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
43693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comint vp9_reader_init(vp9_reader *r,
44693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                    const uint8_t *buffer,
45693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                    size_t size,
46693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                    vpx_decrypt_cb decrypt_cb,
47693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                    void *decrypt_state);
486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.orgvoid vp9_reader_fill(vp9_reader *r);
506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
51d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint vp9_reader_has_error(vp9_reader *r);
52d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
5310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.orgconst uint8_t *vp9_reader_find_end(vp9_reader *r);
546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic INLINE int vp9_read(vp9_reader *r, int prob) {
566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int bit = 0;
57d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  BD_VALUE value;
58d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  BD_VALUE bigsplit;
596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int count;
606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int range;
61d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
63d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (r->count < 0)
64d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    vp9_reader_fill(r);
656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
66d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  value = r->value;
67d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  count = r->count;
686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
69d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  range = split;
726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (value >= bigsplit) {
74d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    range = r->range - split;
756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    value = value - bigsplit;
766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    bit = 1;
776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  {
806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    register unsigned int shift = vp9_norm[range];
816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    range <<= shift;
826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    value <<= shift;
836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    count -= shift;
846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  r->value = value;
86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  r->count = count;
87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  r->range = range;
886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return bit;
906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic INLINE int vp9_read_bit(vp9_reader *r) {
9310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  return vp9_read(r, 128);  // vp9_prob_half
9410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org}
956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic INLINE int vp9_read_literal(vp9_reader *r, int bits) {
97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int literal = 0, bit;
9810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
9910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  for (bit = bits - 1; bit >= 0; bit--)
100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    literal |= vp9_read_bit(r) << bit;
1016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return literal;
1036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
1046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
10541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic INLINE int vp9_read_tree(vp9_reader *r, const vp9_tree_index *tree,
10641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                const vp9_prob *probs) {
107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vp9_tree_index i = 0;
108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  while ((i = tree[i + vp9_read(r, probs[i >> 1])]) > 0)
110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    continue;
111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return -i;
113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
115dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
116dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}  // extern "C"
117dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
118dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1190e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org#endif  // VP9_DECODER_VP9_READER_H_
120