xref: /aosp_15_r20/external/puffin/src/bit_reader.cc (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
1*07fb1d06SElliott Hughes // Copyright 2017 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes 
5*07fb1d06SElliott Hughes #include "puffin/src/bit_reader.h"
6*07fb1d06SElliott Hughes 
7*07fb1d06SElliott Hughes #include "puffin/src/logging.h"
8*07fb1d06SElliott Hughes 
9*07fb1d06SElliott Hughes namespace puffin {
10*07fb1d06SElliott Hughes 
CacheBits(size_t nbits)11*07fb1d06SElliott Hughes bool BufferBitReader::CacheBits(size_t nbits) {
12*07fb1d06SElliott Hughes   if ((in_size_ - index_) * 8 + in_cache_bits_ < nbits) {
13*07fb1d06SElliott Hughes     return false;
14*07fb1d06SElliott Hughes   }
15*07fb1d06SElliott Hughes   if (nbits > sizeof(in_cache_) * 8) {
16*07fb1d06SElliott Hughes     return false;
17*07fb1d06SElliott Hughes   }
18*07fb1d06SElliott Hughes   while (in_cache_bits_ < nbits) {
19*07fb1d06SElliott Hughes     in_cache_ |= in_buf_[index_++] << in_cache_bits_;
20*07fb1d06SElliott Hughes     in_cache_bits_ += 8;
21*07fb1d06SElliott Hughes   }
22*07fb1d06SElliott Hughes   return true;
23*07fb1d06SElliott Hughes }
24*07fb1d06SElliott Hughes 
ReadBits(size_t nbits)25*07fb1d06SElliott Hughes uint32_t BufferBitReader::ReadBits(size_t nbits) {
26*07fb1d06SElliott Hughes   return in_cache_ & ((1U << nbits) - 1);
27*07fb1d06SElliott Hughes }
28*07fb1d06SElliott Hughes 
DropBits(size_t nbits)29*07fb1d06SElliott Hughes void BufferBitReader::DropBits(size_t nbits) {
30*07fb1d06SElliott Hughes   in_cache_ >>= nbits;
31*07fb1d06SElliott Hughes   in_cache_bits_ -= nbits;
32*07fb1d06SElliott Hughes }
33*07fb1d06SElliott Hughes 
ReadBoundaryBits()34*07fb1d06SElliott Hughes uint8_t BufferBitReader::ReadBoundaryBits() {
35*07fb1d06SElliott Hughes   return in_cache_ & ((1 << (in_cache_bits_ & 7)) - 1);
36*07fb1d06SElliott Hughes }
37*07fb1d06SElliott Hughes 
SkipBoundaryBits()38*07fb1d06SElliott Hughes size_t BufferBitReader::SkipBoundaryBits() {
39*07fb1d06SElliott Hughes   size_t nbits = in_cache_bits_ & 7;
40*07fb1d06SElliott Hughes   in_cache_ >>= nbits;
41*07fb1d06SElliott Hughes   in_cache_bits_ -= nbits;
42*07fb1d06SElliott Hughes   return nbits;
43*07fb1d06SElliott Hughes }
44*07fb1d06SElliott Hughes 
GetByteReaderFn(size_t length,std::function<bool (uint8_t *,size_t)> * read_fn)45*07fb1d06SElliott Hughes bool BufferBitReader::GetByteReaderFn(
46*07fb1d06SElliott Hughes     size_t length, std::function<bool(uint8_t*, size_t)>* read_fn) {
47*07fb1d06SElliott Hughes   index_ -= (in_cache_bits_ + 7) / 8;
48*07fb1d06SElliott Hughes   in_cache_ = 0;
49*07fb1d06SElliott Hughes   in_cache_bits_ = 0;
50*07fb1d06SElliott Hughes   TEST_AND_RETURN_FALSE(length <= in_size_ - index_);
51*07fb1d06SElliott Hughes   *read_fn = [this, length](uint8_t* buffer, size_t count) mutable {
52*07fb1d06SElliott Hughes     TEST_AND_RETURN_FALSE(count <= length);
53*07fb1d06SElliott Hughes     if (buffer != nullptr) {
54*07fb1d06SElliott Hughes       memcpy(buffer, &in_buf_[index_], count);
55*07fb1d06SElliott Hughes     }
56*07fb1d06SElliott Hughes     index_ += count;
57*07fb1d06SElliott Hughes     length -= count;
58*07fb1d06SElliott Hughes     return true;
59*07fb1d06SElliott Hughes   };
60*07fb1d06SElliott Hughes   return true;
61*07fb1d06SElliott Hughes }
62*07fb1d06SElliott Hughes 
Offset() const63*07fb1d06SElliott Hughes size_t BufferBitReader::Offset() const {
64*07fb1d06SElliott Hughes   return index_ - in_cache_bits_ / 8;
65*07fb1d06SElliott Hughes }
66*07fb1d06SElliott Hughes 
OffsetInBits() const67*07fb1d06SElliott Hughes uint64_t BufferBitReader::OffsetInBits() const {
68*07fb1d06SElliott Hughes   return (index_ * 8) - in_cache_bits_;
69*07fb1d06SElliott Hughes }
70*07fb1d06SElliott Hughes 
BitsRemaining() const71*07fb1d06SElliott Hughes uint64_t BufferBitReader::BitsRemaining() const {
72*07fb1d06SElliott Hughes   return ((in_size_ - index_) * 8) + in_cache_bits_;
73*07fb1d06SElliott Hughes }
74*07fb1d06SElliott Hughes 
75*07fb1d06SElliott Hughes }  // namespace puffin
76