libopenraw  0.3.7
bititerator.cpp
1 /* -*- tab-width:4; c-basic-offset:4 -*- */
2 /*
3  * libopenraw - bititerator.cpp
4  *
5  * Copyright (C) 2008 Rafael Avila de Espindola.
6  * Copyright (C) 2022 Hubert Figuiere
7  *
8  * This library is free software: you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <assert.h>
24 #include <algorithm>
25 #include "bititerator.hpp"
26 
27 namespace OpenRaw {
28 namespace Internals {
29 
30 BitIterator::BitIterator(const uint8_t * const p, size_t size)
31  : m_p(p)
32  , m_size(size)
33  , m_bitBuffer(0)
34  , m_bitsOnBuffer(0)
35 
36 {
37 }
38 
39 void BitIterator::addByte(uint8_t byte)
40 {
41  m_bitBuffer = (m_bitBuffer << 8) | byte;
42  m_bitsOnBuffer += 8;
43 }
44 
45 void BitIterator::load(size_t numBits)
46 {
47  size_t numBytes = (numBits + 7) / 8;
48 
49  // align the bits on the right
50  m_bitBuffer >>= (32 - m_bitsOnBuffer);
51 
52  // load the new bits from the right
53  size_t i = 0;
54  for (; i < numBytes && m_size > 0; ++i) {
55  addByte(*m_p);
56  ++m_p;
57  m_size--;
58  }
59  for (; i < numBytes; ++i) {
60  addByte(0);
61  }
62 
63  // align the bits on the left
64  m_bitBuffer = m_bitBuffer << (32 - m_bitsOnBuffer);
65 }
66 
67 uint32_t BitIterator::get(size_t n)
68 {
69  uint32_t ret = peek(n);
70 
71  skip(n);
72 
73  return ret;
74 }
75 
76 uint32_t BitIterator::peek(size_t n)
77 {
78  assert(n <= 25);
79 
80  if (n == 0) {
81  return 0;
82  }
83 
84  if (n > m_bitsOnBuffer) {
85  load(n - m_bitsOnBuffer);
86  }
87 
88  assert(n <= m_bitsOnBuffer);
89 
90  return m_bitBuffer >> (32 - n);
91 }
92 
93 void BitIterator::skip(size_t n)
94 {
95  size_t num_bits = std::min(n, m_bitsOnBuffer);
96  m_bitsOnBuffer -= num_bits;
97  m_bitBuffer <<= num_bits;
98 }
99 
100 }
101 }
Global namespace for libopenraw.
Definition: arwfile.cpp:29