Line data Source code
1 : /*
2 : * Copyright (C) 2010 The Android Open Source Project
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #include "ABitReader.h"
18 :
19 : #include <log/log.h>
20 : #include <media/stagefright/foundation/ADebug.h>
21 :
22 : namespace stagefright {
23 :
24 0 : ABitReader::ABitReader(const uint8_t *data, size_t size)
25 : : mData(data),
26 : mSize(size),
27 : mReservoir(0),
28 0 : mNumBitsLeft(0) {
29 0 : }
30 :
31 0 : void ABitReader::fillReservoir() {
32 0 : CHECK_GT(mSize, 0u);
33 :
34 0 : mReservoir = 0;
35 : size_t i;
36 0 : for (i = 0; mSize > 0 && i < 4; ++i) {
37 0 : mReservoir = (mReservoir << 8) | *mData;
38 :
39 0 : ++mData;
40 0 : --mSize;
41 : }
42 :
43 0 : mNumBitsLeft = 8 * i;
44 0 : mReservoir <<= 32 - mNumBitsLeft;
45 0 : }
46 :
47 0 : uint32_t ABitReader::getBits(size_t n) {
48 0 : CHECK_LE(n, 32u);
49 :
50 0 : uint32_t result = 0;
51 0 : while (n > 0) {
52 0 : if (mNumBitsLeft == 0) {
53 0 : fillReservoir();
54 : }
55 :
56 0 : size_t m = n;
57 0 : if (m > mNumBitsLeft) {
58 0 : m = mNumBitsLeft;
59 : }
60 :
61 0 : result = (result << m) | (mReservoir >> (32 - m));
62 0 : mReservoir <<= m;
63 0 : mNumBitsLeft -= m;
64 :
65 0 : n -= m;
66 : }
67 :
68 0 : return result;
69 : }
70 :
71 0 : void ABitReader::skipBits(size_t n) {
72 0 : while (n > 32) {
73 0 : getBits(32);
74 0 : n -= 32;
75 : }
76 :
77 0 : if (n > 0) {
78 0 : getBits(n);
79 : }
80 0 : }
81 :
82 0 : void ABitReader::putBits(uint32_t x, size_t n) {
83 0 : CHECK_LE(n, 32u);
84 :
85 0 : while (mNumBitsLeft + n > 32) {
86 0 : mNumBitsLeft -= 8;
87 0 : --mData;
88 0 : ++mSize;
89 : }
90 :
91 0 : mReservoir = (mReservoir >> n) | (x << (32 - n));
92 0 : mNumBitsLeft += n;
93 0 : }
94 :
95 0 : size_t ABitReader::numBitsLeft() const {
96 0 : return mSize * 8 + mNumBitsLeft;
97 : }
98 :
99 0 : const uint8_t *ABitReader::data() const {
100 0 : return mData - (mNumBitsLeft + 7) / 8;
101 : }
102 :
103 : } // namespace stagefright
|