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)15CFX_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()22void CFX_BitStream::ByteAlign() { 23 m_BitPos = FxAlignToBoundary<8>(m_BitPos); 24 } 25 GetBits(uint32_t nBits)26uint32_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