xref: /aosp_15_r20/external/pdfium/core/fxcrt/cfx_bitstream.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fxcrt/cfx_bitstream.h"
8 
9 #include <limits>
10 
11 #include "core/fxcrt/fx_memory.h"
12 #include "core/fxcrt/fx_system.h"
13 #include "third_party/base/check_op.h"
14 
CFX_BitStream(pdfium::span<const uint8_t> pData)15 CFX_BitStream::CFX_BitStream(pdfium::span<const uint8_t> pData)
16     : m_BitSize(pData.size() * 8), m_pData(pData) {
17   CHECK_LE(m_pData.size(), std::numeric_limits<size_t>::max() / 8);
18 }
19 
20 CFX_BitStream::~CFX_BitStream() = default;
21 
ByteAlign()22 void CFX_BitStream::ByteAlign() {
23   m_BitPos = FxAlignToBoundary<8>(m_BitPos);
24 }
25 
GetBits(uint32_t nBits)26 uint32_t CFX_BitStream::GetBits(uint32_t nBits) {
27   DCHECK(nBits > 0);
28   DCHECK(nBits <= 32);
29   if (nBits > m_BitSize || m_BitPos > m_BitSize - nBits)
30     return 0;
31 
32   const uint32_t bit_pos = m_BitPos % 8;
33   size_t byte_pos = m_BitPos / 8;
34   uint8_t current_byte = m_pData[byte_pos];
35 
36   if (nBits == 1) {
37     uint32_t bit = (current_byte & (1 << (7 - bit_pos))) ? 1 : 0;
38     m_BitPos++;
39     return bit;
40   }
41 
42   uint32_t bit_left = nBits;
43   uint32_t result = 0;
44   if (bit_pos) {
45     uint32_t bits_readable = 8 - bit_pos;
46     if (bits_readable >= bit_left) {
47       result = (current_byte & (0xff >> bit_pos)) >> (bits_readable - bit_left);
48       m_BitPos += bit_left;
49       return result;
50     }
51     bit_left -= bits_readable;
52     result = (current_byte & ((1 << bits_readable) - 1)) << bit_left;
53     ++byte_pos;
54   }
55   while (bit_left >= 8) {
56     bit_left -= 8;
57     result |= m_pData[byte_pos++] << bit_left;
58   }
59   if (bit_left)
60     result |= m_pData[byte_pos] >> (8 - bit_left);
61   m_BitPos += nBits;
62   return result;
63 }
64