1 // Copyright (c) 2012 The Chromium 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 #include "media/base/bit_reader.h" 6 7 namespace media { 8 9 BitReader::BitReader(const uint8* data, off_t size) 10 : data_(data), bytes_left_(size), num_remaining_bits_in_curr_byte_(0) { 11 DCHECK(data_ != NULL && bytes_left_ > 0); 12 13 UpdateCurrByte(); 14 } 15 16 BitReader::~BitReader() {} 17 18 bool BitReader::SkipBits(int num_bits) { 19 DCHECK_GE(num_bits, 0); 20 DLOG_IF(INFO, num_bits > 100) 21 << "BitReader::SkipBits inefficient for large skips"; 22 23 // Skip any bits in the current byte waiting to be processed, then 24 // process full bytes until less than 8 bits remaining. 25 while (num_bits > 0 && num_bits > num_remaining_bits_in_curr_byte_) { 26 num_bits -= num_remaining_bits_in_curr_byte_; 27 num_remaining_bits_in_curr_byte_ = 0; 28 UpdateCurrByte(); 29 30 // If there is no more data remaining, only return true if we 31 // skipped all that were requested. 32 if (num_remaining_bits_in_curr_byte_ == 0) 33 return (num_bits == 0); 34 } 35 36 // Less than 8 bits remaining to skip. Use ReadBitsInternal to verify 37 // that the remaining bits we need exist, and adjust them as necessary 38 // for subsequent operations. 39 uint64 not_needed; 40 return ReadBitsInternal(num_bits, ¬_needed); 41 } 42 43 int BitReader::bits_available() const { 44 return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_; 45 } 46 47 bool BitReader::ReadBitsInternal(int num_bits, uint64* out) { 48 DCHECK_LE(num_bits, 64); 49 50 *out = 0; 51 52 while (num_remaining_bits_in_curr_byte_ != 0 && num_bits != 0) { 53 int bits_to_take = std::min(num_remaining_bits_in_curr_byte_, num_bits); 54 55 *out <<= bits_to_take; 56 *out += curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_to_take); 57 num_bits -= bits_to_take; 58 num_remaining_bits_in_curr_byte_ -= bits_to_take; 59 curr_byte_ &= (1 << num_remaining_bits_in_curr_byte_) - 1; 60 61 if (num_remaining_bits_in_curr_byte_ == 0) 62 UpdateCurrByte(); 63 } 64 65 return num_bits == 0; 66 } 67 68 void BitReader::UpdateCurrByte() { 69 DCHECK_EQ(num_remaining_bits_in_curr_byte_, 0); 70 71 if (bytes_left_ == 0) 72 return; 73 74 // Load a new byte and advance pointers. 75 curr_byte_ = *data_; 76 ++data_; 77 --bytes_left_; 78 num_remaining_bits_in_curr_byte_ = 8; 79 } 80 81 } // namespace media 82