• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ASTC_CODEC_BASE_BIT_STREAM_H_
16 #define ASTC_CODEC_BASE_BIT_STREAM_H_
17 
18 #include <cassert>
19 #include <cstdint>
20 
21 namespace astc_codec {
22 namespace base {
23 
24 // Represents a stream of bits that can be read or written in arbitrary-sized
25 // chunks.
26 template<typename IntType = uint64_t>
27 class BitStream {
28  public:
29   // Creates an empty BitStream.
30   BitStream() = default;
BitStream(IntType data,uint32_t data_size)31   BitStream(IntType data, uint32_t data_size)
32       : data_(data), data_size_(data_size) {
33     assert(data_size_ <= sizeof(data_) * 8);
34   }
35 
36   // Return the number of bits in the stream.
Bits()37   uint32_t Bits() const { return data_size_; }
38 
39   // Put |size| bits into the stream.
40   // Fails if there is not enough space in the buffer to store the bits.
41   template<typename ResultType>
PutBits(ResultType x,uint32_t size)42   void PutBits(ResultType x, uint32_t size) {
43     assert(data_size_ + size <= sizeof(data_) * 8);
44 
45     data_ |= (IntType(x) & MaskFor(size)) << data_size_;
46     data_size_ += size;
47   }
48 
49   // Get |count| bits from the stream.
50   // Returns true if |count| bits were successfully retrieved.
51   template<typename ResultType>
GetBits(uint32_t count,ResultType * result)52   bool GetBits(uint32_t count, ResultType* result) {
53     if (count <= data_size_) {
54       *result = static_cast<ResultType>(data_ & MaskFor(count));
55       data_ = data_ >> count;
56       data_size_ -= count;
57       return true;
58     } else {
59       *result = ResultType();
60       return false;
61     }
62   }
63 
64  private:
MaskFor(uint32_t bits)65   IntType MaskFor(uint32_t bits) const {
66     return (bits == sizeof(IntType) * 8) ? ~IntType(0)
67                                          : (IntType(1) << bits) - 1;
68   }
69 
70   IntType data_ = IntType();
71   uint32_t data_size_ = 0;
72 };
73 
74 }  // namespace base
75 }  // namespace astc_codec
76 
77 #endif  // ASTC_CODEC_BASE_BIT_STREAM_H_
78