1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 #include "vpx_rac.h"
20
21 #define DEF( name, bytes, read, write) \
22 static unsigned int bytestream_get_ ## name(const uint8_t **b) \
23 { \
24 (*b) += bytes; \
25 return read(*b - bytes); \
26 }
27
28 DEF(be24, 3, MPP_RB24, MPP_WB24)
29 DEF(be16, 2, MPP_RB16, MPP_WB16)
30
31 const uint8_t vpx_norm_shift[256] = {
32 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
33 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
34 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
35 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
36 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
37 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
39 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 };
45
vpx_init_range_decoder(VpxRangeCoder * c,const uint8_t * buf,int buf_size)46 void vpx_init_range_decoder(VpxRangeCoder *c, const uint8_t *buf, int buf_size)
47 {
48 c->high = 255;
49 c->bits = -16;
50 c->buffer = buf;
51 c->end = buf + buf_size;
52 c->code_word = bytestream_get_be24(&c->buffer);
53 }
54
vpx_rac_renorm(VpxRangeCoder * c)55 unsigned int vpx_rac_renorm(VpxRangeCoder *c)
56 {
57 int shift = vpx_norm_shift[c->high];
58 int bits = c->bits;
59 unsigned int code_word = c->code_word;
60
61 c->high <<= shift;
62 code_word <<= shift;
63 bits += shift;
64 if (bits >= 0 && c->buffer < c->end) {
65 code_word |= bytestream_get_be16(&c->buffer) << bits;
66 bits -= 16;
67 }
68 c->bits = bits;
69 return code_word;
70 }
71
vpx_rac_get_prob(VpxRangeCoder * c,uint8_t prob)72 int vpx_rac_get_prob(VpxRangeCoder *c, uint8_t prob)
73 {
74 unsigned int code_word = vpx_rac_renorm(c);
75 unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
76 unsigned int low_shift = low << 16;
77 int bit = code_word >= low_shift;
78
79 c->high = bit ? c->high - low : low;
80 c->code_word = bit ? code_word - low_shift : code_word;
81
82 return bit;
83 }
84
85 // branchy variant, to be used where there's a branch based on the bit decoded
vpx_rac_get_prob_branchy(VpxRangeCoder * c,int prob)86 int vpx_rac_get_prob_branchy(VpxRangeCoder *c, int prob)
87 {
88 unsigned long code_word = vpx_rac_renorm(c);
89 unsigned low = 1 + (((c->high - 1) * prob) >> 8);
90 unsigned low_shift = low << 16;
91
92 if (code_word >= low_shift) {
93 c->high -= low;
94 c->code_word = code_word - low_shift;
95 return 1;
96 }
97
98 c->high = low;
99 c->code_word = code_word;
100 return 0;
101 }
102
103 // rounding is different than vpx_rac_get, is vpx_rac_get wrong?
vpx_rac_get(VpxRangeCoder * c)104 int vpx_rac_get(VpxRangeCoder *c)
105 {
106 return vpx_rac_get_prob(c, 128);
107 }
108
vpx_rac_get_uint(VpxRangeCoder * c,int bits)109 int vpx_rac_get_uint(VpxRangeCoder *c, int bits)
110 {
111 int value = 0;
112
113 while (bits--) {
114 value = (value << 1) | vpx_rac_get(c);
115 }
116
117 return value;
118 }
119
120