|
1 /* |
|
2 * skulltag::BitReader class - Allows reading arbitrary bit lengths of data. |
|
3 * Version 1 - Revsion 0 |
|
4 * |
|
5 * Copyright 2009 Timothy Landers |
|
6 * email: code.vortexcortex@gmail.com |
|
7 * |
|
8 * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
9 * of this software and associated documentation files (the "Software"), to deal |
|
10 * in the Software without restriction, including without limitation the rights |
|
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
12 * copies of the Software, and to permit persons to whom the Software is |
|
13 * furnished to do so, subject to the following conditions: |
|
14 * |
|
15 * The above copyright notice and this permission notice shall be included in |
|
16 * all copies or substantial portions of the Software. |
|
17 * |
|
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
24 * THE SOFTWARE. |
|
25 */ |
|
26 |
|
27 #include "bitreader.h" |
|
28 /** Prevents naming convention problems via encapsulation. */ |
|
29 namespace skulltag { |
|
30 // BitReader class implementation |
|
31 |
|
32 int BitReader::intBitSize = 0; |
|
33 int BitReader::intSize = 0; |
|
34 int BitReader::mask[32] = {0}; |
|
35 |
|
36 /** Creates a new BitReader. */ |
|
37 BitReader::BitReader(){ |
|
38 init(); |
|
39 } |
|
40 |
|
41 /** Creates a new BitReader. |
|
42 * @param input Source of data that bits will be read from. |
|
43 * @param max Maximum number of chars to read. */ |
|
44 BitReader::BitReader( unsigned char const * input, int const &max ){ |
|
45 inputBuffer( input, max ); |
|
46 } |
|
47 |
|
48 /** Sets the input buffer that bytes will be read from. |
|
49 * @param input Source of data that bits will be read from. |
|
50 * @param max Maximum number of chars to input. |
|
51 * @return true if successful, false if an error occurs. */ |
|
52 bool BitReader::inputBuffer( unsigned char const * input, int const &max ){ |
|
53 init(); // zero the vars. |
|
54 currentByte = input; |
|
55 if ( input == 0 ) return false; |
|
56 if ( max < 1 ) return false; |
|
57 bytesAvailable = max; |
|
58 bitsAvailable = max << 3; |
|
59 maximumBytes = max; |
|
60 return true; |
|
61 } |
|
62 |
|
63 /** Initializes this BitReader */ |
|
64 void BitReader::init(){ |
|
65 // initialize static variables if not initialized yet. |
|
66 if ( intSize == 0 ){ |
|
67 intSize = sizeof maximumBytes; |
|
68 mask[0] = 0; |
|
69 |
|
70 // fill mask such that m = { 0, 1, 3, 7, 15, etc. } |
|
71 for ( int i = 1; i < 32; i++ ) mask[i] = (mask[i-1] << 1) | 1; |
|
72 |
|
73 intBitSize = intSize << 3; |
|
74 } |
|
75 |
|
76 // initialize member variables. |
|
77 bitsAvailable = 0; |
|
78 bytesAvailable = 0; |
|
79 bufferBits = 0; |
|
80 currentByte = 0; |
|
81 maximumBytes = 0; |
|
82 bitsUsed = 0; |
|
83 } |
|
84 |
|
85 /** Fills the internal bit buffer. |
|
86 * @return true if successful, false if an error occurs. */ |
|
87 bool BitReader::fill(){ |
|
88 if ( (currentByte == 0) || (bytesAvailable <= 0) ) return false; |
|
89 |
|
90 // while there's at least one octet free in the buffer, and one byte to read. |
|
91 while ( (bitsUsed < (intBitSize - 8)) && (bytesAvailable > 0) ){ |
|
92 |
|
93 // put a byte into the bottom end of the buffer. |
|
94 bufferBits |= (*currentByte & mask[8]) << (intBitSize - bitsUsed - 8); |
|
95 |
|
96 // Set variables to reflect the change. |
|
97 currentByte++; |
|
98 bytesAvailable--; |
|
99 bitsUsed += 8; |
|
100 } |
|
101 return true; |
|
102 } |
|
103 |
|
104 /** Fetches a specified number of bits and stores them in an int. |
|
105 * @param bits destination of the retrieved bits. <br> |
|
106 * The bits will be stored in the least significant portion of the int. |
|
107 * @param count the number of bits to fetch. |
|
108 * @return the number of bits read -- may not be equal to the amount requested. */ |
|
109 int BitReader::get( int &bits, int const &count ){ |
|
110 bits = 0; |
|
111 // Requesting more bits than are available. |
|
112 if ( count > bitsAvailable ) return 0; |
|
113 if ( (count > bitsUsed) && (!fill()) ) return 0; |
|
114 bits = (bufferBits >> (intBitSize - count)) & mask[count]; |
|
115 // lesser of bits in buffer or requested bits. |
|
116 int got = (bitsUsed < count) ? bitsUsed : count; |
|
117 // get as many bits from the buffer as we can. |
|
118 if ( got > 0 ){ |
|
119 bufferBits <<= got; |
|
120 bitsUsed -= got; |
|
121 bitsAvailable -= got; |
|
122 } |
|
123 // if more bits are requested. |
|
124 if ( count > got ){ |
|
125 if (!fill()) { |
|
126 bits = (bits >> (count - got)) & mask[count - got]; |
|
127 return got; |
|
128 } |
|
129 got = count - got; |
|
130 // avoid reading more bits than available. |
|
131 if ( got <= bitsAvailable ){ |
|
132 bits |= (bufferBits >> (intBitSize - got)) & mask[got]; |
|
133 bufferBits <<= got; |
|
134 bitsUsed -= got; |
|
135 bitsAvailable -= got; |
|
136 } |
|
137 } |
|
138 return count; |
|
139 } |
|
140 |
|
141 /** @return Amount of bits that can be read from this BitReader. */ |
|
142 int BitReader::availableBits(){ return bitsAvailable; } |
|
143 |
|
144 } // end namespace skulltag |