blob: 9a441b41077e6b4100b746168dddef7bcd74cbf6 [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
John Koleszarc2140b82010-09-09 08:16:39 -04002 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
John Koleszar94c52e42010-06-18 12:39:21 -04004 * Use of this source code is governed by a BSD-style license
John Koleszar09202d82010-06-04 16:19:40 -04005 * 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
John Koleszar94c52e42010-06-18 12:39:21 -04007 * in the file PATENTS. All contributing project authors may
John Koleszar09202d82010-06-04 16:19:40 -04008 * be found in the AUTHORS file in the root of the source tree.
John Koleszar0ea50ce2010-05-18 11:58:33 -04009 */
10
Yaowu Xu87d2c3c2015-07-17 14:09:05 -070011#ifndef VPX_DSP_BITREADER_H_
12#define VPX_DSP_BITREADER_H_
Ronald S. Bultje4cca47b2012-12-18 15:31:19 -080013
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -040014#include <stddef.h>
15#include <limits.h>
Dmitry Kovalev7f99c3c2013-03-05 14:12:16 -080016
John Koleszar5ebe94f2012-12-23 07:20:10 -080017#include "./vpx_config.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040018#include "vpx_ports/mem.h"
Joey Parrish18c08602014-04-15 14:10:58 -070019#include "vpx/vp8dx.h"
John Koleszarb7492342010-05-24 11:39:59 -040020#include "vpx/vpx_integer.h"
Yaowu Xu87d2c3c2015-07-17 14:09:05 -070021#include "vpx_dsp/prob.h"
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -040022
James Zern40aa9102014-01-18 12:16:11 -080023#ifdef __cplusplus
24extern "C" {
25#endif
26
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080027typedef size_t BD_VALUE;
28
29#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
30
James Zern1e0aa942015-07-01 19:10:43 -070031// This is meant to be a large, positive constant that can still be efficiently
32// loaded as an immediate (on platforms like ARM, for example).
33// Even relatively modest values like 100 would work fine.
34#define LOTS_OF_BITS 0x40000000
35
John Koleszarc6b90392012-07-13 15:21:29 -070036typedef struct {
James Zerne1f55e02014-11-24 19:27:07 -080037 // Be careful when reordering this struct, it may impact the cache negatively.
38 BD_VALUE value;
39 unsigned int range;
40 int count;
Dmitry Kovalev67d06002013-04-15 14:54:19 -070041 const uint8_t *buffer_end;
42 const uint8_t *buffer;
Joey Parrish18c08602014-04-15 14:10:58 -070043 vpx_decrypt_cb decrypt_cb;
44 void *decrypt_state;
James Zerne1f55e02014-11-24 19:27:07 -080045 uint8_t clear_buffer[sizeof(BD_VALUE) + 1];
Yaowu Xubf825142015-07-20 13:49:15 -070046} vpx_reader;
John Koleszar0ea50ce2010-05-18 11:58:33 -040047
Yaowu Xubf825142015-07-20 13:49:15 -070048int vpx_reader_init(vpx_reader *r,
Joey Parrish18c08602014-04-15 14:10:58 -070049 const uint8_t *buffer,
50 size_t size,
51 vpx_decrypt_cb decrypt_cb,
52 void *decrypt_state);
Johannbb9c95e2011-02-04 16:00:00 -050053
Yaowu Xubf825142015-07-20 13:49:15 -070054void vpx_reader_fill(vpx_reader *r);
Timothy B. Terriberryc17b62e2010-05-05 17:58:19 -040055
Yaowu Xubf825142015-07-20 13:49:15 -070056const uint8_t *vpx_reader_find_end(vpx_reader *r);
Dmitry Kovalev67d06002013-04-15 14:54:19 -070057
Yaowu Xubf825142015-07-20 13:49:15 -070058static INLINE int vpx_reader_has_error(vpx_reader *r) {
James Zern1e0aa942015-07-01 19:10:43 -070059 // Check if we have reached the end of the buffer.
60 //
61 // Variable 'count' stores the number of bits in the 'value' buffer, minus
62 // 8. The top byte is part of the algorithm, and the remainder is buffered
63 // to be shifted into it. So if count == 8, the top 16 bits of 'value' are
64 // occupied, 8 for the algorithm and 8 in the buffer.
65 //
66 // When reading a byte from the user's buffer, count is filled with 8 and
67 // one byte is filled into the value buffer. When we reach the end of the
68 // data, count is additionally filled with LOTS_OF_BITS. So when
69 // count == LOTS_OF_BITS - 1, the user's data has been exhausted.
70 //
71 // 1 if we have tried to decode bits after the end of stream was encountered.
72 // 0 No error.
73 return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS;
74}
75
Yaowu Xubf825142015-07-20 13:49:15 -070076static INLINE int vpx_read(vpx_reader *r, int prob) {
John Koleszarc6b90392012-07-13 15:21:29 -070077 unsigned int bit = 0;
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080078 BD_VALUE value;
79 BD_VALUE bigsplit;
John Koleszarc6b90392012-07-13 15:21:29 -070080 int count;
81 unsigned int range;
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080082 unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
Scott LaVarnway67a1f982011-06-20 14:44:16 -040083
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080084 if (r->count < 0)
Yaowu Xubf825142015-07-20 13:49:15 -070085 vpx_reader_fill(r);
Scott LaVarnway67a1f982011-06-20 14:44:16 -040086
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080087 value = r->value;
88 count = r->count;
John Koleszar0ea50ce2010-05-18 11:58:33 -040089
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080090 bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
John Koleszar0ea50ce2010-05-18 11:58:33 -040091
John Koleszarc6b90392012-07-13 15:21:29 -070092 range = split;
John Koleszar0ea50ce2010-05-18 11:58:33 -040093
John Koleszarc6b90392012-07-13 15:21:29 -070094 if (value >= bigsplit) {
Dmitry Kovalevd7efe062013-11-26 12:38:58 -080095 range = r->range - split;
John Koleszarc6b90392012-07-13 15:21:29 -070096 value = value - bigsplit;
97 bit = 1;
98 }
John Koleszar0ea50ce2010-05-18 11:58:33 -040099
John Koleszarc6b90392012-07-13 15:21:29 -0700100 {
Alex Converse6aa21632015-11-19 15:07:55 -0800101 register int shift = vpx_norm[range];
John Koleszarc6b90392012-07-13 15:21:29 -0700102 range <<= shift;
103 value <<= shift;
104 count -= shift;
105 }
Dmitry Kovalevd7efe062013-11-26 12:38:58 -0800106 r->value = value;
107 r->count = count;
108 r->range = range;
Scott LaVarnway67a1f982011-06-20 14:44:16 -0400109
John Koleszarc6b90392012-07-13 15:21:29 -0700110 return bit;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400111}
112
Yaowu Xubf825142015-07-20 13:49:15 -0700113static INLINE int vpx_read_bit(vpx_reader *r) {
114 return vpx_read(r, 128); // vpx_prob_half
Dmitry Kovalev67d06002013-04-15 14:54:19 -0700115}
116
Yaowu Xubf825142015-07-20 13:49:15 -0700117static INLINE int vpx_read_literal(vpx_reader *r, int bits) {
Dmitry Kovalevd7efe062013-11-26 12:38:58 -0800118 int literal = 0, bit;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400119
Dmitry Kovalev0b446242013-04-19 10:37:24 -0700120 for (bit = bits - 1; bit >= 0; bit--)
Yaowu Xubf825142015-07-20 13:49:15 -0700121 literal |= vpx_read_bit(r) << bit;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400122
Dmitry Kovalevd7efe062013-11-26 12:38:58 -0800123 return literal;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400124}
Henrik Lundin67fb3a52010-12-16 16:46:31 +0100125
Yaowu Xu70ad6682015-07-20 14:04:21 -0700126static INLINE int vpx_read_tree(vpx_reader *r, const vpx_tree_index *tree,
Yaowu Xubf825142015-07-20 13:49:15 -0700127 const vpx_prob *probs) {
Yaowu Xu70ad6682015-07-20 14:04:21 -0700128 vpx_tree_index i = 0;
Dmitry Kovalevd7efe062013-11-26 12:38:58 -0800129
Yaowu Xubf825142015-07-20 13:49:15 -0700130 while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0)
Dmitry Kovalevd7efe062013-11-26 12:38:58 -0800131 continue;
132
133 return -i;
134}
Deb Mukherjeec6f1bf42012-04-12 09:24:03 -0700135
James Zern40aa9102014-01-18 12:16:11 -0800136#ifdef __cplusplus
137} // extern "C"
138#endif
139
Yaowu Xu87d2c3c2015-07-17 14:09:05 -0700140#endif // VPX_DSP_BITREADER_H_