1 // Copyright 2017 PDFium Authors. All rights reserved. 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 CFX_BitStream(pdfium::span<const uint8_t> pData)14CFX_BitStream::CFX_BitStream(pdfium::span<const uint8_t> pData) 15 : m_BitPos(0), m_BitSize(pData.size() * 8), m_pData(pData.data()) { 16 ASSERT(pData.size() <= std::numeric_limits<uint32_t>::max() / 8); 17 } 18 ~CFX_BitStream()19CFX_BitStream::~CFX_BitStream() {} 20 ByteAlign()21void CFX_BitStream::ByteAlign() { 22 m_BitPos = FxAlignToBoundary<8>(m_BitPos); 23 } 24 GetBits(uint32_t nBits)25uint32_t CFX_BitStream::GetBits(uint32_t nBits) { 26 ASSERT(nBits > 0); 27 ASSERT(nBits <= 32); 28 if (nBits > m_BitSize || m_BitPos > m_BitSize - nBits) 29 return 0; 30 31 const uint32_t bit_pos = m_BitPos % 8; 32 uint32_t byte_pos = m_BitPos / 8; 33 const uint8_t* data = m_pData.Get(); 34 uint8_t current_byte = data[byte_pos]; 35 36 if (nBits == 1) { 37 int 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 |= data[byte_pos++] << bit_left; 58 } 59 if (bit_left) 60 result |= data[byte_pos] >> (8 - bit_left); 61 m_BitPos += nBits; 62 return result; 63 } 64